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 bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration
) {
21 if (configuration
!= DEFAULT_CONFIGURATION
) {
25 // Configure endpoints > 0
26 addEndpoint(EPINT_IN
, MAX_PACKET_SIZE_EPINT
);
27 //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
29 // We activate the endpoint to be able to recceive data
30 //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
35 uint8_t * HIDKeyboard::stringImanufacturerDesc() {
36 static uint8_t stringImanufacturerDescriptor
[] = {
38 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
39 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
41 return stringImanufacturerDescriptor
;
44 uint8_t * HIDKeyboard::stringIproductDesc() {
45 static uint8_t stringIproductDescriptor
[] = {
47 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
48 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
50 return stringIproductDescriptor
;
53 uint8_t * HIDKeyboard::stringIserialDesc() {
54 static uint8_t stringIserialDescriptor
[] = {
56 STRING_DESCRIPTOR
, /*bDescriptorType 0x03*/
57 '0',0 /*bString iSerial*/
59 return stringIserialDescriptor
;
62 uint8_t * HIDKeyboard::reportDesc() {
63 static uint8_t reportDescriptor
[] = {
64 USAGE_PAGE(1), 0x01, // Generic Desktop
65 USAGE(1), 0x06, // Keyboard
66 COLLECTION(1), 0x01, // Application
68 USAGE_PAGE(1), 0x07, // Key Codes
69 USAGE_MINIMUM(1), 0xE0,
70 USAGE_MAXIMUM(1), 0xE7,
71 LOGICAL_MINIMUM(1), 0x00,
72 LOGICAL_MAXIMUM(1), 0x01,
74 REPORT_COUNT(1), 0x08,
75 INPUT(1), 0x02, // Data, Variable, Absolute
77 REPORT_COUNT(1), 0x01,
79 INPUT(1), 0x01, // Constant
81 REPORT_COUNT(1), 0x05,
83 USAGE_PAGE(1), 0x08, // LEDs
84 USAGE_MINIMUM(1), 0x01,
85 USAGE_MAXIMUM(1), 0x05,
86 OUTPUT(1), 0x02, // Data, Variable, Absolute
88 REPORT_COUNT(1), 0x01,
90 OUTPUT(1), 0x01, // Constant
93 REPORT_COUNT(1), 0x06,
95 LOGICAL_MINIMUM(1), 0x00,
96 LOGICAL_MAXIMUM(1), 0xFF,
97 USAGE_PAGE(1), 0x07, // Key Codes
98 USAGE_MINIMUM(1), 0x00,
99 USAGE_MAXIMUM(1), 0xFF,
100 INPUT(1), 0x00, // Data, Array
103 reportLength
= sizeof(reportDescriptor
);
104 return reportDescriptor
;
107 uint16_t HIDKeyboard::reportDescLength() {
112 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
113 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
114 + (1 * HID_DESCRIPTOR_LENGTH) \
115 + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
116 uint8_t * HIDKeyboard::configurationDesc() {
117 static uint8_t configurationDescriptor
[] = {
118 CONFIGURATION_DESCRIPTOR_LENGTH
,// bLength
119 CONFIGURATION_DESCRIPTOR
, // bDescriptorType
120 LSB(TOTAL_DESCRIPTOR_LENGTH
), // wTotalLength (LSB)
121 MSB(TOTAL_DESCRIPTOR_LENGTH
), // wTotalLength (MSB)
122 0x01, // bNumInterfaces
123 DEFAULT_CONFIGURATION
, // bConfigurationValue
124 0x00, // iConfiguration
125 C_RESERVED
| C_REMOTE_WAKEUP
, // bmAttributes
126 C_POWER(100), // bMaxPowerHello World from Mbed
128 INTERFACE_DESCRIPTOR_LENGTH
, // bLength
129 INTERFACE_DESCRIPTOR
, // bDescriptorType
130 0x00, // bInterfaceNumber
131 0x00, // bAlternateSetting
132 0x01, // bNumEndpoints
133 HID_CLASS
, // bInterfaceClass
134 1, // bInterfaceSubClass (boot)
135 1, // bInterfaceProtocol (keyboard)
138 HID_DESCRIPTOR_LENGTH
, // bLength
139 HID_DESCRIPTOR
, // bDescriptorType
140 LSB(HID_VERSION_1_11
), // bcdHID (LSB)
141 MSB(HID_VERSION_1_11
), // bcdHID (MSB)
142 0x00, // bCountryCode
143 0x01, // bNumDescriptors
144 REPORT_DESCRIPTOR
, // bDescriptorType
145 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
146 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
148 ENDPOINT_DESCRIPTOR_LENGTH
, // bLength
149 ENDPOINT_DESCRIPTOR
, // bDescriptorType
150 PHY_TO_DESC(EP1IN
), // bEndpointAddress
151 E_INTERRUPT
, // bmAttributes
152 LSB(MAX_PACKET_SIZE_EPINT
), // wMaxPacketSize (LSB)
153 MSB(MAX_PACKET_SIZE_EPINT
), // wMaxPacketSize (MSB)
154 1, // bInterval (milliseconds)
156 return configurationDescriptor
;
160 uint8_t * HIDKeyboard::deviceDesc() {
161 static uint8_t deviceDescriptor
[] = {
162 DEVICE_DESCRIPTOR_LENGTH
, /* bLength */
163 DEVICE_DESCRIPTOR
, /* bDescriptorType */
164 LSB(USB_VERSION_2_0
), /* bcdUSB (LSB) */
165 MSB(USB_VERSION_2_0
), /* bcdUSB (MSB) */
166 0x00, /* bDeviceClass */
167 0x00, /* bDeviceSubClass */
168 0x00, /* bDeviceprotocol */
169 MAX_PACKET_SIZE_EP0
, /* bMaxPacketSize0 */
170 (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
171 (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
172 (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
173 (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
174 (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
175 (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
176 0, /* iManufacturer */
178 0, /* iSerialNumber */
179 0x01 /* bNumConfigurations */
181 return deviceDescriptor
;
185 bool HIDKeyboard::USBCallback_request() {
186 bool success
= false;
187 CONTROL_TRANSFER
* transfer
= getTransferPtr();
188 uint8_t *hidDescriptor
;
190 // Process additional standard requests
192 if ((transfer
->setup
.bmRequestType
.Type
== STANDARD_TYPE
))
194 switch (transfer
->setup
.bRequest
)
197 switch (DESCRIPTOR_TYPE(transfer
->setup
.wValue
))
199 case REPORT_DESCRIPTOR
:
200 if ((reportDesc() != NULL
) \
201 && (reportDescLength() != 0))
203 transfer
->remaining
= reportDescLength();
204 transfer
->ptr
= reportDesc();
205 transfer
->direction
= DEVICE_TO_HOST
;
210 // Find the HID descriptor, after the configuration descriptor
211 hidDescriptor
= findDescriptor(HID_DESCRIPTOR
);
212 if (hidDescriptor
!= NULL
)
214 transfer
->remaining
= HID_DESCRIPTOR_LENGTH
;
215 transfer
->ptr
= hidDescriptor
;
216 transfer
->direction
= DEVICE_TO_HOST
;
230 // Process class-specific requests
232 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
234 switch (transfer->setup.bRequest)
237 // First byte will be used for report ID
238 //outputReport.data[0] = transfer->setup.wValue & 0xff;
239 //outputReport.length = transfer->setup.wLength + 1;
240 outputReport.length = transfer->setup.wLength;
242 //transfer->remaining = sizeof(outputReport.data) - 1;
243 //transfer->ptr = &outputReport.data[1];
244 transfer->remaining = sizeof(outputReport.data);
245 transfer->ptr = &outputReport.data[0];
246 transfer->direction = HOST_TO_DEVICE;
247 transfer->notify = true;