Hi, habe jetzt alles rauf und runter gesucht und Nichts gefunden... Suche eine VHDL Testbench, mit der man Basis-SDCard Kommandos testen kann. Am liebsten für den "DAT" Modus, zur Not auch für SPI. Dabei reicht mir sogar für den Anfang wenn auf ein korrektes CMD0 eine Response kommt. Wenn mehr geht, umso besser. Hat da jemand etwas passendes? Will ungern alles auf der Hardware testen... Danke und Gruß
So, hab es jetzt auf der Hardware in Betrieb genommen und die Testbench nachgestrickt. Diese "kann" im Moment CMD 0 und 8. Werde die TB updaten bis sie auch Daten lesen/schreiben kann. Vielleicht hilft es ja dem ein oder anderen. Ein Review schadet sicher auch nicht, wenn jemand Lust hat.
1 | signal SD_CMD : std_logic; |
2 | signal SD_CLK : std_logic; |
3 | signal SD_WP_N : std_logic; |
4 | signal SD_DAT : std_logic_vector(3 downto 0); |
5 | signal SD_dataBuf : std_logic_vector(47 downto 0); |
6 | signal SD_received_command : unsigned(5 downto 0); |
7 | |
8 | ...
|
9 | |
10 | process
|
11 | begin
|
12 | SD_CMD <= 'Z'; |
13 | wait until SD_CMD = '0'; |
14 | SD_dataBuf <= (others => '0'); |
15 | for i in 0 to 46 loop |
16 | wait until SD_CLK = '0'; |
17 | wait until SD_CLK = '1'; |
18 | SD_dataBuf <= SD_dataBuf(46 downto 0) & SD_CMD; |
19 | end loop; |
20 | |
21 | wait until SD_CLK = '0'; |
22 | wait until SD_CLK = '1'; |
23 | |
24 | SD_received_command <= unsigned(SD_dataBuf(45 downto 40)); |
25 | |
26 | wait until SD_CLK = '0'; |
27 | wait until SD_CLK = '1'; |
28 | |
29 | if (SD_received_command = 8) then |
30 | wait for 10 us; |
31 | for i in 0 to 47 loop |
32 | wait until SD_CLK = '0'; |
33 | wait until SD_CLK = '1'; |
34 | SD_CMD <= SD_dataBuf(47); |
35 | SD_dataBuf <= SD_dataBuf(46 downto 0) & '1'; |
36 | end loop; |
37 | SD_received_command <= (others => '0'); |
38 | end if; |
39 | end process; |
CMD0 und CMD8 müssen zwingend eine korrekte Checksumme haben - die sehe ich oben überhaupt nicht.
Richtig, die Checksum wird aktuell nicht geprüft. Ein guter Hinweis, die Prüfung werde ich auch einbauen, allerdings mit Assertion, das Verhalten der SDCard bei falschem CRC möchte ich nicht nachbilden.
Die Testbench kann jetzt deutlich mehr: - Unterstützung für alle Basiskommandos, damit Block Read funktioniert - Block read(CMD17) wird unterstützt - Block write(CMD24) wird theoretisch auch unterstützt. Hier liegt der Hase im Pfeffer: auf der Hardware klappt fast alles: - Initialisierung - Block read - Block erase Nur das Block write tut einfach NICHTS. - Die Reponse sieht gut aus, keine Fehlermeldung. - Die DAT Leitung wird für 255 * 10 ns auf Low gezogen, nachdem ich meine Daten+CRC geschickt habe. Scheint mir etwas kurz... - Danach kann ich problemlos wieder Block Reads und auch Writes starten, ohne Fehler. Nur die Daten wurden nicht geschrieben. Kann jemand eventuell den Block Write Teil der Testbench reviewen? Eventuell fehlt da was. Vielleicht hat ja jemand auch sonst Ideen was noch fehlen kann, bzw. was ich falsch mache oder wie ich mehr erfahren kann...
FPGA zum Spass schrieb im Beitrag #5841943: > Vielleicht hat ja jemand auch sonst Ideen was noch fehlen kann, bzw. was > ich falsch mache oder wie ich mehr erfahren kann... Ich bin ja noch nicht auf die Idee gekommen SD-Kartenzugriffe in Hardware machen zu wollen. Ich hätte dafür einen Mikrocontroller (oder einen SoC) und ein Stück Software genommen. Das wäre jetzt auch mein Ansatz zur Fehlersuche: Ich würde bei einem funktionierenden System mit Oszi + Protokolldekoder schauen, was da auf den SPI-Leitungen passiert. Duke
Ich will das auch von einem Prozessor aus machen. Allerdings den DAT Modus, nicht SPI. Mein FPGA Code ist nur in der Lage: - Kommandos per SW Anfrage abzuschicken und die Antwort zur Verfügung zu stellen. - Daten per Kommando auf der DAT Leitung (Später 4 DAT Leitungen) einzulesen - Daten per Kommando auf der DAT Leitung auszugeben. - Die korrekten CRCs zu berechnen. D.h. auf unterster Schicht wird also das Interface zur Verfügung gestellt, die Kommandos selbst (bis auf den CRC) baut die Software zusammen. das funktioniert bis auf die Schreibefehle auch sauber, leider komme ich bei diesen nicht weiter. Was ich bisher rausgefunden habe: - CMD24 wird akzeptiert, setzt keine Fehlerbits oder sonstiges. - nach dem Schreiben aller 4096 Daten Bits + 2 StartStop Bits + 16 CRC Bits bleibt die DAT Leitung noch 4098 SDCLK Takte auf High, geht dann für einen Takt auf Low und dann wieder auf High. Das macht für mich keinen Sinn. Warum sollte nach dem Empfang nochmal für fast einen weiteren Block gewartet werden? Normalerweise müsste DAT doch sofort auf 0 gezogen werden.
Die Lösung ist gefunden, dank: http://wiki.seabright.co.nz/wiki/SdCardProtocol.html in kurz, dieser Satz: "The CMD and DAT lines are bidirectional. Handover occurs at the end of a command where both the host and the card switch to input mode for two clocks before the card starts driving in push/pull mode" Der gilt nämlich nicht nur in diese Richtung, sondern auch andersrum. Nach Empfang der Quittung auf CMD24 habe ich im nächsten Takt mein StartBit geschickt für die Übertragung der Daten auf der DAT line. Das funktioniert aber nicht, sondern man muss "ein bischen" Warten und zwar in Takten, nicht in Zeit, weil ein Takt bei 400 KHz ja schon recht lange ist. Wie viel weiß ich nicht genau, 31 tuns auf jeden Fall. Vieleicht stößt ja mal jemand auf das gleiche Problem. Die Testbench oben kann man jedenfalls verwenden, auch wenn sie diesen Fall noch nicht abdeckt.
So, noch eine letzte Version, jetzt mit Unterstützung der Umschaltung auf 4 DAT Lines. Die TB verhält sich sicher nicht überall dem Standard gerecht, sollte aber für die Basisfunktionen ausreichend sein.
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.