Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
USBJoystick/USBJoystick.h
- Committer:
- arnoz
- Date:
- 2021-10-01
- Revision:
- 116:7a67265d7c19
- Parent:
- 113:7330439f2ffc
File content as of revision 116:7a67265d7c19:
/* USBJoystick.h */ /* USB device example: Joystick*/ /* Copyright (c) 2011 ARM Limited. All rights reserved. */ /* Modified Mouse code for Joystick - WH 2012 */ #ifndef USBJOYSTICK_H #define USBJOYSTICK_H #include "USBHID.h" #include "circbuf.h" // Bufferd incoming LedWiz message structure struct LedWizMsg { uint8_t data[8]; }; // 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; /* Common usage */ enum JOY_BUTTON { JOY_B0 = 0x0001, JOY_B1 = 0x0002, JOY_B2 = 0x0004, JOY_B3 = 0x0008, JOY_B4 = 0x0010, JOY_B5 = 0x0020, JOY_B6 = 0x0040, JOY_B7 = 0x0080, JOY_B8 = 0x0100, JOY_B9 = 0x0200, JOY_B10 = 0x0400, JOY_B11 = 0x0800, JOY_B12 = 0x1000, JOY_B13 = 0x2000, JOY_B14 = 0x4000, JOY_B15 = 0x8000 }; /** * * USBJoystick example * @code * #include "mbed.h" * #include "USBJoystick.h" * * USBJoystick joystick; * * int main(void) * { * while (1) * { * joystick.move(20, 0); * wait(0.5); * } * } * * @endcode * * * @code * #include "mbed.h" * #include "USBJoystick.h" * #include <math.h> * * USBJoystick joystick; * * int main(void) * { * while (1) { * // Basic Joystick * joystick.update(tx, y, z, buttonBits); * wait(0.001); * } * } * @endcode */ class USBJoystick: public USBHID { public: // Length of our joystick reports. Important: This must be kept in sync // with the actual joystick report format sent in update(). static const int reportLen = 14; // Joystick axis report format static const int AXIS_FORMAT_XYZ = 0; // nudge on X/Y, plunger on Z static const int AXIS_FORMAT_RXRYRZ = 1; // nudge on Rx/Ry, plunger on Rz /** * Constructor * * @param vendor_id Your vendor_id (default: 0x1234) * @param product_id Your product_id (default: 0x0002) * @param product_release Your product_release (default: 0x0001) * @param waitforConnect don't return until the connection is established * @param enableJoystick enable the joystick interface (if false, uses the OUT-only LedWiz-style interface) * @param axisFormat an AXIS_FORMAT_xxx value specifying the joystick axis report format * @param useKB enable the USB keyboard reporting interface */ USBJoystick(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, int waitForConnect, bool enableJoystick, int axisFormat, bool useKB) : USBHID(16, 64, vendor_id, product_id, product_release, false) { _init(); this->useKB = useKB; this->enableJoystick = enableJoystick; this->axisFormat = axisFormat; connect(waitForConnect); }; /* read a report from the LedWiz buffer */ bool readLedWizMsg(LedWizMsg &msg) { 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 * is reserved (must be 0), and bytes 2-6 are the currently pressed keys, as * USB key codes. */ bool kbUpdate(uint8_t data[8]); /** * Send a media key update. The argument gives the bit mask of media keys * currently pressed. See the HID report descriptor for the order of bits. */ bool mediaUpdate(uint8_t data); /** * Update the joystick status * * @param x x-axis position * @param y y-axis position * @param z z-axis position * @param buttons buttons state, as a bit mask (combination with '|' of JOY_Bn values) * @returns true if there is no error, false otherwise */ bool update(int16_t x, int16_t y, int16_t z, uint32_t buttons, uint16_t status); /** * Update just the status */ bool updateStatus(uint32_t stat); /** * Write the plunger status report header. * * Note that we automatically add the "calibration mode" bit to the flags, * so the caller doesn't have to include this. The caller only has to * include the sensor-specific flags. * * @param npix number of pixels in the sensor (0 for non-imaging sensors) * @param pos the decoded plunger position, or -1 if none detected * @param flags (see USBProtocol.h, message type 2A, "byte 7" bit flags) * @param avgScanTime average sensor scan time in microseconds * @param processingTime time in microseconds to process the current frame */ bool sendPlungerStatus(int npix, int pos, int flags, uint32_t avgScanTime, uint32_t processingTime); /** * Send a secondary plunger status report header. * * @param nativeScale upper bound of the sensor's native reading scale * @param jitterLo low end of jitter filter window (in sensor native scale units) * @param jitterHi high end of jitter filter window * @param rawPos raw position reading, before applying jitter filter * @param axcTime auto-exposure time in microseconds */ bool sendPlungerStatus2( int nativeScale, int jitterLo, int jitterHi, int rawPos, int axcTime); /** * Send a barcode plunger status report header. * * @param nbits number of bits in bar code * @param codetype bar code type (1=Gray code/Manchester bit coding) * @param pixofs pixel offset of first bit * @param raw raw bar code bits * @param mask mask of successfully read bar code bits */ bool sendPlungerStatusBarcode( int nbits, int codetype, int startOfs, int pixPerBit, int raw, int mask); /** * Send a quadrature sensor status report header. * * @param chA channel "A" reading * @param chB channel "B" reading */ bool sendPlungerStatusQuadrature(int chA, int chB); /** * Send a VCNL4010 sensor extra status report * * @param proxCount raw proximity count reading from the sensor */ bool sendPlungerStatusVCNL4010(int filteredProxCount, int rawProxCount); /** * Write an exposure report. We'll fill out a report with as many pixels as * will fit in the packet, send the report, and update the index to the next * pixel to send. The caller should call this repeatedly to send reports for * all pixels. * * @param idx current index in pixel array, updated to point to next pixel to send * @param npix number of pixels in the overall array * @param pix pixel array */ bool sendPlungerPix(int &idx, int npix, const uint8_t *pix); /** * Write a configuration report. * * @param numOutputs the number of configured output channels * @param unitNo the device unit number * @param plungerZero plunger zero calibration point * @param plungerMax plunger max calibration point * @param plungerRlsTime measured plunger release time, in milliseconds * @param configured true if a configuration has been saved to flash from the host * @param sbxpbx true if this firmware version supports SBX/PBX protocol extensions * @param newAccelFeatures true if this firmware version supports the new accelerometer * features (adjustable dynamic range, adjustable auto-centering mode time, * auto-centering mode on/off) * @param flashStatusFeature true if this firmware version supports the flash write * success flags in the status bits * @param reportTimingFeatures true if this firmware version supports configurable * joystick report timing * @param chimeLogicFeature true if this firmware version supports Chime Logic * @param freeHeapBytes number of free bytes in the malloc heap */ bool reportConfig(int numOutputs, int unitNo, int plungerZero, int plungerMax, int plunterRlsTime, bool configured, bool sbxpbx, bool newAccelFeatures, bool flashStatusFeature, bool reportTimingFeatures, bool chimeLogicFeature, size_t freeHeapBytes); /** * Write a configuration variable query report. * * @param data the 7-byte data variable buffer, starting with the variable ID byte */ bool reportConfigVar(const uint8_t *data); /** * Write a device ID report. */ bool reportID(int index); /** * Write a build data report * * @param date build date plus time, in __DATE__ " " __TIME__ macro format ("Mon dd, yyyy hh:mm:ss") */ bool reportBuildInfo(const char *date); /** * Write a physical button status report. * * @param numButtons the number of buttons * @param state the button states, 1 bit per button, 8 buttons per byte, * starting with button 0 in the low-order bit (0x01) of the * first byte */ bool reportButtonStatus(int numButtons, const uint8_t *state); /** * Write an IR raw sensor input report. This reports a set of raw * timing reports for input read from the IR sensor, for learning * remote purposes. * * @param n number of items to report, up to maxRawIR * @param data items to report; each is a timing reading, in 2us * increments, with the low bit in each report set to 0 for * a "space" (IR off) or 1 for a "mark" (IR on) */ bool reportRawIR(int n, const uint16_t *data); /** * Maximum number of raw IR readings that can be sent in one report * via reportRawIR(). */ static const int maxRawIR = (reportLen - 3)/2; /** * Write an IR input report. This reports a decoded command read in * learning mode to the host. * * @param pro protocol ID (see IRProtocolID.h) * @param flags bit flags: 0x02 = protocol uses dittos * @param code decoded command code */ bool reportIRCode(uint8_t pro, uint8_t flags, uint64_t code); /** * Send a joystick report to the host * * @returns true if there is no error, false otherwise */ bool update(); /** * Move the cursor to (x, y) * * @param x x-axis position * @param y y-axis position * @returns true if there is no error, false otherwise */ bool move(int16_t x, int16_t y); /** * Set the z position * * @param z z-axis osition */ bool setZ(int16_t z); /** * Press one or several buttons * * @param buttons button state, as a bitwise combination of JOY_Bn values * @returns true if there is no error, false otherwise */ bool buttons(uint32_t buttons); /* USB descriptor overrides */ virtual const uint8_t *configurationDesc(); virtual const uint8_t *reportDesc(int idx, uint16_t &len); /* USB descriptor string overrides */ virtual const uint8_t *stringImanufacturerDesc(); virtual const uint8_t *stringIserialDesc(); virtual const 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) { return interface == 0 || interface == 1; } virtual bool EP1_OUT_callback(); virtual bool EP4_OUT_callback(); private: // Incoming LedWiz message buffer. Each LedWiz message is exactly 8 bytes. CircBuf<LedWizMsg, 16> lwbuf; // enable the joystick interface bool enableJoystick; // joystick axis reporting format bool axisFormat; // enable the keyboard interface for button inputs bool useKB; // keyboard maximum idle time between reports uint8_t kbIdleTime; // media maximum idle time between reports uint8_t mediaIdleTime; // current X, Y, Z axis values int16_t _x; int16_t _y; int16_t _z; // joystick button status bits uint16_t _buttonsLo; uint16_t _buttonsHi; // special status flag bits uint16_t _status; void _init(); }; #endif