Forum: Projekte & Code STM32F4 USB High Speed VCP mit USB3320 PHY


von Markus R. (maggus)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe den USB HS Core vom STM32F4VGT auf einem Discovery mit dem 
externen PHY USB3320 zum laufen bekommen und möchte mein 
Beispielprogramm zu Verfügung stellen. Den USB3320 gibt es leider nur im 
QFN32, Alternativen habe ich allerdings keine gefunden. Mein 
funktionierender, wirrer Aufbau um das Discovery Board zeigt aber, dass 
es auch mit Adapterplatine geht.

Der USB3320 brauch einen externen Takt (oder eigenes Quarz) zur Speisung 
seiner 60Mhz PLL. Ich verwende dazu den MCO2 Ausgang des STM32F4 in 
Verbindung mit der internen PLL2, die 52Mhz ausgibt. Gegen Jitter 
scheint der USB3320 relativ unempfindlich zu sein, siehe auch 
Datenblatt.

Für die restliche Verdrahtung gibt es nur eine Möglichkeit, da die PINs 
des ULPI Interfaces vom STM32F4 fest sind. Versorgt wird der USB3320 mit 
den 3V des Discovery Boards (was so ziemlich die untere Grenze 
darstellt), die 1,8V werden mittels Labornetzteil zur Verfügung 
gestellt. RESETB liegt auf PC15.

Ich verwende den STM32F4 nur als CDC Device (VCP), deshalb liegt der 
ID-Pin des USB3320 auf VDDIO.

Zur Software: Ich habe jetzt einfach mal das komplette CooCox CoIDE 
Projekt angehängt. Für alle, die kein CoIDE verwenden, es müssen 
folgende defines vorhanden sein:

STM32F407VG
HSE_VALUE=8000000
STM32F40_41xxx
USE_STDPERIPH_DRIVER
USE_USB_OTG_HS
USE_ULPI_PHY

Nachdem ein beliebiges Zeichen an den STM32F4 gesendet wird, werden 
10000 mal 4096 Bytes an den Host gesendet. Vor jedem Senden werden die 
4096 Bytes in den Sendepuffer des USB Stacks kopiert. Mit einem kleinen 
LabVIEW Programm habe ich so die Geschwindigkeit gemessen und komme auf 
ca. 3,4MByte pro Sekunde.

Wenn man sich das Umkopieren spart (bzw. in der tatsächlichen Anwendung 
per DMA erledigt) und lediglich den Pointer in der Funktion VCP_DataTx 
um 4096 erhöht
1
static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
2
{
3
  uint32_t i=0;
4
5
  /*  while(i < Len) {
6
      APP_Rx_Buffer[APP_Rx_ptr_in] = *(Buf + i);
7
      APP_Rx_ptr_in++;
8
      i++;
9
      // To avoid buffer overflow
10
      if(APP_Rx_ptr_in >= APP_RX_DATA_SIZE)
11
      {
12
        APP_Rx_ptr_in = 0;
13
      }
14
    }*/
15
  APP_Rx_ptr_in = (APP_Rx_ptr_in + 4096) % APP_RX_DATA_SIZE;
16
17
  
18
  return USBD_OK;
19
}

ergibt sich eine Übertragungsgeschwindigkeit von ca. 11,6MByte pro 
Sekunde. Dabei muss allerdings in der main-Schleife zwischen den 
Übertragungen mit delay_us(300) 300us gewartet werden, sodass der Puffer 
nicht überläuft. Könnte man natürlich auch noch etwas eleganter lösen, 
für einen ersten Test reichts aber.

Prinzipiell funktioniert das ganze auch mit dem LS Core und der 
Schnittstelle, die das Discovery schon on board hat. Dazu muss 
USE_USB_OTG_HS durch USE_USB_OTG_FS ersetzt werden und USE_ULPI_PHY aus 
den defines entfernt werden. Außerdem ist auf das Timing beim schreiben 
des Puffers zu achten.

