Advertisement
Guest User

Untitled

a guest
Mar 1st, 2014
490
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.70 KB | None | 0 0
  1.  
  2.  
  3. /* Copyright (c) 2011, Peter Barrett
  4. **
  5. ** Permission to use, copy, modify, and/or distribute this software for
  6. ** any purpose with or without fee is hereby granted, provided that the
  7. ** above copyright notice and this permission notice appear in all copies.
  8. **
  9. ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
  12. ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
  13. ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  14. ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  15. ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  16. ** SOFTWARE.
  17. */
  18.  
  19. #include "Platform.h"
  20. #include "USBAPI.h"
  21. #include "USBDesc.h"
  22.  
  23. #if defined(USBCON)
  24. #ifdef HID_ENABLED
  25.  
  26. //#define RAWHID_ENABLED
  27.  
  28. //  Singletons for mouse and keyboard
  29.  
  30. Mouse_ Mouse;
  31. Keyboard_ Keyboard;
  32. // *** Add a joystick too
  33. Joystick_ Joystick;
  34.  
  35. //================================================================================
  36. //================================================================================
  37.  
  38. //  HID report descriptor
  39.  
  40. #define LSB(_x) ((_x) & 0xFF)
  41. #define MSB(_x) ((_x) >> 8)
  42.  
  43. #define RAWHID_USAGE_PAGE   0xFFC0
  44. #define RAWHID_USAGE        0x0C00
  45. #define RAWHID_TX_SIZE 64
  46. #define RAWHID_RX_SIZE 64
  47.  
  48. extern const u8 _hidReportDescriptor[] PROGMEM;
  49. const u8 _hidReportDescriptor[] = {
  50.  
  51.     //  Mouse
  52.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  // 54
  53.     0x09, 0x02,                    // USAGE (Mouse)
  54.     0xa1, 0x01,                    // COLLECTION (Application)
  55.     0x09, 0x01,                    //   USAGE (Pointer)
  56.     0xa1, 0x00,                    //   COLLECTION (Physical)
  57.     0x85, 0x01,                    //     REPORT_ID (1)
  58.     0x05, 0x09,                    //     USAGE_PAGE (Button)
  59.     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
  60.     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
  61.     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
  62.     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
  63.     0x95, 0x03,                    //     REPORT_COUNT (3)
  64.     0x75, 0x01,                    //     REPORT_SIZE (1)
  65.     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
  66.     0x95, 0x01,                    //     REPORT_COUNT (1)
  67.     0x75, 0x05,                    //     REPORT_SIZE (5)
  68.     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
  69.     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
  70.     0x09, 0x30,                    //     USAGE (X)
  71.     0x09, 0x31,                    //     USAGE (Y)
  72.     0x09, 0x38,                    //     USAGE (Wheel)
  73.     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
  74.     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
  75.     0x75, 0x08,                    //     REPORT_SIZE (8)
  76.     0x95, 0x03,                    //     REPORT_COUNT (3)
  77.     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
  78.     0xc0,                          //   END_COLLECTION
  79.     0xc0,                          // END_COLLECTION
  80.  
  81.     //  Keyboard
  82.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  // 47
  83.     0x09, 0x06,                    // USAGE (Keyboard)
  84.     0xa1, 0x01,                    // COLLECTION (Application)
  85.     0x85, 0x02,                    //   REPORT_ID (2)
  86.     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
  87.  
  88.     0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
  89.     0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
  90.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  91.     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
  92.     0x75, 0x01,                    //   REPORT_SIZE (1)
  93.  
  94.     0x95, 0x08,                    //   REPORT_COUNT (8)
  95.     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
  96.     0x95, 0x01,                    //   REPORT_COUNT (1)
  97.     0x75, 0x08,                    //   REPORT_SIZE (8)
  98.     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
  99.  
  100.     0x95, 0x06,                    //   REPORT_COUNT (6)
  101.     0x75, 0x08,                    //   REPORT_SIZE (8)
  102.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  103.     0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
  104.     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
  105.  
  106.     0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
  107.     0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
  108.     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
  109.     0xc0,                          // END_COLLECTION
  110.  
  111. #if RAWHID_ENABLED
  112.     //  RAW HID
  113.     0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE),   // 30
  114.     0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
  115.  
  116.     0xA1, 0x01,             // Collection 0x01
  117.     0x85, 0x03,             // REPORT_ID (3)
  118.     0x75, 0x08,             // report size = 8 bits
  119.     0x15, 0x00,             // logical minimum = 0
  120.     0x26, 0xFF, 0x00,       // logical maximum = 255
  121.  
  122.     0x95, 64,               // report count TX
  123.     0x09, 0x01,             // usage
  124.     0x81, 0x02,             // Input (array)
  125.  
  126.     0x95, 64,               // report count RX
  127.     0x09, 0x02,             // usage
  128.     0x91, 0x02,             // Output (array)
  129.     0xC0                    // end collection
  130. #endif
  131.  
  132.    // JOYSTICK HID
  133.     // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis)
  134.  
  135.     0x05, 0x01,         // USAGE_PAGE (Generic Desktop)
  136.     0x09, 0x04,         // USAGE (Joystick)
  137.     0xa1, 0x01,         // COLLECTION (Application)
  138.         0x85, 0x03,         // REPORT_ID (3)  (This is important when HID_SendReport() is called)
  139.  
  140.         //Buttons:
  141.         0x05, 0x09,         // USAGE_PAGE (Button)
  142.         0x19, 0x01,         // USAGE_MINIMUM (Button 1)
  143.         0x29, 0x20,         // USAGE_MAXIMUM (Button 32)
  144.         0x15, 0x00,         // LOGICAL_MINIMUM (0)
  145.         0x25, 0x01,         // LOGICAL_MAXIMUM (1)
  146.         0x75, 0x01,         // REPORT_SIZE (1)
  147.         0x95, 0x20,         // REPORT_COUNT (32)
  148.         0x55, 0x00,         // UNIT_EXPONENT (0)
  149.         0x65, 0x00,         // UNIT (None)
  150.         0x81, 0x02,         // INPUT (Data,Var,Abs)
  151.  
  152.         // 8 bit Throttle and Steering
  153.         0x05, 0x02,         // USAGE_PAGE (Simulation Controls)
  154.  
  155.         0x15, 0x00,         // LOGICAL_MINIMUM (0)
  156.         0x26, 0xff, 0x00,       // LOGICAL_MAXIMUM (255)
  157.         0xA1, 0x00,         // COLLECTION (Physical)
  158.             0x09, 0xBB,         // USAGE (Throttle)
  159.             0x09, 0xBA,         // USAGE (Steering)
  160.             0x75, 0x08,         // REPORT_SIZE (8)
  161.             0x95, 0x02,         // REPORT_COUNT (2)
  162.             0x81, 0x02,         // INPUT (Data,Var,Abs)
  163.  
  164.         0xc0,               // END_COLLECTION
  165.         // Two Hat switches
  166.  
  167.         0x05, 0x01,         // USAGE_PAGE (Generic Desktop)
  168.  
  169.         0x09, 0x39,         // USAGE (Hat switch)
  170.         0x15, 0x00,         // LOGICAL_MINIMUM (0)
  171.         0x25, 0x07,         // LOGICAL_MAXIMUM (7)
  172.         0x35, 0x00,         // PHYSICAL_MINIMUM (0)
  173.         0x46, 0x3B, 0x01,       // PHYSICAL_MAXIMUM (315)
  174.         0x65, 0x14,         // UNIT (Eng Rot:Angular Pos)
  175.         0x75, 0x04,         // REPORT_SIZE (4)
  176.         0x95, 0x01,         // REPORT_COUNT (1)
  177.         0x81, 0x02,         // INPUT (Data,Var,Abs)
  178.  
  179.         0x09, 0x39,         // USAGE (Hat switch)
  180.         0x15, 0x00,         // LOGICAL_MINIMUM (0)
  181.         0x25, 0x07,         // LOGICAL_MAXIMUM (7)
  182.         0x35, 0x00,         // PHYSICAL_MINIMUM (0)
  183.         0x46, 0x3B, 0x01,       // PHYSICAL_MAXIMUM (315)
  184.         0x65, 0x14,         // UNIT (Eng Rot:Angular Pos)
  185.         0x75, 0x04,         // REPORT_SIZE (4)
  186.         0x95, 0x01,         // REPORT_COUNT (1)
  187.         0x81, 0x02,         // INPUT (Data,Var,Abs)
  188.  
  189.         0x15, 0x00,         // LOGICAL_MINIMUM (0)
  190.         0x26, 0xff, 0x00,       // LOGICAL_MAXIMUM (255)
  191.         0x75, 0x08,         // REPORT_SIZE (8)
  192.  
  193.         0x09, 0x01,         // USAGE (Pointer)
  194.         0xA1, 0x00,         // COLLECTION (Physical)
  195.             0x09, 0x30,     // USAGE (x)
  196.             0x09, 0x31,     // USAGE (y)
  197.             0x09, 0x32,     // USAGE (z)
  198.             0x09, 0x33,     // USAGE (rx)
  199.             0x09, 0x34,     // USAGE (ry)
  200.             0x09, 0x35,     // USAGE (rz)
  201.             0x95, 0x06,     // REPORT_COUNT (2)
  202.             0x81, 0x02,     // INPUT (Data,Var,Abs)
  203.         0xc0,               // END_COLLECTION
  204.  
  205.     0xc0                    // END_COLLECTION
  206.  
  207. };
  208.  
  209. extern const HIDDescriptor _hidInterface PROGMEM;
  210. const HIDDescriptor _hidInterface =
  211. {
  212.     D_INTERFACE(HID_INTERFACE,1,3,0,0),
  213.     D_HIDREPORT(sizeof(_hidReportDescriptor)),
  214.     D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
  215. };
  216.  
  217. //================================================================================
  218. //================================================================================
  219. //  Driver
  220.  
  221. u8 _hid_protocol = 1;
  222. u8 _hid_idle = 1;
  223.  
  224. #define WEAK __attribute__ ((weak))
  225.  
  226. int WEAK HID_GetInterface(u8* interfaceNum)
  227. {
  228.     interfaceNum[0] += 1;   // uses 1
  229.     return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
  230. }
  231.  
  232. int WEAK HID_GetDescriptor(int i)
  233. {
  234.     return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
  235. }
  236.  
  237. void WEAK HID_SendReport(u8 id, const void* data, int len)
  238. {
  239.     USB_Send(HID_TX, &id, 1);
  240.     USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
  241. }
  242.  
  243. bool WEAK HID_Setup(Setup& setup)
  244. {
  245.     u8 r = setup.bRequest;
  246.     u8 requestType = setup.bmRequestType;
  247.     if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
  248.     {
  249.         if (HID_GET_REPORT == r)
  250.         {
  251.             //HID_GetReport();
  252.             return true;
  253.         }
  254.         if (HID_GET_PROTOCOL == r)
  255.         {
  256.             //Send8(_hid_protocol); // TODO
  257.             return true;
  258.         }
  259.     }
  260.  
  261.     if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
  262.     {
  263.         if (HID_SET_PROTOCOL == r)
  264.         {
  265.             _hid_protocol = setup.wValueL;
  266.             return true;
  267.         }
  268.  
  269.         if (HID_SET_IDLE == r)
  270.         {
  271.             _hid_idle = setup.wValueL;
  272.             return true;
  273.         }
  274.     }
  275.     return false;
  276. }
  277.  
  278. //================================================================================
  279. //================================================================================
  280. // Joystick
  281. //  Usage: Joystick.move(x, y, throttle, buttons)
  282. //  x & y forward/left = 0, centre = 127, back/right = 255
  283. //  throttle max = 0, min = 255
  284. //  8 buttons packed into 1 byte
  285.  
  286. Joystick_::Joystick_()
  287. {
  288. }
  289.  
  290. void Joystick_::move(uint8_t x, uint8_t y, uint8_t z, uint8_t xrot, uint8_t yrot, uint8_t zrot, uint8_t throttle, uint8_t rudder, uint8_t buttons, uint8_t hatSw1, uint8_t hatSw2)
  291. {
  292.     u8 j[13];
  293.     uint32_t buttonTmp;
  294.     buttonTmp = buttons;
  295.  
  296.     j[0] = buttonTmp & 0xFF;     // Break 32 bit button-state out into 4 bytes, to send over USB
  297.     buttonTmp >>= 8;
  298.     j[1] = buttonTmp & 0xFF;
  299.     buttonTmp >>= 8;
  300.     j[2] = buttonTmp & 0xFF;
  301.     buttonTmp >>= 8;
  302.     j[3] = buttonTmp & 0xFF;
  303.  
  304.     j[4] = throttle;
  305.     j[5] = rudder;
  306.  
  307.     j[6] = (hatSw2 << 4) | hatSw1;
  308.  
  309.     j[7] = x;
  310.     j[8] = y;
  311.     j[9] = z;
  312.  
  313.     j[10] = xrot;
  314.     j[11] = yrot;
  315.     j[12] = zrot;
  316.  
  317.     //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
  318.     HID_SendReport(3, j, 13);
  319. }
  320.  
  321. //================================================================================
  322. //================================================================================
  323. //  Mouse
  324.  
  325. Mouse_::Mouse_(void) : _buttons(0)
  326. {
  327. }
  328.  
  329. void Mouse_::begin(void)
  330. {
  331. }
  332.  
  333. void Mouse_::end(void)
  334. {
  335. }
  336.  
  337. void Mouse_::click(uint8_t b)
  338. {
  339.     _buttons = b;
  340.     move(0,0,0);
  341.     _buttons = 0;
  342.     move(0,0,0);
  343. }
  344.  
  345. void Mouse_::move(signed char x, signed char y, signed char wheel)
  346. {
  347.     u8 m[4];
  348.     m[0] = _buttons;
  349.     m[1] = x;
  350.     m[2] = y;
  351.     m[3] = wheel;
  352.     HID_SendReport(1,m,4);
  353. }
  354.  
  355. void Mouse_::buttons(uint8_t b)
  356. {
  357.     if (b != _buttons)
  358.     {
  359.         _buttons = b;
  360.         move(0,0,0);
  361.     }
  362. }
  363.  
  364. void Mouse_::press(uint8_t b)
  365. {
  366.     buttons(_buttons | b);
  367. }
  368.  
  369. void Mouse_::release(uint8_t b)
  370. {
  371.     buttons(_buttons & ~b);
  372. }
  373.  
  374. bool Mouse_::isPressed(uint8_t b)
  375. {
  376.     if ((b & _buttons) > 0)
  377.         return true;
  378.     return false;
  379. }
  380.  
  381. //================================================================================
  382. //================================================================================
  383. //  Keyboard
  384.  
  385. Keyboard_::Keyboard_(void)
  386. {
  387. }
  388.  
  389. void Keyboard_::begin(void)
  390. {
  391. }
  392.  
  393. void Keyboard_::end(void)
  394. {
  395. }
  396.  
  397. void Keyboard_::sendReport(KeyReport* keys)
  398. {
  399.     HID_SendReport(2,keys,sizeof(KeyReport));
  400. }
  401.  
  402. extern
  403. const uint8_t _asciimap[128] PROGMEM;
  404.  
  405. #define SHIFT 0x80
  406. const uint8_t _asciimap[128] =
  407. {
  408.     0x00,             // NUL
  409.     0x00,             // SOH
  410.     0x00,             // STX
  411.     0x00,             // ETX
  412.     0x00,             // EOT
  413.     0x00,             // ENQ
  414.     0x00,             // ACK
  415.     0x00,             // BEL
  416.     0x2a,           // BS   Backspace
  417.     0x2b,           // TAB  Tab
  418.     0x28,           // LF   Enter
  419.     0x00,             // VT
  420.     0x00,             // FF
  421.     0x00,             // CR
  422.     0x00,             // SO
  423.     0x00,             // SI
  424.     0x00,             // DEL
  425.     0x00,             // DC1
  426.     0x00,             // DC2
  427.     0x00,             // DC3
  428.     0x00,             // DC4
  429.     0x00,             // NAK
  430.     0x00,             // SYN
  431.     0x00,             // ETB
  432.     0x00,             // CAN
  433.     0x00,             // EM
  434.     0x00,             // SUB
  435.     0x00,             // ESC
  436.     0x00,             // FS
  437.     0x00,             // GS
  438.     0x00,             // RS
  439.     0x00,             // US
  440.  
  441.     0x2c,          //  ' '
  442.     0x1e|SHIFT,    // !
  443.     0x34|SHIFT,    // "
  444.     0x20|SHIFT,    // #
  445.     0x21|SHIFT,    // $
  446.     0x22|SHIFT,    // %
  447.     0x24|SHIFT,    // &
  448.     0x34,          // '
  449.     0x26|SHIFT,    // (
  450.     0x27|SHIFT,    // )
  451.     0x25|SHIFT,    // *
  452.     0x2e|SHIFT,    // +
  453.     0x36,          // ,
  454.     0x2d,          // -
  455.     0x37,          // .
  456.     0x38,          // /
  457.     0x27,          // 0
  458.     0x1e,          // 1
  459.     0x1f,          // 2
  460.     0x20,          // 3
  461.     0x21,          // 4
  462.     0x22,          // 5
  463.     0x23,          // 6
  464.     0x24,          // 7
  465.     0x25,          // 8
  466.     0x26,          // 9
  467.     0x33|SHIFT,      // :
  468.     0x33,          // ;
  469.     0x36|SHIFT,      // <
  470.     0x2e,          // =
  471.     0x37|SHIFT,      // >
  472.     0x38|SHIFT,      // ?
  473.     0x1f|SHIFT,      // @
  474.     0x04|SHIFT,      // A
  475.     0x05|SHIFT,      // B
  476.     0x06|SHIFT,      // C
  477.     0x07|SHIFT,      // D
  478.     0x08|SHIFT,      // E
  479.     0x09|SHIFT,      // F
  480.     0x0a|SHIFT,      // G
  481.     0x0b|SHIFT,      // H
  482.     0x0c|SHIFT,      // I
  483.     0x0d|SHIFT,      // J
  484.     0x0e|SHIFT,      // K
  485.     0x0f|SHIFT,      // L
  486.     0x10|SHIFT,      // M
  487.     0x11|SHIFT,      // N
  488.     0x12|SHIFT,      // O
  489.     0x13|SHIFT,      // P
  490.     0x14|SHIFT,      // Q
  491.     0x15|SHIFT,      // R
  492.     0x16|SHIFT,      // S
  493.     0x17|SHIFT,      // T
  494.     0x18|SHIFT,      // U
  495.     0x19|SHIFT,      // V
  496.     0x1a|SHIFT,      // W
  497.     0x1b|SHIFT,      // X
  498.     0x1c|SHIFT,      // Y
  499.     0x1d|SHIFT,      // Z
  500.     0x2f,          // [
  501.     0x31,          // bslash
  502.     0x30,          // ]
  503.     0x23|SHIFT,    // ^
  504.     0x2d|SHIFT,    // _
  505.     0x35,          // `
  506.     0x04,          // a
  507.     0x05,          // b
  508.     0x06,          // c
  509.     0x07,          // d
  510.     0x08,          // e
  511.     0x09,          // f
  512.     0x0a,          // g
  513.     0x0b,          // h
  514.     0x0c,          // i
  515.     0x0d,          // j
  516.     0x0e,          // k
  517.     0x0f,          // l
  518.     0x10,          // m
  519.     0x11,          // n
  520.     0x12,          // o
  521.     0x13,          // p
  522.     0x14,          // q
  523.     0x15,          // r
  524.     0x16,          // s
  525.     0x17,          // t
  526.     0x18,          // u
  527.     0x19,          // v
  528.     0x1a,          // w
  529.     0x1b,          // x
  530.     0x1c,          // y
  531.     0x1d,          // z
  532.     0x2f|SHIFT,    //
  533.     0x31|SHIFT,    // |
  534.     0x30|SHIFT,    // }
  535.     0x35|SHIFT,    // ~
  536.     0               // DEL
  537. };
  538.  
  539. uint8_t USBPutChar(uint8_t c);
  540.  
  541. // press() adds the specified key (printing, non-printing, or modifier)
  542. // to the persistent key report and sends the report.  Because of the way
  543. // USB HID works, the host acts like the key remains pressed until we
  544. // call release(), releaseAll(), or otherwise clear the report and resend.
  545. size_t Keyboard_::press(uint8_t k)
  546. {
  547.     uint8_t i;
  548.     if (k >= 136) {         // it's a non-printing key (not a modifier)
  549.         k = k - 136;
  550.     } else if (k >= 128) {  // it's a modifier key
  551.         _keyReport.modifiers |= (1<<(k-128));
  552.         k = 0;
  553.     } else {                // it's a printing key
  554.         k = pgm_read_byte(_asciimap + k);
  555.         if (!k) {
  556.             setWriteError();
  557.             return 0;
  558.         }
  559.         if (k & 0x80) {                     // it's a capital letter or other character reached with shift
  560.             _keyReport.modifiers |= 0x02;   // the left shift modifier
  561.             k &= 0x7F;
  562.         }
  563.     }
  564.  
  565.     // Add k to the key report only if it's not already present
  566.     // and if there is an empty slot.
  567.     if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
  568.         _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
  569.         _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
  570.  
  571.         for (i=0; i<6; i++) {
  572.             if (_keyReport.keys[i] == 0x00) {
  573.                 _keyReport.keys[i] = k;
  574.                 break;
  575.             }
  576.         }
  577.         if (i == 6) {
  578.             setWriteError();
  579.             return 0;
  580.         }
  581.     }
  582.     sendReport(&_keyReport);
  583.     return 1;
  584. }
  585.  
  586. // release() takes the specified key out of the persistent key report and
  587. // sends the report.  This tells the OS the key is no longer pressed and that
  588. // it shouldn't be repeated any more.
  589. size_t Keyboard_::release(uint8_t k)
  590. {
  591.     uint8_t i;
  592.     if (k >= 136) {         // it's a non-printing key (not a modifier)
  593.         k = k - 136;
  594.     } else if (k >= 128) {  // it's a modifier key
  595.         _keyReport.modifiers &= ~(1<<(k-128));
  596.         k = 0;
  597.     } else {                // it's a printing key
  598.         k = pgm_read_byte(_asciimap + k);
  599.         if (!k) {
  600.             return 0;
  601.         }
  602.         if (k & 0x80) {                         // it's a capital letter or other character reached with shift
  603.             _keyReport.modifiers &= ~(0x02);    // the left shift modifier
  604.             k &= 0x7F;
  605.         }
  606.     }
  607.  
  608.     // Test the key report to see if k is present.  Clear it if it exists.
  609.     // Check all positions in case the key is present more than once (which it shouldn't be)
  610.     for (i=0; i<6; i++) {
  611.         if (0 != k && _keyReport.keys[i] == k) {
  612.             _keyReport.keys[i] = 0x00;
  613.         }
  614.     }
  615.  
  616.     sendReport(&_keyReport);
  617.     return 1;
  618. }
  619.  
  620. void Keyboard_::releaseAll(void)
  621. {
  622.     _keyReport.keys[0] = 0;
  623.     _keyReport.keys[1] = 0;
  624.     _keyReport.keys[2] = 0;
  625.     _keyReport.keys[3] = 0;
  626.     _keyReport.keys[4] = 0;
  627.     _keyReport.keys[5] = 0;
  628.     _keyReport.modifiers = 0;
  629.     sendReport(&_keyReport);
  630. }
  631.  
  632. size_t Keyboard_::write(uint8_t c)
  633. {
  634.     uint8_t p = press(c);       // Keydown
  635.     uint8_t r = release(c);     // Keyup
  636.     return (p);                 // just return the result of press() since release() almost always returns 1
  637. }
  638.  
  639. #endif
  640.  
  641. #endif /* if defined(USBCON) */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement