This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G1507: UART-DMA: Bytes skipped on transmitting when doing RIS register poll for end of transmission event detection instead of using interrupt routine

Part Number: MSPM0G1507
Other Parts Discussed in Thread: SYSCONFIG, MSPM0G3519

Tool/software:

Hi to everyone,

We have developed PCB with MSPM0G1507 MCU embedded on it. We are now in the process of writing the code for it and we have some strange issue with the UART module during message transmitting from the MCU.

First of all, we are using Code Composer Studio 12.8.1 to develop the project, using TI DriverLib and SysConfig as a code base and GCC compiler.

I'll make a short introduction to the problem first. We developed the PCB with intention for it to be a common control board for a lot of various machine projects and therefore a lot of components are used within the MCU. Among other things, we are using 3 UART modules. For this reason our intention is to use almost all DMA channels for various modules. Therefore, we have to use one DMA channel per UART module and reconfigure it when we need to switch between transmitting and receiving data over UART module. Also, to avoid a lot of CPU interrupts, we are trying to poll CPU Raw Interrupt Status registers for each UART module. Specifically for transmitting, we are checking if end of transmission flag is set in CPU_INT.RIS register and this way check if data transmission is complete.

Initially, we saw that this works just fine. After we detect a flag set into CPU_INT.RIS register, we also clear it over ICLR register and we continue with our program, but we just ran into some issue. In one of our projects we have to send machine status periodically (once per second for example) and now we saw that occasionally some bytes are skipped (not sent) on UART line. We are sending data packet of 10 bytes and occasionally 1 byte is skipped (each time it happens it can be different one). This happens usually 5-10% of the times and not with some specific period or order. We did a lot of tests to try to find the cause and we are 99% percent sure that it has something with this RIS register polling approach (and not just with UART module).

The status string is initiated as a char array and just 3 of its characters are modified within program main loop. One of the tests we tried is to disable the code optimization level by the compiler and this just reduced the problem to maybe about 1% of error appearance. Another test we tried is to replace status string variable with static string matching the status string and here actually there are no errors, regardless of code optimization level. So here we thought this has to be connected somehow with variable use.

But then we did the test where we actually ran interrupt routine on end of transmission event and here we actually also don't have errors. But... In our main project we also have ADC module running. There we want to do DMA Ping-Pong concept for ADC and in the main program loop we call a function in which we poll CPU_INT.RIS register of the ADC module and check if DMA_DONE interrupt flag is set, when we switch between ping and pong memory locations. The reason I'm writing about ADC concept is to make a parallel between ADC and UART interrupt flag polling and to make then a point that some bytes happens to be skipped on transmitting over UART module even if we use standard interrupt routine on UART module but we use RIS register polling routine on some other module.

At the end I have to add that DMA_DONE_TX flag is also set when we get end of transmission flag set. Also, we tapped to the UART module transmit line with the data logger and we can confirm that the byte is really skipped (not just like low or high line for the length of that byte).

So our conclusion is that if we use RIS registers polling anywhere in the code for any MCU module, some byte from character array variable gets skipped during UART transmission. If we are sending statis string or we don't use RIS registers polling then we don't have bytes skipped. As per RIS register and debug information, we see that the data is correctly passed to the DMA module and that the DMA module transfers requested amount of bytes to the UART module and that it seems that UART module then does not serialize all the data on the UART transmit line.

So now I'm reaching to you for help with a question, is it possible to successfully make end of transmission detection over RIS register polling instead of regular interrupt routine with some specific MCU configuration or procedure and to do this with all the data sent over the UART bus? I can provide test project if needed.

Thanks in advance and best regards!

Jovan

  • Please refer to DMA_ERR_01 in Errata.

    https://www.ti.com/lit/pdf/slaz742

    Need to confirm:

    1. CPU/MCLK/PD1 running higher frequency that PD0/ULPCLK.

    2. DMA and CPU access PD0 at the same time.

    If both above are confirm from your side, this data loss issue is caused by DMA_ERR_01.

    How to fix:

    1. Set CPU/PD1 and PD0 both running at 40MHz.

    2. CPU and DMA should not be accessing PD0 peripherals at the same time.

    3. Choose UART3 in PD1 to handle the heaviest communication tasks

    4. Do not use CPU poll to read PD0 register.

    There is not much choice, but I can consider to use G1518 instead, there is no DMA_ERR_01  in G1518.

  • Hi Helic,

    thank you very much for your support. You nailed it!

    I can confirm that we have set the CPU/MCLK/PD1 frequency to come from SYSPLLX2 at 80MHz while ULPCLK/PD0 works at 40MHz, and that our code made DMA and CPU to use PD0 at the same time (DMA was moving the data to UART1 and CPU was polling CPU_INT.RIS register of UART1 module, and probably at some point they were accessing PD0 at the same time).

    As per your suggestion, we lowered the CPU/MCLCK/PD1 frequency to 40MHz and this was enough to fix the problem. We are aware that we should not make CPU and DMA use PD0 peripherals at the same time, but in our case, with your suggested changes, this seems not to be a problem anymore. We are using UART3 for the heaviest communication tasks, but we also need to use UART1 or UART0 for some additional, not so heavy communication tasks.

    I will use this message to point to some non-related topic. I don't know if this is an error or what, but I checked the Errata document you pointed me too in your response, and in the DMA_ERR_01 section, as an example, it is written that the "ADC is a PD0 peripheral", but in the MSPM0G1507 datasheet, on the Functional Block Diagram of MSPM0G150x MCU, ADC modules are connected to the PD1. What's correct between these two things?

    Another question is about your suggested MCU replacement. I tried to find some information about this MCU on TI website but there is nothing about this specific model of MCU. I found a datasheet related to a group of MCUs to which this MCU belongs and from this group, only the page about MSPM0G3519 MCU is available, but there is info that this MCU is still not in production. Could you tell me more about these MCUs, are they available yet, or are they going to be available soon?

    Thank you once more for your support!

  • but in the MSPM0G1507 datasheet, on the Functional Block Diagram of MSPM0G150x MCU, ADC modules are connected to the PD1. What's correct between these two things?

    In MSPM0Gx50x device, ADC belong to PD0, allthough ADC has PD1 access port, but most of ADC register's access port are from PD0.

    Could you tell me more about these MCUs, are they available yet, or are they going to be available soon?

    They are going to be avaliable soon.

    And, not all tips from my reply need to take into consideration, only one isOK, depending on your requirement.

  • Thank you once more more for your support and all answered questions!