HIDKeyboard.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <stdint.h>
  2. #include "USBHID.h"
  3. #include "USBHID_Types.h"
  4. #include "USBDescriptor.h"
  5. #include "HIDKeyboard.h"
  6. #define DEFAULT_CONFIGURATION (1)
  7. HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) : USBDevice(vendor_id, product_id, product_release) { USBDevice::connect(); }
  8. bool HIDKeyboard::sendReport(report_keyboard_t report) {
  9. USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
  10. return true;
  11. }
  12. uint8_t HIDKeyboard::leds() { return led_state; }
  13. bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
  14. if (configuration != DEFAULT_CONFIGURATION) {
  15. return false;
  16. }
  17. // Configure endpoints > 0
  18. addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
  19. // addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
  20. // We activate the endpoint to be able to recceive data
  21. // readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
  22. return true;
  23. }
  24. uint8_t *HIDKeyboard::stringImanufacturerDesc() {
  25. static uint8_t stringImanufacturerDescriptor[] = {
  26. 0x18, /*bLength*/
  27. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  28. 't',
  29. 0,
  30. 'm',
  31. 0,
  32. 'k',
  33. 0,
  34. '-',
  35. 0,
  36. 'k',
  37. 0,
  38. 'b',
  39. 0,
  40. 'd',
  41. 0,
  42. '.',
  43. 0,
  44. 'c',
  45. 0,
  46. 'o',
  47. 0,
  48. 'm',
  49. 0 /*bString iManufacturer*/
  50. };
  51. return stringImanufacturerDescriptor;
  52. }
  53. uint8_t *HIDKeyboard::stringIproductDesc() {
  54. static uint8_t stringIproductDescriptor[] = {
  55. 0x0a, /*bLength*/
  56. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  57. 'm',
  58. 0,
  59. 'b',
  60. 0,
  61. 'e',
  62. 0,
  63. 'd',
  64. 0 /*bString iProduct*/
  65. };
  66. return stringIproductDescriptor;
  67. }
  68. uint8_t *HIDKeyboard::stringIserialDesc() {
  69. static uint8_t stringIserialDescriptor[] = {
  70. 0x04, /*bLength*/
  71. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  72. '0', 0 /*bString iSerial*/
  73. };
  74. return stringIserialDescriptor;
  75. }
  76. uint8_t *HIDKeyboard::reportDesc() {
  77. static uint8_t reportDescriptor[] = {
  78. USAGE_PAGE(1), 0x01, // Generic Desktop
  79. USAGE(1), 0x06, // Keyboard
  80. COLLECTION(1), 0x01, // Application
  81. USAGE_PAGE(1), 0x07, // Key Codes
  82. 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
  83. REPORT_COUNT(1), 0x01, REPORT_SIZE(1), 0x08, INPUT(1), 0x01, // Constant
  84. REPORT_COUNT(1), 0x05, REPORT_SIZE(1), 0x01, USAGE_PAGE(1), 0x08, // LEDs
  85. USAGE_MINIMUM(1), 0x01, USAGE_MAXIMUM(1), 0x05, OUTPUT(1), 0x02, // Data, Variable, Absolute
  86. REPORT_COUNT(1), 0x01, REPORT_SIZE(1), 0x03, OUTPUT(1), 0x01, // Constant
  87. REPORT_COUNT(1), 0x06, REPORT_SIZE(1), 0x08, LOGICAL_MINIMUM(1), 0x00, LOGICAL_MAXIMUM(1), 0xFF, USAGE_PAGE(1), 0x07, // Key Codes
  88. USAGE_MINIMUM(1), 0x00, USAGE_MAXIMUM(1), 0xFF, INPUT(1), 0x00, // Data, Array
  89. END_COLLECTION(0),
  90. };
  91. reportLength = sizeof(reportDescriptor);
  92. return reportDescriptor;
  93. }
  94. uint16_t HIDKeyboard::reportDescLength() {
  95. reportDesc();
  96. return reportLength;
  97. }
  98. #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) + (1 * INTERFACE_DESCRIPTOR_LENGTH) + (1 * HID_DESCRIPTOR_LENGTH) + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
  99. uint8_t *HIDKeyboard::configurationDesc() {
  100. static uint8_t configurationDescriptor[] = {
  101. CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
  102. CONFIGURATION_DESCRIPTOR, // bDescriptorType
  103. LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
  104. MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
  105. 0x01, // bNumInterfaces
  106. DEFAULT_CONFIGURATION, // bConfigurationValue
  107. 0x00, // iConfiguration
  108. C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
  109. C_POWER(100), // bMaxPowerHello World from Mbed
  110. INTERFACE_DESCRIPTOR_LENGTH, // bLength
  111. INTERFACE_DESCRIPTOR, // bDescriptorType
  112. 0x00, // bInterfaceNumber
  113. 0x00, // bAlternateSetting
  114. 0x01, // bNumEndpoints
  115. HID_CLASS, // bInterfaceClass
  116. 1, // bInterfaceSubClass (boot)
  117. 1, // bInterfaceProtocol (keyboard)
  118. 0x00, // iInterface
  119. HID_DESCRIPTOR_LENGTH, // bLength
  120. HID_DESCRIPTOR, // bDescriptorType
  121. LSB(HID_VERSION_1_11), // bcdHID (LSB)
  122. MSB(HID_VERSION_1_11), // bcdHID (MSB)
  123. 0x00, // bCountryCode
  124. 0x01, // bNumDescriptors
  125. REPORT_DESCRIPTOR, // bDescriptorType
  126. (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
  127. (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
  128. ENDPOINT_DESCRIPTOR_LENGTH, // bLength
  129. ENDPOINT_DESCRIPTOR, // bDescriptorType
  130. PHY_TO_DESC(EP1IN), // bEndpointAddress
  131. E_INTERRUPT, // bmAttributes
  132. LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
  133. MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
  134. 1, // bInterval (milliseconds)
  135. };
  136. return configurationDescriptor;
  137. }
  138. #if 0
  139. uint8_t * HIDKeyboard::deviceDesc() {
  140. static uint8_t deviceDescriptor[] = {
  141. DEVICE_DESCRIPTOR_LENGTH, /* bLength */
  142. DEVICE_DESCRIPTOR, /* bDescriptorType */
  143. LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
  144. MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
  145. 0x00, /* bDeviceClass */
  146. 0x00, /* bDeviceSubClass */
  147. 0x00, /* bDeviceprotocol */
  148. MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
  149. (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
  150. (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
  151. (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
  152. (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
  153. (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
  154. (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
  155. 0, /* iManufacturer */
  156. 0, /* iProduct */
  157. 0, /* iSerialNumber */
  158. 0x01 /* bNumConfigurations */
  159. };
  160. return deviceDescriptor;
  161. }
  162. #endif
  163. bool HIDKeyboard::USBCallback_request() {
  164. bool success = false;
  165. CONTROL_TRANSFER *transfer = getTransferPtr();
  166. uint8_t * hidDescriptor;
  167. // Process additional standard requests
  168. if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) {
  169. switch (transfer->setup.bRequest) {
  170. case GET_DESCRIPTOR:
  171. switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) {
  172. case REPORT_DESCRIPTOR:
  173. if ((reportDesc() != NULL) && (reportDescLength() != 0)) {
  174. transfer->remaining = reportDescLength();
  175. transfer->ptr = reportDesc();
  176. transfer->direction = DEVICE_TO_HOST;
  177. success = true;
  178. }
  179. break;
  180. case HID_DESCRIPTOR:
  181. // Find the HID descriptor, after the configuration descriptor
  182. hidDescriptor = findDescriptor(HID_DESCRIPTOR);
  183. if (hidDescriptor != NULL) {
  184. transfer->remaining = HID_DESCRIPTOR_LENGTH;
  185. transfer->ptr = hidDescriptor;
  186. transfer->direction = DEVICE_TO_HOST;
  187. success = true;
  188. }
  189. break;
  190. default:
  191. break;
  192. }
  193. break;
  194. default:
  195. break;
  196. }
  197. }
  198. // Process class-specific requests
  199. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  200. switch (transfer->setup.bRequest) {
  201. case SET_REPORT:
  202. // LED indicator
  203. // TODO: check Interface and Report length?
  204. // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
  205. // if (transfer->setup.wLength == 1)
  206. transfer->remaining = 1;
  207. // transfer->ptr = ?? what ptr should be set when OUT(not used?)
  208. transfer->direction = HOST_TO_DEVICE;
  209. transfer->notify = true; /* notify with USBCallback_requestCompleted */
  210. success = true;
  211. default:
  212. break;
  213. }
  214. }
  215. return success;
  216. }
  217. void HIDKeyboard::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
  218. if (length > 0) {
  219. CONTROL_TRANSFER *transfer = getTransferPtr();
  220. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  221. switch (transfer->setup.bRequest) {
  222. case SET_REPORT:
  223. led_state = buf[0];
  224. break;
  225. default:
  226. break;
  227. }
  228. }
  229. }
  230. }