![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
WIP PID
Dependencies: USBDEVICE USBJoystick mbed
Fork of USBJoystick_HelloWorld2 by
Revision 1:caf8a4134cbf, committed 2018-07-07
- Comitter:
- Cirrus01
- Date:
- Sat Jul 07 10:48:38 2018 +0000
- Parent:
- 0:e43878690c0e
- Commit message:
- First
Changed in this revision
diff -r e43878690c0e -r caf8a4134cbf USBDEVICE.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDEVICE.lib Sat Jul 07 10:48:38 2018 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/USBDEVICE/#d9c7334e2183
diff -r e43878690c0e -r caf8a4134cbf USBDevice.lib --- a/USBDevice.lib Thu Jan 05 14:23:14 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/USBDevice/#01321bd6ff89
diff -r e43878690c0e -r caf8a4134cbf USBJoystick.lib --- a/USBJoystick.lib Thu Jan 05 14:23:14 2017 +0000 +++ b/USBJoystick.lib Sat Jul 07 10:48:38 2018 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/wim/code/USBJoystick/#e086541742c3 +https://os.mbed.com/users/Cirrus01/code/USBJoystick/#7f1e68e6da0c
diff -r e43878690c0e -r caf8a4134cbf USBPID/USBPID.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBPID/USBPID.cpp Sat Jul 07 10:48:38 2018 +0000 @@ -0,0 +1,276 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "stdint.h" +#include "USBHAL.h" +#include "USBPID.h" + + +USBPID::USBPID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release) +{ + output_length = output_report_length; + input_length = input_report_length; + if(connect) { + USBDevice::connect(); + } +} + + +bool USBPID::send(PID_REPORT *report) +{ + return write(EPINT_IN, report->data, report->length, MAX_PID_REPORT_SIZE); +} + +bool USBPID::sendNB(PID_REPORT *report) +{ + return writeNB(EPINT_IN, report->data, report->length, MAX_PID_REPORT_SIZE); +} + + +bool USBPID::read(PID_REPORT *report) +{ + uint32_t bytesRead = 0; + bool result; + result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_PID_REPORT_SIZE); + if(!readStart(EPINT_OUT, MAX_PID_REPORT_SIZE)) + return false; + report->length = bytesRead; + return result; +} + + +bool USBPID::readNB(PID_REPORT *report) +{ + uint32_t bytesRead = 0; + bool result; + result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_PID_REPORT_SIZE); + // if readEP_NB did not succeed, does not issue a readStart + if (!result) + return false; + report->length = bytesRead; + if(!readStart(EPINT_OUT, MAX_PID_REPORT_SIZE)) + return false; + return result; +} + + +uint16_t USBPID::reportDescLength() { + reportDesc(); + return reportLength; +} + + + +// +// Route callbacks from lower layers to class(es) +// + + +// Called in ISR context +// Called by USBDevice on Endpoint0 request +// This is used to handle extensions to standard requests +// and class specific requests +// Return true if class handles this request +bool USBPID::USBCallback_request() { + bool success = false; + CONTROL_TRANSFER * transfer = getTransferPtr(); + uint8_t *PIDDescriptor; + + // Process additional standard requests + + if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) + { + switch (transfer->setup.bRequest) + { + case GET_DESCRIPTOR: + switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) + { + case REPORT_DESCRIPTOR: + if ((reportDesc() != NULL) \ + && (reportDescLength() != 0)) + { + transfer->remaining = reportDescLength(); + transfer->ptr = reportDesc(); + transfer->direction = DEVICE_TO_HOST; + success = true; + } + break; + case PID_DESCRIPTOR: + // Find the PID descriptor, after the configuration descriptor + PIDDescriptor = findDescriptor(PID_DESCRIPTOR); + if (PIDDescriptor != NULL) + { + transfer->remaining = PID_DESCRIPTOR_LENGTH; + transfer->ptr = PIDDescriptor; + transfer->direction = DEVICE_TO_HOST; + success = true; + } + break; + + default: + break; + } + break; + default: + break; + } + } + + // Process class-specific requests + + if (transfer->setup.bmRequestType.Type == CLASS_TYPE) + { + switch (transfer->setup.bRequest) + { + case SET_REPORT: + // First byte will be used for report ID + outputReport.data[0] = transfer->setup.wValue & 0xff; + outputReport.length = transfer->setup.wLength + 1; + + transfer->remaining = sizeof(outputReport.data) - 1; + transfer->ptr = &outputReport.data[1]; + transfer->direction = HOST_TO_DEVICE; + transfer->notify = true; + success = true; + default: + break; + } + } + + return success; +} + + +#define DEFAULT_CONFIGURATION (1) + + +// Called in ISR context +// Set configuration. Return false if the +// configuration is not supported +bool USBPID::USBCallback_setConfiguration(uint8_t configuration) { + if (configuration != DEFAULT_CONFIGURATION) { + return false; + } + + // Configure endpoints > 0 + addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); + addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT); + + // We activate the endpoint to be able to recceive data + readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); + return true; +} + + +uint8_t * USBPID::stringIinterfaceDesc() { + static uint8_t stringIinterfaceDescriptor[] = { + 0x08, //bLength + STRING_DESCRIPTOR, //bDescriptorType 0x03 + 'P',0,'I',0,'D',0, //bString iInterface - PID + }; + return stringIinterfaceDescriptor; +} + +uint8_t * USBPID::stringIproductDesc() { + static uint8_t stringIproductDescriptor[] = { + 0x16, //bLength + STRING_DESCRIPTOR, //bDescriptorType 0x03 + 'P',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - PID device + }; + return stringIproductDescriptor; +} + + + +uint8_t * USBPID::reportDesc() { + static uint8_t reportDescriptor[] = { + 0x06, LSB(0xFFAB), MSB(0xFFAB), + 0x0A, LSB(0x0200), MSB(0x0200), + 0xA1, 0x01, // Collection 0x01 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, input_length, // report count + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + 0x95, output_length,// report count + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection + + }; + reportLength = sizeof(reportDescriptor); + return reportDescriptor; +} + +#define DEFAULT_CONFIGURATION (1) +#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ + + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ + + (1 * PID_DESCRIPTOR_LENGTH) \ + + (2 * ENDPOINT_DESCRIPTOR_LENGTH)) + +uint8_t * USBPID::configurationDesc() { + static uint8_t configurationDescriptor[] = { + CONFIGURATION_DESCRIPTOR_LENGTH,// bLength + CONFIGURATION_DESCRIPTOR, // bDescriptorType + LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) + MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) + 0x01, // bNumInterfaces + DEFAULT_CONFIGURATION, // bConfigurationValue + 0x00, // iConfiguration + C_RESERVED | C_SELF_POWERED, // bmAttributes + C_POWER(0), // bMaxPower + + INTERFACE_DESCRIPTOR_LENGTH, // bLength + INTERFACE_DESCRIPTOR, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + PID_CLASS, // bInterfaceClass + PID_SUBCLASS_NONE, // bInterfaceSubClass + PID_PROTOCOL_NONE, // bInterfaceProtocol + 0x00, // iInterface + + PID_DESCRIPTOR_LENGTH, // bLength + PID_DESCRIPTOR, // bDescriptorType + LSB(PID_VERSION_1_11), // bcdPID (LSB) + MSB(PID_VERSION_1_11), // bcdPID (MSB) + 0x00, // bCountryCode + 0x01, // bNumDescriptors + REPORT_DESCRIPTOR, // bDescriptorType + (uint8_t)(LSB(this->reportDescLength())), // wDescriptorLength (LSB) + (uint8_t)(MSB(this->reportDescLength())), // wDescriptorLength (MSB) + + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_IN), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) + + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_OUT), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) + }; + return configurationDescriptor; +}
diff -r e43878690c0e -r caf8a4134cbf USBPID/USBPID.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBPID/USBPID.h Sat Jul 07 10:48:38 2018 +0000 @@ -0,0 +1,172 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USB_PID_H +#define USB_PID_H + +/* These headers are included for child class. */ +#include "USBEndpoints.h" +#include "USBDescriptor.h" +#include "USBDevice_Types.h" + +#include "USBPID_Types.h" +#include "USBDevice.h" + + +/** + * USBPID example + * @code + * #include "mbed.h" + * #include "USBPID.h" + * + * USBPID pid; + * PID_REPORT recv; + * BusOut leds(LED1,LED2,LED3,LED4); + * + * int main(void) { + * while (1) { + * pid.read(&recv); + * leds = recv.data[0]; + * } + * } + * @endcode + */ + +class USBPID: public USBDevice { +public: + + /** + * Constructor + * + * @param output_report_length Maximum length of a sent report (up to 64 bytes) (default: 64 bytes) + * @param input_report_length Maximum length of a received report (up to 64 bytes) (default: 64 bytes) + * @param vendor_id Your vendor_id + * @param product_id Your product_id + * @param product_release Your preoduct_release + * @param connect Connect the device + */ + USBPID(uint8_t output_report_length = 64, uint8_t input_report_length = 64, uint16_t vendor_id = 0x1209, uint16_t product_id = 0x0001, uint16_t product_release = 0x0001, bool connect = true); + + + /** + * Send a Report. warning: blocking + * + * @param report Report which will be sent (a report is defined by all data and the length) + * @returns true if successful + */ + bool send(PID_REPORT *report); + + + /** + * Send a Report. warning: non blocking + * + * @param report Report which will be sent (a report is defined by all data and the length) + * @returns true if successful + */ + bool sendNB(PID_REPORT *report); + + /** + * Read a report: blocking + * + * @param report pointer to the report to fill + * @returns true if successful + */ + bool read(PID_REPORT * report); + + /** + * Read a report: non blocking + * + * @param report pointer to the report to fill + * @returns true if successful + */ + bool readNB(PID_REPORT * report); + +protected: + uint16_t reportLength; + + /* + * Get the Report descriptor + * + * @returns pointer to the report descriptor + */ + virtual uint8_t * reportDesc(); + + /* + * Get the length of the report descriptor + * + * @returns the length of the report descriptor + */ + virtual uint16_t reportDescLength(); + + /* + * Get string product descriptor + * + * @returns pointer to the string product descriptor + */ + virtual uint8_t * stringIproductDesc(); + + /* + * Get string interface descriptor + * + * @returns pointer to the string interface descriptor + */ + virtual uint8_t * stringIinterfaceDesc(); + + /* + * Get configuration descriptor + * + * @returns pointer to the configuration descriptor + */ + virtual uint8_t * configurationDesc(); + + + /* + * PID Report received by SET_REPORT request. Warning: Called in ISR context + * First byte of data will be the report ID + * + * @param report Data and length received + */ + virtual void PID_callbackSetReport(PID_REPORT *report){}; + + + /* + * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context + * This is used to handle extensions to standard requests + * and class specific requests + * + * @returns true if class handles this request + */ + virtual bool USBCallback_request(); + + + /* + * Called by USBDevice layer. Set configuration of the device. + * For instance, you can add all endpoints that you need on this function. + * + * @param configuration Number of the configuration + * @returns true if class handles this request + */ + virtual bool USBCallback_setConfiguration(uint8_t configuration); + +private: + PID_REPORT outputReport; + uint8_t output_length; + uint8_t input_length; +}; + +#endif
diff -r e43878690c0e -r caf8a4134cbf USBPID/USBPID_Types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBPID/USBPID_Types.h Sat Jul 07 10:48:38 2018 +0000 @@ -0,0 +1,92 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USBCLASS_PID_TYPES +#define USBCLASS_PID_TYPES + +#include <stdint.h> + +/* */ +#define PID_VERSION_1_0 (0x0100) + +/* PID Class */ +#define PID_CLASS (15) // 0x0F +#define PID_SUBCLASS_NONE (0) +#define PID_PROTOCOL_NONE (0) + +/* Descriptors */ +#define PID_DESCRIPTOR (33) +#define PID_DESCRIPTOR_LENGTH (0x09) +#define REPORT_DESCRIPTOR (34) + +/* Class requests */ +#define GET_REPORT (0x1) +#define GET_IDLE (0x2) +#define SET_REPORT (0x9) +#define SET_IDLE (0xa) + +/* HID Class Report Descriptor */ +/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */ +/* of data as per HID Class standard */ + +/* Main items */ +#define INPUT(size) (0x80 | size) +#define OUTPUT(size) (0x90 | size) +#define FEATURE(size) (0xb0 | size) +#define COLLECTION(size) (0xa0 | size) +#define END_COLLECTION(size) (0xc0 | size) + +/* Global items */ +#define USAGE_PAGE(size) (0x04 | size) +#define LOGICAL_MINIMUM(size) (0x14 | size) +#define LOGICAL_MAXIMUM(size) (0x24 | size) +#define PHYSICAL_MINIMUM(size) (0x34 | size) +#define PHYSICAL_MAXIMUM(size) (0x44 | size) +#define UNIT_EXPONENT(size) (0x54 | size) +#define UNIT(size) (0x64 | size) +#define REPORT_SIZE(size) (0x74 | size) +#define REPORT_ID(size) (0x84 | size) +#define REPORT_COUNT(size) (0x94 | size) +#define PUSH(size) (0xa4 | size) +#define POP(size) (0xb4 | size) + +/* Local items */ +#define USAGE(size) (0x08 | size) +#define USAGE_O(size) (0x0b | size) +#define USAGE_MINIMUM(size) (0x18 | size) +#define USAGE_MAXIMUM(size) (0x28 | size) +#define DESIGNATOR_INDEX(size) (0x38 | size) +#define DESIGNATOR_MINIMUM(size) (0x48 | size) +#define DESIGNATOR_MAXIMUM(size) (0x58 | size) +#define STRING_INDEX(size) (0x78 | size) +#define STRING_MINIMUM(size) (0x88 | size) +#define STRING_MAXIMUM(size) (0x98 | size) +#define DELIMITER(size) (0xa8 | size) + +/* PID Report */ +/* Where report IDs are used the first byte of 'data' will be the */ +/* report ID and 'length' will include this report ID byte. */ + +#define MAX_PID_REPORT_SIZE (64) + +typedef struct { + uint32_t length; + uint8_t data[MAX_PID_REPORT_SIZE]; +} PID_REPORT; + +#endif \ No newline at end of file
diff -r e43878690c0e -r caf8a4134cbf config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.h Sat Jul 07 10:48:38 2018 +0000 @@ -0,0 +1,86 @@ +#define TARGET_STM32F4XX +#define NUM_OF_BUTTONS 32 +#define NUM_OF_HAT_BUTTONS 4 +#define SYSTEM_CLOCK_HZ 96000000 // 96MHz + +// Joystick button input pin assignments. +// +// You can wire up to 32 GPIO ports to buttons (equipped with +// momentary switches). Connect each switch between the desired +// GPIO port and ground (J9 pin 12 or 14). When the button is pressed, +// we'll tell the host PC that the corresponding joystick button is +// pressed. We debounce the keystrokes in software, so you can simply +// wire directly to pushbuttons with no additional external hardware. +// +// Note that we assign 24 buttons by default, even though the USB +// joystick interface can handle up to 32 buttons. VP itself only +// allows mapping of up to 24 buttons in the preferences dialog +// (although it can recognize 32 buttons internally). If you want +// more buttons, you can reassign pins that are assigned by default +// as LedWiz outputs. To reassign a pin, find the pin you wish to +// reassign in the LedWizPortMap array below, and change the pin name +// there to NC (for Not Connected). You can then change one of the +// "NC" entries below to the reallocated pin name. The limit is 32 +// buttons total. +// +// (If you're using TLC5940 chips to control outputs, many of the +// GPIO pins that are mapped to LedWiz outputs in the default +// mapping can be reassigned as keys, since the TLC5940 outputs +// take over for the GPIO pins. The exceptions are the pins that +// are reassigned to control the TLC5940 chips.) +// +// Note: PTD1 (pin J2-12) should NOT be assigned as a button input, +// as this pin is physically connected on the KL25Z to the on-board +// indicator LED's blue segment. + +PinName buttonMap[] = { + PB_3, // button 1 + PB_5, // button 2 + PB_10, // button 3 + PC_7, // button 4 + PB_6, // button 5 + PA_5, // button 6 + PB_4, // button 7 + PB_13, // button 8 + PB_14, // button 9 + PB_15, // button 10 + PB_1, // button 11 + PB_2, // button 12 + PC_5, // button 13 + PC_6, // button 14 + PC_8, // button 15 + PH_1, // button 16 + PH_0, // button 17 + PC_15, // button 18 + PC_14, // button 19 + PB_7, // button 20 + NC, // button 21 + NC, // button 22 + NC, // button 23 + NC, // button 24 + NC, // button 25 + NC, // button 26 + NC, // button 27 + NC, // button 28 + NC, // button 29 + NC, // button 30 + NC, // button 31 + NC // button 32 +}; + +PinName hatMap[] = { + PA_13, // button 1 + PA_14, // button 2 + PA_15, // button 3 + PC_4, // button 4 + NC, // button 5 + NC, // button 6 + NC, // button 7 + NC // button 8 +}; + + +// STANDARD ID SETTINGS. These provide full, transparent LedWiz compatibility. +const uint16_t USB_VENDOR_ID = 0x1209; +const uint16_t USB_PRODUCT_ID = 0xACDE; +const uint16_t USB_PRODUCT_VER = 0x0002; \ No newline at end of file
diff -r e43878690c0e -r caf8a4134cbf main.cpp --- a/main.cpp Thu Jan 05 14:23:14 2017 +0000 +++ b/main.cpp Sat Jul 07 10:48:38 2018 +0000 @@ -24,19 +24,34 @@ */ #include "mbed.h" +#include "config.h" #include "USBJoystick.h" //#define LANDTIGER 1 -//USBMouse mouse; +// number of elements in an array +#define countof(x) (sizeof(x)/sizeof((x)[0])) + +// The Simulator Device USBJoystick joystick; +// Variables for Button input +DigitalIn *buttonDigIn[NUM_OF_BUTTONS]; // config.h +DigitalIn *hatDigIn[NUM_OF_HAT_BUTTONS]; // config.h + // Variables for Heartbeat and Status monitoring DigitalOut myled1(LED1); DigitalOut myled2(LED2); DigitalOut myled3(LED3); DigitalOut heartbeatLED(LED4); +AnalogIn xi(A0); +AnalogIn yi(A1); +AnalogIn fi(A2); +AnalogIn bi(A3); +AnalogIn ri(A4); +AnalogIn ti(A5); + Ticker heartbeat; Serial pc(USBTX, USBRX); // tx, rx @@ -54,27 +69,214 @@ heartbeat.detach(); } +// button state +struct ButtonState +{ + // current on/off state + int pressed; + + // Sticky time remaining for current state. When a + // state transition occurs, we set this to a debounce + // period. Future state transitions will be ignored + // until the debounce time elapses. + int t; +} buttonState[NUM_OF_BUTTONS]; + +// timer for button reports +static Timer buttonTimer; + +// initialize the button inputs +void initButtons() +{ + // create the digital inputs + for (int i = 0 ; i < countof(buttonDigIn) ; ++i) + { + if (i < countof(buttonMap) && buttonMap[i] != NC) + buttonDigIn[i] = new DigitalIn(buttonMap[i]); + else + buttonDigIn[i] = 0; + } + + // start the button timer + buttonTimer.start(); +} + + +// read the button input state +uint32_t readButtons() +{ + // start with all buttons off + uint32_t buttons = 0; + + // figure the time elapsed since the last scan + int dt = buttonTimer.read_ms(); + + // reset the timef for the next scan + buttonTimer.reset(); + + // scan the button list + uint32_t bit = 1; + DigitalIn **di = buttonDigIn; + ButtonState *bs = buttonState; + for (int i = 0 ; i < countof(buttonDigIn) ; ++i, ++di, ++bs, bit <<= 1) + { + // read this button + if (*di != 0) + { + // deduct the elapsed time since the last update + // from the button's remaining sticky time + bs->t -= dt; + if (bs->t < 0) + bs->t = 0; + + // If the sticky time has elapsed, note the new physical + // state of the button. If we still have sticky time + // remaining, ignore the physical state; the last state + // change persists until the sticky time elapses so that + // we smooth out any "bounce" (electrical transients that + // occur when the switch contact is opened or closed). + if (bs->t == 0) + { + // get the new physical state + int pressed = !(*di)->read(); + + // update the button's logical state if this is a change + if (pressed != bs->pressed) + { + // store the new state + bs->pressed = pressed; + + // start a new sticky period for debouncing this + // state change + bs->t = 25; + } + } + + // if it's pressed, OR its bit into the state + if (bs->pressed) + buttons |= bit; + } + } + + // return the new button list + return buttons; +} + +// timer for hat button reports +static Timer hatTimer; + +// button state +struct HatState +{ + // current on/off state + int pressed; + + // Sticky time remaining for current state. When a + // state transition occurs, we set this to a debounce + // period. Future state transitions will be ignored + // until the debounce time elapses. + int t; +} hatState[NUM_OF_HAT_BUTTONS]; + +// initialize the hat inputs +void initHat() +{ + // create the digital inputs + for (int i = 0 ; i < countof(hatDigIn) ; ++i) + { + if (i < countof(hatMap) && hatMap[i] != NC) + hatDigIn[i] = new DigitalIn(hatMap[i]); + else + hatDigIn[i] = 0; + } +} + +// read the button input state +uint32_t readHat() +{ + // start with all buttons off + uint8_t hat = 0; + + // figure the time elapsed since the last scan + int dt = hatTimer.read_ms(); + + // reset the timef for the next scan + hatTimer.reset(); + + // scan the button list + uint8_t bit = 1; + DigitalIn **di = hatDigIn; + HatState *bs = hatState; + for (int i = 0 ; i < countof(hatDigIn) ; ++i, ++di, ++bs, bit <<= 1) + { + // read this button + if (*di != 0) + { + // deduct the elapsed time since the last update + // from the button's remaining sticky time + bs->t -= dt; + if (bs->t < 0) + bs->t = 0; + + // If the sticky time has elapsed, note the new physical + // state of the button. If we still have sticky time + // remaining, ignore the physical state; the last state + // change persists until the sticky time elapses so that + // we smooth out any "bounce" (electrical transients that + // occur when the switch contact is opened or closed). + if (bs->t == 0) + { + // get the new physical state + int pressed = !(*di)->read(); + + // update the button's logical state if this is a change + if (pressed != bs->pressed) + { + // store the new state + bs->pressed = pressed; + + // start a new sticky period for debouncing this + // state change + bs->t = 25; + } + } + + // if it's pressed, OR its bit into the state + if (bs->pressed) + hat |= bit; + } + } + + // return the new button list + return hat; +} int main() { - uint16_t i = 0; + //uint16_t i = 0; int16_t throttle = 0; int16_t rudder = 0; + int16_t flaps = 0; + int16_t breaks = 0; int16_t x = 0; int16_t y = 0; - int32_t radius = 120; - int32_t angle = 0; - uint8_t tmp = 0; + //int32_t radius = 120; + //int32_t angle = 0; + //uint8_t tmp = 0; uint32_t buttons = 0; uint8_t hat = 0; pc.printf("Hello World from Joystick!\n\r"); - + + initButtons(); + initHat(); heartbeat_start(); while (1) { - // Basic Joystick - throttle = (i >> 8) & 0xFF; // value -127 .. 128 - rudder = (i >> 8) & 0xFF; // value -127 .. 128 +/* // Basic Joystick + throttle = (i >> 8) & 0xFF; // value -127 .. 128 + rudder = (i >> 8) & 0xFF; // value -127 .. 128 + flaps = (i >> 8) & 0xFF; // value -127 .. 128 + breaks = (i >> 8) & 0xFF; // value -127 .. 128 #if (BUTTONS4 == 1) buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button @@ -96,15 +298,26 @@ #if (HAT8 == 1) hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral #endif - i++; + i++; - x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128 - y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128 - angle += 3; + //x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128 + //y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128 + //angle += 3; +*/ - joystick.update(throttle, rudder, x, y, buttons, hat); + buttons = readButtons(); + hat = readHat(); + + x = int(((double)xi.read() - 0.5) * 254); + y = int(((double)yi.read() - 0.5) * 254); + flaps = int(((double)fi.read() - 0.5) * 254); + breaks = int(((double)bi.read() - 0.5) * 254); + rudder = int(((double)ri.read() - 0.5) * 254); + throttle = int(((double)ti.read() - 0.5) * 254); + + joystick.update(throttle, rudder, flaps, breaks, x, y, buttons, hat); wait(0.001); } - pc.printf("Bye World!\n\r"); + //pc.printf("Bye World!\n\r"); } \ No newline at end of file