Ich habe das Programm hauptsächlich aus Teilen der 
STM32_USB-Host-Device_Lib_V2.1.0 und den enthaltenen Beispielen 
erstellt, außerdem hat mir die Demo auf dieser Seite geholfen: 
http://mikrocontroller.bplaced.net/wordpress/?page_id=1263

Wer Fragen oder Verbesserungsvorschläge hat, bitte hier posten.

von Gert (Gast)


Lesenswert?

Tolle Sache. Daumen hoch!

von Peter (Gast)


Lesenswert?

Wirklich klasse, Gratulation!

Zur Adapter-Platine: Hast Du die per Hand bestückt? Kann man sowas 
kleines löten?

Zur Schaltung: Hast Du vlt. einen kleinen Schaltplan für die Anbindung 
des USB3320?

Gruß Peter

von Markus R. (maggus)


Angehängte Dateien:

Lesenswert?

Hallo Peter,

Schaltplan habe ich mal erstellt. Abblockkondensatoren der ICs und 
Versorgung des STM32F4 fehlen, aber das Prinzip sollte klar werden.

Zum Löten: Ich hab mir bei Ebay die Adapterplatine für das QFN32 geholt 
und dann per Hand gelötet. Kniffelig war, dass der USB3320 das große Pad 
unter dem Gehäuse verlötet haben muss (GND). Bei der Adapterplatine ist 
dieses Pad zum Glück mit einigen Vias durchkontaktiert. Ich habe den 
Lötstopplack auf der Unterseite der Platine entfernt, das Pad auf der 
Oberseite verzinnt, das Zinn durch Hitzezufuhr mit dem Lötkolben von der 
Unterseite zum schmelzen gebracht und das IC mit der Pinzette auf das 
geschmolzene Zinn gelegt.
Die äußeren Pads zu verlöten war absolut unproblematisch, da Kontakte an 
den Seitenrändern des ICs vorhanden sind.

Ich muss aber dazu sagen, dass ich eine JBC Lötstation und ein 
Stereomikroskop verwende ;-)

Adapterplatine ist dieser hier:
http://www.ebay.de/itm/1x-QFN32-5mm-x-5mm-Adapter-P011-25-/281190068538?pt=Elektromechanische_Bauelemente&hash=item41783bf13a

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Hallo Markus,

vielen Dank für die zusaätzliche Info. Die ganze Sache ist sehr 
interessant.
Die Lösung mit der Adapterplatine ist wohl die günstigste aber es wird 
den ein oder anderen verschrecken. Ich kauf mir auch lieber mal alles 
doppelt.

Ansonsten Spitze! Evtl. kann man noch eine etwas aussagekrfäftigeres 
Beispiel machen. Per DMA einen Port abfragen und an den USB übergeben 
o.ä.. Ist nat. auch eine Frage des Aufwandes.

Und die 11,6 MB sind nat. sehr viel. Ein FX2 macht aber so um die 24. 
Stellt sich die Frage, ob das überhaupt möglich ist.

Gruß Peter

von Markus R. (maggus)


Lesenswert?

Peter schrieb:
> Ich kauf mir auch lieber mal alles doppelt.

IC und Adapterplatine sind ja zum Glück nicht teuer, da lässt sich das 
verschmerzen.

Noch ein kleiner Nachtrag zum code. Die Funktion usb_gets(...) in 
usbd_cdc_vcp.c muss geändert werden, da sonst empfangene Pakete verloren 
gehen können:
1
uint32_t usb_gets(uint8_t * buf)
2
{
3
  uint32_t len, i;
4
5
  if(usb_rx_len)
6
  {
7
    len = usb_rx_len;
8
    usb_rx_len = 0;
9
    // copy buffer
10
    for(i=0; i<len; i++)
11
      buf[i] = APP_Tx_Buffer[i];
12
  }
13
  else
14
  {
15
    len = 0;
16
  }
17
18
  return len;
19
}

Eleganter wäre es natürlich, noch einen Empfangs-Fifo zu implementieren, 
sodass keine Pakete überschrieben werden können.

