SD Karte 4 Bit Modus CRC Datencheck

Gast #4797850
Lesenswert?

Hi forum,

ich hab ne frage zum crc check von der sd karte im 4 bit modus.

falls der crc check failt, wie erhalte ich von der karte eine anntwort, 
dass der crc fehlerhaft war?
ich schicke die daten vom block rüber, danach den crc, mein controller 
wartet (3 mal), solange bis die  erste datenleitung wieder 1 ist und 
wenn ich den beschriebenen block daten lesen will, lese ich nur nullen.

ich hab die realisierung des crc's jeder datenleitung selbst in c 
realisiert, weshalb ich vermute, dass da irgendwo ein fehler ist und 
würde gern von der karte wissen, ob denn beim schreiben der daten-crc16 
fehlerhaft war.

hab in der sd karten spec nur ein 'crc error status' für einen command 
gefunden, nicht fürs datenschreiben.


würde mich um tipps und info sehr freuen.


vielen dank
thorben
#4798077
Lesenswert?

Hi,

Es gibt zwei CRCs, eine fuer die Kommandos und eine fuer die Daten.
Wenn du ein Schreibkommando absetzt bekommst du zunächst eine Response 
der Karte. Wenn nicht, dann war die CRC des Kommandos falsch oder das 
Kommando Illegal. In so einem Fall liest man ACMD13 das SD Status 
Register und überprüft dort welche Fehlerbits gesetzt sind.

Ist die Response der Karte aber gekommen und OK, schickt man die Daten. 
Nach der Daten schickt man die CRC. Danach kommt von der Karte ein crc 
status token dass einem mitteilt ob die Daten richtig empfangen wurden 
oder nicht. Falls sie das wurden, kann die Karte danach busy werden um 
schlieslich die Daten zu programmieren.

Gruss
Gast #4798098
Lesenswert?

ich hätte noch eine frage.

berechne ich den crc16 vom zu sendeten 512 langen array und übertrage 
dann den crc über die 4 leitungen oder muss ich für jede datenleitung 
einen eigenen crc berechnen und diesen übertragen?
Gast #4798157
Lesenswert?

ich beschreibe nochmal kurz wie ich es mache:

ich sende 512 bytes mit dem inhalt 255.
danach berechne ich den crc16 für jede datenleitung, d. h. ein crc16 
über ein 128 byte langes array, wo nur 1 stehen.
ich erhalte für jede datenleitung den berechneten crc16 wert 60841, was 
in hexadecimal EDA9 entspricht.

d. h.
dat0: 0b1110110110101001 (pin0)
dat1: 0b1110110110101001 (pin1)
dat2: 0b1110110110101001 (pin2)
dat3: 0b1110110110101001 (pin3)


d. h. ich sende sozusagen, wenn man es quer anschaut: FFF0FF0FF0F0F00F 
rüber.

meine funktion, die 4 bits sendet, erhält einen 8 bit wert und schreibt 
ihn auf den pins parralel, zuerst die 4 MSB bits, dann die 4 LSB bits
der crc wird nach den daten folgend ausgegeben:

[c]
   for(j=0;j<16;j++)
   {

     SD_CLK_LOW;

      if(j < 8)
      {

        SD_DAT_WRITE((alt_u8)(crc_send_buffer_MSB >> 28) & 0x0F);
        printf("%u ", (unsigned int)(crc_send_buffer_MSB >> 28) & 0x0F);
        crc_send_buffer_MSB <<= 4;

      }

      else
      {

        SD_DAT_WRITE((alt_u8)(crc_send_buffer_LSB >> 28) & 0x0F);
        printf("%u ", (unsigned int)(crc_send_buffer_LSB >> 28) & 0x0F);
        crc_send_buffer_LSB <<= 4;

      }

     SD_CLK_HIGH;

   }
[c]

