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
--- /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
--- 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
--- 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
--- /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;
+}
--- /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
--- /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
--- /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
--- 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
