Trying to get the SDHC to work using their example

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

Trying to get the SDHC to work using their example

2,979 Views
tmf
Contributor I
Trying to get the SDHC to work
Description:I have TWK-K60 REVC system.

I downloaded sample codes to run the SDHC card.

It will not work and am not sure why, maybe the code is wrong, maybe the SDHC properties are wrong, or maybe CW10.1 is not setup right.

I have CW 10.1 installed on WIN7 and all patches applied.

See attached files, these are my complete workspace with a project called fm15 within.

Load on CW10.1 and see please.

Do you need startup.c? I went into debug mode and the compiler is seemingly creating what looks like it own startup code by doing such things as zeroing .bss and also copying initialized variables etc....

Please be very specific on the solution as I am very technical and should be able to handle it.

We are now delayed 1 week due to this so please help soon.

Richard.

This has been posted on the personal support board now 7 days without anyone looking at it from FREESCALE :smileysad: not having good luck, hope someone can help.

 

Richard.

 

0 Kudos
16 Replies

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

Hi Richard,

 

could you, please, put a breakpoint in the CardSelection function in the component's C module (probably SDHC.c) on the if statement with the "Id != SDHC_NO_CARD" condition and send me the dump of the DeviceDataPrv local variable (in a readable form) and the SDHC registers. Also could you, please, send me the type of the inserted card (SD/MMC, capacity, manufacturer etc.). Thank you.

 

Ladislav

0 Kudos

1,318 Views
tmf
Contributor I
DeviceDataPrv 0x1fff07ec $R4 *DeviceDataPrv 0x1fff07ec 0x1fff07ec Enabled 0x1 0x1fff07ec UserDataPtr 0x1fff16cc 0x1fff07f0 EventMask 0x7 0x1fff07f4 State 0x2 0x1fff07f8 Substate 0x4 0x1fff07f9 CmdState 0x3 0x1fff07fa CardId 0x1 0x1fff07fb NewCardId 0x0 0x1fff07fc CardType 0x0 0x1fff07fd HighCapacity 0x0 0x1fff07fe CardState 0x0 0x1fff07ff HighVoltage 0x1 0x1fff0800 CardsVoltages 0xff8000 0x1fff0804 RetryCounter 0x1964 0x1fff0808 Cards 0x1fff080c 0x1fff080c [0] 0x1fff080c 0x1fff080c Initialized 0x1 0x1fff080c Type 0x0 0x1fff080d CID 0x1fff0810 0x1fff0810 [0] 1657536604 0x1fff0810 [1] 537920656 0x1fff0814 [2] 1397573920 0x1fff0818 [3] 1396035 0x1fff081c RCA 0xb368 0x1fff0820 CSD 0x1fff0824 0x1fff0824 [0] 0 0x1fff0824 [1] 0 0x1fff0828 [2] 0 0x1fff082c [3] 0 0x1fff0830 Block 0x1fff0834 0x1fff0834 [0...99] [100...199] [200...299] [300...399] [400...499] [500...511] DataWidths 0x1 0x1fff0a34 HighCapacity 0x0 0x1fff0a35 LastError 0x0 0x1fff0a38 LastErrorAddress 0x0 0x1fff0a3c TransferTableMem 0x1fff0a40 0x1fff0a40 TransferTable 0x1fff0a44 0x1fff0a84 *TransferTable 0x1fff0a44 0x1fff0a44 Attributes 0 0x1fff0a44 Length 0 0x1fff0a46 Address 0 0x1fff0a48 TransferBlockSize 0x0 0x1fff0a88 TransferBlockCount 0x0 0x1fff0a8c CardInfoPtr 0x00000000 0x1fff0a90 *CardInfoPtr 0x00000000 0x00000000 Type -48 0x00000000 BlockLength 8191 0x00000002 BlockCount 13809 0x00000004 Caps 0x00000008 0x00000008 DataWidths 0xdd 0x00000008 Operations 0x1d 0x00000009 HighSpeed 0x0 0x0000000a HighCapacity 0x0 0x0000000b LowVoltage 0xe9 0x0000000c Read 0x0000000e 0x0000000e MaxBlockLength 0 0x0000000e MisalignBlock 0xe9 0x00000010 PartialBlock 0x1d 0x00000011 Write 0x00000012 0x00000012 MaxBlockLength 0 0x00000012 MisalignBlock 0xe9 0x00000014 PartialBlock 0x1d 0x00000015 Erase 0x00000016 0x00000016 SectorSize 0 0x00000016 Pattern 0xe9 0x00000018 WriteProtect 0x0000001a 0x0000001a GroupSize 0 0x0000001a Permanent 0xe9 0x0000001c TransferOperation 0x0 0x1fff0a94 Address 0x0 0x1fff0a98 DataWidth 0x1 0x1fff0a9c Frequency 0x0 0x1fff0a9d SpeedMode 0x0 0x1fff0a9e EnabledMode 0x1 0x1fff0a9f Secured Digital Host Controller (SDHC) Registers SDHC_DSADDR 0x0 0x400b1000 SDHC_BLKATTR 0x10000 0x400b1004 SDHC_CMDARG 0x40ff8000 0x400b1008 SDHC_XFERTYP 0x1020000 0x400b100c SDHC_CMDRSP0 0xb3680500 0x400b1010 SDHC_CMDRSP1 0x20100490 0x400b1014 SDHC_CMDRSP2 0x534d4920 0x400b1018 SDHC_CMDRSP3 0x154d43 0x400b101c SDHC_DATPORT 0x0 0x400b1020 SDHC_PRSSTAT 0xff880008 0x400b1024 SDHC_PROCTL 0x220 0x400b1028 SDHC_SYSCTL 0x7108f 0x400b102c SDHC_IRQSTAT 0x0 0x400b1030 SDHC_IRQSTATEN 0x117f010f 0x400b1034 SDHC_IRQSIGEN 0x3 0x400b1038 SDHC_AC12ERR 0x0 0x400b103c SDHC_HTCAPBLT 0x7f30000 0x400b1040 SDHC_WML 0x8100810 0x400b1044 SDHC_FEVT non-readable 0x400b1050 SDHC_ADMAES 0x0 0x400b1054 SDHC_ADSADDR 0x0 0x400b1058 SDHC_VENDOR 0x0 0x400b10c0 SDHC_MMCBOOT 0x0 0x400b10c4 SDHC_HOSTVER 0x1201 0x400b10fc Here is the info you need, this is a 1G Lexar I have a 2G Lexar same results. We are building a system for a customer who has order 50,000 of them, we need this to work with 99% of all cards..... are we going to be able to do this? Richard.
0 Kudos

