My environment: MQX 4.1, MFS, K70FX, eMMC, DDR
I'm writing a small ascii file to MFS installed over the SD card driver. When I try to display the contents of the file (using the "type" shell command) I can see corrupted data sometimes. Not all the time. I have noticed that if I create multiple files and then "type" them from the shell, sometimes the data printed to the shell is good and other times the data is corrupted. I have tracked the corruption to the esdhc driver. I am seeing data corruption when the ADMA engine transfers data to DDR. After the transfer is complete the buffer in DDR contains some new data mixed with old data. For example, if I "type" file1.txt and then "type" file2.txt, the data printed to the screen contains file1.txt data intermixed with file2.txt data.
I don't understand the ESDHC_IS_HANDLING_CACHE code. What is the purpose of head, body, and tail? It looks like ESDHC_IS_HANDLING_CACHE is not meant to be optional. It's forced true in esdhc_prv.h.
I'm also wondering if the problem may be related to the clock domains between the eMMC and DDR. I've run pattern tests, walking ones/zeros over the address range of DDR with no errors. My eMMC clock is running at approximately 750kHz and the DDR clock is 120MHz. I think the ADMA is sitting in the middle transferring data from SDHC_DATPORT to DDR.
Has anyone seen any issues like this before?
Thanks.
Dear pbanta,
ESDHC_IS_HANDLING_CACHE defaults to 1 for platforms which feature data cache. This macro is not a user option - it has to correspond with cache setting (enabled/disabled). Please do not change it unless you are absolutely sure that you know what you are doing (e.g. you have the data cache intentionally disabled or so).
K70 features data cache and I suppose that you have it enabled so PSP_HAS_DATA_CACHE should be 1. Could you, please, verify that it is so?
Best regards, Pavel
HI Pavel,
Yes, I can verify that PSP_HAS_DATA_CACHE is set to 1 in kinetis.h. And from esdhc_prv.h:
#ifndef ESDHC_IS_HANDLING_CACHE
#define ESDHC_IS_HANDLING_CACHE PSP_HAS_DATA_CACHE
#endif
Thanks for the help,
Paul
I've been looking at the sdcard driver in more detail and stepping through the code in the debugger. @pbanta asked about the usage of the head, body, and tail dma transfer buffers. This section of code looks unusual to me as well.
When executed in the debugger the number of bytes to read (variable n) passed into _eshdc_read() is always 512. The 'head' buffer descriptor always ends up being 32 bytes, the 'body' descriptor is 480 bytes, and the 'tail' descriptor is not used. Also interesting to note is that the head buffer descriptor transfers data from a different area of memory than the body buffer descriptor. The head uses 32 bytes of memory allocated during initialization of the sdcard driver in _eshdc_install(), whereas the body buffer descriptor uses memory passed into _eshdc_read() via the data_ptr variable.
I've also referenced the SD host controller spec PDF document located on the sdcard.org website. It provides specific details of the ADMA transfer process, but did not shed any light on why the MQX driver is designed the way that it is.
Does anyone understand why the adma buffer transfer was designed this way?
Hi Ken,
Sorry for the delay in replying. I got busy with other portions of the firmware and forgot about this because I worked around the problem. I got rid of DMA in the driver. Yes, it's slower, but it is reliable and my application doesn't need high speed access to the eMMC and I have "bigger fish to fry". I would like to see this issue addressed and fixed because I would prefer not to have custom modifications in my peripheral IO drivers. I ended up using the Cloning Wizard to export an MQX tree and I made all my changes in the exported tree.
Paul
I know this is dredging up an old thread, but how exactly were you able to get rid of the DMA? Looking at the reference manual (VFxxx Controller Reference Manual Rev 0 figure 10-41) it appears the only way to output data from the SDHC peripheral is via DMA. Thanks
Hi everyone,
I don't understand the head, body, tail ADMA handling in the driver either. Maybe someone could give us some hints?
I am working with MQX 4.1.2 on the Vybrid M4. I also see problems with with SD-card driver (_esdhc_read) in combination with active caches and cached memory. (but I think in my case it has nothing to do with DDR3 or interrupts)
I think it is problem regarding the cache handling in the driver and the cache controller.
In my case I found a workaround in my application to have data consistency after a read access:
flush the data after buffer_read re-init -> then start the read access
(open file in filesystem, loop: write access, CRC handling, etc.)
...
memset(buffer_read, 0, accessSize );
//workaround to to fix problem in case of application uses cached memory
_DCACHE_FLUSH_MBYTES(buffer_read, accessSize );
returnSize = read(fd, buffer_read, accessSize );
...
Could anyone try or approve this?
BR Tobi
Hi pbanta,
Have you had any success in resolving your issue with the sdcard? I ask because I've had a similar problem which I reported in another forum post (see here).
I observed that corruption seems to occur when interrupts occur while data is being copied to/from the sdcard dma buffer. As a test I modified the sdcard driver to disable interrupts while the data is copied and it has significantly improved my problem. I provided details on what I changed in the other post hoping that Freescale will comment.
Perhaps you could try making the same change and report whether it helps your particular issue?
Thanks,
-Ken
We know about sporadic problem with DDR under MQX4.1.
TWR-K70F120M BSP configures incorrect DDR2 clock frequency. By default it is 120 MHz. JEDEC specifications minimum requires 125 MHz. Maximum allowed by K70 chip is 150 MHz.
There is Freescale MQX RTOS 4.1.0.1 Patch which apply fix for this issue – increase DDR clock.
https://www.freescale.com/webapp/sps/download/license.jsp?colCode=FSLMQXOS_4_1_0_1_PATCH
Could you please try applying this patch and testing it again?
If this doesn’t help, could you please share here code which you use for writing your files – that we can reproduce it on our side under the same conditions?
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I had PLL1 set to 150MHz when I discovered the problem. According to the K70 reference manual PLL1 is used to provide clock to the DDR controller. I lowered PLL1 to 120MHz and I still saw the problem. I will try 125MHz and let you know the results.
Thanks,
Paul