Keyboard firmwares for Atmel AVR and Cortex-M
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* Copyright (c) 2010-2011 mbed.org, MIT License
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  4. * and associated documentation files (the "Software"), to deal in the Software without
  5. * restriction, including without limitation the rights to use, copy, modify, merge, publish,
  6. * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
  7. * Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or
  10. * substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  13. * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  14. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  15. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. */
  18. #include "stdint.h"
  19. #include "USBCDC.h"
  20. static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
  21. #define DEFAULT_CONFIGURATION (1)
  22. #define CDC_SET_LINE_CODING 0x20
  23. #define CDC_GET_LINE_CODING 0x21
  24. #define CDC_SET_CONTROL_LINE_STATE 0x22
  25. // Control Line State bits
  26. #define CLS_DTR (1 << 0)
  27. #define CLS_RTS (1 << 1)
  28. #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
  29. USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
  30. terminal_connected = false;
  31. USBDevice::connect(connect_blocking);
  32. }
  33. bool USBCDC::USBCallback_request(void) {
  34. /* Called in ISR context */
  35. bool success = false;
  36. CONTROL_TRANSFER * transfer = getTransferPtr();
  37. /* Process class-specific requests */
  38. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  39. switch (transfer->setup.bRequest) {
  40. case CDC_GET_LINE_CODING:
  41. transfer->remaining = 7;
  42. transfer->ptr = cdc_line_coding;
  43. transfer->direction = DEVICE_TO_HOST;
  44. success = true;
  45. break;
  46. case CDC_SET_LINE_CODING:
  47. transfer->remaining = 7;
  48. transfer->notify = true;
  49. success = true;
  50. break;
  51. case CDC_SET_CONTROL_LINE_STATE:
  52. if (transfer->setup.wValue & CLS_DTR) {
  53. terminal_connected = true;
  54. } else {
  55. terminal_connected = false;
  56. }
  57. success = true;
  58. break;
  59. default:
  60. break;
  61. }
  62. }
  63. return success;
  64. }
  65. void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
  66. // Request of setting line coding has 7 bytes
  67. if (length != 7) {
  68. return;
  69. }
  70. CONTROL_TRANSFER * transfer = getTransferPtr();
  71. /* Process class-specific requests */
  72. if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
  73. if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
  74. if (memcmp(cdc_line_coding, buf, 7)) {
  75. memcpy(cdc_line_coding, buf, 7);
  76. int baud = buf[0] + (buf[1] << 8)
  77. + (buf[2] << 16) + (buf[3] << 24);
  78. int stop = buf[4];
  79. int bits = buf[6];
  80. int parity = buf[5];
  81. lineCodingChanged(baud, bits, parity, stop);
  82. }
  83. }
  84. }
  85. }
  86. // Called in ISR context
  87. // Set configuration. Return false if the
  88. // configuration is not supported.
  89. bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
  90. if (configuration != DEFAULT_CONFIGURATION) {
  91. return false;
  92. }
  93. // Configure endpoints > 0
  94. addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
  95. addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
  96. addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
  97. // We activate the endpoint to be able to recceive data
  98. readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
  99. return true;
  100. }
  101. bool USBCDC::send(uint8_t * buffer, uint32_t size) {
  102. return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
  103. }
  104. bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
  105. if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
  106. return false;
  107. if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
  108. return false;
  109. return true;
  110. }
  111. bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
  112. if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
  113. return false;
  114. if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
  115. return false;
  116. return true;
  117. }
  118. uint8_t * USBCDC::deviceDesc() {
  119. static uint8_t deviceDescriptor[] = {
  120. 18, // bLength
  121. 1, // bDescriptorType
  122. 0x10, 0x01, // bcdUSB
  123. 2, // bDeviceClass
  124. 0, // bDeviceSubClass
  125. 0, // bDeviceProtocol
  126. MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
  127. (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor
  128. (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
  129. 0x00, 0x01, // bcdDevice
  130. 1, // iManufacturer
  131. 2, // iProduct
  132. 3, // iSerialNumber
  133. 1 // bNumConfigurations
  134. };
  135. return deviceDescriptor;
  136. }
  137. uint8_t * USBCDC::stringIinterfaceDesc() {
  138. static uint8_t stringIinterfaceDescriptor[] = {
  139. 0x08,
  140. STRING_DESCRIPTOR,
  141. 'C',0,'D',0,'C',0,
  142. };
  143. return stringIinterfaceDescriptor;
  144. }
  145. uint8_t * USBCDC::stringIproductDesc() {
  146. static uint8_t stringIproductDescriptor[] = {
  147. 0x16,
  148. STRING_DESCRIPTOR,
  149. 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
  150. };
  151. return stringIproductDescriptor;
  152. }
  153. #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
  154. uint8_t * USBCDC::configurationDesc() {
  155. static uint8_t configDescriptor[] = {
  156. // configuration descriptor
  157. 9, // bLength
  158. 2, // bDescriptorType
  159. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  160. MSB(CONFIG1_DESC_SIZE),
  161. 2, // bNumInterfaces
  162. 1, // bConfigurationValue
  163. 0, // iConfiguration
  164. 0x80, // bmAttributes
  165. 50, // bMaxPower
  166. // IAD to associate the two CDC interfaces
  167. 0x08, // bLength
  168. 0x0b, // bDescriptorType
  169. 0x00, // bFirstInterface
  170. 0x02, // bInterfaceCount
  171. 0x02, // bFunctionClass
  172. 0x02, // bFunctionSubClass
  173. 0, // bFunctionProtocol
  174. 0, // iFunction
  175. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  176. 9, // bLength
  177. 4, // bDescriptorType
  178. 0, // bInterfaceNumber
  179. 0, // bAlternateSetting
  180. 1, // bNumEndpoints
  181. 0x02, // bInterfaceClass
  182. 0x02, // bInterfaceSubClass
  183. 0x01, // bInterfaceProtocol
  184. 0, // iInterface
  185. // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
  186. 5, // bFunctionLength
  187. 0x24, // bDescriptorType
  188. 0x00, // bDescriptorSubtype
  189. 0x10, 0x01, // bcdCDC
  190. // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
  191. 5, // bFunctionLength
  192. 0x24, // bDescriptorType
  193. 0x01, // bDescriptorSubtype
  194. 0x03, // bmCapabilities
  195. 1, // bDataInterface
  196. // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
  197. 4, // bFunctionLength
  198. 0x24, // bDescriptorType
  199. 0x02, // bDescriptorSubtype
  200. 0x06, // bmCapabilities
  201. // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
  202. 5, // bFunctionLength
  203. 0x24, // bDescriptorType
  204. 0x06, // bDescriptorSubtype
  205. 0, // bMasterInterface
  206. 1, // bSlaveInterface0
  207. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  208. ENDPOINT_DESCRIPTOR_LENGTH, // bLength
  209. ENDPOINT_DESCRIPTOR, // bDescriptorType
  210. PHY_TO_DESC(EPINT_IN), // bEndpointAddress
  211. E_INTERRUPT, // bmAttributes (0x03=intr)
  212. LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
  213. MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
  214. 16, // bInterval
  215. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  216. 9, // bLength
  217. 4, // bDescriptorType
  218. 1, // bInterfaceNumber
  219. 0, // bAlternateSetting
  220. 2, // bNumEndpoints
  221. 0x0A, // bInterfaceClass
  222. 0x00, // bInterfaceSubClass
  223. 0x00, // bInterfaceProtocol
  224. 0, // iInterface
  225. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  226. ENDPOINT_DESCRIPTOR_LENGTH, // bLength
  227. ENDPOINT_DESCRIPTOR, // bDescriptorType
  228. PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
  229. E_BULK, // bmAttributes (0x02=bulk)
  230. LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
  231. MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
  232. 0, // bInterval
  233. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  234. ENDPOINT_DESCRIPTOR_LENGTH, // bLength
  235. ENDPOINT_DESCRIPTOR, // bDescriptorType
  236. PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
  237. E_BULK, // bmAttributes (0x02=bulk)
  238. LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
  239. MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
  240. 0 // bInterval
  241. };
  242. return configDescriptor;
  243. }