Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32] Obsługa SD - CRC error dla CMD8

24 Lut 2011 21:25 2332 2
  • Poziom 8  
    Witam!

    Właśnie piszę obsługę kart SD i natrafiłem na problem. Wszystko robię według tej specyfikacji Link. Dla karty SD v1.0 Inicjalizacja przebiega bez problemu. Problem mam z kartą SD v2.0. Po wysłaniu CMD0 wysyłam CMD8 w celu ustalenia wersji karty. Argument CMD8 wynosi 0x1AA oraz obowiązkowe CRC - 0x87. Mimo to, odbierając odpowiedź, otrzymuję wynik - 1001b czyli Idle_state oraz CRC_error. Szukałem już na google jakichś wskazówek, lecz wszędzie ludzie piszą, że to jest właśnie poprawna sekwencja. Ktoś miał podobne problemy? Korzystam z karty SanDisk 2GB (na "przodzie" karty w kółku 2).

    Kod inicjalizacji:


    Code:

    uint8_t SD_init(void)
    {
       uint8_t response;
       uint16_t counter;                  //local counter
       //r3_response r3;                     //R3 response

       /*Initialize SPI interface*/
       SPI_init(SPI_BaudRatePrescaler_128);      //Frequency between 400kHz and 100kHz

       /*Deselect all devices*/
       SPI_deselect();


       /*Send dummy clocks to establish link with SD card*/
       for (counter = 0; counter < 10; counter++)
          SPI_send(0xFF);

       delay_ms(10);

       /*Enable SD card*/
       SPI_select(SELECT_SD_CARD);

       /*-----------------------------------------------*/
       /* SET SD CARD TO SPI MODE                    */
       /*-----------------------------------------------*/
       counter = 1000;                      //one second for delay_ms;
       CardType = 0;
       do{
          delay_ms(1);
          /*Send command GO IDLE STATE*/
          SD_command(CMD_GO_IDLE_STATE, 0);
       } while((SD_getR1() != IDLE_STATE) && (--counter));

       if (!counter)
          return SD_TIME_OUT;

       /* ************************************************ */
       /* COMPLETE SD CARD INITIALIZATION                  */
       /* FIGURE OUT WHAT TYPE OF CARD IS INSTALLED...     */
       /* ************************************************ */
       /*Check if the Card is SDv1 or SDv2*/
       counter = 2000;
       do{
          delay_ms(1);
          SD_command(CMD_SEND_IF_COND, 0x1AA);
          response = SD_getR1();
       } while ((response != 0x01) && (--counter));

       if (!counter)
          return SD_TIME_OUT;


       if (response == (ILLEGAL_COMMAND | IDLE_STATE))
       {
          CardType = 1;                     //SDC v1
       }
       else
       {
          CardType = 2;                     //SDC v2
       }

       counter = 2000;
       if (CardType == 1)
       {
          do
          {
             delay_ms(1);
             SD_command(CMD_SEND_OP_COND, 0);
          } while ( SD_getR1() && (--counter));

          if (!counter)
             return (SD_TIME_OUT);

       }
       else if (CardType == 2)
       {

       }


       return (0);
    }


    Dodano po 1 [minuty]:

    Aha jeszcze, co do ścisłości zamieszczam kod funkcji SD_command, w której zadbałem o prawidłowe CRC dla CMD0 i CMD8

    Code:

    void SD_command(uint8_t cmd, uint32_t arg)
    {
       uint8_t i;
       sd_argument temp;

       SPI_select(SELECT_SD_CARD);

       /*Send buffer clocks to ensure no operation is pending*/
       SPI_send(0xFF);

       /*Send command to SD/MMC card*/
       SPI_send(0x40 | cmd);

       /*Send argument*/
       temp.ul = arg;
       for (i = 0; i < 4; i++)
          SPI_send(temp.b[i]);

       /*If GO_IDLE_STATE command send CRC*/
       if (cmd == CMD_GO_IDLE_STATE)
          SPI_send(0x95);
       else if (cmd == CMD_SEND_IF_COND)
          SPI_send(0x87);

       SPI_send(0xFF);

    }


    Dodano po 31 [minuty]:

    Hmmm wszystko wskazuje na to że ta dwójka na karcie SD to jakiś chwyt marketingowy. Bo karta dobrze reaguje na inicjalizację jak dla SD v1.0. Jednak jeżeli ktoś ma jakąś wiedze na ten temat to prosił bym o wskazówki.
  • Poziom 15  
    Ta dwójka w kółeczku to jest rating szybkości karty. Oznacza to, że musi charakteryzować się prędkością zapisu na poziomie przynajmniej 2 MB/s.
  • Poziom 12  
    Poniżej jest przytoczony fragment zapisu startu ARMputera BF210.
    Jak widać bootloader U-boot również raportuje błąd w czasie wykonywania komendy 8, ale radośnie go zlewa i ty uczyń podobnie. Komendę podaj, wyniki zlej.


    U-Boot 1.3.3 (Dec 15 2008 - 18:17:51)

    DRAM: 32 MB
    Atmel: Flash: 0 kB
    DataFlash:AT45DB011
    Nb pages: 512
    Page Size: 264
    Size= 135168 bytes
    Logical address: 0xC0000000
    Area 0: C0000000 to C0002C57 (RO) Darrell loader
    Area 1: C0002C58 to C0020DEF (RO) U-boot
    Area 2: C0020DF0 to C0020FFF Environment
    In: serial
    Out: serial
    Err: serial
    Using MAC address 00:17:A9:00:04:28
    Hit any key to stop autoboot: 0
    mmc: command 8 failed (status: 0x0010c0e5)
    Manufacturer ID: 1B
    OEM/Application ID: 534D
    Product name: SMI
    Product Revision: 1.0
    Product Serial Number: 278532850
    Manufacturing Date: 07/06
    SD Card detected (RCA 45928)
    CSD structure version: 1.0
    MMC System Spec version: 0
    Card command classes: 5f5
    Read block length: 512
    Supports partial reads
    Write block length: 512
    Does not support partial writes
    Supports group WP: 32
    Card capacity: 970 MB
    File format: 0/0
    Write protection:
    mmc: Using 262144 cycles data timeout (DTOR=0x64)