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.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. uint8_t HIDKeyboard::leds() {
  16. return led_state;
  17. }
  18. bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
  19. if (configuration != DEFAULT_CONFIGURATION) {
  20. return false;
  21. }
  22. // Configure endpoints > 0
  23. addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
  24. //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
  25. // We activate the endpoint to be able to recceive data
  26. //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
  27. return true;
  28. }
  29. uint8_t * HIDKeyboard::stringImanufacturerDesc() {
  30. static uint8_t stringImanufacturerDescriptor[] = {
  31. 0x18, /*bLength*/
  32. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  33. 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
  34. };
  35. return stringImanufacturerDescriptor;
  36. }
  37. uint8_t * HIDKeyboard::stringIproductDesc() {
  38. static uint8_t stringIproductDescriptor[] = {
  39. 0x0a, /*bLength*/
  40. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  41. 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
  42. };
  43. return stringIproductDescriptor;
  44. }
  45. uint8_t * HIDKeyboard::stringIserialDesc() {
  46. static uint8_t stringIserialDescriptor[] = {
  47. 0x04, /*bLength*/
  48. STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
  49. '0',0 /*bString iSerial*/
  50. };
  51. return stringIserialDescriptor;
  52. }
  53. uint8_t * HIDKeyboard::reportDesc() {
  54. static uint8_t reportDescriptor[] = {
  55. USAGE_PAGE(1), 0x01, // Generic Desktop
  56. USAGE(1), 0x06, // Keyboard
  57. COLLECTION(1), 0x01, // Application
  58. USAGE_PAGE(1), 0x07, // Key Codes
  59. USAGE_MINIMUM(1), 0xE0,
  60. USAGE_MAXIMUM(1), 0xE7,
  61. LOGICAL_MINIMUM(1), 0x00,
  62. LOGICAL_MAXIMUM(1), 0x01,
  63. REPORT_SIZE(1), 0x01,
  64. REPORT_COUNT(1), 0x08,
  65. INPUT(1), 0x02, // Data, Variable, Absolute
  66. REPORT_COUNT(1), 0x01,
  67. REPORT_SIZE(1), 0x08,
  68. INPUT(1), 0x01, // Constant
  69. REPORT_COUNT(1), 0x05,
  70. REPORT_SIZE(1), 0x01,
  71. USAGE_PAGE(1), 0x08, // LEDs
  72. USAGE_MINIMUM(1), 0x01,
  73. USAGE_MAXIMUM(1), 0x05,
  74. OUTPUT(1), 0x02, // Data, Variable, Absolute
  75. REPORT_COUNT(1), 0x01,
  76. REPORT_SIZE(1), 0x03,
  77. OUTPUT(1), 0x01, // Constant
  78. REPORT_COUNT(1), 0x06,
  79. REPORT_SIZE(1), 0x08,
  80. LOGICAL_MINIMUM(1), 0x00,
  81. LOGICAL_MAXIMUM(1), 0xFF,
  82. USAGE_PAGE(1), 0x07, // Key Codes
  83. USAGE_MINIMUM(1), 0x00,
  84. USAGE_MAXIMUM(1), 0xFF,
  85. INPUT(1), 0x00, // Data, Array
  86. END_COLLECTION(0),
  87. };
  88. reportLength = sizeof(reportDescriptor);
  89. return reportDescriptor;
  90. }
  91. uint16_t HIDKeyboard::reportDescLength() {
  92. reportDesc();
  93. return reportLength;
  94. }
  95. #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
  96. + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
  97. + (1 * HID_DESCRIPTOR_LENGTH) \
  98. + (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. {
  170. switch (transfer->setup.bRequest)
  171. {
  172. case GET_DESCRIPTOR:
  173. switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
  174. {
  175. case REPORT_DESCRIPTOR:
  176. if ((reportDesc() != NULL) \
  177. && (reportDescLength() != 0))
  178. {
  179. transfer->remaining = reportDescLength();
  180. transfer->ptr = reportDesc();
  181. transfer->direction = DEVICE_TO_HOST;
  182. success = true;
  183. }
  184. break;
  185. case HID_DESCRIPTOR:
  186. // Find the HID descriptor, after the configuration descriptor
  187. hidDescriptor = findDescriptor(HID_DESCRIPTOR);
  188. if (hidDescriptor != NULL)
  189. {
  190. transfer->remaining = HID_DESCRIPTOR_LENGTH;
  191. transfer->ptr = hidDescriptor;
  192. transfer->direction = DEVICE_TO_HOST;
  193. success = true;
  194. }
  195. break;
  196. default:
  197. break;
  198. }
  199. break;
  200. default:
  201. break;
  202. }
  203. }
  204. // Process class-specific requests
  205. if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
  206. {
  207. switch (transfer->setup.bRequest) {
  208. case SET_REPORT:
  209. // LED indicator
  210. // TODO: check Interface and Report length?
  211. // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
  212. // if (transfer->setup.wLength == 1)
  213. transfer->remaining = 1;
  214. //transfer->ptr = ?? what ptr should be set when OUT(not used?)
  215. transfer->direction = HOST_TO_DEVICE;
  216. transfer->notify = true; /* notify with USBCallback_requestCompleted */
  217. success = true;
  218. default:
  219. break;
  220. }
  221. }
  222. return success;
  223. }
  224. void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
  225. {
  226. if (length > 0) {
  227. CONTROL_TRANSFER *transfer = getTransferPtr();
  228. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  229. switch (transfer->setup.bRequest) {
  230. case SET_REPORT:
  231. led_state = buf[0];
  232. break;
  233. default:
  234. break;
  235. }
  236. }
  237. }
  238. }