wenn ich es mir auf der console anschaue, scheint alles okay zu sein.
der crc ist korrekt, trotzdem ist das gelesene array leer.
die lesefunktion, die ich verwende, funktioniert, hab ein 'hallo' damit 
schonmal lesen können. der ursprüngliche inhalt vom lesearray war 
gefüllt mit zahlen und meine lesefunktion füllt das lesearray mit 
nullen, da auf den gelesenen block nicht, wie erwünscht 255 
reingeschrieben wurde.
lese und schreibe-funktion wird auch diesselbe addresse übergeben.

ist alles etwas mega kompliziert formuliert, aber vielen vielen dank für 
jeden tipp
Angehängte Dateien:
Gast #4798271
Lesenswert?

ich hab die mir mehrmals angeschaut und gelesen, hab auch geschrieben, 
dass ich nichts dazu wirklich gefunden habe, ob man es deaktivieren kann 
und hab halt nochmal nachgefragt, ob dies auch so ist
Gast #4798279
Lesenswert?

fpga_thorben schrieb:
> ich hab die mir mehrmals angeschaut und gelesen, hab auch geschrieben,
> dass ich nichts dazu wirklich gefunden habe, ob man es deaktivieren kann
> und hab halt nochmal nachgefragt, ob dies auch so ist

Ok, ich nehm alles zurück.

fpga_thorben schrieb:
> hab in der sd karten spec nur ein 'crc error status' für einen command
> gefunden, nicht fürs datenschreiben.

Habe das hier übersehen.
Gast #4799280
Lesenswert?

initialisierung klappt, lesen auch. die karte hat fat32 format.

ich sende den cmd24 mit blockadresse, kriege eine antwort, dass alles 
okay ist.

dann wird die clock gesetzt, nullen für den start gesendet, bits 
rübergesendet, danach crc und am ende mit 1 der transfer beendet. es 
wird gewartet, bis die datenleitung 1 eine 1 ist und wird noch 8 mal die 
clock übertragen.
Gast #4807254
Lesenswert?

joooo, hab die fehler gefunden. alles richtig gemacht. bloß im 
vorgegebenem code war die 4 bit modus initialisierung der ausgangspins 
falsch und am ende wurde zu kurz auf das busy der sd karte gewartet ;-)
Gast #4807904
Lesenswert?

ich hätte noch eine frage, ich hab 3 sd karten evaluiert und ist voll 
lahm.

liegt es am prozessor? hab 50 mhz am start.

bevor ich schreibe, wie schnell es ist, wollte ich vorab fragen, ob der 
spi modus höhere raten schafft, weil man ja auf crc verzichtet?
Gast #4807907
Lesenswert?

also, im spec steht ja, dass 12 MB/s möglich sind. wenn ich es jetzt mit 
nem fpga mache, kriege ich die rate oder dauert auch die berechnung des 
crc's der sd karte ziemlich lange?


vielen dank für antworten
Gast #4807928
Lesenswert?

das heißt ich kann davon ausgehen, wenn ich es in vhdl z. b. realisiere 
und es läuft, dann hab ich deutlich höhere datenraten? brauch nämlich 10 
mbyte/s fürs lesen und 3 fürs lesen. software seitig hab ich nicht mal 
ein zehntel davon ;-).
Gast #4808068
Lesenswert?

Also, falls ich mich nicht irre, ist ja eig. der 4 bit Mode die 
schnellste Übertragung. die Karten haben ja eine mind. Datenrate, die 
sie schaffen. Im default modus sind 12mbytes/s ja, je nach kartentyp 
drin. Mir geht es nicht um mein System, dass die frequenzen nicht 
einhält, da mach ich mir eher keine sorgen. Ich bin mir nicht sicher, ob 
wegen des CRC's die Rate nicht erreicht werden kann, weil die SD Karte 
zu lange braucht, um den CRC zu berechnen. Ich hab 3 Karten getestet und 
alle haben eine unterschiedliche Datenrate, was mich stützig macht. Eig. 
müssten die alle gleich schnell sein. ich erreiche beim lesen bei einer 
um die 440 kbytes/s, bei einer anderen Karte nur 330. Das lässt mich 
vermuten, dass die Karte mega lahm ist.
Beim Schreiben erreiche bei einer 119 kbyte/s bei einer anderen nur 89.

Woran könnte das liegen?

