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
fpga_thorben schrieb: > hab in der sd karten spec nur ein 'crc error status' für einen command > gefunden, nicht fürs datenschreiben. Probier mal aus ob der nicht auch bei CRC Fehlern in Datenblöcken gesetzt wird. Bei SD Karten kann man auch mit ACMD22 die Anzahl der geschriebenen Blöcke prüfen.
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
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?
Fuer jede Datenleitung separat auf der jeweiligen leitung. Das steht aber alles in der SD spec und ist eigentlich gut erklaert.
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
Ich wuerde raten, die Kartenresponse und das CRC Token auszuwerten, ggf. nach dem Kommando das Status register zu lesen. Dort sieht man nämlich dann wo das Problem liegt.
ich hätte noch eine frage. kann ich den crc auch einfach deaktivieren? oder muss der sein? in der initialisierungsfunktion habe ich so eine option z. b. nicht.
Ohne die Antwort auf deine Frage zu wissen, warum ließt du dir nicht einfach die Spezifikation durch, anstatt dich durch ein Forum zu fragen? Umständlicher gehts doch kaum... https://members.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf
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
Nein kann man nicht. Nur im SPI mode kann man es optional deaktivieren. Gruss
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.
vllt noch eine frage, hat jemand es hinbekommen im 4 bit modus auf die karte zu schreiben und kann mir den code vllt senden? ich habe bereits diesen verwendet, leider das gleiche ergebnis, konnte nicht auf die karte schreiben... Beitrag "Sd-Card endlich im 4-Bit-Mode! -> Init Read Write"
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.
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 ;-)
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?
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
4bit-modus in software macht wohl nicht wirklich Sinn. Wenn, dann crc in hardware. Und dann mit ausgereiftem code z.B. von Elm Chan - für alles andere ist das Leben zu kurz.
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 ;-).
fpga_thorben schrieb: > 10 mbyte/s fürs lesen das ist gewaltig. ich hatte im 1-bit-sdio-Modus 1,8 mbytes/sec: Beitrag "Re: sd-card SDIO Initialisierung" im 4-bit modus wären das dann ca. 6 mbyte/s.
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.
ich zitiere mich selbst: Ausprobiert habe ich 3 8GB-sdKarten. Ergebnis für beide Modi: Karte 1 ~600kbyte/sec Karte 2 ~1200kbyte/sec Karte 3 ~1900kbyte/sec Meine Vermutung: Karte3 wird ohne besondere Initialisierung immer im 4bit-Modus betrieben, bei den beiden anderen Karten funktioniert die Umstellung nicht. Beitrag "sdio problem mit 4bit-modus"
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
Alles klar, danke für die Ínfos. Ich werd wohl wahrscheinlich es auf nem Altera Fpga den Shit implementieren und berichten, obs klappt bzw. wie schnell es dann geht ;-)
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.
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 :-).
fpga_thorben schrieb: > . 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. Das mit dem Busy im Programming State (DAT0 low) hattest Du gesehen? In dem Zustand nimmt er nur ganz wenige Befehle an.
meinst du nach einen block write? dort berprüfe ich es. ebenso in cmd12. dort warte ich nach der antwort auf busy.
jo, war mein fehler, an der falschen stelle nach dem busy gefragt, klappt bei mir nachdem ich die antwort bekommen habe. hab da nen blöden fehler gemacht ;-).
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?
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.