Problem with UART DMA transfer on the receive line

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

Problem with UART DMA transfer on the receive line

1,680 Views
andrihartmann
Contributor I

I am currently running into the problem that the UART DMA for receiving bytes sometimes does not receive any bytes even though they are received by the hardware.

We are using the microcontroller MK66FN2M0VLQ18 with all the drivers from SDK_2.3.0_FRDM-K66F. Our code follows the code of the K66F evaluation board from the driver examples called edma_transfer. The UART interface is used to communicate with a display module where it acts as a "serial slave".

We also have a bootloader in place that is called upon start. If new firmware is present to the bootloader, it updates the Flash of the microcontroller and informs the user during the update process with the display module by showing an image and some text. This is done by the simple UARTBlocking write and read commands because the bootloader is not time critical. As soon as the bootloader finishes updating the application, it jumps to the application. Inside the application we then use the UART EDMA transfer because we have a time critical system and the functions should be all non-blocking.

In the initialization of the display module a startup image is shown on the screen with UART commands. Every command send to the display module is acknowledged by the display module with the byte pattern 0x06. 

Now it sometimes happens that the updating process gets stuck because the microcontroller does not receive the ACK from the screen and the application stops. After inspection I found out, that the signals on the UART line appear as expected (measuring with an oscilloscope) but they are not received by the DMA. If I try to find the problem inside the driver, I see that the DMA receive interrupt is triggered but the buffer to store the receive variables is filled with zero. Afterwards, I even try to abort the current transfer and resend the commands, but it still does not fill the buffer. I also tried to reset the communication port by reinitializing again:

We only run into the problem when we call the UARTBlocking read and write functions during the bootloader step and the problem also does not occur consistently (maybe every third time). I transferred the bootloader part that communicates with the display module to the application to get rid of all the unknown parameters from the bootloader. This also allows me to debug the code better. The problem still occurs as described before so it has to do something with calling the UART Blocking functions and afterwards the UART EDMA functions.

Because I do not want to touch the drivers from the SDK and expect them to be working I am asking for your help here.

Has someone had problems with the DMA RX line before and can maybe help me? Or is this problem known to NXP?

Thank you for your time and I am looking forward to hear from you.

Tags (3)
0 Kudos
6 Replies

1,518 Views
Sabina_Bruce
NXP Employee
NXP Employee

Hello Andri,

Hope you are doing well.

I'd like to make sure I am understanding the issue correctly before jumping in to check any sections of the code. 

From what I understood, the issue sometimes presents itself but only when the READBLOCKING function is used in bootloader. Have you tried Read_NonBlocking function in bootloader and the problem does not present itself?

Also, could you try updating your drivers to the latest version 2.7.0 and see if the problem persists?

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,520 Views
andrihartmann
Contributor I

To follow up on my last response.

In the meantime I tried the drivers from SDK 2.5.0 and 2.7.0. Unfortunately it did not solve the issue and we still get the error.

Is there any news from your side? I do not want to look for the problems in the driver and I do not even know if I would be able to find it (considering if I had the time to do so).

Thank you for your answer in advance.

Best regards,

Andri Hartmann

0 Kudos

1,520 Views
Sabina_Bruce
NXP Employee
NXP Employee

Hello Andri,

Hope you are doing well.

I've checked with detail the example that you are referring to edma_transfer. Some things that may be necessary to check is the implementation you have in your application. The drivers that are used in the example and specifically the UART_ReadBlocking is not called on its own. It is encapsulated by other functions that prevent errors and check additional flags, etc. In this example GETCHAR is using the UART_ReadBlocking at a very low level. Higher up in the application where you might find the GETCHAR debug functions executing you may observe that there are some mutex that protect this read blocking function. 

I'd recommend to check in your application if there is any way to protect the UART_ReadBlocking to avoid unexpected behavior or make a possible test with the NonBlocking function. I understand you cannot change the boot loader, but I recommend to make a test at least outside of your boot loader to check if your problem persists. 

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

1,520 Views
andrihartmann
Contributor I

Hi Sabine

Thank you for your answer. Unfortunately it is not really what I have asked. I understand that there is some mutex functionality that has to be considered when there is multiple access in parallel possible. This does not apply for us because the communication happens sequentially. Also forget about the bootloader. I moved the uart transfers into one application as visible in the code snippet I attach to this reply.

Sequential steps of application:

  1. setting up uart0 for blocking transfer
  2. blocking read and writes
  3. deinitializing uart0
  4. reinitializing uart0 for edma transfer
  5. non-blocking read and writes

Description of the problem on step 5: When the microcontroller sends the command 0xFF, 0x03 to the display, it will get the display response consisting of an acknowledge byte (0x06) and a 16 bit number split into two bytes. As seen in the attached document this can be e.g. 0x06, 0x45, 0xFE. Even though the bytes are present on the receive line, it can happen that the data that is then being received by the UART DMA controller is zero and not what is present on the line. The interrupt itself to notify the DMA that there is data received over UART is always triggered. If I resend the command 3 or 4 times it can be that one of the received bytes shows up on the memory location for receive but it is not on the right index. Therefore I would see that there is some problem memory problem I miss which only happens when the UART is used for with the blocking transfer driver functions and then with the non-blocking DMA transfer functions.

I hope this describes my problem better.

Thank you for your time.

Best regards,

Andri

0 Kudos

1,520 Views
Sabina_Bruce
NXP Employee
NXP Employee

Hope you are doing well.

I just wanted to provide an update, I am still working on your case attempting to reproduce the same behavior you are experiencing.

I will update you when I have further information for you.

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

1,519 Views
andrihartmann
Contributor I

Hi Sabina
Thank you for your answer.

I can confirm, that it only happens when the bootloader calls the UART_ReadBlocking function. As a test I added all the code related to the display module from the booloader code to our application code and I could replicate the same behavior.

Unfortunately we cannot change the bootloader, so the Blocking read will stay in there. In the meantime I will update the drivers to 2.7.0 and try again.

Best regards,

Andri

0 Kudos