Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HIDKeyboard.cpp 9.8KB

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