Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Thu Dec 24 01:37:40 2015 +0000
Revision:
37:ed52738445fc
Parent:
35:e959ffba78fd
Child:
38:091e511ce8a0
Bug fixes to USB HAL

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 3:3514575d4f86 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
mjr 3:3514575d4f86 2 * Modified Mouse code for Joystick - WH 2012
mjr 3:3514575d4f86 3 *
mjr 3:3514575d4f86 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mjr 3:3514575d4f86 5 * and associated documentation files (the "Software"), to deal in the Software without
mjr 3:3514575d4f86 6 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
mjr 3:3514575d4f86 7 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
mjr 3:3514575d4f86 8 * Software is furnished to do so, subject to the following conditions:
mjr 3:3514575d4f86 9 *
mjr 3:3514575d4f86 10 * The above copyright notice and this permission notice shall be included in all copies or
mjr 3:3514575d4f86 11 * substantial portions of the Software.
mjr 3:3514575d4f86 12 *
mjr 3:3514575d4f86 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mjr 3:3514575d4f86 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mjr 3:3514575d4f86 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mjr 3:3514575d4f86 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mjr 3:3514575d4f86 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mjr 3:3514575d4f86 18 */
mjr 3:3514575d4f86 19
mjr 3:3514575d4f86 20 #include "stdint.h"
mjr 3:3514575d4f86 21 #include "USBJoystick.h"
mjr 21:5048e16cc9ef 22
mjr 21:5048e16cc9ef 23 #include "config.h" // Pinscape configuration
mjr 21:5048e16cc9ef 24
mjr 35:e959ffba78fd 25
mjr 35:e959ffba78fd 26
mjr 21:5048e16cc9ef 27 // Length of our joystick reports. Important: This must be kept in sync
mjr 21:5048e16cc9ef 28 // with the actual joystick report format sent in update().
mjr 21:5048e16cc9ef 29 const int reportLen = 14;
mjr 21:5048e16cc9ef 30
mjr 11:bd9da7088e6e 31 bool USBJoystick::update(int16_t x, int16_t y, int16_t z, uint32_t buttons, uint16_t status)
mjr 3:3514575d4f86 32 {
mjr 3:3514575d4f86 33 _x = x;
mjr 3:3514575d4f86 34 _y = y;
mjr 3:3514575d4f86 35 _z = z;
mjr 11:bd9da7088e6e 36 _buttonsLo = (uint16_t)(buttons & 0xffff);
mjr 11:bd9da7088e6e 37 _buttonsHi = (uint16_t)((buttons >> 16) & 0xffff);
mjr 10:976666ffa4ef 38 _status = status;
mjr 3:3514575d4f86 39
mjr 3:3514575d4f86 40 // send the report
mjr 3:3514575d4f86 41 return update();
mjr 3:3514575d4f86 42 }
mjr 35:e959ffba78fd 43
mjr 11:bd9da7088e6e 44 bool USBJoystick::update()
mjr 11:bd9da7088e6e 45 {
mjr 3:3514575d4f86 46 HID_REPORT report;
mjr 11:bd9da7088e6e 47
mjr 3:3514575d4f86 48 // Fill the report according to the Joystick Descriptor
mjr 6:cc35eb643e8f 49 #define put(idx, val) (report.data[idx] = (val) & 0xff, report.data[(idx)+1] = ((val) >> 8) & 0xff)
mjr 10:976666ffa4ef 50 put(0, _status);
mjr 10:976666ffa4ef 51 put(2, 0); // second byte of status isn't used in normal reports
mjr 11:bd9da7088e6e 52 put(4, _buttonsLo);
mjr 11:bd9da7088e6e 53 put(6, _buttonsHi);
mjr 11:bd9da7088e6e 54 put(8, _x);
mjr 11:bd9da7088e6e 55 put(10, _y);
mjr 11:bd9da7088e6e 56 put(12, _z);
mjr 21:5048e16cc9ef 57
mjr 21:5048e16cc9ef 58 // important: keep reportLen in sync with the actual byte length of
mjr 21:5048e16cc9ef 59 // the reports we build here
mjr 11:bd9da7088e6e 60 report.length = reportLen;
mjr 3:3514575d4f86 61
mjr 5:a70c0bce770d 62 // send the report
mjr 10:976666ffa4ef 63 return sendTO(&report, 100);
mjr 10:976666ffa4ef 64 }
mjr 10:976666ffa4ef 65
mjr 35:e959ffba78fd 66 bool USBJoystick::kbUpdate(uint8_t data[8])
mjr 35:e959ffba78fd 67 {
mjr 35:e959ffba78fd 68 // set up the report
mjr 35:e959ffba78fd 69 HID_REPORT report;
mjr 35:e959ffba78fd 70 report.data[0] = REPORT_ID_KB; // report ID = keyboard
mjr 35:e959ffba78fd 71 memcpy(&report.data[1], data, 8); // copy the kb report data
mjr 35:e959ffba78fd 72 report.length = 9; // length = ID prefix + kb report length
mjr 35:e959ffba78fd 73
mjr 35:e959ffba78fd 74 // send it to endpoint 4 (the keyboard interface endpoint)
mjr 35:e959ffba78fd 75 return writeTO(EP4IN, report.data, report.length, MAX_PACKET_SIZE_EPINT, 100);
mjr 35:e959ffba78fd 76 }
mjr 35:e959ffba78fd 77
mjr 35:e959ffba78fd 78 bool USBJoystick::mediaUpdate(uint8_t data)
mjr 35:e959ffba78fd 79 {
mjr 35:e959ffba78fd 80 // set up the report
mjr 35:e959ffba78fd 81 HID_REPORT report;
mjr 35:e959ffba78fd 82 report.data[0] = REPORT_ID_MEDIA; // report ID = media
mjr 35:e959ffba78fd 83 report.data[1] = data; // key pressed bits
mjr 35:e959ffba78fd 84 report.length = 2;
mjr 35:e959ffba78fd 85
mjr 35:e959ffba78fd 86 // send it
mjr 35:e959ffba78fd 87 return writeTO(EP4IN, report.data, report.length, MAX_PACKET_SIZE_EPINT, 100);
mjr 35:e959ffba78fd 88 }
mjr 35:e959ffba78fd 89
mjr 10:976666ffa4ef 90 bool USBJoystick::updateExposure(int &idx, int npix, const uint16_t *pix)
mjr 10:976666ffa4ef 91 {
mjr 10:976666ffa4ef 92 HID_REPORT report;
mjr 10:976666ffa4ef 93
mjr 10:976666ffa4ef 94 // Set the special status bits to indicate it's an exposure report.
mjr 10:976666ffa4ef 95 // The high 5 bits of the status word are set to 10000, and the
mjr 10:976666ffa4ef 96 // low 11 bits are the current pixel index.
mjr 10:976666ffa4ef 97 uint16_t s = idx | 0x8000;
mjr 10:976666ffa4ef 98 put(0, s);
mjr 25:e22b88bd783a 99
mjr 25:e22b88bd783a 100 // start at the second byte
mjr 25:e22b88bd783a 101 int ofs = 2;
mjr 25:e22b88bd783a 102
mjr 25:e22b88bd783a 103 // in the first report, add the total pixel count as the next two bytes
mjr 25:e22b88bd783a 104 if (idx == 0)
mjr 25:e22b88bd783a 105 {
mjr 25:e22b88bd783a 106 put(ofs, npix);
mjr 25:e22b88bd783a 107 ofs += 2;
mjr 25:e22b88bd783a 108 }
mjr 10:976666ffa4ef 109
mjr 10:976666ffa4ef 110 // now fill out the remaining words with exposure values
mjr 11:bd9da7088e6e 111 report.length = reportLen;
mjr 25:e22b88bd783a 112 for ( ; ofs + 1 < report.length ; ofs += 2)
mjr 10:976666ffa4ef 113 {
mjr 10:976666ffa4ef 114 uint16_t p = (idx < npix ? pix[idx++] : 0);
mjr 10:976666ffa4ef 115 put(ofs, p);
mjr 10:976666ffa4ef 116 }
mjr 10:976666ffa4ef 117
mjr 10:976666ffa4ef 118 // send the report
mjr 35:e959ffba78fd 119 return sendTO(&report, 100);
mjr 3:3514575d4f86 120 }
mjr 9:fd65b0a94720 121
mjr 35:e959ffba78fd 122 bool USBJoystick::reportConfig(int numOutputs, int unitNo, int plungerZero, int plungerMax)
mjr 33:d832bcab089e 123 {
mjr 33:d832bcab089e 124 HID_REPORT report;
mjr 33:d832bcab089e 125
mjr 33:d832bcab089e 126 // initially fill the report with zeros
mjr 33:d832bcab089e 127 memset(report.data, 0, sizeof(report.data));
mjr 33:d832bcab089e 128
mjr 33:d832bcab089e 129 // Set the special status bits to indicate that it's a config report.
mjr 33:d832bcab089e 130 uint16_t s = 0x8800;
mjr 33:d832bcab089e 131 put(0, s);
mjr 33:d832bcab089e 132
mjr 33:d832bcab089e 133 // write the number of configured outputs
mjr 33:d832bcab089e 134 put(2, numOutputs);
mjr 33:d832bcab089e 135
mjr 33:d832bcab089e 136 // write the unit number
mjr 33:d832bcab089e 137 put(4, unitNo);
mjr 33:d832bcab089e 138
mjr 35:e959ffba78fd 139 // write the plunger zero and max values
mjr 35:e959ffba78fd 140 put(6, plungerZero);
mjr 35:e959ffba78fd 141 put(8, plungerMax);
mjr 35:e959ffba78fd 142
mjr 33:d832bcab089e 143 // send the report
mjr 33:d832bcab089e 144 report.length = reportLen;
mjr 35:e959ffba78fd 145 return sendTO(&report, 100);
mjr 33:d832bcab089e 146 }
mjr 33:d832bcab089e 147
mjr 33:d832bcab089e 148 bool USBJoystick::move(int16_t x, int16_t y)
mjr 33:d832bcab089e 149 {
mjr 3:3514575d4f86 150 _x = x;
mjr 3:3514575d4f86 151 _y = y;
mjr 3:3514575d4f86 152 return update();
mjr 3:3514575d4f86 153 }
mjr 3:3514575d4f86 154
mjr 33:d832bcab089e 155 bool USBJoystick::setZ(int16_t z)
mjr 33:d832bcab089e 156 {
mjr 3:3514575d4f86 157 _z = z;
mjr 3:3514575d4f86 158 return update();
mjr 3:3514575d4f86 159 }
mjr 3:3514575d4f86 160
mjr 33:d832bcab089e 161 bool USBJoystick::buttons(uint32_t buttons)
mjr 33:d832bcab089e 162 {
mjr 11:bd9da7088e6e 163 _buttonsLo = (uint16_t)(buttons & 0xffff);
mjr 11:bd9da7088e6e 164 _buttonsHi = (uint16_t)((buttons >> 16) & 0xffff);
mjr 3:3514575d4f86 165 return update();
mjr 3:3514575d4f86 166 }
mjr 21:5048e16cc9ef 167
mjr 21:5048e16cc9ef 168 bool USBJoystick::updateStatus(uint32_t status)
mjr 21:5048e16cc9ef 169 {
mjr 21:5048e16cc9ef 170 HID_REPORT report;
mjr 21:5048e16cc9ef 171
mjr 21:5048e16cc9ef 172 // Fill the report according to the Joystick Descriptor
mjr 21:5048e16cc9ef 173 #define put(idx, val) (report.data[idx] = (val) & 0xff, report.data[(idx)+1] = ((val) >> 8) & 0xff)
mjr 21:5048e16cc9ef 174 memset(report.data, 0, reportLen);
mjr 21:5048e16cc9ef 175 put(0, status);
mjr 21:5048e16cc9ef 176 report.length = reportLen;
mjr 21:5048e16cc9ef 177
mjr 21:5048e16cc9ef 178 // send the report
mjr 21:5048e16cc9ef 179 return sendTO(&report, 100);
mjr 21:5048e16cc9ef 180 }
mjr 21:5048e16cc9ef 181
mjr 3:3514575d4f86 182 void USBJoystick::_init() {
mjr 3:3514575d4f86 183
mjr 3:3514575d4f86 184 _x = 0;
mjr 3:3514575d4f86 185 _y = 0;
mjr 3:3514575d4f86 186 _z = 0;
mjr 11:bd9da7088e6e 187 _buttonsLo = 0x0000;
mjr 11:bd9da7088e6e 188 _buttonsHi = 0x0000;
mjr 9:fd65b0a94720 189 _status = 0;
mjr 3:3514575d4f86 190 }
mjr 3:3514575d4f86 191
mjr 3:3514575d4f86 192
mjr 35:e959ffba78fd 193 // --------------------------------------------------------------------------
mjr 35:e959ffba78fd 194 //
mjr 35:e959ffba78fd 195 // USB HID Report Descriptor - Joystick
mjr 35:e959ffba78fd 196 //
mjr 35:e959ffba78fd 197 static uint8_t reportDescriptorJS[] =
mjr 35:e959ffba78fd 198 {
mjr 35:e959ffba78fd 199 USAGE_PAGE(1), 0x01, // Generic desktop
mjr 35:e959ffba78fd 200 USAGE(1), 0x04, // Joystick
mjr 35:e959ffba78fd 201 COLLECTION(1), 0x01, // Application
mjr 35:e959ffba78fd 202
mjr 35:e959ffba78fd 203 // input report (device to host)
mjr 35:e959ffba78fd 204
mjr 35:e959ffba78fd 205 USAGE_PAGE(1), 0x06, // generic device controls - for config status
mjr 35:e959ffba78fd 206 USAGE(1), 0x00, // undefined device control
mjr 35:e959ffba78fd 207 LOGICAL_MINIMUM(1), 0x00, // 8-bit values
mjr 35:e959ffba78fd 208 LOGICAL_MAXIMUM(1), 0xFF,
mjr 35:e959ffba78fd 209 REPORT_SIZE(1), 0x08, // 8 bits per report
mjr 35:e959ffba78fd 210 REPORT_COUNT(1), 0x04, // 4 reports (4 bytes)
mjr 35:e959ffba78fd 211 INPUT(1), 0x02, // Data, Variable, Absolute
mjr 35:e959ffba78fd 212
mjr 35:e959ffba78fd 213 USAGE_PAGE(1), 0x09, // Buttons
mjr 35:e959ffba78fd 214 USAGE_MINIMUM(1), 0x01, // { buttons }
mjr 35:e959ffba78fd 215 USAGE_MAXIMUM(1), 0x20, // { 1-32 }
mjr 35:e959ffba78fd 216 LOGICAL_MINIMUM(1), 0x00, // 1-bit buttons - 0...
mjr 35:e959ffba78fd 217 LOGICAL_MAXIMUM(1), 0x01, // ...to 1
mjr 35:e959ffba78fd 218 REPORT_SIZE(1), 0x01, // 1 bit per report
mjr 35:e959ffba78fd 219 REPORT_COUNT(1), 0x20, // 32 reports
mjr 35:e959ffba78fd 220 UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
mjr 35:e959ffba78fd 221 UNIT(1), 0x00, // Unit (None)
mjr 35:e959ffba78fd 222 INPUT(1), 0x02, // Data, Variable, Absolute
mjr 35:e959ffba78fd 223
mjr 35:e959ffba78fd 224 USAGE_PAGE(1), 0x01, // Generic desktop
mjr 35:e959ffba78fd 225 USAGE(1), 0x30, // X axis
mjr 35:e959ffba78fd 226 USAGE(1), 0x31, // Y axis
mjr 35:e959ffba78fd 227 USAGE(1), 0x32, // Z axis
mjr 35:e959ffba78fd 228 LOGICAL_MINIMUM(2), 0x00,0xF0, // each value ranges -4096
mjr 35:e959ffba78fd 229 LOGICAL_MAXIMUM(2), 0x00,0x10, // ...to +4096
mjr 35:e959ffba78fd 230 REPORT_SIZE(1), 0x10, // 16 bits per report
mjr 35:e959ffba78fd 231 REPORT_COUNT(1), 0x03, // 3 reports (X, Y, Z)
mjr 35:e959ffba78fd 232 INPUT(1), 0x02, // Data, Variable, Absolute
mjr 9:fd65b0a94720 233
mjr 35:e959ffba78fd 234 // output report (host to device)
mjr 35:e959ffba78fd 235 REPORT_SIZE(1), 0x08, // 8 bits per report
mjr 35:e959ffba78fd 236 REPORT_COUNT(1), 0x08, // output report count - 8-byte LedWiz format
mjr 35:e959ffba78fd 237 0x09, 0x01, // usage
mjr 35:e959ffba78fd 238 0x91, 0x01, // Output (array)
mjr 35:e959ffba78fd 239
mjr 35:e959ffba78fd 240 END_COLLECTION(0)
mjr 35:e959ffba78fd 241 };
mjr 35:e959ffba78fd 242
mjr 35:e959ffba78fd 243 //
mjr 35:e959ffba78fd 244 // USB HID Report Descriptor - Keyboard/Media Control
mjr 35:e959ffba78fd 245 //
mjr 35:e959ffba78fd 246 static uint8_t reportDescriptorKB[] =
mjr 35:e959ffba78fd 247 {
mjr 35:e959ffba78fd 248 USAGE_PAGE(1), 0x01, // Generic Desktop
mjr 35:e959ffba78fd 249 USAGE(1), 0x06, // Keyboard
mjr 35:e959ffba78fd 250 COLLECTION(1), 0x01, // Application
mjr 35:e959ffba78fd 251 REPORT_ID(1), REPORT_ID_KB,
mjr 10:976666ffa4ef 252
mjr 35:e959ffba78fd 253 USAGE_PAGE(1), 0x07, // Key Codes
mjr 35:e959ffba78fd 254 USAGE_MINIMUM(1), 0xE0,
mjr 35:e959ffba78fd 255 USAGE_MAXIMUM(1), 0xE7,
mjr 35:e959ffba78fd 256 LOGICAL_MINIMUM(1), 0x00,
mjr 35:e959ffba78fd 257 LOGICAL_MAXIMUM(1), 0x01,
mjr 35:e959ffba78fd 258 REPORT_SIZE(1), 0x01,
mjr 35:e959ffba78fd 259 REPORT_COUNT(1), 0x08,
mjr 35:e959ffba78fd 260 INPUT(1), 0x02, // Data, Variable, Absolute
mjr 35:e959ffba78fd 261 REPORT_COUNT(1), 0x01,
mjr 35:e959ffba78fd 262 REPORT_SIZE(1), 0x08,
mjr 35:e959ffba78fd 263 INPUT(1), 0x01, // Constant
mjr 35:e959ffba78fd 264
mjr 35:e959ffba78fd 265 REPORT_COUNT(1), 0x05,
mjr 35:e959ffba78fd 266 REPORT_SIZE(1), 0x01,
mjr 35:e959ffba78fd 267 USAGE_PAGE(1), 0x08, // LEDs
mjr 35:e959ffba78fd 268 USAGE_MINIMUM(1), 0x01,
mjr 35:e959ffba78fd 269 USAGE_MAXIMUM(1), 0x05,
mjr 35:e959ffba78fd 270 OUTPUT(1), 0x02, // Data, Variable, Absolute
mjr 35:e959ffba78fd 271 REPORT_COUNT(1), 0x01,
mjr 35:e959ffba78fd 272 REPORT_SIZE(1), 0x03,
mjr 35:e959ffba78fd 273 OUTPUT(1), 0x01, // Constant
mjr 10:976666ffa4ef 274
mjr 35:e959ffba78fd 275 REPORT_COUNT(1), 0x06,
mjr 35:e959ffba78fd 276 REPORT_SIZE(1), 0x08,
mjr 35:e959ffba78fd 277 LOGICAL_MINIMUM(1), 0x00,
mjr 35:e959ffba78fd 278 LOGICAL_MAXIMUM(1), 0x65,
mjr 35:e959ffba78fd 279 USAGE_PAGE(1), 0x07, // Key Codes
mjr 35:e959ffba78fd 280 USAGE_MINIMUM(1), 0x00,
mjr 35:e959ffba78fd 281 USAGE_MAXIMUM(1), 0x65,
mjr 35:e959ffba78fd 282 INPUT(1), 0x00, // Data, Array
mjr 35:e959ffba78fd 283 END_COLLECTION(0),
mjr 3:3514575d4f86 284
mjr 35:e959ffba78fd 285 // Media Control
mjr 35:e959ffba78fd 286 USAGE_PAGE(1), 0x0C,
mjr 35:e959ffba78fd 287 USAGE(1), 0x01,
mjr 35:e959ffba78fd 288 COLLECTION(1), 0x01,
mjr 35:e959ffba78fd 289 REPORT_ID(1), REPORT_ID_MEDIA,
mjr 35:e959ffba78fd 290 USAGE_PAGE(1), 0x0C,
mjr 35:e959ffba78fd 291 LOGICAL_MINIMUM(1), 0x00,
mjr 35:e959ffba78fd 292 LOGICAL_MAXIMUM(1), 0x01,
mjr 35:e959ffba78fd 293 REPORT_SIZE(1), 0x01,
mjr 35:e959ffba78fd 294 REPORT_COUNT(1), 0x07,
mjr 35:e959ffba78fd 295 USAGE(1), 0xE9, // Volume Up
mjr 35:e959ffba78fd 296 USAGE(1), 0xEA, // Volume Down
mjr 35:e959ffba78fd 297 USAGE(1), 0xE2, // Mute
mjr 35:e959ffba78fd 298 USAGE(1), 0xB5, // Next Track
mjr 35:e959ffba78fd 299 USAGE(1), 0xB6, // Previous Track
mjr 35:e959ffba78fd 300 USAGE(1), 0xB7, // Stop
mjr 35:e959ffba78fd 301 USAGE(1), 0xCD, // Play / Pause
mjr 35:e959ffba78fd 302 INPUT(1), 0x02, // Input (Data, Variable, Absolute)
mjr 35:e959ffba78fd 303 REPORT_COUNT(1), 0x01,
mjr 35:e959ffba78fd 304 INPUT(1), 0x01,
mjr 35:e959ffba78fd 305 END_COLLECTION(0),
mjr 35:e959ffba78fd 306 };
mjr 29:582472d0bc57 307
mjr 35:e959ffba78fd 308 //
mjr 35:e959ffba78fd 309 // USB HID Report Descriptor - LedWiz only, with no joystick or keyboard
mjr 35:e959ffba78fd 310 // input reporting
mjr 35:e959ffba78fd 311 //
mjr 35:e959ffba78fd 312 static uint8_t reportDescriptorLW[] =
mjr 35:e959ffba78fd 313 {
mjr 35:e959ffba78fd 314 USAGE_PAGE(1), 0x01, // Generic desktop
mjr 35:e959ffba78fd 315 USAGE(1), 0x00, // Undefined
mjr 21:5048e16cc9ef 316
mjr 35:e959ffba78fd 317 COLLECTION(1), 0x01, // Application
mjr 21:5048e16cc9ef 318
mjr 35:e959ffba78fd 319 // input report (device to host)
mjr 35:e959ffba78fd 320 USAGE_PAGE(1), 0x06, // generic device controls - for config status
mjr 35:e959ffba78fd 321 USAGE(1), 0x00, // undefined device control
mjr 35:e959ffba78fd 322 LOGICAL_MINIMUM(1), 0x00, // 8-bit values
mjr 35:e959ffba78fd 323 LOGICAL_MAXIMUM(1), 0xFF,
mjr 35:e959ffba78fd 324 REPORT_SIZE(1), 0x08, // 8 bits per report
mjr 35:e959ffba78fd 325 REPORT_COUNT(1), reportLen, // standard report length (same as if we were in joystick mode)
mjr 35:e959ffba78fd 326 INPUT(1), 0x02, // Data, Variable, Absolute
mjr 35:e959ffba78fd 327
mjr 35:e959ffba78fd 328 // output report (host to device)
mjr 35:e959ffba78fd 329 REPORT_SIZE(1), 0x08, // 8 bits per report
mjr 35:e959ffba78fd 330 REPORT_COUNT(1), 0x08, // output report count (LEDWiz messages)
mjr 35:e959ffba78fd 331 0x09, 0x01, // usage
mjr 35:e959ffba78fd 332 0x91, 0x01, // Output (array)
mjr 35:e959ffba78fd 333
mjr 35:e959ffba78fd 334 END_COLLECTION(0)
mjr 35:e959ffba78fd 335 };
mjr 35:e959ffba78fd 336
mjr 21:5048e16cc9ef 337
mjr 35:e959ffba78fd 338 uint8_t * USBJoystick::reportDescN(int idx)
mjr 35:e959ffba78fd 339 {
mjr 35:e959ffba78fd 340 if (enableJoystick)
mjr 35:e959ffba78fd 341 {
mjr 35:e959ffba78fd 342 // Joystick reports are enabled. Use the full joystick report
mjr 35:e959ffba78fd 343 // format, or full keyboard report format, depending on which
mjr 35:e959ffba78fd 344 // interface is being requested.
mjr 35:e959ffba78fd 345 switch (idx)
mjr 35:e959ffba78fd 346 {
mjr 35:e959ffba78fd 347 case 0:
mjr 35:e959ffba78fd 348 // joystick interface
mjr 35:e959ffba78fd 349 reportLength = sizeof(reportDescriptorJS);
mjr 35:e959ffba78fd 350 return reportDescriptorJS;
mjr 35:e959ffba78fd 351
mjr 35:e959ffba78fd 352 case 1:
mjr 35:e959ffba78fd 353 // keyboard interface
mjr 35:e959ffba78fd 354 reportLength = sizeof(reportDescriptorKB);
mjr 35:e959ffba78fd 355 return reportDescriptorKB;
mjr 35:e959ffba78fd 356
mjr 35:e959ffba78fd 357 default:
mjr 35:e959ffba78fd 358 // unknown interface
mjr 35:e959ffba78fd 359 reportLength = 0;
mjr 35:e959ffba78fd 360 return 0;
mjr 35:e959ffba78fd 361 }
mjr 35:e959ffba78fd 362 }
mjr 35:e959ffba78fd 363 else
mjr 35:e959ffba78fd 364 {
mjr 35:e959ffba78fd 365 // Joystick reports are disabled. Use the LedWiz-only format.
mjr 35:e959ffba78fd 366 reportLength = sizeof(reportDescriptorLW);
mjr 35:e959ffba78fd 367 return reportDescriptorLW;
mjr 35:e959ffba78fd 368 }
mjr 35:e959ffba78fd 369 }
mjr 3:3514575d4f86 370
mjr 3:3514575d4f86 371 uint8_t * USBJoystick::stringImanufacturerDesc() {
mjr 3:3514575d4f86 372 static uint8_t stringImanufacturerDescriptor[] = {
mjr 3:3514575d4f86 373 0x10, /*bLength*/
mjr 3:3514575d4f86 374 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
mjr 3:3514575d4f86 375 'm',0,'j',0,'r',0,'c',0,'o',0,'r',0,'p',0 /*bString iManufacturer - mjrcorp*/
mjr 3:3514575d4f86 376 };
mjr 3:3514575d4f86 377 return stringImanufacturerDescriptor;
mjr 3:3514575d4f86 378 }
mjr 3:3514575d4f86 379
mjr 3:3514575d4f86 380 uint8_t * USBJoystick::stringIserialDesc() {
mjr 3:3514575d4f86 381 static uint8_t stringIserialDescriptor[] = {
mjr 3:3514575d4f86 382 0x16, /*bLength*/
mjr 3:3514575d4f86 383 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
mjr 3:3514575d4f86 384 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
mjr 3:3514575d4f86 385 };
mjr 3:3514575d4f86 386 return stringIserialDescriptor;
mjr 3:3514575d4f86 387 }
mjr 3:3514575d4f86 388
mjr 3:3514575d4f86 389 uint8_t * USBJoystick::stringIproductDesc() {
mjr 3:3514575d4f86 390 static uint8_t stringIproductDescriptor[] = {
mjr 9:fd65b0a94720 391 0x28, /*bLength*/
mjr 3:3514575d4f86 392 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
mjr 3:3514575d4f86 393 'P',0,'i',0,'n',0,'s',0,'c',0,'a',0,'p',0,'e',0,
mjr 3:3514575d4f86 394 ' ',0,'C',0,'o',0,'n',0,'t',0,'r',0,'o',0,'l',0,
mjr 3:3514575d4f86 395 'l',0,'e',0,'r',0 /*String iProduct */
mjr 3:3514575d4f86 396 };
mjr 3:3514575d4f86 397 return stringIproductDescriptor;
mjr 3:3514575d4f86 398 }
mjr 35:e959ffba78fd 399
mjr 35:e959ffba78fd 400 #define DEFAULT_CONFIGURATION (1)
mjr 35:e959ffba78fd 401
mjr 35:e959ffba78fd 402 uint8_t * USBJoystick::configurationDesc()
mjr 35:e959ffba78fd 403 {
mjr 35:e959ffba78fd 404 int rptlen0 = reportDescLengthN(0);
mjr 35:e959ffba78fd 405 int rptlen1 = reportDescLengthN(1);
mjr 35:e959ffba78fd 406 if (useKB)
mjr 35:e959ffba78fd 407 {
mjr 35:e959ffba78fd 408 int cfglenKB = ((1 * CONFIGURATION_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 409 + (2 * INTERFACE_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 410 + (2 * HID_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 411 + (4 * ENDPOINT_DESCRIPTOR_LENGTH));
mjr 35:e959ffba78fd 412 static uint8_t configurationDescriptorWithKB[] =
mjr 35:e959ffba78fd 413 {
mjr 35:e959ffba78fd 414 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
mjr 35:e959ffba78fd 415 CONFIGURATION_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 416 LSB(cfglenKB), // wTotalLength (LSB)
mjr 35:e959ffba78fd 417 MSB(cfglenKB), // wTotalLength (MSB)
mjr 35:e959ffba78fd 418 0x02, // bNumInterfaces - TWO INTERFACES (JOYSTICK + KEYBOARD)
mjr 35:e959ffba78fd 419 DEFAULT_CONFIGURATION, // bConfigurationValue
mjr 35:e959ffba78fd 420 0x00, // iConfiguration
mjr 35:e959ffba78fd 421 C_RESERVED | C_SELF_POWERED, // bmAttributes
mjr 35:e959ffba78fd 422 C_POWER(0), // bMaxPowerHello World from Mbed
mjr 35:e959ffba78fd 423
mjr 35:e959ffba78fd 424 // INTERFACE 0 - JOYSTICK/LEDWIZ
mjr 35:e959ffba78fd 425 INTERFACE_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 426 INTERFACE_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 427 0x00, // bInterfaceNumber - first interface = 0
mjr 35:e959ffba78fd 428 0x00, // bAlternateSetting
mjr 35:e959ffba78fd 429 0x02, // bNumEndpoints
mjr 35:e959ffba78fd 430 HID_CLASS, // bInterfaceClass
mjr 35:e959ffba78fd 431 HID_SUBCLASS_NONE, // bInterfaceSubClass
mjr 35:e959ffba78fd 432 HID_PROTOCOL_NONE, // bInterfaceProtocol
mjr 35:e959ffba78fd 433 0x00, // iInterface
mjr 35:e959ffba78fd 434
mjr 35:e959ffba78fd 435 HID_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 436 HID_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 437 LSB(HID_VERSION_1_11), // bcdHID (LSB)
mjr 35:e959ffba78fd 438 MSB(HID_VERSION_1_11), // bcdHID (MSB)
mjr 35:e959ffba78fd 439 0x00, // bCountryCode
mjr 35:e959ffba78fd 440 0x01, // bNumDescriptors
mjr 35:e959ffba78fd 441 REPORT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 442 LSB(rptlen0), // wDescriptorLength (LSB)
mjr 35:e959ffba78fd 443 MSB(rptlen0), // wDescriptorLength (MSB)
mjr 35:e959ffba78fd 444
mjr 35:e959ffba78fd 445 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 446 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 447 PHY_TO_DESC(EPINT_IN), // bEndpointAddress - EPINT == EP1
mjr 35:e959ffba78fd 448 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 449 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 450 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 451 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 452
mjr 35:e959ffba78fd 453 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 454 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 455 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress - EPINT == EP1
mjr 35:e959ffba78fd 456 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 457 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 458 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 459 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 460
mjr 35:e959ffba78fd 461 // INTERFACE 1 - KEYBOARD
mjr 35:e959ffba78fd 462 INTERFACE_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 463 INTERFACE_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 464 0x01, // bInterfaceNumber - second interface = 1
mjr 35:e959ffba78fd 465 0x00, // bAlternateSetting
mjr 35:e959ffba78fd 466 0x02, // bNumEndpoints
mjr 35:e959ffba78fd 467 HID_CLASS, // bInterfaceClass
mjr 35:e959ffba78fd 468 1, // bInterfaceSubClass - KEYBOARD
mjr 35:e959ffba78fd 469 1, // bInterfaceProtocol - KEYBOARD
mjr 35:e959ffba78fd 470 0x00, // iInterface
mjr 35:e959ffba78fd 471
mjr 35:e959ffba78fd 472 HID_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 473 HID_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 474 LSB(HID_VERSION_1_11), // bcdHID (LSB)
mjr 35:e959ffba78fd 475 MSB(HID_VERSION_1_11), // bcdHID (MSB)
mjr 35:e959ffba78fd 476 0x00, // bCountryCode
mjr 35:e959ffba78fd 477 0x01, // bNumDescriptors
mjr 35:e959ffba78fd 478 REPORT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 479 LSB(rptlen1), // wDescriptorLength (LSB)
mjr 35:e959ffba78fd 480 MSB(rptlen1), // wDescriptorLength (MSB)
mjr 35:e959ffba78fd 481
mjr 35:e959ffba78fd 482 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 483 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 484 PHY_TO_DESC(EP4IN), // bEndpointAddress
mjr 35:e959ffba78fd 485 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 486 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 487 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 488 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 489
mjr 35:e959ffba78fd 490 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 491 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 492 PHY_TO_DESC(EP4OUT), // bEndpointAddress
mjr 35:e959ffba78fd 493 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 494 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 495 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 496 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 497 };
mjr 35:e959ffba78fd 498
mjr 35:e959ffba78fd 499 // Keyboard + joystick interfaces
mjr 35:e959ffba78fd 500 return configurationDescriptorWithKB;
mjr 35:e959ffba78fd 501 }
mjr 35:e959ffba78fd 502 else
mjr 35:e959ffba78fd 503 {
mjr 35:e959ffba78fd 504 // No keyboard - joystick interface only
mjr 35:e959ffba78fd 505 int cfglenNoKB = ((1 * CONFIGURATION_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 506 + (1 * INTERFACE_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 507 + (1 * HID_DESCRIPTOR_LENGTH)
mjr 35:e959ffba78fd 508 + (2 * ENDPOINT_DESCRIPTOR_LENGTH));
mjr 35:e959ffba78fd 509 static uint8_t configurationDescriptorNoKB[] =
mjr 35:e959ffba78fd 510 {
mjr 35:e959ffba78fd 511 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
mjr 35:e959ffba78fd 512 CONFIGURATION_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 513 LSB(cfglenNoKB), // wTotalLength (LSB)
mjr 35:e959ffba78fd 514 MSB(cfglenNoKB), // wTotalLength (MSB)
mjr 35:e959ffba78fd 515 0x01, // bNumInterfaces
mjr 35:e959ffba78fd 516 DEFAULT_CONFIGURATION, // bConfigurationValue
mjr 35:e959ffba78fd 517 0x00, // iConfiguration
mjr 35:e959ffba78fd 518 C_RESERVED | C_SELF_POWERED, // bmAttributes
mjr 35:e959ffba78fd 519 C_POWER(0), // bMaxPowerHello World from Mbed
mjr 35:e959ffba78fd 520
mjr 35:e959ffba78fd 521 INTERFACE_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 522 INTERFACE_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 523 0x00, // bInterfaceNumber
mjr 35:e959ffba78fd 524 0x00, // bAlternateSetting
mjr 35:e959ffba78fd 525 0x02, // bNumEndpoints
mjr 35:e959ffba78fd 526 HID_CLASS, // bInterfaceClass
mjr 35:e959ffba78fd 527 1, // bInterfaceSubClass
mjr 35:e959ffba78fd 528 1, // bInterfaceProtocol (keyboard)
mjr 35:e959ffba78fd 529 0x00, // iInterface
mjr 35:e959ffba78fd 530
mjr 35:e959ffba78fd 531 HID_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 532 HID_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 533 LSB(HID_VERSION_1_11), // bcdHID (LSB)
mjr 35:e959ffba78fd 534 MSB(HID_VERSION_1_11), // bcdHID (MSB)
mjr 35:e959ffba78fd 535 0x00, // bCountryCode
mjr 35:e959ffba78fd 536 0x01, // bNumDescriptors
mjr 35:e959ffba78fd 537 REPORT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 538 (uint8_t)(LSB(rptlen0)), // wDescriptorLength (LSB)
mjr 35:e959ffba78fd 539 (uint8_t)(MSB(rptlen0)), // wDescriptorLength (MSB)
mjr 35:e959ffba78fd 540
mjr 35:e959ffba78fd 541 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 542 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 543 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
mjr 35:e959ffba78fd 544 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 545 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 546 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 547 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 548
mjr 35:e959ffba78fd 549 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
mjr 35:e959ffba78fd 550 ENDPOINT_DESCRIPTOR, // bDescriptorType
mjr 35:e959ffba78fd 551 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
mjr 35:e959ffba78fd 552 E_INTERRUPT, // bmAttributes
mjr 35:e959ffba78fd 553 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
mjr 35:e959ffba78fd 554 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
mjr 35:e959ffba78fd 555 1, // bInterval (milliseconds)
mjr 35:e959ffba78fd 556 };
mjr 35:e959ffba78fd 557
mjr 35:e959ffba78fd 558 return configurationDescriptorNoKB;
mjr 35:e959ffba78fd 559 }
mjr 35:e959ffba78fd 560 }
mjr 35:e959ffba78fd 561
mjr 35:e959ffba78fd 562 // Set the configuration. We need to set up the endpoints for
mjr 35:e959ffba78fd 563 // our active interfaces.
mjr 35:e959ffba78fd 564 bool USBJoystick::USBCallback_setConfiguration(uint8_t configuration)
mjr 35:e959ffba78fd 565 {
mjr 35:e959ffba78fd 566 // we only have one valid configuration
mjr 35:e959ffba78fd 567 if (configuration != DEFAULT_CONFIGURATION)
mjr 35:e959ffba78fd 568 return false;
mjr 35:e959ffba78fd 569
mjr 35:e959ffba78fd 570 // Configure endpoint 1 - we use this in all cases, for either
mjr 35:e959ffba78fd 571 // the combined joystick/ledwiz interface or just the ledwiz interface
mjr 35:e959ffba78fd 572 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
mjr 35:e959ffba78fd 573 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
mjr 35:e959ffba78fd 574 readStart(EPINT_OUT, MAX_HID_REPORT_SIZE);
mjr 35:e959ffba78fd 575
mjr 35:e959ffba78fd 576 // if the keyboard is enabled, configure endpoint 4 for the kb interface
mjr 35:e959ffba78fd 577 if (useKB)
mjr 35:e959ffba78fd 578 {
mjr 35:e959ffba78fd 579 addEndpoint(EP4IN, MAX_PACKET_SIZE_EPINT);
mjr 35:e959ffba78fd 580 addEndpoint(EP4OUT, MAX_PACKET_SIZE_EPINT);
mjr 35:e959ffba78fd 581 readStart(EP4OUT, MAX_PACKET_SIZE_EPINT);
mjr 35:e959ffba78fd 582 }
mjr 35:e959ffba78fd 583
mjr 35:e959ffba78fd 584 // success
mjr 35:e959ffba78fd 585 return true;
mjr 35:e959ffba78fd 586 }
mjr 35:e959ffba78fd 587
mjr 35:e959ffba78fd 588 // Handle messages on endpoint 4 - this is the keyboard interface.
mjr 35:e959ffba78fd 589 // The host uses this to send updates for the keyboard indicator LEDs
mjr 35:e959ffba78fd 590 // (caps lock, num lock, etc). We don't do anything with these, but
mjr 37:ed52738445fc 591 // we have to read them to keep the pipe open.
mjr 35:e959ffba78fd 592 bool USBJoystick::EP4_OUT_callback()
mjr 35:e959ffba78fd 593 {
mjr 35:e959ffba78fd 594 // read this message
mjr 35:e959ffba78fd 595 uint32_t bytesRead = 0;
mjr 37:ed52738445fc 596 uint8_t led[MAX_HID_REPORT_SIZE];
mjr 35:e959ffba78fd 597 USBDevice::readEP(EP4OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
mjr 35:e959ffba78fd 598
mjr 35:e959ffba78fd 599 // start the next read
mjr 35:e959ffba78fd 600 return readStart(EP4OUT, MAX_HID_REPORT_SIZE);
mjr 35:e959ffba78fd 601 }