mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik An W.S.: Läuft deine USB Implementierung auch auf STM32F303?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Hallo W.S., wie du weisst, nutze und empfehle ich gerne deine USB 
Implementierung. Hast du diese schon einmal auf einem STM32F303 
ausprobiert? Ich würde gerne dokumentieren, ob das geht.

Autor: Jitterer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um weiche implementierung geht es?

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jitterer schrieb:
> Um welche Implementierung geht es?

Diese: Beitrag "Re: STM32F4 USB CDC"

Oder falls er für den STM32F303 eine andere veröffentlicht hat, würde 
ich sie gerne weiter empfehlen.

: Bearbeitet durch User
Autor: W.S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Hast du diese schon einmal auf einem STM32F303
> ausprobiert?

Nö. Aber einer für den STM32F302 ist mit dabei. Ich nehme mal an, daß 
diese Version ohne großartige Änderungen auch auf dem F303 läuft. 
Allenfalls müssen die Leute, die den GCC benutzen, sich um dessen 
Eigenheiten kümmern. Irgendwo hab ich auch noch eine Version für den 
LPC4088 herumfliegen, falls da ein dediziertes Interesse besteht. 
Ansonsten ist die weitestgehend baugleich zu der für den LPC1751, 
lediglich die Mechanik mit dem INAK_BI funktioniert beim LPC4088 nicht, 
weswegen ich da ein "Software-INAK_BI" eingebaut habe.

W.S.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist übrigens der gleiche Code, wie der von 2015 für STM32F103.

Autor: Stefanus F. (stefanus)
Datum:
Angehängte Dateien:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo W.S.,

ich habe gerade das Nucleo-F303RE Board erhalten und konnte die USB-CDC 
Implementierung der HAL erfolgreich testen. Daraus schliesse ich, dass 
keine Hardware Ok ist. Sie besteht nur auf einem abgeschnittenen USB 
Kabel und einem Pull-Up Widerstand and DP, den ich mit 3,3V verbunden 
habe.

Nun probiere ich deinen Code aus, den ich wegen seiner Kompaktheit 
bevorzugen würde.

Ein paar Zeilen musste ich für meine Entwicklungsumgebung (Eclipse, gcc, 
AC6 Tools) anpassen, damit ich den Code compilieren kann. Dabei habe ich 
mich an dem bereits funktionierenden Programm für den STM32F103RB 
orientiert.

Mit ist aufgefallen, dass die Adressen der NVIC Register anders sind - 
habe ich (hoffentlich korrekt) angepasst. Es funktioniert aber noch 
nicht.

Die LED blinkt wie gewünscht. Wenn ich das USB Kabel an den Laptop 
stecke, erscheinen folgende Meldungen (Linux, dmesg):
[ 9380.967330] usb 1-3.2: new full-speed USB device number 28 using xhci_hcd
[ 9396.500206] usb 1-3.2: device descriptor read/64, error -110
[ 9412.117042] usb 1-3.2: device descriptor read/64, error -110
[ 9412.304996] usb 1-3.2: new full-speed USB device number 29 using xhci_hcd
[ 9427.733833] usb 1-3.2: device descriptor read/64, error -110
[ 9443.350617] usb 1-3.2: device descriptor read/64, error -110
[ 9443.459037] usb 1-3-port2: attempt power cycle
[ 9444.062612] usb 1-3.2: new full-speed USB device number 30 using xhci_hcd
[ 9449.158919] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[ 9454.535186] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[ 9454.743043] usb 1-3.2: device not accepting address 30, error -62
[ 9454.823072] usb 1-3.2: new full-speed USB device number 31 using xhci_hcd
[ 9459.915358] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[ 9465.287711] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[ 9465.499570] usb 1-3.2: device not accepting address 31, error -62
[ 9465.499933] usb 1-3-port2: unable to enumerate USB device

Ich habe zur Kontrolle einen Breakpoint in den Interrupthandler gesetzt 
und konnte so feststellen, dass er aufgerufen wird, sobald ich das USB 
Kabel an den Laptop stecke. Innerhalb der ISR passiert das:

I = 10111100000000
(I & ERR) ist wahr
(I & SUSP) ist wahr
(I & RESET) ist wahr

Zweiter Aufruf der ISR:

I= 1000000000
(I & SOF) ist wahr

Dritter Aufruf der ISR:

I = 110100000000
(I & SUSP) ist wahr
(I & RESET) ist wahr

Danach wird die ISR nicht mehr angesprungen.

Ich habe den Quelltext und ein Protokoll von Wireshark angehängt, weil 
ich mal gelesen habe, dass dies helfen könnte. Den Inhalt des Protokolls 
kann ich mangels Know-How aber nicht verstehen.

