Forum: Mikrocontroller und Digitale Elektronik ATmega32U2: USB-Debugging, da Enumeration unter Win7 mittendrin abbricht, Linux ok.


von Thomas T. (knibbel)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier einen ATmega32U2, welcher irgenwann mal per USB Daten mit 
dem PC austauschen soll. USB-Stack basiert auf den Routinen von Guy 
Weiler (www.weigu.lu/b/usb), allerdings inzwischen mit einer Vielzahl 
von Änderungen. Programmiert wird in Assembler...

Das Handling ist so gestaltet, das nur SETUP-Pakete im ATmega32U2 
Interrupts auslösen und bearbeitet werden.

Die Enumeration des ATmega32U2 an einem Linux-PC klappt auch 
einwandfrei: Nach den zwei "Get Descriptor: Configuration", werden noch 
ein paar Strings (Manufacturer, Product und Serial) übertragen und der 
ATmega32U2 ist danach korrekt als USB-Device angemeldet.

Unter Windows 7 bricht die Enumeration allerdings mittendrin ab (Siehe 
Bild). Es werden noch die zwei "Get Descriptor: Configuration" 
übertragen. Danach meint mein ATmega32U2 aber auf einen "Get Status" 
reagieren zu müssen und sendet seine zwei Statusbytes. Im angehängten 
Bild kann man sehen, dass nach der korrekten Abwicklung des zweiten 
"Configuration" (Request, Response & Status) mein "Get Status"-Response 
als zweite Response für "Configuration" interpretiert wird, obwohl 
"Configuration" bereits abgeschlossen war...

Die Strings danach werden dann nicht mehr übertragen und das USB-Device 
ist nicht korrekt angemeldet...

Wenn ich meine "Get Status"-Response auskommentiere und stattdessen ein 
STALL sende, dann klappt die Enumeration auch unter Windows. Ich will 
aber wissen, warum mein ATmega32U2 meint, einen "Get Status"-Response 
senden zu müssen.

Ich habe daraufhin mittels Software-USB-Sniffer versucht, etwas Licht 
ins Dunkel zu bekommen. Unter Linux mittels usbmon und wireshark klappt 
das auch hervorragend, unter Windows habe ich jedoch das Gefühl, dass 
ich nicht alles zu sehen bekomme...

Ok, dachte ich, dann schaue ich mir die Signale mit dem Logikanalyser an 
und dekodiere die Enumeration per Hand. Signale mitgeschrieben, Pegel 
angeguckt und von der schieren Menge erschlagen worden. Per Hand ist das 
nicht möglich, das würde Monate dauern...

An Hardwaredebuggern gibts den "Beagle 12", den "Beagle 480" und den 
"OpenVizsla". Letzteren hätte ich mir ja noch gegönnt, wenn man ihn denn 
irgendwo kaufen könnte. Aber die beiden "Beagle"-Geräte sind mir für 
meine einmalige Aktion schlicht zu teuer, davon abgesehen weiss ich 
nicht, ob der "Beagle 12" wirklich alle Pakete die über USB 
transportiert werden, auch anzeigt.

Wie kann ich weiter vorgehen? Im Moment lasse ich "Get Status" 
auskommentiert und mache mit der Software weiter.

Kann man sich irgendwo die "Beagle"-Geräte für 1-2 Wochen leihen (ich 
mache das nur hobbymäßig und vorrangig am Wochenende...)?

Gibt es irgendwo den "OpenVizsla" noch (gebraucht) zu kaufen? Wie sieht 
die Benutzersoftware dafür aus, gibt es die überhaupt? Da die Quellen 
verfügbar sind: Wäre ein Nachbau sinnvoll?

Habt Ihr irgendwelche Vorschläge? Ausser Kommentare wie "Zeig deinen 
Code!". Ich denke die sinnvolle Richtung lautet jetzt 
Hardware-Debugging...

Gruß,
Thomas

von Jim M. (turboj)


