work in progress
Dependencies: FastAnalogIn FastIO USBDevice mbed FastPWM SimpleDMA
Fork of Pinscape_Controller by
Diff: main.cpp
- Revision:
- 21:5048e16cc9ef
- Parent:
- 20:4c43877327ab
- Child:
- 22:71422c359f2a
diff -r 4c43877327ab -r 5048e16cc9ef main.cpp --- a/main.cpp Sat Feb 28 00:32:57 2015 +0000 +++ b/main.cpp Sat Mar 28 07:59:47 2015 +0000 @@ -216,6 +216,7 @@ #include "crc32.h" // our local configuration file +#define DECL_EXTERNS #include "config.h" @@ -260,15 +261,20 @@ // -------------------------------------------------------------------------- // -// Potentiometer configuration +// Define a symbol to tell us whether any sort of plunger sensor code +// is enabled in this build. Note that this doesn't tell us that a +// plunger device is actually attached or *currently* enabled; it just +// tells us whether or not the code for plunger sensing is enabled in +// the software build. This lets us leave out some unnecessary code +// on installations where no physical plunger is attached. // -#ifdef POT_SENSOR_ENABLED -#define IF_POT(x) x +const int PLUNGER_CODE_ENABLED = +#if defined(ENABLE_CCD_SENSOR) || defined(ENABLE_POT_SENSOR) + 1; #else -#define IF_POT(x) + 0; #endif - // --------------------------------------------------------------------------- // // On-board RGB LED elements - we use these for diagnostic displays. @@ -1049,8 +1055,8 @@ cfg.d.plungerMin = 0; // assume we can go all the way forward... cfg.d.plungerMax = npix; // ...and all the way back cfg.d.plungerZero = npix/6; // the rest position is usually around 1/2" back - cfg.d.ledWizUnitNo = DEFAULT_LEDWIZ_UNIT_NUMBER; - cfg.d.plungerEnabled = true; + cfg.d.ledWizUnitNo = DEFAULT_LEDWIZ_UNIT_NUMBER - 1; // unit numbering starts from 0 internally + cfg.d.plungerEnabled = PLUNGER_CODE_ENABLED; } // Create the joystick USB client. Note that we use the LedWiz unit @@ -1094,10 +1100,15 @@ // create the accelerometer object Accel accel(MMA8451_SCL_PIN, MMA8451_SDA_PIN, MMA8451_I2C_ADDRESS, MMA8451_INT_PIN); +#ifdef ENABLE_JOYSTICK // last accelerometer report, in joystick units (we report the nudge // acceleration via the joystick x & y axes, per the VP convention) int x = 0, y = 0; + // flag: send a pixel dump after the next read + bool reportPix = false; +#endif + // create our plunger sensor object PlungerSensor plungerSensor; @@ -1129,9 +1140,10 @@ // 0 = default // 1 = cocked (plunger has been pulled back about 1" from state 0) // 2 = uncocked (plunger is pulled back less than 1" from state 1) - // 3 = launching (plunger has been released from state 1 or 2, or - // pushed forward about 1/4" from state 0) - // 4 = launching, plunger is no longer pushed forward + // 3 = launching, plunger is forward beyond park position + // 4 = launching, plunger is behind park position + // 5 = pressed and holding (plunger has been pressed forward beyond + // the park position from state 0) int lbState = 0; // Time since last lbState transition. Some of the states are time- @@ -1202,9 +1214,6 @@ // 0x01 -> plunger sensor enabled uint16_t statusFlags = (cfg.d.plungerEnabled ? 0x01 : 0x00); - // flag: send a pixel dump after the next read - bool reportPix = false; - // we're all set up - now just loop, processing sensor reports and // host requests for (;;) @@ -1257,7 +1266,7 @@ // 1 = Set Configuration: // data[2] = LedWiz unit number (0x00 to 0x0f) // data[3] = feature enable bit mask: - // 0x01 = enable CCD + // 0x01 = enable plunger sensor // we'll need a reset if the LedWiz unit number is changing uint8_t newUnitNo = data[2] & 0x0f; @@ -1277,6 +1286,7 @@ // save the configuration cfg.save(iap, flash_addr); } +#ifdef ENABLE_JOYSTICK else if (data[1] == 2) { // 2 = Calibrate plunger @@ -1298,6 +1308,7 @@ ledB = 0; ledG = 1; } +#endif // ENABLE_JOYSTICK } else { @@ -1535,11 +1546,11 @@ case 0: // Base state. If the plunger is pulled back by an inch // or more, go to "cocked" state. If the plunger is pushed - // forward by 1/4" or more, go to "launch" state. + // forward by 1/4" or more, go to "pressed" state. if (znew >= cockThreshold) newState = 1; else if (znew <= pushThreshold) - newState = 3; + newState = 5; break; case 1: @@ -1585,22 +1596,34 @@ else if (lbTimer.read_ms() > 200) newState = 0; break; + + case 5: + // Press-and-Hold state. If the plunger is no longer pushed + // forward, AND it's been at least 50ms since we generated + // the simulated Launch Ball button press, return to the base + // state. The minimum time is to ensure that VP has a chance + // to see the button press and to avoid transient key bounce + // effects when the plunger position is right on the threshold. + if (znew > pushThreshold && lbTimer.read_ms() > 50) + newState = 0; + break; } // change states if desired const uint32_t lbButtonBit = (1 << (LaunchBallButton - 1)); if (newState != lbState) { - // if we're entering Launch state, and the ZB Launch Ball - // LedWiz signal is turned on, simulate a Launch Ball button - // press - if (newState == 3 && lbState != 4 && wizOn[ZBLaunchBallPort-1]) + // If we're entering Launch state OR we're entering the + // Press-and-Hold state, AND the ZB Launch Ball LedWiz signal + // is turned on, simulate a Launch Ball button press. + if (((newState == 3 && lbState != 4) || newState == 5) + && wizOn[ZBLaunchBallPort-1]) { lbBtnTimer.reset(); lbBtnTimer.start(); simButtons |= lbButtonBit; } - + // if we're switching to state 0, release the button if (newState == 0) simButtons &= ~(1 << (LaunchBallButton - 1)); @@ -1611,17 +1634,48 @@ // start timing in the new state lbTimer.reset(); } - - // if the simulated Launch Ball button press is in effect, - // and either it's been in effect too long or the ZB Launch - // Ball signal is no longer active, turn off the button - if ((simButtons & lbButtonBit) != 0 - && (!wizOn[ZBLaunchBallPort-1] || lbBtnTimer.read_ms() > 250)) + + // If the Launch Ball button press is in effect, but the + // ZB Launch Ball LedWiz signal is no longer turned on, turn + // off the button. + // + // If we're in one of the Launch states (state #3 or #4), + // and the button has been on for long enough, turn it off. + // The Launch mode is triggered by a pull-and-release gesture. + // From the user's perspective, this is just a single gesture + // that should trigger just one momentary press on the Launch + // Ball button. Physically, though, the plunger usually + // bounces back and forth for 500ms or so before coming to + // rest after this gesture. That's what the whole state + // #3-#4 business is all about - we stay in this pair of + // states until the plunger comes to rest. As long as we're + // in these states, we won't send duplicate button presses. + // But we also don't want the one button press to continue + // the whole time, so we'll time it out now. + // + // (This could be written as one big 'if' condition, but + // I'm breaking it out verbosely like this to make it easier + // for human readers such as myself to comprehend the logic.) + if ((simButtons & lbButtonBit) != 0) { - lbBtnTimer.stop(); - simButtons &= ~lbButtonBit; + int turnOff = false; + + // turn it off if the ZB Launch Ball signal is off + if (!wizOn[ZBLaunchBallPort-1]) + turnOff = true; + + // also turn it off if we're in state 3 or 4 ("Launch"), + // and the button has been on long enough + if ((lbState == 3 || lbState == 4) && lbBtnTimer.read_ms() > 250) + turnOff = true; + + // if we decided to turn off the button, do so + if (turnOff) + { + lbBtnTimer.stop(); + simButtons &= ~lbButtonBit; + } } - } // If a firing event is in progress, generate synthetic reports to @@ -1710,6 +1764,7 @@ // update the buttons uint32_t buttons = readButtons(); +#ifdef ENABLE_JOYSTICK // If it's been long enough since our last USB status report, // send the new report. We throttle the report rate because // it can overwhelm the PC side if we report too frequently. @@ -1732,6 +1787,13 @@ x = xa; y = ya; + // Report the current plunger position UNLESS the ZB Launch Ball + // signal is on, in which case just report a constant 0 value. + // ZB Launch Ball turns off the plunger position because it + // tells us that the table has a Launch Ball button instead of + // a traditional plunger. + int zrep = (ZBLaunchBallPort != 0 && wizOn[ZBLaunchBallPort-1] ? 0 : z); + // Send the status report. Note that the nominal x and y axes // are reversed - this makes it more intuitive to set up in VP. // If we mount the Freesale card flat on the floor of the cabinet @@ -1739,12 +1801,12 @@ // arrangement of our nominal axes aligns with VP's standard // setting, so that we can configure VP with X Axis = X on the // joystick and Y Axis = Y on the joystick. - js.update(y, x, z, buttons | simButtons, statusFlags); + js.update(y, x, zrep, buttons | simButtons, statusFlags); // we've just started a new report interval, so reset the timer reportTimer.reset(); } - + // If we're in pixel dump mode, report all pixel exposure values if (reportPix) { @@ -1755,6 +1817,17 @@ reportPix = false; } +#else // ENABLE_JOYSTICK + // We're a secondary controller, with no joystick reporting. Send + // a generic status report to the host periodically for the sake of + // the Windows config tool. + if (reportTimer.read_ms() > 200) + { + js.updateStatus(0); + } + +#endif // ENABLE_JOYSTICK + #ifdef DEBUG_PRINTF if (x != 0 || y != 0) printf("%d,%d\r\n", x, y);