Ob sich noch etwas mehr Geschwindigkeit machen lässt muss ich mal 
ausprobieren, momentan habe ich aber noch ein anderes Problem: Ich muss 
ca. pro Millisekunde 4200 Byte versenden. Das klappt sehr gut, wenn ich 
das Device direkt an einen USB-Port anschließe. Gehe ich aber über einen 
(Exsys 7 Port High Speed) Hub, hängt sich der USB Stack auf. 
USB_Tx_State bleibt auf 1, allerdings wird usbd_cdc_DataIn(...) nicht 
mehr angesprungen, die Daten werden also nicht mehr abtransportiert.

Das ganze passiert nach einer zufälligen Anzahl von verseneten 
4200-Byte-Paketen, allerdings scheinbar immer, nachdem die ersten 512 
Byte eines solchen Paketes durch Handle_USBAsynchXfer(...) versendet 
wurden. Es scheint, als würde dann der EP1-Transfer-Complete-Interrupt 
ausbleiben. Dieser ist aber nötig, damit usbd_cdc_DataIn(...) weiterhin 
angesprungen wird.

Den Füllstand von APP_Rx_Buffer prüfe ich manuell durch die Anfangs- und 
Endpointer APP_Rx_ptr_out und APP_Rx_ptr_in und sorge dafür, dass er 
nicht überläuft.

Im myST-Forum habe ich eine ähnliche Problembeschreibung gefunden, 
allerdings keine Lösung dazu.

von Peter (Gast)


Lesenswert?

So ein Hub braucht nat. auch seine Zeit, um den Datenstrom zu 
koordinieren. Kontinuierliches Streaming wird da wohl nicht möglich 
sein.

von Markus R. (maggus)


Lesenswert?

Peter schrieb:
> So ein Hub braucht nat. auch seine Zeit, um den Datenstrom zu
> koordinieren. Kontinuierliches Streaming wird da wohl nicht möglich
> sein.

Dass die Datenrate irgendwie aufgeteilt werden muss ist klar, aber das 
erklärt nicht warum das Paket scheinbar nicht ankommt (oder zumindest 
der Interrupt nicht ausgelöst wird). Um solche Fälle wie verlorene 
Pakete / zu hohe Buslast müsste sich doch eigentlich der Stack kümmern.

Ein Empfang von Daten ist auch weiterhin möglich, nachdem beim Senden 
nichts mehr geht.

von Peter (Gast)


Lesenswert?

Markus R. schrieb:
> Dass die Datenrate irgendwie aufgeteilt werden muss ist klar, aber das
> erklärt nicht warum das Paket scheinbar nicht ankommt (oder zumindest
> der Interrupt nicht ausgelöst wird). Um solche Fälle wie verlorene
> Pakete / zu hohe Buslast müsste sich doch eigentlich der Stack kümmern.

Da hast Du auch wieder Recht.

Ich würde einfach versuchen ein paar Dinge auszuschließen:
- Einfache Senderoutine (irgendwas konstantes, unabhängig vom Empfang)
- oder nur Senden / gar keinen Empfang.
- oder Datenrate senken.
- oder Polling-Betrieb.
- oder das Ganze mal an einem Full-Speed Hub betreiben (falls man sowas 
heutzutage noch kaufen kann).
- oder einen anderen High-Speed Hub verwenden.

Was passiert eigentlich, wenn usb_rx_len = -1 ist oder 9999999?

von Peter (Gast)


Lesenswert?

Markus R. schrieb:
> static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
> {
>   uint32_t i=0;
>
>   APP_Rx_ptr_in = (APP_Rx_ptr_in + 4096) % APP_RX_DATA_SIZE;
>
>
>   return USBD_OK;
> }

Auch das macht vermutlich nicht was es soll.

von usb_for_free (Gast)


Lesenswert?

Hi,

kann mir jemand kurz erklären, warum ein extra IC verwendet wird, wenn 
im STM32F4xx ein HS-USB Port vorhanden ist?

Danke und Gruß

von Gerd (Gast)


Lesenswert?