Lesenswert?

Du hast nicht zufällig die maxPacketSize des EP0 hochgesetzt ohne das 
auch im Code zu ändern? Der Configuration Deskriptor ist meistens größer 
als ein USB Paket, und es ist AFAIK nicht egal wie er für die 
Übertragung aufgeteilt wird.

von Jim M. (turboj)


Lesenswert?

Thomas T. schrieb:
> unter Windows habe ich jedoch das Gefühl, dass
> ich nicht alles zu sehen bekomme...

Das ist korrekt. Man sieht keine USB Resets - die habe ich erst auf dem 
neuen DSO gesehen. :-(

von Joe F. (easylife)


Lesenswert?

Mich macht stutzig, dass bei bLength des Configuration Descriptors die 
Länge 0 steht.
Üblicherweise läuft das so, dass der Host beim ersten Get Configuration 
Descriptor nur 4 Bytes haben will.

Das erste Byte ist dann 0x09 (Descriptor Length), das 2. 0x02 
(Configuration), und dann kommt ein Wort "wTotalLength".

Beim 2. Abfragen weiss der Host also jetzt, wie lang der Descriptor ist 
(wTotalLength), und fragt den kompletten Descriptor ab.

Wenn der Descriptor nicht in ein 64 Byte Paket passt, muss er auf 
mehrere In-Pakete aufgeteilt werden, und das scheint hier das Problem zu 
sein.

Es könnte z.B. sein dass PID nicht richtig toggelt (zwischen DATA0 und 
DATA1).
Klapp doch mal "Expert Info" auf (wenn das geht), vielleicht gibt es ja 
hier weiterführende Infos.

von Thomas (Gast)


Lesenswert?

Dein Code kann vermutlich mit dem usbreset nicht korrekt umgehen. Die 
ersten requests unterscheiden sich bei Win und osx/linux. Ich habe das 
früher benutzt um Win als Host zu detektieren. Bei Bedarf kann ich das 
raussuchen ist schon 15 Jahre her hab den genauen Ablauf nicht mehr 
parat.
Thomas

von Jim M. (turboj)


Lesenswert?

Thomas T. schrieb:
> Ok, dachte ich, dann schaue ich mir die Signale mit dem Logikanalyser an
> und dekodiere die Enumeration per Hand. Signale mitgeschrieben, Pegel
> angeguckt und von der schieren Menge erschlagen worden. Per Hand ist das
> nicht möglich, das würde Monate dauern...

Dafür gibts sigrok und PulseView. Damit hab ich mal meine USB Sachen 
analysiert, nicht ganz schmerzfrei - ich musste erstmal meine 
Eingagsdaten nach binär konvertieren - aber tat.

von Thomas T. (knibbel)


Lesenswert?

Thomas T. schrieb:
> Habt Ihr irgendwelche Vorschläge? Ausser Kommentare wie "Zeig deinen
> Code!". Ich denke die sinnvolle Richtung lautet jetzt
> Hardware-Debugging...

Das hätte ich selbst mal nicht so voreilig schreiben sollen...

Fehler gefunden.

Letztlich hatte ich in der Beantwortung von "Get Status", also nach dem 
Senden meiner beiden Statusbytes vergessen, im Anschluß ein 
"Acknowledge" zu übertragen. Da kam die Enumeration wohl ausm Tritt. Bei 
Linux fällt es nicht auf, weil da vielleicht kein "Get Status" vom 
Device gefordert war.

Jetzt läuft es aber fehlerfrei.

Stellt sich aber heraus, dass das Schreiben von USB-Routinen nicht 
trivial ist. Erst recht nicht in Assembler. Eine günstige, gute 
Debug-Möglichkeit auf der Hardwareebene (also Signale direkt von D+ und 
D- interpretieren) wäre wirklich wünschenswert. Und dann vielleicht noch 
als Open Source.

Trotzdem vielen Dank für eure Hinweise.

Gruß,
Thomas

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.