[UPDATE150418]UART DRIVER UPDATE

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

[UPDATE150418]UART DRIVER UPDATE

Postby costaud » Tue Nov 18, 2014 2:33 am

150418 update:
add more annotation to explain how to choose different uart output mode.
A simple DMA to output data to uart0
Move output data in interrupt handler instead of in system task.
uart_driver_with_buffer_150418.rar
(1.27 MiB) Downloaded 2257 times




============================================================
150413 update:
uart_driver_with_buffer_150413.rar
(1.27 MiB) Downloaded 682 times

fix some errors in parity setting in uart_config()
add definitions in uart_register.h


150410 update:
uart_driver_with_buffer_150408.rar
(1.27 MiB) Downloaded 719 times


add a demo with uart data buffer and task
send data via uart fifo empty interrupt
recv data via uart fifo full and timeout interrupt

==========================================
150112 update:
1. ADD SOME APIs FOR CFG
2.FIX SOME ERROR OF DEFINITION IN UART.H
THIS IS FOR NONE_OS VERSION.

uart_for_none_os.rar
(9.22 KiB) Downloaded 874 times


I RECOMMEND THE RTOS VERSION DRIVER , MORE FRIENDLY.
YOU CAN GET FROM
https://github.com/espressif/esp_iot_rtos_sdk



===========================================================
141123 update: GENERATE A TX BREAK SIGNAL!

In order to issue a tx break signal , you should do like this :
1. set UART_TXFIFO_RST,
2. set UART_TXD_BRK
3. set a timer to RESET UART_TXD_BRK
3. reset UART_TXD_BRK in timer(or other event)

Code: Select all

   
//   1. set UART_TXFIFO_RST,         
SET_PERI_REG_MASK(UART_CONF0(UART0), UART_RXFIFO_RST | UART_TXFIFO_RST);
CLEAR_PERI_REG_MASK(UART_CONF0(UART0), UART_RXFIFO_RST | UART_TXFIFO_RST);
//   2. set UART_TXD_BRK
SET_PERI_REG_MASK(UART_CONF0(UART0), UART_TXD_BRK);
//   3. set a timer to RESET UART_TXD_BRK
os_timer_arm(&brk_timer,1,0);


Code: Select all

   
//timer
os_timer_t brk_timer;
void ICACHE_FLASH_ATTR clr_brk_bit()
{
    CLEAR_PERI_REG_MASK(UART_CONF0(UART0), UART_TXD_BRK);
}

LOCAL void ICACHE_FLASH_ATTR
uart_config(uint8 uart_no)
{
......
os_timer_setfn(&brk_timer, (os_timer_func_t *)clr_brk_bit, NULL);
}


Also you can set up a loop back test for this :
1.enable UART_BRK_DET interrupt in uart initial func

Code: Select all

//1.enable UART_BRK_DET interrupt in uart initial func
SET_PERI_REG_MASK(UART_INT_ENA(uart_no),  UART_BRK_DET_INT_ENA);

2.process UART_BRK_DET_INT in uart interrupt handler

Code: Select all

//2.process UART_BRK_DET_INT in uart interrupt handler
......
else if(UART_BRK_DET_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_BRK_DET_INT_ST)) {
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_BRK_DET_INT_CLR);//clear interrupt
CLEAR_PERI_REG_MASK(UART_CONF0(UART0), UART_LOOPBACK);//disable uart loopback
CLEAR_PERI_REG_MASK(UART_CONF0(UART0), UART_TXD_BRK);//CLEAR BRK BIT
os_printf("BRK INTR\n\r");
}
......

3.IN TESTCASE :START A LOOPBACK TX BRK SIGNAL AND TRIGGER THE INTERRUPT

Code: Select all

//enable uart loopback
SET_PERI_REG_MASK(UART_CONF0(UART0), UART_LOOPBACK);
//reset fifo
SET_PERI_REG_MASK(UART_CONF0(UART0), UART_RXFIFO_RST | UART_TXFIFO_RST);
CLEAR_PERI_REG_MASK(UART_CONF0(UART0), UART_RXFIFO_RST | UART_TXFIFO_RST);
//set  UART_TXD_BRK bit
SET_PERI_REG_MASK(UART_CONF0(UART0), UART_TXD_BRK);




==========================================================================
[ATTENTION PLEASE]:
In the rx tout and rx fifo full interrupt handler, make sure to read the whole fifo data out ,then set the interrupt clear bit.


