NAND-Flash Reader mit FTDI-USB

OP #2573475
Lesenswert?

Hi Leute,
ich möchte gerne einen NAND-Flash (MT29F8G08ADBDAH4, ONFI 1.0) über USB 
(FTDI2232H, Sync. FIFO Mode) auslesen.

Der NAND-Flash ist Speicher eines Datenloggers, dessen Microcontroller 
(leider ohne USB) braucht mir aber zu lange (20 Minuten), um die Daten 
seriell zu übertragen. Das NAND-Interface ist vorsorglich nach draußen 
geführt worden und der µC kann während der Übertragung stillgelegt 
werden.

Nun habe ich von einem Bekannten ein CoolRunnerII Demo-Board bekommen, 
mit dem ich das am liebsten realisieren möchte. Elektrisch habe ich das 
ganze schon zusammengestrickt, nun solls mit VHDL weitergehen.

Da ich Anfänger bei VHDL bin, habe ich erstmal kleine Übungen gemacht:
- 7 Segment-Anzeige zur Statusanzeige.
- FTDI im Empfangsmodus (Empfang von PC-Daten), schreibt empfangene 
Daten über eine kleine SM auf 7 Segment-Anzeige

Das hat mit immerhin knapp 30 MB/sec geklappt, egal, wo ich beim Senden 
aufgehört habe, das letzt gesendete Byte blieb auf der 7SegAnzeige 
stehen.
Scheint also was funktioniert zu haben.

Nun brauche ich aber etwas Hilfe.

Der FTDI liefert im Sync. FIFO-Mode einen 60MHz Takt und will pro Takt 
ein Byte haben.. Der NAND-Flash kann aber nur 20 MHz.
Wie löst man sowas? Im CPLD kann ich ja nichts zwischenspeichern und ich 
will auch keine Bytes doppelt senden.

Jemand ne Idee bzw. sowas schon mal gemacht?



Knulli
Persönliche Seite #2575063
Lesenswert?

Knut E. schrieb:
> Der FTDI liefert im Sync. FIFO-Mode einen 60MHz Takt und will pro Takt
> ein Byte haben.. Der NAND-Flash kann aber nur 20 MHz.

Ich hab so ein Problem mal mit einem Controller und zu langsamen 
Dual-Port RAM gehabt, ich hab das dann so gelöst, dass ich ein Magic für 
den Start Sende und dann nur jedes x-te empangene Byte auswerte.
Bei dir z.B. 3 mal das Selbe senden, jedes Dritte auswerten.
Gast #2575116
Lesenswert?

Ich hab das Ding auch mal benutzt...
Der FIFO hat doch ne Flusskontrolle, sprich RD und WR, wenn du die nicht 
setzt passiert auch nix und wenn der FIFO leer ist hört der FTDI auch 
ganz von alleine das Übertragen auf.

Eigentlich überhaupt kein Problem, also nix extra schreiben, einfach das 
Write-Signal benutzten.

Gruß
OP #2575413
Lesenswert?

@duke:
seh' ich mir mal an

@steffen:
siehe Anhang, ist aber vorerst nur der receiver-teil 
(PC-->CPLD-LED-Anzeige).

@nils:
bytes mehrfach senden wollte ich ja gerade vermeiden, das senkt die 
Datenrate und da kann ich dann gleich den async FIFO nehmen

@franke:
Sendet der FTDI einfach wann er Lust hat und der Meinung ist, daß der 
Sendepuffer voll genug ist? Gibts da Timeouts wenn ich nur 10 Byte zu 
senden habe? Hab im Manual nix dazu gefunden.

Knulli
Angehängte Dateien:
OP #2585886
Lesenswert?

So, da bin ich wieder.
Bin gerade auf der Suche nach verlorengegangenen Bytes. Ich hab mir für 
den Sendeteil (Daten zum PC senden) mal eine kleine Logik gebaut, die 
nichts weiter machen soll, als ein Byte bei jedem Takt zu inkrementieren 
und dem FTDI zum Senden zu übergeben. Das mit den TXE und WR ist auch 
eingebaut, aber genau da scheint es Probleme zu geben.
Möglicherweise zielte da Steffens Frage nach den Timing Constraints 
drauf ab.

Fakt ist, wenn ich mehr als 510 Byte ohne längere Pause senden möchte, 
geht immer ein Byte verloren. Es kommt 0..255, 0..253, 255 an.
Sende ich 2048 Bytes kommen die Daten so an:
0..255,0..253,255,0..255,0..252,254,255,0..255,0..251,253..255,0..255,0. 
.250,252..255
Also jedes 511 te wird verschluckt.
Hat jemand dieses Problem mit einem FTDI schon mal (möglichst einfach) 
gelöst?

Knulli

      case FIFOWriteStatus is
        when FIFO_WR_IDLE  => if STA = '0' then
                                FIFOWriteStatus <= FIFO_WAIT_TXE;
                                FIFO_Data <= (others => 'Z');
                                ByteCNT   <= (others => '0');
                              end if;
        when FIFO_WAIT_TXE => if TXE = '0' then
                                FIFOWriteStatus <= FIFO_WR_DATA;
                              end if;
        when FIFO_WR_DATA  => if (TXE = '1') then
                                WR_buf <= '1';
                                FIFOWriteStatus <= FIFO_WAIT_TXE;
                              else
                                WR_buf <= '0';
                                FIFO_Data <= ByteCNT(7 downto 0);
                                ByteCNT   <= ByteCNT + 1;
                                -- bis 1FD gehts ohne Aussetzer...
                                if (ByteCNT >= x"00000800" - 1) then
                                  FIFOWriteStatus <= FIFO_WR_DONE;
                                end if;
                              end if;
        when FIFO_WR_DONE  => FIFO_Data <= (others => 'Z');
                              --ByteCNT <= x"AAAAAAAA";
                              WR_buf <= '1';
                              --FIFOWriteStatus <= FIFO_WR_IDLE;
                              if Div_CNT = 0 then
                                cnt_sel <= cnt_sel - 1;
                              end if;
      end case;

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