Forum: Mikrocontroller und Digitale Elektronik FX3: Mehrere I/F


von P. K. (pek)


Lesenswert?

Hallo zusammen

Hatte eigentlich einen sehr schnellen Start mit dem FX3 DVK, das Slave 
FIFO und das I2C-Beispiel funktionieren soweit.

Da ich mehr von der Hardwareseite komme, und von ThreadX bis jetzt nicht 
gross 'ne Ahnung habe, stellt sich folgende Frage: Ich habe in meinem 
System I2C, SPI, GPIOs, UART, Slave-FIFO und später dann noch ein 
eMMC-Memory (FX3S). Ich benötige einen IN und OUT Endpoint für das 
Slave-FIFO, einen IN und OUT Endpoint  für das eMMC-Memory, der ganze 
Rest soll über den Command-EP0 adressiert werden.

Die Beispiele im Cypress-DVK (und auch die Doku, soweit ichs bis jetzt 
überblicke) behandeln jeweils genau ein einziges I/F, deshalb stehe ich 
ein wenig am Berg, wie die ganze Firmware strukturiert werden soll, wenn 
ich mehrere davon habe:
Ich kriege den Eindruck, dass da ein einziger Application-Thread sein 
soll, mit einem einzigen Application-Init (habe ja auch nur eine einzige 
Debug-Uart und kann den USB nur einmal starten). Reicht es nun, alle I/F 
zu initialisieren und dann die Callbacks pro EP zu etablieren 
(...SetupCallback) und zu betreiben (...EventCallback), oder stehe ich 
mir da auf den eigenen Füssen herum?
Wie macht Ihr das? Gibt es allenfalls irgendwo ein Beispiel?

Gruss

von Christian R. (supachris)


Lesenswert?

Du musst dann zunächst mal in den USB Descriptoren 4 Endpoints 
definieren. Die kannst du dann in der Firmware einstelllen und entweder 
DMA Kanäle zuordnen oder auch nicht (Dann EventCallback erstellen, siehe 
Bulkloop manual Beispiel). Insgesamt kann der FX3 32 Endpoints 
behandeln, reicht also dicke. GPIF-DMA kann nur 4 Threads, also quasi 4 
Kanäle. DMA Kanäle ansonsten müsste es aber auch genug geben, genaue 
Anzahl müsste ich nachschlagen. Mit dem FX3S kenn ich mich auch nicht so 
aus, aber den normalen FX3 bemuttele ich seit einer ganzen Weile. Deine 
EP0 Kommandos kommen dann in z.B. "CyFxSlFifoApplnUSBSetupCB()" rein, da 
solltest du am besten Vendor Kommandos benutzen.

: Bearbeitet durch User
von P. K. (pek)


Lesenswert?

Das mit den Descriptoren ist soweit mal klar, ebenfalls das zentrale 
ConfigureIOMatrix, Merci!

Das würde also bedeuten, dass ich gar nichts unterteile, sondern alles 
zusammengeführt wird, also aus:
1
   CyU3PUsbRegisterSetupCallback(CyFxSlFifoApplnUSBSetupCB, CyTrue);
und
1
   CyU3PUsbRegisterSetupCallback(CyFxUSBI2CSetupCB, CyTrue);
und
1
   CyU3PUsbRegisterSetupCallback(CyFxUSBSPISetupCB, CyTrue);

wird dann
1
   CyU3PUsbRegisterSetupCallback(CyFxUSBAlleZusammenSetupCB, CyTrue);
mit dem gesammelten Inhalt der Einzelbeispiele (Vendor Kommandos 
abhandeln und DMA einrichten etc. alles in derselben Methode)?

von Christian R. (supachris)


Lesenswert?

Also die IOMatrix ist für das GPIF und die restlichen IO GEschichten, 
das hat mit USB erst mal nix zu tun. Die Endpoints werden in der 
descriptor Datei definiert und dann mit den entsprechenden Funktionen 
und den richtigen Indizes dem USB Host auf seine Anfrage hin bekannt 
gegeben. Da kannst du viele Endpoints machen. Die müssen natürlich auch 
alle konfiguriert werden, dafür reicht eine Funktion, einfach erweitern. 
Die DMA Kanäle kannst du natürlich auch alle hintereinander in einer 
Funktion einstellen und aktivieren. SetupCallback kann es natürlich nur 
eines geben, denn darin musst du dann dekodieren, ob es ein USB Standard 
Request oder Vendor Request ist, was das Target ist (Device, Interface 
oder Endpoint) und was das Kommando jetzt machen soll. Darüber läuft 
dann sämtliche Kommunikation durch den Control Endpoint 0.

: Bearbeitet durch User
von P. K. (pek)


Lesenswert?

OK. Ich denke das gibt mir mal einen Überblick wie ich das ankpacken 
soll (das "SetupCallback kann es natürlich nur eines geben" war 
vermutlich die essentielle Info, welche ich gesucht hatte). Vielen Dank!

von P. K. (pek)


Lesenswert?

Eine Frage in diesem Zusammenhang hätte ich noch, und zwar betreffend 
der Thread stack size. In den Beispielen findet sich so ziemlich vieles 
(0x0400, 0x0800, 0x1000), aber ich habe nirgends Hinweise darauf 
gefunden, wie gross der Stack denn nun sein muss.

Gibt es einen deterministischen Weg, die Stackgrösse zu bestimmen, oder 
vergrössert man bei jedem (nicht fehlerbedingten) Overflow?

von Christian R. (supachris)


Lesenswert?

Das ist mir in der Tat auch schleierhaft, steht aber vielleicht irgendwo 
im Programmers Manual.

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.