SDHC - How to properly terminate a Multi-Sector Read

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDHC - How to properly terminate a Multi-Sector Read

938 Views
JHinkle
Senior Contributor I

I've implemented Multi-Sector read - CMD18

I'm not using the AutoCmd12 capability because I could never get it to work so I want to understand and implement it the manual way.

My understanding is that CMD18 is issued and the card starts dumping sectors.

I set SDHC_BLKATTR to the the number of sectors and 512 bytes.

I read 512 byte blocks until I have acquired the number of wanted sectors.

I issue a CMD12 to tell the card to stop sending data.

NOW - my issue - I can't get the SDHC to report data transfer complete.

SDHC_PRSSTAT never has SDHC_PRSSTAT_RTA_MASK,  SDHC_PRSSTAT_DLA_MASK, or SDHC_PRSSTAT_CDIHB_MASK as ZERO --- always showing the data transfer incomplete.

I've tried dummy reads after CMD12 -- that works sometime - but not always.

Can someone please identify the proper code to manually terminate CMD18?

Thanks.

Joe

Labels (1)
0 Kudos
2 Replies

696 Views
JHinkle
Senior Contributor I

Does not work.

I've tried Auto-CMD12 and manually issuing CMD12.

Eitherway - SDHC_PRSSTAT has the following flags set:

CDIHB

RTA - this flag is why CDIHB is set

As long as the CDIHB flag is set - you can not execute another read command - dead!

So, the question is - how to exit CMD18 (multi-block read) with either auto-CMD12 or manual CMD12 and clear the RTA flag in SDHC_PRSSTAT since THAT is what is setting the CDIHB flag.

The manual says the the TRA flag is set as long as data has not been removed from the SDHC controller - which makes sense since the card was sending data as CMD12 was executed.

Turns out - the following works

while(1)
{
         if(SDHC_IRQSTAT & SDHC_IRQSTAT_TC_MASK)
               break;

         if(SDHC_PRSSTAT & SDHC_PRSSTAT_RTA_MASK)
            r = SDHC_DATPORT;
}

Keep reading data from the SDHC as long as the RTA is set and then exit once TC is set.

I've timed the above while loop at 32 usec.

The picture below shows a File read request from FatFS.  Since the data from the card is NOT on sd card sector boundaries, FatFS needs to make a single SD read, followed by a Multi-Block, followed by a single SD read.

The traces shown have the actual read operation active LO.

You can see the first and last single SD read with a multi-block read in the middle.  The second trace shows the while loop stated above which ends the multi-block read.

Hope this helps someone else.  NXP/Freescale does NOT have any documentation in the K64 Reference Manual on how to properly recover from using the Auto-CMD12 feature of the SDHC controller.

SD Read.png

0 Kudos

696 Views
mjbcswitzerland
Specialist V

Joe

I think that this behavior is normal.

In the uTasker project I use the following (comments should make it clear why it escapes the loop):

    while ((SDHC_IRQSTAT & SDHC_IRQSTAT_TC) == 0) {                      // wait for transfer to complete
        if ((SDHC_PRSSTAT & SDHC_PRSSTAT_CCIHB) != 0) {                  // during block reads the data inhibit remains set and we use it to continue
            break;
        }
    }

Regards

Mark

0 Kudos