Forum: FPGA, VHDL & Co. Immer noch Kompaktblitz


von Christian P. (kron)


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.

von Falk B. (falk)


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

von Christian P. (kron)


Lesenswert?

Ok, hier ist sie, hab ein wenig gekürzt, sonst wird's zuviel:
1
constant addr_status_register: std_logic_vector (4 downto 0)  := "10111";--Statusregister (R), Command (W)
2
3
begin
4
5
data_in <= DATA;
6
DATA <= data_out when (rw_flag = '0') else (others => 'Z');
7
8
RESET_CF_N <= reset_reset AND reset_state;
9
10
state_machine: process (CLK,reset_cf)
11
begin
12
if (reset_cf = '1') then
13
IOWR_N <= '1';
14
IORD_N <= '1';
15
addr_temp <= "00000";
16
state <= idle;
17
next_state <= idle;
18
data_in_buffer <= (others => '0');
19
read_counter <= (others => '0');
20
ADDR <= "11111";
21
reset_state <= '0';
22
elsif (falling_edge (CLK)) then
23
24
case state is
25
26
when idle =>
27
IOWR_N <= '1';
28
IORD_N <= '1';
29
reset_state <= '1';
30
if (START2 = '1' AND CD1_N = '0' AND CD2_N = '0') then--eigentlich START, Debugphase
31
addr_temp <= addr_status_register;
32
state <= read_1;--Lesevorgang fürs Statusregister
33
next_state <= check_status_register;--Als erstes soll das Statusregister gecheckt werden
34
else
35
state <= idle;
36
end if;
37
38
when check_status_register =>
39
ADDR <= "11111";
40
case (data_in_buffer (15 downto 14)) is
41
when "00" =>
42
leds (5) <= '0';
43
when "01" =>
44
leds (5) <= blink_counter (25);
45
when "10" =>
46
leds (5) <= blink_counter (22);
47
when "11" =>
48
leds (5) <= '1';
49
when others =>
50
null;
51
end case;
52
...--Gekürzt. Hier werden alle Bits angezeigt.
53
end case;
54
--------------------------------------------Beginn Lesevorgang        
55
when read_1 =>--ADDR valid
56
ADDR <= addr_temp;
57
read_counter <= read_counter +1;
58
if (read_counter = "0011") then
59
IORD_N <= '0';--IORD auf 0 ziehen
60
state <= read_5;
61
read_counter <= (others => '0');
62
end if;
63
64
when read_5 =>
65
read_counter <= read_counter +1;--Warten auf t2
66
if (read_counter = "0101") then
67
if (IORDY = '1') then
68
state <= read_6;
69
read_counter <= (others => '0');
70
end if;
71
end if;
72
73
when read_6 =>
74
IORD_N <= '1';
75
data_in_buffer <= data_in;--Hier wird gelesen
76
state <= read_9;
77
78
when read_9 =>
79
read_counter <= read_counter +1;--Warten auf t2
80
if (read_counter = "1011") then
81
state <= read_10;
82
end if;
83
84
when read_10 =>
85
IORD_N <= '1';
86
ADDR <= "11111";
87
read_counter <= (others => '0');
88
state <= next_state;
89
---------------------------------------------Ende Lesevorgang
90
91
when others =>
92
null;
93
end case;
94
end if;
95
end process state_machine;

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

von Falk B. (falk)


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

von Falk B. (falk)


Lesenswert?

Un mach mal ne gescheite Formatierung. Das kann keine Sau vernünfig 
lesen.

von TheMason (Gast)


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

von Christian P. (kron)


Angehängte Dateien:

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! :)

von Christian P. (kron)


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?

von Dirk (Gast)


Lesenswert?

Nein, Du ?

von Christian P. (kron)


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!

von Falk B. (falk)


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

von Christian P. (kron)


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.

von Falk B. (falk)


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

von BigR (Gast)


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?

von Mark (Gast)


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

von Christian P. (kron)


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. ;)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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

von Christian P. (kron)


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.

von Mark (Gast)


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?

von Dirk (Gast)


Lesenswert?

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

von Christian P. (kron)


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"?

von Falk B. (falk)


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

von Mark (Gast)


Lesenswert?

hast Du Dir mal das IORDY angeschaut? Das wäre auch interessant!

von Christian P. (kron)


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.

von Christian P. (kron)


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?

von Falk B. (falk)


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

von Christian P. (kron)


Lesenswert?

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

von Falk B. (falk)


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

von TheMason (Gast)


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

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
Noch kein Account? Hier anmelden.