usb_for_free schrieb:
> kann mir jemand kurz erklären, warum ein extra IC verwendet wird, wenn
> im STM32F4xx ein HS-USB Port vorhanden ist?

Das ist wie beim UART am ATmega8. Ohne MAX232 IC geht da auch nix.

von Markus R. (maggus)


Lesenswert?

Gerd schrieb:
> Das ist wie beim UART am ATmega8.

Naja, so ähnlich. Der MAX232 ist ja nur ein Pegelwandler.

Das Interface zwischen STM32F4 und USB3320 ist ein paralleles mit 60Mhz 
Takt. Der USB3320 kümmert sich dann u.A. um die Serialisierung der Daten 
und das "Treiben" der D+ und D- Leitungen mit den passenden Pegeln.

ARMs mit HS USB PHY on board sind leider nicht ganz so verbreitet.

Peter schrieb:
> Auch das macht vermutlich nicht was es soll.

Dem Stack wird signalisiert, dass neue Daten in APP_Rx_Buffer bereit 
liegen, indem APP_Rx_ptr_in inkrementiert bzw. bei erreichen von 
APP_RX_DATA_SIZE auf 0 zurückgesetzt wird. Da ich ausschließlich Blöcke 
mit 4096 Byte senden will, schiebt der obige code den pointer immer um 
4096 weiter und setzt ihn am Ende auf 0 zurück. APP_RX_DATA_SIZE ist 
eine ganzzahliges vielfaches von 4096. Das ganze ist deshalb so, damit 
ich per DMA immer 4096 Byte schreiben kann, ohne über die Grenzen von 
APP_Rx_Buffer hinauszukommen.

Momentan bin ich etwas weiter, aber nicht klüger: Ich habe die Tipps von 
Peter teilweise umgesetzt und APP_Rx_Buffer leer gelassen und lediglich 
APP_Rx_ptr_in erhöht, wenn der "Füllstand" des Buffers es zulässt. Und 
siehe da, schon erreiche ich auch am USB-Hub die volle Datenrate von nun 
ca. 13MByte pro Sekunde.

Was ich aber nicht verstehe ist folgendes: Wenn ich an manchen Stellen 
in APP_Rx_Buffer den Inhalt ändere (ich wollte z.B. am Anfang jedes 
Paketes die Werte 255, 255, 0 haben), dann bricht die Übertragung nach 
einer (scheibar zufälligen) Anzahl von Paketen ab. Bei Anschluss an 
einem Port direkt funktioniert es unabhängig vom Inhalt des Buffers.

von Markus R. (maggus)


Lesenswert?

Mittlerweile denke ich, dass das ganze eher ein Hardwareproblem ist. Mit 
dem on Board Fullspeed PHY funktioniert es - zumindest soweit ich das 
bisher testen konnte.

Ich habe die Leitungen zwischen Discovery-Board und der PHY-Platine mal 
um ca. die Hälfte verkürzt und die Übertragung ist erheblich sicherer 
geworden. Vor allem die Änderung vieler Bits auf einmal (also z.B. die 
Übertragung der Zeichenfolge 255, 0, 255, 0, 255, 0... ) ist aber nach 
wie vor problematisch. Nachdem ich im Ausgangsposting immer den gleichen 
Wert übertragen habe, ist mir das damals nicht aufgefallen.

Um ein vernünftiges Layout wird man wahrscheinlich trotzdem nicht 
herumkommen, wenn beliebige Zeichenketten versendet werden sollen. Oder 
hat jemand einen Vorschlag, wie man es auch mit Discovery-Board und 
Adapterplatine halbwegs vernünftig zum laufen bekommen könnte?

Was ich noch nicht verstehe: Zeichenketten, die am USB Hub nicht 
funktionieren, funktionieren bei direkter Verbindung schon. Dabei müsste 
das doch eigentlich vom parallelen ULPI-Interface unabhängig sein?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

