Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Sun Mar 19 05:30:53 2017 +0000
Revision:
78:1e00b3fa11af
Parent:
77:0b96f6867312
Child:
82:4f6209cb5c33
Ad hoc IR command send; Shift button 'AND' and 'OR' modes; new accelerometer auto centering options

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 0:5acbbe3f4cf4 1 /* USBJoystick.h */
mjr 0:5acbbe3f4cf4 2 /* USB device example: Joystick*/
mjr 0:5acbbe3f4cf4 3 /* Copyright (c) 2011 ARM Limited. All rights reserved. */
mjr 0:5acbbe3f4cf4 4 /* Modified Mouse code for Joystick - WH 2012 */
mjr 0:5acbbe3f4cf4 5
mjr 0:5acbbe3f4cf4 6 #ifndef USBJOYSTICK_H
mjr 0:5acbbe3f4cf4 7 #define USBJOYSTICK_H
mjr 0:5acbbe3f4cf4 8
mjr 0:5acbbe3f4cf4 9 #include "USBHID.h"
mjr 77:0b96f6867312 10 #include "circbuf.h"
mjr 35:e959ffba78fd 11
mjr 39:b3815a1c3802 12 // Bufferd incoming LedWiz message structure
mjr 38:091e511ce8a0 13 struct LedWizMsg
mjr 38:091e511ce8a0 14 {
mjr 38:091e511ce8a0 15 uint8_t data[8];
mjr 38:091e511ce8a0 16 };
mjr 38:091e511ce8a0 17
mjr 39:b3815a1c3802 18 // interface IDs
mjr 39:b3815a1c3802 19 const uint8_t IFC_ID_JS = 0; // joystick + LedWiz interface
mjr 39:b3815a1c3802 20 const uint8_t IFC_ID_KB = 1; // keyboard interface
mjr 39:b3815a1c3802 21
mjr 35:e959ffba78fd 22 // keyboard interface report IDs
mjr 63:5cd1a5f3a41b 23 const uint8_t REPORT_ID_KB = 1;
mjr 63:5cd1a5f3a41b 24 const uint8_t REPORT_ID_MEDIA = 2;
mjr 35:e959ffba78fd 25
mjr 0:5acbbe3f4cf4 26 /* Common usage */
mjr 0:5acbbe3f4cf4 27 enum JOY_BUTTON {
mjr 0:5acbbe3f4cf4 28 JOY_B0 = 0x0001,
mjr 0:5acbbe3f4cf4 29 JOY_B1 = 0x0002,
mjr 0:5acbbe3f4cf4 30 JOY_B2 = 0x0004,
mjr 0:5acbbe3f4cf4 31 JOY_B3 = 0x0008,
mjr 0:5acbbe3f4cf4 32 JOY_B4 = 0x0010,
mjr 0:5acbbe3f4cf4 33 JOY_B5 = 0x0020,
mjr 0:5acbbe3f4cf4 34 JOY_B6 = 0x0040,
mjr 0:5acbbe3f4cf4 35 JOY_B7 = 0x0080,
mjr 0:5acbbe3f4cf4 36 JOY_B8 = 0x0100,
mjr 0:5acbbe3f4cf4 37 JOY_B9 = 0x0200,
mjr 0:5acbbe3f4cf4 38 JOY_B10 = 0x0400,
mjr 0:5acbbe3f4cf4 39 JOY_B11 = 0x0800,
mjr 0:5acbbe3f4cf4 40 JOY_B12 = 0x1000,
mjr 0:5acbbe3f4cf4 41 JOY_B13 = 0x2000,
mjr 0:5acbbe3f4cf4 42 JOY_B14 = 0x4000,
mjr 0:5acbbe3f4cf4 43 JOY_B15 = 0x8000
mjr 0:5acbbe3f4cf4 44 };
mjr 0:5acbbe3f4cf4 45
mjr 0:5acbbe3f4cf4 46 /**
mjr 0:5acbbe3f4cf4 47 *
mjr 0:5acbbe3f4cf4 48 * USBJoystick example
mjr 0:5acbbe3f4cf4 49 * @code
mjr 0:5acbbe3f4cf4 50 * #include "mbed.h"
mjr 0:5acbbe3f4cf4 51 * #include "USBJoystick.h"
mjr 0:5acbbe3f4cf4 52 *
mjr 0:5acbbe3f4cf4 53 * USBJoystick joystick;
mjr 0:5acbbe3f4cf4 54 *
mjr 0:5acbbe3f4cf4 55 * int main(void)
mjr 0:5acbbe3f4cf4 56 * {
mjr 0:5acbbe3f4cf4 57 * while (1)
mjr 0:5acbbe3f4cf4 58 * {
mjr 0:5acbbe3f4cf4 59 * joystick.move(20, 0);
mjr 0:5acbbe3f4cf4 60 * wait(0.5);
mjr 0:5acbbe3f4cf4 61 * }
mjr 0:5acbbe3f4cf4 62 * }
mjr 0:5acbbe3f4cf4 63 *
mjr 0:5acbbe3f4cf4 64 * @endcode
mjr 0:5acbbe3f4cf4 65 *
mjr 0:5acbbe3f4cf4 66 *
mjr 0:5acbbe3f4cf4 67 * @code
mjr 0:5acbbe3f4cf4 68 * #include "mbed.h"
mjr 0:5acbbe3f4cf4 69 * #include "USBJoystick.h"
mjr 0:5acbbe3f4cf4 70 * #include <math.h>
mjr 0:5acbbe3f4cf4 71 *
mjr 0:5acbbe3f4cf4 72 * USBJoystick joystick;
mjr 0:5acbbe3f4cf4 73 *
mjr 0:5acbbe3f4cf4 74 * int main(void)
mjr 0:5acbbe3f4cf4 75 * {
mjr 0:5acbbe3f4cf4 76 * while (1) {
mjr 0:5acbbe3f4cf4 77 * // Basic Joystick
mjr 0:5acbbe3f4cf4 78 * joystick.update(tx, y, z, buttonBits);
mjr 0:5acbbe3f4cf4 79 * wait(0.001);
mjr 0:5acbbe3f4cf4 80 * }
mjr 0:5acbbe3f4cf4 81 * }
mjr 0:5acbbe3f4cf4 82 * @endcode
mjr 0:5acbbe3f4cf4 83 */
mjr 0:5acbbe3f4cf4 84
mjr 0:5acbbe3f4cf4 85
mjr 77:0b96f6867312 86 class USBJoystick: public USBHID
mjr 77:0b96f6867312 87 {
mjr 77:0b96f6867312 88 public:
mjr 77:0b96f6867312 89 // Length of our joystick reports. Important: This must be kept in sync
mjr 77:0b96f6867312 90 // with the actual joystick report format sent in update().
mjr 77:0b96f6867312 91 static const int reportLen = 14;
mjr 77:0b96f6867312 92
mjr 38:091e511ce8a0 93
mjr 77:0b96f6867312 94 /**
mjr 77:0b96f6867312 95 * Constructor
mjr 77:0b96f6867312 96 *
mjr 77:0b96f6867312 97 * @param vendor_id Your vendor_id (default: 0x1234)
mjr 77:0b96f6867312 98 * @param product_id Your product_id (default: 0x0002)
mjr 77:0b96f6867312 99 * @param product_release Your product_release (default: 0x0001)
mjr 77:0b96f6867312 100 */
mjr 77:0b96f6867312 101 USBJoystick(uint16_t vendor_id, uint16_t product_id, uint16_t product_release,
mjr 77:0b96f6867312 102 int waitForConnect, bool enableJoystick, bool useKB)
mjr 77:0b96f6867312 103 : USBHID(16, 64, vendor_id, product_id, product_release, false)
mjr 77:0b96f6867312 104 {
mjr 77:0b96f6867312 105 _init();
mjr 77:0b96f6867312 106 this->useKB = useKB;
mjr 77:0b96f6867312 107 this->enableJoystick = enableJoystick;
mjr 77:0b96f6867312 108 connect(waitForConnect);
mjr 77:0b96f6867312 109 };
mjr 77:0b96f6867312 110
mjr 77:0b96f6867312 111 /* read a report from the LedWiz buffer */
mjr 77:0b96f6867312 112 bool readLedWizMsg(LedWizMsg &msg)
mjr 77:0b96f6867312 113 {
mjr 77:0b96f6867312 114 return lwbuf.read(msg);
mjr 77:0b96f6867312 115 }
mjr 77:0b96f6867312 116
mjr 77:0b96f6867312 117 /* get the idle time settings, in milliseconds */
mjr 77:0b96f6867312 118 uint32_t getKbIdle() const { return kbIdleTime * 4UL; }
mjr 77:0b96f6867312 119 uint32_t getMediaIdle() const { return mediaIdleTime * 4UL; }
mjr 77:0b96f6867312 120
mjr 39:b3815a1c3802 121
mjr 77:0b96f6867312 122 /**
mjr 77:0b96f6867312 123 * Send a keyboard report. The argument gives the key state, in the standard
mjr 77:0b96f6867312 124 * 6KRO USB keyboard report format: byte 0 is the modifier key bit mask, byte 1
mjr 77:0b96f6867312 125 * is reserved (must be 0), and bytes 2-6 are the currently pressed keys, as
mjr 77:0b96f6867312 126 * USB key codes.
mjr 77:0b96f6867312 127 */
mjr 77:0b96f6867312 128 bool kbUpdate(uint8_t data[8]);
mjr 77:0b96f6867312 129
mjr 77:0b96f6867312 130 /**
mjr 77:0b96f6867312 131 * Send a media key update. The argument gives the bit mask of media keys
mjr 77:0b96f6867312 132 * currently pressed. See the HID report descriptor for the order of bits.
mjr 77:0b96f6867312 133 */
mjr 77:0b96f6867312 134 bool mediaUpdate(uint8_t data);
mjr 77:0b96f6867312 135
mjr 77:0b96f6867312 136 /**
mjr 77:0b96f6867312 137 * Update the joystick status
mjr 77:0b96f6867312 138 *
mjr 77:0b96f6867312 139 * @param x x-axis position
mjr 77:0b96f6867312 140 * @param y y-axis position
mjr 77:0b96f6867312 141 * @param z z-axis position
mjr 77:0b96f6867312 142 * @param buttons buttons state, as a bit mask (combination with '|' of JOY_Bn values)
mjr 77:0b96f6867312 143 * @returns true if there is no error, false otherwise
mjr 77:0b96f6867312 144 */
mjr 77:0b96f6867312 145 bool update(int16_t x, int16_t y, int16_t z, uint32_t buttons, uint16_t status);
mjr 77:0b96f6867312 146
mjr 77:0b96f6867312 147 /**
mjr 77:0b96f6867312 148 * Update just the status
mjr 77:0b96f6867312 149 */
mjr 77:0b96f6867312 150 bool updateStatus(uint32_t stat);
mjr 77:0b96f6867312 151
mjr 77:0b96f6867312 152 /**
mjr 77:0b96f6867312 153 * Write the plunger status report.
mjr 77:0b96f6867312 154 *
mjr 77:0b96f6867312 155 * @param npix number of pixels in the sensor (0 for non-imaging sensors)
mjr 77:0b96f6867312 156 * @param edgePos the pixel position of the detected edge in this image, or -1 if none detected
mjr 77:0b96f6867312 157 * @param dir sensor orientation (1 = standard, -1 = reversed, 0 = unknown)
mjr 77:0b96f6867312 158 * @param avgScanTime average sensor scan time in microseconds
mjr 77:0b96f6867312 159 * @param processingTime time in microseconds to process the current frame
mjr 77:0b96f6867312 160 */
mjr 77:0b96f6867312 161 bool sendPlungerStatus(int npix, int edgePos, int dir, uint32_t avgScanTime, uint32_t processingTime);
mjr 77:0b96f6867312 162
mjr 77:0b96f6867312 163 /**
mjr 77:0b96f6867312 164 * Write an exposure report. We'll fill out a report with as many pixels as
mjr 77:0b96f6867312 165 * will fit in the packet, send the report, and update the index to the next
mjr 77:0b96f6867312 166 * pixel to send. The caller should call this repeatedly to send reports for
mjr 77:0b96f6867312 167 * all pixels.
mjr 77:0b96f6867312 168 *
mjr 77:0b96f6867312 169 * @param idx current index in pixel array, updated to point to next pixel to send
mjr 77:0b96f6867312 170 * @param npix number of pixels in the overall array
mjr 77:0b96f6867312 171 * @param pix pixel array
mjr 77:0b96f6867312 172 */
mjr 77:0b96f6867312 173 bool sendPlungerPix(int &idx, int npix, const uint8_t *pix);
mjr 77:0b96f6867312 174
mjr 77:0b96f6867312 175 /**
mjr 77:0b96f6867312 176 * Write a configuration report.
mjr 77:0b96f6867312 177 *
mjr 77:0b96f6867312 178 * @param numOutputs the number of configured output channels
mjr 77:0b96f6867312 179 * @param unitNo the device unit number
mjr 77:0b96f6867312 180 * @param plungerZero plunger zero calibration point
mjr 77:0b96f6867312 181 * @param plungerMax plunger max calibration point
mjr 77:0b96f6867312 182 * @param plungerRlsTime measured plunger release time, in milliseconds
mjr 77:0b96f6867312 183 * @param configured true if a configuration has been saved to flash from the host
mjr 77:0b96f6867312 184 * @param sbxpbx true if this firmware version supports SBX/PBX protocol extensions
mjr 78:1e00b3fa11af 185 * @param newAccelFeatures true if this firmware version supports the new accelerometer
mjr 78:1e00b3fa11af 186 * features (adjustable dynamic range, adjustable auto-centering mode time,
mjr 78:1e00b3fa11af 187 * auto-centering mode on/off)
mjr 77:0b96f6867312 188 * @param freeHeapBytes number of free bytes in the malloc heap
mjr 77:0b96f6867312 189 */
mjr 77:0b96f6867312 190 bool reportConfig(int numOutputs, int unitNo,
mjr 77:0b96f6867312 191 int plungerZero, int plungerMax, int plunterRlsTime,
mjr 78:1e00b3fa11af 192 bool configured, bool sbxpbx, bool newAccelFeatures,
mjr 78:1e00b3fa11af 193 size_t freeHeapBytes);
mjr 77:0b96f6867312 194
mjr 77:0b96f6867312 195 /**
mjr 77:0b96f6867312 196 * Write a configuration variable query report.
mjr 77:0b96f6867312 197 *
mjr 77:0b96f6867312 198 * @param data the 7-byte data variable buffer, starting with the variable ID byte
mjr 77:0b96f6867312 199 */
mjr 77:0b96f6867312 200 bool reportConfigVar(const uint8_t *data);
mjr 77:0b96f6867312 201
mjr 77:0b96f6867312 202 /**
mjr 77:0b96f6867312 203 * Write a device ID report.
mjr 77:0b96f6867312 204 */
mjr 77:0b96f6867312 205 bool reportID(int index);
mjr 77:0b96f6867312 206
mjr 77:0b96f6867312 207 /**
mjr 77:0b96f6867312 208 * Write a build data report
mjr 77:0b96f6867312 209 *
mjr 77:0b96f6867312 210 * @param date build date plus time, in __DATE__ " " __TIME__ macro format ("Mon dd, yyyy hh:mm:ss")
mjr 77:0b96f6867312 211 */
mjr 77:0b96f6867312 212 bool reportBuildInfo(const char *date);
mjr 77:0b96f6867312 213
mjr 77:0b96f6867312 214 /**
mjr 77:0b96f6867312 215 * Write a physical button status report.
mjr 77:0b96f6867312 216 *
mjr 77:0b96f6867312 217 * @param numButtons the number of buttons
mjr 77:0b96f6867312 218 * @param state the button states, 1 bit per button, 8 buttons per byte,
mjr 77:0b96f6867312 219 * starting with button 0 in the low-order bit (0x01) of the
mjr 77:0b96f6867312 220 * first byte
mjr 77:0b96f6867312 221 */
mjr 77:0b96f6867312 222 bool reportButtonStatus(int numButtons, const uint8_t *state);
mjr 77:0b96f6867312 223
mjr 77:0b96f6867312 224 /**
mjr 77:0b96f6867312 225 * Write an IR raw sensor input report. This reports a set of raw
mjr 77:0b96f6867312 226 * timing reports for input read from the IR sensor, for learning
mjr 77:0b96f6867312 227 * remote purposes.
mjr 77:0b96f6867312 228 *
mjr 77:0b96f6867312 229 * @param n number of items to report, up to maxRawIR
mjr 77:0b96f6867312 230 * @param data items to report; each is a timing reading, in 2us
mjr 77:0b96f6867312 231 * increments, with the low bit in each report set to 0 for
mjr 77:0b96f6867312 232 * a "space" (IR off) or 1 for a "mark" (IR on)
mjr 77:0b96f6867312 233 */
mjr 77:0b96f6867312 234 bool reportRawIR(int n, const uint16_t *data);
mjr 77:0b96f6867312 235
mjr 77:0b96f6867312 236 /**
mjr 77:0b96f6867312 237 * Maximum number of raw IR readings that can be sent in one report
mjr 77:0b96f6867312 238 * via reportRawIR().
mjr 77:0b96f6867312 239 */
mjr 77:0b96f6867312 240 static const int maxRawIR = (reportLen - 3)/2;
mjr 77:0b96f6867312 241
mjr 77:0b96f6867312 242 /**
mjr 77:0b96f6867312 243 * Write an IR input report. This reports a decoded command read in
mjr 77:0b96f6867312 244 * learning mode to the host.
mjr 77:0b96f6867312 245 *
mjr 77:0b96f6867312 246 * @param pro protocol ID (see IRProtocolID.h)
mjr 77:0b96f6867312 247 * @param flags bit flags: 0x02 = protocol uses dittos
mjr 77:0b96f6867312 248 * @param code decoded command code
mjr 77:0b96f6867312 249 */
mjr 77:0b96f6867312 250 bool reportIRCode(uint8_t pro, uint8_t flags, uint64_t code);
mjr 35:e959ffba78fd 251
mjr 77:0b96f6867312 252 /**
mjr 77:0b96f6867312 253 * Send a joystick report to the host
mjr 77:0b96f6867312 254 *
mjr 77:0b96f6867312 255 * @returns true if there is no error, false otherwise
mjr 77:0b96f6867312 256 */
mjr 77:0b96f6867312 257 bool update();
mjr 77:0b96f6867312 258
mjr 77:0b96f6867312 259 /**
mjr 77:0b96f6867312 260 * Move the cursor to (x, y)
mjr 77:0b96f6867312 261 *
mjr 77:0b96f6867312 262 * @param x x-axis position
mjr 77:0b96f6867312 263 * @param y y-axis position
mjr 77:0b96f6867312 264 * @returns true if there is no error, false otherwise
mjr 77:0b96f6867312 265 */
mjr 77:0b96f6867312 266 bool move(int16_t x, int16_t y);
mjr 77:0b96f6867312 267
mjr 77:0b96f6867312 268 /**
mjr 77:0b96f6867312 269 * Set the z position
mjr 77:0b96f6867312 270 *
mjr 77:0b96f6867312 271 * @param z z-axis osition
mjr 77:0b96f6867312 272 */
mjr 77:0b96f6867312 273 bool setZ(int16_t z);
mjr 77:0b96f6867312 274
mjr 77:0b96f6867312 275 /**
mjr 77:0b96f6867312 276 * Press one or several buttons
mjr 77:0b96f6867312 277 *
mjr 77:0b96f6867312 278 * @param buttons button state, as a bitwise combination of JOY_Bn values
mjr 77:0b96f6867312 279 * @returns true if there is no error, false otherwise
mjr 77:0b96f6867312 280 */
mjr 77:0b96f6867312 281 bool buttons(uint32_t buttons);
mjr 77:0b96f6867312 282
mjr 77:0b96f6867312 283 /* USB descriptor overrides */
mjr 77:0b96f6867312 284 virtual const uint8_t *configurationDesc();
mjr 77:0b96f6867312 285 virtual const uint8_t *reportDesc(int idx, uint16_t &len);
mjr 39:b3815a1c3802 286
mjr 77:0b96f6867312 287 /* USB descriptor string overrides */
mjr 77:0b96f6867312 288 virtual const uint8_t *stringImanufacturerDesc();
mjr 77:0b96f6867312 289 virtual const uint8_t *stringIserialDesc();
mjr 77:0b96f6867312 290 virtual const uint8_t *stringIproductDesc();
mjr 77:0b96f6867312 291
mjr 77:0b96f6867312 292 /* set/get idle time */
mjr 77:0b96f6867312 293 virtual void setIdleTime(int ifc, int rptid, int t)
mjr 77:0b96f6867312 294 {
mjr 77:0b96f6867312 295 // Remember the new value if operating on the keyboard. Remember
mjr 77:0b96f6867312 296 // separate keyboard and media control idle times, in case the
mjr 77:0b96f6867312 297 // host wants separate report rates.
mjr 77:0b96f6867312 298 if (ifc == IFC_ID_KB)
mjr 77:0b96f6867312 299 {
mjr 77:0b96f6867312 300 if (rptid == REPORT_ID_KB)
mjr 77:0b96f6867312 301 kbIdleTime = t;
mjr 77:0b96f6867312 302 else if (rptid == REPORT_ID_MEDIA)
mjr 77:0b96f6867312 303 mediaIdleTime = t;
mjr 77:0b96f6867312 304 }
mjr 77:0b96f6867312 305 }
mjr 77:0b96f6867312 306 virtual uint8_t getIdleTime(int ifc, int rptid)
mjr 77:0b96f6867312 307 {
mjr 77:0b96f6867312 308 // Return the kb idle time if the kb interface is the one requested.
mjr 77:0b96f6867312 309 if (ifc == IFC_ID_KB)
mjr 77:0b96f6867312 310 {
mjr 77:0b96f6867312 311 if (rptid == REPORT_ID_KB)
mjr 77:0b96f6867312 312 return kbIdleTime;
mjr 77:0b96f6867312 313 if (rptid == REPORT_ID_MEDIA)
mjr 77:0b96f6867312 314 return mediaIdleTime;
mjr 77:0b96f6867312 315 }
mjr 77:0b96f6867312 316
mjr 77:0b96f6867312 317 // we don't use idle times for other interfaces or report types
mjr 77:0b96f6867312 318 return 0;
mjr 77:0b96f6867312 319 }
mjr 77:0b96f6867312 320
mjr 77:0b96f6867312 321 /* callback overrides */
mjr 77:0b96f6867312 322 virtual bool USBCallback_setConfiguration(uint8_t configuration);
mjr 77:0b96f6867312 323 virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate)
mjr 77:0b96f6867312 324 { return interface == 0 || interface == 1; }
mjr 77:0b96f6867312 325
mjr 77:0b96f6867312 326 virtual bool EP1_OUT_callback();
mjr 77:0b96f6867312 327 virtual bool EP4_OUT_callback();
mjr 77:0b96f6867312 328
mjr 77:0b96f6867312 329 private:
mjr 38:091e511ce8a0 330
mjr 77:0b96f6867312 331 // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes.
mjr 77:0b96f6867312 332 CircBuf<LedWizMsg, 16> lwbuf;
mjr 77:0b96f6867312 333
mjr 77:0b96f6867312 334 bool enableJoystick;
mjr 77:0b96f6867312 335 bool useKB;
mjr 77:0b96f6867312 336 uint8_t kbIdleTime;
mjr 77:0b96f6867312 337 uint8_t mediaIdleTime;
mjr 77:0b96f6867312 338 int16_t _x;
mjr 77:0b96f6867312 339 int16_t _y;
mjr 77:0b96f6867312 340 int16_t _z;
mjr 77:0b96f6867312 341 uint16_t _buttonsLo;
mjr 77:0b96f6867312 342 uint16_t _buttonsHi;
mjr 77:0b96f6867312 343 uint16_t _status;
mjr 77:0b96f6867312 344
mjr 77:0b96f6867312 345 void _init();
mjr 0:5acbbe3f4cf4 346 };
mjr 0:5acbbe3f4cf4 347
mjr 38:091e511ce8a0 348 #endif