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.

TMS570LC4357-EP: MibADC + DMA related issues

Part Number: TMS570LC4357-EP
Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN

Dear ti team

When reading data via DMA and writing it to the memory buffer, I encountered the following situation:

During debug execution, data was visible in the buffer, but paused data showed as zero.

I eventually found the forum post I referenced, but still couldn't figure out how to change the cache type to direct-write mode. Later, I disabled the cache and discovered data was present in the buffer.

The configuration is as follows:

image.png

1. How do I change the cache type to write through? Will there be any adverse effects after the change?

2. Is the common usage of ADC continuous conversion mode + group memory threshold interrupt or periodic trigger source (RTI/ePWM) +DMA?

3. Is it necessary to collect data 10 times with DMA and average the data of each channel?(Is the data collected in a single session sufficiently accurate?

4. Is there only three threshold interrupts in MibADC1? (Threshold interrupt for each channel is not possible?)

Finally attached is my code, looking forward to reply, thank you.

HL_sys_main.c 

  • Hi Shuo,

    During debug execution, data was visible in the buffer, but paused data showed as zero.
    1. How do I change the cache type to write through? Will there be any adverse effects after the change?

    This is clearly cache-coherance issue.

    Refer below thread once:

    (+) TMDX570LC43HDK: DMA can't read some data correctly(trying to sci tx) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    2. Is the common usage of ADC continuous conversion mode + group memory threshold interrupt or periodic trigger source (RTI/ePWM) +DMA?

    Use periodic trigger (RTI or ePWM) + DMA if you need synchronized, deterministic sampling

    Use continuous mode + threshold interrupt, if you don't need synchronization.

    3. Is it necessary to collect data 10 times with DMA and average the data of each channel?(Is the data collected in a single session sufficiently accurate?
    • Start with single samples and measure your noise levels
    • Implement averaging (4-16 samples) if noise is problematic
    • 10 samples is reasonable but not mandatory - optimize based on your requirements
    4. Is there only three threshold interrupts in MibADC1? (Threshold interrupt for each channel is not possible?)

    No, per channel threshold is not available. Only group level threshold is available, i mean we need to assign channels to the group and can provide threshold to the corresponding group.

    --
    Thanks & regards,
    Jagadish.

  • Hi,Gundavarapu,

    Thank you for your reply.

    1. I will attempt to resolve the cache consistency issue using the link you provided.

    2. If I monitor the voltage and current across 25 channels of the Group, driven by RTI, and send a DMA request for 10 data points each time, with the MCU averaging the 10 data points across all 25 channels, is this approach reasonable? Is there an issue with my code? (Please see HL_sys_main.c)

    3. Are you referring to the three threshold interrupts shown in the diagram below when you mention that only group-level thresholds are supported? Are the interrupts for EVENT, Group1, and Group2? I want to use 25 channels for Group1, setting a threshold for each channel. If the value falls below or exceeds that threshold, an action (such as power disconnection) should be triggered.

  • 2. If I monitor the voltage and current across 25 channels of the Group, driven by RTI, and send a DMA request for 10 data points each time, with the MCU averaging the 10 data points across all 25 channels, is this approach reasonable? Is there an issue with my code? (Please see HL_sys_main.c)

    Yes, this approach is generally reasonable. However, make sure this:

    This device has internal FIFO of max 64 words. So, maybe you can keep the 50 words as FIFO for your group. So, after two RTI interrupts the FIFO threshold might reach right, that will trigger the DMA transfer, so DMA will transfer these converted 50 words from FIFO to RAM. Maybe it is not possible to move 10 data points of data in single shot.

    3. Are you referring to the three threshold interrupts shown in the diagram below when you mention that only group-level thresholds are supported? Are the interrupts for EVENT, Group1, and Group2? I want to use 25 channels for Group1, setting a threshold for each channel. If the value falls below or exceeds that threshold, an action (such as power disconnection) should be triggered.

    Not Magnitude threshold interrupt, it is Group threshold interrupt. Refer below section of TRM:

    --
    Thanks & regards,
    Jagadish.

  • Hi,Gundavarapu,

    As shown in the figure, you can see that I used 13 channels, each channel acquired 10 times, and then the average was calculated for each channel. This should be completed within a single RTI interrupt, right? Currently, the program appears to be running normally, and the results match expectations. I'm a bit unclear on your point—if I use 25 channels later, would that exceed the FIFO size?

    Additionally, if the DMA plus average value calculation method is used, there is no need to consider the use of threshold interrupts, so we won't dwell on this issue for now.

  • Hi Shuo Liu,

    Apologies for the delayed response!

    As shown in the figure, you can see that I used 13 channels, each channel acquired 10 times, and then the average was calculated for each channel. This should be completed within a single RTI interrupt, right? Currently, the program appears to be running normally, and the results match expectations. I'm a bit unclear on your point—if I use 25 channels later, would that exceed the FIFO size?

    Your configuration seems to be fine and there is not issue.

    Even with 25 channels also you won't get any issues. Please proceed with this and let me know if you face any issues in future.

    --
    Thanks & regards,
    Jagadish.

  • Hi,Gundavarapu,

    Thank you very much for your reply.

    1. What impact would changing the cache to a write-through cache have?Will there be a significant loss in performance?

    2. Can the issue be resolved by calling the _dCacheInvalidate_() function within the DMA interrupt handler? Or invalidate data by scope.

    3. Must continuous mode trigger an interrupt before data can be acquired?

  • Hi Shuo,

    1. What impact would changing the cache to a write-through cache have?Will there be a significant loss in performance?
    • Write-through cache forces every write operation to go through to main memory immediately, eliminating the benefit of write buffering
    • The performance degradation will be most significant for write-intensive operations
    • Read operations should not be significantly affected
    • For DMA-based applications, write-through can actually improve system reliability by ensuring cache coherency
    2. Can the issue be resolved by calling the _dCacheInvalidate_() function within the DMA interrupt handler? Or invalidate data by scope.

    Yes, calling cache invalidate functions in the DMA interrupt handler is a valid and commonly used solution for maintaining cache coherency with DMA transfers.

    Scope-based invalidation is more efficient: Instead of invalidating the entire cache with _dCacheInvalidate_(), you should invalidate only the specific memory range where DMA wrote data. This minimizes performance impact.

    3. Must continuous mode trigger an interrupt before data can be acquired?

    No, continuous ADC mode does NOT require an interrupt to trigger before DMA can acquire data. The ADC hardware automatically generates DMA request signals upon each conversion completion, and the DMA controller responds to these hardware triggers independently of the CPU. The BTC interrupt in your code is only used to notify the CPU when the entire buffer is full and ready for processing, not to enable the DMA transfers themselves.

    --
    Thanks & regards,
    Jagadish.

  • Hi,Gundavarapu,

    Thank you for your prompt reply.

    In that case, the optimal solution would be to disable the specific memory range where DMA writes data.

    However, I discovered that in HL_sys_core.h, only the definition of the _dCacheInvalidate_() function exists, but there is no function to invalidate data within a specified range.

    I couldn't find any relevant definitions in the SL_TMS570LC4357_NoOS project either. How can I disable DMA from writing to a specific memory range?

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

    Regarding the third question I asked earlier, I may not have expressed myself clearly.

    I found in the forum that it is not recommended to use DMA and continuous mode together, as it may cause timing issues.

    Is it feasible to use continuous mode without any interrupts (conversion-end interrupt and threshold interrupt), simply fetching data from the ADC RAM at fixed intervals? Personally, I find this approach rather unreasonable.

  • Hi Shuo,

    However, I discovered that in HL_sys_core.h, only the definition of the _dCacheInvalidate_() function exists, but there is no function to invalidate data within a specified range.

    I couldn't find any relevant definitions in the SL_TMS570LC4357_NoOS project either. How can I disable DMA from writing to a specific memory range?

    You're correct that the HALCoGen-generated HL_sys_core.h only provides _dCacheInvalidate_() which invalidates the entire data cache. Unfortunately, HALCoGen does not provide a built-in function for range-based cache invalidation.

    So maybe we need to use _dCacheInvalidate_ only, better to invalidate entire cache.

    Regarding the third question I asked earlier, I may not have expressed myself clearly.

    I found in the forum that it is not recommended to use DMA and continuous mode together, as it may cause timing issues.

    Is it feasible to use continuous mode without any interrupts (conversion-end interrupt and threshold interrupt), simply fetching data from the ADC RAM at fixed intervals? Personally, I find this approach rather unreasonable.

    Yes, you are correct this might cause timing issues.

    But on DMA side we can take care of one thing, we can off the Auto initialization.

    If we off this DMA Auto initialization, then automatic transfer of next block will not take place after previous block transfer. We need to call this below highlighted DMA Hardware trigger again.

    If didn't call this API, then there won't be any further transfers will happen to DMA and won't be any overwrites into memory.

    You can use this method.

    However, i don't know how your conversion end interrupt method will be useful here, because conversion end interrupt will only assure that ADC conversion completed but it doesn't mean DMA transfer completed. So maybe fetching data based on this interrupt is not an ideal method, i think. But test it in practical and if it is working for you then you might use this method as well.

    Here is my tested code:
    DMA_Memory_to_Memory_Transfer_RM57_Hardware_Trigger_AutoInit_Off.zip

    Here i am using Hardware triggering for DMA with N2HET1[23] which is J4 on controller.

    --

    Thanks & regards,
    Jagadish.

  • Hi,Gundavarapu,

    1. I saw someone using the `_dcacheInvalidateRange_()` and `_dcacheCleanRange_()` functions under FreeRTOS in the forum. Are these functions only available under FreeRTOS?

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/640825/tms570lc4357-how-to-force-the-cached-data-back-into-sram/2365336?tisearch=e2e-sitesearch&keymatch=_dCacheInvalidateRange_#

    2. Disable DMA auto-initialization and call the `dmaSetChEnable` function within the interrupt handler. This should be one way to avoid timing issues.

    But what I really want to ask is: Is it advisable to use only continuous mode (no interrupts, no DMA) and then read the converted data from the ADC's RAM at fixed intervals?I find this rather unreasonable.

  • HI Shuo,

    HALCoGen is not providing this routine, i verified on all my project i didn't see any API with this name on HALCoGen generated.

    So, i think this customer implemented on his own.

    But what I really want to ask is: Is it advisable to use only continuous mode (no interrupts, no DMA) and then read the converted data from the ADC's RAM at fixed intervals?I find this rather unreasonable.

    Yes, i think you can use this method. I don't see any issues in implementing it.

    The only thing to remember is that no guarantee of data coherence. For example, sometimes you might see partial updated data i mean half of the buffer might have newly converted data and other part of the buffer might have old, converted data.

    Sometimes entire buffer might be overwritten with some new data, and you might lose one complete cycle of conversion data.

    These things can happen, if you are okay with these things then there won't be any issues in implementing this method.

    --
    Thanks & regards,
    Jagadish.