USB Joystick library, modified to work as a 6 DOF joystick.

Dependents:   USBJoystick_Test

Fork of USBJoystick by Wim Huiskamp

Committer:
smartsystemdesign
Date:
Fri Jan 13 17:11:32 2017 +0000
Revision:
4:0ffbedd2cb73
Parent:
2:1549541d3b4b
Child:
5:767e64df3776
Fixed the joystick axes' LOGICAL_MINIMUM to be -32768, according to the USB HID Descriptor Tool.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:e086541742c3 1 /* mbed USBJoystick Library
wim 0:e086541742c3 2 * Copyright (c) 2012, v01: Initial version, WH,
wim 0:e086541742c3 3 * Modified USBMouse code ARM Limited.
wim 0:e086541742c3 4 * (c) 2010-2011 mbed.org, MIT License
wim 0:e086541742c3 5 * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button
wim 0:e086541742c3 6 *
wim 0:e086541742c3 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:e086541742c3 8 * of this software and associated documentation files (the "Software"), to deal
wim 0:e086541742c3 9 * in the Software without restriction, inclumosig without limitation the rights
wim 0:e086541742c3 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:e086541742c3 11 * copies of the Software, and to permit persons to whom the Software is
wim 0:e086541742c3 12 * furnished to do so, subject to the following conditions:
wim 0:e086541742c3 13 *
wim 0:e086541742c3 14 * The above copyright notice and this permission notice shall be included in
wim 0:e086541742c3 15 * all copies or substantial portions of the Software.
wim 0:e086541742c3 16 *
wim 0:e086541742c3 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:e086541742c3 18 * IMPLIED, INCLUmosiG BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:e086541742c3 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:e086541742c3 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:e086541742c3 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:e086541742c3 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:e086541742c3 23 * THE SOFTWARE.
wim 0:e086541742c3 24 */
wim 0:e086541742c3 25
wim 0:e086541742c3 26
wim 0:e086541742c3 27 #include "stdint.h"
wim 0:e086541742c3 28 #include "USBJoystick.h"
wim 0:e086541742c3 29
smartsystemdesign 2:1549541d3b4b 30 bool USBJoystick::update(int16_t x, int16_t y, int16_t z, int16_t rx, int16_t ry, int16_t rz, uint32_t buttons, uint8_t hat) {
wim 0:e086541742c3 31
wim 0:e086541742c3 32 _x = x;
smartsystemdesign 2:1549541d3b4b 33 _y = y;
smartsystemdesign 2:1549541d3b4b 34 _z = z;
smartsystemdesign 2:1549541d3b4b 35 _rx = rx;
smartsystemdesign 2:1549541d3b4b 36 _ry = ry;
smartsystemdesign 2:1549541d3b4b 37 _rz = rz;
wim 0:e086541742c3 38 _buttons = buttons;
wim 0:e086541742c3 39 _hat = hat;
wim 0:e086541742c3 40
wim 0:e086541742c3 41 return update();
wim 0:e086541742c3 42 }
wim 0:e086541742c3 43
wim 0:e086541742c3 44 bool USBJoystick::update() {
wim 0:e086541742c3 45 HID_REPORT report;
wim 0:e086541742c3 46
wim 0:e086541742c3 47 // Fill the report according to the Joystick Descriptor
smartsystemdesign 2:1549541d3b4b 48 report.data[0] = _x & 0xffff;
smartsystemdesign 2:1549541d3b4b 49 report.data[1] = _y & 0xffff;
smartsystemdesign 2:1549541d3b4b 50 report.data[2] = _z & 0xffff;
smartsystemdesign 2:1549541d3b4b 51 report.data[3] = _rx & 0xffff;
smartsystemdesign 2:1549541d3b4b 52 report.data[4] = _ry & 0xffff;
smartsystemdesign 2:1549541d3b4b 53 report.data[5] = _rz & 0xffff;
wim 0:e086541742c3 54
wim 0:e086541742c3 55 #if (BUTTONS4 == 1)
wim 0:e086541742c3 56 //Hat and 4 Buttons
wim 0:e086541742c3 57 // report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;
wim 0:e086541742c3 58 // report.length = 5;
wim 0:e086541742c3 59
wim 0:e086541742c3 60
wim 0:e086541742c3 61 //Use 4 bit padding for hat4 or hat8
smartsystemdesign 2:1549541d3b4b 62 report.data[6] = (_hat & 0x0f) ;
wim 0:e086541742c3 63
wim 0:e086541742c3 64 //Use 4 bit padding for buttons
smartsystemdesign 2:1549541d3b4b 65 report.data[7] = (_buttons & 0x0f) ;
smartsystemdesign 2:1549541d3b4b 66 report.length = 8;
wim 0:e086541742c3 67 #endif
wim 0:e086541742c3 68
wim 0:e086541742c3 69 #if (BUTTONS8 == 1)
wim 0:e086541742c3 70 //Hat and first 4 Buttons
wim 0:e086541742c3 71 // report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;
wim 0:e086541742c3 72 //
wim 0:e086541742c3 73 //Use bit padding for last 4 Buttons
wim 0:e086541742c3 74 // report.data[5] = (_buttons & 0xf0) >> 4;
wim 0:e086541742c3 75 // report.length = 6;
wim 0:e086541742c3 76
wim 0:e086541742c3 77 //Use 4 bit padding for hat4 or hat8
smartsystemdesign 2:1549541d3b4b 78 report.data[6] = (_hat & 0x0f) ;
wim 0:e086541742c3 79
wim 0:e086541742c3 80 //Use 8 bits for buttons
smartsystemdesign 2:1549541d3b4b 81 report.data[7] = (_buttons & 0xff) ;
smartsystemdesign 2:1549541d3b4b 82 report.length = 8;
wim 0:e086541742c3 83 #endif
wim 0:e086541742c3 84
wim 0:e086541742c3 85 #if (BUTTONS32 == 1)
wim 0:e086541742c3 86 //Use 4 bit padding for hat4 or hat8
smartsystemdesign 2:1549541d3b4b 87 report.data[6] = (_hat & 0x0f) ;
wim 0:e086541742c3 88
wim 0:e086541742c3 89 //No bit padding for 32 buttons
smartsystemdesign 2:1549541d3b4b 90 report.data[7] = (_buttons >> 0) & 0xff;
smartsystemdesign 2:1549541d3b4b 91 report.data[8] = (_buttons >> 8) & 0xff;
smartsystemdesign 2:1549541d3b4b 92 report.data[9] = (_buttons >> 16) & 0xff;
smartsystemdesign 2:1549541d3b4b 93 report.data[10] = (_buttons >> 24) & 0xff;
smartsystemdesign 2:1549541d3b4b 94 report.length = 11;
wim 0:e086541742c3 95 #endif
wim 0:e086541742c3 96
wim 0:e086541742c3 97 return send(&report);
wim 0:e086541742c3 98 }
wim 0:e086541742c3 99
smartsystemdesign 2:1549541d3b4b 100 bool USBJoystick::move(int16_t x, int16_t y, int16_t z, int16_t rx, int16_t ry, int16_t rz) {
wim 0:e086541742c3 101 _x = x;
wim 0:e086541742c3 102 _y = y;
smartsystemdesign 2:1549541d3b4b 103 _z = z;
smartsystemdesign 2:1549541d3b4b 104 _rx = rx;
smartsystemdesign 2:1549541d3b4b 105 _ry = ry;
smartsystemdesign 2:1549541d3b4b 106 _rz = rz;
wim 0:e086541742c3 107 return update();
wim 0:e086541742c3 108 }
wim 0:e086541742c3 109
wim 0:e086541742c3 110 bool USBJoystick::buttons(uint32_t buttons) {
wim 0:e086541742c3 111 _buttons = buttons;
wim 0:e086541742c3 112 return update();
wim 0:e086541742c3 113 }
wim 0:e086541742c3 114
wim 0:e086541742c3 115 bool USBJoystick::hat(uint8_t hat) {
wim 0:e086541742c3 116 _hat = hat;
wim 0:e086541742c3 117 return update();
wim 0:e086541742c3 118 }
wim 0:e086541742c3 119
wim 0:e086541742c3 120 void USBJoystick::_init() {
smartsystemdesign 2:1549541d3b4b 121 _x = 0x0000;
smartsystemdesign 2:1549541d3b4b 122 _y = 0x0000;
smartsystemdesign 2:1549541d3b4b 123 _z = 0x0000;
smartsystemdesign 2:1549541d3b4b 124 _rx = 0x0000;
smartsystemdesign 2:1549541d3b4b 125 _ry = 0x0000;
smartsystemdesign 2:1549541d3b4b 126 _rz = 0x0000;
wim 0:e086541742c3 127 _buttons = 0x00000000;
wim 0:e086541742c3 128 _hat = 0x00;
wim 0:e086541742c3 129 }
wim 0:e086541742c3 130
wim 0:e086541742c3 131
wim 0:e086541742c3 132 uint8_t * USBJoystick::reportDesc() {
wim 0:e086541742c3 133 static uint8_t reportDescriptor[] = {
smartsystemdesign 2:1549541d3b4b 134 // value in () is the number of bytes. These bytes follow the comma, least significant byte first
smartsystemdesign 2:1549541d3b4b 135 // see USBHID_Types.h for more info
wim 0:e086541742c3 136 USAGE_PAGE(1), 0x01, // Generic Desktop
wim 0:e086541742c3 137 LOGICAL_MINIMUM(1), 0x00, // Logical_Minimum (0)
wim 0:e086541742c3 138 USAGE(1), 0x04, // Usage (Joystick)
wim 0:e086541742c3 139 COLLECTION(1), 0x01, // Application
smartsystemdesign 2:1549541d3b4b 140
smartsystemdesign 2:1549541d3b4b 141 // 6 Axes of Joystick
wim 0:e086541742c3 142 USAGE_PAGE(1), 0x01, // Generic Desktop
wim 0:e086541742c3 143 USAGE(1), 0x01, // Usage (Pointer)
wim 0:e086541742c3 144 COLLECTION(1), 0x00, // Physical
wim 0:e086541742c3 145 USAGE(1), 0x30, // X
wim 0:e086541742c3 146 USAGE(1), 0x31, // Y
smartsystemdesign 2:1549541d3b4b 147 USAGE(1), 0x32, // Z
smartsystemdesign 2:1549541d3b4b 148 USAGE(1), 0x33, // RX
smartsystemdesign 2:1549541d3b4b 149 USAGE(1), 0x34, // RY
smartsystemdesign 2:1549541d3b4b 150 USAGE(1), 0x35, // RZ
smartsystemdesign 4:0ffbedd2cb73 151 LOGICAL_MINIMUM(2), 0x00, 0x80, // -32768 (using 2's complement)
smartsystemdesign 2:1549541d3b4b 152 LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767 (0x7fff, least significant byte first)
smartsystemdesign 2:1549541d3b4b 153 REPORT_SIZE(1), 0x10, // REPORT_SIZE describes the number of bits in this element (16, in this case)
smartsystemdesign 2:1549541d3b4b 154 REPORT_COUNT(1), 0x06,
smartsystemdesign 1:8b5f213b169f 155 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 156 END_COLLECTION(0),
wim 0:e086541742c3 157
wim 0:e086541742c3 158 #if (HAT4 == 1)
wim 0:e086541742c3 159 // 4 Position Hat Switch
wim 0:e086541742c3 160 USAGE(1), 0x39, // Usage (Hat switch)
wim 0:e086541742c3 161 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 162 LOGICAL_MAXIMUM(1), 0x03, // 3
wim 0:e086541742c3 163 PHYSICAL_MINIMUM(1), 0x00, // Physical_Minimum (0)
wim 0:e086541742c3 164 PHYSICAL_MAXIMUM(2), 0x0E, 0x01, // Physical_Maximum (270)
wim 0:e086541742c3 165 UNIT(1), 0x14, // Unit (Eng Rot:Angular Pos)
wim 0:e086541742c3 166 REPORT_SIZE(1), 0x04,
wim 0:e086541742c3 167 REPORT_COUNT(1), 0x01,
wim 0:e086541742c3 168 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 169 #endif
wim 0:e086541742c3 170 #if (HAT8 == 1)
wim 0:e086541742c3 171 // 8 Position Hat Switch
wim 0:e086541742c3 172 USAGE(1), 0x39, // Usage (Hat switch)
wim 0:e086541742c3 173 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 174 LOGICAL_MAXIMUM(1), 0x07, // 7
wim 0:e086541742c3 175 PHYSICAL_MINIMUM(1), 0x00, // Physical_Minimum (0)
wim 0:e086541742c3 176 PHYSICAL_MAXIMUM(2), 0x3B, 0x01, // Physical_Maximum (315)
wim 0:e086541742c3 177 UNIT(1), 0x14, // Unit (Eng Rot:Angular Pos)
wim 0:e086541742c3 178 REPORT_SIZE(1), 0x04,
wim 0:e086541742c3 179 REPORT_COUNT(1), 0x01,
wim 0:e086541742c3 180 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 181 #endif
wim 0:e086541742c3 182
wim 0:e086541742c3 183 // Padding 4 bits
wim 0:e086541742c3 184 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 185 REPORT_COUNT(1), 0x04,
wim 0:e086541742c3 186 INPUT(1), 0x01, // Constant
wim 0:e086541742c3 187
wim 0:e086541742c3 188
wim 0:e086541742c3 189 #if (BUTTONS4 == 1)
wim 0:e086541742c3 190 // 4 Buttons
wim 0:e086541742c3 191 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 192 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 193 USAGE_MAXIMUM(1), 0x04, // 4
wim 0:e086541742c3 194 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 195 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 196 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 197 REPORT_COUNT(1), 0x04,
wim 0:e086541742c3 198 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 199 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 200 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 201
wim 0:e086541742c3 202 // Padding 4 bits
wim 0:e086541742c3 203 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 204 REPORT_COUNT(1), 0x04,
wim 0:e086541742c3 205 INPUT(1), 0x01, // Constant
wim 0:e086541742c3 206
wim 0:e086541742c3 207 #endif
wim 0:e086541742c3 208 #if (BUTTONS8 == 1)
wim 0:e086541742c3 209 // 8 Buttons
wim 0:e086541742c3 210 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 211 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 212 USAGE_MAXIMUM(1), 0x08, // 8
wim 0:e086541742c3 213 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 214 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 215 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 216 REPORT_COUNT(1), 0x08,
wim 0:e086541742c3 217 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 218 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 219 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 220 #endif
wim 0:e086541742c3 221
wim 0:e086541742c3 222 #if (BUTTONS32 == 1)
wim 0:e086541742c3 223 // 32 Buttons
wim 0:e086541742c3 224 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 225 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 226 USAGE_MAXIMUM(1), 0x20, // 32
wim 0:e086541742c3 227 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 228 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 229 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 230 REPORT_COUNT(1), 0x20,
wim 0:e086541742c3 231 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 232 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 233 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 234 #endif
wim 0:e086541742c3 235
wim 0:e086541742c3 236 END_COLLECTION(0)
wim 0:e086541742c3 237 };
wim 0:e086541742c3 238
wim 0:e086541742c3 239 reportLength = sizeof(reportDescriptor);
wim 0:e086541742c3 240 return reportDescriptor;
wim 0:e086541742c3 241 }