Ich würde mich sehr freuen, wenn du mir helfen könntest, das Ding ans 
Laufen zu bringen. Dann kann ich das funktionierende Projekt zu meiner 
neuen Webseite http://stefanfrings.de/stm32/stm32f3.html hinzufügen.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Ich habe zur Kontrolle einen Breakpoint in den Interrupthandler gesetzt

Das funktioniert nicht. Bei sowas wirst du vom Host binnen weniger ms 
auf Passiv gesetzt und rausgeschmissen. Ich habe nicht umsonst das 
"debugfkt.inc" mit reingegeben. Damit kann man sich diverse Meldungen, 
die man an irgend einer Stelle (oder mehreren) erzeugen will, temporär 
in einen RAM Bereich schreiben und dann anschließend außerhalb des 
Interupthandlers über irgend einen anderen Kanal ausgeben.

Merke: bloß im Int-Handler keine Zeit vertrödeln.

Probiere das ganze doch mal an einem Windows-PC aus und guck dir mit 
usbview an, was der Host vom deinem µC an Descriptor-Paketen gekriegt 
hat.

Wenn da garnix ist, dann stimmt entweder was mit den Interruptnummern 
und Namen nicht oder der USB-Core ist tatsächlich etwas anders als 
erwartet. Oder hast du's mit dem nop() übertrieben?

Ich hab derzeit weder nen F302 noch einen F303 da - geschweige denn auf 
LP gelötet, kann das ganze also momentan nicht nachvollziehen.

W.S.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Oder hast du's mit dem nop() übertrieben?

Ich hoffe nicht. Genau so funktioniert es auf dem STM32F103.

Ich versuche morgen mal etwas mit Hilfe von Trace Meldungen 
herauszufinden, damit die ISR zügig durchläuft.

Autor: Stefanus F. (stefanus)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt Trace Meldungen eingebaut, die alle Verzweigungen an if() 
und switch() anzeigen (ausser bei "Start of Frame"). Dabei erscheinen 
folgende Meldungen:
setup
Hello World!
(jetzt USB einstecken)
ERR
SUSP
RESET
CTR
DIR
logEpCtrl
SETUP
isStandardReques
GET_STATUS
Soweit ich dem Wireshark Trace entnehme, antwortet der µC jedoch nicht 
auf den GET DESCRIPTOR Request.

Beitrag #5761466 wurde vom Autor gelöscht.
Beitrag #5761482 wurde vom Autor gelöscht.
Autor: Stefanus F. (stefanus)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mehr Trace Meldungen bringen mich leider nicht weiter. Ich erkenne die 
Problemursache nicht, weil ich den Soll-Zustand nicht kenne.
setup
InitEndpoints
setAddr adr=0
Hello World!
(USB Kabel einstecken)
ERR
SUSP
RESET
InitEndpoints
setAddr adr=0
CTR
DIR
logEpCtrl
SETUP
rdCtrlBlock maxlen=8
clrBuf logEpNum=0
isStandardRequest
GET_STATUS
doGetStatus for 00
forElse
stall
Hello World!
CTR
DIR
logEpCtrl
SETUP
rdCtrlBlock maxlen=8
clrBuf logEpNum=0
isStandardRequest
GET_STATUS
doGetStatus for 00
forElse
stall

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hurra, ich habe etwas greifbares gefunden: In der Funktion 
ReadControlBlock ist count immer 0.

Das ist gar kein GET_STATUS Request, es sieht  nur so aus, weil der CMD 
Puffer voller Nullen ist und 0 zufällig der Wert von GET_STATUS ist.

Ich bin ziemlich sicher, dass der Code zum USB Interface des STM32F303 
passen müsste, weil ich beim Vergleich mit dem Referenzhandbuch keine 
Abweichungen gefunden habe. Ich konnte alle Registerzugriffe in der Doku 
wieder finden und umgekehrt habe ich kein relevantes Register/Bit 
gefunden, das eventuell noch gesetzt werden muss.

WS, kannst du mir helfen, heraus zu finden, warum ReadControlBlock nur 0 
Bytes liest?

: Bearbeitet durch User
Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> In der Funktion
> ReadControlBlock ist count immer 0.

Nanana.. du hast dich offenbar auf einen ACK vom Host gesetzt.

Also, bei einem EP-Interrupt wird der Endpointstatus aus den 
USB_EpRegs(EpNum) gelesen. Und wenn dort das SETUP Bit (1<<11) gesetzt 
ist, dann HAT der Host 8 Byte in den µC transferiert. Wenn nicht, dann 
ist das bloß ein leerer Block vom Host, der als ACK dient - und dann 
wird auch nicht OnSetup aufgerufen, sondern OnEpCtrlOut. Und das dient 
lediglich dazu, den evtl. vorhandenen Rest an Daten in weiteren Blöcken 
zum Host zu schaufeln.

