UART receive failure after 120 bytes

mpulis
Posts: 21
Joined: Mon Aug 07, 2017 7:53 am

UART receive failure after 120 bytes

Postby mpulis » Thu Jun 14, 2018 7:09 am

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;
			}
		 }
	}		
Attachments
Serial.PNG
Serial.PNG (19.84 KiB) Viewed 826 times

MartinStej
Posts: 1
Joined: Mon Apr 08, 2019 7:09 pm

Re: UART receive failure after 120 bytes

Postby MartinStej » Mon Apr 08, 2019 7:26 pm

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 416 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

ESP_Sprite
Posts: 2721
Joined: Thu Nov 26, 2015 4:08 am

Re: UART receive failure after 120 bytes

Postby ESP_Sprite » Tue Apr 09, 2019 3:35 am

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.

newsettler_AI
Posts: 94
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART receive failure after 120 bytes

Postby newsettler_AI » Tue Apr 09, 2019 5:57 pm

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...)?

Who is online

Users browsing this forum: Baidu [Spider] and 21 guests