Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Thu Feb 18 07:32:20 2016 +0000
Revision:
47:df7a88cd249c
Parent:
40:cc0d9814522b
Child:
48:058ace2aed1d
3-channel linked DMA scheme for CCD image capture working

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 35:e959ffba78fd 10
mjr 39:b3815a1c3802 11 // Bufferd incoming LedWiz message structure
mjr 38:091e511ce8a0 12 struct LedWizMsg
mjr 38:091e511ce8a0 13 {
mjr 38:091e511ce8a0 14 uint8_t data[8];
mjr 38:091e511ce8a0 15 };
mjr 38:091e511ce8a0 16
mjr 39:b3815a1c3802 17 // Circular buffer for incoming reports. We write reports in the IRQ
mjr 39:b3815a1c3802 18 // handler, and we read reports in the main loop in normal application
mjr 39:b3815a1c3802 19 // (non-IRQ) context.
mjr 39:b3815a1c3802 20 //
mjr 39:b3815a1c3802 21 // The design is organically safe for IRQ threading; there are no critical
mjr 39:b3815a1c3802 22 // sections. The IRQ context has exclusive access to the write pointer,
mjr 39:b3815a1c3802 23 // and the application context has exclusive access to the read pointer,
mjr 39:b3815a1c3802 24 // so there are no test-and-set or read-and-modify race conditions.
mjr 38:091e511ce8a0 25 template<class T, int cnt> class CircBuf
mjr 38:091e511ce8a0 26 {
mjr 38:091e511ce8a0 27 public:
mjr 38:091e511ce8a0 28 CircBuf()
mjr 38:091e511ce8a0 29 {
mjr 38:091e511ce8a0 30 iRead = iWrite = 0;
mjr 38:091e511ce8a0 31 }
mjr 38:091e511ce8a0 32
mjr 38:091e511ce8a0 33 // Read an item from the buffer. Returns true if an item was available,
mjr 39:b3815a1c3802 34 // false if the buffer was empty. (Called in the main loop, in application
mjr 39:b3815a1c3802 35 // context.)
mjr 38:091e511ce8a0 36 bool read(T &result)
mjr 38:091e511ce8a0 37 {
mjr 38:091e511ce8a0 38 if (iRead != iWrite)
mjr 38:091e511ce8a0 39 {
mjr 39:b3815a1c3802 40 //{uint8_t *d = buf[iRead].data; printf("circ read [%02x %02x %02x %02x %02x %02x %02x %02x]\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);}
mjr 38:091e511ce8a0 41 memcpy(&result, &buf[iRead], sizeof(T));
mjr 38:091e511ce8a0 42 iRead = advance(iRead);
mjr 38:091e511ce8a0 43 return true;
mjr 38:091e511ce8a0 44 }
mjr 38:091e511ce8a0 45 else
mjr 38:091e511ce8a0 46 return false;
mjr 38:091e511ce8a0 47 }
mjr 38:091e511ce8a0 48
mjr 39:b3815a1c3802 49 // Write an item to the buffer. (Called in the IRQ handler, in interrupt
mjr 39:b3815a1c3802 50 // context.)
mjr 38:091e511ce8a0 51 bool write(const T &item)
mjr 38:091e511ce8a0 52 {
mjr 38:091e511ce8a0 53 int nxt = advance(iWrite);
mjr 38:091e511ce8a0 54 if (nxt != iRead)
mjr 38:091e511ce8a0 55 {
mjr 39:b3815a1c3802 56 memcpy(&buf[iWrite], &item, sizeof(T));
mjr 38:091e511ce8a0 57 iWrite = nxt;
mjr 38:091e511ce8a0 58 return true;
mjr 38:091e511ce8a0 59 }
mjr 38:091e511ce8a0 60 else
mjr 38:091e511ce8a0 61 return false;
mjr 38:091e511ce8a0 62 }
mjr 38:091e511ce8a0 63
mjr 38:091e511ce8a0 64 private:
mjr 38:091e511ce8a0 65 int advance(int i)
mjr 38:091e511ce8a0 66 {
mjr 39:b3815a1c3802 67 ++i;
mjr 39:b3815a1c3802 68 return i < cnt ? i : 0;
mjr 38:091e511ce8a0 69 }
mjr 38:091e511ce8a0 70
mjr 38:091e511ce8a0 71 int iRead;
mjr 38:091e511ce8a0 72 int iWrite;
mjr 38:091e511ce8a0 73 T buf[cnt];
mjr 38:091e511ce8a0 74 };
mjr 38:091e511ce8a0 75
mjr 39:b3815a1c3802 76 // interface IDs
mjr 39:b3815a1c3802 77 const uint8_t IFC_ID_JS = 0; // joystick + LedWiz interface
mjr 39:b3815a1c3802 78 const uint8_t IFC_ID_KB = 1; // keyboard interface
mjr 39:b3815a1c3802 79
mjr 35:e959ffba78fd 80 // keyboard interface report IDs
mjr 35:e959ffba78fd 81 const uint8_t REPORT_ID_KB = 1;
mjr 35:e959ffba78fd 82 const uint8_t REPORT_ID_MEDIA = 2;
mjr 35:e959ffba78fd 83
mjr 0:5acbbe3f4cf4 84 /* Common usage */
mjr 0:5acbbe3f4cf4 85 enum JOY_BUTTON {
mjr 0:5acbbe3f4cf4 86 JOY_B0 = 0x0001,
mjr 0:5acbbe3f4cf4 87 JOY_B1 = 0x0002,
mjr 0:5acbbe3f4cf4 88 JOY_B2 = 0x0004,
mjr 0:5acbbe3f4cf4 89 JOY_B3 = 0x0008,
mjr 0:5acbbe3f4cf4 90 JOY_B4 = 0x0010,
mjr 0:5acbbe3f4cf4 91 JOY_B5 = 0x0020,
mjr 0:5acbbe3f4cf4 92 JOY_B6 = 0x0040,
mjr 0:5acbbe3f4cf4 93 JOY_B7 = 0x0080,
mjr 0:5acbbe3f4cf4 94 JOY_B8 = 0x0100,
mjr 0:5acbbe3f4cf4 95 JOY_B9 = 0x0200,
mjr 0:5acbbe3f4cf4 96 JOY_B10 = 0x0400,
mjr 0:5acbbe3f4cf4 97 JOY_B11 = 0x0800,
mjr 0:5acbbe3f4cf4 98 JOY_B12 = 0x1000,
mjr 0:5acbbe3f4cf4 99 JOY_B13 = 0x2000,
mjr 0:5acbbe3f4cf4 100 JOY_B14 = 0x4000,
mjr 0:5acbbe3f4cf4 101 JOY_B15 = 0x8000
mjr 0:5acbbe3f4cf4 102 };
mjr 0:5acbbe3f4cf4 103
mjr 0:5acbbe3f4cf4 104 /* X, Y and T limits */
mjr 0:5acbbe3f4cf4 105 /* These values do not directly map to screen pixels */
mjr 0:5acbbe3f4cf4 106 /* Zero may be interpreted as meaning 'no movement' */
mjr 0:5acbbe3f4cf4 107 #define JX_MIN_ABS (-127) /*!< The maximum value that we can move to the left on the x-axis */
mjr 0:5acbbe3f4cf4 108 #define JY_MIN_ABS (-127) /*!< The maximum value that we can move up on the y-axis */
mjr 0:5acbbe3f4cf4 109 #define JZ_MIN_ABS (-127) /*!< The minimum value for the Z axis */
mjr 0:5acbbe3f4cf4 110 #define JX_MAX_ABS (127) /*!< The maximum value that we can move to the right on the x-axis */
mjr 0:5acbbe3f4cf4 111 #define JY_MAX_ABS (127) /*!< The maximum value that we can move down on the y-axis */
mjr 0:5acbbe3f4cf4 112 #define JZ_MAX_ABS (127) /*!< The maximum value for the Z axis */
mjr 0:5acbbe3f4cf4 113
mjr 0:5acbbe3f4cf4 114 /**
mjr 0:5acbbe3f4cf4 115 *
mjr 0:5acbbe3f4cf4 116 * USBJoystick example
mjr 0:5acbbe3f4cf4 117 * @code
mjr 0:5acbbe3f4cf4 118 * #include "mbed.h"
mjr 0:5acbbe3f4cf4 119 * #include "USBJoystick.h"
mjr 0:5acbbe3f4cf4 120 *
mjr 0:5acbbe3f4cf4 121 * USBJoystick joystick;
mjr 0:5acbbe3f4cf4 122 *
mjr 0:5acbbe3f4cf4 123 * int main(void)
mjr 0:5acbbe3f4cf4 124 * {
mjr 0:5acbbe3f4cf4 125 * while (1)
mjr 0:5acbbe3f4cf4 126 * {
mjr 0:5acbbe3f4cf4 127 * joystick.move(20, 0);
mjr 0:5acbbe3f4cf4 128 * wait(0.5);
mjr 0:5acbbe3f4cf4 129 * }
mjr 0:5acbbe3f4cf4 130 * }
mjr 0:5acbbe3f4cf4 131 *
mjr 0:5acbbe3f4cf4 132 * @endcode
mjr 0:5acbbe3f4cf4 133 *
mjr 0:5acbbe3f4cf4 134 *
mjr 0:5acbbe3f4cf4 135 * @code
mjr 0:5acbbe3f4cf4 136 * #include "mbed.h"
mjr 0:5acbbe3f4cf4 137 * #include "USBJoystick.h"
mjr 0:5acbbe3f4cf4 138 * #include <math.h>
mjr 0:5acbbe3f4cf4 139 *
mjr 0:5acbbe3f4cf4 140 * USBJoystick joystick;
mjr 0:5acbbe3f4cf4 141 *
mjr 0:5acbbe3f4cf4 142 * int main(void)
mjr 0:5acbbe3f4cf4 143 * {
mjr 0:5acbbe3f4cf4 144 * while (1) {
mjr 0:5acbbe3f4cf4 145 * // Basic Joystick
mjr 0:5acbbe3f4cf4 146 * joystick.update(tx, y, z, buttonBits);
mjr 0:5acbbe3f4cf4 147 * wait(0.001);
mjr 0:5acbbe3f4cf4 148 * }
mjr 0:5acbbe3f4cf4 149 * }
mjr 0:5acbbe3f4cf4 150 * @endcode
mjr 0:5acbbe3f4cf4 151 */
mjr 0:5acbbe3f4cf4 152
mjr 0:5acbbe3f4cf4 153
mjr 0:5acbbe3f4cf4 154 class USBJoystick: public USBHID {
mjr 0:5acbbe3f4cf4 155 public:
mjr 0:5acbbe3f4cf4 156
mjr 0:5acbbe3f4cf4 157 /**
mjr 0:5acbbe3f4cf4 158 * Constructor
mjr 0:5acbbe3f4cf4 159 *
mjr 0:5acbbe3f4cf4 160 * @param vendor_id Your vendor_id (default: 0x1234)
mjr 0:5acbbe3f4cf4 161 * @param product_id Your product_id (default: 0x0002)
mjr 0:5acbbe3f4cf4 162 * @param product_release Your product_release (default: 0x0001)
mjr 0:5acbbe3f4cf4 163 */
mjr 35:e959ffba78fd 164 USBJoystick(uint16_t vendor_id, uint16_t product_id, uint16_t product_release,
mjr 35:e959ffba78fd 165 int waitForConnect, bool enableJoystick, bool useKB)
mjr 35:e959ffba78fd 166 : USBHID(16, 64, vendor_id, product_id, product_release, false)
mjr 35:e959ffba78fd 167 {
mjr 35:e959ffba78fd 168 _init();
mjr 35:e959ffba78fd 169 this->useKB = useKB;
mjr 35:e959ffba78fd 170 this->enableJoystick = enableJoystick;
mjr 35:e959ffba78fd 171 connect(waitForConnect);
mjr 35:e959ffba78fd 172 };
mjr 38:091e511ce8a0 173
mjr 38:091e511ce8a0 174 /* read a report from the LedWiz buffer */
mjr 38:091e511ce8a0 175 bool readLedWizMsg(LedWizMsg &msg)
mjr 38:091e511ce8a0 176 {
mjr 38:091e511ce8a0 177 return lwbuf.read(msg);
mjr 38:091e511ce8a0 178 }
mjr 0:5acbbe3f4cf4 179
mjr 39:b3815a1c3802 180 /* get the idle time settings, in milliseconds */
mjr 39:b3815a1c3802 181 uint32_t getKbIdle() const { return kbIdleTime * 4UL; }
mjr 39:b3815a1c3802 182 uint32_t getMediaIdle() const { return mediaIdleTime * 4UL; }
mjr 39:b3815a1c3802 183
mjr 39:b3815a1c3802 184
mjr 0:5acbbe3f4cf4 185 /**
mjr 35:e959ffba78fd 186 * Send a keyboard report. The argument gives the key state, in the standard
mjr 35:e959ffba78fd 187 * 6KRO USB keyboard report format: byte 0 is the modifier key bit mask, byte 1
mjr 35:e959ffba78fd 188 * is reserved (must be 0), and bytes 2-6 are the currently pressed keys, as
mjr 35:e959ffba78fd 189 * USB key codes.
mjr 35:e959ffba78fd 190 */
mjr 35:e959ffba78fd 191 bool kbUpdate(uint8_t data[8]);
mjr 35:e959ffba78fd 192
mjr 35:e959ffba78fd 193 /**
mjr 35:e959ffba78fd 194 * Send a media key update. The argument gives the bit mask of media keys
mjr 35:e959ffba78fd 195 * currently pressed. See the HID report descriptor for the order of bits.
mjr 35:e959ffba78fd 196 */
mjr 35:e959ffba78fd 197 bool mediaUpdate(uint8_t data);
mjr 35:e959ffba78fd 198
mjr 35:e959ffba78fd 199 /**
mjr 35:e959ffba78fd 200 * Update the joystick status
mjr 0:5acbbe3f4cf4 201 *
mjr 0:5acbbe3f4cf4 202 * @param x x-axis position
mjr 0:5acbbe3f4cf4 203 * @param y y-axis position
mjr 0:5acbbe3f4cf4 204 * @param z z-axis position
mjr 0:5acbbe3f4cf4 205 * @param buttons buttons state, as a bit mask (combination with '|' of JOY_Bn values)
mjr 0:5acbbe3f4cf4 206 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 207 */
mjr 11:bd9da7088e6e 208 bool update(int16_t x, int16_t y, int16_t z, uint32_t buttons, uint16_t status);
mjr 10:976666ffa4ef 209
mjr 10:976666ffa4ef 210 /**
mjr 21:5048e16cc9ef 211 * Update just the status
mjr 21:5048e16cc9ef 212 */
mjr 21:5048e16cc9ef 213 bool updateStatus(uint32_t stat);
mjr 21:5048e16cc9ef 214
mjr 21:5048e16cc9ef 215 /**
mjr 10:976666ffa4ef 216 * Write an exposure report. We'll fill out a report with as many pixels as
mjr 10:976666ffa4ef 217 * will fit in the packet, send the report, and update the index to the next
mjr 10:976666ffa4ef 218 * pixel to send. The caller should call this repeatedly to send reports for
mjr 10:976666ffa4ef 219 * all pixels.
mjr 10:976666ffa4ef 220 *
mjr 10:976666ffa4ef 221 * @param idx current index in pixel array, updated to point to next pixel to send
mjr 10:976666ffa4ef 222 * @param npix number of pixels in the overall array
mjr 10:976666ffa4ef 223 * @param pix pixel array
mjr 10:976666ffa4ef 224 */
mjr 47:df7a88cd249c 225 bool updateExposure(int &idx, int npix, const uint8_t *pix);
mjr 33:d832bcab089e 226
mjr 33:d832bcab089e 227 /**
mjr 33:d832bcab089e 228 * Write a configuration report.
mjr 33:d832bcab089e 229 *
mjr 33:d832bcab089e 230 * @param numOutputs the number of configured output channels
mjr 33:d832bcab089e 231 * @param unitNo the device unit number
mjr 40:cc0d9814522b 232 * @param plungerZero plunger zero calibration point
mjr 40:cc0d9814522b 233 * @param plungerMax plunger max calibration point
mjr 40:cc0d9814522b 234 * @param configured true if a configuration has been saved to flash from the host
mjr 33:d832bcab089e 235 */
mjr 40:cc0d9814522b 236 bool reportConfig(int numOutputs, int unitNo, int plungerZero, int plungerMax, bool configured);
mjr 40:cc0d9814522b 237
mjr 40:cc0d9814522b 238 /**
mjr 40:cc0d9814522b 239 * Write a device ID report.
mjr 40:cc0d9814522b 240 */
mjr 40:cc0d9814522b 241 bool reportID();
mjr 0:5acbbe3f4cf4 242
mjr 0:5acbbe3f4cf4 243 /**
mjr 35:e959ffba78fd 244 * Send a joystick report to the host
mjr 0:5acbbe3f4cf4 245 *
mjr 0:5acbbe3f4cf4 246 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 247 */
mjr 0:5acbbe3f4cf4 248 bool update();
mjr 9:fd65b0a94720 249
mjr 0:5acbbe3f4cf4 250 /**
mjr 0:5acbbe3f4cf4 251 * Move the cursor to (x, y)
mjr 0:5acbbe3f4cf4 252 *
mjr 0:5acbbe3f4cf4 253 * @param x x-axis position
mjr 0:5acbbe3f4cf4 254 * @param y y-axis position
mjr 0:5acbbe3f4cf4 255 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 256 */
mjr 0:5acbbe3f4cf4 257 bool move(int16_t x, int16_t y);
mjr 0:5acbbe3f4cf4 258
mjr 0:5acbbe3f4cf4 259 /**
mjr 0:5acbbe3f4cf4 260 * Set the z position
mjr 0:5acbbe3f4cf4 261 *
mjr 0:5acbbe3f4cf4 262 * @param z z-axis osition
mjr 0:5acbbe3f4cf4 263 */
mjr 0:5acbbe3f4cf4 264 bool setZ(int16_t z);
mjr 0:5acbbe3f4cf4 265
mjr 0:5acbbe3f4cf4 266 /**
mjr 0:5acbbe3f4cf4 267 * Press one or several buttons
mjr 0:5acbbe3f4cf4 268 *
mjr 0:5acbbe3f4cf4 269 * @param buttons button state, as a bitwise combination of JOY_Bn values
mjr 0:5acbbe3f4cf4 270 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 271 */
mjr 11:bd9da7088e6e 272 bool buttons(uint32_t buttons);
mjr 35:e959ffba78fd 273
mjr 35:e959ffba78fd 274 /* USB descriptor overrides */
mjr 35:e959ffba78fd 275 virtual uint8_t * configurationDesc();
mjr 35:e959ffba78fd 276 virtual uint8_t * reportDescN(int n);
mjr 0:5acbbe3f4cf4 277
mjr 0:5acbbe3f4cf4 278 /* USB descriptor string overrides */
mjr 0:5acbbe3f4cf4 279 virtual uint8_t *stringImanufacturerDesc();
mjr 0:5acbbe3f4cf4 280 virtual uint8_t *stringIserialDesc();
mjr 0:5acbbe3f4cf4 281 virtual uint8_t *stringIproductDesc();
mjr 35:e959ffba78fd 282
mjr 39:b3815a1c3802 283 /* set/get idle time */
mjr 39:b3815a1c3802 284 virtual void setIdleTime(int ifc, int rptid, int t)
mjr 39:b3815a1c3802 285 {
mjr 39:b3815a1c3802 286 // Remember the new value if operating on the keyboard. Remember
mjr 39:b3815a1c3802 287 // separate keyboard and media control idle times, in case the
mjr 39:b3815a1c3802 288 // host wants separate report rates.
mjr 39:b3815a1c3802 289 if (ifc == IFC_ID_KB)
mjr 39:b3815a1c3802 290 {
mjr 39:b3815a1c3802 291 if (rptid == REPORT_ID_KB)
mjr 39:b3815a1c3802 292 kbIdleTime = t;
mjr 39:b3815a1c3802 293 else if (rptid == REPORT_ID_MEDIA)
mjr 39:b3815a1c3802 294 mediaIdleTime = t;
mjr 39:b3815a1c3802 295 }
mjr 39:b3815a1c3802 296 }
mjr 39:b3815a1c3802 297 virtual uint8_t getIdleTime(int ifc, int rptid)
mjr 39:b3815a1c3802 298 {
mjr 39:b3815a1c3802 299 // Return the kb idle time if the kb interface is the one requested.
mjr 39:b3815a1c3802 300 if (ifc == IFC_ID_KB)
mjr 39:b3815a1c3802 301 {
mjr 39:b3815a1c3802 302 if (rptid == REPORT_ID_KB)
mjr 39:b3815a1c3802 303 return kbIdleTime;
mjr 39:b3815a1c3802 304 if (rptid == REPORT_ID_MEDIA)
mjr 39:b3815a1c3802 305 return mediaIdleTime;
mjr 39:b3815a1c3802 306 }
mjr 39:b3815a1c3802 307
mjr 39:b3815a1c3802 308 // we don't use idle times for other interfaces or report types
mjr 39:b3815a1c3802 309 return 0;
mjr 39:b3815a1c3802 310 }
mjr 39:b3815a1c3802 311
mjr 35:e959ffba78fd 312 /* callback overrides */
mjr 35:e959ffba78fd 313 virtual bool USBCallback_setConfiguration(uint8_t configuration);
mjr 35:e959ffba78fd 314 virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate)
mjr 35:e959ffba78fd 315 { return interface == 0 || interface == 1; }
mjr 38:091e511ce8a0 316
mjr 38:091e511ce8a0 317 virtual bool EP1_OUT_callback();
mjr 35:e959ffba78fd 318 virtual bool EP4_OUT_callback();
mjr 38:091e511ce8a0 319
mjr 0:5acbbe3f4cf4 320 private:
mjr 39:b3815a1c3802 321
mjr 39:b3815a1c3802 322 // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes.
mjr 39:b3815a1c3802 323 CircBuf<LedWizMsg, 64> lwbuf;
mjr 39:b3815a1c3802 324
mjr 35:e959ffba78fd 325 bool enableJoystick;
mjr 35:e959ffba78fd 326 bool useKB;
mjr 39:b3815a1c3802 327 uint8_t kbIdleTime;
mjr 39:b3815a1c3802 328 uint8_t mediaIdleTime;
mjr 6:cc35eb643e8f 329 int16_t _x;
mjr 6:cc35eb643e8f 330 int16_t _y;
mjr 6:cc35eb643e8f 331 int16_t _z;
mjr 11:bd9da7088e6e 332 uint16_t _buttonsLo;
mjr 11:bd9da7088e6e 333 uint16_t _buttonsHi;
mjr 10:976666ffa4ef 334 uint16_t _status;
mjr 38:091e511ce8a0 335
mjr 0:5acbbe3f4cf4 336 void _init();
mjr 0:5acbbe3f4cf4 337 };
mjr 0:5acbbe3f4cf4 338
mjr 38:091e511ce8a0 339 #endif