www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT90USB: Enumeration vollständig?


Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe eine Frage zur Enumeration von USB (HID) Devices unter 
WindowsXP. Bin nun mit meiner Firmware für den AT90USB647 irgendwie an 
einem toten Punkt angelangt... Meine konkrete Frage lautet: Wann ist die 
Enumeration device-seitig abgeschlossen? Meinen USB Traffic beobachte 
ich mit USBlyzer, und der gibt mir nach dem (vollständigen oder eben 
unvollständigen) Enumerationsprozess folgende Infos zu meinem Device:

Connection Status      Device connected 
Current Configuration  0 
Speed                  Low 
Device Address         0  
Number Of Open Pipes   0 

Device Descriptor 
Offset Field            Size Value    Description 
     0 bLength            1    12h  
     1 bDescriptorType    1    01h    Device 
     2 bcdUSB             2  0110h    USB Spec 1.1 
     4 bDeviceClass       1    00h    Class info in Ifc Descriptors 
     5 bDeviceSubClass    1    00h  
     6 bDeviceProtocol    1    00h  
     7 bMaxPacketSize0    1    08h    8 bytes 
     8 idVendor           2  03EBh    Atmel Corp. 
    10 idProduct          2  2013h  
    12 bcdDevice          2  0100h    1.00 
    14 iManufacturer      1    01h  
    15 iProduct           1    02h  
    16 iSerialNumber      1    03h  
    17 bNumConfigurations 1    01h  

Windows-seitig ist noch kein Treiber für mein Gerät vorhanden, und ich 
frage mich, ob das allein der Grund dafür ist, dass:
1. Full-Speed nicht erkannt wird
2. die Strings nicht komplett ausgelesen werden (nur StringIndex3 und 
StringIndex2)
3. im Windows Gerätemanager bei meinem Device das gelbe Ausrufezeichen 
auftaucht.

Ist mit der Enumeration erstmal alles in Ordnung und wird sich alles 
fügen, wenn ich Windows-seitig für einen Treiber gesorgt habe? Oder 
sollte mein Device-Status auch ohne vorhandenen Windowstreiber schon 
anders aussehen?

Gruß,
Trillian

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
unter http://www.beyondlogic.org/usbnutshell/usb7.htm wird der 
Enum-Vorgang beschrieben. Du solltest mindestens eine Geräteadresse 
bekommen.
Ich kann dir für eine HID-Tastatur den Bespielcode von Maxim empfehlen, 
speziell für MAX3421E und MAX3420. Die untere Schicht musst du selber 
implementieren. Irgendwo liegt ein sauber umgeschriebener Code für den 
Blackfin DSP bei mir rum. Der ist auch lesbar :)
Die Speederkennung läuft über Pull-Up und Down-Widerstände, die meist 
per Software geschaltet werden können. Wie es beim Atmel ist weiß ich 
leider nicht, ich habe die oben genannten Chips verwendet. Wenn dies 
nicht erfolgt, wird ein Low-Speedgerät signalisiert.

2. Wie schaut dein Stringdescriptor aus? Index 0 (das erste Element) 
muss die Sprachversionen der folgenden Elemente beinhalten. Das kann ein 
Grund sein, weshalb der eine nicht gelesen wird, weil Index 1 bei dir 
als Sprache verwendet wird.

3. Das Device hat keinen Treiber und ist Windows in der Ansteuerung 
unbekannt, deswegen das !

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Benjamin,

danke schonmal für die Antwort :) Also durch den ganzen Enum-kram hab 
ich mich schon einigermaßen durchgewühlt und grob auch alles verstanden. 
Das was ich im USBlyzer nachvollziehen kann ist folgendes:

1. komischerweise wird zuerst nach dem String0 Deskriptor (Str Lang ID) 
gefragt, der dann auch offensichtlich korrekt übertragen wird. Sieht 
dann eingelesenerweise so aus:
String Descriptor 
Offset Field             Size   Value   Description
0      bLength             1      04h  
1      bDescriptorType     1      03h   String 
2      wLANGID[0]          2    0409h   English (United States) 

2. dann wird gleich String Deskriptor 3 abgefragt
String Descriptor 
Offset Field             Size   Value                    Description
0      bLength             1      0Eh  
1      bDescriptorType     1      03h                    String 
2      bString             12   0031h 0030h 0041h 0030h
                                0031h 0031h              "10A011" 