1,318 Views
tmf
Contributor I

OK that looks like crap.

 

I made a PDF..... see attached.

 

Richard.

 

0 Kudos

1,318 Views
tmf
Contributor I

OK I decided to move the CW and the project to a WIN XP machine from the Vista Machine.... now I get new error messages......

 

So what am I not doing????

 

Am I not starting the project correctly?

Do I need a startup.c file?

 

I do not know why the result would differ......

 

Richard.

 

0 Kudos

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

There are several problems with the "Typical usage" example code in the component's help which caused the errors.

  1. Waiting for card insertion (while (!SD.Inserted) {}) should be placed before the Init function call because the Init function resets the inserted card. If the card is not reset, it may be in an unpredictible state and that may cause an internal component error.
  2. In the SD_Wait function, there is no test for the Timeout variable. This may cause that next operation is executed without finishing the previous one. This may cause a card timeout error.
  3. After detecting card removal it is better to call the Deinit function rather than trying to reselect the card. The card may be electrically connected to the slot pads even if the card detection pin is signalling card removal and hence the card deselection fails.

I would recommend to test your application with a wider set of cards (SD/MMC - various spec. versions, high/low capacity, ...). Beside unveiled errors in the software component there could be also problems with electrical requirements of the various specifications.

 

Ladislav

0 Kudos

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

Thank you again for the info. I'll try to figure out what the problem is and I'll let you know.

 

Ladislav

0 Kudos

1,318 Views
tmf
Contributor I

I did some very close investigations into when this error occurs, its in SDHC_SelectCard(), it selects an RCA of 1, and send the command CMD7 with argument 0x00010000 which looks right, its the 1 shift 16 left, when the SDHC hardware gets the command it returns 0x00400700 in RSP0 which means invalid command was sent and shows it was CMD7. SDHC_R1_IS_ILLEGAL_COMMAND(Response) ((Response)[0] & 0x00400000UL) Not sure why at this point CMD7 is illegal....

0 Kudos

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

According to the specification, illegal commands are not responded to. The flag is set and sent with the next valid command. Therefore the illegal command may be the CMD1 sent at the end of card detection (which should be ignored by SD cards). Please, could you try the following workaround:

  • Turn off SDHC code generation (rigth click on the SDHC component in the project panel, select Code generation/Don't write generated...).
  • In the generated SDHC module, in the CardRegistration function, in the top level switch (DeviceDataPrv->Substate), case ..._CR_FINISH (probably the last), replace the whole switch (DeviceDataPrv->CardType) by the following code:

          DeviceDataPrv->State = LDD_SDHC_VOLTAGE_VALIDATION;
          DeviceDataPrv->Substate = SDHC1_VV_FINISH;
          VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE);

 

  • Few lines above this code, there should be the comment /* Start the registration of the next card */. Below this comment correct the following line (replace the red text by the blue text):

          DeviceDataPrv->Substate = SDHC1_CR_START_FINISH;

          CardRegistration(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE);

 