This is a UART register description.
Uart_reg_release_141118.xls
(36 KiB) Downloaded 1213 times


The two uart modules have their own independent register address and hw fifo.
We can distinguish them with the macros UART0 and UART1.

To config a register, you can do like this:

Code: Select all

/*
 *e.g.
 *#define TEST_REG_ADDR      0x60000000
 *#define TEST_REG_FUNC 0x0000007F
 *#define TEST_REG_FUNC_S 8

 *BASE ADDR:0x60000000
 *TEST_REG_FUNC  MASK FOR THE CONFIG ITEM(0x7F means it takes 7 bit)
 *TEST_REG_FUNC_S  is the bit offset from the lsb
 *eg.in order to set 0x55:
 *((0x55 & TEST_REG_FUNC)<<TEST_REG_FUNC_S)
 *you can use it along with the macros below
 *GET_PERI_REG_BITS(reg, hipos,lowpos)
 *GET_PERI_REG_BITS(TEST_REG_ADDR,TEST_REG_FUNC_S+7,TEST_REG_FUNC_S)
 *SET_PERI_REG_BITS(reg,bit_map,value,shift)
 *SET_PERI_REG_BITS(TEST_REG_ADDR,TEST_REG_FUNC,0x55,TEST_REG_FUNC_S)
*/

Do compare the difference of the macros, WRITE_PERI_REG,SET_PERI_REG_BITS,SET_PERI_REG_MASK

Here are some reference codes:
1.uart1 pin mux select:

Code: Select all

PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);   //CONFIG GPIO2 TO UART1 TXD

2.config uart speed

Code: Select all

uart_div_modify(uart_no, UART_CLK_FREQ / (115200));  //CONFIG UART baudrate to 115200

3.config UART0 data format

Code: Select all

  WRITE_PERI_REG(UART_CONF0(UART0),
                   (BIT(1))                //ENABLE PARITY CHECK
                 |(BIT(0))                    //SET ODD CHECK
                 | (0x1 << UART_STOP_BIT_NUM_S)  //STOP BIT SET
                 | (0x3 << UART_BIT_NUM_S)       //DATA BIT SET

4. Reset tx/rx fifo

Code: Select all

  //clear rx and tx fifo
  SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
  CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);

5.interrupt config

Code: Select all