W.S.

Autor: Stefanus F. (stefanus)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab den Fehler gefunden (freu)!

Und zwar hat dieser Mikrocontroller ein 1:1 Mapping für den Speicher der 
USB Schnittstelle, anstatt diese komische Lösung wo jedes zweite Word 
fehlt.

Ich habe den Code entsprechend angepasst. Man kann jetzt am Anfang der 
usb.c einstellen, welche Variante man benötigt.

Ich glaube, jetzt bin ich Fit genug, mir das Tutorial von Niklas 
(https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32) an zu 
tun :-)

Also falls jemand eine schlanke USB-CDC Implementierung für STM32F3 
sucht, jetzt haben wir eine - siehe Anhang.

Nochmal herzlichen Dank an W.S für seine Hilfestellungen. Ohne Dich 
hätte ich das sicher nicht so schnell hinbekommen.

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der main.c fehlte eine Funktion, die habe übereifrig weg geputzt:
// Delay some milliseconds
void delay_ms(int ms)
{
    uint32_t start=systick_count;
    while (systick_count-start<ms);
}

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiss zufällig jemand, warum man den Pull-Up Widerstand an D+ 
üblicherweise mit einem Transistor schaltet und nicht einfach direkt an 
einen GPIO Pin anschließt?

Autor: STM Apprentice (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Also falls jemand eine schlanke USB-CDC Implementierung für STM32F3
> sucht, jetzt haben wir eine - siehe Anhang.

Das ist schön, aber ich vermute dass die Nichtfunktionalität
dieses Teils mit 32-Bit(-Windows7)-Systemen immer noch besteht.

Meine Vermutung wäre dass irgend ein Endpoint-Request von den
32-Bit Treibern von dieser USB-Implementierung nicht richtig
oder gar nicht ge-handled wird.

Ich weiss schon, das klingt unplausibel aber mir fällt nichts
besseres ein .... hab schon so manche Programmfehler entdeckt
die sich nur auf 32-Bit Systemen äussern.

Muss ja auch nicht unbedingt ein Fehler des "Nuvoton" USB Teils
sein.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Oder hast du's mit dem nop() übertrieben?

Ich weiss nicht mehr woher ich das habe. Jedenfalls habe ich 
ausprobiert, wie viele NOP innerhalb der Nop() Funktion nötig sind und 
bin nun auf einen gekommen - entsprechend deiner Vorlage.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Ich hab den Fehler gefunden (freu)!

Uff... na gottseidank. Wieder ein Chip mehr in der Liste.

Stefanus F. schrieb:
> Weiss zufällig jemand, warum man den Pull-Up Widerstand an D+
> üblicherweise mit einem Transistor schaltet und nicht einfach direkt an
> einen GPIO Pin anschließt?

Nö, ich schätze mal, das weiß keiner so recht. Vielleicht liegt es an 
irgendwelchen USB-Cores, die den 1k5 über ein dediziertes Pin bedienen 
und dabei dessen Polarität nicht vom Programmierer einstellen lassen.

Es gibt auch Schaltungen, wo der 1k5 einfach an +3.3V geht. Ohne 
irgendwelches Schalten. In solchen Fällen muß man sich aber mit dem 
Anwerfen des USB nach dem Einschalten beeilen.

W.S.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Wieder ein Chip mehr in der Liste.

Das war mein Ziel. Der STM32F303 fehlte mir dort.

Falls du meine Anpassung in deine Vorlage übernehmen möchtest, sind die 
relevanten Änderungen folgende:

Zwei neue defines:
/* For devices with 2 x 16 bits / word access schema (e.g. STM32F303xD and xE) */
#define shift 0
#define memwidth word

/* For devices with 1 x 16 bits / word access schema (e.g. STM32F103xx, STM32F302xx, STM32F303xB and xC) */
// #define shift 1
// #define memwidth dword

Sowie alle weiteren Stellen, wo die diese dann benutzt werden. Es 
betrifft Shift Operationen, die Größe der Felder in der Struktur 
TEpTableEntry und die Größe der temporären Variablen in 
ReadControlBlock() und WriteControlBlock().

Und dann hast du einen Text bezüglich der "kruden" Speicherstruktur 
hinterlassen, dieser gilt nur für für die kleineren STM32F303xB und xC. 
Der STM32F303xD und xE hat keine "krude" Speicherstruktur.

: Bearbeitet durch User
Autor: N. M. (mani)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Weiss zufällig jemand, warum man den Pull-Up Widerstand an D+
> üblicherweise mit einem Transistor schaltet und nicht einfach direkt an
> einen GPIO Pin anschließt?

Ich habe den Widerstand bei mir direkt an einem GPIO des uC. 
Funktioniert bei mir zumindest ohne Probleme. Hab aber glaub ich 
vorsichtshalber einen High Current Pin genommen gehabt.

Könnte es daran liegen, dass man vermeiden will das beim Strecken 
Spannung direkt an dem uC Pin über D+ anliegen kann bevor VCC dann ist.
Sollte zwar über den Stecker geschehen, aber vllt nochmal zusätzlich?

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
N. M. schrieb:
> Könnte es daran liegen, dass man vermeiden will das beim Strecken
> Spannung direkt an dem uC Pin über D+ anliegen kann bevor VCC dann ist.

Gute Idee, ja das könnte es sein. Wie war das nochmal - ich glaube ohne 
VCC dürfen an den 5V Toleranten Pins maximal 4V anliegen. Das wiederum 
wäre nur mit zusätzlichen Schutzdioden sicher einzuhalten.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Weiss zufällig jemand, warum man den Pull-Up Widerstand an D+
> üblicherweise mit einem Transistor schaltet und nicht einfach direkt an
> einen GPIO Pin anschließt?

Vielleicht weil es lästig ist, zwischen "High" und "Hochohmig" 
umzuschalten; auf "Low" sollte man den Widerstand m.W. nicht schalten. 
Vielleicht auch weil man die Basis/Gate des Transistors dann noch 
zusätzlich mit einem Pull-Up versehen kann, welcher dafür sorgt, dass 
der 1,5kΩ-Pullup beim Starten der Firmware nicht versehentlich aktiviert 
wird. Vielleicht auch einfach um den uC-Pin anderweitig verwenden zu 
können, falls USB nicht benutzt wird (wird durch den Transistor von D+ 
"entkoppelt").
PS: Einige neuere STM32 (F0 glaube ich) haben ebenfalls die einfache 
"USB"-Peripherie wie der F103, aber mit integriertem Pullup. Damit 
erledigt sich dieses ganze Problem. Die "OTG"-Peripherie der größeren 
Controller hat diesen Pullup auch immer integriert. Die ist aber wie 
gesagt nicht so einfach zu programmieren.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Niklas,
ich habe mir übrigens gestern dein USB Tutorial erneut durchgelesen. 
Dieses mal habe ich vieles davon verstanden und konnte die Parallelen 
zwischen deinen Erklärungen und W.S. Quelltext (der ja anders 
strukturiert ist, als deiner) erkennen.

Ich glaube der Knackpunkt war, die laufende Schnittstelle einmal mit 
Trace Meldungen zu beobachten und ab und zu mal mit dem Debugger in 
weitere Details zu gucken.

Langsam werde ich daraus schlau :-)

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den aktuellen Stand USB Implementierung findet man immer hier: 
http://stefanfrings.de/stm32/stm32f3.html#vcpnohal

