📜 ⬆️ ⬇️

UART FIFO Buffer Features in ESP32

ESP32 has three UARTs. Each of which places the FIFO buffer of the receiver and the FIFO buffer of the transmitter in shared memory of 1024 bytes (ESP32 technical reference manual 3.5):



However, when trying to increase the size of the FIFO buffer of the UART2 transmitter from 128 to 256 bytes, it had an unexpected effect - the transmitted data spoiled the FIFO buffer of the UART0 receiver, which according to the documentation should not be.


Unfortunately, the documentation (ESP32 technical reference manual 3.5) does not contain a description of the FIFO buffer registers. However, in the header files esp-idf (in uart_struct.h) showed up:


1) FIFO transmitter buffer status register (offset from base address 0x5c):


union { struct { uint32_t status:24; uint32_t reserved24: 8; }; uint32_t val; } mem_tx_status; 

2) FIFO status register of the receiver buffer (offset relative to the base address 0x60):


  union { struct { uint32_t status: 24; uint32_t reserved24: 8; }; struct { uint32_t reserved0: 2; uint32_t rd_addr: 11; /*This register stores the rx mem read address.*/ uint32_t wr_addr: 11; /*This register stores the rx mem write address.*/ uint32_t reserved: 8; }; uint32_t val; } mem_rx_status; 

Assuming that mem_tx_status corresponds to the purpose of the mem_rx_status bit, we write the following code to get the addresses of the FIFO buffers:


 #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include <driver/uart.h> void print_uart_st(uart_dev_t *u,int num) { printf("UART%d:\n",num); printf("rx_st=0x%X\n",(unsigned int)u->mem_rx_status.val); printf("rx_rd=0x%X\n",(unsigned int)u->mem_rx_status.rd_addr); printf("rx_wr=0x%X\n",(unsigned int)u->mem_rx_status.wr_addr); uint32_t tx_s = u->mem_tx_status.val; printf("tx_st=0x%X\n",tx_s); printf("tx_rd=0x%X\n",(tx_s>>2)&2047); printf("tx_wr=0x%X\n",(tx_s>>13)&2047); } uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; void UARTtest(void * param) { uart_param_config(UART_NUM_1,&uart_config); uart_param_config(UART_NUM_2,&uart_config); uart_driver_install(UART_NUM_1, 256, 0, 0, NULL, 0); uart_driver_install(UART_NUM_2, 256, 0, 0, NULL, 0); uart_set_pin(UART_NUM_1, UART_PIN_NO_CHANGE, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_set_pin(UART_NUM_2, UART_PIN_NO_CHANGE, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); vTaskDelay(1000/portTICK_PERIOD_MS); while (1) { print_uart_st(&UART0,0); print_uart_st(&UART1,1); print_uart_st(&UART2,2); vTaskDelay(2000/portTICK_PERIOD_MS); char s[256]; uart_write_bytes(UART_NUM_1, s, 1); uart_write_bytes(UART_NUM_2, s, 2); if(gets(s)!=NULL) { printf("recived=%s\n",s); } } } void app_main(void) { xTaskCreate(UARTtest, "UARTtest", 4096, NULL, 5, NULL); } 

After launch we get:


UART0:
rx_st = 0x300600
rx_rd = 0x180
rx_wr = 0x180
tx_st = 0xCE058
tx_rd = 0x16
tx_wr = 0x67
UART1:
rx_st = 0x400800
rx_rd = 0x200
rx_wr = 0x200
tx_st = 0x100200
tx_rd = 0x80
tx_wr = 0x80
UART2:
rx_st = 0x500A00
rx_rd = 0x280
rx_wr = 0x280
tx_st = 0x200400
tx_rd = 0x100
tx_wr = 0x100

The output is carried out via UART0, therefore tx_wr and tx_rd are different from 0. According to the obtained results, the memory allocation between the FIFO UART0,1,2 buffers is the following:


AddressesUART
0x00 ... 0x7FUART0 TX_FIFO
0x80 ... 0xFFUART1 TX_FIFO
0x100 ... 0x17FUART2 TX_FIFO
0x180 ... 0x1FFUART0 RX_FIFO
0x200 ... 0x27FUART1 RX_FIFO
0x280 ... 0x2FFUART2 RX_FIFO

In addition, the status registers of the FIFO buffers are 11 bits wide, which means that the memory size allocated for the FIFO buffer = 2Kb is possible. When you set UART0.mem_conf.tx_size = 15 (memory is allocated chunks of 128 bytes long), 1920 bytes will be allocated, and the tx_wr register will transmit to 1919 when transmitted and then proceed through 0. However, the memory is addressed only ml. 10 bits, i.e. real total memory allocated for FIFO buffer = 1Kb.


Total:

  1. The distribution of the total memory allocated by ESP32 to the FIFO UART does not match that given in the technical reference manual 3.5;
  2. Total memory FIFO UART = 1Kb.


')

Source: https://habr.com/ru/post/419955/


All Articles