Page 1 of 1

UART receive failure after 120 bytes

Posted: Thu Jun 14, 2018 7:09 am
by mpulis
Hi,

I've set up a UART communications channel using UART 1 on the ESP-WROOM32.

I've set up a thread running which constantly checks fro any UART events from the xQueueReceive() function. If the packet length being received is less or equal to 120 bytes, then no problem is encountered.

If the length of the packet being received exceeds 120 bytes, then I've met some unexpected behavior. The first part of the received packet is truncated at 120 bytes (which I've been led to believe is a hardware-defined limitation) but I'm not always receiving the rest of the message.

So, for example, if I'm being sent a 150 byte packet, I expect to receive a packet of 120 and a packet of 30 bytes. Instead, the second packet is arriving arbitrarily with some missing bytes, most of the times being truncated to 8 bytes. I've attached an example of such below, with 2 packets (120+30) being received correctly while the 3rd is cut off at the 8-byte mark.

My settings for the UART channel are as follows:
Data Bits: 8; Stop Bits: 1; Parity: Even; No HW Flow Ctrl, RX_flow_control_thresh: default

I've tried this out at different baud rates (38400 and 19200) but the same problem persists.

A posted snippet of my code can be found below. I've only copied what I believe to be the relevant section.

Code: Select all

void serialTask(void *pvParameters)
{
	int uart_num = (int) pvParameters;
	uart_event_t event;
	size_t buffered_size;
	uint8_t data=0;
	uint32_t datalen;
	uint8_t i;
	datalen = 0;
	uart_get_buffered_data_len(UARTNUM, &datalen);
	size_t size = 1024;			
   	uint8_t* dtmp = (uint8_t*)malloc(size);
	for (;;) 
	{
	    //Waiting for UART event.
		if (xQueueReceive(UARTqueue, (void *)&event, (portTickType)portMAX_DELAY))
		{
			switch (event.type) 
			{
				case UART_DATA:
					ESP_LOGE(TAG, "serialTask: uart data break\n");
					int len = uart_read_bytes(uart_num, dtmp, event.size, 10);
             				ESP_LOGI(TAG, "uart read: %d", len);
             				break;
			}
		 }
	}		

Re: UART receive failure after 120 bytes

Posted: Mon Apr 08, 2019 7:26 pm
by MartinStej
Hi,
same here. According to the technical reference (pg 336), default HW buffer size is simply 128 Bytes:
UART_RAM.png
UART & RAM layout
UART_RAM.png (27.78 KiB) Viewed 7502 times
I could verify that 128 Bytes is exactly edge where everything works. According to the technical reference it is possible to reorganize it. For example when you're not using TX, you can easily gain another 128 Bytes. When using only 2 UARTs (log + custom), then in theory you can gain another 256 Bytes. I did not study it in detail yet.

Seems to me that `uart_read_bytes()` function handle some kind of buffer abstraction.
Maybe DMA can easily solve this.

Best regards
Martin

Re: UART receive failure after 120 bytes

Posted: Tue Apr 09, 2019 3:35 am
by ESP_Sprite
You may want to play with the low watermark (rxfifo_full_thresh) a bit... it sounds like somehow the rx fifo overflows and isn't emptied soon enough. You can set this watermark lower so the interrupt triggers earlier and can empty the FIFO earlier, reducing the chance of an overflow.

Re: UART receive failure after 120 bytes

Posted: Tue Apr 09, 2019 5:57 pm
by newsettler_AI
Try this:

Code: Select all

if (xQueueReceive(UARTqueue, (void *)&event, (portTickType)portMAX_DELAY))
{
	switch (event.type) 
	{
		case UART_DATA:
			//ESP_LOGE(TAG, "serialTask: uart data break\n");
			int len = uart_read_bytes(uart_num, dtmp, event.size, (portTickType) portMAX_DELAY);
			ESP_LOGI(TAG, "uart read: %d", len);
			break;
		case UART_BREAK:
			ESP_LOGI(TAG, "uart rx break");
			uart_flush_input(YOUR_UART_NUM);
			xQueueReset(UARTqueue);
			break;
	}
}
P.S. Does parity really need to be set "even" ? In 99% its "None" everywhere :)

P.P.S. Have you tried to test with other uart events? What if other event comes ( UART_PARITY_ERR, UART_FRAME_ERR...)?

Re: UART receive failure after 120 bytes

Posted: Mon Jul 17, 2023 8:40 am
by Thejaswi
any example code to read more than 120 bytes from UART at a time