Troubleshooting Missing Data Issue in LPUART_ReceiveEDMA for Multi-Device Communication

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Troubleshooting Missing Data Issue in LPUART_ReceiveEDMA for Multi-Device Communication

Jump to solution
471 Views
zakaria
Contributor II

Hi!

im working on a project using RT1064 the LPUART1 with a Baudrate of 460800

In my project, I'm receiving data from five slave devices. The microcontroller sends a request consisting of 91 bytes, and it checks for available data using the function getUartNumberOfBytesToRead. Upon detection of data, the program jumps to the custom function receiveUart() to read the reply from the slave device. This process is repeated for all five devices

T_ENUM_UART_ERROR receiveUart(const T_ENUM_UART_DEVICE uartDevice, TCHAR* pData, const TUINT32 bufferLength, TINT32* pNumberOfBytesReceived)
  
  {
    T_ENUM_UART_ERROR	error = UART_ERROR_NOT_OPEN;
    
    if ((0 != pNumberOfBytesReceived) && (0 != pData))
    {
      if(tableUartDeviceInfo[uartDevice].SeparateDMAChannels){
        if(UART_DEVICE_MAX > uartDevice && tableUartDeviceInfo[uartDevice].uartOpen){
              
          LPUART_TransferGetReceiveCountEDMA(tableUartDeviceInfo[uartDevice].UartBase,
                                             &tableUartDeviceInfo[uartDevice].pUartDevice->uartEDMAHandle,
                                             pNumberOfBytesReceived));

          
          LPUART_TransferAbortReceiveEDMA(tableUartDeviceInfo[uartDevice].UartBase,
                                          &tableUartDeviceInfo[uartDevice].pUartDevice->uartEDMAHandle);
          
        
          memcpy(pData, tableUartDeviceInfo[uartDevice].pUartDevice->rxBuffer, bufferLength);
          *pNumberOfBytesReceived = bufferLength;
          
          memset(tableUartDeviceInfo[uartDevice].pUartDevice->rxBuffer, 0, UART_INTERNAL_BUFFER_SIZE);
          
          LPUART_ReceiveEDMA(tableUartDeviceInfo[uartDevice].UartBase, 
                             &tableUartDeviceInfo[uartDevice].pUartDevice->uartEDMAHandle,
                             &tableUartDeviceInfo[uartDevice].pUartDevice->receiveXfer);
          
          error = UART_OK;
        }
      }
          else{
            *pNumberOfBytesReceived = 0;
            error = UART_OK;
          }
    }
	else{
      error = UART_ERROR_INVALID_POINTER;
	}
    
    return error;
  }

.

However, during testing with three devices, I observed an issue. The devices are expected to send back 85 bytes of non-zero data as part of a protocol. Although the size of the received data remains correct at 85 bytes, the actual data itself is intermittently being read as zeros or getting cut off.

zakaria_0-1701099757666.png

more context: the three packets of data being sent are repeated every 250ms as shown below

a single paket takes around 2ms

zakaria_1-1701099815942.png

I'm interested in determining whether there's a method to check for data corruption in the receive register of the LPUART. Additionally, I'd like to know if data corruption in the receive register is a common issue. Thanks.

 

 

 

I need assistance in resolving this problem

Labels (1)
Tags (1)
0 Kudos
1 Solution
301 Views
zakaria
Contributor II

Hi @Kan_Li and thanks for your reply!

the buffer whose pointer is assigned to receiveXfer.data (lpuart_transfer_t receiveXfer;) is declared globally

the configuration in the linker file is as follows:

 

 

...
define symbol __ram_vector_table_size__   	=  isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__ 	=  isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;

define symbol m_application_start      		= 0x70040000;

define symbol m_interrupts_start       		= 0x00000000 + m_application_start;
define symbol m_interrupts_end         		= 0x000003FF + m_application_start;

define symbol m_flash_config_start     		= 0x00000400 + m_application_start;
define symbol m_flash_config_end       		= 0x0000040F + m_application_start;

define symbol m_text_start             		= 0x00000410 + m_application_start;
// Flash starts at 0x70000000 with 4MB 		= 0x00400000
define symbol m_text_end               		= 0x703FFFFF - 32; // consider BOOT_APP_FLASH_REGION

define symbol m_interrupts_ram_start   		= 0x20000000;
define symbol m_interrupts_ram_end     		= 0x20000000 + __ram_vector_table_offset__;

// DTCM RAM 0x20000 Bytes 128kB
define symbol m_data_start             		= m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end               		= 0x2001FFFF;

