Hallo, mag mir einer von euch bei der Übersetzung eines USB-Protokolls helfen, bzw. mal kontrollieren, ob ich das soweit richtig gemacht habe? Ich empfange in einer HID-Tastatur-SETUP Sequenz folgendes: 80 06 00 01 00 00 40 00 Aus https://www.lowlevel.eu/wiki/Universal_Serial_Bus würde ich es wie folg übersetzen: Byte 0: 0x80 bmRequestType: Bit 0-4: Empfänger = Geräte Bit 5-6: Typ des Request = Standardrequest Bit 7: Richtung des Transfers = Host zum Gerät Byte 1: 0x06 bRequest: Nummer des Request = 6 Byte 2+3: 0x0001 wValue: Requestspezifischer Wert = 1 (k.A. was das bedeutet) Byte 4+5: 0x0000 wIndex: Requestspezifisch, kein Index, kein Offset = 0 Byte 6+7: 0x4000 wLength: Länge der zu übertragenden Daten = 0 Danach bekomme ich ein DATA0 Paket ohne Dateninhalt und ein ACK. Würde also mit der Datenlänge = 0 passen. Habe ich das soweit richtig übersetzt?
USB schrieb: > Byte 0: 0x80 > bmRequestType: > Bit 7: Richtung des Transfers = Host zum Gerät falsch > Byte 1: 0x06 > bRequest: Nummer des Request = 6 GET_DESCRIPTOR > Byte 2+3: 0x0001 > wValue: Requestspezifischer Wert = 1 (k.A. was das bedeutet) Die Spezifikation sagt: > The wValue field specifies the descriptor type in the high byte and > the descriptor index in the low byte. Und du hast hier Little Endian und Big Endian verwechselt; der Deskriptor-Typ ist 1 (Gerät). > Byte 6+7: 0x4000 > wLength: Länge der zu übertragenden Daten = 0 Nein, diese Zahl ist nicht Null, sondern 64.
ok, Danke. Einige Nachfragen hätte ich noch, vielleicht mal von hinten begonnen: Byte 6+7 = 64 weil erst das höherwertige 0x00 Übertragen wird, danach die 0x40 und dies eben zusammen 0x0040 = 64 ergibt. Ok, aber was ich dann nicht verstehe, es werden in den nachfolgenden Sequenzen keineswegs 64 Bytes übertragen, sondern ein DATA0 Paket ohne Inhalt. Danach kommt dann ein Device-Deskriptor mit 18Byte Länge... Danach neue Setupprozesse. Frage: Was sagen mir diese 64 Byte Länge an dieser Stelle? Tatsächlich ist in einem sehr viel späteren Frame wirklich mal ein Datenpaket dieser Länge mit dabei... das kommt aber erst sehr viel später... Byte 1: 0x06 Ist klar. Ist ein GetDescriptor. Danach kommt auch ein Descriptor von 18 Byte Länge im nächsten Frame im DATA0. Macht also Sinn für mich. Byte 0: 0x80 Ist das nicht 1000.0000 und somit die 1 im 7. Bit gesetzt? Wenn ich dies nun "anders-herum" übersetze und die Zahl 0000.0001 daraus mache, dann stimmen doch die aussagen für die oben angegebenen Werte nicht mehr... Ich kann doch nicht mal die Werte verdrehen und mal nicht... Da verstehe ich eine Sache irgendwie noch nicht 100%...
USB schrieb: > weil erst das höherwertige 0x00 Übertragen wird Nein, USB ist immer Little Endian; die Bytes auf dem Bus sind 40 00. Siehe Abschnitt 8.1 der Spezifikation. > es werden in den nachfolgenden Sequenzen keineswegs > 64 Bytes übertragen, sondern ein DATA0 Paket ohne Inhalt. Danach kommt > dann ein Device-Deskriptor mit 18Byte Länge wLength ist die maximale Länge. > Byte 0: 0x80 > Ist das nicht 1000.0000 und somit die 1 im 7. Bit gesetzt? Ja, das 7. Bit ist gesetzt. Und 1 = Device-to-host. Du darfst halt nicht irgendeiner Webseite glauben, sondern irgendeiner anderen: http://www.usb.org/developers/docs/usb20_docs/usb_20_080416.zip
aah ja, da scheint dann ja ein Fehler in meiner Quelle zu liegen... Danke!
so langsam komme ich weiter. Mein Device schickt einen get_Konfigurationsdescriptor mit dem Befehl: SETUP DATA0: 80 06 00 02 00 00 09 00 es wird also (0x80) Host seitig ein Get-(0x60) Transfer vom Gerät zum Host angefordert. Die 0x02 kennzeichnet einen Konfigurationsdescriptor. Der Host erlaubt dabei zunächst bis zu 9 Bytes (0x0009) anzunehmen. Der Host bekommt als Antwort: DATA1: 09 02 22 00 01 01 04 80 C8 Länge dieses Frames 0x09 = 9 Bytes Es ist ein Konfigurationsdescriptor 0x02 Die totale Länge des gesamten Descritpors wäre 0x0022 Bytes lang. Es gibt nur eine Konfiguration des Gerätes 0x01 Die Nummer dieser einen Konfiguration wird mit 0x01 angewählt Die 0x80 ist ein historisches Artefkat 0xC8 gibt an, dass das Gerät bis zu 200mA Strom verbrauchen wird. Danach fordert der Host mir SETUP DATA0 80 06 00 02 00 00 22 00 genau den gleichen Descriptor an, doch reserviert dieses mal einen genügenden Speicherbereich von 22 Bytes. In dem nächsten DATA1 Paket erhalte ich jetzt den ganzen Konfigurationsdeskriptor. DATA1: 09 02 22 00 01 01 04 80 C8 09 04 00 00 01 03 01 01 05 09 21 10 01 00 01 22 41 00 07 05 82 03 40 00 01 Die ersten 9 Bytes sind klar, doch was sagen mir die Bytes dahinter? Ich suche jetzt schon eine ganze Zeit lang nach den Stichworten Konfigurationsdescriptor, doch finde nicht so richtig eine Übersetzungshilfe was ich hier nun wo zu erwarten habe. Wie übersetze ich die Bytes 10 bis 22?
ich meine natürlich die Bytes 10 bis 0x22 also von Dec. 10 bis Dec. 34
USB schrieb: > Die ersten 9 Bytes sind klar, doch was sagen mir die Bytes dahinter? Abschnitt 9.6.3 der Spezifikation sagt: > When the host requests the configuration descriptor, all related > interface and endpoint descriptors are returned (refer to Section 9.4.3). Abschnitt 9.4.3 sagt: > A request for a configuration descriptor returns the configuration > descriptor, all interface descriptors, and endpoint descriptors for > all of the interfaces in a single request. The first interface > descriptor follows the configuration descriptor. The endpoint > descriptors for the first interface follow the first interface > descriptor. If there are additional interfaces, their interface > descriptor and endpoint descriptors follow the first interface’s endpoint > descriptors. Class-specific and/or vendor-specific > descriptors follow the standard descriptors they extend or modify.
aah, ok Danke. dann ist der Konfigurationsdescriptor: 09 02 22 00 01 01 04 80 C8 danach kommt ein Interfacedescriptor: 09 04 00 00 01 03 01 01 05 dann scheint ein Classspecific-Interfacedecriptor zu kommen: 09 21 10 01 00 01 22 41 00 welcher scheinbar ein HID Device beschreibt...? und schließlich ein Endpunktdescriptor: 05 82 03 40 00 01
Nachdem diese Descriptoren allesamt eingelesen ist, führt das Device folgendes Code aus: SETUP DATA0: 00 09 01 00 00 00 00 00 ACK dies übersetze ich zu einem Set_Coniguration. Da es nur eine Configuration gibt, ist diese natürlich die 01 im dritten Byte. Nun beobachte ich folgendes auf dem Bus: SETUP DATA0: 81 06 00 21 00 00 09 00 Die Antwort lautet: DATA1: 09 21 10 01 00 01 22 41 00 Offenbar wird mit 0x81 der bmRequestType von 10000001 gesetzt. In der Tabelle 9-3 unter Überschrift Standard Device Requests findet man diese Kombination nur zusammen mit bRequest GET_STATUS und GET_INTERFACE. Die 0x06 hingegen beschreibt einen GET_DESCRIPTOR. Das 4. Byte beschreibt den Typ des verlangten Descriptors und das 3. Byte den Index. Es wird also der HID-specific-Descriptor abgefragt. Die letzten beiden Bytes geben den aktuell reservierten Speicherplatz im Host an, es sind nur 9 Stück. Die Antwort des HID-Devices (0x21) sagt mit 0x0041, dass der Report Descriptor 65 Bytes umfasst. Danach sendet der Host die abgewandelte Anfrage: SETUP DATA0: 81 06 00 22 00 00 41 00 Danach empfange ich den gesamten Report Descriptor: DATA1 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 FF 00 05 07 19 00 2A FF 00 81 00 und danach ein DATA0 C0 Nun habe ich eine ganze Reihe Fragen hierzu: Das 4. Byte beschreibt den Descriptor Typ = Report. Wo finde ich weitere Informationen, wie ich nun die Kommunikation mit meinem Device gestalte, bzw. wie ich die Daten aus diesem Report nun für mich brauchbar überführen kann?
USB schrieb: > Wo finde ich weitere Informationen, wie ich nun die Kommunikation mit > meinem Device gestalte In der HID-Spezifikation. (Die ich mir nicht antun werde. Viel Erfolg noch ...)
In jedem Fall vielen Dank, hast mir gerade am Anfang gut in die Spur geholfen. Ich gucke mal, was ich noch so raus bekomme. Vielleicht guckt ja noch ein anderer USB-Profi mal rüber...?
Siehe
> http://eleccelerator.com/usbdescreqparser/
1 | 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) |
2 | 0x09, 0x06, // Usage (Keyboard) |
3 | 0xA1, 0x01, // Collection (Application) |
4 | 0x05, 0x07, // Usage Page (Kbrd/Keypad) |
5 | 0x19, 0xE0, // Usage Minimum (0xE0) |
6 | 0x29, 0xE7, // Usage Maximum (0xE7) |
7 | 0x15, 0x00, // Logical Minimum (0) |
8 | 0x25, 0x01, // Logical Maximum (1) |
9 | 0x75, 0x01, // Report Size (1) |
10 | 0x95, 0x08, // Report Count (8) |
11 | 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) |
12 | 0x95, 0x01, // Report Count (1) |
13 | 0x75, 0x08, // Report Size (8) |
14 | 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) |
15 | 0x95, 0x05, // Report Count (5) |
16 | 0x75, 0x01, // Report Size (1) |
17 | 0x05, 0x08, // Usage Page (LEDs) |
18 | 0x19, 0x01, // Usage Minimum (Num Lock) |
19 | 0x29, 0x05, // Usage Maximum (Kana) |
20 | 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) |
21 | 0x95, 0x01, // Report Count (1) |
22 | 0x75, 0x03, // Report Size (3) |
23 | 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) |
24 | 0x95, 0x06, // Report Count (6) |
25 | 0x75, 0x08, // Report Size (8) |
26 | 0x15, 0x00, // Logical Minimum (0) |
27 | 0x26, 0xFF, 0x00, // Logical Maximum (255) |
28 | 0x05, 0x07, // Usage Page (Kbrd/Keypad) |
29 | 0x19, 0x00, // Usage Minimum (0x00) |
30 | 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) |
31 | 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) |
32 | 0xC0, // End Collection |
33 | |
34 | // 64 bytes |
Das ist also eine Tastatur.
ja, dass es eine Tastatur ist, ist mir auch klar. Ich nähere mich der Sache derzeit mit den Usage-Table Dokumenten. Der Beginn des Reports lautet: 0x05 0x01 Im HID-TableDokument V1.12 findet man: Usages are 32-bit identifiers, where the high order 16 bits represents the usage page and the low order 16-bits represents the usage ID. Also: high 16-bit: usage page low 16-bit: usage ID 0x05 0x01 Also Little Endian: Usage Page: 01 = Generic Desktop Usage ID: 05 = GamePad ??????????????? Dickes Fragezeichen dahinter... Es ist kein Gamepad, sondern eine Tastatur. Kann mir einer dieses Problem auflösen?
Was soll mir der Post darüber denn sagen? Laut den HID-Usage-Table Dokumenten muss ich diese 32 Bit in jeweils 2 16Bit Wörter unterteilen und werde damit auf die Fährte eines Gamepads gelenkt, was natürlich falsch ist, aber warum? Welches Detail übersehe ich bei der manuellen Übersetzung?
USB schrieb: > high 16-bit: usage page > low 16-bit: usage ID Du weist schon warum da '16-bit' steht? USB schrieb: > Was soll mir der Post darüber denn sagen? Das daß: USB schrieb: > Der Beginn des Reports lautet: > 0x05 0x01 nicht mit dem zusammenpasst USB schrieb: > Also Little Endian: > Usage Page: 01 = Generic Desktop > Usage ID: 05 = GamePad ??????????????? sondern Dein '0x05 0x01' zusammen die 'Usage Page' ist und nicht Page & ID und das steht auch so im Post davor:
1 | 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) |
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.