Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed FastIO FastPWM USBDevice
Diff: USBJoystick/USBJoystick.h
- Revision:
- 39:b3815a1c3802
- Parent:
- 38:091e511ce8a0
- Child:
- 40:cc0d9814522b
--- a/USBJoystick/USBJoystick.h Tue Jan 05 05:23:07 2016 +0000 +++ b/USBJoystick/USBJoystick.h Mon Jan 11 21:08:36 2016 +0000 @@ -8,12 +8,20 @@ #include "USBHID.h" +// Bufferd incoming LedWiz message structure struct LedWizMsg { uint8_t data[8]; }; -// circular buffer for incoming reports +// Circular buffer for incoming reports. We write reports in the IRQ +// handler, and we read reports in the main loop in normal application +// (non-IRQ) context. +// +// The design is organically safe for IRQ threading; there are no critical +// sections. The IRQ context has exclusive access to the write pointer, +// and the application context has exclusive access to the read pointer, +// so there are no test-and-set or read-and-modify race conditions. template<class T, int cnt> class CircBuf { public: @@ -23,11 +31,13 @@ } // Read an item from the buffer. Returns true if an item was available, - // false if the buffer was empty. + // false if the buffer was empty. (Called in the main loop, in application + // context.) bool read(T &result) { if (iRead != iWrite) { + //{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]);} memcpy(&result, &buf[iRead], sizeof(T)); iRead = advance(iRead); return true; @@ -36,12 +46,14 @@ return false; } + // Write an item to the buffer. (Called in the IRQ handler, in interrupt + // context.) bool write(const T &item) { int nxt = advance(iWrite); if (nxt != iRead) { - memcpy(&buf[nxt], &item, sizeof(T)); + memcpy(&buf[iWrite], &item, sizeof(T)); iWrite = nxt; return true; } @@ -52,7 +64,8 @@ private: int advance(int i) { - return i + 1 >= cnt ? 0 : i + 1; + ++i; + return i < cnt ? i : 0; } int iRead; @@ -60,6 +73,10 @@ T buf[cnt]; }; +// interface IDs +const uint8_t IFC_ID_JS = 0; // joystick + LedWiz interface +const uint8_t IFC_ID_KB = 1; // keyboard interface + // keyboard interface report IDs const uint8_t REPORT_ID_KB = 1; const uint8_t REPORT_ID_MEDIA = 2; @@ -151,7 +168,6 @@ _init(); this->useKB = useKB; this->enableJoystick = enableJoystick; - reqTimer.start(); connect(waitForConnect); }; @@ -161,6 +177,11 @@ return lwbuf.read(msg); } + /* get the idle time settings, in milliseconds */ + uint32_t getKbIdle() const { return kbIdleTime * 4UL; } + uint32_t getMediaIdle() const { return mediaIdleTime * 4UL; } + + /** * Send a keyboard report. The argument gives the key state, in the standard * 6KRO USB keyboard report format: byte 0 is the modifier key bit mask, byte 1 @@ -251,6 +272,35 @@ virtual uint8_t *stringIserialDesc(); virtual uint8_t *stringIproductDesc(); + /* set/get idle time */ + virtual void setIdleTime(int ifc, int rptid, int t) + { + // Remember the new value if operating on the keyboard. Remember + // separate keyboard and media control idle times, in case the + // host wants separate report rates. + if (ifc == IFC_ID_KB) + { + if (rptid == REPORT_ID_KB) + kbIdleTime = t; + else if (rptid == REPORT_ID_MEDIA) + mediaIdleTime = t; + } + } + virtual uint8_t getIdleTime(int ifc, int rptid) + { + // Return the kb idle time if the kb interface is the one requested. + if (ifc == IFC_ID_KB) + { + if (rptid == REPORT_ID_KB) + return kbIdleTime; + if (rptid == REPORT_ID_MEDIA) + return mediaIdleTime; + } + + // we don't use idle times for other interfaces or report types + return 0; + } + /* callback overrides */ virtual bool USBCallback_setConfiguration(uint8_t configuration); virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate) @@ -260,9 +310,14 @@ virtual bool EP4_OUT_callback(); private: - Timer reqTimer; + + // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes. + CircBuf<LedWizMsg, 64> lwbuf; + bool enableJoystick; bool useKB; + uint8_t kbIdleTime; + uint8_t mediaIdleTime; int16_t _x; int16_t _y; int16_t _z; @@ -270,9 +325,6 @@ uint16_t _buttonsHi; uint16_t _status; - // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes. - CircBuf<LedWizMsg, 64> lwbuf; - void _init(); };