Immer noch Kompaktblitz

#622914
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.
#622918
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
#622944
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. :)
Gast #622974
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
#623501
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! :)
Angehängte Dateien:
#624656
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
Gast #624933
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
#625411
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. ;)
#626340
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"?
#629435
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
Gast #629442
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren