USBJoystick updated for 32 buttons and added wait-for-connect.

Dependents:   joy2

Committer:
gagarinlg
Date:
Sun Aug 01 17:20:34 2021 +0000
Revision:
3:1f1c9178c55e
Parent:
2:de0ca539fa79
working

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"
gagarinlg 2:de0ca539fa79 29 #include "../buffer_builder.hpp"
wim 0:e086541742c3 30
gagarinlg 3:1f1c9178c55e 31 bool USBJoystick::update(int16_t t, int16_t r, int16_t x, int16_t y, uint16_t z, uint16_t rx, uint16_t ry, uint16_t rz, uint32_t buttons, uint8_t hat) {
wim 0:e086541742c3 32
wim 0:e086541742c3 33 _t = t;
wim 0:e086541742c3 34 _r = r;
wim 0:e086541742c3 35 _x = x;
wim 0:e086541742c3 36 _y = y;
gagarinlg 3:1f1c9178c55e 37 _z = z;
gagarinlg 3:1f1c9178c55e 38 _rx = rx;
gagarinlg 3:1f1c9178c55e 39 _ry = ry;
gagarinlg 3:1f1c9178c55e 40 _rz = rz;
wim 0:e086541742c3 41 _buttons = buttons;
wim 0:e086541742c3 42 _hat = hat;
wim 0:e086541742c3 43
wim 0:e086541742c3 44 return update();
wim 0:e086541742c3 45 }
gagarinlg 3:1f1c9178c55e 46 HID_REPORT report;
wim 0:e086541742c3 47 bool USBJoystick::update() {
gagarinlg 3:1f1c9178c55e 48
wim 0:e086541742c3 49
gagarinlg 2:de0ca539fa79 50 uint8_t* data = &report.data[0];
gagarinlg 2:de0ca539fa79 51 buffer_builder::put_u16le(data, _t);
gagarinlg 2:de0ca539fa79 52 buffer_builder::put_u16le(data, _r);
gagarinlg 2:de0ca539fa79 53 buffer_builder::put_u16le(data, _x);
gagarinlg 2:de0ca539fa79 54 buffer_builder::put_u16le(data, _y);
gagarinlg 3:1f1c9178c55e 55 buffer_builder::put_u32le(data, 0x00);
gagarinlg 3:1f1c9178c55e 56 buffer_builder::put_u16le(data, _z);
gagarinlg 3:1f1c9178c55e 57 buffer_builder::put_u16le(data, _rx);
gagarinlg 3:1f1c9178c55e 58 buffer_builder::put_u16le(data, _ry);
gagarinlg 3:1f1c9178c55e 59 buffer_builder::put_u16le(data, _rz);
gagarinlg 2:de0ca539fa79 60 #if (BUTTONS4 == 1 && 0)
wim 0:e086541742c3 61 //Hat and 4 Buttons
wim 0:e086541742c3 62 // report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;
wim 0:e086541742c3 63 // report.length = 5;
wim 0:e086541742c3 64
wim 0:e086541742c3 65
wim 0:e086541742c3 66 //Use 4 bit padding for hat4 or hat8
gagarinlg 2:de0ca539fa79 67 buffer_builder::put_u8(data, _hat);
wim 0:e086541742c3 68
wim 0:e086541742c3 69 //Use 4 bit padding for buttons
gagarinlg 2:de0ca539fa79 70 buffer_builder::put_u8(data, _buttons);
wim 0:e086541742c3 71 #endif
wim 0:e086541742c3 72
gagarinlg 2:de0ca539fa79 73 #if (BUTTONS8 == 1 && 0)
wim 0:e086541742c3 74 //Hat and first 4 Buttons
wim 0:e086541742c3 75 // report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;
wim 0:e086541742c3 76 //
wim 0:e086541742c3 77 //Use bit padding for last 4 Buttons
wim 0:e086541742c3 78 // report.data[5] = (_buttons & 0xf0) >> 4;
wim 0:e086541742c3 79 // report.length = 6;
wim 0:e086541742c3 80
wim 0:e086541742c3 81 //Use 4 bit padding for hat4 or hat8
gagarinlg 2:de0ca539fa79 82 buffer_builder::put_u8(data, _hat);
wim 0:e086541742c3 83
wim 0:e086541742c3 84 //Use 8 bits for buttons
gagarinlg 2:de0ca539fa79 85 buffer_builder::put_u8(data, _buttons);
wim 0:e086541742c3 86 #endif
wim 0:e086541742c3 87
gagarinlg 2:de0ca539fa79 88 #if (BUTTONS32 == 1 && 0)
wim 0:e086541742c3 89 //Use 4 bit padding for hat4 or hat8
gagarinlg 2:de0ca539fa79 90 // report.data[4] = (_hat & 0x0f) ;
gagarinlg 2:de0ca539fa79 91 // buffer_builder::put_u8(data, _hat);
wim 0:e086541742c3 92
wim 0:e086541742c3 93 //No bit padding for 32 buttons
gagarinlg 2:de0ca539fa79 94 // buffer_builder::put_u32le(data, _buttons);
wim 0:e086541742c3 95 #endif
gagarinlg 2:de0ca539fa79 96 report.length = data - &report.data[0];
wim 0:e086541742c3 97 return send(&report);
wim 0:e086541742c3 98 }
wim 0:e086541742c3 99
wim 0:e086541742c3 100 bool USBJoystick::throttle(int16_t t) {
wim 0:e086541742c3 101 _t = t;
wim 0:e086541742c3 102 return update();
wim 0:e086541742c3 103 }
wim 0:e086541742c3 104
wim 0:e086541742c3 105 bool USBJoystick::rudder(int16_t r) {
wim 0:e086541742c3 106 _r = r;
wim 0:e086541742c3 107 return update();
wim 0:e086541742c3 108 }
wim 0:e086541742c3 109
wim 0:e086541742c3 110 bool USBJoystick::move(int16_t x, int16_t y) {
wim 0:e086541742c3 111 _x = x;
wim 0:e086541742c3 112 _y = y;
wim 0:e086541742c3 113 return update();
wim 0:e086541742c3 114 }
wim 0:e086541742c3 115
wim 0:e086541742c3 116 bool USBJoystick::buttons(uint32_t buttons) {
wim 0:e086541742c3 117 _buttons = buttons;
wim 0:e086541742c3 118 return update();
wim 0:e086541742c3 119 }
wim 0:e086541742c3 120
wim 0:e086541742c3 121 bool USBJoystick::hat(uint8_t hat) {
wim 0:e086541742c3 122 _hat = hat;
wim 0:e086541742c3 123 return update();
wim 0:e086541742c3 124 }
wim 0:e086541742c3 125
wim 0:e086541742c3 126
wim 0:e086541742c3 127 void USBJoystick::_init() {
wim 0:e086541742c3 128 _t = -127;
wim 0:e086541742c3 129 _r = -127;
wim 0:e086541742c3 130 _x = 0;
wim 0:e086541742c3 131 _y = 0;
wim 0:e086541742c3 132 _buttons = 0x00000000;
wim 0:e086541742c3 133 _hat = 0x00;
wim 0:e086541742c3 134 }
wim 0:e086541742c3 135
wim 0:e086541742c3 136
wim 0:e086541742c3 137 uint8_t * USBJoystick::reportDesc() {
wim 0:e086541742c3 138 static uint8_t reportDescriptor[] = {
wim 0:e086541742c3 139
wim 0:e086541742c3 140 USAGE_PAGE(1), 0x01, // Generic Desktop
wim 0:e086541742c3 141 USAGE(1), 0x04, // Usage (Joystick)
wim 0:e086541742c3 142 COLLECTION(1), 0x01, // Application
wim 0:e086541742c3 143 USAGE_PAGE(1), 0x02, // Simulation Controls
wim 0:e086541742c3 144 USAGE(1), 0xBB, // Throttle
gagarinlg 2:de0ca539fa79 145 USAGE(1), 0xBA, // Rudder
gagarinlg 2:de0ca539fa79 146
gagarinlg 2:de0ca539fa79 147 /*
wim 0:e086541742c3 148 LOGICAL_MINIMUM(1), 0x81, // -127
wim 0:e086541742c3 149 LOGICAL_MAXIMUM(1), 0x7f, // 127
wim 0:e086541742c3 150 REPORT_SIZE(1), 0x08,
gagarinlg 2:de0ca539fa79 151 */
gagarinlg 2:de0ca539fa79 152 LOGICAL_MINIMUM(2), 0x01, 0x80, // -32767
gagarinlg 2:de0ca539fa79 153 LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
gagarinlg 2:de0ca539fa79 154 REPORT_SIZE(1), 0x10,
wim 0:e086541742c3 155 REPORT_COUNT(1), 0x02,
gagarinlg 2:de0ca539fa79 156 INPUT(1), 0x02, // Data, Variable, Absolute
gagarinlg 2:de0ca539fa79 157 #if 1
wim 0:e086541742c3 158 USAGE_PAGE(1), 0x01, // Generic Desktop
wim 0:e086541742c3 159 USAGE(1), 0x30, // X
wim 0:e086541742c3 160 USAGE(1), 0x31, // Y
wim 0:e086541742c3 161 // 8 bit values
gagarinlg 2:de0ca539fa79 162 // LOGICAL_MINIMUM(1), 0x81, // -127
gagarinlg 2:de0ca539fa79 163 // LOGICAL_MAXIMUM(1), 0x7f, // 127
gagarinlg 2:de0ca539fa79 164 // REPORT_SIZE(1), 0x08,
gagarinlg 2:de0ca539fa79 165 // REPORT_COUNT(1), 0x04,
gagarinlg 2:de0ca539fa79 166 // INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 167 // 16 bit values
gagarinlg 2:de0ca539fa79 168 LOGICAL_MINIMUM(2), 0x01, 0x80, // -32767
gagarinlg 2:de0ca539fa79 169 LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
gagarinlg 2:de0ca539fa79 170 REPORT_SIZE(1), 0x10,
gagarinlg 3:1f1c9178c55e 171 REPORT_COUNT(1), 0x02,
gagarinlg 2:de0ca539fa79 172 INPUT(1), 0x02, // Data, Variable, Absolute
gagarinlg 3:1f1c9178c55e 173 REPORT_SIZE(1), 0x20,
gagarinlg 3:1f1c9178c55e 174 REPORT_COUNT(1), 0x01,
gagarinlg 3:1f1c9178c55e 175 INPUT(1), 0x01, // Constant
wim 0:e086541742c3 176
gagarinlg 3:1f1c9178c55e 177 USAGE_PAGE(1), 0x01, // Generic Desktop
gagarinlg 3:1f1c9178c55e 178 USAGE(1), 0x32, // Z
gagarinlg 3:1f1c9178c55e 179 USAGE(1), 0x33, // RX
gagarinlg 3:1f1c9178c55e 180 USAGE(1), 0x34, // RY
gagarinlg 3:1f1c9178c55e 181 USAGE(1), 0x35, // Rz
gagarinlg 3:1f1c9178c55e 182 LOGICAL_MINIMUM(2), 0x01, 0x80, // -32767
gagarinlg 3:1f1c9178c55e 183 LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
gagarinlg 3:1f1c9178c55e 184 REPORT_SIZE(1), 0x10,
gagarinlg 3:1f1c9178c55e 185 REPORT_COUNT(1), 0x04,
gagarinlg 3:1f1c9178c55e 186 INPUT(1), 0x02, // Data, Variable, Absolute
gagarinlg 3:1f1c9178c55e 187
gagarinlg 2:de0ca539fa79 188 #endif
gagarinlg 2:de0ca539fa79 189 #if (HAT4 == 1 && 0)
wim 0:e086541742c3 190 // 4 Position Hat Switch
wim 0:e086541742c3 191 USAGE(1), 0x39, // Usage (Hat switch)
wim 0:e086541742c3 192 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 193 LOGICAL_MAXIMUM(1), 0x03, // 3
wim 0:e086541742c3 194 PHYSICAL_MINIMUM(1), 0x00, // Physical_Minimum (0)
wim 0:e086541742c3 195 PHYSICAL_MAXIMUM(2), 0x0E, 0x01, // Physical_Maximum (270)
wim 0:e086541742c3 196 UNIT(1), 0x14, // Unit (Eng Rot:Angular Pos)
wim 0:e086541742c3 197 REPORT_SIZE(1), 0x04,
wim 0:e086541742c3 198 REPORT_COUNT(1), 0x01,
wim 0:e086541742c3 199 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 200 #endif
gagarinlg 2:de0ca539fa79 201 #if (HAT8 == 1 && 0)
wim 0:e086541742c3 202 // 8 Position Hat Switch
wim 0:e086541742c3 203 USAGE(1), 0x39, // Usage (Hat switch)
wim 0:e086541742c3 204 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 205 LOGICAL_MAXIMUM(1), 0x07, // 7
wim 0:e086541742c3 206 PHYSICAL_MINIMUM(1), 0x00, // Physical_Minimum (0)
wim 0:e086541742c3 207 PHYSICAL_MAXIMUM(2), 0x3B, 0x01, // Physical_Maximum (315)
wim 0:e086541742c3 208 UNIT(1), 0x14, // Unit (Eng Rot:Angular Pos)
wim 0:e086541742c3 209 REPORT_SIZE(1), 0x04,
wim 0:e086541742c3 210 REPORT_COUNT(1), 0x01,
wim 0:e086541742c3 211 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 212 #endif
wim 0:e086541742c3 213
wim 0:e086541742c3 214 // Padding 4 bits
gagarinlg 2:de0ca539fa79 215 // REPORT_SIZE(1), 0x01,
gagarinlg 2:de0ca539fa79 216 // REPORT_COUNT(1), 0x04,
gagarinlg 2:de0ca539fa79 217 // INPUT(1), 0x01, // Constant
wim 0:e086541742c3 218
wim 0:e086541742c3 219
wim 0:e086541742c3 220 #if (BUTTONS4 == 1)
wim 0:e086541742c3 221 // 4 Buttons
wim 0:e086541742c3 222 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 223 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 224 USAGE_MAXIMUM(1), 0x04, // 4
wim 0:e086541742c3 225 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 226 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 227 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 228 REPORT_COUNT(1), 0x04,
wim 0:e086541742c3 229 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 230 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 231 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 232
wim 0:e086541742c3 233 // Padding 4 bits
wim 0:e086541742c3 234 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 235 REPORT_COUNT(1), 0x04,
wim 0:e086541742c3 236 INPUT(1), 0x01, // Constant
wim 0:e086541742c3 237
wim 0:e086541742c3 238 #endif
wim 0:e086541742c3 239 #if (BUTTONS8 == 1)
wim 0:e086541742c3 240 // 8 Buttons
wim 0:e086541742c3 241 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 242 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 243 USAGE_MAXIMUM(1), 0x08, // 8
wim 0:e086541742c3 244 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 245 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 246 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 247 REPORT_COUNT(1), 0x08,
wim 0:e086541742c3 248 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 249 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 250 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 251 #endif
wim 0:e086541742c3 252
gagarinlg 2:de0ca539fa79 253 #if (BUTTONS32 == 1 && 0)
wim 0:e086541742c3 254 // 32 Buttons
wim 0:e086541742c3 255 USAGE_PAGE(1), 0x09, // Buttons
wim 0:e086541742c3 256 USAGE_MINIMUM(1), 0x01, // 1
wim 0:e086541742c3 257 USAGE_MAXIMUM(1), 0x20, // 32
wim 0:e086541742c3 258 LOGICAL_MINIMUM(1), 0x00, // 0
wim 0:e086541742c3 259 LOGICAL_MAXIMUM(1), 0x01, // 1
wim 0:e086541742c3 260 REPORT_SIZE(1), 0x01,
wim 0:e086541742c3 261 REPORT_COUNT(1), 0x20,
wim 0:e086541742c3 262 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
wim 0:e086541742c3 263 UNIT(1), 0x00, // Unit (None)
wim 0:e086541742c3 264 INPUT(1), 0x02, // Data, Variable, Absolute
wim 0:e086541742c3 265 #endif
wim 0:e086541742c3 266
wim 0:e086541742c3 267 END_COLLECTION(0)
wim 0:e086541742c3 268 };
wim 0:e086541742c3 269
wim 0:e086541742c3 270 reportLength = sizeof(reportDescriptor);
wim 0:e086541742c3 271 return reportDescriptor;
wim 0:e086541742c3 272 }