3. dann wird schon der komplette Konfigurationsdeskriptor bzw 255 Byte 
(inkl. 1 Interface- und 2 Endpointdeskriptoren) verlangt und gesendet
Configuration Descriptor 1 Self Powered
Offset Field                Size   Value  Description 
0      bLength                1      09h  
1      bDescriptorType        1      02h  Configuration 
2      wTotalLength           2    0020h  
4      bNumInterfaces         1      01h  
5      bConfigurationValue    1      01h  
6      iConfiguration         1      00h  
7      bmAttributes           1      C0h  Self Powered 
       4..0: Reserved          ...00000   
       5: Remote Wakeup        ..0.....   No 
       6: Self Powered         .1......   Yes 
       7: Reserved (set to one)1.......
          (bus-powered for 1.0)     
8      bMaxPower              1      32h  100 mA 

Interface Descriptor 0/0 HID, 2 Endpoints
Offset Field                Size  Value  Description 
0      bLength                1     09h  
1      bDescriptorType        1     04h  Interface 
2      bInterfaceNumber       1     00h  
3      bAlternateSetting      1     00h  
4      bNumEndpoints          1     02h  
5      bInterfaceClass        1     03h  HID 
6      bInterfaceSubClass     1     00h  
7      bInterfaceProtocol     1     00h  
8      iInterface             1     00h  

Endpoint Descriptor 01 1, Control, 8 bytes
...

Endpoint Descriptor 82 2, Control, 8 bytes
...

4. Port Status wird abgefragt mit der Antwort, dass ein Device 
angesteckt ist, der Port enabled ist und das Device "Low-Speed" wäre

5. jetzt wirds irgendwie komisch: Es wird nochmal String Deskriptor 0 
abgefragt und gesendet. Dann String Deskriptor 2. Dann nochmal String 
Deskriptor 0 und nochmals Nummer 2.

6. Abfrage und Übertragung des Device Deskriptors (wie oben im 
Eröffnungsbeitrag)

7. Abfrage und Übertragung von 9 Byte des Config Descriptors

8. Abfrage und Übertragung von 32 Byte des Config Descriptors

9. ClearPortFeature Request mit Value 0001h (Feature: Enabled/Disabled) 
<-- weiß ich nich so recht was mit anzufangen, der Port in dem mein 
Device steckt wird geenabled bzw. gedisabled??

So und dann is Ende mit meinem Device. Ist im Großen und Ganzen 
irgendwie anders als bei USB in a nutshell beschrieben - oder der 
USBlyzer gibt das Ganze ein bisschen komisch wieder.

Meine Frage ist immernoch: Kann ich mich jetzt der Windows-Seite widmen 
oder läuft was schief bei meiner "Enumeration"?

LG Trillian

Edit: Achso ja, mein AT90 sagt mir, er hätte eine Adresse bekommen. Das 
Register UDADDR sieht so aus: 10000010 (es wurde die Adresse 2 vergeben 
und diese ist auch enabled)

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du den kompletten Descriptor mal Posten mir per Email schicken. 
Dann würde ich mir den ansehen.

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok E-Mail ist raus - hoffe sie kommt auch an ;) Danke schonmal

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habs bekommen. Ich hab zwei kleine Fehler gefunden. Beim Entpunkt gibtst 
du als  Typ Isochron an. Als Wert nimmst du aber 0x00 was für Control 
steht. Wenn es wirklich isochron sein soll, dann muss es 0x01 sein + 
zusätzliche Flags. Und dann muss auch das letzte Byte gesetzt sein fürs 
Polling Intervall.
Bei den Strings musst du auch für Index 2 und 3 die Sprache setzen. Ich 
kopiers mal ohne explizite Erlaubnis hier herein.

USB_STRING0_DESCRIPTOR:
0x08;.......size of descriptor (4bytes)
0x03;.......string descriptor
0x09
0x04;.......index of unicode language (english)
0x09
0x04;.......index of unicode language (english)
0x09
0x04;.......index of unicode language (english)

so müsste das aussehen. Wenn du ein HID Gerät hast, musst du zusätzlich 
noch den HID-Descriptor schreiben und den übertragen, deswegen das ! im 
Gerätemanager. Sonst lädt Windoof die Treiber selber.

