Advertisement
Guest User

Pro Micro joystick code

a guest
Apr 4th, 2015
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.27 KB | None | 0 0
  1. The Ino:
  2.  
  3. ThumbState_t thumbSt;
  4.  
  5. const bool DEBUG = false; // set to true to debug the raw values
  6.  
  7. int xPin = A2;
  8. int yPin = A3;
  9. int xZero, yZero;
  10. int xValue, yValue;
  11. int deadzone = 5; // smaller values will be set to 0
  12.  
  13. void setup(){
  14. pinMode(xPin, INPUT);
  15. pinMode(yPin, INPUT);
  16.  
  17. if(DEBUG) {
  18. Serial.begin(9600);
  19. }
  20.  
  21. // calculate neutral position
  22. xZero = analogRead(xPin);
  23. yZero = analogRead(yPin);
  24.  
  25. thumbSt.xAxis = 0;
  26. thumbSt.yAxis = 0;
  27. }
  28.  
  29. void loop(){
  30. xValue = analogRead(xPin) - xZero;
  31. yValue = analogRead(yPin) - yZero;
  32.  
  33. if(abs(xValue) < deadzone) {
  34. xValue = 0;
  35. }
  36. if(abs(yValue) < deadzone) {
  37. yValue = 0;
  38. }
  39.  
  40. thumbSt.xAxis = map(xValue, 400, -400, -32768, 32768); // here the axis is inverted
  41. thumbSt.yAxis = map(yValue, -400, 400, -32768, 32768);
  42.  
  43. if(DEBUG) {
  44. Serial.print("X: ");
  45. Serial.println(xValue);
  46. Serial.print("Y: ");
  47. Serial.println(yValue);
  48. }
  49.  
  50. // Send to USB
  51. Thumbstick.setState(&thumbSt);
  52. }
  53.  
  54.  
  55. The HID.ccp:
  56.  
  57.  
  58.  
  59. /* Copyright (c) 2011, Peter Barrett
  60. **
  61. ** Permission to use, copy, modify, and/or distribute this software for
  62. ** any purpose with or without fee is hereby granted, provided that the
  63. ** above copyright notice and this permission notice appear in all copies.
  64. **
  65. ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  66. ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  67. ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
  68. ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
  69. ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  70. ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  71. ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  72. ** SOFTWARE.
  73. */
  74.  
  75. #include "Platform.h"
  76. #include "USBAPI.h"
  77. #include "USBDesc.h"
  78.  
  79. #if defined(USBCON)
  80. #ifdef HID_ENABLED
  81.  
  82. // #define RAWHID_ENABLED
  83. // #define KBAM_ENABLED
  84. // #define JOYSTICK_ENABLED
  85. #define THUMBSTICK_ENABLED
  86.  
  87. // Singletons for mouse and keyboard
  88.  
  89. #ifdef KBAM_ENABLED
  90. Mouse_ Mouse;
  91. Keyboard_ Keyboard;
  92. #endif
  93.  
  94. #ifdef JOYSTICK_ENABLED
  95. Joystick_ Joystick;
  96. #endif
  97.  
  98. #ifdef THUMBSTICK_ENABLED
  99. Thumbstick_ Thumbstick;
  100. #endif
  101.  
  102. //================================================================================
  103. //================================================================================
  104.  
  105. // HID report descriptor
  106.  
  107. #define LSB(_x) ((_x) & 0xFF)
  108. #define MSB(_x) ((_x) >> 8)
  109.  
  110. #define RAWHID_USAGE_PAGE 0xFFC0
  111. #define RAWHID_USAGE 0x0C00
  112. #define RAWHID_TX_SIZE 64
  113. #define RAWHID_RX_SIZE 64
  114.  
  115. extern const u8 _hidReportDescriptor[] PROGMEM;
  116. const u8 _hidReportDescriptor[] = {
  117.  
  118. #ifdef KBAM_ENABLED
  119. // Mouse
  120. 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
  121. 0x09, 0x02, // USAGE (Mouse)
  122. 0xa1, 0x01, // COLLECTION (Application)
  123. 0x09, 0x01, // USAGE (Pointer)
  124. 0xa1, 0x00, // COLLECTION (Physical)
  125. 0x85, 0x01, // REPORT_ID (1)
  126. 0x05, 0x09, // USAGE_PAGE (Button)
  127. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  128. 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
  129. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  130. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  131. 0x95, 0x03, // REPORT_COUNT (3)
  132. 0x75, 0x01, // REPORT_SIZE (1)
  133. 0x81, 0x02, // INPUT (Data,Var,Abs)
  134. 0x95, 0x01, // REPORT_COUNT (1)
  135. 0x75, 0x05, // REPORT_SIZE (5)
  136. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  137. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  138. 0x09, 0x30, // USAGE (X)
  139. 0x09, 0x31, // USAGE (Y)
  140. 0x09, 0x38, // USAGE (Wheel)
  141. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  142. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  143. 0x75, 0x08, // REPORT_SIZE (8)
  144. 0x95, 0x03, // REPORT_COUNT (3)
  145. 0x81, 0x06, // INPUT (Data,Var,Rel)
  146. 0xc0, // END_COLLECTION
  147. 0xc0, // END_COLLECTION
  148.  
  149. // Keyboard
  150. 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
  151. 0x09, 0x06, // USAGE (Keyboard)
  152. 0xa1, 0x01, // COLLECTION (Application)
  153. 0x85, 0x02, // REPORT_ID (2)
  154. 0x05, 0x07, // USAGE_PAGE (Keyboard)
  155.  
  156. 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
  157. 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
  158. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  159. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  160. 0x75, 0x01, // REPORT_SIZE (1)
  161.  
  162. 0x95, 0x08, // REPORT_COUNT (8)
  163. 0x81, 0x02, // INPUT (Data,Var,Abs)
  164. 0x95, 0x01, // REPORT_COUNT (1)
  165. 0x75, 0x08, // REPORT_SIZE (8)
  166. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  167.  
  168. 0x95, 0x06, // REPORT_COUNT (6)
  169. 0x75, 0x08, // REPORT_SIZE (8)
  170. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  171. 0x25, 0x65, // LOGICAL_MAXIMUM (101)
  172. 0x05, 0x07, // USAGE_PAGE (Keyboard)
  173.  
  174. 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
  175. 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
  176. 0x81, 0x00, // INPUT (Data,Ary,Abs)
  177. 0xc0, // END_COLLECTION
  178. #endif
  179.  
  180. #ifdef RAWHID_ENABLED
  181. // RAW HID
  182. 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
  183. 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
  184.  
  185. 0xA1, 0x01, // Collection 0x01
  186. 0x85, 0x03, // REPORT_ID (3)
  187. 0x75, 0x08, // report size = 8 bits
  188. 0x15, 0x00, // logical minimum = 0
  189. 0x26, 0xFF, 0x00, // logical maximum = 255
  190.  
  191. 0x95, 64, // report count TX
  192. 0x09, 0x01, // usage
  193. 0x81, 0x02, // Input (array)
  194.  
  195. 0x95, 64, // report count RX
  196. 0x09, 0x02, // usage
  197. 0x91, 0x02, // Output (array)
  198. 0xC0, // end collection
  199. #endif
  200.  
  201. // *** Here is where the RAW_HID has been converted to a Joystick device
  202. // *** Inspired by helmpcb.com/electronics/usb-joystick
  203. // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID
  204. // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32)
  205.  
  206. #ifdef JOYSTICK_ENABLED
  207.  
  208. // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis)
  209.  
  210. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  211. 0x09, 0x04, // USAGE (Joystick)
  212. 0xa1, 0x01, // COLLECTION (Application)
  213. 0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called)
  214.  
  215. //Buttons:
  216. 0x05, 0x09, // USAGE_PAGE (Button)
  217. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  218. 0x29, 0x20, // USAGE_MAXIMUM (Button 32)
  219. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  220. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  221. 0x75, 0x01, // REPORT_SIZE (1)
  222. 0x95, 0x20, // REPORT_COUNT (32)
  223. 0x55, 0x00, // UNIT_EXPONENT (0)
  224. 0x65, 0x00, // UNIT (None)
  225. 0x81, 0x02, // INPUT (Data,Var,Abs)
  226.  
  227. // 8 bit Throttle and Steering
  228. 0x05, 0x02, // USAGE_PAGE (Simulation Controls)
  229.  
  230. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  231. 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
  232. 0xA1, 0x00, // COLLECTION (Physical)
  233. 0x09, 0xBB, // USAGE (Throttle)
  234. 0x09, 0xBA, // USAGE (Steering)
  235. 0x75, 0x08, // REPORT_SIZE (8)
  236. 0x95, 0x02, // REPORT_COUNT (2)
  237. 0x81, 0x02, // INPUT (Data,Var,Abs)
  238.  
  239. 0xc0, // END_COLLECTION
  240.  
  241. // Two Hat switches
  242. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  243.  
  244. 0x09, 0x39, // USAGE (Hat switch)
  245. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  246. 0x25, 0x07, // LOGICAL_MAXIMUM (7)
  247. 0x35, 0x00, // PHYSICAL_MINIMUM (0)
  248. 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
  249. 0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
  250. 0x75, 0x04, // REPORT_SIZE (4)
  251. 0x95, 0x01, // REPORT_COUNT (1)
  252. 0x81, 0x02, // INPUT (Data,Var,Abs)
  253.  
  254. 0x09, 0x39, // USAGE (Hat switch)
  255. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  256. 0x25, 0x07, // LOGICAL_MAXIMUM (7)
  257. 0x35, 0x00, // PHYSICAL_MINIMUM (0)
  258. 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
  259. 0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
  260. 0x75, 0x04, // REPORT_SIZE (4)
  261. 0x95, 0x01, // REPORT_COUNT (1)
  262. 0x81, 0x02, // INPUT (Data,Var,Abs)
  263.  
  264. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  265. 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
  266. 0x75, 0x08, // REPORT_SIZE (8)
  267.  
  268. // Axes
  269. 0x09, 0x01, // USAGE (Pointer)
  270. 0xA1, 0x00, // COLLECTION (Physical)
  271. 0x09, 0x30, // USAGE (x)
  272. 0x09, 0x31, // USAGE (y)
  273. 0x09, 0x32, // USAGE (z)
  274. 0x09, 0x33, // USAGE (rx)
  275. 0x09, 0x34, // USAGE (ry)
  276. 0x09, 0x35, // USAGE (rz)
  277. 0x95, 0x06, // REPORT_COUNT (2)
  278. 0x81, 0x02, // INPUT (Data,Var,Abs)
  279. 0xc0, // END_COLLECTION
  280. 0xc0, // END_COLLECTION
  281. #endif
  282.  
  283. #ifdef THUMBSTICK_ENABLED
  284.  
  285. // Thumbstick - 2 axis joystick, no buttons
  286. 0x05, 0x01, // USAGE Page (Generic Desktop)
  287. 0x09, 0x04, // USAGE (Joystick) /
  288. 0xa1, 0x01, // COLLECTION (Application)
  289. 0x85, 0x04, // REPORT_ID
  290. 0x09, 0x01, // USAGE (Pointer)
  291. 0xa1, 0x00, // COLLECTION (Physical)
  292. 0x05, 0x01, // USAGE Page (Generic Desktop)
  293. 0x09, 0x30, // USAGE (x)
  294. 0x09, 0x31, // USAGE (y)
  295. 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768)
  296. 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
  297. 0x75, 16, // REPORT_SIZE (16)
  298. 0x95, 2, // REPORT_COUNT (2)
  299. 0x81, 0x82, // INPUT (Data, Variable, Absolute, Volatile)
  300. 0xc0, // END_COLLECTION
  301. 0xc0, // END_COLLECTION
  302. #endif
  303.  
  304. };
  305.  
  306. extern const HIDDescriptor _hidInterface PROGMEM;
  307. const HIDDescriptor _hidInterface =
  308. {
  309. D_INTERFACE(HID_INTERFACE,1,3,0,0),
  310. D_HIDREPORT(sizeof(_hidReportDescriptor)),
  311. D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
  312. };
  313.  
  314. //================================================================================
  315. //================================================================================
  316. // Driver
  317.  
  318. u8 _hid_protocol = 1;
  319. u8 _hid_idle = 1;
  320.  
  321. #define WEAK __attribute__ ((weak))
  322.  
  323. int WEAK HID_GetInterface(u8* interfaceNum)
  324. {
  325. interfaceNum[0] += 1; // uses 1
  326. return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
  327. }
  328.  
  329. int WEAK HID_GetDescriptor(int i)
  330. {
  331. return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
  332. }
  333.  
  334. void WEAK HID_SendReport(u8 id, const void* data, int len)
  335. {
  336. USB_Send(HID_TX, &id, 1);
  337. USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
  338. }
  339.  
  340. bool WEAK HID_Setup(Setup& setup)
  341. {
  342. u8 r = setup.bRequest;
  343. u8 requestType = setup.bmRequestType;
  344. if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
  345. {
  346. if (HID_GET_REPORT == r)
  347. {
  348. //HID_GetReport();
  349. return true;
  350. }
  351. if (HID_GET_PROTOCOL == r)
  352. {
  353. //Send8(_hid_protocol); // TODO
  354. return true;
  355. }
  356. }
  357.  
  358. if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
  359. {
  360. if (HID_SET_PROTOCOL == r)
  361. {
  362. _hid_protocol = setup.wValueL;
  363. return true;
  364. }
  365.  
  366. if (HID_SET_IDLE == r)
  367. {
  368. _hid_idle = setup.wValueL;
  369. return true;
  370. }
  371. }
  372. return false;
  373. }
  374.  
  375. //================================================================================
  376. //================================================================================
  377. // Joystick
  378. // Usage: Joystick.move(inputs go here)
  379. //
  380. // The report data format must match the one defined in the descriptor exactly
  381. // or it either won't work, or the pc will make a mess of unpacking the data
  382. //
  383. #ifdef JOYSTICK_ENABLED
  384.  
  385. Joystick_::Joystick_()
  386. {
  387. }
  388.  
  389.  
  390. #define joyBytes 13 // should be equivalent to sizeof(JoyState_t)
  391.  
  392. void Joystick_::setState(JoyState_t *joySt)
  393. {
  394. uint8_t data[joyBytes];
  395. uint32_t buttonTmp;
  396. buttonTmp = joySt->buttons;
  397.  
  398. data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB
  399. buttonTmp >>= 8;
  400. data[1] = buttonTmp & 0xFF;
  401. buttonTmp >>= 8;
  402. data[2] = buttonTmp & 0xFF;
  403. buttonTmp >>= 8;
  404. data[3] = buttonTmp & 0xFF;
  405.  
  406. data[4] = joySt->throttle; // Throttle
  407. data[5] = joySt->rudder; // Steering
  408.  
  409. data[6] = (joySt->hatSw2 << 4) | joySt->hatSw1; // Pack hat-switch states into a single byte
  410.  
  411. data[7] = joySt->xAxis; // X axis
  412. data[8] = joySt->yAxis; // Y axis
  413. data[9] = joySt->zAxis; // Z axis
  414. data[10] = joySt->xRotAxis; // rX axis
  415. data[11] = joySt->yRotAxis; // rY axis
  416. data[12] = joySt->zRotAxis; // rZ axis
  417.  
  418. //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
  419. HID_SendReport(3, data, joyBytes);
  420. // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from
  421. }
  422.  
  423. #endif
  424.  
  425. #ifdef THUMBSTICK_ENABLED
  426.  
  427. Thumbstick_::Thumbstick_()
  428. {
  429. }
  430.  
  431. void Thumbstick_::setState(ThumbState_t *thumbSt)
  432. {
  433. int16_t data[2];
  434. data[0] = thumbSt->xAxis; // X axis
  435. data[1] = thumbSt->yAxis; // Y axis
  436. //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
  437. HID_SendReport(4, data, 4);
  438. }
  439.  
  440. #endif
  441.  
  442.  
  443. //================================================================================
  444. //================================================================================
  445. // Mouse
  446.  
  447. Mouse_::Mouse_(void) : _buttons(0)
  448. {
  449. }
  450.  
  451. void Mouse_::begin(void)
  452. {
  453. }
  454.  
  455. void Mouse_::end(void)
  456. {
  457. }
  458.  
  459. void Mouse_::click(uint8_t b)
  460. {
  461. _buttons = b;
  462. move(0,0,0);
  463. _buttons = 0;
  464. move(0,0,0);
  465. }
  466.  
  467. void Mouse_::move(signed char x, signed char y, signed char wheel)
  468. {
  469. u8 m[4];
  470. m[0] = _buttons;
  471. m[1] = x;
  472. m[2] = y;
  473. m[3] = wheel;
  474. HID_SendReport(1,m,4);
  475. }
  476.  
  477. void Mouse_::buttons(uint8_t b)
  478. {
  479. if (b != _buttons)
  480. {
  481. _buttons = b;
  482. move(0,0,0);
  483. }
  484. }
  485.  
  486. void Mouse_::press(uint8_t b)
  487. {
  488. buttons(_buttons | b);
  489. }
  490.  
  491. void Mouse_::release(uint8_t b)
  492. {
  493. buttons(_buttons & ~b);
  494. }
  495.  
  496. bool Mouse_::isPressed(uint8_t b)
  497. {
  498. if ((b & _buttons) > 0)
  499. return true;
  500. return false;
  501. }
  502.  
  503. //================================================================================
  504. //================================================================================
  505. // Keyboard
  506.  
  507. Keyboard_::Keyboard_(void)
  508. {
  509. }
  510.  
  511. void Keyboard_::begin(void)
  512. {
  513. }
  514.  
  515. void Keyboard_::end(void)
  516. {
  517. }
  518.  
  519. void Keyboard_::sendReport(KeyReport* keys)
  520. {
  521. HID_SendReport(2,keys,sizeof(KeyReport));
  522. }
  523.  
  524. extern
  525. const uint8_t _asciimap[128] PROGMEM;
  526.  
  527. #define SHIFT 0x80
  528. const uint8_t _asciimap[128] =
  529. {
  530. 0x00, // NUL
  531. 0x00, // SOH
  532. 0x00, // STX
  533. 0x00, // ETX
  534. 0x00, // EOT
  535. 0x00, // ENQ
  536. 0x00, // ACK
  537. 0x00, // BEL
  538. 0x2a, // BS Backspace
  539. 0x2b, // TAB Tab
  540. 0x28, // LF Enter
  541. 0x00, // VT
  542. 0x00, // FF
  543. 0x00, // CR
  544. 0x00, // SO
  545. 0x00, // SI
  546. 0x00, // DEL
  547. 0x00, // DC1
  548. 0x00, // DC2
  549. 0x00, // DC3
  550. 0x00, // DC4
  551. 0x00, // NAK
  552. 0x00, // SYN
  553. 0x00, // ETB
  554. 0x00, // CAN
  555. 0x00, // EM
  556. 0x00, // SUB
  557. 0x00, // ESC
  558. 0x00, // FS
  559. 0x00, // GS
  560. 0x00, // RS
  561. 0x00, // US
  562.  
  563. 0x2c, // ' '
  564. 0x1e|SHIFT, // !
  565. 0x34|SHIFT, // "
  566. 0x20|SHIFT, // #
  567. 0x21|SHIFT, // $
  568. 0x22|SHIFT, // %
  569. 0x24|SHIFT, // &
  570. 0x34, // '
  571. 0x26|SHIFT, // (
  572. 0x27|SHIFT, // )
  573. 0x25|SHIFT, // *
  574. 0x2e|SHIFT, // +
  575. 0x36, // ,
  576. 0x2d, // -
  577. 0x37, // .
  578. 0x38, // /
  579. 0x27, // 0
  580. 0x1e, // 1
  581. 0x1f, // 2
  582. 0x20, // 3
  583. 0x21, // 4
  584. 0x22, // 5
  585. 0x23, // 6
  586. 0x24, // 7
  587. 0x25, // 8
  588. 0x26, // 9
  589. 0x33|SHIFT, // :
  590. 0x33, // ;
  591. 0x36|SHIFT, // <
  592. 0x2e, // =
  593. 0x37|SHIFT, // >
  594. 0x38|SHIFT, // ?
  595. 0x1f|SHIFT, // @
  596. 0x04|SHIFT, // A
  597. 0x05|SHIFT, // B
  598. 0x06|SHIFT, // C
  599. 0x07|SHIFT, // D
  600. 0x08|SHIFT, // E
  601. 0x09|SHIFT, // F
  602. 0x0a|SHIFT, // G
  603. 0x0b|SHIFT, // H
  604. 0x0c|SHIFT, // I
  605. 0x0d|SHIFT, // J
  606. 0x0e|SHIFT, // K
  607. 0x0f|SHIFT, // L
  608. 0x10|SHIFT, // M
  609. 0x11|SHIFT, // N
  610. 0x12|SHIFT, // O
  611. 0x13|SHIFT, // P
  612. 0x14|SHIFT, // Q
  613. 0x15|SHIFT, // R
  614. 0x16|SHIFT, // S
  615. 0x17|SHIFT, // T
  616. 0x18|SHIFT, // U
  617. 0x19|SHIFT, // V
  618. 0x1a|SHIFT, // W
  619. 0x1b|SHIFT, // X
  620. 0x1c|SHIFT, // Y
  621. 0x1d|SHIFT, // Z
  622. 0x2f, // [
  623. 0x31, // bslash
  624. 0x30, // ]
  625. 0x23|SHIFT, // ^
  626. 0x2d|SHIFT, // _
  627. 0x35, // `
  628. 0x04, // a
  629. 0x05, // b
  630. 0x06, // c
  631. 0x07, // d
  632. 0x08, // e
  633. 0x09, // f
  634. 0x0a, // g
  635. 0x0b, // h
  636. 0x0c, // i
  637. 0x0d, // j
  638. 0x0e, // k
  639. 0x0f, // l
  640. 0x10, // m
  641. 0x11, // n
  642. 0x12, // o
  643. 0x13, // p
  644. 0x14, // q
  645. 0x15, // r
  646. 0x16, // s
  647. 0x17, // t
  648. 0x18, // u
  649. 0x19, // v
  650. 0x1a, // w
  651. 0x1b, // x
  652. 0x1c, // y
  653. 0x1d, // z
  654. 0x2f|SHIFT, //
  655. 0x31|SHIFT, // |
  656. 0x30|SHIFT, // }
  657. 0x35|SHIFT, // ~
  658. 0 // DEL
  659. };
  660.  
  661. uint8_t USBPutChar(uint8_t c);
  662.  
  663. // press() adds the specified key (printing, non-printing, or modifier)
  664. // to the persistent key report and sends the report. Because of the way
  665. // USB HID works, the host acts like the key remains pressed until we
  666. // call release(), releaseAll(), or otherwise clear the report and resend.
  667. size_t Keyboard_::press(uint8_t k)
  668. {
  669. uint8_t i;
  670. if (k >= 136) { // it's a non-printing key (not a modifier)
  671. k = k - 136;
  672. } else if (k >= 128) { // it's a modifier key
  673. _keyReport.modifiers |= (1<<(k-128));
  674. k = 0;
  675. } else { // it's a printing key
  676. k = pgm_read_byte(_asciimap + k);
  677. if (!k) {
  678. setWriteError();
  679. return 0;
  680. }
  681. if (k & 0x80) { // it's a capital letter or other character reached with shift
  682. _keyReport.modifiers |= 0x02; // the left shift modifier
  683. k &= 0x7F;
  684. }
  685. }
  686.  
  687. // Add k to the key report only if it's not already present
  688. // and if there is an empty slot.
  689. if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
  690. _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
  691. _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
  692.  
  693. for (i=0; i<6; i++) {
  694. if (_keyReport.keys[i] == 0x00) {
  695. _keyReport.keys[i] = k;
  696. break;
  697. }
  698. }
  699. if (i == 6) {
  700. setWriteError();
  701. return 0;
  702. }
  703. }
  704. sendReport(&_keyReport);
  705. return 1;
  706. }
  707.  
  708. // release() takes the specified key out of the persistent key report and
  709. // sends the report. This tells the OS the key is no longer pressed and that
  710. // it shouldn't be repeated any more.
  711. size_t Keyboard_::release(uint8_t k)
  712. {
  713. uint8_t i;
  714. if (k >= 136) { // it's a non-printing key (not a modifier)
  715. k = k - 136;
  716. } else if (k >= 128) { // it's a modifier key
  717. _keyReport.modifiers &= ~(1<<(k-128));
  718. k = 0;
  719. } else { // it's a printing key
  720. k = pgm_read_byte(_asciimap + k);
  721. if (!k) {
  722. return 0;
  723. }
  724. if (k & 0x80) { // it's a capital letter or other character reached with shift
  725. _keyReport.modifiers &= ~(0x02); // the left shift modifier
  726. k &= 0x7F;
  727. }
  728. }
  729.  
  730. // Test the key report to see if k is present. Clear it if it exists.
  731. // Check all positions in case the key is present more than once (which it shouldn't be)
  732. for (i=0; i<6; i++) {
  733. if (0 != k && _keyReport.keys[i] == k) {
  734. _keyReport.keys[i] = 0x00;
  735. }
  736. }
  737.  
  738. sendReport(&_keyReport);
  739. return 1;
  740. }
  741.  
  742. void Keyboard_::releaseAll(void)
  743. {
  744. _keyReport.keys[0] = 0;
  745. _keyReport.keys[1] = 0;
  746. _keyReport.keys[2] = 0;
  747. _keyReport.keys[3] = 0;
  748. _keyReport.keys[4] = 0;
  749. _keyReport.keys[5] = 0;
  750. _keyReport.modifiers = 0;
  751. sendReport(&_keyReport);
  752. }
  753.  
  754. size_t Keyboard_::write(uint8_t c)
  755. {
  756. uint8_t p = press(c); // Keydown
  757. uint8_t r = release(c); // Keyup
  758. return (p); // just return the result of press() since release() almost always returns 1
  759. }
  760.  
  761. #endif
  762.  
  763. #endif /* if defined(USBCON) */
  764.  
  765. And the USBAPI.h:
  766.  
  767.  
  768.  
  769. #ifndef __USBAPI__
  770. #define __USBAPI__
  771.  
  772. #if defined(USBCON)
  773.  
  774. //================================================================================
  775. //================================================================================
  776. // USB
  777.  
  778. class USBDevice_
  779. {
  780. public:
  781. USBDevice_();
  782. bool configured();
  783.  
  784. void attach();
  785. void detach(); // Serial port goes down too...
  786. void poll();
  787. };
  788. extern USBDevice_ USBDevice;
  789.  
  790. //================================================================================
  791. //================================================================================
  792. // Serial over CDC (Serial1 is the physical port)
  793.  
  794. class Serial_ : public Stream
  795. {
  796. private:
  797. ring_buffer *_cdc_rx_buffer;
  798. public:
  799. void begin(uint16_t baud_count);
  800. void end(void);
  801.  
  802. virtual int available(void);
  803. virtual void accept(void);
  804. virtual int peek(void);
  805. virtual int read(void);
  806. virtual void flush(void);
  807. virtual size_t write(uint8_t);
  808. operator bool();
  809. };
  810. extern Serial_ Serial;
  811.  
  812. //================================================================================
  813. //================================================================================
  814. // Joystick
  815. // Implemented in HID.cpp
  816. // The list of parameters here needs to match the implementation in HID.cpp
  817.  
  818.  
  819. typedef struct JoyState // Pretty self explanitory. Simple state to store all the joystick parameters
  820. {
  821. uint8_t xAxis;
  822. uint8_t yAxis;
  823. uint8_t zAxis;
  824.  
  825. uint8_t xRotAxis;
  826. uint8_t yRotAxis;
  827. uint8_t zRotAxis;
  828.  
  829. uint8_t throttle;
  830. uint8_t rudder;
  831.  
  832. uint8_t hatSw1;
  833. uint8_t hatSw2;
  834.  
  835. uint32_t buttons; // 32 general buttons
  836.  
  837. } JoyState_t;
  838.  
  839. class Joystick_
  840. {
  841. public:
  842. Joystick_();
  843. void setState(JoyState_t *joySt);
  844.  
  845. };
  846. extern Joystick_ Joystick;
  847.  
  848.  
  849. //================================================================================
  850. //================================================================================
  851. // ThumbStick
  852. // Implemented in HID.cpp
  853. // The list of parameters here needs to match the implementation in HID.cpp
  854.  
  855. typedef struct ThumbState
  856. {
  857. int16_t xAxis;
  858. int16_t yAxis;
  859. } ThumbState_t;
  860.  
  861. class Thumbstick_
  862. {
  863. public:
  864. Thumbstick_();
  865. void setState(ThumbState_t *trackSt);
  866. };
  867. extern Thumbstick_ Thumbstick;
  868.  
  869. //================================================================================
  870. //================================================================================
  871. // Mouse
  872.  
  873. #define MOUSE_LEFT 1
  874. #define MOUSE_RIGHT 2
  875. #define MOUSE_MIDDLE 4
  876. #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
  877.  
  878. class Mouse_
  879. {
  880. private:
  881. uint8_t _buttons;
  882. void buttons(uint8_t b);
  883. public:
  884. Mouse_(void);
  885. void begin(void);
  886. void end(void);
  887. void click(uint8_t b = MOUSE_LEFT);
  888. void move(signed char x, signed char y, signed char wheel = 0);
  889. void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
  890. void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
  891. bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
  892. };
  893. extern Mouse_ Mouse;
  894.  
  895. //================================================================================
  896. //================================================================================
  897. // Keyboard
  898.  
  899. #define KEY_LEFT_CTRL 0x80
  900. #define KEY_LEFT_SHIFT 0x81
  901. #define KEY_LEFT_ALT 0x82
  902. #define KEY_LEFT_GUI 0x83
  903. #define KEY_RIGHT_CTRL 0x84
  904. #define KEY_RIGHT_SHIFT 0x85
  905. #define KEY_RIGHT_ALT 0x86
  906. #define KEY_RIGHT_GUI 0x87
  907.  
  908. #define KEY_UP_ARROW 0xDA
  909. #define KEY_DOWN_ARROW 0xD9
  910. #define KEY_LEFT_ARROW 0xD8
  911. #define KEY_RIGHT_ARROW 0xD7
  912. #define KEY_BACKSPACE 0xB2
  913. #define KEY_TAB 0xB3
  914. #define KEY_RETURN 0xB0
  915. #define KEY_ESC 0xB1
  916. #define KEY_INSERT 0xD1
  917. #define KEY_DELETE 0xD4
  918. #define KEY_PAGE_UP 0xD3
  919. #define KEY_PAGE_DOWN 0xD6
  920. #define KEY_HOME 0xD2
  921. #define KEY_END 0xD5
  922. #define KEY_CAPS_LOCK 0xC1
  923. #define KEY_F1 0xC2
  924. #define KEY_F2 0xC3
  925. #define KEY_F3 0xC4
  926. #define KEY_F4 0xC5
  927. #define KEY_F5 0xC6
  928. #define KEY_F6 0xC7
  929. #define KEY_F7 0xC8
  930. #define KEY_F8 0xC9
  931. #define KEY_F9 0xCA
  932. #define KEY_F10 0xCB
  933. #define KEY_F11 0xCC
  934. #define KEY_F12 0xCD
  935.  
  936. // Low level key report: up to 6 keys and shift, ctrl etc at once
  937. typedef struct
  938. {
  939. uint8_t modifiers;
  940. uint8_t reserved;
  941. uint8_t keys[6];
  942. } KeyReport;
  943.  
  944. class Keyboard_ : public Print
  945. {
  946. private:
  947. KeyReport _keyReport;
  948. void sendReport(KeyReport* keys);
  949. public:
  950. Keyboard_(void);
  951. void begin(void);
  952. void end(void);
  953. virtual size_t write(uint8_t k);
  954. virtual size_t press(uint8_t k);
  955. virtual size_t release(uint8_t k);
  956. virtual void releaseAll(void);
  957. };
  958. extern Keyboard_ Keyboard;
  959.  
  960. //================================================================================
  961. //================================================================================
  962. // Low level API
  963.  
  964. typedef struct
  965. {
  966. uint8_t bmRequestType;
  967. uint8_t bRequest;
  968. uint8_t wValueL;
  969. uint8_t wValueH;
  970. uint16_t wIndex;
  971. uint16_t wLength;
  972. } Setup;
  973.  
  974. //================================================================================
  975. //================================================================================
  976. // HID 'Driver'
  977.  
  978. int HID_GetInterface(uint8_t* interfaceNum);
  979. int HID_GetDescriptor(int i);
  980. bool HID_Setup(Setup& setup);
  981. void HID_SendReport(uint8_t id, const void* data, int len);
  982.  
  983. //================================================================================
  984. //================================================================================
  985. // MSC 'Driver'
  986.  
  987. int MSC_GetInterface(uint8_t* interfaceNum);
  988. int MSC_GetDescriptor(int i);
  989. bool MSC_Setup(Setup& setup);
  990. bool MSC_Data(uint8_t rx,uint8_t tx);
  991.  
  992. //================================================================================
  993. //================================================================================
  994. // CSC 'Driver'
  995.  
  996. int CDC_GetInterface(uint8_t* interfaceNum);
  997. int CDC_GetDescriptor(int i);
  998. bool CDC_Setup(Setup& setup);
  999.  
  1000. //================================================================================
  1001. //================================================================================
  1002.  
  1003. #define TRANSFER_PGM 0x80
  1004. #define TRANSFER_RELEASE 0x40
  1005. #define TRANSFER_ZERO 0x20
  1006.  
  1007. int USB_SendControl(uint8_t flags, const void* d, int len);
  1008. int USB_RecvControl(void* d, int len);
  1009.  
  1010. uint8_t USB_Available(uint8_t ep);
  1011. int USB_Send(uint8_t ep, const void* data, int len); // blocking
  1012. int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
  1013. int USB_Recv(uint8_t ep); // non-blocking
  1014. void USB_Flush(uint8_t ep);
  1015.  
  1016. #endif
  1017.  
  1018. #endif /* if defined(USBCON) */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement