3 #include "USBHID_Types.h"
4 #include "USBDescriptor.h"
5 #include "HIDKeyboard.h"
7 #define DEFAULT_CONFIGURATION (1)
9 HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) : USBDevice(vendor_id, product_id, product_release) { USBDevice::connect(); }
11 bool HIDKeyboard::sendReport(report_keyboard_t report) {
12 USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
16 uint8_t HIDKeyboard::leds() { return led_state; }
18 bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
19 if (configuration != DEFAULT_CONFIGURATION) {
23 // Configure endpoints > 0
24 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
25 // addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
27 // We activate the endpoint to be able to recceive data
28 // readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
32 uint8_t *HIDKeyboard::stringImanufacturerDesc() {
33 static uint8_t stringImanufacturerDescriptor[] = {
35 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
57 0 /*bString iManufacturer*/
59 return stringImanufacturerDescriptor;
62 uint8_t *HIDKeyboard::stringIproductDesc() {
63 static uint8_t stringIproductDescriptor[] = {
65 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
73 0 /*bString iProduct*/
75 return stringIproductDescriptor;
78 uint8_t *HIDKeyboard::stringIserialDesc() {
79 static uint8_t stringIserialDescriptor[] = {
81 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
82 '0', 0 /*bString iSerial*/
84 return stringIserialDescriptor;
87 uint8_t *HIDKeyboard::reportDesc() {
88 static uint8_t reportDescriptor[] = {
89 USAGE_PAGE(1), 0x01, // Generic Desktop
90 USAGE(1), 0x06, // Keyboard
91 COLLECTION(1), 0x01, // Application
93 USAGE_PAGE(1), 0x07, // Key Codes
94 USAGE_MINIMUM(1), 0xE0, USAGE_MAXIMUM(1), 0xE7, LOGICAL_MINIMUM(1), 0x00, LOGICAL_MAXIMUM(1), 0x01, REPORT_SIZE(1), 0x01, REPORT_COUNT(1), 0x08, INPUT(1), 0x02, // Data, Variable, Absolute
96 REPORT_COUNT(1), 0x01, REPORT_SIZE(1), 0x08, INPUT(1), 0x01, // Constant
98 REPORT_COUNT(1), 0x05, REPORT_SIZE(1), 0x01, USAGE_PAGE(1), 0x08, // LEDs
99 USAGE_MINIMUM(1), 0x01, USAGE_MAXIMUM(1), 0x05, OUTPUT(1), 0x02, // Data, Variable, Absolute
101 REPORT_COUNT(1), 0x01, REPORT_SIZE(1), 0x03, OUTPUT(1), 0x01, // Constant
103 REPORT_COUNT(1), 0x06, REPORT_SIZE(1), 0x08, LOGICAL_MINIMUM(1), 0x00, LOGICAL_MAXIMUM(1), 0xFF, USAGE_PAGE(1), 0x07, // Key Codes
104 USAGE_MINIMUM(1), 0x00, USAGE_MAXIMUM(1), 0xFF, 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) + (1 * INTERFACE_DESCRIPTOR_LENGTH) + (1 * HID_DESCRIPTOR_LENGTH) + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
117 uint8_t *HIDKeyboard::configurationDesc() {
118 static uint8_t configurationDescriptor[] = {
119 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
120 CONFIGURATION_DESCRIPTOR, // bDescriptorType
121 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
122 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
123 0x01, // bNumInterfaces
124 DEFAULT_CONFIGURATION, // bConfigurationValue
125 0x00, // iConfiguration
126 C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
127 C_POWER(100), // bMaxPowerHello World from Mbed
129 INTERFACE_DESCRIPTOR_LENGTH, // bLength
130 INTERFACE_DESCRIPTOR, // bDescriptorType
131 0x00, // bInterfaceNumber
132 0x00, // bAlternateSetting
133 0x01, // bNumEndpoints
134 HID_CLASS, // bInterfaceClass
135 1, // bInterfaceSubClass (boot)
136 1, // bInterfaceProtocol (keyboard)
139 HID_DESCRIPTOR_LENGTH, // bLength
140 HID_DESCRIPTOR, // bDescriptorType
141 LSB(HID_VERSION_1_11), // bcdHID (LSB)
142 MSB(HID_VERSION_1_11), // bcdHID (MSB)
143 0x00, // bCountryCode
144 0x01, // bNumDescriptors
145 REPORT_DESCRIPTOR, // bDescriptorType
146 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
147 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
149 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
150 ENDPOINT_DESCRIPTOR, // bDescriptorType
151 PHY_TO_DESC(EP1IN), // bEndpointAddress
152 E_INTERRUPT, // bmAttributes
153 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
154 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
155 1, // bInterval (milliseconds)
157 return configurationDescriptor;
161 uint8_t * HIDKeyboard::deviceDesc() {
162 static uint8_t deviceDescriptor[] = {
163 DEVICE_DESCRIPTOR_LENGTH, /* bLength */
164 DEVICE_DESCRIPTOR, /* bDescriptorType */
165 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
166 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
167 0x00, /* bDeviceClass */
168 0x00, /* bDeviceSubClass */
169 0x00, /* bDeviceprotocol */
170 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
171 (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
172 (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
173 (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
174 (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
175 (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
176 (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
177 0, /* iManufacturer */
179 0, /* iSerialNumber */
180 0x01 /* bNumConfigurations */
182 return deviceDescriptor;
186 bool HIDKeyboard::USBCallback_request() {
187 bool success = false;
188 CONTROL_TRANSFER *transfer = getTransferPtr();
189 uint8_t * hidDescriptor;
191 // Process additional standard requests
193 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) {
194 switch (transfer->setup.bRequest) {
196 switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) {
197 case REPORT_DESCRIPTOR:
198 if ((reportDesc() != NULL) && (reportDescLength() != 0)) {
199 transfer->remaining = reportDescLength();
200 transfer->ptr = reportDesc();
201 transfer->direction = DEVICE_TO_HOST;
206 // Find the HID descriptor, after the configuration descriptor
207 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
208 if (hidDescriptor != NULL) {
209 transfer->remaining = HID_DESCRIPTOR_LENGTH;
210 transfer->ptr = hidDescriptor;
211 transfer->direction = DEVICE_TO_HOST;
225 // Process class-specific requests
226 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
227 switch (transfer->setup.bRequest) {
230 // TODO: check Interface and Report length?
231 // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
232 // if (transfer->setup.wLength == 1)
234 transfer->remaining = 1;
235 // transfer->ptr = ?? what ptr should be set when OUT(not used?)
236 transfer->direction = HOST_TO_DEVICE;
237 transfer->notify = true; /* notify with USBCallback_requestCompleted */
247 void HIDKeyboard::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
249 CONTROL_TRANSFER *transfer = getTransferPtr();
250 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
251 switch (transfer->setup.bRequest) {