I have an issue where the DMA complete interrupt is triggered but the values in the FIFO are stale. (as in they hold the same value as they did during the previous conversion). I have confirmed with a scope that the values are not valid by probing the input to the ADC.
Additionally I have added some code to memset the fifo back to 0 after reading from it. To confirm that the ADC is really not sampling the same value repeatedly.
My set up is as follows:
All modules are using the core clock at 160Mhz. (ADC0,1,2, DMAMUX,EDMA,BCTU,eMIOS0)
emios0ch0 master bus at 20khz.
emios0ch4 as trigger for BCTU.
BCTU FIFO adc mask 0b111.
read ch0 for adc 0,1,2
read ch1 for adc 0,1,2
read ch4 for adc 0,1,2
watermark set to 8.
in the `Bctu_FIFO1_WatermarkNotification` which is called from the DMA complete interrupt i read from the FIFO.
i have not found a pattern in when this is happening, but it happens very frequently.
I checked the errata and didn't see anything that could point to an issue.
Essentially what I've surmised is that DMA is triggered to read the data but the ADC has either not finished sampling or has not sampled.
@PetrS I've used your example on how to use the BCTU ADC and DMA as a starting point, but instead of PIT i use the eMIOS, but this inherently should not be an issue.
Would appreciate any pointers.
Thanks!
EDIT:
I noticed the screenshot for the ADC config does not accurately represent my current config. It shows that HW averaging is enabled. I don't actually have this enabled, the screenshot is from a branch where I was messing around with different ADC settings to attempt to improve accuracy.)
Solved! Go to Solution.
I finally figured out the issue. I was not setting `MPU_ENABLE`.
So because MPU_ENABLE is not set this `__attribute__((section(".mcal_bss_no_cacheable"))) has no effect.
Hi all,
Hello @frank_yang_1,
thanks for your reply. Yes I did narrow it down to being an issue with the data cache as I noted in my reply here: https://community.nxp.com/t5/S32K/S32K344-eMIOS-triggered-BCTU-ADC-conversion-with-FIFO-and-DMA/m-p/...
I added:
__attribute__((section(".mcal_bss_no_cacheable"))) to the BctuDmaFifo1.
but that does not seem to fix the problem.
What data could be cached that would result in the DMA not updating values.
I can think of three things either the configurations for the DMA itself, the fifo that the results are copied into, or the actual registers that the DMA is reading from.
Since I am using the DMA with the BCTU the BCTU is what actually initializes the DMA channel using this function:
And here is the BctuFifo Config:
And the BctuDmaFifo1 which I have added the attribute to and confirmed it ends up in the right section in the .map file:
what other things can i check to further narrow this down?
Hi
As your mentioned, the BctuDmaFifo1 is already in non-cache area.
Then maybe you could disable all CACHE by calling Cache_Ip_Disable() and remove the macro
If the issue is still exist, then this issue is not related to CACHE. Need to check you project configuration in this case.
BR
Frank
@frank_yang_1 yes I have done an A B test with removing the D_CACHE_ENABLE and I_CACHE_ENABLE.
D_CACHE_ENABLE | I_CACHE_ENABLE | BctuDmaFifo1 has stale/ missing data |
TRUE | TRUE | YES |
TRUE | FALSE | YES |
FALSE | TRUE | NO |
FALSE | FALSE | NO |
This makes it very clear to me that the data cache is what's causing the issue with the DMA.
I looked for `Cache_Ip_Disable()` but this function is not present in my project.
I then checked s32ds and I see that there is a Cache_Ip module, which I don't have included in my project.
I wonder if that is why adding `__attribute__((section(".mcal_bss_no_cacheable")))` has no effect.
I finally figured out the issue. I was not setting `MPU_ENABLE`.
So because MPU_ENABLE is not set this `__attribute__((section(".mcal_bss_no_cacheable"))) has no effect.
@frank_yang_1 @PetrS thanks for your help!
Lastly, one strange thing I observed is that when i include the Cache_ip module it stops working again. Not really sure why that happens.
Here is the commit that when added stops it from working. (even with -D D_CACHE_ENABLE -D MPU_ENABLE and the BctuDmaFifo1 having the `(section(".mcal_bss_no_cacheable")` attribute.
commit 516694f8c52edc100c36b324e5581dba3b9d013c
Author:
Date: Tue Mar 12 10:12:21 2024 -0700
add cache ip to cmake
diff --git a/BPB/boards/CMakeLists.txt b/BPB/boards/CMakeLists.txt
index ab166ef..6bdf396 100644
--- a/BPB/boards/CMakeLists.txt
+++ b/BPB/boards/CMakeLists.txt
@@ -54,6 +54,8 @@ target_sources( ${BSP_NAME} INTERFACE
S32DS_autogen/RTD/src/Axbs_Ip.c
S32DS_autogen/RTD/src/Bctu_Ip_Irq.c
S32DS_autogen/RTD/src/Bctu_Ip.c
+ S32DS_autogen/RTD/src/Cache_Ip_HwAcc_ArmCoreMx.c
+ S32DS_autogen/RTD/src/Cache_Ip.c
S32DS_autogen/RTD/src/CDD_Rm_Ipw.c
S32DS_autogen/RTD/src/CDD_Rm.c
S32DS_autogen/RTD/src/Clock_Ip_Data.c
and here is the config i had set for the cache_ip module: (those changes were added in previous commit from where i add this module to the build path)
+ <instance name="Cache_Ip" uuid="f3c0916d-63cb-47de-b7e0-871fe15778e6" type="Cache_Ip" type_id="Cache_Ip" mode="general" enabled="true" comment="" custom_name_enabled="false" editing_lock="false">
+ <config_set name="Cache_Ip">
+ <setting name="Name" value="Cache"/>
+ <struct name="ConfigTimeSupport">
+ <setting name="POST_BUILD_VARIANT_USED" value="false"/>
+ <setting name="IMPLEMENTATION_CONFIG_VARIANT" value="VARIANT-POST-BUILD"/>
+ </struct>
+ <struct name="MclGeneral">
+ <setting name="Name" value="MclGeneral"/>
+ <setting name="MclEnableUserModeSupport" value="false"/>
+ <struct name="MclCache">
+ <setting name="Name" value="MclCache"/>
+ <setting name="MclEnableCache" value="true"/>
+ <setting name="MclEnableCacheDevErrorDetect" value="false"/>
+ </struct>
+ </struct>
+ </config_set>
+ </instance>
Hi, sorry for forgetting to check the latest post
In this situation, you could check the MPU register for region configuration.
Then you could check the area of BctuDmaFifo1 address belong to and its policy.
BR
Frank.
Confirmed that there is no DMA error bit set and no DMA error interrupt triggered.
This indicates that the DMA is actually not copying data, but reporting that it has.
Hi,
if there is no DMA transfer, check the path for enabling DMA request, through BCTU, DMAMUX, DMA.
If DMA was triggered and perform transfer, but destination is not updated, check if this does not relate to data cache.
For a configuration; ADC clock should not be higher than 80Mhz, so use prescaler.
BR, Petr
Hey @PetrS
I tested the suggestion for setting the AD_CLK to 80Mhz instead of 160Mhz.
I confirmed that the ADC data is less noisy and more accurate than before as a result of this change, but it does not fix the DMA stale values issue.
Which lead me to think that it might be a data caching issue with the DMA. I found this question: https://community.nxp.com/t5/S32K/S32K3/m-p/1414177 and attempted to incorporate the changes suggested in the solution. But it's different enough where I'm not quite sure what changes I should be making.
I added:
@PetrS I found what you are referencing.
My ADC MODULE_CLK is set to 160Mhz as it consumes CORE_CLK which is at 160Mhz. And because my prescaler is 1 s32ds which actually means 0 not 1 so the AD_CLK is also 160Mhz, which is in violation of the requirement for the AD_CLK as you mentioned. I found where this is referenced in the reference manual.
I will give this a try and report back. What is strange is that I have been using 160Mhz as the ad_clk for a while and it has been working.
I changed the way i triggered my ADC reads from using emios triggering BCTU to read conversion list to fifo.
And instead I use emios ch0 reload event to trigger inject conversion for adc0,1,2 and then read the data from the adc injected conversion complete of one of the adcs to read values from all ADCs.
I confirmed that this works and that the ADC is producing sensible values.
@PetrS why should the ADC clock not be higher than 80Mhz? I am using s32k344 in the reference manual it states that the max clock frequency for the module is 160Mhz. (see attached screenshot from reference manual). Or is this is BCTU controlling ADC specific requirement. i looked through the reference manual and can't find anything that requires ADC max clock to be 80Mhz.
As for the DMA.
There is a transfer, but the destination is not updated.
How can i check whether this relates to data cache?