uSDHC bare metal driver

Showing results for 
Search instead for 
Did you mean: 

uSDHC bare metal driver

Contributor III

I am writing a bare metal uSDHC driver for the iMX6Q based on the SDK version and am having an issue with reading (haven't tried writing yet). I can send commands to the SDHC card and get the proper responses back, so sending commands is not an issue. I believe the code for setting up for the read is also correct including the setup for the adma2. I'm using a CMD17 (read single block) to try to read the MBR (sector 0) of a known good (16GB) SDCARD using a known good OTS board from Boundary Devices. I initialize the read buffer (512 bytes) with the value 0x5a to detect what is read. This is what I get back (buffer starts at 0x104098a0):



The 55 aa at the end is correct and some of the 00 bytes may be as well. Since none of the bytes are 0x5a, 512 bytes were read from somewhere.

Below is what the data should be:



Here are the registers just before sending the command:



Below are the registers after the read (note that INT_STATUS has already been cleared):



In my setup I use three adma2 descriptors. The first one covers from the beginning of the buffer until the start of the first cache line. The read data is read into a separate uncached buffer (in DRAM), then copied into the real buffer. The second one is used to read in the rest of the data down to the last full 32 bytes (last full cache line). This data is read into physical memory, then the virtual memory is invalidated forcing the cache to be re-loaded. The third descriptor is used to read anything left over, and acts like the first one.

 The adma2 descriptors are set up (in uncached DRAM) in this example such that, the buffer was started on a cache line so only two of the descriptor are used (third one not needed). There doesn’t appear to be any descriptor errors (AMDA_ERR_STATUS = 0), and the addresses of the 2 descriptors used are 0x184000C0, and 0x184000C8. The ADMA_SYS_ADDR reg shows 0x184000D0 which shows that the 2 descriptors used were executed. No errors are reported in the INT_STATUS reg.

It has the appearance of some kind of timing issue or data not ready, card can send data fast enough (@25MHz). Both CIHB and CDIHB are checked as you can see in the attached code.

Any ideas where to start looking for errors as to why the data is incorrect?


Labels (1)
Tags (1)
0 Kudos
3 Replies

Contributor III

The board I'm using has been in production several years so I think it's solid. I'm using the same pin settings that the company uses in their linux distro:

PAD_CTL_DSE_38ohm |

I think the problem has to do more with the adma and/or cache issues. In the example above, the first adma descriptor is:

   LEN:   32

   ATT:  0x21

   ADDR:  0x18400080  (uncached DRAM)


The second one is:

   LEN:  480

   ATTR:  0x23

   ADDR:  0x104098C0

I don't flush the descriptors before the read because they are in uncached memory. My system is flat-mapped - virtual address = physical addr.

Right after the read, the 32 bytes in the uncached memory read all zeros (before the read all bytes were 0x5a) so something happened. After the read, the data from uncached memory is copied into the beginning of the data buffer (at 0x104098A0), then a dcache_invalidate is done over the part of the buffer in cached memory (starting at 0x1040_98C0) to update the virtual memory. However the data is already wrong at this point.

Don't know where to look for a solution.


0 Kudos

NXP TechSupport
NXP TechSupport

>The board I'm using has been in production several years so I think it's solid.


in such case one can try the same test in verified (working) software : uboot or

linux. For ADMA there is ERR004536 erratum

Chip Errata for the i.MX 6Dual/6Quad and i.MX 6DualPlus/6QuadPlus - IMX6DQCE


Best regards

0 Kudos

NXP TechSupport
NXP TechSupport

Hi ogj


>Any ideas where to start looking for errors as to why the data is incorrect?


in general, it may be due to signal integrity issues as described for example on


Best regards

0 Kudos