Autor: Willi S. (willi_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... als das durch einen PortPin schaltbaren 1,5kΩ an D+ hat einen 
einfachen Grund ... es kann eine erneute Enumeration des USB Device 
erzwungen werden ... wenn der Portpin von "Input" auf "Output high" 
geschaltet wird ... dann ist der 1,5kΩ aktiv und der USB Host meit ein 
neues Device ist angesteckt gewirden ... ihne den USB-Stecker betätigen 
zu müssen ... uch nutze gerne dies ... um nach dem Laden des Codes in 
den STM32F103 sofort eune Enumeration durch den Host auszulösen ...

... leider hab' ch auf meinem STM32F193 den Code von W.S. (nich) nicht 
zum laufen gebracht ... der GCC mit "Option 0" wird der NOP unangetastet 
gelassen ... ein PID / VID wird (leider) nicht übertragen ... Clock und 
Ports sind nach Angaben initialisiert PA11 PA12 bleiben in ihrem 
ResetZustand - umschalten auf "alternate" zeigt keinen Effekt - wie auch 
in RM0008 erwähnt ...  aber ich suche noch weiter ...

... übrigens ... wo finde ich einen CDC Treiber für WinXP ? ... meine 3 
PCs laufen noch wunderbar damit und sind damit zu schade für den Schrot 
...

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Willi S. schrieb:
> wo finde ich einen CDC Treiber für WinXP

Am einfachsten auf der Webseite von ST. Im Quellcode änderst du dann die 
VID und PID auf die Nummern von ST

> "Option 0"

Was soll das sein?

> leider hab' ich auf meinem STM32F193 den Code von W.S. nicht zum laufen gebracht

Stimmt die Modellnummer? Ich habe dazu kein Datenblatt gefunden.

Meine Rechtschreibung ist schlimm, aber deine so schlimm, dass man 
teilweise nicht mehr erkennen kann, was du gemeint hast.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.