- Die Drähte auf Deinem Bild sind recht dick. Hast Du Fädeldraht?
- Die Drähte kürzen
- einen Widerstand von ca. 22 Ohm in die Drähte löten
- mehrere Abblockkondensatoren dem PHY spendieren, deiner hat ja gar 
nichts.

Große Geschwindigkeit = Störanfällig und da muss schon etwas für den 
EMV-Schutz getan werden.

von Karl (Gast)


Lesenswert?

hi,
hast du die Treiber für VCP von ST mit installiert oder kann man das 
ohne diese Treiber verwenden? Bin nämlich auf der Suche nach einer 
Lösung den USB-HS von einem STM32f4 zu verwenden, ohne diese Treiber 
extra installieren zu müssen.
Werde mir dein Projekt mal was näher ansehen. Danke.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Irgend einen Treiber wird man schon benötigen.
In der Regel meldet man sich mit VID/PID an und dann initialisiert man 
seine Art wie z.B. HID Device oder MassStorage und anhand dem wird der 
Treiber geladen.
Man kann somit auch z.B. LibUSB nutzen oder sonstige Tools.

von Karl (Gast)


Lesenswert?

Bin noch nicht so der Experte in USB-Sachen, da dies auch ein komplexes 
Thema ist. Ist es beim STM32F4 nicht möglich das mit Windowstreibern zu 
realisieren, also in der Art Plug and Play!?

von Jim M. (turboj)


Lesenswert?

WinUSB mit WCID müsste IMO gehen, ist aber erst ab Windows 8 ab Werk 
eingebaut. Mit WCID sagt das USB Gerät dem Windows OS Bescheid, dass es 
den WinUSB Treiber laden soll. Für STM32 gibt es AFAIK sogar fertigen 
Code.

Für Windows 7 und älter braucht man die übliche Inf Datei.

von Karl (Gast)


Lesenswert?

danke für die Infos. werde mal ein wenig rumexperimentieren.

von Markus R. (maggus)


Lesenswert?

@Karl: Ich hab den Treiber von ST installiert. Falls sich eine Lösung 
ohne den ST-Treiber findet, wäre ich auch interessiert!

@Markus Müller: Danke für die Vorschläge. Ich hätte zwar noch Fädeldraht 
und Wiederstände zum terminieren da, wollte jetzt aber nicht noch weiter 
an dem Verhau rumpfuschen. Bzgl. der Abblockkondensatoren: Die sind 
unter der QFN32-Adapterplatine montiert.
Ich hab jetzt mal ein 4-lagiges Layout mit STM32F4 und USB3320 (u.A.) 
drauf gemacht, wenn die Platine geliefert und bestückt ist werde ich das 
Ganze nochmal testen.

von Uwe B. (derexponent)


Lesenswert?

Hi Markus,

ich sitze gerade auch am USB3300
(allerdings ein fertiges Modul von E.B.A.Y)

konntest du die Daten, die du von der CPU aus sendest, am Empfänger 
verifizieren ?
(auf Vollständigkeit und Fehlerfreiheit ?)

