Hallo, ich versuche derzeit eine USB-Verbindung zwischen einem PIC32MZ2048EFH064 Mikrocontroller (USB Device) und einem Windows 10 PC (USB Host) herzustellen. Im Grunde genommen sieht es schon gar nicht so schlecht aus. Das Device wird im Gerätemanager angezeigt, allerdings mit dem Hinweis, dass es nicht gestartet werden kann (Code 10). Anhand der Ergebnisse mehrerer Software USB Sniffer (siehe Screenshots) bin ich der Meinung, dass die Deskriptoren korrekt übertragen werden. Nach deren Übertragung fragt der Host dann den Device Status ab, woraufhin die Verbindung scheinbar abgebrochen wird. Für die gleiche Hardware habe ich eine andere Software auf Basis von Harmony 3 (gleiche Clocksettings), mit der das Ganze funktioniert. Deshalb schließe ich Hardwareprobleme bzw. Oszillatoreinstellungen aus. Es muss sich um ein Softwareproblem handeln. Ich wäre über jeden Tipp dankbar, da ich nicht mehr weiß, was ich noch ausprobieren könnte. Vielen Dank für eure Hilfe!
Versuch's mal mit Linux, die Meldungen des Linux Kernel sind oft relativ hilfreich. Mit Wireshark kann man USB ebenfalls ganz gut debuggen. Sicher dass du auf Get Status korrekt antwortest?
Ich habe das Problem anscheinend gefunden. Wenn ich den Configuration Descriptor wie folgt abändere, funktioniert es: uint8_t USB_ConfigurationDescriptor[] = { /* bLength */ USB_CONFIGURATION_DESCRIPTOR_LENGTH, /* bDescriptorType */ 0x02, /* wTotalLength */ USB_CONFIGURATION_DESCRIPTOR_LENGTH,0x00, /* bNumInterfaces */ 0, /* bConfigurationValue */ 1, /* iConfiguration */ 0, // no string /* bmAttributes */ 0xC0, // self-powered /* bMaxPower */ 0x00 }; So habe ich zwar noch kein Interface bzw. keine Endpoints definiert, aber immerhin klappt schonmal die Enumeration. Dann versuche ich jetzt mal das Interface und die Enpoints mit zu übergeben.
Charly schrieb: > Ich habe das Problem anscheinend gefunden. Ah, ja logisch, so wie es ursprünglich war kann es nicht funktionieren. Der Configuration-Deskriptor muss die Interface- und Endpoint-Deskriptoren mit enthalten, als ein großer Block. Dieser Block wird dann "am Stück" abgefragt. Die einzelnen Interface/Endpoint-Deskriptoren werden nicht explizit abgefragt. Der Code dafür ist also überflüssig. In der USB-Spec heißt es: "The standard request to a device supports three types of descriptors: device (also device_qualifier), configuration (also other_speed_configuration), and string." PS: USB-Tutorial mit STM32 gesehen?
Niklas G. schrieb: > Ah, ja logisch, so wie es ursprünglich war kann es nicht funktionieren. > Der Configuration-Deskriptor muss die Interface- und > Endpoint-Deskriptoren mit enthalten, als ein großer Block. Dieser Block > wird dann "am Stück" abgefragt. Ja genau, das habe ich mittlerweile auch woanders gesehen. Wenn ich das allerdings versuche, schlägt die Enumeration wieder fehl. So sieht mein Deskriptor nun aus, wobei USB_CONFIGURATION_DESCRIPTOR_wTotalLength = 25 ist:
1 | uint8_t USB_ConfigurationDescriptorFull[] = { |
2 | /* bLength */ USB_CONFIGURATION_DESCRIPTOR_LENGTH, |
3 | /* bDescriptorType */ 0x02, |
4 | /* wTotalLength */ USB_16bitTo8bitArrange(USB_CONFIGURATION_DESCRIPTOR_wTotalLength), |
5 | /* bNumInterfaces */ 1, |
6 | /* bConfigurationValue */ 1, |
7 | /* iConfiguration */ 0, // no string |
8 | /* bmAttributes */ 0x80 | 0x40, // self-powered |
9 | /* bMaxPower */ 0, |
10 | |
11 | /* bLength */ USB_INTERFACE_DESCRIPTOR_LENGTH, |
12 | /* bDescriptorType */ 0x04, |
13 | /* bInterfaceNumber */ 0x00, |
14 | /* bAlternateSetting */ 0, |
15 | /* bNumEndpoints */ 1, |
16 | /* bInterfaceClass */ 0xff, // vendor specific |
17 | /* bInterfaceSubClass */ 0xff, |
18 | /* bInterfaceProtocol */ 0xff, |
19 | /* iInterface */ 0, // no string |
20 | |
21 | /* bLength */ USB_ENDPOINT_DESCRIPTOR_LENGTH, |
22 | /* bDescriptorType */ 0x05, |
23 | /* bEndpointAddress */ 1 | 0x00, |
24 | /* bmAttributes */ 0x02, |
25 | /* wMaxPacketSize */ USB_16bitTo8bitArrange(MAIN_SPI_RX_BUFFER_SIZE), |
26 | /* bInterval */ 1 |
27 | };
|
Deshalb folgende Frage: Bin ja gerade erstmal nur an der Enumeration dran. Das heißt ich teile dem Host mit, dass es ein Interface mit einem zusätzlichen Endpunkt 1 gibt. Innerhalb des Mikrocontrollers exisitert der Endpunkt 1 aber noch nicht. Könnte das ein Problem sein? Nach dem, was ich gelesen habe, versucht der Host ja zunächst gar nicht diesen Endpunkt zu erreichen, oder?
Niklas G. schrieb: > PS: USB-Tutorial mit STM32 gesehen? Das habe ich schonmal überflogen, weil ich ursprünglich auch einen STM32-Controller verwenden sollte. Allerdings benötige ich USB Hi-Speed, STM32 unterstützt von Haus aus allerdings nur Full Speed. Ich werde nochmal in dem Artikel lesen, vielleicht finde ich was Hilfreiches.
Charly schrieb: > Könnte das ein Problem sein? Nach dem, > was ich gelesen habe, versucht der Host ja zunächst gar nicht diesen > Endpunkt zu erreichen, oder? Das tut er wenn erst nach SET_CONFIGURATION. Wie gesagt: Schließ das Gerät einfach mal an einen Linux-Host an und schau dir die "dmesg"-Ausgabe an. Wenn du Glück hast sagt es dir direkt was falsch ist. Charly schrieb: > Allerdings benötige ich USB Hi-Speed, > STM32 unterstützt von Haus aus allerdings nur Full Speed. Die STM32F7x3 haben einen integrierten USB HS PHY. Viele weitere STM32 wie die STM32F407 haben einen USB HS Controller, brauchen aber einen externen USB HS PHY der über ULPI angebunden wird.
Folgendes habe ich im UsbAudio Thread geschrieben: Am wichtigsten ist erst mal, dass im Config Deskriptor die wTotalLength korrekt ist. Falls das nicht stimmt gibt es alle möglichen lustigen Fehler. Ansonsten gibt UsbDevView ja schon Hinweise und Warnungen aus. Wenn ein Device gar nicht gefunden wird weil es nicht durch die Enum kommt kann der Fehler nur daran liegen, dass mindestens einer der unten beschriebenen Requests nicht so funktioniert wie er sollte. Damit die Enum funktioniert müssen folgende Requests funktionieren 1. Getdescriptor für Device und Config 2. SetAddress 3. SetConfig Danach kann usbview auch was anzeigen. Ein Getdescriptor muss auch mit seltsamen Angaben im wLength Feld umgehen können und der Host kann jederzeit einen Request abbrechen wenn er keine Lust mehr hat mehr Daten zu lesen. Ich würde im ersten Schritt erst mal alle Konstanten in den Deskriptoren überprüfen. Danach anstelle USB_16bitTo8bitArrange die Werte manuell in little Endian setzen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.