3 #include "USBHID_Types.h"
4 #include "USBDescriptor.h"
5 #include "HIDKeyboard.h"
7 #define DEFAULT_CONFIGURATION (1)
10 HIDKeyboard::HIDKeyboard(uint16_t vendor_id
, uint16_t product_id
, uint16_t product_release
): USBDevice(vendor_id
, product_id
, product_release
)
15 bool HIDKeyboard::sendReport(report_keyboard_t report
) {
16 USBDevice::write(EP1IN
, report
.raw
, sizeof(report
), MAX_PACKET_SIZE_EP1
);
20 uint8_t HIDKeyboard::leds() {
24 bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration
) {
25 if (configuration
!= DEFAULT_CONFIGURATION
) {
29 // Configure endpoints > 0
30 addEndpoint(EPINT_IN
, MAX_PACKET_SIZE_EPINT
);
31 //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
33 // We activate the endpoint to be able to recceive data
34 //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
39 uint8_t * HIDKeyboard::stringImanufacturerDesc() {
40 static uint8_t stringImanufacturerDescriptor
[] = {
42 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
43 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
45 return stringImanufacturerDescriptor
;
48 uint8_t * HIDKeyboard::stringIproductDesc() {
49 static uint8_t stringIproductDescriptor
[] = {
51 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
52 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
54 return stringIproductDescriptor
;
57 uint8_t * HIDKeyboard::stringIserialDesc() {
58 static uint8_t stringIserialDescriptor
[] = {
60 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
61 '0',0 /*bString iSerial*/
63 return stringIserialDescriptor
;
66 uint8_t * HIDKeyboard::reportDesc() {
67 static uint8_t reportDescriptor
[] = {
68 USAGE_PAGE(1), 0x01, // Generic Desktop
69 USAGE(1), 0x06, // Keyboard
70 COLLECTION(1), 0x01, // Application
72 USAGE_PAGE(1), 0x07, // Key Codes
73 USAGE_MINIMUM(1), 0xE0,
74 USAGE_MAXIMUM(1), 0xE7,
75 LOGICAL_MINIMUM(1), 0x00,
76 LOGICAL_MAXIMUM(1), 0x01,
78 REPORT_COUNT(1), 0x08,
79 INPUT(1), 0x02, // Data, Variable, Absolute
81 REPORT_COUNT(1), 0x01,
83 INPUT(1), 0x01, // Constant
85 REPORT_COUNT(1), 0x05,
87 USAGE_PAGE(1), 0x08, // LEDs
88 USAGE_MINIMUM(1), 0x01,
89 USAGE_MAXIMUM(1), 0x05,
90 OUTPUT(1), 0x02, // Data, Variable, Absolute
92 REPORT_COUNT(1), 0x01,
94 OUTPUT(1), 0x01, // Constant
97 REPORT_COUNT(1), 0x06,
99 LOGICAL_MINIMUM(1), 0x00,
100 LOGICAL_MAXIMUM(2), 0xFF, 0x00,
101 USAGE_PAGE(1), 0x07, // Key Codes
102 USAGE_MINIMUM(1), 0x00,
103 USAGE_MAXIMUM(1), 0xFF,
104 INPUT(1), 0x00, // Data, Array
107 reportLength
= sizeof(reportDescriptor
);
108 return reportDescriptor
;
111 uint16_t HIDKeyboard::reportDescLength() {
116 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
117 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
118 + (1 * HID_DESCRIPTOR_LENGTH) \
119 + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
120 uint8_t * HIDKeyboard::configurationDesc() {
121 static uint8_t configurationDescriptor
[] = {
122 CONFIGURATION_DESCRIPTOR_LENGTH
,// bLength
123 CONFIGURATION_DESCRIPTOR
, // bDescriptorType
124 LSB(TOTAL_DESCRIPTOR_LENGTH
), // wTotalLength (LSB)
125 MSB(TOTAL_DESCRIPTOR_LENGTH
), // wTotalLength (MSB)
126 0x01, // bNumInterfaces
127 DEFAULT_CONFIGURATION
, // bConfigurationValue
128 0x00, // iConfiguration
129 C_RESERVED
| C_REMOTE_WAKEUP
, // bmAttributes
130 C_POWER(100), // bMaxPowerHello World from Mbed
132 INTERFACE_DESCRIPTOR_LENGTH
, // bLength
133 INTERFACE_DESCRIPTOR
, // bDescriptorType
134 0x00, // bInterfaceNumber
135 0x00, // bAlternateSetting
136 0x01, // bNumEndpoints
137 HID_CLASS
, // bInterfaceClass
138 1, // bInterfaceSubClass (boot)
139 1, // bInterfaceProtocol (keyboard)
142 HID_DESCRIPTOR_LENGTH
, // bLength
143 HID_DESCRIPTOR
, // bDescriptorType
144 LSB(HID_VERSION_1_11
), // bcdHID (LSB)
145 MSB(HID_VERSION_1_11
), // bcdHID (MSB)
146 0x00, // bCountryCode
147 0x01, // bNumDescriptors
148 REPORT_DESCRIPTOR
, // bDescriptorType
149 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
150 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
152 ENDPOINT_DESCRIPTOR_LENGTH
, // bLength
153 ENDPOINT_DESCRIPTOR
, // bDescriptorType
154 PHY_TO_DESC(EP1IN
), // bEndpointAddress
155 E_INTERRUPT
, // bmAttributes
156 LSB(MAX_PACKET_SIZE_EPINT
), // wMaxPacketSize (LSB)
157 MSB(MAX_PACKET_SIZE_EPINT
), // wMaxPacketSize (MSB)
158 1, // bInterval (milliseconds)
160 return configurationDescriptor
;
164 uint8_t * HIDKeyboard::deviceDesc() {
165 static uint8_t deviceDescriptor
[] = {
166 DEVICE_DESCRIPTOR_LENGTH
, /* bLength */
167 DEVICE_DESCRIPTOR
, /* bDescriptorType */
168 LSB(USB_VERSION_2_0
), /* bcdUSB (LSB) */
169 MSB(USB_VERSION_2_0
), /* bcdUSB (MSB) */
170 0x00, /* bDeviceClass */
171 0x00, /* bDeviceSubClass */
172 0x00, /* bDeviceprotocol */
173 MAX_PACKET_SIZE_EP0
, /* bMaxPacketSize0 */
174 (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
175 (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
176 (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
177 (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
178 (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
179 (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
180 0, /* iManufacturer */
182 0, /* iSerialNumber */
183 0x01 /* bNumConfigurations */
185 return deviceDescriptor
;
189 bool HIDKeyboard::USBCallback_request() {
190 bool success
= false;
191 CONTROL_TRANSFER
* transfer
= getTransferPtr();
192 uint8_t *hidDescriptor
;
194 // Process additional standard requests
196 if ((transfer
->setup
.bmRequestType
.Type
== STANDARD_TYPE
))
198 switch (transfer
->setup
.bRequest
)
201 switch (DESCRIPTOR_TYPE(transfer
->setup
.wValue
))
203 case REPORT_DESCRIPTOR
:
204 if ((reportDesc() != NULL
) \
205 && (reportDescLength() != 0))
207 transfer
->remaining
= reportDescLength();
208 transfer
->ptr
= reportDesc();
209 transfer
->direction
= DEVICE_TO_HOST
;
214 // Find the HID descriptor, after the configuration descriptor
215 hidDescriptor
= findDescriptor(HID_DESCRIPTOR
);
216 if (hidDescriptor
!= NULL
)
218 transfer
->remaining
= HID_DESCRIPTOR_LENGTH
;
219 transfer
->ptr
= hidDescriptor
;
220 transfer
->direction
= DEVICE_TO_HOST
;
234 // Process class-specific requests
235 if (transfer
->setup
.bmRequestType
.Type
== CLASS_TYPE
)
237 switch (transfer
->setup
.bRequest
) {
240 // TODO: check Interface and Report length?
241 // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
242 // if (transfer->setup.wLength == 1)
244 transfer
->remaining
= 1;
245 //transfer->ptr = ?? what ptr should be set when OUT(not used?)
246 transfer
->direction
= HOST_TO_DEVICE
;
247 transfer
->notify
= true; /* notify with USBCallback_requestCompleted */
257 void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf
, uint32_t length
)
260 CONTROL_TRANSFER
*transfer
= getTransferPtr();
261 if (transfer
->setup
.bmRequestType
.Type
== CLASS_TYPE
) {
262 switch (transfer
->setup
.bRequest
) {