Demo for USBJoystick updated for 32 buttons.
Dependencies: USBDevice USBJoystick_SIM mbed USBJoystick_2
Fork of USBJoystick_HelloWorld2 by
Revision 1:b106cf2e99ba, committed 2018-07-22
- Comitter:
- Cirrus01
- Date:
- Sun Jul 22 10:36:35 2018 +0000
- Parent:
- 0:e43878690c0e
- Child:
- 2:967da2faedcd
- Commit message:
- Inital
Changed in this revision
--- a/USBDevice.lib Thu Jan 05 14:23:14 2017 +0000 +++ b/USBDevice.lib Sun Jul 22 10:36:35 2018 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/USBDevice/#01321bd6ff89 +http://mbed.org/users/mbed_official/code/USBDevice/#53949e6131f6
--- a/USBJoystick.lib Thu Jan 05 14:23:14 2017 +0000 +++ b/USBJoystick.lib Sun Jul 22 10:36:35 2018 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/wim/code/USBJoystick/#e086541742c3 +https://os.mbed.com/users/Cirrus01/code/USBJoystick_SIM/#92574cf6e9af
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config.h Sun Jul 22 10:36:35 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
+ PC_4, // button 16
+ NC, // button 17
+ NC, // button 18
+ NC, // button 19
+ NC, // 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
+ PB_7, // 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 Sun Jul 22 10:36:35 2018 +0000
@@ -2,7 +2,7 @@
* Copyright (c) 2012, v01: Initial version, WH,
* Modified USBMouse code ARM Limited.
* (c) 2010-2011 mbed.org, MIT License
- * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button
+ * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +24,7 @@
*/
#include "mbed.h"
+#include "config.h"
#include "USBJoystick.h"
//#define LANDTIGER 1
@@ -32,79 +33,331 @@
USBJoystick joystick;
// Variables for Heartbeat and Status monitoring
-DigitalOut myled1(LED1);
+DigitalOut myled1(LED4);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
-DigitalOut heartbeatLED(LED4);
+DigitalOut heartbeatLED(LED1);
+
+AnalogIn inX(A0);
+AnalogIn inY(A1);
+AnalogIn inRudder(A2);
+AnalogIn inThrottle(A3);
+AnalogIn inBreaks(A4);
+AnalogIn inFlaps(A5);
Ticker heartbeat;
Serial pc(USBTX, USBRX); // tx, rx
+// number of elements in an array
+#define countof(x) (sizeof(x)/sizeof((x)[0]))
+
+// button input map array
+DigitalIn *buttonDigIn[NUM_OF_BUTTONS]; // config.h
+
+// hat button input map array
+DigitalIn *hatDigIn[NUM_OF_HAT_BUTTONS]; // config.h
+
// Heartbeat monitor
-void pulse() {
- heartbeatLED = !heartbeatLED;
+void pulse()
+{
+ heartbeatLED = !heartbeatLED;
+}
+
+void heartbeat_start()
+{
+ heartbeatLED=1;
+ heartbeat.attach(&pulse, 0.5);
+}
+
+void heartbeat_stop()
+{
+ heartbeat.detach();
}
-void heartbeat_start() {
- heartbeatLED=1;
- heartbeat.attach(&pulse, 0.5);
-}
+// 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 bt;
+} buttonState[NUM_OF_BUTTONS];
-void heartbeat_stop() {
- heartbeat.detach();
+// 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();
}
-int main() {
- uint16_t i = 0;
- int16_t throttle = 0;
- int16_t rudder = 0;
- int16_t x = 0;
- int16_t y = 0;
- int32_t radius = 120;
- int32_t angle = 0;
- uint8_t tmp = 0;
- uint32_t buttons = 0;
- uint8_t hat = 0;
+// 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();
- pc.printf("Hello World from Joystick!\n\r");
+ // 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->bt -= dt;
+ if (bs->bt < 0)
+ bs->bt = 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->bt == 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->bt = 10;
+ }
+ }
+
+ // if it's pressed, OR its bit into the state
+ if (bs->pressed)
+ buttons |= bit;
+ }
+ }
+
+ // return the new button list
+ return buttons;
+}
- heartbeat_start();
+// hat 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 ht;
+} hatState[NUM_OF_HAT_BUTTONS];
+
+// timer for hat reports
+static Timer hatTimer;
+
+// 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;
+ }
+}
- while (1) {
- // Basic Joystick
- throttle = (i >> 8) & 0xFF; // value -127 .. 128
- rudder = (i >> 8) & 0xFF; // value -127 .. 128
+// read the hat button input state
+uint8_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 *hs = hatState;
+ for (int i = 0 ; i < countof(hatDigIn) ; ++i, ++di, ++hs, bit <<= 1)
+ {
+ // read this button
+ if (*di != 0)
+ {
+ // deduct the elapsed time since the last update
+ // from the button's remaining sticky time
+ hs->ht -= dt;
+ if (hs->ht < 0)
+ hs->ht = 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 (hs->ht == 0)
+ {
+ // get the new physical state
+ int pressed = !(*di)->read();
+
+ // update the button's logical state if this is a change
+ if (pressed != hs->pressed)
+ {
+ // store the new state
+ hs->pressed = pressed;
+
+ // start a new sticky period for debouncing this
+ // state change
+ hs->ht = 10;
+ }
+ }
+
+ // if it's pressed, OR its bit into the state
+ if (hs->pressed)
+ hat |= bit;
+ pc.printf("Hat: %d\n", hat);
+ }
+ }
+
+ // return the new button list
+ //pc.printf("Hat: %d", hat);
+ return hat;
+}
-#if (BUTTONS4 == 1)
- buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button
-#endif
-#if (BUTTONS8 == 1)
- buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
-#endif
-#if (BUTTONS32 == 1)
- tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
- buttons = (( tmp << 0) & 0x000000FF);
- buttons = buttons | ((~tmp << 8) & 0x0000FF00);
- buttons = buttons | (( tmp << 16) & 0x00FF0000);
- buttons = buttons | ((~tmp << 24) & 0xFF000000);
-#endif
+int main()
+{
+ //uint16_t i = 0;
+ int16_t throttle = 0;
+ int16_t rudder = 0;
+ int16_t breaks = 0;
+ int16_t flaps = 0;
+ int16_t x = 0;
+ int16_t y = 0;
+ //int32_t radius = 120;
+ //int32_t angle = 0;
+ //uint8_t tmp = 0;
+ //uint32_t tmp = 1;
+ uint32_t buttons = 0;
+ uint8_t hat = 0;
+
+ pc.printf("Hello World from Joystick!\n\r");
+
+ initButtons();
+ initHat();
+
+ heartbeat_start();
-#if (HAT4 == 1)
- hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral
+ while (1) {
+ // Basic Joystick
+ // throttle = (i >> 8) & 0xFF; // value -127 .. 128
+ // rudder = (i >> 8) & 0xFF; // value -127 .. 128
+ // breaks = (i >> 8) & 0xFF; // value 0 .. 255
+ // flaps = (i >> 8) & 0xFF; // value 0 .. 255
+
+/*
+#if (BUTTONS4 == 1)
+ buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button
+#endif
+#if (BUTTONS8 == 1)
+ buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
+#endif
+#if (BUTTONS32 == 1)
+ //tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
+ //buttons = (( tmp << 0) & 0x000000FF);
+ //buttons = buttons | ((~tmp << 8) & 0x0000FF00);
+ //buttons = buttons | (( tmp << 16) & 0x00FF0000);
+ //buttons = buttons | ((~tmp << 24) & 0xFF000000);//
+ buttons = tmp;
+ tmp += 1;
+ pc.printf("Tmp: %u\n", tmp);
+#endif
+
+#if (HAT4 == 1)
+ hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral
#endif
#if (HAT8 == 1)
- hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral
-#endif
- i++;
+ hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral
+#endif
+ 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;
+*/
+
+ buttons = readButtons();
+ hat = readHat();
+ //pc.printf("Hat: %d\n", hat);
- 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;
+ throttle = inThrottle.read() * 256 - 128;
+ if(throttle < -127)
+ throttle = -127;
+ if(throttle > 127)
+ throttle = 127;
+ rudder = inRudder.read() * 256 - 128;
+ if(rudder < -127)
+ rudder = -127;
+ if(rudder > 127)
+ rudder = 127;
+ breaks = inBreaks.read() * 256 - 127;
+ if(breaks < -127)
+ breaks = -127;
+ if(breaks > 127)
+ breaks = 127;
+ flaps = inFlaps.read() * 256 - 127;
+ if(flaps < -127)
+ flaps = -127;
+ if(flaps > 127)
+ flaps = 127;
- joystick.update(throttle, rudder, x, y, buttons, hat);
- wait(0.001);
- }
-
- pc.printf("Bye World!\n\r");
+ x = inX.read() * 256 - 127;
+ if(x < -127)
+ x = -127;
+ if(x > 127)
+ x = 127;
+ y = inY.read() * 254 - 127;
+ if(y < -127)
+ y = -127;
+ if(y < 127)
+ y = 127;
+
+ joystick.update(throttle, rudder, breaks, flaps, x, y, buttons, hat);
+ wait(0.01);
+ }
+
+ //pc.printf("Bye World!\n\r");
}
\ No newline at end of file
--- a/mbed.bld Thu Jan 05 14:23:14 2017 +0000 +++ b/mbed.bld Sun Jul 22 10:36:35 2018 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/9baf128c2fab \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/e7ca05fa8600 \ No newline at end of file
