mikrocontroller.net

Forum: FPGA, VHDL & Co. Immer noch Kompaktblitz


Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich knabbere immer noch an einem Projekt, bei dem ich Daten auf eine 
Compact-Flash-Karte schreiben muss.
Ich kenne das CFA-Paper mittlerweile gut auswendig und habe jetzt
zum zweiten Mal schön Schritt für Schritt eine Statemachine
gebaut, die genau den Timings im Paper folgt.
Die Vorgehensweise ist ja folgende:

1. Statusregister checken, ob Karte nicht busy ist und auch keine Daten 
will (halt Idle-Zustand)
2. Nötige Register und Kommandos für den Schreibvorgang beschreiben
3. Eigentlicher Schreibvorgang

Probleme macht mir schon der erste Schritt. Ich habe hier zwei 
CF-Karten, eine 16Mb, eine 2Gb, beide FAT-formatiert und (unter Windows) 
voll funktionsfähig.
Nachdem ich bei meinem ersten Versuch der Statemachine immer nur die 
einzelnen Bits für Busy und DRQ gecheckt habe, ließ ich mir nun die 
kompletten ausgelesenen 16bit mittels LEDs anzeigen. Hier sind einige 
Ergebnisse, ich hab dann mal variiert und verschiedene Register 
ausgelesen:

featureregister: 1111 1110 1000 0100 - FE84 - klein
featureregister: 0100 0000 0100 0000 - 4040 - groß
 Statusregister: 1111 1110 1000 0100 - FE84 - klein
 Statusregister: 0100 1000 0100 1000 - 4848 - groß
           LBA1: 0100 0000 0100 0000 - 4040 - groß
                 0100 1000 0100 1000 - 4848 - groß beim zweiten Mal 
anschalten
           LBA1: 1111 1110 1000 0100 - FE84 - klein
    Sektorcount: 0100 0000 0100 1000 - 4048 - groß
    Sektorcount: 0100 0000 0100 1100 - 404C - groß beim 2. Mal
    Sektorcount: 0000 0100 0000 0000 - 0400 - groß am nächsten Morgen
    Sektorcount: 0100 0000 0100 1100 - 0400 - groß am nächsten Morgen
    Sektorcount: 1111 1110 1000 0100 - FE84 - klein

Offensichtlich kommen da immer ähnliche Sachen raus, die nichts mit
dem vermutlichen Inhalt des Registers zu tun haben.

Kann zufällig jemand an Hand der ausgegebenen Bits
irgendwas sehen, was evtl. falsch laufen könnte?

Kann bei Bedarf die SM auch posten, wenn das hilft.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>ich knabbere immer noch an einem Projekt, bei dem ich Daten auf eine
>Compact-Flash-Karte schreiben muss.

>Probleme macht mir schon der erste Schritt. Ich habe hier zwei

Da bist du ja weit gekommen . . . ;-)

>CF-Karten, eine 16Mb, eine 2Gb, beide FAT-formatiert und (unter Windows)
>voll funktionsfähig.

Ich würde fürs erste die Finger von der 2GB Karte lassen.

>Kann bei Bedarf die SM auch posten, wenn das hilft.

Das wäre nicht schlecht. Denn wie es scheint ist dein Lesezugiff eher 
ein Griff in die Lostrommel.

MfG
Falk

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, hier ist sie, hab ein wenig gekürzt, sonst wird's zuviel:
constant addr_status_register: std_logic_vector (4 downto 0)  := "10111";--Statusregister (R), Command (W)

begin

data_in <= DATA;
DATA <= data_out when (rw_flag = '0') else (others => 'Z');

RESET_CF_N <= reset_reset AND reset_state;

state_machine: process (CLK,reset_cf)
begin
if (reset_cf = '1') then
IOWR_N <= '1';
IORD_N <= '1';
addr_temp <= "00000";
state <= idle;
next_state <= idle;
data_in_buffer <= (others => '0');
read_counter <= (others => '0');
ADDR <= "11111";
reset_state <= '0';
elsif (falling_edge (CLK)) then

case state is

when idle =>
IOWR_N <= '1';
IORD_N <= '1';
reset_state <= '1';
if (START2 = '1' AND CD1_N = '0' AND CD2_N = '0') then--eigentlich START, Debugphase
addr_temp <= addr_status_register;
state <= read_1;--Lesevorgang fürs Statusregister
next_state <= check_status_register;--Als erstes soll das Statusregister gecheckt werden
else
state <= idle;
end if;

when check_status_register =>
ADDR <= "11111";
case (data_in_buffer (15 downto 14)) is
when "00" =>
leds (5) <= '0';
when "01" =>
leds (5) <= blink_counter (25);
when "10" =>
leds (5) <= blink_counter (22);
when "11" =>
leds (5) <= '1';
when others =>
null;
end case;
...--Gekürzt. Hier werden alle Bits angezeigt.
end case;
--------------------------------------------Beginn Lesevorgang        
when read_1 =>--ADDR valid
ADDR <= addr_temp;
read_counter <= read_counter +1;
if (read_counter = "0011") then
IORD_N <= '0';--IORD auf 0 ziehen
state <= read_5;
read_counter <= (others => '0');
end if;

when read_5 =>
read_counter <= read_counter +1;--Warten auf t2
if (read_counter = "0101") then
if (IORDY = '1') then
state <= read_6;
read_counter <= (others => '0');
end if;
end if;

when read_6 =>
IORD_N <= '1';
data_in_buffer <= data_in;--Hier wird gelesen
state <= read_9;

when read_9 =>
read_counter <= read_counter +1;--Warten auf t2
if (read_counter = "1011") then
state <= read_10;
end if;

when read_10 =>
IORD_N <= '1';
ADDR <= "11111";
read_counter <= (others => '0');
state <= next_state;
---------------------------------------------Ende Lesevorgang

when others =>
null;
end case;
end if;
end process state_machine;

Na mal sehen, ob du (@Falk) oder irgendjemand mich erlösen kann. :)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>Ok, hier ist sie, hab ein wenig gekürzt, sonst wird's zuviel:

Das ist schlecht! Dann man sieht dann nicht alle Zusammenhänge! Und 
Quelltexte bitte als Anhang!

MfG
Falk

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Un mach mal ne gescheite Formatierung. Das kann keine Sau vernünfig 
lesen.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@christian

also die formatierung solltest du echt ändern. ist nicht wirklich schön 
zu lesen.

was ich bisher sehe ist das du das data-in register nicht als flip-flop 
ausgelegt hast sondern als latch. mach mal in dem state (z.b. Read_10, 
aber auf jedenfall in einem state in dem die daten anliegen müssen) in 
dem du das daten wort lesen willst ein data_in <= DATA;
dann wie sieht das mit dem takt aus ? da deine state-machine mit dem 
system-takt läuft kann das evtl. zu schnell für die kompaktblitz-karte 
sein.
da solltest du auch mal nach schauen.

noch eine frage : ist beim "rauskürzen" evtl die anweisung next_state <= 
read_1 irgenwie verschütt gegangen ? ansonsten macht deine statemachine 
nicht viel (außer im zustand check-register hängenzubleiben(

gruß
rene

Autor: Christian Peters (kron)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

vielen Dank erstmal für eure Antworten.

@Formatierung:
Als ich den Text mit meinen Tabs reinkopiert habe,
sah er furchtbar aus, weil ich nur 2 Leerzeichen als Tab nehme,
hier sinds aber vier, deshalb habe ich alle Tabs rausgemacht.
Jetzt habe ich die Datei angefügt und es sollte hübscher aussehen.

>was ich bisher sehe ist das du das data-in register nicht als flip-flop
>ausgelegt hast sondern als latch. mach mal in dem state (z.b. Read_10,
>aber auf jedenfall in einem state in dem die daten anliegen müssen) in
>dem du das daten wort lesen willst ein data_in <= DATA;

Also die Verbindung zur CF-Karte ist ja ein Bus, und den
behandle ich in Zeile 89f tristatemäßig (jaja, ich weiß,
tristates werden nicht als Tristates behandelt und sollen nur in die 
Top-Ebene, aber ich habe es schon bei mehreren Projekten umgebaut
und bei manchen nicht, es geht beides, die ISE erkennt das schon
und macht das Richtige daraus, also bitte keine Tristatevorträge ;) ).
Data_in ist also praktisch der Eingang des Datenbus und den übernehme 
ich immer mit ebendiesen Zeilen.
Die "eigentliche" Datenübernahme geschieht dann in Zeile 278,
und zwar dann auch getaktet.

>dann wie sieht das mit dem takt aus ? da deine state-machine mit dem
>system-takt läuft kann das evtl. zu schnell für die kompaktblitz-karte
>sein.

Ja, die SM läuft mit dem Systemtakt von 40 MHz, was natürlich
etwas schnell wäre für die Blitzkarte, aber wie in den Zeilen
261, 269 und 283 zu sehen ist, warte ich dort die entsprechenden
Zeiten mittels eines Zählers.

Die nötigen Timings habe ich aus dem CF-Paper entnommen,
zur Absicherung habe ich erstmal PIO-Mode 0 angestrebt,
da alle Zeiten min-Zeiten sind, und das langsamste muss dann auf
alle Fälle gehen. Hier mal ein Bildchen mit ein paar wichtigen Zeiten:

http://img442.imageshack.us/img442/2521/timingsgw1.png

>noch eine frage : ist beim "rauskürzen" evtl die anweisung next_state <=
>read_1 irgenwie verschütt gegangen ? ansonsten macht deine statemachine
>nicht viel (außer im zustand check-register hängenzubleiben

Also die SM geht so, es gibt zwei State-Signale, einmal "state", das ist
das normale, welches auch in der case-Anweisung gecheckt wird.
Und dann gibt es "next_state", was so wie ein Merker genutzt wird.
In Zeile 132 und 133 sieht man das, state wird read_1 und next_state
check_status_register. Das heißt, die SM geht auf read_1, und dann in 
Zeile 291
wird state auf next_state gesetzt.
Der state check_status_register zeigt momentan nur die einzelnen Bits
von data_in_buffer an, da ich nur 6 LEDs habe, musste ich die 16bit
ein bißchen kodieren, deshalb die blinky-Geschichte.

Danke schonmal fürs nochmal Draufschauen! :)

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Quellcode ist übrigens ein kleiner Fehler bei der LED-Darstellung,
das end if in Zeile 248 dürfte nicht auskommentiert sein, so schaltet es 
nicht auf den else-Zweig um. Aber das ist ja für die Hauptfunktion eher 
uninteressant.
Hat jemand etwas gefunden?

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, Du ?

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein. Und danke für deinen Bericht.

Aber ich hoffe dass nicht jeder der (bis jetzt) 12 Downloader,
die nichts finden, schreibt, dass er nichts hat.

Falls ich die Lösung finde, werde ich natürlich auch hier auflösen!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>Aber ich hoffe dass nicht jeder der (bis jetzt) 12 Downloader,
>die nichts finden, schreibt, dass er nichts hat.

Kleiner Tipp. Um das Ganze sinvoll zu debggen zu können, solltest du 
einen UART mit einbauen (gibts fertig bei Xilinx, xapp 233 glaub ich). 
Dann kanst du direkt grössere Datenmengen zum PC schicken un dort mit 
einem Terminalprogramm anzeigen lassen. Z.B. HTERM, das kann 
ASCI/Dezimal/Binär/HEX.
Und dann sollstest du mal mehrere Register auslesen und schauen, ob da 
halbwegs plausible Daten rauskommen.

MfG
Falk

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schonmal gesagt ist das Board schon fix.
Und verschiedene Register auslesen ist doch genau das,
was ich mache?! Der Fehler liegt bestimmt nicht in der
Weiterverarbeitung der erhaltenen Daten, ob ich die dann
am PC oder über LEDs anzeigen lasse, ist schnuppe.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>Weiterverarbeitung der erhaltenen Daten, ob ich die dann
>am PC oder über LEDs anzeigen lasse, ist schnuppe.

Wenn du meinst so schlau zu sein, viel Spass bei Debuggen.

MFg
Falk

Autor: BigR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian: Ich habe es mal kurz überflogen und verstehe es noch nicht 
ganz, aber wie kommt die SM aus dem Zustand "check_status_register" 
wieder raus?

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian,

mir sind auf die Schnelle folgende Sachen aufgefallen:

1)
evetuell interpretierst Du t1 falsch. Aus dem Bild kann ich das auch 
nicht
recht deuten - gib mal die Infos die in den Notes versteckt sind.
Die Zeit bezieht sich auf die steigende Flanke IORD/IOWR und den Beginn 
der Änderung IORDY.

2)
Du fragst in der Statemachine direkt das Signal IORDY ab, welches
asynchron zu Deinem Takt ist. Synchronisiere das mal mit einem Flip-Flop
ein.

3)
State 10 kannst Du weglassen, die Adresse muss am Ende nicht auf '11111'
gesetzt werden und IORD_N war ja eh schon '1'.

4)
für den timer würde ich den Typ integer verwenden, da tut man sich beim 
Lesen leichter.

5)
kann es sein dass die Karte nach dem Reset eine längere Zeit braucht, 
bis man
darauf zugreifen kann? Falls ja, hast Du das sichergestellt? Dein 
CF-Reset hab ich noch nicht durchschaut

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo und danke für eure Antworten und Hinweise,

@Falk: Warum so empfindlich? Fakt ist, das Board liegt hier und ich 
kriege keine UART oder irgendwas anderes drauf.

>wie kommt die SM aus dem Zustand "check_status_register" wieder raus?

In dieser Version gar nicht, das ist ja erstmal nur eine Testversion.
Wenn die ausgelesenen Register nicht stimmen, bringt mir die komplette 
SM nichts.

>evetuell interpretierst Du t1 falsch.
t1 ist die Zeit von address valid bis IORD-setup, das stimmt schon.

>Du fragst in der Statemachine direkt das Signal IORDY ab
Ok, das habe ich geändert, hat aber leider nichts geändert.

>State 10 kannst Du weglassen
Von hier:
http://www.compuphase.com/mbr_fat.htm

habe ich diesen Tipp übernommen:
Although this is optional, it is recommended that both /CS0 and /CS1 are 
inactivated at the end of the read or write cycle.
Ich weiß, dass es nichts bringt, aber es schadet auch nicht. :)
Da ich sowieso die langen Cycle-Times einhalten muss, habe ich genug
Zeit für alle möglichen Absicherungen.

>kann es sein dass die Karte nach dem Reset eine längere Zeit braucht,
>bis man darauf zugreifen kann?
Habe nichts darüber gefunden, aber es kann sein und ich habe jetzt
ca. 30 Sekunden Wartezeit eingebaut, bevor irgendwas passiert.
Hat wiederum leider nichts gebracht! :(

Wirklich tausend Dank für eure Tips,
auch wenn der erlösende (noch) nicht dabei war.
Ich werde auf alle Fälle dranbleiben,
obwohl ich ja hoffte, dass ihr mir einen
Kardinalsfehler aufzeigt, der den Knoten platzen lässt. ;)

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wär's wenn du mal einen Testbench schreibst und dir die 
Timingdiagramme ansiehst?

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das habe ich natürlich gemacht,
die Timings sind wie aus dem Bilderbuch,
alles sieht genau so aus, wie es laut Paper und Quellcode sein soll.

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian,

kannst Du mal einen Logic-Analyzer oder wenigstens ein 4-Kanal
Digi-Scope an die Flash-Schnittstelle hängen und das Timing
hier posten?

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist es ein elektro-mechanisches Problem ?
Pin verbogen, kalte Lötstelle o.ä.

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

also die Pins sehen erstmal alle gut aus,
und da die Karte ja schon etwas von sich gibt,
schließe ich erstmal auch 'ne kalte Lötstelle aus.
Habe leider kein Digitaloszi, deshalb hier ein
Ausdruckscan:

http://img459.imageshack.us/img459/6071/osziscanik5.jpg

Das ist einmal das IORD-Signal, und, stellvertretend für
den Adressbus, das Signal CS0, welches bei Aktivität auf 0 ist
und sonst auf 1.
Die wichtigsten Zeiten habe ich mal mit dazugeschrieben, es sieht 
wirklich
alles gut aus (leider).

Ich habe außerdem noch IORD zusammen mit einem Signal des Datenbusses
analysiert.
Dabei fiel mir auf, dass das Signal "sofort" (20 ns danach)
mit IORD auf 0 geht. Aber vielleicht ist die Karte halt schneller
als der PIO-Modus 0, den ich momentan fahre. Wenn IORD weggenommen wird,
kommt ca. 30ns später der Tristate und zieht das Datensignal wieder 
hoch.
Ach, ich scanne das auch noch schnell, warum so viele Worte, hier:

http://img262.imageshack.us/img262/7154/osziscan2vt0.jpg

Ist es normal, dass das Signal so langsam von 0 hoch"kriecht"?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>Ist es normal, dass das Signal so langsam von 0 hoch"kriecht"?

Sicher, der Ausgang geht auf Tristate und irgendwelche Pull-Ups ziehen 
es auf HIGH.

MFg
Falk

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast Du Dir mal das IORDY angeschaut? Das wäre auch interessant!

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja habe ich, bleibt immer auf 1, wird nicht negiert.

Das gleiche gilt für IOCS16.
Das ist eigentlich auch interessant, weil ja IOCS16 0-aktiv ist.
Aber das Signal wird nur im PIO-Mode 1 und 2 genutzt,
und vielleicht läuft die Karte in einem schnelleren Modus.

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da beide Karten von Sandisk sind und aber unterschiedlich antworten,
kann es sein, dass es Sandisk nicht so genau nimmt mit den 
CF-Spezifikationen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>kann es sein, dass es Sandisk nicht so genau nimmt mit den
>CF-Spezifikationen?

Kaum. Setz erstmal eine soldide Debugumgebung auf.

MFg
Falk

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll denn das heißen? (Ich meine jetzt nicht den Tipfehler)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Peters (kron)

>Was soll denn das heißen? (Ich meine jetzt nicht den Tipfehler)

Dass du erstmal eine solide Testumgebung brauchst, um überhaut was zu 
sehen und vergleichen zu können. Im Moment bist du noch reichlich im 
Blindflug unterwegs. Ich wiederhole mich . . .

MFg
Falk

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@christian

du solltest dir wirklich irgendwie überlegen/versuchen ob du nicht 
irgendwie 2 pins für eine serielle abgreifen/klauen kannst. das 
vereinfacht erheblich (vor allem bist du nicht auf one-shots angewiesen 
die sich nur durch reset wiederholen lassen)

gruß
rene

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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