Ist aus dem Appnote vom MAX3421E, mit dem ich ein anderes Interconnect 
gebaut habe.
// HID Descriptor--It's at CD[18]
  0x09,      // bLength
  0x21,      // bDescriptorType = HID
  0x10,0x01,    // bcdHID(L/H) Rev 1.1
  0x00,      // bCountryCode (none)
  0x01,      // bNumDescriptors (one report descriptor)
  0x22,      // bDescriptorType  (report)
  43,0                    // CD[25]: wDescriptorLength(L/H) (report 
descriptor size is 43 bytes)

Dafür gibt es noch weitere Abfragen im Standardprotokoll, die 
implementiert sein müssen und den Descriptor explizit abfragen. Du musst 
dann diesen (obiges Beispiel ist Tastatur) zurückliefern.
In meinem Code sind die Descriptoren für Config/Interface/HID/Endpunkte 
direkt in einem char Array, weil der Host den gesamten Descriptor haben 
will.

Hoffe es hilft,
Benjamin

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry hab noch was vergessen. Zum HID Descriptor brauchst du noch nen 
Report Descriptor :)

const unsigned char RepD[]=   // Report descriptor
  {
  0x05,0x01,    // Usage Page (generic desktop)
  0x09,0x06,    // Usage (keyboard)
  0xA1,0x01,    // Collection
  0x05,0x07,    //   Usage Page 7 (keyboard/keypad)
  0x19,0xE0,    //   Usage Minimum = 224
  0x29,0xE7,    //   Usage Maximum = 231
  0x15,0x00,    //   Logical Minimum = 0
  0x25,0x01,    //   Logical Maximum = 1
  0x75,0x01,    //   Report Size = 1
  0x95,0x08,    //   Report Count = 8
  0x81,0x02,    //  Input(Data,Variable,Absolute)
  0x95,0x01,    //   Report Count = 1
  0x75,0x08,    //   Report Size = 8
  0x81,0x01,    //  Input(Constant)
  0x19,0x00,    //   Usage Minimum = 0
  0x29,0x65,    //   Usage Maximum = 101
  0x15,0x00,    //   Logical Minimum = 0,
  0x25,0x65,    //   Logical Maximum = 101
  0x75,0x08,    //   Report Size = 8
  0x95,0x01,    //   Report Count = 1
  0x81,0x00,    //  Input(Data,Variable,Array)
  0xC0};      // End Collection

Wieder aus dem Beispielcode vom Maxim. MAcht ne schöne Tastatur.

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmals vielen Dank für so eine ausführliche Antwort :)

Ok - alles schaff ich heute abend nicht mehr zu realisieren - dafür war 
der Tag schon zu lang ;) Die Sache mit dem Isochronous Endpoint hatte 
ich nur noch falsch auskommentiert, es soll tatsächlich ein Control EP 
sein. Sorry...

Das mit dem String 0 Descriptor habe ich mal probiert, aber an der oben 
beschrieben Abfolge und dem erstmal fehlenden String 1 Descriptor hat 
sich nichts geändert. Ich glaube auch nicht dass man für jeden einzelnen 
String eine extra Sprach-Definition im String 0 Descriptor vornehmen 
muss - vielmehr hat man eben die Möglichkeit, bei Bedarf mehr als eine 
unterstützte Sprache dort zu hinterlegen.

Ich glaube die Sache mit dem HID- und dem HID-Report Descriptor ist das 
Problem bei mir. Ich muss zugeben, dass mir das vollkommen neu ist... 
Ich werde die beiden morgen gleich mal zu den anderen Descriptoren 
hinzufügen und dann hier nochmal berichten.

Ich denke wirklich das isses nun. Super, dankeschön :)

LG Trillian

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei den String D. musst du, soweit ich weiß, die Sprachen angeben, weil 
er damit die Anzahl berechnet. Ausser sind oben bereits irgendwo 
genannt. Genau kann ichs dir aber nicht sagen.

Nur noch als Info:
Wenn die Anfrage kommt über einen Setuprequest, ich kenns als 
SUD-Packet,
dann musst du in Offset 0x03 nachsehen, so wie jetzt auch.

Der Wert dort drinnen, sagt dir, welchen Descriptor du senden musst.

0x01  // Device
0x02  // Configuration
0x03  // String
0x21  // HID
0x22  // Report

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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