new maxusb library
[goodfet] / client / USBKeyboard.py
1 # USBKeyboard.py
2 #
3 # Contains class definitions to implement a USB keyboard.
4
5 from USB import *
6 from USBDevice import *
7 from USBConfiguration import *
8 from USBInterface import *
9 from USBEndpoint import *
10
11 class USBKeyboardInterface(USBInterface):
12     name = "USB keyboard interface"
13
14     hid_descriptor = b'\x09\x21\x10\x01\x00\x01\x22\x2b\x00'
15     report_descriptor = b'\x05\x01\x09\x06\xA1\x01\x05\x07\x19\xE0\x29\xE7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x19\x00\x29\x65\x15\x00\x25\x65\x75\x08\x95\x01\x81\x00\xC0'
16
17     def __init__(self, verbose=0):
18         descriptors = { 
19                 USB.desc_type_hid    : self.hid_descriptor,
20                 USB.desc_type_report : self.report_descriptor
21         }
22
23         endpoint = USBEndpoint(
24                 3,          # endpoint number
25                 USBEndpoint.direction_in,
26                 USBEndpoint.transfer_type_interrupt,
27                 USBEndpoint.sync_type_none,
28                 USBEndpoint.usage_type_data,
29                 16384,      # max packet size
30                 10,         # polling interval, see USB 2.0 spec Table 9-13
31                 self.handle_buffer_available    # handler function
32         )
33
34         # TODO: un-hardcode string index (last arg before "verbose")
35         USBInterface.__init__(
36                 self,
37                 0,          # interface number
38                 0,          # alternate setting
39                 3,          # interface class
40                 0,          # subclass
41                 0,          # protocol
42                 0,          # string index
43                 verbose,
44                 [ endpoint ],
45                 descriptors
46         )
47
48         # "ls<ENTER><KEY UP>"
49         self.text = [ chr(x) for x in [ 0x0f, 0x16, 0x28, 0x00 ] ]
50
51     def handle_buffer_available(self):
52         if not self.text:
53             return
54
55         letter = self.text.pop(0)
56         self.type_letter(letter)
57
58     def type_letter(self, letter, modifiers=0):
59         data = bytes([ 0, 0, ord(letter) ])
60
61         if self.verbose > 2:
62             print(self.name, "sending keypress 0x%02x" % ord(letter))
63
64         self.device.maxusb_app.send_on_endpoint(3, data)
65
66
67 class USBKeyboardDevice(USBDevice):
68     name = "USB keyboard device"
69
70     def __init__(self, maxusb_app, verbose=0):
71         config = USBConfiguration(
72                 1,                                          # index
73                 "Maxim Emulated Keyboard Configuration",    # string desc
74                 [ USBKeyboardInterface() ]                  # interfaces
75         )
76
77         USBDevice.__init__(
78                 self,
79                 maxusb_app,
80                 0,                      # device class
81                 0,                      # device subclass
82                 0,                      # protocol release number
83                 64,                     # max packet size for endpoint 0
84                 0x610b,                 # vendor id
85                 0x4653,                 # product id
86                 0x3412,                 # device revision
87                 "Maxim",                # manufacturer string
88                 "MAX3420E Enum Code",   # product string
89                 "S/N3420E",             # serial number string
90                 [ config ],
91                 verbose=verbose
92         )
93