How to setup a loopback test of uart speed

costaud
Posts: 138
Joined: Fri Oct 24, 2014 7:40 pm

How to setup a loopback test of uart speed

Postby costaud » Mon Nov 03, 2014 3:10 am

As the esp8266 uart speed can be set up to 115200*40( that is around 4.5Mbps), we can setup a uart loopback test like this.

in uart.c

Code: Select all

LOCAL void ICACHE_FLASH_ATTR
uart_config(uint8 uart_no)
{
    if (uart_no == UART1) {
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
    } else {
        /* rcv_buff size if 0x100 */
        ETS_UART_INTR_ATTACH(uart0_rx_intr_handler,  &(UartDev.rcv_buff));
        PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
    }

    uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));

    WRITE_PERI_REG(UART_CONF0(uart_no),    UartDev.exist_parity
                   | UartDev.parity
                   | (UartDev.stop_bits << UART_STOP_BIT_NUM_S)
                   | (UartDev.data_bits << UART_BIT_NUM_S));
    //clear rx and tx fifo,not ready
    SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);//|UART_LOOPBACK);/*if set UART_LOOPBACK BIT,the tx rx will be connected inside the chip*/
    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
    //set rx fifo trigger  and rx tout en , rx tout thresh
    //WRITE_PERI_REG(UART_CONF1(uart_no), (UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S);
    WRITE_PERI_REG(UART_CONF1(uart_no), UART_RX_TOUT_EN |
                               (0x10 &UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S   );
    //clear all interrupt
    WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
    //enable rx_interrupt : rx fifo full and rx tout
    CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), 0x1ff);//DISABLE FIFO_FULL INT
    SET_PERI_REG_MASK(UART_INT_ENA(uart_no),  UART_RXFIFO_TOUT_INT_ENA);// UART_RXFIFO_FULL_INT_ENA |

}

STATUS ICACHE_FLASH_ATTR
uart0_tx_one_char(uint8 TxChar)  //add definition in uart.h
{
    while (true)
   {
      uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(UART0)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
      if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
         break;
      }
   }
   WRITE_PERI_REG(UART_FIFO(UART0) , TxChar);
   return OK;
}

LOCAL void ICACHE_FLASH_ATTR
uart0_rx_intr_handler(void *para)
{
    /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
     * uart1 and uart0 respectively
     */
   RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
   uint8 RcvChar;
   static uint32 t1=0,t2=0;
   uint32 fifo_cnt=0;
   if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_RXFIFO_FULL_INT_ST)) {
      os_printf("full intr\n\r");
      WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
   }else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_RXFIFO_TOUT_INT_ST)) {
      //os_printf("uart rx time out \n\r");
      WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
      while (READ_PERI_REG(UART_STATUS(UART0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
      RcvChar = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
      if(RcvChar=='U'){
         uart0_tx_one_char(RcvChar);
      }else{
         uart0_tx_one_char('T');
         uart0_tx_one_char(RcvChar);
         uart0_tx_one_char('T');
         while(1){}
      }
      }
      WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
       }
   else{
      //clear all interrupt
      os_printf("other intr occured\n\r");
      WRITE_PERI_REG(UART_INT_CLR(UART0), 0xffff);
   }

}
void ICACHE_FLASH_ATTR
uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
{
    // rom use 74880 baut_rate, here reinitialize
    UartDev.baut_rate = uart0_br;
    uart_config(UART0);
    UartDev.baut_rate = uart1_br;
    uart_config(UART1);
    ETS_UART_INTR_ENABLE();
    // install uart1 putc callback
    os_install_putc1((void *)uart1_write_char);

}



in user_main.c:

Code: Select all

#include "osapi.h"
//#include "driver/uart.h"
os_timer_t uart_init_timer;
void loop_test_init()
{
   uart_init(115200*40, 74880);
   int i = 0;
   while( (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S))!=0){}
      for(i=0;i<20;i++){
         uart0_tx_one_char('U');
      }

}

void user_init(void)
{
os_printf("SDK version:%d.%d.%d\n", SDK_VERSION_MAJOR, SDK_VERSION_MINOR, SDK_VERSION_REVISION);
os_timer_disarm(&uart_init_timer);
os_timer_setfn(&uart_init_timer, (os_timer_func_t *)loop_test_init, NULL);
os_timer_arm(&uart_init_timer, 1000, 0);
/*
#if ESP_PLATFORM
    user_esp_platform_init();
#endif

    user_devicefind_init();
#ifdef SERVER_SSL_ENABLE
    user_webserver_init(SERVER_SSL_PORT);
#else
    user_webserver_init(SERVER_PORT);
#endif
*/
}


in uart.c, we config the uart rx timeout interrupt .and in the INT handler print the bytes in the rx fifo again.
If the UART_LOOPBACK BIT is set ,the tx rx will be connected inside the chip.
Otherwise, we should connect the uart0 tx and rx on the board.


The uart0 will tx several letters of 'U' in a circular manner. Then the rx side will receive and trigger a rx timeout INT.
In the rx INT handler , it check the rx byte , if not correct, the programme hang up and cause a watch dog reset.

The speed of uart can reach 1000000 / 0.220us = 4.545 Mbps

02.png
02.png (41.89 KiB) Viewed 12014 times

01.png
01.png (64.22 KiB) Viewed 12014 times

ESP_Alfred
Posts: 56
Joined: Mon Nov 10, 2014 7:31 pm

Re: How to setup a loopback test of uart speed

Postby ESP_Alfred » Mon Nov 17, 2014 11:28 pm

Oh, My God.

The UART rate is so high!!!

Who is online

Users browsing this forum: No registered users and 92 guests