Hallo,
in einem gemeinsamen Projekt beschäftige ich mich grade mit der PC
Anbindung eines CY7C68001 EZ-USB SX2™ High-Speed USB Interface Device.
Ich habe mir jetzt Gedanken über das Senden/Empfangen von Daten mit
einer Windows-Anwendung. Die Überlegung bestand darin nach der
Initalisierung (Device suchen, Endpoint Konfiguration auslesen und
abspeichern) einen Thread zu starten der zyklisch überprüft ob der
Cypress-Chip neue Daten verschickt. Sofern ich die CyApi und die CyAPI.h
richtig interpretiere gibt es leider keine Möglichkeit, dass der Chip
sich selber bei dem PC/Windowsprogramm meldet (auslösen von
Interrupt/Thread/Event), wenn er neue Daten versenden möchte. In diesem
"RecieveThread" sollen dann die Funktion BeginDataXfer(), WaitForXfer()
und FinishDataXfer aufgerufeb werden und anhand deren Rückgabewerte
entschieden werden ob es neue Daten gab.
Ein andere Thread soll ausgelöst werden, sobald der Benutzer/das
Programm Daten an den Chip senden möchte und sich wieder beenden.
Nun zu meinen Fragen:
1. Gibts irgendwo noch Code-Beispiele zur Anwendung der CyApi?
2. Gibts noch eine elegantere Lösung als das "polling" nach neuen Daten?
3. Kümmert sich die CyApi.dll um den exklusiven Zugriff auf den
USB-Port, oder muss ich in beiden Threads beim Zugriff auf den Port ein
Mutex setzen und wieder lösen um keine Probleme bei der Kommunikation zu
bekommen?
Mit freundlichem Gruß
Domi
1. Massenhaft Code gibts in dem 70MB großen Komplett-Paket von Cypress
für den FX2:
http://download.cypress.com.edgesuite.net/design_resources/developer_kits/contents/cy3681_ez_usb_fx2_development_kit_15.zip
Da sind auch Beispiele für den SX2 drin. CyAPI ist ja eh dei gleiche.
2. Das geht nur über Polling, denn ein USB Device ist immer der Slave,
der schickt niemals selbst Daten. Alle Daten werden vom Host
angefordert.
3. Die CyAPI macht das, du kannst einen oder mehrere Lese- und/oder
Schreib- Threads gleichzeitig laufen lassen, beispielsweise um mehrere
Endpoints "gleichzeitig" auszulesen.
Super, danke für die Erläuterungen.
In dem Paket konnte ich aber keine Beispiele finden, in dem die CyApi
genutzt wurde. Naja vielleicht findet sich noch etwas.
Hallo,
bin inzwischen weitergekommen, habe jetzt einen Thread der nacheinander
die Endpoints abfragt und mögliche Daten ausließt. Dieser Thread lässt
sich aber offensichtlich nicht richtig beenden oder irgendetwas bleibt
noch aktiv trotz Beendigung (die Treiber-Lib vielleicht???). Eine
Variable, die ebenfalls in der Schleife abgefragt wird, nutze ich um den
Thread zu beenden. Beim Durchsteppen mit dem Debugger sehe ich auch,
dass ich aus dem Thread.
Mein eigentliches Programm kann sich aber nicht beenden solange die
Platine an ist (werden ständig Daten gesendet), wenn ich diese jedoch
ausschalte ist der Prozess aus dem TaskManager verschwunden.
In meiner Klasse in der ich die CyApi anwende, wird bei
Destruktor-Aufruf das USBDevice geschlossen:
m_pUSBDevice->~CCyUSBDevice(); Muss ich sonst noch irgendetwas machen,
damit sich das Ding trennt und mein Programm beendet werden kann?
Guten Morgen,
ich habe die Vermutung, dass der eigentliche Treiber CyUSB.sys noch
aktiv ist (die Verbindung zwischen Programm und Lib aber durch den
~CCyUSBDevice() Aufruf aber beendet wird), gibt es eine Möglichkeit das
festzustellen bzw. diesen zu entladen/killen was auch immer? ;)
So habe ein Event genutzt zum Beenden des Threads, dieser beendet sich
auch. Der Prozess des Hauptprogramms bleibt aber trotzdem im Taskmanager
erhalten (das Fenster ist nicht mehr zu sehen, nachdem ich es beendet
habe) solange die Platine an ist. Sobald ich diese abschalte
verschwindet auch der Prozess. Irgendetwas vom USB ist noch aktiv. Habe
auch mal testweise die asynchrone Datenübertagung mit XferData
ausgetautsch:
unsigned char inBuf4[512] = {0};
long length = 512;
pCUSBBox->m_pUSBDevice->EndPoints[2]->XferData(inBuf4, length4);
Dann habe ich aber trotzdem noch das gleiche Verhalten mit dem Prozess
der sich nicht beendet. Sobald ich die Datenübertragung auskommentiere,
also nur einen leeren Thread laufen lasse, schließt sich der Prozess
nach Programmbeendigung ohne Probleme.
help ;)
Blöd, dass es keine Funktion in der CyAPI.h zum Abfragen der Endpoints
nach Daten gibt...
Ich habe auch ein Board auf dem der SX2 CY7C68001 vorhanden ist. Ich
hatte damals diese Board gekauf, da die Ansteuerung vom FPGA aus recht
einfach gestaltet ist.
Jedoch habe ich noch so einige Fragen:
1. Ist auf dem Chip schon eine Firmware vorhanden, oder muss ich einen
externen EEPROM anschließen, die dann die Firmware enthält?
2. Muss ich den Chip zuerst per USB konfigurieren oder wie wird das
gemacht?
3. Schicke ich vom PC aus einen Befehl in Richtung CY7C68001, so das der
mich über den Füllstatus der Fifos informiert?
Was für ein Datendurchsatz ist denn mit diesem Chip zu erwarten? Es
steht auf der Cypress Seite das dieser Chip überarbeitet wurde, aber
leider nicht welcher der Nachfolger ist.
Gibt es auch ähnlich Chips für Firewire 400 oder 800?
Michale wrote:
> 1. Ist auf dem Chip schon eine Firmware vorhanden, oder muss ich einen> externen EEPROM anschließen, die dann die Firmware enthält?
Nein, denn der SX2 hat gar keinen integrierten 8051 Kern, somit keine
Firmware. Du musst alles per externem Controller einstellen.
> 2. Muss ich den Chip zuerst per USB konfigurieren oder wie wird das> gemacht?
Nein, siehe oben. Das muss ein externer Controller machen.
> 3. Schicke ich vom PC aus einen Befehl in Richtung CY7C68001, so das der> mich über den Füllstatus der Fifos informiert?
Nein. Wenn Daten im FIFO sind, und der Endpoint entsprechend
konfiguriert wurde, kannst du die Daten abholen, sind keine Daten oder
zu wenig da, bekommst du ein TimeOut.
Tu dir einen Gefallen, und verwende den 68013, also den FX2, der hat
einen integrierten 8051 Core, der alles erledigt.
zur Geschwindigkeit: Direkt aus dem Chip heraus hab ich etwa 40 MByte/s
hinbekommen. Externes Slave-FIFO Interface müsste ähnlich sein, kann ich
demnächst testen.
Für FireWire gibts solche Chips nicht, da der FW-Stack riesengroß ist.
WIr verwenden kleine Module von www.orsys.de
Schon mal Danke für Deine Antworten. Ich finde die Doku bei Cypress sehr
schlecht. Dort ist mir halt nicht wirklich klar geworden das ich diesen
Chip erst konfigurieren muss bevor ich ihn verwenden kann.
Den Vorteil des 68013 kann ich nicht erkennen. Wieso ist es besser einen
8051 Core im USB-Device zu haben? Ich dachte immer der 68001 ist
leichter anzusteuern, da der schon fertig konfiguriert ist und ich nur
noch die Daten anlegen muss.
Michael wrote:
> Den Vorteil des 68013 kann ich nicht erkennen. Wieso ist es besser einen> 8051 Core im USB-Device zu haben? Ich dachte immer der 68001 ist> leichter anzusteuern, da der schon fertig konfiguriert ist und ich nur> noch die Daten anlegen muss.
Wenn du den 68001 an einen Controller hängst, kannst du die ganze
Einstellerei auch über den machen. Aber es sind eben einige Register,
die du beschreiben musst. Das würde im 68013 der 8051 erledigen. Wenn
man das Slave FIFO-Interface benutzt, hat der 8051 Core dann auch nix
mehr zu tun, der stellt alles ein und die USB-Engine übernimmt dann den
kompletten Datenverkehr.
Irgendwo stand mal, man könne die Register auch per USB einstellen, aber
in der Doku von Cypress ist nix zu finden.
Der Compiler (Keil C51) ist mit im Paket von Cypress kostenlos
enthalten. Für die Programmierung gibt es zwei Möglichkeiten:
- Du compilierst und linkst dein Programm und wandelst es in ein
spezielles Format um, um es anschließend in den EEPROM zu laden.
Der 8051 holt sich das Programm automatisch aus dem EEPROM in
seinen RAM.
- Du konfigurierst den Treiber des Cypress so, dass er beim Einstecken
des Gerätes an den USB Port des Rechners automatisch das Binary in
den RAM lädt.
Funktionieren tuen beide Varianten tadellos. Ist aber alles ausführlich
im Datenblatt beschrieben.
Edit: Alle benötigten Tools sind im Paket von Cypress enthalten.
Man kann aber auch den kostenlosen SDCC Kompiler benutzen, wenn man mehr
als 4k Programmspeicher braucht. Der Keil im Cypress-Paket ist
beschränkt. Aber für einfache Datenübertragung reicht das.
Ich muss sagen das ich mir das ganze einfacher vorgestellt hätte.
Momentan benutze ich einen FTDI-USB-Chip. Dieser hat einfach nur 1 Flag
der mir anzeigt ob die internen FIFOS voll sind. Solange diese nicht
voll sind schreibe ich einfach in die FIFOS meine Daten und der Rest
wird vom FTDI-IC gemacht. Ich werde mir mal das Datenblatt vom 68013
durchlesen. Mal sehen wie gut es beschrieben ist.
Dann werde ich sicherlich noch einige Fragen haben.
Momentan habe ich das SX2 Board von Cypress hier. Wenn ich das noch
richtig in Erinnerung habe ist dort der 68001 und der 68013 verbaut.
Michael wrote:
> Ich muss sagen das ich mir das ganze einfacher vorgestellt hätte.> Momentan benutze ich einen FTDI-USB-Chip. Dieser hat einfach nur 1 Flag> der mir anzeigt ob die internen FIFOS voll sind. Solange diese nicht> voll sind schreibe ich einfach in die FIFOS meine Daten und der Rest> wird vom FTDI-IC gemacht.
Wenn man den FX2 eingestellt hat, macht der auch nix anderes. Das
Framework von Cypress auf dem 8051 stellt nur alle Register passend ein
und dann arbeitet der Slave-FIFO autonom.
Ist in den Entwickler-Paketen sehr gut beschrieben, sind ja auch massig
Beispiele dabei. Man muss nur die Register entsprechend einstellen
(FIFOs aktivieren, Flags programmieren, Auto-In, Auto-Out...) und schon
gehts los. War selbst überrascht, wie einfach das geht.
Hallo,
meine ursprünglichen Problem konnte ich inzwischen lösen. Habe nun ein
neues Problem bzw. Unklarheit: Versendet oder empfängt die ich der
BeginDataXfer()-Funktion ein Datenarray genau in der EP-Größe oder kann
ich auch größere Datenpakete versenden/empfangen? Ich habe gelesen, dass
mehrere Pakete pro Microframe übertragen werden können nur wie kann ich
das umsetzen? Deshalb die Frage mit der Datenpuffergröße bei den
Datentransferfunktionen.
Du kannst auch viel viel größere Datenmengen übertragen als ein Paket.
Musst halt vorher mit SetXferSize die Größe setzen. Erst wenn man da 64k
oder größer einstellt (und dann auch soviel abholt), erreicht man die
volle Geschwindigkeit.