Forum: Mikrocontroller und Digitale Elektronik ATmega32u2 USB HID Media Keys


von N. G. (newgeneration) Benutzerseite


Lesenswert?

Hallo Forum,

ich wollte mir ein kleines Keyboard bauen, dass nur die Mediatasten hat, 
also
 - Mute
 - Vol+
 - Vol-
 - play/pause
 - stop
 - << (spulen)
 - >> (spulen)
 - skip fwd
 - skip bckwd
Soweit der Plan.
Als Hardware habe ich hier einen ATmega32u2 vor mir liegen, der zwas 
abenteuerlich verlötet ist, aber funktioniert. Der Atmel DFU-Bootloader 
funktioniert und ich habe den AVR schon dazu gebracht, sich am PC 
(Windows) als Tastatur anzumelden. Normale Tastendrücke senden geht.
Als "Lib" verwende ich diese: http://www.weigu.lu/b/usb/index.html
Diese hat einen Standard-Desc. eingebaut:
1
// Report Descriptor Keyboard
2
  0x05,0x01,// Usage_Page (Generic Desktop)
3
  0x09,0x06,// Usage (Keyboard)
4
  0xA1,0x01,// Collection (Application)
5
  0x05,0x07,// Usage page (Key Codes)
6
  0x19,0xE0,// Usage_Minimum (224)
7
  0x29,0xE7,// Usage_Maximum (231)
8
  0x15,0x00,// Logical_Minimum (0)
9
  0x25,0x01,// Logical_Maximum (1)
10
  0x75,0x01,// Report_Size (1)
11
  0x95,0x08,// Report_Count (8)
12
  0x81,0x02,// Input (Data,Var,Abs) = Modifier Byte
13
  0x81,0x01,// Input (Constant) = Reserved Byte
14
  0x19,0x00,// Usage_Minimum (0)
15
  0x29,0x65,// Usage_Maximum (101)
16
  0x15,0x00,// Logical_Minimum (0)
17
  0x25,0x65,// Logical_Maximum (101)
18
  0x75,0x08,// Report_Size (8)
19
  0x95,0x06,// Report_Count (6)
20
  0x81,0x00,// Input (Data,Array) = Keycode Bytes(6)
21
  0x05,0x08,// Usage Page (LEDs)
22
  0x19,0x01,// Usage_Minimum (1)
23
  0x29,0x05,// Usage_Maximum (5)
24
  0x15,0x00,// Logical_Minimum (0)
25
  0x25,0x01,// Logical_Maximum (1)
26
  0x75,0x01,// Report_Size (1)
27
  0x95,0x05,// Report_Count (5)
28
  0x91,0x02,// Output (Data,Var,Abs) = LEDs (5 bits)
29
  0x95,0x03,// Report_Count (3)
30
  0x91,0x01,// Output (Constant) = Pad (3 bits)
31
  0xC0    // End_Collection

Jetzt zum Problem:
ich habe keine Ahnung, wie der richtige Descriptor auszusehen hat, damit 
man auch die Media-Tasten nutzen kann.
Ich kenne mich auch mit USB nicht aus, das ist mein erstes Projekt in 
dieser Richtung.

Es wäre nett, wenn evtl jmd einen passenden Desriptor hätte oder es mir 
erklären könnte.

mfG
N.G.

von marc (Gast)


Lesenswert?

Hallo;
Es wäre nett, wenn evtl jmd einen passenden Desriptor hätte oder es mir
erklären könnte.


Aus dem Stegreif nicht, da meine letzten Entwicklungen im Bereich HID 
USB 15 Jahre zurückligen, aber(nicht böse gemeint):

 - die USB Spezifikation ist verstanden, insbesondere zur HID Klasse ?

oder anders: Hast du dir die entsprechenden Schriften von der USB 
Organisation einmal besorgt.

Dort gib es auch Tools zur Erstellung passender Descriptoren.
Aber:
Solange das Konzept nicht verstanden wurde ist das immer fischen im 
Dunkeln.

Oder anders:
Auch wenn Ihnen / dir jemand einen zufällig passenden Descriptor Gäbe
Wäre das Prinzip nicht verstanden.

Gruss

von N. G. (newgeneration) Benutzerseite


Lesenswert?

marc schrieb:
> aber(nicht böse gemeint)
ich kann die Einwände verstehen.

marc schrieb:
> die USB Spezifikation ist verstanden, insbesondere zur HID Klasse ?

Naja, nur so halb, bzw: ich habs gelesen komme damit aber insgesamt noch 
nicht zu recht. Die Mediatasten müssen wohl von einem Consumer Device 
sein, die normalen Tasten von einem Generic desktop device/Keyboard. 
Aber ich bekomme auch nach testen keinen funktionierenden Deskriptor 
hin.
Habe ich mal zusammengebastelt (ist aber wahrscheinlich in mehr als 5 
dingen falsch...):
1
USAGE_PAGE (Consumer Devices)          05 0C
2
USAGE (Consumer Control)               09 01
3
COLLECTION (Application)               A1 01 
4
  USAGE_PAGE (Keyboard)                05 07
5
  USAGE_MINIMUM (Keyboard Mute)        19 7F
6
  USAGE_MAXIMUM (Keyboard Volume Down) 29 81
7
  LOGICAL_MINIMUM (0)                  15 00 
