mikrocontroller.net

Forum: FPGA, VHDL & Co. SD Card Testbench


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.


   signal SD_CMD               : std_logic;
   signal SD_CLK               : std_logic;
   signal SD_WP_N              : std_logic;
   signal SD_DAT               : std_logic_vector(3 downto 0);
   signal SD_dataBuf           : std_logic_vector(47 downto 0); 
   signal SD_received_command  : unsigned(5 downto 0); 

...

   process
   begin
      SD_CMD <= 'Z';
      wait until SD_CMD = '0';
      SD_dataBuf <= (others => '0'); 
      for i in 0 to 46 loop
         wait until SD_CLK = '0';
         wait until SD_CLK = '1';
         SD_dataBuf <= SD_dataBuf(46 downto 0) & SD_CMD;
      end loop;
      
      wait until SD_CLK = '0';
      wait until SD_CLK = '1';
      
      SD_received_command <= unsigned(SD_dataBuf(45 downto 40));
      
      wait until SD_CLK = '0';
      wait until SD_CLK = '1';
      
      if (SD_received_command = 8) then
         wait for 10 us;
         for i in 0 to 47 loop
            wait until SD_CLK = '0';
            wait until SD_CLK = '1';
            SD_CMD     <= SD_dataBuf(47);
            SD_dataBuf <= SD_dataBuf(46 downto 0) & '1';
         end loop;
         SD_received_command <= (others => '0');
      end if;
   end process;


Autor: Jim M. (turboj)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CMD0 und CMD8 müssen zwingend eine korrekte Checksumme haben -  die sehe 
ich oben überhaupt nicht.

Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: FPGA zum Spass (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: FPGA zum Spass (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.