If you make these changes, the last command sent before CMD7 should be CMD3. This does not affect the functionality in the case you have only one card slot connected to the SDHC bus.

0 Kudos

1,318 Views
tmf
Contributor I

yes this has worked! thanks!

 

now in the function SD_ReadBlockPart(&SD, address, 0, 512, Buf);

 

I am trying to get by LBA (sector), is address the sector or do you need to multiply by 512?

 

Richard.

 

0 Kudos

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

Great! I'm glad that it finally works. I'm sorry for the inconveniencies.

The address parameter in the demo example is a byte address. Internally the function uses the SD_ByteToCardAddress function which divides the byte address by 512 to get sector address (for high capacity cards) or uses the byte address directly (for low capacity cards) according to CardInfo.Caps.HighCapacity. If you want to use sector addresses, create a similar function SD_SectorToCardAddress, which will multiply by 512 for low capacity cards.

 

Ladislav

0 Kudos

1,318 Views
tmf
Contributor I

OK all working and hooked up to a FAT16/32 file system and all OK!

 

BUT....

 

You need ot start the component off with a clock of 400khz, I filled in higher speeds in the list, and called them through a function to change speed, when I do this it breaks..... any procedure to crank the speed up and how high can it go, do the cards tell you?

 

RIchard.

 

 

0 Kudos

1,318 Views
LadislavVadkerti
NXP Employee
NXP Employee

Did you get any error from the GetError function?

Here is an example how to speed up the communication (in the context of the Typical usage example code):

 

      /* Switch from default 1-bit communication to 4-bit (if supported) */

      if (SD.CardInfo.Caps.DataWidths & LDD_SDHC_CARD_DATA_WIDTH_4_BIT) {
        SDHC1_SetDataWidth(SD.SDHCPtr, LDD_SDHC_CARD_DATA_WIDTH_4_BIT);
        SD_Wait(&SD);
      }
      printf("Reading at 400kHz\n");
      SD_Read(&SD);
      SDHC1_SelectBusClock(SD.SDHCPtr, SDHC1_BUS_CLOCK_1MHz);
      SD_Wait(&SD);
      printf("Reading at 1MHz\n");
      SD_Read(&SD);
      SDHC1_SelectBusClock(SD.SDHCPtr, SDHC1_BUS_CLOCK_10MHz);
      SD_Wait(&SD);
      printf("Reading at 10MHz\n");
      SD_Read(&SD);
      if (SD.CardInfo.Caps.HighSpeed) {
        SDHC1_SelectBusClock(SD.SDHCPtr, SDHC1_BUS_CLOCK_50MHz);
        SD_Wait(&SD);
        printf("Reading at 50MHz\n");
        SD_Read(&SD);
      }

 

The maximum low speed frequency is 25MHz. If you use higher frequencies (e.g. 50MHz), you should turn on high slew rate bits in the port control module on the SDHC pins. Otherwise you can get a data CRC error.

 

Ladislav

0 Kudos

1,318 Views
tmf
Contributor I

I just also found a SDHC example project for Kinetis using Processor Expert and this demo program gets the same results as mine.

 

Here is the output of the demo:

 

+++ Step 0 - begin +++
Description: Card initialization example
1) Reseting card...
2) Card inserted - detecting card type...
3) Card detected - selecting card...
ERROR Internal component error
+++ Step 0 - end +++

 

I get the same ERROR which is 12

 

Richard

 

0 Kudos

1,318 Views
gustavod
Contributor III

Hi Richard,

 

Have you ever tried the BRTOS demo? We have a demo for the TWR-K60N512-KIT that supports the use of a SDHC card.

Here we have a video showing bitmap pictures being loaded in a LCD display:

http://www.youtube.com/watch?v=PrbfsqETglY

 

The demo code can be download here:

http://brtos.googlecode.com/files/BRTOS%25201.66%2520Kinetis%2520-%2520SD%2520card%2520-%2520BMP%252...

 

Regards,

Gustavo

 

0 Kudos

1,318 Views
tmf
Contributor I

We do not want an OS and we want to use Processor Expert for Kinetis, they advertise how simple it is to make things work, and yes most of the time it does, but so far with DMA to DAC, and SDHC it does not.

 

Richard.

 

0 Kudos

1,318 Views
gustavod
Contributor III

Ok Richard, I just wanted to help.

If you had tested the demo you would have seen that the SDHC / FAT32 code is completely independent to the OS.

 

Sometimes is good to understand what you are doing and not just rely in Processor Expert. Portable C code can be used in any microcontroller. Think about it. 

0 Kudos