An I/O controller for virtual pinball machines: accelerometer nudge sensing, analog plunger input, button input encoding, LedWiz compatible output controls, and more.

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cfgVarMsgMap.h Source File

cfgVarMsgMap.h

00001 // Define the configuration variable USB get/set mapper.  We use
00002 // macros for the get/set operations to allow for common source
00003 // code for the two operations.  main.cpp #includes this file twice:
00004 // once for the SET function and once for the GET function.  main.cpp
00005 // redefines the v_xxx macros according to the current inclusion mode.
00006 //
00007 // This is a little tricky to follow because of the macros, but the
00008 // benefit is that the get and set functions automatically stay in
00009 // sync in terms of the variable types and byte mappings in the USB
00010 // messages, since they're both generated automatically from the
00011 // same code.
00012 //
00013 // The SET function is called directly from the corresponding USB
00014 // protocol message to set one variable.  The data buffer is simply
00015 // the data passed in from the USB message.
00016 //
00017 // The GET function is called in a loop from our configuration
00018 // variable reporting function.  The report function loops through
00019 // each variable in turn to generate a series of reports.  The
00020 // caller in this case fills in data[1] with the variable ID, and
00021 // it also fills in data[2] with the current index being queried
00022 // for the array variables (buttons, outputs).  We fill in the
00023 // rest of the data[] bytes with the current variable value(s),
00024 // encoded for the USB protocol message.
00025 
00026 
00027 void v_func
00028 {
00029     switch (data[1])
00030     {
00031         // ********** UNRECOGNIZED VARIABLE IDs **********
00032         // For any variable ID we don't recognize, we'll ignore SET
00033         // requests and return all zeroes on QUERY requests.  This
00034         // provides sensible default behavior if a newer version of 
00035         // the config tool is used with an older version of the 
00036         // firwmare.  Because of the default all-zero query response,
00037         // new variable added over time should use zero values as
00038         // the standard defaults whenever possible.  Note that the
00039         // config tool can also use QUERY VARIABLE 0 to determine
00040         // the number of variables supported by the firmware it's
00041         // talking to, if it needs to know whether or not a 
00042         // particular variable exists (a variable exists if its ID
00043         // is within the range returned by the QUERY 0 call).
00044         // 
00045     default:
00046         break;
00047         
00048         
00049         // ********** DESCRIBE CONFIGURATION VARIABLES **********
00050     case 0:
00051         v_byte_ro(22, 2);       // number of SCALAR variables
00052         v_byte_ro(6, 3);        // number of ARRAY variables
00053         break;
00054         
00055         // ********** SCALAR VARIABLES **********
00056         
00057     case 1:
00058         // USB identification (Vendor ID, Product ID)
00059         v_ui16(usbVendorID, 2);
00060         v_ui16(usbProductID, 4);
00061         break;
00062         
00063     case 2:
00064         // Pinscape Controller unit number (nominal unit number, 1-16)
00065         if_msg_valid(data[2] >= 1 && data[2] <= 16)
00066             v_byte(psUnitNo, 2);
00067         break;
00068         
00069     case 3:
00070         // Joystick report settings
00071         v_byte(joystickEnabled, 2);
00072         v_byte(joystickAxisFormat, 3);
00073         v_ui32(jsReportInterval_us, 4);
00074         
00075 #if VAR_MODE_SET
00076         // apply a default if the report interval is zero
00077         if (cfg.jsReportInterval_us == 0)
00078             cfg.jsReportInterval_us = 8333;
00079 #endif
00080         break;
00081         
00082     case 4:
00083         // Accelerometer options
00084         v_byte(accel.orientation, 2);
00085         v_byte(accel.range, 3);
00086         v_byte(accel.autoCenterTime, 4);
00087         v_byte(accel.stutter, 5);
00088         break;
00089 
00090     case 5:
00091         // Plunger sensor type
00092         v_byte(plunger.sensorType, 2);
00093         break;
00094         
00095     case 6:
00096         // Plunger sensor pin assignments
00097         v_byte(plunger.sensorPin[0], 2);
00098         v_byte(plunger.sensorPin[1], 3);
00099         v_byte(plunger.sensorPin[2], 4);
00100         v_byte(plunger.sensorPin[3], 5);
00101         break;
00102         
00103     case 7:
00104         // Plunger calibration button and indicator light pin assignments
00105         v_byte(plunger.cal.features, 2);
00106         v_byte(plunger.cal.btn, 3);
00107         v_byte(plunger.cal.led, 4);
00108         break;
00109         
00110     case 8:
00111         // ZB Launch Ball setup
00112         v_byte(plunger.zbLaunchBall.port, 2);
00113         v_byte(plunger.zbLaunchBall.keytype, 3);
00114         v_byte(plunger.zbLaunchBall.keycode, 4);
00115         v_ui16(plunger.zbLaunchBall.pushDistance, 5);
00116         break;
00117         
00118     case 9:
00119         // TV ON setup
00120         v_byte(TVON.statusPin, 2);
00121         v_byte(TVON.latchPin, 3);
00122         v_byte(TVON.relayPin, 4);
00123         v_ui16(TVON.delayTime, 5);
00124         break;
00125         
00126     case 10:
00127         // TLC5940NT PWM controller chip setup
00128         v_byte(tlc5940.nchips, 2);
00129         v_byte(tlc5940.sin, 3);
00130         v_byte(tlc5940.sclk, 4);
00131         v_byte(tlc5940.xlat, 5);
00132         v_byte(tlc5940.blank, 6);
00133         v_byte(tlc5940.gsclk, 7);
00134         break;
00135         
00136     case 11:
00137         // 74HC595 shift register chip setup
00138         v_byte(hc595.nchips, 2);
00139         v_byte(hc595.sin, 3);
00140         v_byte(hc595.sclk, 4);
00141         v_byte(hc595.latch, 5);
00142         v_byte(hc595.ena, 6);
00143         break;
00144         
00145     case 12:
00146         // Disconnect reboot timeout
00147         v_byte(disconnectRebootTimeout, 2);
00148         break;
00149         
00150     case 13:
00151         // plunger calibration
00152         v_ui16(plunger.cal.zero, 2);
00153         v_ui16(plunger.cal.max, 4);
00154         v_byte(plunger.cal.tRelease, 6);
00155         v_byte(plunger.cal.calibrated, 7);
00156         break;
00157         
00158     case 14:
00159         // expansion board configuration
00160         v_byte(expan.typ, 2);
00161         v_byte(expan.vsn, 3);
00162         v_byte(expan.ext[0], 4);
00163         v_byte(expan.ext[1], 5);
00164         v_byte(expan.ext[2], 6);
00165         break;
00166         
00167     case 15:
00168         // night mode configuration
00169         v_byte(nightMode.btn, 2);
00170         v_byte(nightMode.flags, 3);
00171         v_byte(nightMode.port, 4);
00172         break;
00173         
00174     case 16:
00175         // shift button configuration
00176         v_byte(shiftButton.idx, 2);
00177         v_byte(shiftButton.mode, 3);
00178         break;
00179         
00180     case 17:
00181         // IR sensor and emitter setup
00182         v_byte(IR.sensor, 2);
00183         v_byte(IR.emitter, 3);
00184         break;
00185         
00186     case 18:
00187         // plunger auto-zeroing time
00188         v_byte(plunger.autoZero.flags, 2);
00189         v_byte(plunger.autoZero.t, 3);
00190         break;
00191         
00192     case 19:
00193         // Plunger filters - jitter window size, reversed orientation.
00194         // The reversed orientation byte always has bit 0x80 set to indicate
00195         // that the feature is supported in this version.
00196         v_ui16(plunger.jitterWindow, 2);
00197         v_byte_ro(cfg.plunger.reverseOrientation | 0x80, 4);
00198         v_byte_wo(plunger.reverseOrientation, 4);
00199         break;
00200         
00201     case 20:
00202         // bar-code plunger setup
00203         v_ui16(plunger.barCode.startPix, 2);
00204         break;
00205         
00206     case 21:
00207         // TLC59116 PWM controller setup
00208         v_ui16(tlc59116.chipMask, 2);
00209         v_byte(tlc59116.sda, 4);
00210         v_byte(tlc59116.scl, 5);
00211         v_byte(tlc59116.reset, 6);
00212         break;
00213         
00214     case 22:
00215         // plunger raw configuration
00216         v_ui16(plunger.cal.raw0, 2);
00217         v_ui16(plunger.cal.raw1, 4);
00218         v_ui16(plunger.cal.raw2, 6);
00219         break;
00220         
00221     // case N: // new scalar variable
00222     //
00223     // !!! ATTENTION !!!
00224     // UPDATE CASE 0 ABOVE WHEN ADDING A NEW VARIABLE!!!
00225 
00226     
00227     // ********** SPECIAL DIAGNOSTIC VARIBLES **********
00228     //
00229     // This is a set of variables that act like the array variables
00230     // below.  However, these are generally read-only, and since they
00231     // don't contain restorable configuration data, they're not 
00232     // included in the variable counts reported by a "variable 0"
00233     // query above.
00234     case 220:
00235 #if !VAR_MODE_SET && ENABLE_DIAGNOSTICS
00236         {
00237             uint32_t a;
00238             switch (data[2])
00239             {
00240                 case 1:
00241                     // main loop, average iteration time in us
00242                     a = uint32_t(mainLoopIterTime/mainLoopIterCount);
00243                     v_ui32_ro(a, 3);
00244                     break;
00245                     
00246                 case 2:
00247                     // incoming message average processing time in us
00248                     a = uint32_t(mainLoopMsgTime/mainLoopMsgCount);
00249                     v_ui32_ro(a, 3);
00250                     break;
00251                 
00252                 case 3:
00253                     // PWM update polling routine, average time per call in us
00254                     a = uint32_t(polledPwmTotalTime/polledPwmRunCount);
00255                     v_ui32_ro(a, 3);
00256                     break;
00257                 
00258                 case 4:
00259                     // LedWiz flash update routine, average time per call in us
00260                     a = uint32_t(wizPulseTotalTime/wizPulseRunCount);
00261                     v_ui32_ro(a, 3);
00262                     break;
00263                     
00264                 case 5:
00265                 case 6:
00266                 case 7:
00267                 case 8:
00268                 case 9:
00269                 case 10:
00270                 case 11:
00271                 case 12:
00272                 case 13:
00273                 case 14:
00274                 case 15:
00275                 case 16:
00276                     // main loop checkpoint N, time in us
00277                     a = uint32_t(mainLoopIterCheckpt[data[2]-5]/mainLoopIterCount);
00278                     v_ui32_ro(a, 3);
00279                     break;
00280                     
00281                 case 30:
00282                     a = (plungerSensor != 0 ? plungerSensor->getAvgScanTime() : 0);
00283                     v_ui32_ro(a, 3);
00284                     break;                    
00285             }
00286         }
00287 #endif
00288         break;
00289         
00290     // ********** ARRAY VARIABLES **********
00291 
00292 
00293     // case N: // new array variable
00294     //
00295     // !!! ATTENTION !!!
00296     // UPDATE CASE 0 ABOVE WHEN ADDING A NEW ARRAY VARIABLE!!!
00297     
00298     case 250:
00299         // IR command code - high 32 bits
00300         {
00301             int idx = data[2];
00302             if (idx == 0)
00303             {
00304                 v_byte_ro(MAX_IR_CODES, 3);
00305             }
00306             else if (idx > 0 && idx <= MAX_IR_CODES)
00307             {
00308                 --idx;
00309                 v_ui32(IRCommand[idx].code.hi, 3);
00310             }
00311         }
00312         break;
00313     
00314     case 251:
00315         // IR command code - protocol and low 32 bits
00316         {
00317             int idx = data[2];
00318             if (idx == 0)
00319             {
00320                 v_byte_ro(MAX_IR_CODES, 3);
00321             }
00322             else if (idx > 0 && idx <= MAX_IR_CODES)
00323             {
00324                 --idx;
00325                 v_byte(IRCommand[idx].protocol, 3);
00326                 v_ui32(IRCommand[idx].code.lo, 4);
00327             }
00328         }
00329         break;
00330     
00331     case 252:
00332         // IR command descriptor
00333         {
00334             int idx = data[2];
00335             if (idx == 0)
00336             {
00337                 v_byte_ro(MAX_IR_CODES, 3);
00338             }
00339             else if (idx > 0 && idx <= MAX_IR_CODES)
00340             {
00341                 --idx;
00342                 v_byte(IRCommand[idx].flags, 3);
00343                 v_byte(IRCommand[idx].keytype, 4);
00344                 v_byte(IRCommand[idx].keycode, 5);
00345             }
00346         }
00347         break;
00348     
00349     case 253:
00350         // extended button setup
00351         {
00352             // get the index and check if it's in range
00353             int idx = data[2];
00354             if (idx == 0)
00355             {
00356                 // index 0 on query retrieves number of slots
00357                 v_byte_ro(MAX_BUTTONS, 3);
00358             }
00359             else if (idx > 0 && idx <= MAX_BUTTONS)
00360             {
00361                 // adjust to an array index
00362                 --idx;
00363                 
00364                 // transfer the values
00365                 v_byte(button[idx].typ2, 3);
00366                 v_byte(button[idx].val2, 4);
00367                 v_byte(button[idx].IRCommand2, 5);
00368             }                
00369         }
00370         break;
00371 
00372     case 254:
00373         // button setup
00374         {
00375             // get the button number
00376             int idx = data[2];
00377             
00378             // if it's in range, set the button data
00379             if (idx == 0)
00380             {
00381                 // index 0 on query retrieves number of slots
00382                 v_byte_ro(MAX_BUTTONS, 3);
00383             }
00384             else if (idx > 0 && idx <= MAX_BUTTONS)
00385             {
00386                 // adjust to an array index
00387                 --idx;
00388                 
00389                 // transfer the values
00390                 v_byte(button[idx].pin, 3);
00391                 v_byte(button[idx].typ, 4);
00392                 v_byte(button[idx].val, 5);
00393                 v_byte(button[idx].flags, 6);
00394                 v_byte(button[idx].IRCommand, 7);
00395             }
00396         }
00397         break;
00398         
00399     case 255:
00400         // LedWiz output port setup
00401         {
00402             // get the port number
00403             int idx = data[2];
00404             
00405             // if it's in range, set the port data
00406             if (idx == 0)
00407             {
00408                 // index 0 on query retrieves number of slots
00409                 v_byte_ro(MAX_OUT_PORTS, 3);
00410             }
00411             else if (idx > 0 && idx <= MAX_OUT_PORTS)
00412             {
00413                 // adjust to an array index
00414                 --idx;
00415                 
00416                 // set the values
00417                 v_byte(outPort[idx].typ, 3);
00418                 v_byte(outPort[idx].pin, 4);
00419                 v_byte(outPort[idx].flags, 5);
00420                 v_byte(outPort[idx].flipperLogic, 6);
00421             }
00422         }
00423         break;
00424     }
00425 }
00426