Die Größte (8 GByte) ist die langsamere (Klasse 4)

und die Kleinste (512MByte) die schnellste.

Hätte eher gedacht dass die Größte schneller wäre als die kleinere, 
wegen Klasse 4. Und überhaupt, dass beide gleich schnell sind, weil die 
Karten halt nicht von der Geschwindigkeit her ausgelastet werden.
#4808354
Lesenswert?

fpga_thorben schrieb:
> Also, falls ich mich nicht irre, ist ja eig. der 4 bit Mode die
> schnellste Übertragung.
Ja, wobei es hierbei noch weitere Unterteilungen gibt.
Eine Übersicht gibt hier 
https://www.sdcard.org/developers/overview/bus_speed/index.html oder der 
Standard. Normal Speed (4 bit und  25 MHz) bietet bis zu 12.5MB/s (50 
MHz). Das etwas schnellere High Speed bis zu 25MB/s. Nebst diesen, gibts 
ausserdem noch die UHS Modis die noch höhere Geschwindigkeiten erlauben. 
Verschiedene Karten können verschiedene Modis unterstützen oder eben 
nicht. Der Host muss umschalten (Da gibts Kommandos dafür), falls er 
einen anderen Modus verwenden will.

Das ist die Bus-Datenrate wohlgemerkt. Das ist das Maximum was vom Bus 
her möglich ist. Die tatsächliche Geschwindigkeit ist dann von 
Kartentype zu Type unterscheidlich und auch davon abhängig, in welchem 
Zugriffmuster geschrieben/gelesen wird.

Die Frage wäre daher, wie du denn die Performance misst und bei welchem 
Zugriffsmuster.


> drin. Mir geht es nicht um mein System, dass die frequenzen nicht
> einhält, da mach ich mir eher keine sorgen. Ich bin mir nicht sicher, ob
> wegen des CRC's die Rate nicht erreicht werden kann, weil die SD Karte
> zu lange braucht, um den CRC zu berechnen. Ich hab 3 Karten getestet und

Die Karten haben einen dafür spezialisierten Controller verbaut, die die 
CRC in Hardware erledigen.

Gruss
Persönliche Seite #4808895
Lesenswert?

fpga_thorben schrieb:
> brauch nämlich 10
> mbyte/s fürs lesen und 3 fürs lesen.
Lies den Satz nochmal genau ;-) High-Performance und Software-Bitbanging 
passen irgendwie nicht zusammen. Ein FPGA ist aber auch nicht nötig. Mit 
einem STM32F7 und dessen Hardware-SDIO habe ich bis zu 15 MByte/Sec bei 
<1% CPU-Last geschafft. Dazu braucht es aber viel Puffer-RAM. Optimal 
dafür ist das STM32F746GDISCOVERY, das hat genau das was man braucht.
Gast #4824881
Lesenswert?

hey, hey.
Ich hab ein neues Problem. Hab multiple block read hinbekommen. lese 512 
byte blocks und beende es mit cmd12. das klappt soweit. jedoch will ich 
multiple block write ebenfalls hinkriegen. die block write funktion 
funktioniert wunderbar. Wenn ich aber mehrmals block write durchziehe 
und cmd12 sende, um das Schreiben zu beenden, dann geht der nächste 
befehl nicht und hab nen unexpected status.

Wenn ich den cmd25 sende, mehrere schreibe, cmd12 schicke, dann krieg 
ich ne unerwarteten zustand als antwort und lesen bzw. schreiben geht 
nicht mehr. wenn ich die karte neu initialisiere, kann ich jedoch den 
multiple block, den ich geschrieben auch lesen. bloß muss halt vorher 
neu initialisieren. ich find aus der spec nicht wirklich raus, was ich 
falsch mache.


für hilfe wäre ich sehr erfreut :-).
Gast #5041381
Lesenswert?

Hallo fpga_thorben,

ich habe den crc-Datencheck genauso gemacht. Es funktioniert aber bei 
mir noch nicht.
Hier folgt ein Teil meiner Schreibfunktion:

SD_DAT_OUT;  // set DAT pins to send data to SD card

