Forum: Mikrocontroller und Digitale Elektronik USB: Dual VCOM-Port mit STM32F407


von Rangi J. (rangi)


Angehängte Dateien:

Lesenswert?

Hallo Forum,
ich komme mit meinem USB-Projekt nicht weiter und bräuchte mal Hilfe 
beim Thema USB.
Ich möchte 2 virtuelle COM-Ports mit einem STM32F4xx verwenden. Dazu 
habe ich Anleitungen und Quellen aus:
https://community.st.com/t5/stm32-mcus/how-to-implement-a-dual-cdc-acm-usb-device-using-the-st-classic/ta-p/708039
und Github kombiniert.
Das ganze läuft jetzt, das 2 Ports in Windows erkannt werden, das ich 
beide öffnen kann und dass ich ein Echo zurückbekomme.
Jedoch ist mir jetzt aufgefallen, dass die Interrupt-Last hoch ist, 
sobald ich den ersten Port öffne. Beim zweiten Port ist das nicht so und 
funktioniert sehr gut.
Im pcap hab ich gesehen, dass ständig Nachrichten "URB Function: 
URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL (0x001e)" gesendet werden.
Irgendetwas scheint noch zu fehlen oder nicht zu stimmen.
Im Anhang habe ich mal die beiden pcap-files:
4.pcap - Funktion ok, senden und empfangen von "abcd" im Paket 1745 ff
5.pcap - nicht okay, senden und empfangen von "efgh" im Paket 1123 ff
Im Quellcode habe ich bis dahin folgendes angepasst:
Usb_device.c "USBD_CDC_RegisterInterface(&hUsbDeviceFS, 
&USBD_Interface_fops_FS0);"
hier habe ich 2 cdc interfaces angelegt ...FS0 und ...FS1, wobei ich die 
Receive- und TransmitCplt-Funktionen ergänzt habe. Sonst gab es einen 
Hardfault, weil auf 0 gesprungen werden sollte.
Die "USBD_malloc"-Funktion (static) habe ich durch getrennte Speicher 
ersetzt in der die "USBD_CDC_HandleTypeDef" abgelegt werden.

Vielen Dank für Hinweise

von Rangi J. (rangi)


Lesenswert?

Keiner eine Idee?
Was ich anhand der Logs gesehen habe oder vermute:
alle 480ms wir von Controller ein "URB_INTERRUPT in" von Endpoint 0x84 
ausgelöst.
Daraufhin sagt der Host: "Reset and Clear Stall" was der Controller brav 
bestätigt.
Dann sagt der Host wieder "URB_INTERRUPT in" und nach 480 ms kommt der 
Response.
Woher kommen die 480ms? Ich hab auf dem µC nichts laufen, kein 
Timer-Interrupt, die while(1) ist leer.

Beim ersten Port wird auch der "URB_INTERRUPT in" einamlig angefordert 
und erst ganz am Ende einmal bestätigt.

von Harald A. (embedded)


Lesenswert?

KIs werden in diesem Forum üblicherweise mit Hass überzogen, mir egal, 
mir hilft es manchmal bei der Eingrenzung, vlt Dir auch. Falls Du 
dagegen auch eine Allergie hast oder es nicht hilft bitte einfach 
ignorieren:
https://www.perplexity.ai/search/d1a0004d-0960-4e1e-ad6d-6e044e7de020

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harald A. schrieb:
> Falls Du
> dagegen auch eine Allergie hast oder es nicht hilft bitte einfach
> ignorieren:

Du hättest die Antwort der KI wenigstens mal prüfen können bevor du 
postest, denn sie ist nutzlos.

Die Fehlerbeschreibung klingt als würde das Device auf die IN-Requests 
manchmal nicht korrekt antworten. Schwierig zu sagen wo das in den 
Tiefen der Library schief geht. Grundsätzlich muss es funktionieren, 
habe sowas schonmal mit dem STM32F1 gemacht, aber ohne die Library...

von Rangi J. (rangi)


Lesenswert?

Niklas G. schrieb:
> Du hättest die Antwort der KI wenigstens mal prüfen können bevor du
> postest, denn sie ist nutzlos.

Also ich hab mir das mal angesehen und ich frage mich wie die AI auf 
sowas kommt?