ich habe das Problem das ich im Moment kein PC-Terminal-Programm finde,
das eine Datenrate größer 1MBit/sec fehlerfrei mitmacht :-(

du schreibst du hast es mit "LabVIEW" getestet
kennst du noch ein anderes Programm (das kostenlos ist)
und diese Transferraten unterstützt ?

Gruss Uwe

: Bearbeitet durch User
von Markus R. (maggus)


Lesenswert?

Hallo Uwe,

aufgrund der oben beschriebenen Probleme möchte ich noch kein Urteil 
über die Übertragungssicherheit fällen (auch wenn diese bei USB über 
einen "tieferen" Layer des Übertragungsmodells eigentlich sichergestellt 
sein sollte). Was ich aber bisher über meine Tests mit LabVIEW sagen 
kann ist:
- Wenn eine bestimmte Anzahl von Bytes gesendet wird (und sich die 
Kommunikation zwischen STM32F4 und PHY nicht durch die beschriebenen 
Hardwareprobleme aufhängt), dann kommen sie auch an.
- Zumindest die Stichproben, die ich bisher "per Hand" überprüft habe, 
waren immer fehlerfrei.
Genaueres wird sich zeigen, wenn meine Platine angekommen, bestückt und 
hoffentlich auch lauffähig ist. Das wird aber noch etwas dauern.

Zum Thema Terminalprogramm: Das von dir beschriebene Problem hatte ich 
auch (mit Hterm), deshalb bin ich dann auf LabVIEW zur Messung der 
Geschwindigkeit umgestiegen. Mit Terminalprogramm könnte es gehen, wenn 
du nur kleine Datensätze sendest (also nicht gleich mehrere 10MB). 
Allerdings müsste man dann die Zeit auch genauer stoppen können.

Eine LabVIEW Studentenversion ist übrigens im Buch "Einführung in 
LabVIEW" dabei, das häufig in FH/Uni-Bibliotheken zu finden ist.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Markus R. schrieb:
> und möchte mein
> Beispielprogramm zu Verfügung stellen.

Das ist sehr nett und löblich, aber trotzdem gefällt mir dein Beispiel 
nicht. Zuerst geht es nach meinem Gefühl viel zu kunterbunt 
durcheinander. Dein USB-Code ist mir viel zu wenig gekapselt und - was 
ganz wichtig ist - deine Herangehensweise zur Geschwindigkeitsmessung 
ist praxisfern. Mag ja sein, daß du immer nur 4K große Blöcke 
transportieren willst, aber das ist für ne serielle Schnittstelle (auch 
für eine virtuelle) sehr untypisch.

Ich hab das anders gemacht, allerdings für den STM32F103ZET6. Von NXP 
bin ich es gewöhnt, daß es in jedem µC nen anderen USB-Core hat, also 
geb ich keine Garantie, daß mein Code auch auf nem STM32F4VGT läuft. 
Aber die Herangehensweise ist m.E. das wichtigste. Ich hab einen Sende- 
und einen Empfangspuffer vorgesehen, die vom aufrufenden Programm 
byteweise mittels vorgehaltener Funktionen gelesen bzw. gefüllt werden, 
ohne daß dieses sich in irgendeiner Weise um die USB-spezifischen Dinge 
kümmern muß. Das erledigt komplett der Interrupt. Auch das Inteface, 
also das, was man in .h findet, ist überall gleich. Mir war das wichtig, 
daß für das aufrufende Programm die Zugriffe auf die Puffer NICHT 
direkt, sondern NUR über die vorhandenen Funktionen möglich sind, denn 
dadurch erspart man sich ne Menge Debugging.

Ich hab solche äußerlich vereinheitlichten Treiber für den STM32F103, 
Nuvoton NUC120, LPC2478, LPC1343, LPC17xx geschrieben und die .h Datei 
enthält zum Herausschneiden die .inf für den ganzen Kram - egal, welcher 
µC dahinter steckt.

W.S.

von Uwe B. (derexponent)


Lesenswert?

Markus R. schrieb:
> Eine LabVIEW Studentenversion ist übrigens im Buch "Einführung in
> LabVIEW" dabei, das häufig in FH/Uni-Bibliotheken zu finden ist.

hmm...ok, mal sehen, Danke

Gruss

von Markus R. (maggus)


Lesenswert?

Hallo W.S.,

danke für die Kritik. Hier noch ein paar Anmerkungen:

> Zuerst geht es nach meinem Gefühl viel zu kunterbunt
> durcheinander. Dein USB-Code ist mir viel zu wenig gekapselt
Sehe ich ähnlich. Wie geschrieben, habe ich die Inhalte der 
STM32_USB-Host-Device_Lib_V2.1.0 von ST quasi 1:1 übernommen und das 
CDC-Beispiel auf den STM32F407V und meine Bedürfnisse umgebaut. Durch 
die Modularität (die anfänglich tatsächlich sehr unübersichtlich 
erscheint) sollten sich auch andere Devices (Audio, Massenspeicher...) 
relativ einfach unter Vorbild der ST-Beispiele implementieren lassen.

> deine Herangehensweise zur Geschwindigkeitsmessung
> ist praxisfern. Mag ja sein, daß du immer nur 4K große Blöcke
> transportieren willst, aber das ist für ne serielle Schnittstelle (auch
> für eine virtuelle) sehr untypisch.
Naja, die Geschwindigkeitsmessung (die übrigens im LabVIEW Programm und 
nicht in der uC-Software steckt...) bringt mir die Ergebnisse, die mich 
interessieren: Wie viele solcher Pakete kann ich pro Zeiteinheit maximal 
übertragen. Man muss halt immer im Hinterkopf behalten, dass bei High 
Speed 512 Byte auf einmal übertragen werden. Wenn nur 1 Byte des 512 
Byte Pakets belegt ist, dann ist klar, dass die effektive 
Geschwindigkeit in den Keller geht.
Dass CDC für große Datenmengen nicht ganz so geeignet ist, ist richtig. 
Dafür ist es aber schön einfach.

> geb ich keine Garantie, daß mein Code auch auf nem STM32F4VGT läuft.
Ohne es ausprobiert zu haben: Wird es wahrscheinlich nicht, zumindest 
nicht mit dem ULPI Interface. Inwiefern sich der FS-Core vom F4 und F1 
unterscheiden weiß ich aber auch nicht.

> Aber die Herangehensweise ist m.E. das wichtigste. Ich hab einen Sende-
> und einen Empfangspuffer vorgesehen, die vom aufrufenden Programm
> byteweise mittels vorgehaltener Funktionen gelesen bzw. gefüllt werden,
> ohne daß dieses sich in irgendeiner Weise um die USB-spezifischen Dinge
> kümmern muß. Das erledigt komplett der Interrupt.
> ...
> Mir war das wichtig,
> daß für das aufrufende Programm die Zugriffe auf die Puffer NICHT
> direkt, sondern NUR über die vorhandenen Funktionen möglich sind, denn
> dadurch erspart man sich ne Menge Debugging.
Das ist im code vom Ausgangsposting prinzipiell genau so. Zugriff auf 
die Puffer erhält man mit usb_puts() und usb_gets() in der 
usb_cdc_vcp.c. Um alles andere kümmern sich die Interrupts.

> Ich hab solche äußerlich vereinheitlichten Treiber für den STM32F103,
> Nuvoton NUC120, LPC2478, LPC1343, LPC17xx geschrieben und die .h Datei
> enthält zum Herausschneiden die .inf für den ganzen Kram - egal, welcher
> µC dahinter steckt.
So ein Herstellerübergreifender Stack ist natürlich auch eine schöne 
Sache ;-)

