3 # Contains class definitions to implement a USB keyboard.
6 from USBDevice import *
7 from USBConfiguration import *
8 from USBInterface import *
9 from USBEndpoint import *
11 class USBKeyboardInterface(USBInterface):
12 name = "USB keyboard interface"
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'
17 def __init__(self, verbose=0):
19 USB.desc_type_hid : self.hid_descriptor,
20 USB.desc_type_report : self.report_descriptor
23 endpoint = USBEndpoint(
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
34 # TODO: un-hardcode string index (last arg before "verbose")
35 USBInterface.__init__(
38 0, # alternate setting
48 # "l<KEY UP>s<KEY UP><ENTER><KEY UP>"
49 empty_preamble = [ 0x00 ] * 10
50 text = [ 0x0f, 0x00, 0x16, 0x00, 0x28, 0x00 ]
52 self.keys = [ chr(x) for x in empty_preamble + text ]
54 def handle_buffer_available(self):
58 letter = self.keys.pop(0)
59 self.type_letter(letter)
61 def type_letter(self, letter, modifiers=0):
62 data = bytes([ 0, 0, ord(letter) ])
65 print(self.name, "sending keypress 0x%02x" % ord(letter))
67 self.configuration.device.maxusb_app.send_on_endpoint(3, data)
70 class USBKeyboardDevice(USBDevice):
71 name = "USB keyboard device"
73 def __init__(self, maxusb_app, verbose=0):
74 config = USBConfiguration(
76 "Emulated Keyboard", # string desc
77 [ USBKeyboardInterface() ] # interfaces
85 0, # protocol release number
86 64, # max packet size for endpoint 0
89 0x3412, # device revision
90 "Maxim", # manufacturer string
91 "MAX3420E Enum Code", # product string
92 "S/N3420E", # serial number string