//set rx INTRRUPT PARAM
    WRITE_PERI_REG(UART_CONF1(uart_no),
                   ((60 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |     //UART RX FULL THRESHOLD
                   ((100 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |    //UART RX FLOW CONTROL THRESHOLD
                   UART_RX_FLOW_EN |                                             //ENABLE RX FLOW CONTROL
                   (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |         //UART RX TIMEOUT THRESHOLD
                   UART_RX_TOUT_EN);                                            //UART RX TIMEOUT INTERRUPT ENABLE

6.enable interrupt

Code: Select all

  //clear all interrupt
  WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
  //enable rx_interrupt
  CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no),0x1ff);
  SET_PERI_REG_MASK(UART_INT_ENA(uart_no),   UART_RXFIFO_FULL_INT_ENA |       //ENABLE RX FIFO FULL INTERRUPT
                                                                 UART_RXFIFO_TOUT_INT_ENA |    //ENABLE RX TIMEOUT INTERRUPT
                                                                 UART_FRM_ERR_INT_ENA |        //ENABLE RX FRAME ERROR INTERRUPT
                                                                 UART_PARITY_ERR_INT_ENA|      //ENABLE PARITY CHECK ERROR INTERRUPT
                                                                 UART_BRK_DET_INT_ENA|         //ENABLE BYTE START ERROR INTERRUPT
                                                               );

7.register uart interrupt handler

Code: Select all

ETS_UART_INTR_ATTACH(uart0_rx_intr_handler,  &(UartDev.rcv_buff));  //REGISTER UART INTR HANDLER ,WITH PARAM BUFFER ADDR
8.handler ,do as less job as possible in interrupt handler, or post a signal to the task.
[code]if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){  //DECIDE THE INTERRUPT SOURCE
    while ( (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT){           //PROCESS ALL DATAS IN RX FIFO UNTIL IT IS EMPTY
      RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
     
    }
    WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);                                //AT LAST CLEAR INTERRUPT STATUS
  }

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

Re: [UPDATE141123]UART REGISTER !!(ADD TX BRK SIGNAL)

Postby costaud » Sun Nov 23, 2014 5:13 pm

Update on 141123:add a tx break signal instruction.

User avatar
rudi
Posts: 197
Joined: Fri Oct 24, 2014 7:55 pm

Re: [UPDATE141123]UART REGISTER !!(ADD TX BRK SIGNAL)

Postby rudi » Sun Nov 23, 2014 8:03 pm

great work costaud!!!
txs!!!
rudi :-)

-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

Strolch
Posts: 10
Joined: Fri Oct 24, 2014 7:22 pm

Re: [UPDATE141123]UART REGISTER !!(ADD TX BRK SIGNAL)

Postby Strolch » Sat Jan 10, 2015 11:03 pm

costaud, please can you elaborate a bit more about rx_tout_en, rx_tout_thrhd and txfifo_empty_thrhd?

I want to sent a BRK after the last character is completely sent out.
So, do I set txfifo_empty_thrhd to 0 and wait for the txfifo_empty IRQ?
Or is the UART still shifting data out when the txfifo_empty occures?
Is the UART Tx shiftregister idential to fifo[0], meaning <cnt==0> character is send completely?

Whats the meaning of rx_tout_en and rx_tout_thrhd?
Will the UART fire the rxfifo_tout IRQ when <rx_tout_thrdhd> character times are over?

Thanks in adance,
Jürgen

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

Re: [UPDATE141123]UART REGISTER !!(ADD TX BRK SIGNAL)

Postby costaud » Mon Jan 12, 2015 12:32 pm

Strolch wrote:costaud, please can you elaborate a bit more about rx_tout_en, rx_tout_thrhd and txfifo_empty_thrhd?

I want to sent a BRK after the last character is completely sent out.
So, do I set txfifo_empty_thrhd to 0 and wait for the txfifo_empty IRQ?
Or is the UART still shifting data out when the txfifo_empty occures?
Is the UART Tx shiftregister idential to fifo[0], meaning <cnt==0> character is send completely?

Whats the meaning of rx_tout_en and rx_tout_thrhd?
Will the UART fire the rxfifo_tout IRQ when <rx_tout_thrdhd> character times are over?

Thanks in adance,
Jürgen


soooooo sorry, I forget to choose the "NOTIFY ME" option.

The answer is :
If the BRK bit is set , the break signal will automatically sent when the tx fifo is empty.
And what you need to do is to set a timer to clear the BRK signal.

For uart tx fifo, the fifo length decreased when the start_bit begins.
For uart rx fifo, the fifo length increased when the stop_bit finished.

Strolch
Posts: 10
Joined: Fri Oct 24, 2014 7:22 pm

Re: [UPDATE150112]UART DRIVER UPDATE(ADD SOME APIs FOR CFG)

Postby Strolch » Mon Jan 12, 2015 5:39 pm

Thanks a lot, costaud.
Two questions are remaining:
° rxfifo_tout - is it bit/char time based or more like a fifo treshhold?
° How can I detect that the (last) Tx character is completely shifted out (on the wire)?

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

Re: [UPDATE150112]UART DRIVER UPDATE(ADD SOME APIs FOR CFG)

Postby costaud » Fri Jan 16, 2015 1:22 am

Strolch wrote:Thanks a lot, costaud.
Two questions are remaining:
° rxfifo_tout - is it bit/char time based or more like a fifo treshhold?
° How can I detect that the (last) Tx character is completely shifted out (on the wire)?

every unit of tout_threshold represents 8 bits' cycles

baoshi
Posts: 23
Joined: Tue Dec 02, 2014 8:35 pm

Re: [UPDATE150112]UART DRIVER UPDATE(ADD SOME APIs FOR CFG)

Postby baoshi » Tue Feb 03, 2015 2:26 pm

I do not fully under the parity part in uart.h

Code: Select all

typedef enum {
    NONE_BITS = 0x2,
    ODD_BITS   = 1,
    EVEN_BITS = 0
} UartParityMode;

typedef enum {
    STICK_PARITY_DIS   = 0,
    STICK_PARITY_EN    = 1
} UartExistParity;


It does not seem to tally with register description.

I have since used mine own version

Code: Select all

// Parity mode (bit[1:0])
typedef enum _UART_PARITY_MODE
{
   UART_PARITY_NONE   = 0x00,
   UART_PARITY_EVEN   = 0x02,
   UART_PARITY_ODD   = 0x03
} UART_PARITY_MODE;


Is the understanding correct?

Who is online

Users browsing this forum: No registered users and 13 guests