von Markus R. (maggus)


Lesenswert?

Hallo zusammen,

nachdem jetzt alles aufgebaut ist (USB3320 und STM32F4 auf einer 
4-lagigen Platine), hier mal ein kurzes Update.

Die Übertragung ist deutlich sicherer geworden, ich übertrage damit die 
Daten, die ich aus einem angeschlossenen ADC per DMA auslese. Beim 
Anschluss an einen Port des PCs hatte ich bis jetzt noch keine 
Aussetzer, beim Anschluss an den USB Hub hingegen schon. Ich kann das 
Problem mit dem USB Hub allerdings nicht eingrenzen, mal funktioniert 
es, mal bricht er nach ein paar Paketen ab. Die Kabellängen vom und zum 
Hub scheinen keine Einfluss zu haben.

Die Datenrate habe ich jetzt nicht nochmal gemessen, meine Anwendung 
braucht maximal 3,9 MByte/s und die werden locker erreicht.

von Tommy J. (domme414)


Lesenswert?

Hallo,

ich bin neu hier und wollte mal nachfragen, ob schon jemand versucht hat 
WINUSB zu implementieren bzw. ob dies überhaupt HighSpeed fähig ist. Die 
HighSpeed CDC Variante ist zwar schnell und einfach, aber wenn man es 
etwas professioneller aussehen lassen will, ist dies doch die bessere 
Variante oder?

gruss Tommy

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.