Niklas G. schrieb:
> Die Fehlerbeschreibung klingt als würde das Device auf die IN-Requests
> manchmal nicht korrekt antworten.
Wenn ich dem Wireshark trauen soll, dann kommt die problematische 
Nachricht von mir. Im Bild die No. 1735 als Antwort auf die No. 1720 
nach so etwa 480 ms. Und sie kommt vom EP 0x84, das ist der 
"SECOND_CDC_CMD_EP"
Gibt es im USB-Teil des STM irgendwelche Timeouts die da ablaufen?

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Rangi J. schrieb:
> Im Bild die No. 1735

Äh, wo ist das Bild? Hab keinen Wireshark zur Hand.

von Harald A. (embedded)


Lesenswert?

Der erste Teil ist nicht zielführend, korrekt. Die Nachfrage im zweiten 
Teil konkretisiert es etwas, die dort aufgeführten Punkte könnte man 
prüfen. Und das Angebot der Prüfung des Treibers usb_cdc.c könnte man 
einmal durchlaufen lassen.
Ja, manchmal kommt da tatsächlich nichts Brauchbares raus, dann ist das 
so. Manchmal aber kommen auch Hinweise in die richtige Richtung. Aber 
wie gesagt, alles nur als Angebot, wenn es nicht hilfreich ist einfach 
klassisch weitermachen.

von Harald A. (embedded)


Lesenswert?

Habe es gerade getestet, das gerade erschienene ChatGPT 5.4 antwortet in 
dieser Richtung noch einmal WESENTLICH detaillierter und hoffentlich 
zielführender. Ich kann es leider nicht verlinken, aber Du hast sicher 
jemanden mit Zugriff.

von Rangi J. (rangi)


Lesenswert?

Ich bin auf traditionellem Weg auch weitergekommen.
Ich habe genau die Stelle gefunden, an der der Timeout eingestellt wird. 
In der usbd_composite_builder.c, Zeile 960
1
  /* Append Endpoint descriptor to Configuration descriptor */
2
  __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \
3
                       USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE, CDC_HS_BINTERVAL, CDC_FS_BINTERVAL);
mit der Konstanten CDC_FS_BINTERVAL wird angegeben, dass diese Nachricht 
periodisch gesendet wird. Das lässt sich bis auf 100ms verlängern oder 
mit 0 komplett ausschalten. Augenscheinlich funktioniert das Senden und 
Empfangen mit beiden Schnittstellen.
Jetzt habe ich 2 Fragen:
1. Warum wirkt diese Einstellung nur auf den zweiten Port?
2. Wozu ist das gut? Denn es sieht ja so aus, als ob der Entwickler sich 
was dabei gedacht hat.
3. An welcher Stelle bekommt die HW im STM mitgeteilt, dass hier eine 
periodischer EP konfiguriert ist? Denn zunächst mal wird mit dem Code 
oben nur ein Stück Ram beschrieben und noch keine Register gesetzt.

von Rangi J. (rangi)


Lesenswert?

Rangi J. schrieb:
> Ich bin auf traditionellem Weg auch weitergekommen.

Leider doch nicht, das hat nur einmal funktoniert, dann wieder nicht 
mehr.
Aber ich hab noch was anderes im Ref Manual des 407 gefunden:
Peripheral-mode features
The OTG_FS interface main features in peripheral-mode are the following:
● 1 bidirectional control endpoint0
● 3 IN endpoints (EPs) configurable to support Bulk, Interrupt or 
Isochronous transfers
● 3 OUT endpoints configurable to support Bulk, Interrupt or Isochronous 
transfers

Für mein Projekt, sind aber insgesamt 2 Out- und 4 In-Endpoints 
benötigt:
1
#define CDC_OUT_EP                            0x01U  /* EP1 for CDC data OUT First Instance */
2
#define CDC_IN_EP                             0x81U  /* EP1 for CDC data IN First Instance */
3
#define CDC_CMD_EP                            0x82U  /* EP2 for CDC commands First Instance */
4
5
#define SECOND_CDC_OUT_EP                     0x02  /* EP2 for CDC data OUT Second Instance */
6
#define SECOND_CDC_IN_EP                      0x83  /* EP4 for CDC data IN Second Instance */
7
#define SECOND_CDC_CMD_EP                     0x84  /* EP5 for CDC commands Second Instance */
Bedeutet dass, das der STM32F407 garnicht gehen kann?

von Rangi J. (rangi)


Lesenswert?