// OCRAM2 0xC0000 Bytes 756kB
define symbol m_data2_start            		= 0x20200000;
define symbol m_data2_end              		= 0x202BFFCF;

/* !! ADDRESSDEFINES in DefinesBootAppFlashAddress.h */
define symbol m_data_BootApp_start     		= 0x202BFFD0;
define symbol m_data_BootApp_end       		= 0x202BFFFF;

define symbol m_data_sdram_start       		= 0x80000000;
define symbol m_data_sdram_end         		= m_data_sdram_start + 0xFFFFF;

define symbol SDRAM_vectors_start	   	= m_data_sdram_start;
export symbol SDRAM_vectors_start;

// unsure if this still fits
define exported symbol m_boot_hdr_conf_start	= 0x70000000;
define symbol m_boot_hdr_ivt_start		    = 0x70001000;
define symbol m_boot_hdr_boot_data_start	= 0x70001020;
define symbol m_boot_hdr_dcd_data_start		= 0x70001030;
...

Well, the problem was solved by using non-blocking standard LPUART functions instead of eDMA ones, however, it would be better if the root cause of the problem behind the inconsistency in eDMA data reception was found out.

 

Best regards

Zakaria

View solution in original post

4 Replies
419 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi @zakaria ,

 

Why do you use the abort function during the reception? Maybe you can use a ring buffer in your application as the demo of evkmimxrt1064_lpuart_edma_rb_transfer.

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
408 Views
zakaria
Contributor II

Hi @Kan_Li and thanks for your reply  
I use the abort to change the state from Busy to Idle for RX.
This exact code runs fine on the Freescale Kinetis K66, but not with this problem on the RT1064 (porting done).

A possible cause for the LPUART behaving so strangely with EDMA could be that it is not using DTCM RAM, which was not selected in the linker file.
Could this be the reason?

Best regards 

Zakaria

 

0 Kudos
394 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi @zakaria ,

 

Normally we use a 128KB ITCM, 128KB DTCM and 256KB OCRAM configuration, what is your configuration?  Was the buffer used by eDMA locating in the RAM? 

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

 

0 Kudos
302 Views
zakaria
Contributor II

Hi @Kan_Li and thanks for your reply!

the buffer whose pointer is assigned to receiveXfer.data (lpuart_transfer_t receiveXfer;) is declared globally

the configuration in the linker file is as follows:

 

 

...
define symbol __ram_vector_table_size__   	=  isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__ 	=  isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;

define symbol m_application_start      		= 0x70040000;

define symbol m_interrupts_start       		= 0x00000000 + m_application_start;
define symbol m_interrupts_end         		= 0x000003FF + m_application_start;

define symbol m_flash_config_start     		= 0x00000400 + m_application_start;
define symbol m_flash_config_end       		= 0x0000040F + m_application_start;

define symbol m_text_start             		= 0x00000410 + m_application_start;
// Flash starts at 0x70000000 with 4MB 		= 0x00400000
define symbol m_text_end               		= 0x703FFFFF - 32; // consider BOOT_APP_FLASH_REGION

define symbol m_interrupts_ram_start   		= 0x20000000;
define symbol m_interrupts_ram_end     		= 0x20000000 + __ram_vector_table_offset__;

// DTCM RAM 0x20000 Bytes 128kB
define symbol m_data_start             		= m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end               		= 0x2001FFFF;

// OCRAM2 0xC0000 Bytes 756kB
define symbol m_data2_start            		= 0x20200000;
define symbol m_data2_end              		= 0x202BFFCF;

/* !! ADDRESSDEFINES in DefinesBootAppFlashAddress.h */
define symbol m_data_BootApp_start     		= 0x202BFFD0;
define symbol m_data_BootApp_end       		= 0x202BFFFF;

define symbol m_data_sdram_start       		= 0x80000000;
define symbol m_data_sdram_end         		= m_data_sdram_start + 0xFFFFF;

define symbol SDRAM_vectors_start	   	= m_data_sdram_start;
export symbol SDRAM_vectors_start;

// unsure if this still fits
define exported symbol m_boot_hdr_conf_start	= 0x70000000;
define symbol m_boot_hdr_ivt_start		    = 0x70001000;
define symbol m_boot_hdr_boot_data_start	= 0x70001020;
define symbol m_boot_hdr_dcd_data_start		= 0x70001030;
...

Well, the problem was solved by using non-blocking standard LPUART functions instead of eDMA ones, however, it would be better if the root cause of the problem behind the inconsistency in eDMA data reception was found out.

 

Best regards

Zakaria