Forum: Mikrocontroller und Digitale Elektronik SPI - Multiblock-Read von SD-Card


von Oliver L. (ollil)


Lesenswert?

Hallo,

ich versuche mich gerade an einer Multiblock-Implementation, doch 
irgendwie komme ich nicht auf einen grünen Zweig.

Nach der Initialisierung der Karte führe ich praktisch folgendes durch:

- Adresse = 0
A: sende CMD18 mit der zu lesenden Adresse 
"von-hinten-nach-vorne-gedreht"
B: sende 0xFF und warte bis bis 0xFE gelesen wird
B: sende 512 mal 0xFF und schreibe das gelesene als Ergebniss weg
B: sende 2 mal 0xFF und schmeisse das Ergebniss weg (die CRC)

B wird nun in Summe 8 mal ausgeführt (8 Blöcke gelesen)

- sende CMD12 mit Argument 0
- erhöhe Adresse um Adresse+(8*512)
Nun gehts wieder zurück zu A.

Problem:

Nachdem ich nun 3 mal 8 Blöcke gelesen habe, nimmt die Karte mein CMD12 
nicht mehr an....

Ich habe nun vor das senden des CMD12 noch mal ein senden von 0xFF 
eingebaut.

Nun kann ich 6 mal 8 Blöcke lesen - dann nimmt die Karte wieder mein 
CMD12 nicht an.

Das was ich jeweils gelesen habe ist korrekt und entspricht genau dem, 
was in den ersten 3*8 oder 6*9 Blöcken der Karte gespeichert ist.


Wenn ich noch ein weiteres 0xFF vor dem CMD12 sende, dann komme ich über 
einen Durchlauf von "B" nicht hinaus.

Also - wie genau muss die Abfolge aussehen für nen Multiblock-Read?
Ich habe auch versucht, mit CMD23 vorher die Blockanzahl zu setzen, und 
dann ohne Stop-CMD zu arbeiten, das funktionierte aber auch nicht...

von Oliver L. (ollil)


Lesenswert?

noch nie einer Multibyte-Commandos für ne SD-Card implementiert? ;)

von Oliver L. (ollil)


Lesenswert?

So... multiblock-write habe ich nun endlich hinbekommen.... read noch 
nicht. Hier mal mein write-code:
1
uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *Buffer, uint8_t numblocks )
2
{
3
    uint8_t resp;
4
    uint8_t cmd[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF };
5
#ifdef SPI_CRC
6
    uint16_t crc;
7
#endif
8
9
    MMC_Enable();
10
11
#ifdef MMC_PRESET_MULTIBLOCKCOUNT
12
    // wait until Card is ready
13
    do {
14
        SPDR = 0xff;
15
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
16
    } while ( !SPDR );
17
18
    //CMD55
19
    cmd[0] = 0x40 + 55;
20
    mmc_write_command ( cmd, 1 );
21
22
    //CMD23
23
    cmd[0] = 0x40 + 23;
24
    cmd[4] = numblocks;
25
    mmc_write_command ( cmd, 1 );
26
27
    // wait until Card is ready
28
    do {
29
        SPDR = 0xff;
30
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
31
    } while ( !SPDR );
32
#endif
33
34
    addr = addr << 9; //addr = addr * 512
35
36
    //CMD25
37
    cmd[0] = 0x40 + 25;
38
    cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
39
    cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
40
    cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
41
    cmd[4] = 0;
42
43
    resp =  mmc_write_command ( cmd, 1 );
44
    if ( resp > 1 ) {
45
        return ( 1 );
46
    }
47
48
    for ( uint8_t n = numblocks; n > 0; n-- ) {
49
#ifdef SPI_CRC
50
        crc = crc16 ( Buffer, 512 );
51
#endif
52
        // wait until Card is ready
53
        do {
54
            SPDR = 0xff;
55
            while ( ! ( SPSR & ( 1 << SPIF ) ) );
56
        } while ( !SPDR );
57
58
        // Send multi-block start-token
59
        SPDR = 0xFC;
60
61
        //actually transfer the data
62
        for ( uint16_t i = 512; i; i-- ) {
63
            uint8_t data = *Buffer;
64
            Buffer++;
65
            while ( ! ( SPSR & ( 1 << SPIF ) ) );
66
            SPDR = data;
67
        }
68
69
        // send  CRC
70
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
71
#ifdef SPI_CRC
72
        SPDR = crc >> 8;
73
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
74
        SPDR = crc & 0xFF;
75
#else
76
        SPDR = 0xff;
77
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
78
        SPDR = 0xff;
79
#endif
80
81
#ifdef MMC_PRESET_MULTIBLOCKCOUNT
82
        // Pad 8
83
        SPDR = 0xff;
84
#endif
85
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
86
87
        // Get response
88
        SPDR = 0xff;
89
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
90
        resp = SPDR;
91
        if ( ( resp & 0x0E ) != 4 )
92
            return ( 2 );
93
    }
94
95
    // wait until Card is ready
96
    do {
97
        SPDR = 0xff;
98
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
99
    } while ( !SPDR );
100
101
    // Send "transfer stop byte"
102
    SPDR = 0xFD;
103
    while ( ! ( SPSR & ( 1 << SPIF ) ) );
104
105
    // Pad 8
106
    SPDR = 0xff;
107
    while ( ! ( SPSR & ( 1 << SPIF ) ) );
108
109
    // wait until Card is ready
110
    do {
111
        SPDR = 0xff;
112
        while ( ! ( SPSR & ( 1 << SPIF ) ) );
113
    } while ( !SPDR );
114
115
    MMC_Disable();
116
117
    return ( 0 );
118
}

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.