Forum: Mikrocontroller und Digitale Elektronik SD Card, CMD8, STK500


von Mario EDUARDO (Gast)


Lesenswert?

Hallo,

Ich verwende den Code von Roland Riegel, hab den aber ein wenig an meine 
HW (ordentliche PegelWandler von RIBU Elektronik) anpassen müssen. Im 
Prinzip funktioniert die ganze Sache ausser
ich hab meinen STK500 über den 6-pin ISP angeschlossen,
schalte alles das erste Mal ein. Dann gehts nicht. Wenn ich den STK500 
kurz ausschalte gehts ab dann immer.

Das relevante Code Fragment (inc Debug Code) ist unten zu sehen.
Die Ausgabe bei "uart_putc_hex (r1)" etc ergibt:

r1 = 0x00
r2 = 0x00
r3 = 0x01
r4 = 0x0f <============0

Es scheitert nur(!) beim aller aller ersten Einschalten.

PS: Woher weiß der STK500 eigentlich, dass nicht er als Slave adressiert 
ist, der hat ja keine SS Leitung ?!



===================0
uint8_t sd_raw_init()
{

    uint8_t  r1, r2, r3, r4  ;

    configure_pin_Status  ;

    if ( ! (PINB & SdCard_Present) )
       return (1) ;

    configure_pin_Von   ;
    SdCard_TurnVon      ;

    /* enable inputs for reading card status */
    configure_pin_available();
    configure_pin_locked();

    /* enable outputs for MOSI, SCK, SS, input for MISO */
    configure_pin_ss()      ;
  PORTB |= 0x01           ;
    configure_pin_mosi()    ;
    configure_pin_sck()     ;
    configure_pin_miso()    ;
  configure_pin_SelCrd()  ;
    configure_pin_xferled() ;


    unselect_card();

    /* initialize SPI with lowest frequency; max. 400kHz during 
identification mode of card */
    SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
           (1 << SPE)  | /* SPI Enable */
           (0 << DORD) | /* Data Order: MSB first */
           (1 << MSTR) | /* Master mode */
           (0 << CPOL) | /* Clock Polarity: SCK low when idle */
           (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
           (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
           (1 << SPR0);
    SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */

    /* initialization procedure */
    sd_raw_card_type = 0;

    if(!sd_raw_available())
        return 2;

    /* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 20; ++i)
    {
        /* wait 8 clock cycles */
        sd_raw_rec_byte();
    }

    /* address card */
    select_card();

    /* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 20; ++i)
    {
      /* wait 8 clock cycles */
      sd_raw_rec_byte();
    }

    uint8_t  i = 0 ;

    /* reset card */
    uint8_t response;
    for(uint16_t i = 0; ; ++i)
    {
        response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
        if(response == (1 << R1_IDLE_STATE))
            break;

        if(i == 0x1ff)
        {
            unselect_card();
            return 3;
        }
    }

#if SD_RAW_SDHC

    /* check for version of SD card specification */
    response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 
3.6V */ | 0xaa /* test pattern */);

  uart_putc_hex (0x41) ;
  uart_putc_hex (response) ;

    if((response & (1 << R1_ILL_COMMAND)) == 0)
    {
        r1 = sd_raw_rec_byte();
        r2 = sd_raw_rec_byte();
        r3 = sd_raw_rec_byte();

        if ((r3 & 0x01) == 0)
       {
          uart_putc_hex (0x42) ;
            return 9; /* card operation voltage range doesn't match */
           }

        r4 = sd_raw_rec_byte();

        uart_putc_hex (0) ;
        uart_putc_hex (r1) ;
        uart_putc_hex (r2) ;
        uart_putc_hex (r3) ;
        uart_putc_hex (r4) ;
        uart_putc_hex (0) ;

        if (r4 != 0xaa)
          {
            return 4; /* wrong test pattern */
      }

        /* card conforms to SD 2 card specification */
        sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
    }

    else
#endif
    {
      uart_putc_hex (0x43) ;

        /* determine SD/MMC card type */
        sd_raw_send_command(CMD_APP, 0);
        response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
        if((response & (1 << R1_ILL_COMMAND)) == 0)
        {
            /* card conforms to SD 1 card specification */
            sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
          uart_putc_hex (0x44) ;
        }
        else
        {
            /* MMC card */
        }
    }

    /* wait for card to get ready */
    for(uint16_t i = 0; ; ++i)
    {
        if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << 
SD_RAW_SPEC_2)))
        {
            uint32_t arg = 0;
#if SD_RAW_SDHC
            if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
                arg = 0x40000000;
#endif
            sd_raw_send_command(CMD_APP, 0);
            response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
        }
        else
        {
            response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
        }

        if((response & (1 << R1_IDLE_STATE)) == 0)
            break;

        if(i == 0x7fff)
        {
            unselect_card();
            return 5;
        }
    }

#if SD_RAW_SDHC
    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
    {
        if(sd_raw_send_command(CMD_READ_OCR, 0))
        {
            unselect_card();
            return 6;
        }

        if(sd_raw_rec_byte() & 0x40)
            sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);

        sd_raw_rec_byte();
        sd_raw_rec_byte();
        sd_raw_rec_byte();
    }
#endif

    /* set block size to 512 bytes */
    if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
    {
        unselect_card();
        return 7;
    }

    /* deaddress card */
    unselect_card();

    /* switch to highest SPI frequency possible */
    SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 
*/
//     SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */

#if !SD_RAW_SAVE_RAM
    /* the first block is likely to be accessed first, so precache it 
here */
    raw_block_address = (offset_t) -1;
#if SD_RAW_WRITE_BUFFERING
    raw_block_written = 1;
#endif
    if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
        return 8;
#endif

    return 0;
}
=======================

Danke, Mario

von Mario EDUARDO (Gast)


Lesenswert?

Habs selbst gefunden:

Bei der genannten Library sollte man zuvor z.B. beim 1284er
generell das PORTB auf Eingang stellen und die PullUp aufdrehen,
es wird dann in der SD_RAW_INIT() ohnehin die passende Richtung 
eingestellt, aber eben nicht die PullUp's.

Mario

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.