High-speed SDHC = LDD_SDHC_ERR_TIMEOUT

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

High-speed SDHC = LDD_SDHC_ERR_TIMEOUT

2,391 Views
anguel
Contributor V

Hi!

I am referring to the TWR-K70 SDHC processor expert demo project found in C:\Freescale\CW MCU v10.4\MCU\CodeWarrior_Examples\Processor_Expert\Kinetis\TWR-K70FN1M\SDHC. I have also adapted the project to my Kwikstik (K40). The demo project writes and then reads fine at 25 MHz on Kwikstik (K40) and at 15 MHz on TWR-K70, these MHz values are dictated by the main clocks of the boards.

My SD card is reported as high speed so I tried to go high speed, i.e. to 50 MHz on Kwikstik and 30 MHz on TWR-K70 by using the SDHC_SelectBusClock() method as described in the SDHC LDD component help. This method seems to setup the device to high speed without errors. But then I get “ERROR Command or data timeout” (LDD_SDHC_ERR_TIMEOUT) which is returned by the SDHC_GetError() method called in the SD_Wait() method which is called right after SDHC_TransferBlocks() which is called by SD_TransferBlock() with WRITE parameter called by SD_WriteBlockPart().

The error code is set in the following code in SDHC.c:

  /* Map host error flags to component error codes */

  if ((Flags & (SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT | SDHC_PDD_DATA_TIMEOUT_ERROR_INT)) ||

      ((Flags & SDHC_PDD_AUTO_CMD12_ERROR_INT) && (AutoCMD12ErrorFlags & SDHC_PDD_AUTO_CMD12_TIMEOUT_ERROR))) {

    Error = LDD_SDHC_ERR_TIMEOUT;

The SDHC_IRQSTAT bits that get set when the error occurs are bit 16 = CTOE (Command Timeout Error) and bit 0 = CC (Command Complete). According to the Kinetis K40 guide and some guessing this may identify a CMD line conflict which I expect to be caused by the higher bus speed.

I also found out that if I run the writing part of the demo in a loop at 30 MHz on TWR-K70 the error does not occur each time, but in most cases it does. If I run the demo at 50 MHz on the Kwikstik the error always occurs. The strange thing is that although this error occurs, the test data (I vary this inside my loop) can be successfully written to and then read from the SD card as far as I can see.

The only hint I found was that the code comments in the SDHC LDD help say that FAST slew rate should be set on all SDHC pins. It turns out that fast slew rate seems to be the default setting for Kinetis, I also set it through the Init_GPIO component. Unfortunately, this did not help at all.

Has someone achieved speeds higher than 25 MHz with Kinetis MCUs? I don't know where to look for the cause of the timeout error. Any hints are welcome!

Regards,

Anguel

Labels (1)
Tags (3)
9 Replies

1,408 Views
anguel
Contributor V

UPDATE: I have now observed the same annoying timeout errors at 12.5 MHz, in this case I always have 9 or 12 such errors in 1000 blocks written. The errors always occur in 3 successive blocks but these blocks have random numbers (e.g. in 216, 217, 218 but the next time in 104, 105, 106). I will test with a different card these days. The strange thing is that the blocks seem to be written ok although the error is reported.

Errors in 1000 single block writes:

~ 7 errors @ 1 MHz

~ 500 errors @ 25 MHz

1000 errors @ 50 MHz

0 Kudos

1,408 Views
anguel
Contributor V

Tested with a brand new Class 10 SDHC card from a different Manufacturer. The same problem occurs, so I expect that the problem is either Freescale's SDHC controller or their driver :-(

0 Kudos

1,408 Views
anguel
Contributor V

I looked more thoroughly at the error cause. According to the Flags read by GetCommandError() in SDHC.c it looks like in case of the timeout error bit 20 and bit 1 of IRQSTAT are set.

Bit 20 = DTOE = Data Timeout Error

Bit 1 = Transfer Complete

Now, if I look at the Kinetis reference manual (K40P144M100SF2RM.pdf in my case), there is "Table 49-20. SDHC status for data timeout error/transfer complete bit combinations" which states that whenever Transfer Complete bit AND Data Timeout Error bit are set the transfer is complete.

Therefore, it seems that the code in GetCommandError() in SDHC.c is NOT handling this combination correctly, i.e. it should NOT set an error when this combination of bits occurs but it does.

I hope that Freescale will comment this ASAP.

Anguel

0 Kudos

1,408 Views
LadislavVadkerti
NXP Employee
NXP Employee

Hello,

try to set the data timeout period to a higher value in the "Data timeout exponent" property. The SDHC will wait 2^data_timeout_exp SD bus clock ticks before it sets the data timeout flag.

Best regards,

Ladislav Vadkerti

Freescale Processor Expert Team

1,410 Views
anguel
Contributor V

Ladislav,

Thank you for the fast reply but I think that would be only a workaround and does not solve the problem correctly. The correct solution according to the MCU reference manual would be to change the code of GetCommandError() in SDHC.c:

FROM:

  /* Map host error flags to component error codes */

  if ((Flags & (SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT | SDHC_PDD_DATA_TIMEOUT_ERROR_INT)) ||

      ((Flags & SDHC_PDD_AUTO_CMD12_ERROR_INT) && (AutoCMD12ErrorFlags & SDHC_PDD_AUTO_CMD12_TIMEOUT_ERROR))) {

    Error = LDD_SDHC_ERR_TIMEOUT;


TO:

  /* Map host error flags to component error codes */

  if ((Flags & (SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT)) ||

      ((Flags & (SDHC_PDD_DATA_TIMEOUT_ERROR_INT) && !(Flags | SDHC_PDD_TRANSFER_COMPLETE_INT))) ||

      ((Flags & SDHC_PDD_AUTO_CMD12_ERROR_INT) && (AutoCMD12ErrorFlags & SDHC_PDD_AUTO_CMD12_TIMEOUT_ERROR))) {

    Error = LDD_SDHC_ERR_TIMEOUT;

I hope that I have the correct logic. Could you please let your developers check this???

Thank you,

Anguel

0 Kudos

1,410 Views
LadislavVadkerti
NXP Employee
NXP Employee

No, that is not a workaround. You must set the data timeout according to the card data reading initialization times (you can find them in the SD specs). Ignoring the timeout would be a workaround, because if you have the flag set, it means that the transfer completion is near its timeout limit.

Ladislav Vadkerti

Freescale Processor Expert Team

0 Kudos

1,410 Views
anguel
Contributor V

Sorry but I still do not understand! I am discussing this with my colleagues and they don't understand either. This timeout is because the card does not reply in time, by changing the exponent we will just ignore a timeout that occurred. What is the purpose of this???

And how can I calculate the correct timeout exponent for the card? I also tested with a class 10 SDHC card that should be fast enough to complete in time if the default exponent of 17 is some kind of standard value. And this fast card also gives errors, even at a low MHz clock.


0 Kudos

1,410 Views
LadislavVadkerti
NXP Employee
NXP Employee

There is an asynchronous part of the data access time (see the CSD register's TAAC field in the SD spec.), which is needed for the data transfer initialization on the card (it may be tens of milliseconds, meanwhile the data timeout for exponent 17 is approx. 2.6 ms at 50 MHz SD bus clock [2^17 x 0.02 us]). The card speed is valid only for sequential read of multiple blocks.

Ladislav Vadkerti

Freescale Processor Expert Team

1,410 Views
anguel
Contributor V

I see. Manufacturers probably do not specify such times. So will I just have to increase the exponent until I don't have timeouts? I need to write sampled values to single blocks for now.

0 Kudos