HID.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /* Copyright (c) 2011, Peter Barrett
  2. **
  3. ** Permission to use, copy, modify, and/or distribute this software for
  4. ** any purpose with or without fee is hereby granted, provided that the
  5. ** above copyright notice and this permission notice appear in all copies.
  6. **
  7. ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  8. ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  9. ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
  10. ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
  11. ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  12. ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  13. ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  14. ** SOFTWARE.
  15. */
  16. #include "Platform.h"
  17. #include "USBAPI.h"
  18. #include "USBDesc.h"
  19. #if defined(USBCON)
  20. #ifdef HID_ENABLED
  21. //#define RAWHID_ENABLED
  22. // Singletons for mouse and keyboard
  23. Mouse_ Mouse;
  24. Keyboard_ Keyboard;
  25. //================================================================================
  26. //================================================================================
  27. // HID report descriptor
  28. #define LSB(_x) ((_x) & 0xFF)
  29. #define MSB(_x) ((_x) >> 8)
  30. #define RAWHID_USAGE_PAGE 0xFFC0
  31. #define RAWHID_USAGE 0x0C00
  32. #define RAWHID_TX_SIZE 64
  33. #define RAWHID_RX_SIZE 64
  34. extern const u8 _hidReportDescriptor[] PROGMEM;
  35. const u8 _hidReportDescriptor[] = {
  36. // Mouse
  37. 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
  38. 0x09, 0x02, // USAGE (Mouse)
  39. 0xa1, 0x01, // COLLECTION (Application)
  40. 0x09, 0x01, // USAGE (Pointer)
  41. 0xa1, 0x00, // COLLECTION (Physical)
  42. 0x85, 0x01, // REPORT_ID (1)
  43. 0x05, 0x09, // USAGE_PAGE (Button)
  44. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  45. 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
  46. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  47. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  48. 0x95, 0x03, // REPORT_COUNT (3)
  49. 0x75, 0x01, // REPORT_SIZE (1)
  50. 0x81, 0x02, // INPUT (Data,Var,Abs)
  51. 0x95, 0x01, // REPORT_COUNT (1)
  52. 0x75, 0x05, // REPORT_SIZE (5)
  53. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  54. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  55. 0x09, 0x30, // USAGE (X)
  56. 0x09, 0x31, // USAGE (Y)
  57. 0x09, 0x38, // USAGE (Wheel)
  58. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  59. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  60. 0x75, 0x08, // REPORT_SIZE (8)
  61. 0x95, 0x03, // REPORT_COUNT (3)
  62. 0x81, 0x06, // INPUT (Data,Var,Rel)
  63. 0xc0, // END_COLLECTION
  64. 0xc0, // END_COLLECTION
  65. // Keyboard
  66. 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
  67. 0x09, 0x06, // USAGE (Keyboard)
  68. 0xa1, 0x01, // COLLECTION (Application)
  69. 0x85, 0x02, // REPORT_ID (2)
  70. 0x05, 0x07, // USAGE_PAGE (Keyboard)
  71. 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
  72. 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
  73. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  74. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  75. 0x75, 0x01, // REPORT_SIZE (1)
  76. 0x95, 0x08, // REPORT_COUNT (8)
  77. 0x81, 0x02, // INPUT (Data,Var,Abs)
  78. 0x95, 0x01, // REPORT_COUNT (1)
  79. 0x75, 0x08, // REPORT_SIZE (8)
  80. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  81. 0x95, 0x06, // REPORT_COUNT (6)
  82. 0x75, 0x08, // REPORT_SIZE (8)
  83. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  84. 0x25, 0x65, // LOGICAL_MAXIMUM (101)
  85. 0x05, 0x07, // USAGE_PAGE (Keyboard)
  86. 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
  87. 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
  88. 0x81, 0x00, // INPUT (Data,Ary,Abs)
  89. 0xc0, // END_COLLECTION
  90. #if RAWHID_ENABLED
  91. // RAW HID
  92. 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
  93. 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
  94. 0xA1, 0x01, // Collection 0x01
  95. 0x85, 0x03, // REPORT_ID (3)
  96. 0x75, 0x08, // report size = 8 bits
  97. 0x15, 0x00, // logical minimum = 0
  98. 0x26, 0xFF, 0x00, // logical maximum = 255
  99. 0x95, 64, // report count TX
  100. 0x09, 0x01, // usage
  101. 0x81, 0x02, // Input (array)
  102. 0x95, 64, // report count RX
  103. 0x09, 0x02, // usage
  104. 0x91, 0x02, // Output (array)
  105. 0xC0 // end collection
  106. #endif
  107. };
  108. extern const HIDDescriptor _hidInterface PROGMEM;
  109. const HIDDescriptor _hidInterface =
  110. {
  111. D_INTERFACE(HID_INTERFACE,1,3,0,0),
  112. D_HIDREPORT(sizeof(_hidReportDescriptor)),
  113. D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
  114. };
  115. //================================================================================
  116. //================================================================================
  117. // Driver
  118. u8 _hid_protocol = 1;
  119. u8 _hid_idle = 1;
  120. #define WEAK __attribute__ ((weak))
  121. int WEAK HID_GetInterface(u8* interfaceNum)
  122. {
  123. interfaceNum[0] += 1; // uses 1
  124. return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
  125. }
  126. int WEAK HID_GetDescriptor(int i)
  127. {
  128. return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
  129. }
  130. void WEAK HID_SendReport(u8 id, const void* data, int len)
  131. {
  132. USB_Send(HID_TX, &id, 1);
  133. USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
  134. }
  135. bool WEAK HID_Setup(Setup& setup)
  136. {
  137. u8 r = setup.bRequest;
  138. u8 requestType = setup.bmRequestType;
  139. if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
  140. {
  141. if (HID_GET_REPORT == r)
  142. {
  143. //HID_GetReport();
  144. return true;
  145. }
  146. if (HID_GET_PROTOCOL == r)
  147. {
  148. //Send8(_hid_protocol); // TODO
  149. return true;
  150. }
  151. }
  152. if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
  153. {
  154. if (HID_SET_PROTOCOL == r)
  155. {
  156. _hid_protocol = setup.wValueL;
  157. return true;
  158. }
  159. if (HID_SET_IDLE == r)
  160. {
  161. _hid_idle = setup.wValueL;
  162. return true;
  163. }
  164. }
  165. return false;
  166. }
  167. //================================================================================
  168. //================================================================================
  169. // Mouse
  170. Mouse_::Mouse_(void) : _buttons(0)
  171. {
  172. }
  173. void Mouse_::begin(void)
  174. {
  175. }
  176. void Mouse_::end(void)
  177. {
  178. }
  179. void Mouse_::click(uint8_t b)
  180. {
  181. _buttons = b;
  182. move(0,0,0);
  183. _buttons = 0;
  184. move(0,0,0);
  185. }
  186. void Mouse_::move(signed char x, signed char y, signed char wheel)
  187. {
  188. u8 m[4];
  189. m[0] = _buttons;
  190. m[1] = x;
  191. m[2] = y;
  192. m[3] = wheel;
  193. HID_SendReport(1,m,4);
  194. }
  195. void Mouse_::buttons(uint8_t b)
  196. {
  197. if (b != _buttons)
  198. {
  199. _buttons = b;
  200. move(0,0,0);
  201. }
  202. }
  203. void Mouse_::press(uint8_t b)
  204. {
  205. buttons(_buttons | b);
  206. }
  207. void Mouse_::release(uint8_t b)
  208. {
  209. buttons(_buttons & ~b);
  210. }
  211. bool Mouse_::isPressed(uint8_t b)
  212. {
  213. if ((b & _buttons) > 0)
  214. return true;
  215. return false;
  216. }
  217. //================================================================================
  218. //================================================================================
  219. // Keyboard
  220. Keyboard_::Keyboard_(void)
  221. {
  222. }
  223. void Keyboard_::begin(void)
  224. {
  225. }
  226. void Keyboard_::end(void)
  227. {
  228. }
  229. void Keyboard_::sendReport(KeyReport* keys)
  230. {
  231. HID_SendReport(2,keys,sizeof(KeyReport));
  232. }
  233. extern
  234. const uint8_t _asciimap[128] PROGMEM;
  235. #define SHIFT 0x80
  236. const uint8_t _asciimap[128] =
  237. {
  238. 0x00, // NUL
  239. 0x00, // SOH
  240. 0x00, // STX
  241. 0x00, // ETX
  242. 0x00, // EOT
  243. 0x00, // ENQ
  244. 0x00, // ACK
  245. 0x00, // BEL
  246. 0x2a, // BS Backspace
  247. 0x2b, // TAB Tab
  248. 0x28, // LF Enter
  249. 0x00, // VT
  250. 0x00, // FF
  251. 0x00, // CR
  252. 0x00, // SO
  253. 0x00, // SI
  254. 0x00, // DEL
  255. 0x00, // DC1
  256. 0x00, // DC2
  257. 0x00, // DC3
  258. 0x00, // DC4
  259. 0x00, // NAK
  260. 0x00, // SYN
  261. 0x00, // ETB
  262. 0x00, // CAN
  263. 0x00, // EM
  264. 0x00, // SUB
  265. 0x00, // ESC
  266. 0x00, // FS
  267. 0x00, // GS
  268. 0x00, // RS
  269. 0x00, // US
  270. 0x2c, // ' '
  271. 0x1e|SHIFT, // !
  272. 0x34|SHIFT, // "
  273. 0x20|SHIFT, // #
  274. 0x21|SHIFT, // $
  275. 0x22|SHIFT, // %
  276. 0x24|SHIFT, // &
  277. 0x34, // '
  278. 0x26|SHIFT, // (
  279. 0x27|SHIFT, // )
  280. 0x25|SHIFT, // *
  281. 0x2e|SHIFT, // +
  282. 0x36, // ,
  283. 0x2d, // -
  284. 0x37, // .
  285. 0x38, // /
  286. 0x27, // 0
  287. 0x1e, // 1
  288. 0x1f, // 2
  289. 0x20, // 3
  290. 0x21, // 4
  291. 0x22, // 5
  292. 0x23, // 6
  293. 0x24, // 7
  294. 0x25, // 8
  295. 0x26, // 9
  296. 0x33|SHIFT, // :
  297. 0x33, // ;
  298. 0x36|SHIFT, // <
  299. 0x2e, // =
  300. 0x37|SHIFT, // >
  301. 0x38|SHIFT, // ?
  302. 0x1f|SHIFT, // @
  303. 0x04|SHIFT, // A
  304. 0x05|SHIFT, // B
  305. 0x06|SHIFT, // C
  306. 0x07|SHIFT, // D
  307. 0x08|SHIFT, // E
  308. 0x09|SHIFT, // F
  309. 0x0a|SHIFT, // G
  310. 0x0b|SHIFT, // H
  311. 0x0c|SHIFT, // I
  312. 0x0d|SHIFT, // J
  313. 0x0e|SHIFT, // K
  314. 0x0f|SHIFT, // L
  315. 0x10|SHIFT, // M
  316. 0x11|SHIFT, // N
  317. 0x12|SHIFT, // O
  318. 0x13|SHIFT, // P
  319. 0x14|SHIFT, // Q
  320. 0x15|SHIFT, // R
  321. 0x16|SHIFT, // S
  322. 0x17|SHIFT, // T
  323. 0x18|SHIFT, // U
  324. 0x19|SHIFT, // V
  325. 0x1a|SHIFT, // W
  326. 0x1b|SHIFT, // X
  327. 0x1c|SHIFT, // Y
  328. 0x1d|SHIFT, // Z
  329. 0x2f, // [
  330. 0x31, // bslash
  331. 0x30, // ]
  332. 0x23|SHIFT, // ^
  333. 0x2d|SHIFT, // _
  334. 0x35, // `
  335. 0x04, // a
  336. 0x05, // b
  337. 0x06, // c
  338. 0x07, // d
  339. 0x08, // e
  340. 0x09, // f
  341. 0x0a, // g
  342. 0x0b, // h
  343. 0x0c, // i
  344. 0x0d, // j
  345. 0x0e, // k
  346. 0x0f, // l
  347. 0x10, // m
  348. 0x11, // n
  349. 0x12, // o
  350. 0x13, // p
  351. 0x14, // q
  352. 0x15, // r
  353. 0x16, // s
  354. 0x17, // t
  355. 0x18, // u
  356. 0x19, // v
  357. 0x1a, // w
  358. 0x1b, // x
  359. 0x1c, // y
  360. 0x1d, // z
  361. 0x2f|SHIFT, //
  362. 0x31|SHIFT, // |
  363. 0x30|SHIFT, // }
  364. 0x35|SHIFT, // ~
  365. 0 // DEL
  366. };
  367. uint8_t USBPutChar(uint8_t c);
  368. // press() adds the specified key (printing, non-printing, or modifier)
  369. // to the persistent key report and sends the report. Because of the way
  370. // USB HID works, the host acts like the key remains pressed until we
  371. // call release(), releaseAll(), or otherwise clear the report and resend.
  372. size_t Keyboard_::press(uint8_t k)
  373. {
  374. uint8_t i;
  375. if (k >= 136) { // it's a non-printing key (not a modifier)
  376. k = k - 136;
  377. } else if (k >= 128) { // it's a modifier key
  378. _keyReport.modifiers |= (1<<(k-128));
  379. k = 0;
  380. } else { // it's a printing key
  381. k = pgm_read_byte(_asciimap + k);
  382. if (!k) {
  383. setWriteError();
  384. return 0;
  385. }
  386. if (k & 0x80) { // it's a capital letter or other character reached with shift
  387. _keyReport.modifiers |= 0x02; // the left shift modifier
  388. k &= 0x7F;
  389. }
  390. }
  391. // Add k to the key report only if it's not already present
  392. // and if there is an empty slot.
  393. if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
  394. _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
  395. _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
  396. for (i=0; i<6; i++) {
  397. if (_keyReport.keys[i] == 0x00) {
  398. _keyReport.keys[i] = k;
  399. break;
  400. }
  401. }
  402. if (i == 6) {
  403. setWriteError();
  404. return 0;
  405. }
  406. }
  407. sendReport(&_keyReport);
  408. return 1;
  409. }
  410. // release() takes the specified key out of the persistent key report and
  411. // sends the report. This tells the OS the key is no longer pressed and that
  412. // it shouldn't be repeated any more.
  413. size_t Keyboard_::release(uint8_t k)
  414. {
  415. uint8_t i;
  416. if (k >= 136) { // it's a non-printing key (not a modifier)
  417. k = k - 136;
  418. } else if (k >= 128) { // it's a modifier key
  419. _keyReport.modifiers &= ~(1<<(k-128));
  420. k = 0;
  421. } else { // it's a printing key
  422. k = pgm_read_byte(_asciimap + k);
  423. if (!k) {
  424. return 0;
  425. }
  426. if (k & 0x80) { // it's a capital letter or other character reached with shift
  427. _keyReport.modifiers &= ~(0x02); // the left shift modifier
  428. k &= 0x7F;
  429. }
  430. }
  431. // Test the key report to see if k is present. Clear it if it exists.
  432. // Check all positions in case the key is present more than once (which it shouldn't be)
  433. for (i=0; i<6; i++) {
  434. if (0 != k && _keyReport.keys[i] == k) {
  435. _keyReport.keys[i] = 0x00;
  436. }
  437. }
  438. sendReport(&_keyReport);
  439. return 1;
  440. }
  441. void Keyboard_::releaseAll(void)
  442. {
  443. _keyReport.keys[0] = 0;
  444. _keyReport.keys[1] = 0;
  445. _keyReport.keys[2] = 0;
  446. _keyReport.keys[3] = 0;
  447. _keyReport.keys[4] = 0;
  448. _keyReport.keys[5] = 0;
  449. _keyReport.modifiers = 0;
  450. sendReport(&_keyReport);
  451. }
  452. size_t Keyboard_::write(uint8_t c)
  453. {
  454. uint8_t p = press(c); // Keydown
  455. uint8_t r = release(c); // Keyup
  456. return (p); // just return the result of press() since release() almost always returns 1
  457. }
  458. #endif
  459. #endif /* if defined(USBCON) */