Ich bin mir fast sicher, dass der F407 nicht funktionieren kann.
Deshalb habe ich jetzt mal einen STM32F103RC auf mein Target bestückt.
Hier habe ich jetzt erstmal einfach nur im CubeMx ein neue Projekt 
erstellt, nur Clock, USB (+Rx-, Tx-Interrupt), Debug und CDC aktivert. 
Noch garnichts verändert.
USB funktioniert so aber leider garnicht. Beim Verbinden bekomme ich 
zwar einen (oder mehrere Interrupts), aber auf PC-Seite kommt garnichts 
zurück, keine Reaktion. Auch im USB-Pcap ist absolut nichts zu sehen.
Ich dachte zuerst, der Takt stimmt nicht. Deshalb habe ich einen 
HW-Timer gestellt und ausgemessen. Das kann es nicht sein.
Die D+ und D-Leitungen habe ich bis zum Pin gemessen. Das Kabel 
funktioniert mit einem anderen USB-Gerät problemlos.
Was könnte das Problem sein? Muss man beim F103 noch irgendwas 
aktivieren oder umstellen?

von Rahul D. (rahul)


Lesenswert?

Rangi J. schrieb:
> garnicht

Eselsbrücke: "Gar nicht" wird gar nicht zusammengeschrieben.

Rangi J. schrieb:
> USB funktioniert so aber leider gar nicht.
Die STLinks auf den NUCLEO-Boards unterstützen doch auch eine 
Doppelrolle.
Das muss also gehen. Ist aber wohl nicht so ganz einfach...

von Rangi J. (rangi)


Angehängte Dateien:

Lesenswert?

Hier noch die Schaltung
Bestückt ist nichts außer µC, Kondensatoren, Buchse, Stromversorgung, 
Quarz, Reset-Pull-Up und ESD-Dioden.

von Harald K. (kirnbichler)


Lesenswert?

Rahul D. schrieb:
> Die STLinks auf den NUCLEO-Boards unterstützen doch auch eine
> Doppelrolle.

Ja, aber sie werden nicht zwei Devices implementieren, die jeweils drei 
Endpoints benötigen. Das ist hier ja wohl das Problem; der 
Devicecontroller im µC bietet fünf Endpoints, benötigt werden aber je 
CDC drei.

von Rangi J. (rangi)


Lesenswert?

lt. Datenblatt:
"This dedicated memory is sized to 512 bytes and up to 16 
mono-directional or 8 bidirectional endpoints can be used."

Mal davon abgesehen, funktioniert nicht mal einer.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

zum Glueck bin ich da noch weitgehend ahnungsbefreit, was die Anzahl von 
Endpoints, etc. angeht, aber hier gibt's ein Projekt, wo einer 3x 
USB->Serial auf einem F103 gebastelt hat:

https://github.com/satoshinm/pill_serial/tree/master

Wie gut das funktioniert? Keine Ahnung, bin nur mal druebergestolpert.

Gruss
WK

von Anton (antang)


Lesenswert?

Rangi J. schrieb:
> Deshalb habe ich jetzt mal einen STM32F103RC auf mein Target bestückt.
> Hier habe ich jetzt erstmal einfach nur im CubeMx ein neue Projekt
> erstellt, nur Clock, USB (+Rx-, Tx-Interrupt), Debug und CDC aktivert.
> Noch garnichts verändert.
> USB funktioniert so aber leider garnicht. Beim Verbinden bekomme ich
> zwar einen (oder mehrere Interrupts), aber auf PC-Seite kommt garnichts
> zurück, keine Reaktion. Auch im USB-Pcap ist absolut nichts zu sehen.

Anders als der STM32F407 braucht der STM32F103 einen 1,5 kΩ Pullup an 
der D+-Leitung.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Dergute W. schrieb:
> Wie gut das funktioniert? Keine Ahnung, bin nur mal druebergestolpert

Meine Variante davon funktioniert super 😁 dreifach CDC-ACM auf dem 
STM32F103.

https://github.com/Erlkoenig90/f1usb/tree/vcp

von Rangi J. (rangi)


Lesenswert?

Anton schrieb:
> Anders als der STM32F407 braucht der STM32F103 einen 1,5 kΩ Pullup an
> der D+-Leitung.

Das war ein super Tip. Danke, jetzt bekomme ich erstmal in Windows eine 
Info. Wenn ich Zeit habe gehts hier weiter.
Jede gute Leiterplatte hat mindestens einen Draht. 😁

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.