Versuche gerade mich in die Datenübertragung von meinem FPGA (Spartan3E)
auf einen Host PC einzuarbeiten.
Für die benötigte Datenrate (brauche etwa 7MB/s,(netto) in einem
späteren Schritt wäre eine höhere Datenrate besser) habe ich
mittlerweile heraus gefunden das ich wohl den Slave-FiFo Mode
konfigurieren muß. Damit wäre es mir wohl auch möglich die Logik zum
Füllen der FiFos im FPGA zu beschreiben.
Die VHDL seite macht mir mittlerweile relativ wenig sorgen, damit komme
ich zurecht, aber leider finde ich keinen Anfang wie ich den Cy7 Chip
programmiert bekomme. Da gibt es Firmware und Treiber und eine xx.a51
... weiß nicht so recht wo ich da anfangen soll ... und das TRM ist mir
leider auch keine große Hilfe ... kennt jemand eine Art "Tutorial" zu
der Programmierung, bzw. hat einen gut kommentierten BeispielCode den
ich mir dazu mal anschauen könnte?
Ist die eingeschrängte Keil SW eigentlich ausreichend um den Chip in
Slave FiFo zu versetzen? Nach der Konfiguration ist der 8051 ja quasi
arbeitslos, wenn ich das richtig verstande habe?
Fragen über Fragen...
Thanks
Newbe
Danke schon mal für die Antwort überhaupt und für den Link zum "großen"
DevelopmentKit ... hab da gestern abend wohl das falsche erwischt, bei
dem leider kein Keil Compiler dabei war.
Dann versuche ich mich jetzt mal weiter durch die Quellcodes zu
schlagen, leider fehlt mir im Moment immer noch ein wenig die Übersicht
welchen Teil der Codes man wofür braucht.
Naja, nimm am besten eins der Demo-Projekte zum Anfang.
*fw.c* ist das USB FrameWork, da sollte man nicht viel ändern erst mal.
*sync.c* (bei mir) ist quasi das Hauptprogramm, wo du deine eigenen
Einstellungen für alle Register machst und auch in der Hauptschleife
noch was tun kannst (muss man aber nicht bei Slave FIFO).
*descr.a51* ist die Assembler-Datei, in der alle USB Descriptoren drin
stehen. Die Angaben über die Endpoints, max. Paketgröße usw. müssen mit
den Angaben in der sync.c übereinstimmen.
Ich weiss nicht, wie weit Dein Entwirf fortgeschritten ist. Aber der
FT2232H ist deutlich einfacher zu handhaben. Er braucht keine Firmware
und inzwischen auch erhaeltlich...
Wenn man mit den 25MB/s auskommt, sicher eine Alternative. Hat schon mal
jemand getestet, wie schnell der wirklich Daten wegstreamen kann? Mit
dem FX2 schaffen wir die volle USB Geschwindigkeit von etwa 41MByte/s,
das ist schon ganz ordentlich. Und das bissl Firmware...wird einem ja
alles von Cypress vorgekaut.
Leider kann nicht auf einen anderen Chip umschwenken, der ist fest
implementiert auf einem Board von Trenz Elektronik zusammen mit dem
Spartan 3e1600.
Wühl mich immer noch durch die Beispiele, ... leider scheint die
Konfiguration aus dem Trenzbeispiel ("1st_program") nicht zu laufen, hat
damit jemand schon erfahrungen gesammelt?
Nochmal ne kurze Frage zur allgemeinen Dokumentation sowohl des
Trenzmoduls, welches ja schließlich den Cy7 Chip ausdrücklich
hervorhebt, als auch zu Cypress selbst... Bin ich mit dem Eindruck das
die Beispiele (mal abgesehen vom TRM das mit 400 Seiten aber ein wenig
extrem ist) extrem schlecht dokumentiert sind? ... Hab mit den
Quellcodes und dem Allgemeinverständnis über die Ansteuerung des Chips
und der Verbindung zu meinem FPGA immer noch so meine Probleme ... eine
Art "Blackbox" Lösung wäre mir da ja schon fast lieber .. meine Daten
FiFo mäßig rein takten und schnellst möglich auf den Rechner schieben
lassen ...
naja... werd dann mal weiter trm lesen ...
Gruß
Stefan
Naja, ganz out of the Box ist mit dem FX2 nicht. Dazu ist der viel zu
universell. Eine FIFO Lösung ist jedoch trotzdem recht schnell erstellt.
Dazu gibts auch ein Firmware-Beispiel in dem großen Paket. Im Prinzip
musst du nur einen OUT und einen IN Endpoint erstellen, im Register
IFCONFIG die untersten beiden Bits auf 1 setzen und schon hast du ein
Slave FIFO Interface. Schau halt mal in meinen Quelltext, da hab ich
doch viele Kommentare dran. Das Fine-Tuning mit Buffergrößen usw. kannst
du alles später machen. Im TRM bei Slave FIFOs sind auch die ganzen
Diagramme drin, wie man den FIFO Modus benutzt. Timing dazu gibts im
Datenblatt. Die Quellcodes sind bisweilen etwas schlcht dokumentiert,
aber brauchbar. Das TRM muss man nicht komplett lesen, die Sektion Slave
FIFOs reicht völlig aus.
Das FPGA Design kann/darf ich dir leider nicht geben, aber ein paar
Tipps:
- am besten synchrones Interface (einstellbar in IFCONFIG)
- am Anfang nicht zu schnell den IFCLK, wenn es geht, den internen 30MHz
nehmen oder extern bis 40MHz, die Timings sind recht eng...
- Die FIFO-Flags wie in meinem beispiel fest zuordnen, das macht die
Sache leichter.
- Das PacketEnd ist tückisch:
1. Hast du Vielfache von 512 Byte reingeschrieben, musst du es
eigentlich nicht setzen, weil volle USB Pakete direkt übergeben werden.
startest du aber einen Lesebefehl am PC, der mehr als genau die 512 Byte
hat, kommt der nie zurück, wenn das PacketEnd nicht gesetzt wurde.
2. Wenn FIFO voll darf das PKTEND nicht gesetzt werden. Das heißt aber
nicht, dass man es dann weglassen darf, wenn man z.B. bei einem 2-fach
gepuffertem Endpoint 1024 Byte reingeschrieben hat. Man muss dann
solange warten, bis FIFO nicht mehr voll, und das PKTEND dann
"nachholen".
3. Setzt du das PKTEND nach Vielfachen von 512 Byte, erzeugt das je nach
Einstellung im EPxFIFOCONFIG Register ein leeres Paket. Das muss beim
Lesen vom PC beachtet werden.
3. Nach dem PKTEND darfst du eine Weile keine neuen Daten reinschreiben,
obwohl das FIFO voll nicht gesetzt ist. Warum auch immer.
4. Das PKTEND darf nicht direkt mit dem letzten Wort zusammen gesetzt
werden. Bei Vielfachen von 512 Byte musst du gar min. 2 Takte warten.
(sind die kleinen notes im TRM und Datenblatt...gruselig).
Noch ein paar Allgemeine Sachen. Ein kontinuierliches Streaming über
BULK Endpoints ist schwierig, du brauchst riesige Puffer vor dem USB
Chip. Wir haben Messungen gemacht, da waren Pausen bis zu 50ms, das
musst du locker puffern können (wir arbeiten mittlerweile mit fast dem
ganzen BlockRAM des Virtex 4 LX dafür). Eine hohe Datenrate erreichst du
nur, wenn du viele Daten auf einen Schlag anforderst und die
KernelBufferSize im Treiber hoch stellst (Optimum bei uns 128kiByte).
@Uwe: Er schrieb ja, dass die Hardware fest vorgegeben ist. hat man sich
einmal durch die Basics des FX2 gekämpft, ist es ein schöner, sehr
schneller Chip.
Hi Christian,
erst nochmal vielen Dank für deinen Quelltext und deine ausführliche
Antworten!
Du schreibst in deinem letzten Posting, dass ein kontinuierliches
streaming über Bulk EPs schwierig sei da man große Bufferspeicher vor
dem USB Chip bräuchte. Ist ein Streaming mit etwa 7MByte/s dabei schon
ernsthaft problematisch?
Bekomme im Moment Daten mit 56MBit/s von einem ADC geliefert, die kann
ich im internen Block Ram des Spartan 3e 1600 nicht ausreichend zwischen
Speichern um 50msec überbrücken zu können. Werd dann wohl zur Not den
externen Ram mit nutzen müssen, da könnte ich so ca. 9sec zwischen
speichern ... da das ja aber nur Single-Port Ram sein kann könnte ich da
wohl timing probleme bekommen oder? ...
Stefan K. schrieb:
> Hi Christian,>> erst nochmal vielen Dank für deinen Quelltext und deine ausführliche> Antworten!>> Du schreibst in deinem letzten Posting, dass ein kontinuierliches> streaming über Bulk EPs schwierig sei da man große Bufferspeicher vor> dem USB Chip bräuchte. Ist ein Streaming mit etwa 7MByte/s dabei schon> ernsthaft problematisch?
Ja. Die Datenrate ist nicht entscheidend, eher die Letenzzeit zwischen
den Lese-Anfragen von Windows. Bei uns ist es aber vielleicht noch bissl
schwieriger, da das Gerät hochgeradig interaktiv ist. Klappt aber nun
alles, wir haben die Hardware und die Software soweit, dass keine
Aussetzer mehr auftreten.
> Bekomme im Moment Daten mit 56MBit/s von einem ADC geliefert, die kann> ich im internen Block Ram des Spartan 3e 1600 nicht ausreichend zwischen> Speichern um 50msec überbrücken zu können. Werd dann wohl zur Not den> externen Ram mit nutzen müssen, da könnte ich so ca. 9sec zwischen> speichern ... da das ja aber nur Single-Port Ram sein kann könnte ich da> wohl timing probleme bekommen oder? ...
Naja, wenn der RAM schnell genug ist, dann geht das, 7MB sind ja nicht
die Welt. probier es halt einfach mal aus. Willst du nur kontinuierlich
lesen? Oder auch Blöcke bilden und triggergesteuerte Messungen fester
Länge machen oder sowas?
Im Moment geht es "nur" um das kontinuierliche Auslesen der Daten, und
das System zu welchem diese Daten geschickt werden hat zunächst einmal
während einer laufenden Messung nicht anderes zu erledigen als die Daten
aufnehmen und in einem binary file hintereinander zu schreiben.
Brauche also zunächst eigentlich auch aktuell keine Kommunikation in OUT
Richtung zum Device, obwohl ich die vermutlich dennoch einbinden muss,
da sonst die Abfragen der FiFos vom PC aus nicht funktionieren oder?
Wenn du nur Daten in den PC lesen willst, brauchst du theoretisch nur
den IN Endpoint. Das geht natürlich und macht die Sache noch leichter.
Obwohl auf der FPGA Seite die OUT Geschichte wesentlich einfacher zu
handhaben ist, da gibts kein PacketEnd.
Hallo nochmal...
davon ausgehend das die Beispiele für den FX2 aus dem Cypress Dev.
Packet ursprünglich für das Cypress Eval. Kit geschrieben wurden, frage
ich mich gerade ob ich diese ohne Änderungen auf meinem Trenz Miniboard
überhaupt anwenden kann. Eigentlich sollte die zusätzliche Beschaltung
durch den FPGA doch zunöchst egal sein, da die USB Beispiele (z.B.
Bulkloop) ja darauf nicht zurückgreifen, oder? Hat da schon jemand
Erfahrungen gemacht?
Versuche gerade zunächst einmal das Bulkloop-File auf meinem Chip zur
Funktion zu bringen, bekomme es aber irgendwie nicht ans Rennen.
Hallo nochmal.
Habe mich nun gestern durch das TRM, insbesondere den Slave FiFo Part in
Chapter 9 gewühlt.
Mit meinem neu gewonnen Wissen habe ich jedoch direkt ein Problem mit
dem Cypress bulkloop.c Beispiel:
Dort steht in der TD_Init Routine:
1
//set the slave FIFO interface to 48MHz
2
IFCONFIG|=0x40;// 0100 0000
für ein Slave FIFO mit interner 48 MHz IFClk müsste es aber doch
eigentlich heißen:
1
//set the slave FIFO interface to 48MHz
2
IFCONFIG|=0xC3;// 1100 0011
steh irgendwie schon wieder völlig auf der Leitung...
Also meine SyncBulk.c liegt im Anhang bei, falls jemand die Zeit hat mal
eben drüber zu gucken.
Bei Compilieren werden mir noch jede Menge Warnungen ausgespuckt die
meisten lauten "UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS ...",
denke mal das sind die Interrupt Routinen, welche ja im Slave FIFO Mode
wenn ich das richtig verstanden habe keine Funktion erfüllen. wenn dem
so ist könnte ich diese Warnungen ja einfach ignorieren ... oder?
Einige Warnungen beziehen sich jedoch auf "UNRESOLVED EXTERNAL SYMBOL"
oder auch "REFERENDE MADE TO UNRESOLVED EXTERNAL SYMBOL" ...
Hab im Moment noch nicht so den Durchblick wie ich mit diesen Warnungen
umgehen soll.
Vor ein weiteres Problem stellt mich die dscr.a51 ... deren Syntax
durchblick noch gar nicht. Gibts irgendwo ne Beschreibung der Assembler
Syntax die dort verwendet wird? Die Mnemonics db und dw sagen mir noch
nichts ...
Mal mein bisheriges Verständnis dieser Datei (descr.a51) :
1. DeviceDscr:
Ich habe keine Ahnung was hier definiert wird. habe dazu im Moment im
TRM noch nichts gefunden.
2. DeviceQualDscr:
Denke mal hier handelt es sich um den im TRM Table A-2 benannten
"Device Qualifier"?
hier weiß ich jedoch nicht so recht welchen Wert ich den Device
Classes und dem DeviceProtocol zuweisen soll. Und leider ist im TRM
keine Device Sub-Sub-Class erwähnt ... im Bulkloop Beispiel aber
schon.
Eigentlich sollte dort aber das DeviceProtocol gesetzt werden, oder?
Die MaxPaketsize würde ich gefühlsmäßig auf 512 setzen, da das die
maximale Paketgröße ist die ich in meinem IN EP6 verwenden will.
Number of Configurations = 1? oder 2 wegen FullSpeed Alternative?
3. lese nochmal was weiter ... weitere Fragen kommen bestimmt :-)
Danke schon mal für jetwede Antwort!
Gruß,
Stefan
Poste mal ein Zip mit dem gesamten Projekt des Keil-Compilers. Da sind
sicher einige Einstellungen im Kompiler noch falsch. Mit dem von mir
hier mal geposteten Quellcode gibts 0 Warnungen und 0 Fehler.
DeviceDescriptor: Da steht drin, welche Interfaces, Konfigs, Endpoints
usw. das Gerät hat. Schau dir die Beuspiele im BulkLoop und so an, ist
eigentlich selbsterklärend. Anbei mal ein Beispielfile, was zu dem
Quellcode aus dem anderen Post von mir passt.
Max. paketgröße ist 512 Byte für BULK bei HighSpeed und 64 Byte bei
FullSpeed. Das muss der Chip auf Anforderung umschalten. Ist aber im
Cypress Quelltext schon immer drin (dieses umkopieren da relativ am
Anfang). Die FIFOs müssen dann entsprechend konfiguriert werden, dafür
gibts ein Bit im Statusregister, ob man jetzt im HighSpeed oder
FullSpeed Modus ist. Hab ich in meinem Quelltext alles korrekt drin.
Achso, db define Byte, dw define word ist wie #define nur halt ASM.
Musst du ja nicht anfassen, nur die Zahlen ändern.
Anbei mein Keil Projektordner als ZIP Archiv.
Danke für deine Hilfe! Hoffe das meiste korrekt konfiguriert zu haben.
Bietet die Keil Umgebung eigentlich eine Möglichkeit den Code
Ansatzweise zu simulieren / debuggen? Ist ja ein wenig schwierig fest zu
stellen ob ein eventueller Fehler im SW Anteil des FX2 oder im Hw Anteil
des FPGA liegt oder?
Auf jeden Fall fehlt die EZUSB.LIB und die USBJmpTb.a51 aus dem
Verzeichnis C:\Cypress\USB\Target\Lib\FX2 in deinem Projekt. Desweiteren
findet er die Header nicht. Da hab ich aber auf die schnelle jetzt nicht
den Suchpfad gefunden, wo man das einstellt. Debuggen geht nur mit einem
entsprechendem Debugger, wenn man die größeren gehäuse hat. Ansonsten
gibts so ne Art Monitor-Debugger, der über USB läuft, aber wie das geht,
und ob das mit der kostenlosen Keil Version geht, weiß ich nicht.
Ok. Danke schonmal für diesen Hinweis auf die EZUSB.lib und die
USBJmpTB.a51 damit reduzieren sich die 160 Warnungen schonmal nur noch
auf eine:
"WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT:
?PR?ISR_INT1?SYNCBULK"
Leider immer noch eine Warnmeldung die mir rein gar nichts sagt ...
Unter Project / Options for Target 'Target 1' C51 (Tab) gibt es eine
Einstellung eines Include Paths, welchen ich auf
C:\Cypress\USB\Target\Inc gesetzt habe. Ob das dort richtig ist weiß ich
aber leider auch nicht so 100 prozentig ...
Hab grade mal ausprobiert was geschieht wenn ich versuche eine "Debug
Session" zu starten ... Keil meldet mir dabei aber schon das das Code
Limit von 2048 Byte erreicht wurde da ich aktuell 2132 Bytes nutzen
würde.
Daher habe ich so das Gefühl ich muß die fw.c auch noch anpassen um
unter diesem Limit zu bleiben. Ziemlich viel Arbeit dafür, dass ich die
CPU eigentlich gar nicht nutze ... aber da muß ich jetzt wohl durch ...
rseg DSCR ;; locate the descriptor table in on-part memory.
Da fehlt schon mal ;; vor DSCR, das ist nämlich ein Kommentar.
Dann musst du noch wie in meinem File oben
cseg at 90H
rein schreiben, und das rseg rausnehmen, ohne gehts irgendwie nicht. Das
hat wohl irgendwas mit der Speicher-Belegung zu tun. In der fw.c
solltest du erst mal nix anfassen.
Hi christian,
dann hier auch noch mal ne Frage ... :)
Du hast in deinem hier geposteten sync_bulc.c folgende Zeilen stehen:
1
// FX2 USB PortA = slave fifo enable(s) when IFCFG[1:0] = 11
2
sbitPA0=IOA^0;// alt. function INT 0
3
sbitPA1=IOA^1;// alt. function INT 1
4
//sbit PA2 = IOA ^ 2; // is sloe
5
sbitPA3=IOA^3;// alt. function WU2
6
//sbit PA4 = IOA ^ 4; // is FIFO Adress 0
7
//sbit PA5 = IOA ^ 5; // is FIFO Adress 1
8
//sbit PA6 = IOA ^ 6; // is PKTEND
9
//sbit PA7 = IOA ^ 7; // is FLAGS / SLCS
Sind die auskommentierten Zeilen Default Einstellungen? Bzw. muss ich
dem Controller durch ein entfernen der Kommentare mitteilen, wenn er
z.B. PA4 als FIFOADR0 nutzen soll?
Und ein weitere Frage hast du Erfahrungswerte welche Übertragungsrate
man mit dem 8bit FIFO so erreichen kann ?
Auf dem Board ist ein 24 MHz Oszillator drauf ... und Trenz hat wie ich
nun leider feststellen musste, nachdem ich in dem "Doku"-Gerümpel einen
Schaltplan gefunden habe, leider nur Port B für die Datenübetragung
genutzt und den Port D für irgendwelches SPI Gedrisse verplant ...
mein nächstes Board muß ich dann wohl selber designen und mir vorher mal
ein USB cypress Eval Board zum üben holen....
Also diese Definitionen sind nur für den Compiler, damit man dann z.B.
schreiben kann:
PA0 = 1;
Hat mit den Port-Funktionen erst mal nix zu tun. Die werden per Register
extra umgestellt. Und zwar mit PORTACFG usw.
Naja, der 24Mhz Quarz ist ja erst mal nur für den FX2 an sich. Du kannst
mit dem 8 Bit Port auch USB voll auslasten, denn du kannst ja einen
externen Takt anlegen (vom FPGA) oder aber die 48MHz IFCLK ausgeben
lassen. Das würde ich aber nicht machen, das Timing ist Harakiri und
kaum beherrschbar dann. Wir arbeiten mit 40MHz externem Takt das geht
recht bequem. Mit 40MHz und 8 Bit erreichst du auch die 40MB/s, wenn
dein FPGA kontinuierlich Daten liefern kann.