Hallo, ich bin gerade dabei, den CY7C68013A USB-Controller (die 56-Pin Variante) von Cypress zusammen mit einem FPGA in Betrieb zu nehmen. Ich arbeite im Bulk-Modus und verwende Puffergrößen von 4 mal 512 Byte (also alle Endpoints (2, 4, 6 und 8) werden benutzt). Die Datenübertragung vom PC zum FPGA funktioniert auch schon einwandfrei, nun mache ich allerdings eine äußerst merkwürdige Beobachtung beim Übertragen von Daten vom FPGA zum PC: Pakete mit einer Größe bis 63 Byte werden wie erwartet übertragen. Beim Versuch größere Pakete zu übertragen, wird aber beim Lesen vom PC der Wert 0 für die Größe des übertragenen Paketes angegeben und die Daten können nicht korrekt ausgegeben werden. Ganz gleich, welche Einstellungen ich schon geändert habe (z.B. Busbreite, Auto-Commit, Puffergrößen...), verändert sich dieses Verhalten des Controllers nicht und es können nur Pakete mit einer Größe unter 64 Byte übertragen werden. Ich würde gerne nachvollziehen, woher dieser markante Wert stammt. Seit einiger Zeit zerbreche ich mir schon den Kopf, von was dieser 64er Wert abhängt und wie man ihn ändern (-> 512) könnte. Habt ihr schon einmal ähnliche Beobachtungen gemacht oder vielleicht sogar einen Verdacht, woran es liegen könnte? Es wird übrigens noch viel merkwürdiger: Wenn man am Anfang die gleiche Konfiguration (siehe unten) lädt, die aber statt EP6 den EP8 neu konfiguriert (vgl. „###“-Markierung im Quelltext), dann einmal ein Paket (< 64 Bytes) überträgt, anschließend ganz kurz Reset aktiviert, danach die eigentliche Konfiguration lädt und schließlich noch mal ein Paket (< 64 Bytes) überträgt, so funktioniert auch die Übertragung von größeren Paketen (z.B. 512 Bytes) tadellos. Sobald man aber irgendetwas an diesem Verfahren verändert, gibt es wieder den bekannten Fehler. Ich verfolge schon seit längerer Zeit die anderen Beiträge zum Thema USB-Übertragung im Forum und hoffe, dass jemand von den erfahreneren Experten meine Beobachtung zu deuten weiß. Ich erwarte keinesfalls, dass hier jemand die Arbeit für mich macht ;-) Über jeden kleinen Hinweis würde ich mich sehr freuen, vielleicht kommt euch das ja bekannt vor. Vielen Dank für eure Mühe, Julius Hier ist ein Ausschnitt (nur der Initialisierungs-Teil, sonst wird außerhalb von „fw.c“ nichts mehr gemacht) des Quelltextes: ______________________________________________________________ // set the CPU clock to 48MHz CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ; // set the slave FIFO interface to 48MHz IFCONFIG |= 0x40; //IFCONFIG = 0xc3; SYNCDELAY; // default: all endpoints have their VALID bit set // default: TYPE1 = 1 and TYPE0 = 0 --> BULK // default: EP2 and EP4 DIR bits are 0 (OUT direction) // default: EP6 and EP8 DIR bits are 1 (IN direction) // default: EP2, EP4, EP6, and EP8 are double buffered // we are just using the default values, yes this is not necessary... EP1OUTCFG = 0xA0; EP1INCFG = 0xA0; SYNCDELAY; // see TRM section 15.14 EP2CFG = 0xA2; SYNCDELAY; EP4CFG = 0xA0; SYNCDELAY; EP6CFG = 0xE2; SYNCDELAY; EP8CFG = 0xE0; // out endpoints do not come up armed // since the defaults are double buffered we must write dummy byte counts twice SYNCDELAY; EP2BCL = 0x80; // arm EP2OUT by writing byte count w/skip. SYNCDELAY; EP2BCL = 0x80; SYNCDELAY; EP4BCL = 0x80; // arm EP4OUT by writing byte count w/skip. SYNCDELAY; EP4BCL = 0x80; // enable dual autopointer feature AUTOPTRSETUP |= 0x01; PINFLAGSAB = 0xE4;SYNCDELAY; // 10.07.08 send flags to pins, FLAGA=EP2PF ! PINFLAGSCD = 0xF5; SYNCDELAY;// 10.07.08 send flags to pins, FLAGC=EP4PF ! EP2FIFOPFH = 0x00;SYNCDELAY; // Configure programmable flags A/C EP2FIFOPFL = 0x01;SYNCDELAY; EP4FIFOPFH = 0x00;SYNCDELAY; EP4FIFOPFL = 0x01;SYNCDELAY; Rwuen = TRUE; // Enable remote-wakeup IFCONFIG = 0xc3; SYNCDELAY; // internal clock set 48MHz, fifo slave + external master REVCTL=0x03; SYNCDELAY; // auto in REVCTL = 0x03; // REVCTL.0 and REVCTL.1 set to 1 SYNCDELAY; //########################## //########################## !!! In anderem (erstem) Hexfile bezieht sich dieser markierte Teil statt auf EP6 auf EP8. EP6CFG = 0xE0; // EP8 is DIR=IN, TYPE=BULK SYNCDELAY; FIFORESET = 0x80; // Reset the FIFO SYNCDELAY; FIFORESET = 0x08; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; EP6FIFOCFG = 0x0C; // EP8 is AUTOOUT=0, AUTOIN=1, ZEROLEN=1, WORDWIDE=0 SYNCDELAY; EP6AUTOINLENH = 0x02; // Auto-commit 512-byte packets SYNCDELAY; EP6AUTOINLENL = 0x00; //########################## !!! //########################## // auto out REVCTL = 0x03; // REVCTL.0 and REVCTL.1 to set to 1 SYNCDELAY; EP2CFG = 0xA2; // EP2 is DIR=OUT, TYPE=BULK, SIZE=512, BUF=2x SYNCDELAY; FIFORESET = 0x80; // Reset the FIFO SYNCDELAY; FIFORESET = 0x02; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; OUTPKTEND = 0x82; // Arm both EP2 buffers to “prime the pump” SYNCDELAY; OUTPKTEND = 0x82; SYNCDELAY; EP2FIFOCFG = 0x10; // EP2 is AUTOOUT=1, AUTOIN=0, ZEROLEN=0, WORDWIDE=0 EP2FIFOCFG = 0x19; //0x1D; //0xFF; // Auf diese 4 Zeilen reagiert SLWR-Funktion sensibel: Als ob PKTEND aktiv wäre, falls nicht bestimmtes Bit 0 oder default...??..?? EP4FIFOCFG = 0x19; //0x1D; //0xFF; EP6FIFOCFG = 0x19; //0x1D; //0xFF; EP8FIFOCFG = 0x19; //0x1D; //0xFF;
Das klingt ganz stark, als würde sich entweder der FX2 nur als FullSpeed Device melden, oder aber der Host-Controller bzw. Hub kann nur Full-Speed. Dann ist die Paketgröße nämlich maximal 64 Byte. Du kannst übrigens auch einen einzigen EP 4-fach puffern, da sparst du dir das Umschalten zwischen den Adressen. So machen wir das hier. Was sagt denn die CyConsole? Hat der wirklich 512 Byte Paketgröße? Hast du in den EP-Deskriptoren auch die 512 Byte eingetragen? Irgendwo hier hatte ich mal einen getesteten Quellcode für den FX2 am FPGA hochgeladen, musst du dir mal anschauen. Edit: Lass mal das REVCTL Register so wie es ist, das hat bei mir Probleme gemacht.
Hallo, könntest du deinen Descriptor posten, der wäre noch interessant. Im Fullspeedmodus (12Mbit/s) dürfen laut Spec nur 64Byte übertragen werden, nur im Highspeedmodus 512Byte bzw. die FIFO-Größe darf so groß sein. Benjamin
Willst du eigentlich alle EP an das Slave FIFO Interface führen? Wenn ja, wieso schreibst du dann eine Bytelänge in EP2BCL und EP4BCL? UNd wieso überhaupt bei den OUT Endpints? Die Länge gibts du doch am Host vor. Wenn dann bräuchte man diese BCL und BCH Register, wenn man von der 8051CPU aus Pakete in den IN Endpoint stellen will. Aber bei Slave FIFO hast du an den Registern gar nix rum zu murksen, das läuft völlig autonom am 8051 vorbei. Du wolltest das TRM nochmal genauer studieren.
Hallo, ihr habt Recht, die Puffer kann man hier sicher noch sinnvoller aufteilen. CyConsole sagt auch, es sind im Moment noch 512 Byte. Wahrscheinlich werde ich 2x1024 Byte auf jeder Seite verwenden, um gleichzeitig in einen Endpoint lesen und schreiben zu können. Danke, Christian und Benjamin! Stimmt tatsächlich, der USB-Controller war nur auf Full-Speed eingestellt. Habe ihn nun gleich nach der Initialisierung auf High-Speed gesetzt und die Übertragung von größeren Paketen funktioniert jetzt! Für alle mit einem ähnlichen Problem, die das zu einem späteren Zeitpunkt lesen: Seite 56 im Manual hat genauere Informationen und dieser Teil hilft beim Umschalten: pConfigDscr = pHighSpeedConfigDscr; ((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR; pOtherConfigDscr = pHighSpeedConfigDscr; ((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR; EZUSB_IRQ_CLEAR(); USBIRQ = bmURES; // Clear URES IRQ Aber zur Sicherheit nicht den USB-Reset-Teil auf High-Speed einstellen, das kann zu noch viel größeren Problemen führen. Nein, für das Interface brauche ich nicht alle Endpoints, nur EP2 und EP6... das habe ich bei dieser Version noch nicht übernommen. OK, BCL und BHC sind dann wohl völlig überflüssig. Da lässt sich ja ohnehin noch sehr viel kürzen, weil vieles davon default-Werte sind. Vielen lieben Dank für eure Hilfe! Das hätte ich selbst nicht so schnell herausgefunden ;-) Julius
1024 Byte bei BULK transfer klappt aber nicht. Man kann es zwar einstellen, aber es funktioniert dann nicht gescheit. Außerdem ist dann irgendwann der RAM alle, ich glaub 4x 512 und 2x 512 Byte klappt gerade noch so. Wir haben hier auch für den OUT Endpoint doppelt-gepuffert und für den IN-Endpoint 4-fach gepuffert. Der Upstream ist bei uns wesentlich mehr. Hier hatte ich mal den komplett getesteten Code gepostet, kannst du verwenden: Beitrag "Re: USB-Port auf Spartan 3E für Anwendung nutzen" Die fw.c sollte man tunlichst nur ändern, wenn man ganz genau weiß, was man macht. Um diese FullSpeed/HighSpeed Geschichte kümmert der sich bei den Code-Beispielen von alleine.
Ja, die Puffer sind bei Highspeed und Bulk 512 Byte groß, bei Isochron max 3x1024 Byte. Hoffe du kommst weiter Benjamin
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.