Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri Feb 26 18:42:03 2016 +0000
Revision:
48:058ace2aed1d
Parent:
47:df7a88cd249c
Child:
52:8298b2a73eb2
New plunger processing 1

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 48:058ace2aed1d 228 * Write the special extended exposure report with additional data about the
mjr 48:058ace2aed1d 229 * scan.
mjr 48:058ace2aed1d 230 *
mjr 48:058ace2aed1d 231 * @param edgePos the pixel position of the detected edge in this image, or -1 if none detected
mjr 48:058ace2aed1d 232 * @param dir detected sensor orientation: 1 for standard, -1 for reversed, 0 for unknown
mjr 48:058ace2aed1d 233 * @param avgScanTime average sensor scan time in microseconds
mjr 48:058ace2aed1d 234 * @param processingTime time in microseconds to process the current frame
mjr 48:058ace2aed1d 235 */
mjr 48:058ace2aed1d 236 bool updateExposureExt(int edgePos, int dir, uint32_t avgScanTime, uint32_t processingTime);
mjr 48:058ace2aed1d 237
mjr 48:058ace2aed1d 238 /**
mjr 33:d832bcab089e 239 * Write a configuration report.
mjr 33:d832bcab089e 240 *
mjr 33:d832bcab089e 241 * @param numOutputs the number of configured output channels
mjr 33:d832bcab089e 242 * @param unitNo the device unit number
mjr 40:cc0d9814522b 243 * @param plungerZero plunger zero calibration point
mjr 40:cc0d9814522b 244 * @param plungerMax plunger max calibration point
mjr 40:cc0d9814522b 245 * @param configured true if a configuration has been saved to flash from the host
mjr 33:d832bcab089e 246 */
mjr 40:cc0d9814522b 247 bool reportConfig(int numOutputs, int unitNo, int plungerZero, int plungerMax, bool configured);
mjr 40:cc0d9814522b 248
mjr 40:cc0d9814522b 249 /**
mjr 40:cc0d9814522b 250 * Write a device ID report.
mjr 40:cc0d9814522b 251 */
mjr 40:cc0d9814522b 252 bool reportID();
mjr 0:5acbbe3f4cf4 253
mjr 0:5acbbe3f4cf4 254 /**
mjr 35:e959ffba78fd 255 * Send a joystick report to the host
mjr 0:5acbbe3f4cf4 256 *
mjr 0:5acbbe3f4cf4 257 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 258 */
mjr 0:5acbbe3f4cf4 259 bool update();
mjr 9:fd65b0a94720 260
mjr 0:5acbbe3f4cf4 261 /**
mjr 0:5acbbe3f4cf4 262 * Move the cursor to (x, y)
mjr 0:5acbbe3f4cf4 263 *
mjr 0:5acbbe3f4cf4 264 * @param x x-axis position
mjr 0:5acbbe3f4cf4 265 * @param y y-axis position
mjr 0:5acbbe3f4cf4 266 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 267 */
mjr 0:5acbbe3f4cf4 268 bool move(int16_t x, int16_t y);
mjr 0:5acbbe3f4cf4 269
mjr 0:5acbbe3f4cf4 270 /**
mjr 0:5acbbe3f4cf4 271 * Set the z position
mjr 0:5acbbe3f4cf4 272 *
mjr 0:5acbbe3f4cf4 273 * @param z z-axis osition
mjr 0:5acbbe3f4cf4 274 */
mjr 0:5acbbe3f4cf4 275 bool setZ(int16_t z);
mjr 0:5acbbe3f4cf4 276
mjr 0:5acbbe3f4cf4 277 /**
mjr 0:5acbbe3f4cf4 278 * Press one or several buttons
mjr 0:5acbbe3f4cf4 279 *
mjr 0:5acbbe3f4cf4 280 * @param buttons button state, as a bitwise combination of JOY_Bn values
mjr 0:5acbbe3f4cf4 281 * @returns true if there is no error, false otherwise
mjr 0:5acbbe3f4cf4 282 */
mjr 11:bd9da7088e6e 283 bool buttons(uint32_t buttons);
mjr 35:e959ffba78fd 284
mjr 35:e959ffba78fd 285 /* USB descriptor overrides */
mjr 48:058ace2aed1d 286 virtual const uint8_t *configurationDesc();
mjr 48:058ace2aed1d 287 virtual const uint8_t *reportDescN(int n);
mjr 0:5acbbe3f4cf4 288
mjr 0:5acbbe3f4cf4 289 /* USB descriptor string overrides */
mjr 48:058ace2aed1d 290 virtual const uint8_t *stringImanufacturerDesc();
mjr 48:058ace2aed1d 291 virtual const uint8_t *stringIserialDesc();
mjr 48:058ace2aed1d 292 virtual const uint8_t *stringIproductDesc();
mjr 35:e959ffba78fd 293
mjr 39:b3815a1c3802 294 /* set/get idle time */
mjr 39:b3815a1c3802 295 virtual void setIdleTime(int ifc, int rptid, int t)
mjr 39:b3815a1c3802 296 {
mjr 39:b3815a1c3802 297 // Remember the new value if operating on the keyboard. Remember
mjr 39:b3815a1c3802 298 // separate keyboard and media control idle times, in case the
mjr 39:b3815a1c3802 299 // host wants separate report rates.
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 kbIdleTime = t;
mjr 39:b3815a1c3802 304 else if (rptid == REPORT_ID_MEDIA)
mjr 39:b3815a1c3802 305 mediaIdleTime = t;
mjr 39:b3815a1c3802 306 }
mjr 39:b3815a1c3802 307 }
mjr 39:b3815a1c3802 308 virtual uint8_t getIdleTime(int ifc, int rptid)
mjr 39:b3815a1c3802 309 {
mjr 39:b3815a1c3802 310 // Return the kb idle time if the kb interface is the one requested.
mjr 39:b3815a1c3802 311 if (ifc == IFC_ID_KB)
mjr 39:b3815a1c3802 312 {
mjr 39:b3815a1c3802 313 if (rptid == REPORT_ID_KB)
mjr 39:b3815a1c3802 314 return kbIdleTime;
mjr 39:b3815a1c3802 315 if (rptid == REPORT_ID_MEDIA)
mjr 39:b3815a1c3802 316 return mediaIdleTime;
mjr 39:b3815a1c3802 317 }
mjr 39:b3815a1c3802 318
mjr 39:b3815a1c3802 319 // we don't use idle times for other interfaces or report types
mjr 39:b3815a1c3802 320 return 0;
mjr 39:b3815a1c3802 321 }
mjr 39:b3815a1c3802 322
mjr 35:e959ffba78fd 323 /* callback overrides */
mjr 35:e959ffba78fd 324 virtual bool USBCallback_setConfiguration(uint8_t configuration);
mjr 35:e959ffba78fd 325 virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate)
mjr 35:e959ffba78fd 326 { return interface == 0 || interface == 1; }
mjr 38:091e511ce8a0 327
mjr 38:091e511ce8a0 328 virtual bool EP1_OUT_callback();
mjr 35:e959ffba78fd 329 virtual bool EP4_OUT_callback();
mjr 38:091e511ce8a0 330
mjr 0:5acbbe3f4cf4 331 private:
mjr 39:b3815a1c3802 332
mjr 39:b3815a1c3802 333 // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes.
mjr 39:b3815a1c3802 334 CircBuf<LedWizMsg, 64> lwbuf;
mjr 39:b3815a1c3802 335
mjr 35:e959ffba78fd 336 bool enableJoystick;
mjr 35:e959ffba78fd 337 bool useKB;
mjr 39:b3815a1c3802 338 uint8_t kbIdleTime;
mjr 39:b3815a1c3802 339 uint8_t mediaIdleTime;
mjr 6:cc35eb643e8f 340 int16_t _x;
mjr 6:cc35eb643e8f 341 int16_t _y;
mjr 6:cc35eb643e8f 342 int16_t _z;
mjr 11:bd9da7088e6e 343 uint16_t _buttonsLo;
mjr 11:bd9da7088e6e 344 uint16_t _buttonsHi;
mjr 10:976666ffa4ef 345 uint16_t _status;
mjr 38:091e511ce8a0 346
mjr 0:5acbbe3f4cf4 347 void _init();
mjr 0:5acbbe3f4cf4 348 };
mjr 0:5acbbe3f4cf4 349
mjr 38:091e511ce8a0 350 #endif