// start bits
SD_CLK_LOW;
SD_DAT_WRITE(0x00);
SD_CLK_HIGH;

// write data (512 bytes = 1 block)
for(i = 0; i < nDataLen; i++)    // nDataLen = 512
{
    Data8 = szDataWrite[i];      // was ich in der SD-Karte schreiben 
möchte
    #ifdef SD_4BIT_MODE
        for(j = 0; j < 2; j++)
  {
      SD_CLK_LOW;
      SD_DAT_WRITE((Data8 >> 4) & 0x0F);
      SD_CLK_HIGH;
      Data8 <<= 4;
  }
    #endif
}

// Crc-Datencheck
#ifdef SD_4BIT_MODE
    for(j = 0; j < 16; j++)
    {
        SD_CLK_LOW;
        Crc16Aux = DataCrc16 >> 15;

        if (Crc16Aux  == 0x01)
      SD_DAT_WRITE(0x0F);
        else
      SD_DAT_WRITE(0x00);
        SD_CLK_HIGH;
        DataCrc16 <<= 1;
    }
#endif

// stop bits (value '1')
SD_CLK_LOW;
#ifdef SD_4BIT_MODE
    SD_DAT_WRITE(0x0F);
#endif
SD_CLK_HIGH;

//===== check busy bits (data0 only).
SD_DAT_IN;    // set DAT pins to receive data from SD card

for(i = 0; i < 32 && !bWriteSuccess; i++) // Glaub sollte nur 12 bits 
sein
{
    SD_CLK_LOW;
    SD_CLK_HIGH;    // CRC response output is always two clocks after 
the
                    // end of data

    if ((SD_TEST_DAT & 0x01) == 0x01) // (DAT0==LOW: busy indicate
        bWriteSuccess = TRUE;
}

    if (!bWriteSuccess)
      bSuccess = FALSE;

Das ist die Sequenz: S (Start Bit), content (512 bytes), CRC (16 bit für 
jede der vier Leitungen DAT0-3), E (End Bit)

Es wird in der SD-Karte nicht geschrieben und ich weiß nicht warum?
Hast Du bzw. hat Jemand eine Idee?
fpga_thorben, ist es möglich Deine Schreibfunktion zu zeigen?
Gast #5046723
Lesenswert?

Brue W. schrieb:
> Danach kommt von der Karte ein crc
> status token dass einem mitteilt ob die Daten richtig empfangen wurden
> oder nicht. Falls sie das wurden, kann die Karte danach busy werden um
> schlieslich die Daten zu programmieren.

Hallo Brue W.,

so wie ich es verstanden habe, sollte Z Z S Status E S L*L E Z, also 12 
Bits von der Karte empfangen werden, wobei

Z: High impedance state (-> = 1)
S: Start Bit (= 0)
Status: '101'(transmission error), '010'(non-erroneous transmission)
E: End Bit (=1)
L: Signal is low (logical ‘0’)
*: Repeater?

Ich bekomme aber ein anderes crc status token:
1 1 0  1 0 1   1 0 1 1 1 ... 1
Z Z S  Status  E S L*L E Z

Nach dem 10. Bit bekomme ich immer 1.

Ich dachte, dass ich das crc falsch berechne, aber ich bekomme mit 255 
den gleichen Wert, also 60841, wie im Beispiel von fpga_thorben.

Kann es an dem Takt liegen, da ich den Takt setze/schicke gleichzeitig 
wenn ich die Daten zu der SD-Karte schicke?

for(i = 0; i < nDataLen; i++)
{
    Data8 = szDataWrite[i];
    #ifdef SD_4BIT_MODE
    for(j = 0; j < 2; j++)
    {
        SD_CLK_LOW;
        SD_DAT_WRITE((Data8 >> 4) & 0x0F);
        SD_CLK_HIGH;
        Data8 <<= 4;
    }
}

Ich weiß nicht, was ich falsch mache. Ich habe schon einen Teil meines 
Codes hier hochgeladen. Ich weiß echt nicht, was ich ändern soll.

Hat jemand eine Idee?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren