|
1 |
| - |
2 |
| - |
3 | 1 | /* Copyright (c) 2011, Peter Barrett
|
4 | 2 | **
|
5 | 3 | ** Permission to use, copy, modify, and/or distribute this software for
|
|
23 | 21 |
|
24 | 22 | //#define RAWHID_ENABLED
|
25 | 23 |
|
26 |
| -// Singletons for mouse and keyboard |
| 24 | +// Singletons for mouse, keyboard and joystick |
27 | 25 |
|
28 | 26 | Mouse_ Mouse;
|
29 | 27 | Keyboard_ Keyboard;
|
| 28 | +Joystick_ Joystick; |
| 29 | +Remote_ Remote; |
30 | 30 |
|
31 | 31 | //================================================================================
|
32 | 32 | //================================================================================
|
@@ -124,6 +124,136 @@ const u8 _hidReportDescriptor[] = {
|
124 | 124 | 0x91, 0x02, // Output (array)
|
125 | 125 | 0xC0 // end collection
|
126 | 126 | #endif
|
| 127 | + // *** Here is where the RAW_HID has been converted to a Joystick device |
| 128 | + // *** Inspired by helmpcb.com/electronics/usb-joystick |
| 129 | + // *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID |
| 130 | + // *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32) |
| 131 | + |
| 132 | + // 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis) |
| 133 | + |
| 134 | + 0x05, 0x01,// USAGE_PAGE (Generic Desktop) |
| 135 | + 0x09, 0x04,// USAGE (Joystick) |
| 136 | + 0xa1, 0x01,// COLLECTION (Application) |
| 137 | + 0x85, 0x03,// REPORT_ID (3) (This is important when HID_SendReport() is called) |
| 138 | + |
| 139 | + //Buttons: |
| 140 | + 0x05, 0x09,// USAGE_PAGE (Button) |
| 141 | + 0x19, 0x01,// USAGE_MINIMUM (Button 1) |
| 142 | + 0x29, 0x20,// USAGE_MAXIMUM (Button 32) |
| 143 | + 0x15, 0x00,// LOGICAL_MINIMUM (0) |
| 144 | + 0x25, 0x01,// LOGICAL_MAXIMUM (1) |
| 145 | + 0x75, 0x01,// REPORT_SIZE (1) |
| 146 | + 0x95, 0x20,// REPORT_COUNT (32) |
| 147 | + 0x55, 0x00,// UNIT_EXPONENT (0) |
| 148 | + 0x65, 0x00,// UNIT (None) |
| 149 | + 0x81, 0x02,// INPUT (Data,Var,Abs) |
| 150 | + |
| 151 | + // 8 bit Throttle and Steering |
| 152 | + 0x05, 0x02,// USAGE_PAGE (Simulation Controls) |
| 153 | + |
| 154 | + 0x15, 0x00,// LOGICAL_MINIMUM (0) |
| 155 | + 0x26, 0xff, 0x00,// LOGICAL_MAXIMUM (255) |
| 156 | + 0xA1, 0x00,// COLLECTION (Physical) |
| 157 | + 0x09, 0xBB,// USAGE (Throttle) |
| 158 | + 0x09, 0xBA,// USAGE (Steering) |
| 159 | + 0x75, 0x08,// REPORT_SIZE (8) |
| 160 | + 0x95, 0x02,// REPORT_COUNT (2) |
| 161 | + 0x81, 0x02,// INPUT (Data,Var,Abs) |
| 162 | + |
| 163 | + 0xc0,// END_COLLECTION |
| 164 | + // Two Hat switches |
| 165 | + |
| 166 | + 0x05, 0x01,// USAGE_PAGE (Generic Desktop) |
| 167 | + |
| 168 | + 0x09, 0x39,// USAGE (Hat switch) |
| 169 | + 0x15, 0x00,// LOGICAL_MINIMUM (0) |
| 170 | + 0x25, 0x07,// LOGICAL_MAXIMUM (7) |
| 171 | + 0x35, 0x00,// PHYSICAL_MINIMUM (0) |
| 172 | + 0x46, 0x3B, 0x01,// PHYSICAL_MAXIMUM (315) |
| 173 | + 0x65, 0x14,// UNIT (Eng Rot:Angular Pos) |
| 174 | + 0x75, 0x04,// REPORT_SIZE (4) |
| 175 | + 0x95, 0x01,// REPORT_COUNT (1) |
| 176 | + 0x81, 0x02,// INPUT (Data,Var,Abs) |
| 177 | + |
| 178 | + 0x09, 0x39,// USAGE (Hat switch) |
| 179 | + 0x15, 0x00,// LOGICAL_MINIMUM (0) |
| 180 | + 0x25, 0x07,// LOGICAL_MAXIMUM (7) |
| 181 | + 0x35, 0x00,// PHYSICAL_MINIMUM (0) |
| 182 | + 0x46, 0x3B, 0x01,// PHYSICAL_MAXIMUM (315) |
| 183 | + 0x65, 0x14,// UNIT (Eng Rot:Angular Pos) |
| 184 | + 0x75, 0x04,// REPORT_SIZE (4) |
| 185 | + 0x95, 0x01,// REPORT_COUNT (1) |
| 186 | + 0x81, 0x02,// INPUT (Data,Var,Abs) |
| 187 | + |
| 188 | + 0x15, 0x00,// LOGICAL_MINIMUM (0) |
| 189 | + 0x26, 0xff, 0x00,// LOGICAL_MAXIMUM (255) |
| 190 | + 0x75, 0x08,// REPORT_SIZE (8) |
| 191 | + |
| 192 | + 0x09, 0x01,// USAGE (Pointer) |
| 193 | + 0xA1, 0x00,// COLLECTION (Physical) |
| 194 | + 0x09, 0x30,// USAGE (x) |
| 195 | + 0x09, 0x31,// USAGE (y) |
| 196 | + 0x09, 0x32,// USAGE (z) |
| 197 | + 0x09, 0x33,// USAGE (rx) |
| 198 | + 0x09, 0x34,// USAGE (ry) |
| 199 | + 0x09, 0x35,// USAGE (rz) |
| 200 | + 0x95, 0x06,// REPORT_COUNT (2) |
| 201 | + 0x81, 0x02,// INPUT (Data,Var,Abs) |
| 202 | + 0xc0,// END_COLLECTION |
| 203 | + |
| 204 | + 0xc0// END_COLLECTION |
| 205 | + |
| 206 | + //----------------------------------------------------------------------------- |
| 207 | + |
| 208 | + /* Cross-platform support for controls found on IR Remotes */ |
| 209 | + |
| 210 | + 0x05, 0x0c, //Usage Page (Consumer Devices) |
| 211 | + 0x09, 0x01, //Usage (Consumer Control) |
| 212 | + 0xa1, 0x01, //Collection (Application) |
| 213 | + 0x85, 0x04, //REPORT_ID (4) |
| 214 | + 0x15, 0x00, //Logical Minimum (0) |
| 215 | + 0x25, 0x01, //Logical Maximum (1) |
| 216 | + 0x09, 0xe9, //Usage (Volume Up) |
| 217 | + 0x09, 0xea, //Usage (Volume Down) |
| 218 | + 0x75, 0x01, //Report Size (1) |
| 219 | + 0x95, 0x02, //Report Count (2) |
| 220 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 221 | + |
| 222 | + 0x09, 0xe2, //Usage (Mute) |
| 223 | + 0x95, 0x01, //Report Count (1) |
| 224 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 225 | + |
| 226 | + 0x09, 0xb0, //Usage (Play) |
| 227 | + 0x95, 0x01, //Report Count (1) |
| 228 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 229 | + |
| 230 | + 0x09, 0xb1, //Usage (Pause) |
| 231 | + 0x95, 0x01, //Report Count (1) |
| 232 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 233 | + |
| 234 | + 0x09, 0xb7, //Usage (Stop) |
| 235 | + 0x95, 0x01, //Report Count (1) |
| 236 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 237 | + |
| 238 | + 0x09, 0xb5, //Usage (Next) |
| 239 | + 0x95, 0x01, //Report Count (1) |
| 240 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 241 | + |
| 242 | + 0x09, 0xb6, //Usage (Previous) |
| 243 | + 0x95, 0x01, //Report Count (1) |
| 244 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 245 | + |
| 246 | + 0x09, 0xb3, //Usage (Fast Forward) |
| 247 | + 0x95, 0x01, //Report Count (1) |
| 248 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 249 | + |
| 250 | + 0x09, 0xb4, //Usage (Rewind) |
| 251 | + 0x95, 0x01, //Report Count (1) |
| 252 | + 0x81, 0x06, //Input (Data, Variable, Relative) |
| 253 | + |
| 254 | + 0x95, 0x06, //Report Count (6) Number of bits remaining in byte |
| 255 | + 0x81, 0x07, //Input (Constant, Variable, Relative) |
| 256 | + 0xc0 //End Collection |
127 | 257 | };
|
128 | 258 |
|
129 | 259 | extern const HIDDescriptor _hidInterface PROGMEM;
|
@@ -195,6 +325,54 @@ bool WEAK HID_Setup(Setup& setup)
|
195 | 325 | return false;
|
196 | 326 | }
|
197 | 327 |
|
| 328 | +//================================================================================ |
| 329 | +//================================================================================ |
| 330 | +//Joystick |
| 331 | +// Usage: Joystick.move(inputs go here) |
| 332 | +// |
| 333 | +// The report data format must match the one defined in the descriptor exactly |
| 334 | +// or it either won't work, or the pc will make a mess of unpacking the data |
| 335 | +// |
| 336 | + |
| 337 | +Joystick_::Joystick_() |
| 338 | +{ |
| 339 | +} |
| 340 | + |
| 341 | + |
| 342 | +#define joyBytes 13 // should be equivalent to sizeof(JoyState_t) |
| 343 | + |
| 344 | +void Joystick_::setState(JoyState_t *joySt) |
| 345 | +{ |
| 346 | + uint8_t data[joyBytes]; |
| 347 | + uint32_t buttonTmp; |
| 348 | + buttonTmp = joySt->buttons; |
| 349 | + |
| 350 | + data[0] = buttonTmp & 0xFF;// Break 32 bit button-state out into 4 bytes, to send over USB |
| 351 | + buttonTmp >>= 8; |
| 352 | + data[1] = buttonTmp & 0xFF; |
| 353 | + buttonTmp >>= 8; |
| 354 | + data[2] = buttonTmp & 0xFF; |
| 355 | + buttonTmp >>= 8; |
| 356 | + data[3] = buttonTmp & 0xFF; |
| 357 | + |
| 358 | + data[4] = joySt->throttle;// Throttle |
| 359 | + data[5] = joySt->rudder;// Steering |
| 360 | + |
| 361 | + data[6] = (joySt->hatSw2 << 4) | joySt->hatSw1;// Pack hat-switch states into a single byte |
| 362 | + |
| 363 | + data[7] = joySt->xAxis;// X axis |
| 364 | + data[8] = joySt->yAxis;// Y axis |
| 365 | + data[9] = joySt->zAxis;// Z axis |
| 366 | + data[10] = joySt->xRotAxis;// rX axis |
| 367 | + data[11] = joySt->yRotAxis;// rY axis |
| 368 | + data[12] = joySt->zRotAxis;// rZ axis |
| 369 | + |
| 370 | + //HID_SendReport(Report number, array of values in same order as HID descriptor, length) |
| 371 | + HID_SendReport(3, data, joyBytes); |
| 372 | + // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from |
| 373 | +} |
| 374 | + |
| 375 | + |
198 | 376 | //================================================================================
|
199 | 377 | //================================================================================
|
200 | 378 | // Mouse
|
@@ -513,6 +691,110 @@ size_t Keyboard_::write(uint8_t c)
|
513 | 691 | return p; // just return the result of press() since release() almost always returns 1
|
514 | 692 | }
|
515 | 693 |
|
| 694 | +//================================================================================ |
| 695 | +//================================================================================ |
| 696 | +//Remote |
| 697 | + |
| 698 | +Remote_::Remote_(void) |
| 699 | +{ |
| 700 | +} |
| 701 | + |
| 702 | +void Remote_::begin(void) |
| 703 | +{ |
| 704 | +} |
| 705 | + |
| 706 | +void Remote_::end(void) |
| 707 | +{ |
| 708 | +} |
| 709 | + |
| 710 | +void Remote_::increase(void) |
| 711 | +{ |
| 712 | + u8 m[2]; |
| 713 | + m[0] = VOLUME_UP; |
| 714 | + m[1] = 0; |
| 715 | + HID_SendReport(4,m,2); |
| 716 | +} |
| 717 | + |
| 718 | +void Remote_::decrease(void) |
| 719 | +{ |
| 720 | + u8 m[2]; |
| 721 | + m[0] = VOLUME_DOWN; |
| 722 | + m[1] = 0; |
| 723 | + HID_SendReport(4,m,2); |
| 724 | +} |
| 725 | + |
| 726 | +void Remote_::mute(void) |
| 727 | +{ |
| 728 | + u8 m[2]; |
| 729 | + m[0] = VOLUME_MUTE; |
| 730 | + m[1] = 0; |
| 731 | + HID_SendReport(4,m,2); |
| 732 | +} |
| 733 | + |
| 734 | +void Remote_::play(void) |
| 735 | +{ |
| 736 | + u8 m[2]; |
| 737 | + m[0] = REMOTE_PLAY; |
| 738 | + m[1] = 0; |
| 739 | + HID_SendReport(4,m,2); |
| 740 | +} |
| 741 | + |
| 742 | +void Remote_::pause(void) |
| 743 | +{ |
| 744 | + u8 m[2]; |
| 745 | + m[0] = REMOTE_PAUSE; |
| 746 | + m[1] = 0; |
| 747 | + HID_SendReport(4,m,2); |
| 748 | +} |
| 749 | + |
| 750 | +void Remote_::stop(void) |
| 751 | +{ |
| 752 | + u8 m[2]; |
| 753 | + m[0] = REMOTE_STOP; |
| 754 | + m[1] = 0; |
| 755 | + HID_SendReport(4,m,2); |
| 756 | +} |
| 757 | + |
| 758 | +void Remote_::next(void) |
| 759 | +{ |
| 760 | + u8 m[2]; |
| 761 | + m[0] = REMOTE_NEXT; |
| 762 | + m[1] = 0; |
| 763 | + HID_SendReport(4,m,2); |
| 764 | +} |
| 765 | + |
| 766 | +void Remote_::previous(void) |
| 767 | +{ |
| 768 | + u8 m[2]; |
| 769 | + m[0] = REMOTE_PREVIOUS; |
| 770 | + m[1] = 0; |
| 771 | + HID_SendReport(4,m,2); |
| 772 | +} |
| 773 | + |
| 774 | +void Remote_::forward(void) |
| 775 | +{ |
| 776 | + u8 m[2]; |
| 777 | + m[0] = 0; |
| 778 | + m[1] = REMOTE_FAST_FORWARD >> 8; |
| 779 | + HID_SendReport(4,m,2); |
| 780 | +} |
| 781 | + |
| 782 | +void Remote_::rewind(void) |
| 783 | +{ |
| 784 | + u8 m[2]; |
| 785 | + m[0] = 0; |
| 786 | + m[1] = REMOTE_REWIND >> 8; |
| 787 | + HID_SendReport(4,m,2); |
| 788 | +} |
| 789 | + |
| 790 | +void Remote_::clear(void) |
| 791 | +{ |
| 792 | + u8 m[2]; |
| 793 | + m[0] = 0; |
| 794 | + m[1] = 0; |
| 795 | + HID_SendReport(4,m,2); |
| 796 | +} |
| 797 | + |
516 | 798 | #endif
|
517 | 799 |
|
518 | 800 | #endif /* if defined(USBCON) */
|
0 commit comments