Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- The Ino:
- ThumbState_t thumbSt;
- const bool DEBUG = false; // set to true to debug the raw values
- int xPin = A2;
- int yPin = A3;
- int xZero, yZero;
- int xValue, yValue;
- int deadzone = 5; // smaller values will be set to 0
- void setup(){
- pinMode(xPin, INPUT);
- pinMode(yPin, INPUT);
- if(DEBUG) {
- Serial.begin(9600);
- }
- // calculate neutral position
- xZero = analogRead(xPin);
- yZero = analogRead(yPin);
- thumbSt.xAxis = 0;
- thumbSt.yAxis = 0;
- }
- void loop(){
- xValue = analogRead(xPin) - xZero;
- yValue = analogRead(yPin) - yZero;
- if(abs(xValue) < deadzone) {
- xValue = 0;
- }
- if(abs(yValue) < deadzone) {
- yValue = 0;
- }
- thumbSt.xAxis = map(xValue, 400, -400, -32768, 32768); // here the axis is inverted
- thumbSt.yAxis = map(yValue, -400, 400, -32768, 32768);
- if(DEBUG) {
- Serial.print("X: ");
- Serial.println(xValue);
- Serial.print("Y: ");
- Serial.println(yValue);
- }
- // Send to USB
- Thumbstick.setState(&thumbSt);
- }
- The HID.ccp:
- /* Copyright (c) 2011, Peter Barrett
- **
- ** Permission to use, copy, modify, and/or distribute this software for
- ** any purpose with or without fee is hereby granted, provided that the
- ** above copyright notice and this permission notice appear in all copies.
- **
- ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
- ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- ** SOFTWARE.
- */
- #include "Platform.h"
- #include "USBAPI.h"
- #include "USBDesc.h"
- #if defined(USBCON)
- #ifdef HID_ENABLED
- // #define RAWHID_ENABLED
- // #define KBAM_ENABLED
- // #define JOYSTICK_ENABLED
- #define THUMBSTICK_ENABLED
- // Singletons for mouse and keyboard
- #ifdef KBAM_ENABLED
- Mouse_ Mouse;
- Keyboard_ Keyboard;
- #endif
- #ifdef JOYSTICK_ENABLED
- Joystick_ Joystick;
- #endif
- #ifdef THUMBSTICK_ENABLED
- Thumbstick_ Thumbstick;
- #endif
- //================================================================================
- //================================================================================
- // HID report descriptor
- #define LSB(_x) ((_x) & 0xFF)
- #define MSB(_x) ((_x) >> 8)
- #define RAWHID_USAGE_PAGE 0xFFC0
- #define RAWHID_USAGE 0x0C00
- #define RAWHID_TX_SIZE 64
- #define RAWHID_RX_SIZE 64
- extern const u8 _hidReportDescriptor[] PROGMEM;
- const u8 _hidReportDescriptor[] = {
- #ifdef KBAM_ENABLED
- // Mouse
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
- 0x09, 0x02, // USAGE (Mouse)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x09, 0x01, // USAGE (Pointer)
- 0xa1, 0x00, // COLLECTION (Physical)
- 0x85, 0x01, // REPORT_ID (1)
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x95, 0x03, // REPORT_COUNT (3)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x05, // REPORT_SIZE (5)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x30, // USAGE (X)
- 0x09, 0x31, // USAGE (Y)
- 0x09, 0x38, // USAGE (Wheel)
- 0x15, 0x81, // LOGICAL_MINIMUM (-127)
- 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x03, // REPORT_COUNT (3)
- 0x81, 0x06, // INPUT (Data,Var,Rel)
- 0xc0, // END_COLLECTION
- 0xc0, // END_COLLECTION
- // Keyboard
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
- 0x09, 0x06, // USAGE (Keyboard)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x85, 0x02, // REPORT_ID (2)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
- 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x08, // REPORT_COUNT (8)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 0x95, 0x06, // REPORT_COUNT (6)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x65, // LOGICAL_MAXIMUM (101)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
- 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
- 0x81, 0x00, // INPUT (Data,Ary,Abs)
- 0xc0, // END_COLLECTION
- #endif
- #ifdef RAWHID_ENABLED
- // RAW HID
- 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
- 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
- 0xA1, 0x01, // Collection 0x01
- 0x85, 0x03, // REPORT_ID (3)
- 0x75, 0x08, // report size = 8 bits
- 0x15, 0x00, // logical minimum = 0
- 0x26, 0xFF, 0x00, // logical maximum = 255
- 0x95, 64, // report count TX
- 0x09, 0x01, // usage
- 0x81, 0x02, // Input (array)
- 0x95, 64, // report count RX
- 0x09, 0x02, // usage
- 0x91, 0x02, // Output (array)
- 0xC0, // end collection
- #endif
- // *** Here is where the RAW_HID has been converted to a Joystick device
- // *** Inspired by helmpcb.com/electronics/usb-joystick
- // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID
- // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32)
- #ifdef JOYSTICK_ENABLED
- // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis)
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x04, // USAGE (Joystick)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called)
- //Buttons:
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x20, // USAGE_MAXIMUM (Button 32)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x20, // REPORT_COUNT (32)
- 0x55, 0x00, // UNIT_EXPONENT (0)
- 0x65, 0x00, // UNIT (None)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- // 8 bit Throttle and Steering
- 0x05, 0x02, // USAGE_PAGE (Simulation Controls)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0xA1, 0x00, // COLLECTION (Physical)
- 0x09, 0xBB, // USAGE (Throttle)
- 0x09, 0xBA, // USAGE (Steering)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x02, // REPORT_COUNT (2)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0xc0, // END_COLLECTION
- // Two Hat switches
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x39, // USAGE (Hat switch)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x07, // LOGICAL_MAXIMUM (7)
- 0x35, 0x00, // PHYSICAL_MINIMUM (0)
- 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
- 0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
- 0x75, 0x04, // REPORT_SIZE (4)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x09, 0x39, // USAGE (Hat switch)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x07, // LOGICAL_MAXIMUM (7)
- 0x35, 0x00, // PHYSICAL_MINIMUM (0)
- 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
- 0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
- 0x75, 0x04, // REPORT_SIZE (4)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0x75, 0x08, // REPORT_SIZE (8)
- // Axes
- 0x09, 0x01, // USAGE (Pointer)
- 0xA1, 0x00, // COLLECTION (Physical)
- 0x09, 0x30, // USAGE (x)
- 0x09, 0x31, // USAGE (y)
- 0x09, 0x32, // USAGE (z)
- 0x09, 0x33, // USAGE (rx)
- 0x09, 0x34, // USAGE (ry)
- 0x09, 0x35, // USAGE (rz)
- 0x95, 0x06, // REPORT_COUNT (2)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0xc0, // END_COLLECTION
- 0xc0, // END_COLLECTION
- #endif
- #ifdef THUMBSTICK_ENABLED
- // Thumbstick - 2 axis joystick, no buttons
- 0x05, 0x01, // USAGE Page (Generic Desktop)
- 0x09, 0x04, // USAGE (Joystick) /
- 0xa1, 0x01, // COLLECTION (Application)
- 0x85, 0x04, // REPORT_ID
- 0x09, 0x01, // USAGE (Pointer)
- 0xa1, 0x00, // COLLECTION (Physical)
- 0x05, 0x01, // USAGE Page (Generic Desktop)
- 0x09, 0x30, // USAGE (x)
- 0x09, 0x31, // USAGE (y)
- 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768)
- 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
- 0x75, 16, // REPORT_SIZE (16)
- 0x95, 2, // REPORT_COUNT (2)
- 0x81, 0x82, // INPUT (Data, Variable, Absolute, Volatile)
- 0xc0, // END_COLLECTION
- 0xc0, // END_COLLECTION
- #endif
- };
- extern const HIDDescriptor _hidInterface PROGMEM;
- const HIDDescriptor _hidInterface =
- {
- D_INTERFACE(HID_INTERFACE,1,3,0,0),
- D_HIDREPORT(sizeof(_hidReportDescriptor)),
- D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
- };
- //================================================================================
- //================================================================================
- // Driver
- u8 _hid_protocol = 1;
- u8 _hid_idle = 1;
- #define WEAK __attribute__ ((weak))
- int WEAK HID_GetInterface(u8* interfaceNum)
- {
- interfaceNum[0] += 1; // uses 1
- return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface));
- }
- int WEAK HID_GetDescriptor(int i)
- {
- return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
- }
- void WEAK HID_SendReport(u8 id, const void* data, int len)
- {
- USB_Send(HID_TX, &id, 1);
- USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
- }
- bool WEAK HID_Setup(Setup& setup)
- {
- u8 r = setup.bRequest;
- u8 requestType = setup.bmRequestType;
- if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
- {
- if (HID_GET_REPORT == r)
- {
- //HID_GetReport();
- return true;
- }
- if (HID_GET_PROTOCOL == r)
- {
- //Send8(_hid_protocol); // TODO
- return true;
- }
- }
- if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
- {
- if (HID_SET_PROTOCOL == r)
- {
- _hid_protocol = setup.wValueL;
- return true;
- }
- if (HID_SET_IDLE == r)
- {
- _hid_idle = setup.wValueL;
- return true;
- }
- }
- return false;
- }
- //================================================================================
- //================================================================================
- // Joystick
- // Usage: Joystick.move(inputs go here)
- //
- // The report data format must match the one defined in the descriptor exactly
- // or it either won't work, or the pc will make a mess of unpacking the data
- //
- #ifdef JOYSTICK_ENABLED
- Joystick_::Joystick_()
- {
- }
- #define joyBytes 13 // should be equivalent to sizeof(JoyState_t)
- void Joystick_::setState(JoyState_t *joySt)
- {
- uint8_t data[joyBytes];
- uint32_t buttonTmp;
- buttonTmp = joySt->buttons;
- data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB
- buttonTmp >>= 8;
- data[1] = buttonTmp & 0xFF;
- buttonTmp >>= 8;
- data[2] = buttonTmp & 0xFF;
- buttonTmp >>= 8;
- data[3] = buttonTmp & 0xFF;
- data[4] = joySt->throttle; // Throttle
- data[5] = joySt->rudder; // Steering
- data[6] = (joySt->hatSw2 << 4) | joySt->hatSw1; // Pack hat-switch states into a single byte
- data[7] = joySt->xAxis; // X axis
- data[8] = joySt->yAxis; // Y axis
- data[9] = joySt->zAxis; // Z axis
- data[10] = joySt->xRotAxis; // rX axis
- data[11] = joySt->yRotAxis; // rY axis
- data[12] = joySt->zRotAxis; // rZ axis
- //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
- HID_SendReport(3, data, joyBytes);
- // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from
- }
- #endif
- #ifdef THUMBSTICK_ENABLED
- Thumbstick_::Thumbstick_()
- {
- }
- void Thumbstick_::setState(ThumbState_t *thumbSt)
- {
- int16_t data[2];
- data[0] = thumbSt->xAxis; // X axis
- data[1] = thumbSt->yAxis; // Y axis
- //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
- HID_SendReport(4, data, 4);
- }
- #endif
- //================================================================================
- //================================================================================
- // Mouse
- Mouse_::Mouse_(void) : _buttons(0)
- {
- }
- void Mouse_::begin(void)
- {
- }
- void Mouse_::end(void)
- {
- }
- void Mouse_::click(uint8_t b)
- {
- _buttons = b;
- move(0,0,0);
- _buttons = 0;
- move(0,0,0);
- }
- void Mouse_::move(signed char x, signed char y, signed char wheel)
- {
- u8 m[4];
- m[0] = _buttons;
- m[1] = x;
- m[2] = y;
- m[3] = wheel;
- HID_SendReport(1,m,4);
- }
- void Mouse_::buttons(uint8_t b)
- {
- if (b != _buttons)
- {
- _buttons = b;
- move(0,0,0);
- }
- }
- void Mouse_::press(uint8_t b)
- {
- buttons(_buttons | b);
- }
- void Mouse_::release(uint8_t b)
- {
- buttons(_buttons & ~b);
- }
- bool Mouse_::isPressed(uint8_t b)
- {
- if ((b & _buttons) > 0)
- return true;
- return false;
- }
- //================================================================================
- //================================================================================
- // Keyboard
- Keyboard_::Keyboard_(void)
- {
- }
- void Keyboard_::begin(void)
- {
- }
- void Keyboard_::end(void)
- {
- }
- void Keyboard_::sendReport(KeyReport* keys)
- {
- HID_SendReport(2,keys,sizeof(KeyReport));
- }
- extern
- const uint8_t _asciimap[128] PROGMEM;
- #define SHIFT 0x80
- const uint8_t _asciimap[128] =
- {
- 0x00, // NUL
- 0x00, // SOH
- 0x00, // STX
- 0x00, // ETX
- 0x00, // EOT
- 0x00, // ENQ
- 0x00, // ACK
- 0x00, // BEL
- 0x2a, // BS Backspace
- 0x2b, // TAB Tab
- 0x28, // LF Enter
- 0x00, // VT
- 0x00, // FF
- 0x00, // CR
- 0x00, // SO
- 0x00, // SI
- 0x00, // DEL
- 0x00, // DC1
- 0x00, // DC2
- 0x00, // DC3
- 0x00, // DC4
- 0x00, // NAK
- 0x00, // SYN
- 0x00, // ETB
- 0x00, // CAN
- 0x00, // EM
- 0x00, // SUB
- 0x00, // ESC
- 0x00, // FS
- 0x00, // GS
- 0x00, // RS
- 0x00, // US
- 0x2c, // ' '
- 0x1e|SHIFT, // !
- 0x34|SHIFT, // "
- 0x20|SHIFT, // #
- 0x21|SHIFT, // $
- 0x22|SHIFT, // %
- 0x24|SHIFT, // &
- 0x34, // '
- 0x26|SHIFT, // (
- 0x27|SHIFT, // )
- 0x25|SHIFT, // *
- 0x2e|SHIFT, // +
- 0x36, // ,
- 0x2d, // -
- 0x37, // .
- 0x38, // /
- 0x27, // 0
- 0x1e, // 1
- 0x1f, // 2
- 0x20, // 3
- 0x21, // 4
- 0x22, // 5
- 0x23, // 6
- 0x24, // 7
- 0x25, // 8
- 0x26, // 9
- 0x33|SHIFT, // :
- 0x33, // ;
- 0x36|SHIFT, // <
- 0x2e, // =
- 0x37|SHIFT, // >
- 0x38|SHIFT, // ?
- 0x1f|SHIFT, // @
- 0x04|SHIFT, // A
- 0x05|SHIFT, // B
- 0x06|SHIFT, // C
- 0x07|SHIFT, // D
- 0x08|SHIFT, // E
- 0x09|SHIFT, // F
- 0x0a|SHIFT, // G
- 0x0b|SHIFT, // H
- 0x0c|SHIFT, // I
- 0x0d|SHIFT, // J
- 0x0e|SHIFT, // K
- 0x0f|SHIFT, // L
- 0x10|SHIFT, // M
- 0x11|SHIFT, // N
- 0x12|SHIFT, // O
- 0x13|SHIFT, // P
- 0x14|SHIFT, // Q
- 0x15|SHIFT, // R
- 0x16|SHIFT, // S
- 0x17|SHIFT, // T
- 0x18|SHIFT, // U
- 0x19|SHIFT, // V
- 0x1a|SHIFT, // W
- 0x1b|SHIFT, // X
- 0x1c|SHIFT, // Y
- 0x1d|SHIFT, // Z
- 0x2f, // [
- 0x31, // bslash
- 0x30, // ]
- 0x23|SHIFT, // ^
- 0x2d|SHIFT, // _
- 0x35, // `
- 0x04, // a
- 0x05, // b
- 0x06, // c
- 0x07, // d
- 0x08, // e
- 0x09, // f
- 0x0a, // g
- 0x0b, // h
- 0x0c, // i
- 0x0d, // j
- 0x0e, // k
- 0x0f, // l
- 0x10, // m
- 0x11, // n
- 0x12, // o
- 0x13, // p
- 0x14, // q
- 0x15, // r
- 0x16, // s
- 0x17, // t
- 0x18, // u
- 0x19, // v
- 0x1a, // w
- 0x1b, // x
- 0x1c, // y
- 0x1d, // z
- 0x2f|SHIFT, //
- 0x31|SHIFT, // |
- 0x30|SHIFT, // }
- 0x35|SHIFT, // ~
- 0 // DEL
- };
- uint8_t USBPutChar(uint8_t c);
- // press() adds the specified key (printing, non-printing, or modifier)
- // to the persistent key report and sends the report. Because of the way
- // USB HID works, the host acts like the key remains pressed until we
- // call release(), releaseAll(), or otherwise clear the report and resend.
- size_t Keyboard_::press(uint8_t k)
- {
- uint8_t i;
- if (k >= 136) { // it's a non-printing key (not a modifier)
- k = k - 136;
- } else if (k >= 128) { // it's a modifier key
- _keyReport.modifiers |= (1<<(k-128));
- k = 0;
- } else { // it's a printing key
- k = pgm_read_byte(_asciimap + k);
- if (!k) {
- setWriteError();
- return 0;
- }
- if (k & 0x80) { // it's a capital letter or other character reached with shift
- _keyReport.modifiers |= 0x02; // the left shift modifier
- k &= 0x7F;
- }
- }
- // Add k to the key report only if it's not already present
- // and if there is an empty slot.
- if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
- _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
- _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
- for (i=0; i<6; i++) {
- if (_keyReport.keys[i] == 0x00) {
- _keyReport.keys[i] = k;
- break;
- }
- }
- if (i == 6) {
- setWriteError();
- return 0;
- }
- }
- sendReport(&_keyReport);
- return 1;
- }
- // release() takes the specified key out of the persistent key report and
- // sends the report. This tells the OS the key is no longer pressed and that
- // it shouldn't be repeated any more.
- size_t Keyboard_::release(uint8_t k)
- {
- uint8_t i;
- if (k >= 136) { // it's a non-printing key (not a modifier)
- k = k - 136;
- } else if (k >= 128) { // it's a modifier key
- _keyReport.modifiers &= ~(1<<(k-128));
- k = 0;
- } else { // it's a printing key
- k = pgm_read_byte(_asciimap + k);
- if (!k) {
- return 0;
- }
- if (k & 0x80) { // it's a capital letter or other character reached with shift
- _keyReport.modifiers &= ~(0x02); // the left shift modifier
- k &= 0x7F;
- }
- }
- // Test the key report to see if k is present. Clear it if it exists.
- // Check all positions in case the key is present more than once (which it shouldn't be)
- for (i=0; i<6; i++) {
- if (0 != k && _keyReport.keys[i] == k) {
- _keyReport.keys[i] = 0x00;
- }
- }
- sendReport(&_keyReport);
- return 1;
- }
- void Keyboard_::releaseAll(void)
- {
- _keyReport.keys[0] = 0;
- _keyReport.keys[1] = 0;
- _keyReport.keys[2] = 0;
- _keyReport.keys[3] = 0;
- _keyReport.keys[4] = 0;
- _keyReport.keys[5] = 0;
- _keyReport.modifiers = 0;
- sendReport(&_keyReport);
- }
- size_t Keyboard_::write(uint8_t c)
- {
- uint8_t p = press(c); // Keydown
- uint8_t r = release(c); // Keyup
- return (p); // just return the result of press() since release() almost always returns 1
- }
- #endif
- #endif /* if defined(USBCON) */
- And the USBAPI.h:
- #ifndef __USBAPI__
- #define __USBAPI__
- #if defined(USBCON)
- //================================================================================
- //================================================================================
- // USB
- class USBDevice_
- {
- public:
- USBDevice_();
- bool configured();
- void attach();
- void detach(); // Serial port goes down too...
- void poll();
- };
- extern USBDevice_ USBDevice;
- //================================================================================
- //================================================================================
- // Serial over CDC (Serial1 is the physical port)
- class Serial_ : public Stream
- {
- private:
- ring_buffer *_cdc_rx_buffer;
- public:
- void begin(uint16_t baud_count);
- void end(void);
- virtual int available(void);
- virtual void accept(void);
- virtual int peek(void);
- virtual int read(void);
- virtual void flush(void);
- virtual size_t write(uint8_t);
- operator bool();
- };
- extern Serial_ Serial;
- //================================================================================
- //================================================================================
- // Joystick
- // Implemented in HID.cpp
- // The list of parameters here needs to match the implementation in HID.cpp
- typedef struct JoyState // Pretty self explanitory. Simple state to store all the joystick parameters
- {
- uint8_t xAxis;
- uint8_t yAxis;
- uint8_t zAxis;
- uint8_t xRotAxis;
- uint8_t yRotAxis;
- uint8_t zRotAxis;
- uint8_t throttle;
- uint8_t rudder;
- uint8_t hatSw1;
- uint8_t hatSw2;
- uint32_t buttons; // 32 general buttons
- } JoyState_t;
- class Joystick_
- {
- public:
- Joystick_();
- void setState(JoyState_t *joySt);
- };
- extern Joystick_ Joystick;
- //================================================================================
- //================================================================================
- // ThumbStick
- // Implemented in HID.cpp
- // The list of parameters here needs to match the implementation in HID.cpp
- typedef struct ThumbState
- {
- int16_t xAxis;
- int16_t yAxis;
- } ThumbState_t;
- class Thumbstick_
- {
- public:
- Thumbstick_();
- void setState(ThumbState_t *trackSt);
- };
- extern Thumbstick_ Thumbstick;
- //================================================================================
- //================================================================================
- // Mouse
- #define MOUSE_LEFT 1
- #define MOUSE_RIGHT 2
- #define MOUSE_MIDDLE 4
- #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
- class Mouse_
- {
- private:
- uint8_t _buttons;
- void buttons(uint8_t b);
- public:
- Mouse_(void);
- void begin(void);
- void end(void);
- void click(uint8_t b = MOUSE_LEFT);
- void move(signed char x, signed char y, signed char wheel = 0);
- void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
- void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
- bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
- };
- extern Mouse_ Mouse;
- //================================================================================
- //================================================================================
- // Keyboard
- #define KEY_LEFT_CTRL 0x80
- #define KEY_LEFT_SHIFT 0x81
- #define KEY_LEFT_ALT 0x82
- #define KEY_LEFT_GUI 0x83
- #define KEY_RIGHT_CTRL 0x84
- #define KEY_RIGHT_SHIFT 0x85
- #define KEY_RIGHT_ALT 0x86
- #define KEY_RIGHT_GUI 0x87
- #define KEY_UP_ARROW 0xDA
- #define KEY_DOWN_ARROW 0xD9
- #define KEY_LEFT_ARROW 0xD8
- #define KEY_RIGHT_ARROW 0xD7
- #define KEY_BACKSPACE 0xB2
- #define KEY_TAB 0xB3
- #define KEY_RETURN 0xB0
- #define KEY_ESC 0xB1
- #define KEY_INSERT 0xD1
- #define KEY_DELETE 0xD4
- #define KEY_PAGE_UP 0xD3
- #define KEY_PAGE_DOWN 0xD6
- #define KEY_HOME 0xD2
- #define KEY_END 0xD5
- #define KEY_CAPS_LOCK 0xC1
- #define KEY_F1 0xC2
- #define KEY_F2 0xC3
- #define KEY_F3 0xC4
- #define KEY_F4 0xC5
- #define KEY_F5 0xC6
- #define KEY_F6 0xC7
- #define KEY_F7 0xC8
- #define KEY_F8 0xC9
- #define KEY_F9 0xCA
- #define KEY_F10 0xCB
- #define KEY_F11 0xCC
- #define KEY_F12 0xCD
- // Low level key report: up to 6 keys and shift, ctrl etc at once
- typedef struct
- {
- uint8_t modifiers;
- uint8_t reserved;
- uint8_t keys[6];
- } KeyReport;
- class Keyboard_ : public Print
- {
- private:
- KeyReport _keyReport;
- void sendReport(KeyReport* keys);
- public:
- Keyboard_(void);
- void begin(void);
- void end(void);
- virtual size_t write(uint8_t k);
- virtual size_t press(uint8_t k);
- virtual size_t release(uint8_t k);
- virtual void releaseAll(void);
- };
- extern Keyboard_ Keyboard;
- //================================================================================
- //================================================================================
- // Low level API
- typedef struct
- {
- uint8_t bmRequestType;
- uint8_t bRequest;
- uint8_t wValueL;
- uint8_t wValueH;
- uint16_t wIndex;
- uint16_t wLength;
- } Setup;
- //================================================================================
- //================================================================================
- // HID 'Driver'
- int HID_GetInterface(uint8_t* interfaceNum);
- int HID_GetDescriptor(int i);
- bool HID_Setup(Setup& setup);
- void HID_SendReport(uint8_t id, const void* data, int len);
- //================================================================================
- //================================================================================
- // MSC 'Driver'
- int MSC_GetInterface(uint8_t* interfaceNum);
- int MSC_GetDescriptor(int i);
- bool MSC_Setup(Setup& setup);
- bool MSC_Data(uint8_t rx,uint8_t tx);
- //================================================================================
- //================================================================================
- // CSC 'Driver'
- int CDC_GetInterface(uint8_t* interfaceNum);
- int CDC_GetDescriptor(int i);
- bool CDC_Setup(Setup& setup);
- //================================================================================
- //================================================================================
- #define TRANSFER_PGM 0x80
- #define TRANSFER_RELEASE 0x40
- #define TRANSFER_ZERO 0x20
- int USB_SendControl(uint8_t flags, const void* d, int len);
- int USB_RecvControl(void* d, int len);
- uint8_t USB_Available(uint8_t ep);
- int USB_Send(uint8_t ep, const void* data, int len); // blocking
- int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
- int USB_Recv(uint8_t ep); // non-blocking
- void USB_Flush(uint8_t ep);
- #endif
- #endif /* if defined(USBCON) */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement