Forum: Mikrocontroller und Digitale Elektronik USB HID Device mit STM32F042


von Max G. (l0wside) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erst mal allen ein frohes neues Jahr 2023 mit Glück, Gesundheit und 
lieferbaren Bauteilen!

Ich habe versucht, den USB-Code von W.S. auf dem STM32F042 zum Laufen zu 
bringen und auf ein reines HID-Device umzubauen. Das Gerät wird 
inzwischen sauber enumeriert, sowohl Windows als auch Linux sind damit 
prinzipiell zufrieden.

Ich möchte auf EP1 Reports mit 64 Byte Größe senden (und in einem 
zweiten Schritt empfangen). Der Host pollt auch fröhlich, aber ich 
schaffe es absolut nicht, eine Antwort zu senden.

Beobachtungen:
* Double Filtering hatte ich mal aktiviert, aber inzwischen 
auskommentiert.
* Wenn ich den EP Type korrekt auf "3" für "Interrupt" stelle, löst der 
IRQ-Handler nicht aus. Wenn ich den EP Type (inkorrekt) auf "2" für 
"ISO" stelle, löst der IRQ-Handler aus, aber Linux beschwert sich mit 
-71 über einen Protokollfehler.
* Wenn ich in OnEpIntIn() versuche, zu antworten, scheinen immer 0 Byte 
auf der Host-Seite anzukommen, auch wenn ich die Länge auf die 
(korrekten) 64 stelle. Ob ich (entgegen dem User Manual) die oberen Bits 
von USB_COUNTn_TX (also BL_SIZE und NUM_BLOCKS) auch noch setze, ist 
dabei egal.
* Ich habe User Manual, USB in a Nutshell, eccelerator.com, usbmon, 
Beyond Logic, jede Menge Forenbeiträge und natürlich das USB-Tutorial 
von µC.net durch. Man werfe mir also gerne Blödheit vor, aber nicht 
Faulheit...

Der (mit dem beiliegenden Skript etwas aufgepeppte) Trace von usbmon 
sieht wie unten aus. Problematisch wird es nach dem letzten "Callback 
Control In" (das ist die Antwort auf die Frage nach dem HID Descriptor).

Hat jemand der Anwesenden einen heißen Tipp, wo ich noch schauen könnte? 
Langsam bin ich echt frustriert. Ach so: CubeMX ist mindestens genauso 
frustrierend, und auf CDC zurück will ich nicht[1].

Vielen Dank!
Max
1
>>  Ci:1:000:0 s 80 06 0100 0000 0040 64 < [submission Control In]
2
<<  Ci:1:000:0 0 18 = 12010002 00000040 addeefbe 00010102 0301 [callback Control In]
3
12 01 00 02 00 00 00 40 ad de ef be 00 01 01 02 03 01
4
>>  Co:1:000:0 s 00 05 0006 0000 0000 0 [submission Control Out]
5
0006
6
006:
7
>>  Ci:1:006:0 s 80 06 0100 0000 0012 18 < [submission Control In]
8
<<  Ci:1:006:0 0 18 = 12010002 00000040 addeefbe 00010102 0301 [callback Control In]
9
12 01 00 02 00 00 00 40 ad de ef be 00 01 01 02 03 01
10
>>  Ci:1:006:0 s 80 06 0600 0000 000a 10 < [submission Control In]
11
<<  Ci:1:006:0 -32 0 [callback Control In]
12
>>  Ci:1:006:0 s 80 06 0600 0000 000a 10 < [submission Control In]
13
<<  Ci:1:006:0 -32 0 [callback Control In]
14
>>  Ci:1:006:0 s 80 06 0600 0000 000a 10 < [submission Control In]
15
<<  Ci:1:006:0 -32 0 [callback Control In]
16
>>  Ci:1:006:0 s 80 06 0200 0000 0009 9 < [submission Control In]
17
<<  Ci:1:006:0 0 9 = 09022900 010100c0 0e [callback Control In]
18
09 02 29 00 01 01 00 c0 0e
19
>>  Ci:1:006:0 s 80 06 0200 0000 0029 41 < [submission Control In]
20
<<  Ci:1:006:0 0 41 = 09022900 010100c0 0e090400 00020300 00000921 10010001 22200007 05010340 [callback Control In]
21
09 02 29 00 01 01 00 c0 0e 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01 22 20 00 07 05 01 03 40
22
>>  Ci:1:006:0 s 80 06 0300 0000 00ff 255 < [submission Control In]
23
<<  Ci:1:006:0 0 4 = 04030904 [callback Control In]
24
04 03 09 04
25
>>  Ci:1:006:0 s 80 06 0302 0409 00ff 255 < [submission Control In]
26
<<  Ci:1:006:0 0 32 = 20035500 53004200 20005600 69007200 74007500 61006c00 44006500 6d006f00 [callback Control In]
27
20 03 55 00 53 00 42 00 20 00 56 00 69 00 72 00 74 00 75 00 61 00 6c 00 44 00 65 00 6d 00 6f 00
28
>>  Ci:1:006:0 s 80 06 0301 0409 00ff 255 < [submission Control In]
29
<<  Ci:1:006:0 0 8 = 08034d00 61007800 [callback Control In]
30
08 03 4d 00 61 00 78 00
31
>>  Ci:1:006:0 s 80 06 0303 0409 00ff 255 < [submission Control In]
32
<<  Ci:1:006:0 0 26 = 1a034e00 54003200 30003000 39003100 30003100 34003000 3000 [callback Control In]
33
1a 03 4e 00 54 00 32 00 30 00 30 00 39 00 31 00 30 00 31 00 34 00 30 00 30 00
34
>>  Co:1:006:0 s 00 09 0001 0000 0000 0 [submission Control Out]
35
<<  Co:1:006:0 0 0 [callback Control Out]
36
>>  Ci:1:006:0 s 80 06 0303 0409 00ff 255 < [submission Control In]
37
<<  Ci:1:006:0 0 26 = 1a034e00 54003200 30003000 39003100 30003100 34003000 3000 [callback Control In]
38
1a 03 4e 00 54 00 32 00 30 00 30 00 39 00 31 00 30 00 31 00 34 00 30 00 30 00
39
>>  Co:1:006:0 s 21 0a 0000 0000 0000 0 [submission Control Out]
40
<<  Co:1:006:0 0 0 [callback Control Out]
41
>>  Ci:1:006:0 s 81 06 2200 0000 0020 32 < [submission Control In]
42
<<  Ci:1:006:0 0 32 = 05010900 a1011500 26ff0085 01750895 40090081 82850275 08954009 009182c0 [callback Control In]
43
05 01 09 00 a1 01 15 00 26 ff 00 85 01 75 08 95 40 09 00 81 82 85 02 75 08 95 40 09 00 91 82 c0
44
>>  Ii:1:006:1 -115:8 65 < [submission Interrupt In]
45
<<  Ii:1:006:1 0:8 0 [callback Interrupt In]
46
>>  Ii:1:006:1 -115:8 65 < [submission Interrupt In]
47
<<  Ii:1:006:1 -71:8 0 [callback Interrupt In]
48
>>  Ii:1:006:1 -115:8 65 < [submission Interrupt In]
49
<<  Ii:1:006:1 -71:8 0 [callback Interrupt In]
50
>>  Ii:1:006:1 -115:8 65 < [submission Interrupt In]
51
<<  Ii:1:006:1 -71:8 0 [callback Interrupt In]
52
>>  Ii:1:006:1 -115:8 65 < [submission Interrupt In]
53
<<  Ii:1:006:1 -71:8 0 [callback Interrupt In]

[1] CDC ist wie der Sylt-Shuttle: man setzt sich ins Auto, um Zug zu 
fahren. Ich will aber einfach nur Zug fahren ;)

von Thomas Z. (usbman)


Lesenswert?

da war doch was mit der ReportID zumindest unter Windows
Du must ReportID + 64Bytes schicken für In also:
0x01 + "blablub"... insgesmmt 65 bytes aufgeteilt in 2 packets.

sorry hab schon lange nichts mehr mit HID gemacht.

Für out ist es genauso

von Max G. (l0wside) Benutzerseite


Lesenswert?

Hallo Thomas usbman,

danke für die Unterstützung. Mit deiner Hilfe bin ich weiter gekommen. 
Bei Full Speed können maximal 64 Byte in einem Paket übertragen werden, 
ich habe deshalb die Report Size auf 63 reduziert.

Es sieht aus, als funktioniere nun endlich die Kommunikation. Extrem 
verwirrend war, dass der Linux-Kernel mit dem Pollen bei Interrupts wohl 
erst dann anfängt, wenn man einmal was auf das Device geschrieben hat - 
aber vielleicht ist das Problem auch nur irgendwo zwischen Kernel, 
USB-Spec, usblib, hidapi und Python versteckt. Oder ich habe doch noch 
irgendwo einen Wurm drin. Aber nun kommen die Pakete und Interrupts auch 
mit dem korrekten Endpoint Type.

Mit Windows habe ich noch nicht getestet. Morgen ist auch noch ein Tag 
:)

Viele Grüße,

Max

(der sich viel, viel mehr freut, als aus diesem eher nüchternen Post 
herauszulesen ist. Ich habe jetzt vier Tage mit dem blöden USB 
gekämpft).

von Guido Körber (Gast)


Lesenswert?

Wenn der Report keine ReportID verwendet (= 0), dann rechnet die auch 
nicht zur Reportlänge dazu.

Der ST USB-Stack hat aber zwei spaßige Fehler die wir ST auch mitgeteilt 
haben, die aber bisher in der Library nicht behoben wurden.

Einer davon betrifft bidirektionale Interrupt-Endpoints. Da kann 
mittendrin plötzlich die Senderichtung einfrieren, weil die 
Interrupt-Routine immer beide Interrupt-Flags, also für In und Out 
gleichzeitig löscht.

von Max G. (l0wside) Benutzerseite


Lesenswert?

Guido Körber schrieb:
> Wenn der Report keine ReportID verwendet (= 0), dann rechnet die auch
> nicht zur Reportlänge dazu.

Hallo Guido,

ja, danke. Im Moment bin ich ganz froh, dass es überhaupt funktioniert. 
Der Rauswurf des (letztendlich unnötigen) Report Descriptors kommt dann 
in v 0.02 :)

> Der ST USB-Stack hat aber zwei spaßige Fehler die wir ST auch mitgeteilt
> haben, die aber bisher in der Library nicht behoben wurden.

Ach ja, ST und CubeMX. Wenn ich recht überlege, habe ich bis jetzt jedes 
Mal am Ende den CubeMX-Code rausgeworfen und nur die HAL genommen. 
Bloaty (ohne -Os eigentlich nie zu linken), buggy (siehe dein Beispiel) 
und schlecht dokumentiert (habe zwei Tage gesucht, warum CAN nicht 
funktioniert).

Deswegen habe ich (nach einem vegeblichen Versuch, das zu Fuß zu 
stricken) auf die Library von W.S. aus dem Forum hier aufgesetzt und der 
das Rauchen, nein das CDC abgewöhnt.

Grüße und frohes neues Jahr,

Max

von temp (Gast)


Lesenswert?

Max G. schrieb:
> Deswegen habe ich (nach einem vegeblichen Versuch, das zu Fuß zu
> stricken) auf die Library von W.S. aus dem Forum hier aufgesetzt und der
> das Rauchen, nein das CDC abgewöhnt.

Hier im Forum gibt es ja einige die sich mit dem Code von W.S. ausgiebig 
beschäftigt haben und ihn auch benutzen. Vor einiger Zeit hatte ich hier 
auch mal ein Beispiel für eine Midi-Implementierung eingestellt. Es wäre 
jedenfalls schön, wenn du am Ende hier ein funktionierendes Beispiel 
einstellen könntest.

von Guido Körber (Gast)


Lesenswert?

Max G. schrieb:
> ja, danke. Im Moment bin ich ganz froh, dass es überhaupt funktioniert.
> Der Rauswurf des (letztendlich unnötigen) Report Descriptors kommt dann
> in v 0.02 :)

Nicht den Descriptor raus werfen, nur das Element für die ReportID. Das 
ist 0x85 gefolgt von einem Byte für die ID.

Wenn der Descriptor fehlt, wird das Device nicht enumeriert.

Den USB-Stack von ST haben wir mittlerweile recht gründlich umgegraben, 
der kann jetzt mehr und braucht deutlich weniger Platz :)

von Harry L. (mysth)


Lesenswert?

Guido Körber schrieb:
> Den USB-Stack von ST haben wir mittlerweile recht gründlich umgegraben,
> der kann jetzt mehr und braucht deutlich weniger Platz :)

Kann man sich das irgendwo anschauen?

von Max G. (l0wside) Benutzerseite


Lesenswert?

Guido Körber schrieb:

> Nicht den Descriptor raus werfen, nur das Element für die ReportID.
Ja, ist klar. Da hatte ich mich falsch ausgedrückt. Nicht enumerierende 
Devices hatte ich drei Tage lang, damit bin ich vorerst versorgt.

Im Moment lasse ich die Report ID aber drin. Es muss ja noch Potenzial 
bestehen.  :)

temp schrieb:
> Es wäre
> jedenfalls schön, wenn du am Ende hier ein funktionierendes Beispiel
> einstellen könntest.

Das ist selbstverständlich. Ich habe noch aufgeräumt, Ergebnis ist nun 
hier: Beitrag "USB mit HID für STM32"

von Guido Körber (Gast)


Lesenswert?

Harry L. schrieb:
> Kann man sich das irgendwo anschauen?

Nur als fertiges Produkt :)

Die Bugs haben wir an ST gemeldet, da waren zwei Klöpse drin die 
gefährlich werden können, wenn das in irgend etwas wichtigem passiert. 
Also so wie bei Kunden von uns, die damit z.B. Joysticks bauen und 
teilweise sehr große Maschinen steuern. Wenn da mitten im Betrieb der 
Controller absäuft, dann ist das nicht so witzig.

Die konstruktiven Änderungen sind aber unser Know How, das gibt es nicht 
als Code, sondern nur im Produkt.

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.