8
  LOGICAL_MAXIMUM (1)                  25 01 
9
  REPORT_SIZE (1)                      75 01 
10
  REPORT_COUNT (3)                     95 03 
11
  INPUT (Data,Var,Abs)                 81 02 
12
  INPUT (Cnst,Var,Abs)                 81 03 
13
END_COLLECTION                         C0

Ich würde das Prinzip jedoch schon gerne verstehen ;)
Sprich: lernwillig, nur mit Cerständnisproblemen...

aber Danke schon mal!

: Bearbeitet durch User
von N. G. (newgeneration) Benutzerseite


Lesenswert?

weiß niemand Rat oder einen Link oder ähnliches. Ich werde aus den 
ganzen Tutorials etc. nicht schlau

von Jope (Gast)


Lesenswert?

Das mit dem USAGE "Keyboard Mute", "Keyboard Volume Down", etc. kannst 
Du vergessen, das funktioniert nicht (aus eigener Erfahrung). Die 
Medientasten gehören zu den "Consumer Page"-USAGEs.

Ich habe das im Einsatz, und es funktioniert (unter Windows/Linux).
Eine Kombination aus Keyboard und Consumer Control (Keyboard wird nicht 
benutzt):
1
{ 
2
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
3
    0x09, 0x06,                    // USAGE (Keyboard)
4
    0xa1, 0x01,                    // COLLECTION (Application)
5
    0x85, 0x01,                    //   REPORT_ID (1)
6
    0x05, 0x07,                    //   USAGE_PAGE (Keypad)
7
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
8
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
9
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
10
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
11
    0x75, 0x01,                    //   REPORT_SIZE (1)
12
    0x95, 0x08,                    //   REPORT_COUNT (8)
13
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
14
    0x95, 0x01,                    //   REPORT_COUNT (1)
15
    0x75, 0x08,                    //   REPORT_SIZE (8)
16
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
17
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
18
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
19
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
20
    0xc0,                          // END_COLLECTION
21
22
    0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)    
23
    0x09, 0x01,                    // USAGE (Consumer Control)
24
    0xa1, 0x01,                    // COLLECTION (Application)    
25
    0x85, 0x02,                    //   REPORT_ID (2)
26
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
27
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
28
    0x09, 0xe9,                    //   USAGE (Volume Up)
29
    0x09, 0xea,                    //   USAGE (Volume Down)
30
    0x75, 0x01,                    //   REPORT_SIZE (1)
31
    0x95, 0x02,                    //   REPORT_COUNT (2)
32
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
33
    0x09, 0xe2,                    //   USAGE (Mute)
34
    0x95, 0x01,                    //   REPORT_COUNT (1)    
35
    0x81, 0x06,                    //   INPUT (Data,Var,Rel)  --> relativ, d.h. Senden toggelt Mute 
36
    0x95, 0x05,                    //   REPORT_COUNT (5)      
37
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
38
    0xc0                           // END_COLLECTION
39
};

Damit hat man zwei Reports, einen mit ID 1 (Keyboard, bei mir nicht 
benutzt) und einen für die Medientasten (Consumer Control) mit ID 2, ein 
Byte lang (jeweils ein Bit für Vol+, Vol-, Mute, und 5 Füllbits).

von M. L. (ado)


Lesenswert?

Es gibt noch eine andere AVR-USB Bibiothek mit vielen Beispielen.

http://www.fourwalledcubicle.com/LUFA.php

von Henrik H. (Firma: TU Chemnitz) (heha)


Lesenswert?

Oh, gerade stolpere ich über das gleiche Problem, um dann rauszufinden, 
dass ich das selber sowas ähnliches schon gelöst hatte, vor 10 Jahren:

http://www.tu-chemnitz.de/~heha/basteln/PC/Mikrofonverstärker/OneKey.zip/

Üblicherweise sind HID-Deskriptoren für Tastaturen so gebaut, dass mit 
einem Input-Report vom Typ "Array" eine gewisse Anzahl gleichzeigig 
gedrückter Tasten als Report-ID gemeldet werden. Nullen stehen in leeren 
Arraypositionen, weil HID-Reports stets konstante Länge haben. Der 
Report wird immer dann abgesendet, wenn sich etwas ändert. Um 
Tastenrepeat kümmert sich der Host-PC.

Bei dem von mir „erfundenen“ HID-Deskriptor habe ich die Tasten auf Bits 
eines Bytes gelegt, so wie man das bei wenigen (<=16) Tasten macht: Der 
HID-Deskriptor beschreibt hier für jedes Bit eine Usage (oder keine für 
freie Bits). Geschickterweise so, dass ein simples Lesen von PortB (des 
verwendeten ATtiny25) bereits die richtige Bitkombination liefert. Das 
Umstapeln der Bits muss der PC machen (= das tut er sowieso).

Obwohl das einigermaßen unterdokumentiert ist, funktioniert das 
anscheinend mit jedem Computer, denn bei Mäusen wird's auch so gemacht.

Allerdings verwendet das o.a. Beispiel keine Mediensteuertasten. Es 
dürfte jedoch genauso funktionieren.

Anzumerken wäre noch, dass USB die fürchterliche Hampelei mit Extended 
Keycodes bei PS/2 vergessen lässt: Selten ist etwas neues einfacher 
als der Vorgänger.

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.