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 config.h Source File

config.h

00001 // Pinscape Controller Configuration
00002 //
00003 // !!! ATTENTION !!! 
00004 // If you've come here on advice in a forum to change a GPIO setting or 
00005 // to #define a macro to enable the expansion boards, >>>STOP NOW<<<.  The 
00006 // advice you found is out of date and no longer applies.  You don't need 
00007 // to edit this file or recompile the firmware, and you shouldn't.  Instead,
00008 // use the standard firmware, and set options using the Pinscape Config Tool
00009 // on your Windows PC.  All options that were formerly configurable by 
00010 // editing this file can be selected with the Config Tool.  That's much 
00011 // cleaner and easier than editing the source code, and it eliminates the
00012 // problem of re-synchronizing a private copy of the source code with future 
00013 // updates.  With the config tool, you only need the standard firmware build, 
00014 // so future updates are a simple matter of downloading the latest version.
00015 //
00016 //
00017 // IN THE PAST (but NOT NOW - see above), configuration was handled mostly 
00018 // with #defines and #ifdefs.  To customize the setup, you had to create a 
00019 // private forked copy of the source code, edit the constants defined in 
00020 // config.h, and compile a custom binary.  That's no longer necessary because
00021 // the config tool lets you set all configurable options dynamically.  Of 
00022 // course, you're still free to create a custom version if you want to add 
00023 // entirely new features or make changes that go beyond the configurable
00024 // options.
00025 //
00026 #ifndef CONFIG_H
00027 #define CONFIG_H
00028 
00029 #include "USBJoystick.h"
00030 
00031 
00032 // TEST SETTINGS - FOR DEBUGGING PURPOSES ONLY.  The macros below select
00033 // special option combinations for debugging purposes.
00034 //
00035 // IMPORTANT!  If you're trying to create a custom configuration because
00036 // you have a pin conflict or because you're using the expansion boards,
00037 // DON'T modify this file, DON'T use these macros, and DON'T recompile 
00038 // the firmware.  Use the Config Tool on your Windows PC instead.
00039 #define STANDARD_CONFIG       1     // standard settings, based on v1 base settings
00040 #define TEST_CONFIG_EXPAN     0     // configuration for the expansion boards
00041 #define TEST_KEEP_PRINTF      0     // for debugging purposes, keep printf() enabled
00042                                     // by leaving the SDA UART GPIO pins unallocated
00043 
00044 // Plunger type codes
00045 // NOTE!  These values are part of the external USB interface.  New
00046 // values can be added, but the meaning of an existing assigned number 
00047 // should remain fixed to keep the PC-side config tool compatible across 
00048 // versions.
00049 const int PlungerType_None      = 0;     // no plunger
00050 const int PlungerType_TSL1410R  = 1;     // TSL1410R linear image sensor (1280x1 pixels, 400dpi), serial mode, edge detection
00051 const int PlungerType_TSL1412S  = 3;     // TSL1412S linear image sensor (1536x1 pixels, 400dpi), serial mode, edge detection
00052 const int PlungerType_Pot       = 5;     // potentionmeter
00053 const int PlungerType_OptQuad   = 6;     // AEDR8300 optical quadrature sensor
00054 const int PlungerType_MagQuad   = 7;     // AS5304 magnetic quadrature sensor
00055 const int PlungerType_TSL1401CL = 8;     // TSL1401CL linear image sensor (128x1 pixels, 400dpi), bar code reader
00056 const int PlungerType_VL6180X   = 9;     // VL6180X time-of-flight distance sensor
00057 const int PlungerType_AEAT6012  = 10;    // AEAT-6012-A06 magnetic rotary encoder; absolute angle sensing, 12-bit precision
00058 const int PlungerType_TCD1103   = 11;    // Toshiba TCD1103GFG linear image sensor (1500x1 pixels, ~4600dpi), edge detection
00059 
00060 // Plunger auto-zero flags
00061 const int PlungerAutoZeroEnabled = 0x01; // auto-zeroing enabled
00062 
00063 // Accelerometer orientation codes
00064 // These values are part of the external USB interface
00065 const int OrientationFront     = 0;      // USB ports pointed toward front of cabinet
00066 const int OrientationLeft      = 1;      // ports pointed toward left side of cabinet
00067 const int OrientationRight     = 2;      // ports pointed toward right side of cabinet
00068 const int OrientationRear      = 3;      // ports pointed toward back of cabinet
00069 
00070 // Accelerometer dynamic range codes
00071 const int AccelRange1G         = 0;      // +/-1G
00072 const int AccelRange2G         = 1;      // +/-2G
00073 const int AccelRange4G         = 2;      // +/-4G
00074 const int AccelRange8G         = 3;      // +/-8G
00075 
00076 // input button types
00077 const int BtnTypeNone          = 0;      // unused
00078 const int BtnTypeJoystick      = 1;      // joystick button
00079 const int BtnTypeKey           = 2;      // keyboard key
00080 const int BtnTypeMedia         = 3;      // media control key
00081 
00082 // input button flags
00083 const uint8_t BtnFlagPulse     = 0x01;   // pulse mode - reports each change in the physical switch state
00084                                          // as a brief press of the logical button/keyboard key
00085                                          
00086 // button setup structure
00087 struct ButtonCfg
00088 {
00089     // physical GPIO pin - a Wire-to-PinName mapping index
00090     uint8_t pin;
00091     
00092     // Key type and value reported to the PC
00093     uint8_t typ;        // key type reported to PC - a BtnTypeXxx value
00094     uint8_t val;        // key value reported - meaning depends on 'typ' value:
00095                         //   none     -> no PC input reports (val is unused)
00096                         //   joystick -> val is joystick button number (1..32)
00097                         //   keyboard -> val is USB scan code
00098     uint8_t IRCommand;  // IR command to send when the button is pressed, as
00099                         // an IR command slot number: 1..MAX_IR_CODES, or 0
00100                         // if no IR command is to be sent
00101                         
00102     // Shifted key type and value.  These used when the button is pressed 
00103     // while the Local Shift Button is being held down.  We send the key
00104     // code given here instead of the regular typ/val code in this case.
00105     // If typ2 is BtnTypeNone, we use the regular typ/val code whether or
00106     // not the shift button is being held.
00107     uint8_t typ2;       // shifted key type
00108     uint8_t val2;       // shifted key value
00109     uint8_t IRCommand2; // IR command to send when shifted button is pressed
00110     
00111     // key flags - a bitwise combination of BtnFlagXxx values
00112     uint8_t flags;
00113 
00114     void set(uint8_t pin, uint8_t typ, uint8_t val, uint8_t flags = 0)
00115     {
00116         this->pin = pin;
00117         this->typ = typ;
00118         this->val = val;
00119         this->IRCommand = 0;
00120         this->flags = flags;
00121         this->typ2 = 0;
00122         this->val2 = 0;
00123         this->IRCommand2 = 0;
00124     }
00125         
00126 } __attribute__((packed));
00127     
00128 
00129 // maximum number of input button mappings in configuration
00130 const int MAX_BUTTONS = 48;
00131 
00132 // extra slots for virtual buttons (ZB Launch Ball)
00133 const int VIRTUAL_BUTTONS = 1;             // total number of buttons
00134 const int ZBL_BUTTON_CFG = MAX_BUTTONS;    // index of ZB Launch Ball slot
00135 
00136 // LedWiz output port type codes
00137 // These values are part of the external USB interface
00138 const int PortTypeDisabled     = 0;        // port is disabled - not visible to LedWiz/DOF host
00139 const int PortTypeGPIOPWM      = 1;        // GPIO port, PWM enabled
00140 const int PortTypeGPIODig      = 2;        // GPIO port, digital out
00141 const int PortTypeTLC5940      = 3;        // TLC5940 port
00142 const int PortType74HC595      = 4;        // 74HC595 port
00143 const int PortTypeVirtual      = 5;        // Virtual port - visible to host software, but not connected 
00144                                            //  to a physical output
00145 const int PortTypeTLC59116     = 6;        // TLC59116 port
00146 
00147 // LedWiz output port flag bits
00148 const uint8_t PortFlagActiveLow    = 0x01; // physical output is active-low
00149 const uint8_t PortFlagNoisemaker   = 0x02; // noisemaker device - disable when night mode is engaged
00150 const uint8_t PortFlagGamma        = 0x04; // apply gamma correction to this output
00151 const uint8_t PortFlagFlipperLogic = 0x08; // enable Flipper Logic on the port (timed power limitation)
00152 const uint8_t PortFlagChimeLogic   = 0x10; // enable Chime Logic on this port (min/max time limits)
00153 
00154 // maximum number of output ports
00155 const int MAX_OUT_PORTS = 128;
00156 
00157 // port configuration data
00158 struct LedWizPortCfg
00159 {
00160     // port type:  a PortTypeXxx value
00161     uint8_t typ;        
00162     
00163     // physical output pin:  
00164     //
00165     //  - for a GPIO port, this is an index in the 
00166     //    USB-to-PinName mapping list
00167     //
00168     //  - for a TLC5940 or 74HC595 port, it's the output
00169     //    number in the overall daisy chain, starting 
00170     //    from 0 for OUT0 on the first chip in the chain
00171     //
00172     //  - for a TLC59116, the high 4 bits are the chip
00173     //    address (the low 4 bits of the address only),
00174     //    and the low 4 bits are the output number on
00175     //    the chip
00176     //
00177     //  - for inactive and virtual ports, this is unused
00178     //
00179     uint8_t pin;
00180     
00181     // flags:  a combination of PortFlagXxx values
00182     uint8_t flags;
00183     
00184     // flipper logic properties:
00185     //
00186     //  - high 4 bits (0xF0) give full-power time 
00187     //
00188     //  - low 4 bits (0x0F) give reduced power level (used
00189     //    after full-power time expires), in 6.66% units
00190     //
00191     uint8_t flipperLogic;
00192     
00193     void set(uint8_t typ, uint8_t pin, uint8_t flags = 0, uint8_t flipperLogic = 0)
00194     {
00195         this->typ = typ;
00196         this->pin = pin;
00197         this->flags = flags;
00198         this->flipperLogic = flipperLogic;
00199     }
00200         
00201 } __attribute__ ((packed));
00202 
00203 // IR command configuration flags
00204 const uint8_t IRFlagTVON = 0x01;     // send command at TV ON time
00205 const uint8_t IRFlagDittos = 0x02;   // use "ditto" codes on send
00206 
00207 // IR command configuration data
00208 struct IRCommandCfg
00209 {
00210     uint8_t flags;      // flags: a combination of IRFlagXxx values
00211     uint8_t keytype;    // key type to send when IR command is received
00212     uint8_t keycode;    // key code to send when IR command is received
00213     uint8_t protocol;   // IR protocol ID (see IRRemote/IRProtocolID.h)
00214     struct
00215     {
00216         uint32_t lo;    // low 32 bits of code
00217         uint32_t hi;    // high 32 bits of code
00218     } code;             // 64-bit command code (protocol-specific; see IRProtocols.h)
00219 } __attribute__ ((packed));
00220 
00221 // Maximum number of IR commands
00222 const int MAX_IR_CODES = 16;
00223 
00224 
00225 // Convert a physical pin name to a wire pin name
00226 #define PINNAME_TO_WIRE(p) \
00227     uint8_t((p) == NC ? 0xFF : \
00228       (((p) & 0xF000 ) >> (PORT_SHIFT - 5)) | (((p) & 0xFF) >> 2))
00229 
00230 struct Config
00231 {
00232     // set all values to factory defaults
00233     void setFactoryDefaults()
00234     {
00235         // By default, pretend to be LedWiz unit #8.  This can be from 1 to 16.  Real
00236         // LedWiz units have their unit number set at the factory, and the vast majority
00237         // are set up as unit #1, since that's the default for anyone who doesn't ask
00238         // for a different setting.  It seems rare for anyone to use more than one unit
00239         // in a pin cab, but for the few who do, the others will probably be numbered
00240         // sequentially as #2, #3, etc.  It seems safe to assume that no one out there
00241         // has a unit #8, so we'll use that as our default.  This can be changed from 
00242         // the config tool, but for the sake of convenience, it's better to pick a
00243         // default that most people won't have to change.
00244         usbVendorID = 0xFAFA;      // LedWiz vendor code 
00245         usbProductID = 0x00F7;     // LedWiz product code for unit #8
00246                 
00247         // Set the default Pinscape unit number to #1.  This is a separate identifier
00248         // from the LedWiz ID, so you don't have to worry about making this different
00249         // from your LedWiz units.  Each Pinscape unit should have a unique value for
00250         // this ID, though.
00251         //
00252         // Note that Pinscape unit #1 corresponds to DOF Pinscape #51, PS 2 -> DOF 52,
00253         // and so on - just add 50 to get the DOF ID.
00254         psUnitNo = 1;
00255         
00256         // set a disconnect reboot timeout of 10 seconds by default
00257         disconnectRebootTimeout = 10;
00258         
00259         // enable joystick reports
00260         joystickEnabled = true;
00261         
00262         // use the XYZ axis format
00263         joystickAxisFormat = USBJoystick::AXIS_FORMAT_XYZ;
00264         
00265         // send reports every 8.33ms by default (120 Hz, 2X the typical video
00266         // refresh rate)
00267         jsReportInterval_us = 8333;
00268         
00269         // assume standard orientation, with USB ports toward front of cabinet
00270         accel.orientation = OrientationFront;
00271         
00272         // default dynamic range +/-1G
00273         accel.range = AccelRange1G;
00274         
00275         // default auto-centering time
00276         accel.autoCenterTime = 0;
00277         
00278         // take a new accelerometer reading on every other joystick report
00279         accel.stutter = 2;
00280 
00281         // assume a basic setup with no expansion boards
00282         expan.typ = 0;
00283         expan.vsn = 0;
00284         memset(expan.ext, 0, sizeof(expan.ext));
00285 
00286         // assume no plunger is attached
00287         plunger.enabled = 0x00;
00288         plunger.sensorType = PlungerType_None;
00289         
00290         // no jitter filter
00291         plunger.jitterWindow = 0;
00292         
00293         // normal orientation
00294         plunger.reverseOrientation = false;
00295         
00296 #if TEST_CONFIG_EXPAN || STANDARD_CONFIG
00297         plunger.enabled = 0x01;
00298         plunger.sensorType = PlungerType_TSL1410R;
00299         plunger.sensorPin[0] = PINNAME_TO_WIRE(PTE20); // SI
00300         plunger.sensorPin[1] = PINNAME_TO_WIRE(PTE21); // SCLK
00301         plunger.sensorPin[2] = PINNAME_TO_WIRE(PTB0);  // AO1 = PTB0 = ADC0_SE8
00302         plunger.sensorPin[3] = PINNAME_TO_WIRE(PTE22); // AO2 (parallel mode) = PTE22 = ADC0_SE3
00303 #endif
00304         
00305         // default plunger calibration button settings
00306         plunger.cal.features = 0x03;                   // 0x01 = enable button, 0x02 = enable indicator lamp
00307         plunger.cal.btn = PINNAME_TO_WIRE(PTE29);      // button input (DigitalIn port)
00308         plunger.cal.led = PINNAME_TO_WIRE(PTE23);      // button output (DigitalOut port)
00309         
00310         // set the default plunger calibration
00311         plunger.cal.setDefaults();
00312         
00313         // disable the ZB Launch Ball by default
00314         plunger.zbLaunchBall.port = 0;                  // 0 = disabled
00315         plunger.zbLaunchBall.keytype = BtnTypeKey;      // keyboard key
00316         plunger.zbLaunchBall.keycode = 0x28;            // USB keyboard scan code for Enter key
00317         plunger.zbLaunchBall.pushDistance = 63;         // 63/1000 in == .063" == about 1/16"
00318         
00319         // assume no TV ON switch
00320         TVON.statusPin = PINNAME_TO_WIRE(NC);
00321         TVON.latchPin = PINNAME_TO_WIRE(NC);
00322         TVON.relayPin = PINNAME_TO_WIRE(NC);
00323         TVON.delayTime = 700;   // 7 seconds
00324         
00325 #if TEST_CONFIG_EXPAN
00326         // expansion board TV ON wiring
00327         TVON.statusPin = PINNAME_TO_WIRE(PTD2);
00328         TVON.latchPin = PINNAME_TO_WIRE(PTE0);
00329         TVON.relayPin = PINNAME_TO_WIRE(PTD3);
00330         TVON.delayTime = 700;   // 7 seconds
00331 #endif
00332 
00333         // assume no night mode switch or indicator lamp
00334         nightMode.btn = 0;
00335         nightMode.flags = 0;
00336         nightMode.port = 0;
00337         
00338         // assume no TLC5940 chips
00339         tlc5940.nchips = 0;
00340         
00341 #if TEST_CONFIG_EXPAN
00342         // for expansion board testing purposes, assume the common setup
00343         // with one main board and one power board
00344         tlc5940.nchips = 4;
00345 #endif
00346 
00347         // Default TLC5940 pin assignments.  Note that it's harmless to set
00348         // these to valid pins even if no TLC5940 chips are actually present,
00349         // since the main program won't allocate the connections if 'nchips'
00350         // is zero.  This means that the pins are free to be used for other
00351         // purposes (such as output ports) if not using TLC5940 chips.
00352         tlc5940.sin = PINNAME_TO_WIRE(PTC6);
00353         tlc5940.sclk = PINNAME_TO_WIRE(PTC5);
00354         tlc5940.xlat = PINNAME_TO_WIRE(PTC10);
00355         tlc5940.blank = PINNAME_TO_WIRE(PTC7);        
00356 #if TEST_KEEP_PRINTF
00357         tlc5940.gsclk = PINNAME_TO_WIRE(PTA13);     // PTA1 is reserved for SDA printf()
00358 #else
00359         tlc5940.gsclk = PINNAME_TO_WIRE(PTA1);
00360 #endif
00361         
00362         // assume no 74HC595 chips
00363         hc595.nchips = 0;
00364 
00365 #if TEST_CONFIG_EXPAN
00366         // for expansion board testing purposes, assume one chime board
00367         hc595.nchips = 1;
00368 #endif
00369     
00370         // Default 74HC595 pin assignments.  As with the TLC5940 pins, it's
00371         // harmless to assign pins here even if no 74HC595 chips are used,
00372         // since the main program won't actually allocate the pins if 'nchips'
00373         // is zero.
00374         hc595.sin = PINNAME_TO_WIRE(PTA5);
00375         hc595.sclk = PINNAME_TO_WIRE(PTA4);
00376         hc595.latch = PINNAME_TO_WIRE(PTA12);
00377         hc595.ena = PINNAME_TO_WIRE(PTD4);
00378         
00379         // disable all TLC59116 chips by default
00380         tlc59116.chipMask = 0;
00381         
00382         // Default TLC59116 pin assignments
00383         tlc59116.sda = PINNAME_TO_WIRE(PTC6);
00384         tlc59116.scl = PINNAME_TO_WIRE(PTC5);
00385         tlc59116.reset = PINNAME_TO_WIRE(PTC10);
00386         
00387         // Default IR hardware pin assignments.  On the expansion boards,
00388         // the sensor is connected to PTA13, and the emitter LED is on PTC9.
00389 #if TEST_CONFIG_EXPAN
00390         IR.sensor = PINNAME_TO_WIRE(PTA13);
00391         IR.emitter = PINNAME_TO_WIRE(PTC9);
00392 #else
00393         IR.sensor = PINNAME_TO_WIRE(NC);
00394         IR.emitter = PINNAME_TO_WIRE(NC);
00395 #endif     
00396 
00397         // clear out all IR slots
00398         memset(IRCommand, 0, sizeof(IRCommand));
00399         for (int i = 0 ; i < MAX_IR_CODES ; ++i)
00400         {
00401             IRCommand[i].protocol = 0;
00402             IRCommand[i].keytype = BtnTypeNone;
00403         }
00404    
00405         // initially configure with no LedWiz output ports
00406         outPort[0].typ = PortTypeDisabled;
00407         
00408         // initially configure with no shift key
00409         shiftButton.idx = 0;
00410         shiftButton.mode = 0;
00411             
00412         // initially configure with no input buttons
00413         for (int i = 0 ; i < MAX_BUTTONS ; ++i)
00414             button[i].set(PINNAME_TO_WIRE(NC), BtnTypeNone, 0);
00415 
00416 #if STANDARD_CONFIG | TEST_CONFIG_EXPAN
00417         // For the standard configuration, assign 24 input ports to
00418         // joystick buttons 1-24.  Assign the same GPIO pins used
00419         // in the original v1 default configuration.  For expansion
00420         // board testing purposes, also assign the input ports, with
00421         // the noted differences.
00422         for (int i = 0 ; i < 24 ; ++i) {
00423             static const int bp[] = {
00424                 PINNAME_TO_WIRE(PTC2),  // 1
00425                 PINNAME_TO_WIRE(PTB3),  // 2
00426                 PINNAME_TO_WIRE(PTB2),  // 3
00427                 PINNAME_TO_WIRE(PTB1),  // 4
00428                 PINNAME_TO_WIRE(PTE30), // 5 
00429 #if TEST_CONFIG_EXPAN
00430                 PINNAME_TO_WIRE(PTC11), // 6 - expansion boards use PTC11 for this, since PTE22
00431                                         //     is reserved for a plunger connection
00432 #elif STANDARD_CONFIG
00433                 PINNAME_TO_WIRE(PTE22), // 6 - original standalone setup uses PTE22
00434 #endif
00435                 PINNAME_TO_WIRE(PTE5),  // 7
00436                 PINNAME_TO_WIRE(PTE4),  // 8
00437                 PINNAME_TO_WIRE(PTE3),  // 9
00438                 PINNAME_TO_WIRE(PTE2),  // 10
00439                 PINNAME_TO_WIRE(PTB11), // 11 
00440                 PINNAME_TO_WIRE(PTB10), // 12 
00441                 PINNAME_TO_WIRE(PTB9),  // 13
00442                 PINNAME_TO_WIRE(PTB8),  // 14
00443                 PINNAME_TO_WIRE(PTC12), // 15 
00444                 PINNAME_TO_WIRE(PTC13), // 16 
00445                 PINNAME_TO_WIRE(PTC16), // 17 
00446                 PINNAME_TO_WIRE(PTC17), // 18 
00447                 PINNAME_TO_WIRE(PTA16), // 19 
00448                 PINNAME_TO_WIRE(PTA17), // 20 
00449                 PINNAME_TO_WIRE(PTE31), // 21 
00450                 PINNAME_TO_WIRE(PTD6),  // 22
00451                 PINNAME_TO_WIRE(PTD7),  // 23
00452                 PINNAME_TO_WIRE(PTE1)   // 24
00453             };               
00454             button[i].set(bp[i], 
00455 #if TEST_CONFIG_EXPAN
00456                 // For expansion board testing only, assign the inputs
00457                 // to keyboard keys A, B, etc.  This isn't useful; it's
00458                 // just for testing purposes.  Note that the USB key code
00459                 // for "A" is 4, "B" is 5, and so on sequentially through 
00460                 // the alphabet.
00461                 BtnTypeKey, i+4);
00462 #elif STANDARD_CONFIG
00463                 // For the standard configuration, assign the input to
00464                 // joystick buttons 1-24, as in the original v1 default
00465                 // configuration.
00466                 BtnTypeJoystick, i+1);
00467 #endif
00468 
00469         }
00470 #endif
00471         
00472 #if TEST_CONFIG_EXPAN
00473         // For testing purposes, configure the basic complement of 
00474         // expansion board ports.  AS MENTIONED ABOVE, THIS IS PURELY FOR
00475         // TESTING.  DON'T USE THIS METHOD TO CONFIGURE YOUR EXPANSION 
00476         // BOARDS FOR ACTUAL DEPLOYMENT.  It's much easier and cleaner
00477         // to use the unmodified standard build, and customize your
00478         // installation with the Pinscape Config Tool on Windows.
00479         //
00480         // For this testing setup, we'll configure one main board, one
00481         // power board, and one chime board.  The *physical* ports on
00482         // the board are shown below.  The logical (LedWiz/DOF) numbering
00483         // ISN'T sequential through the physical ports, because we want
00484         // to arrange the DOF ports so that the most important and most
00485         // common toys are assigned to ports 1-32.  Those ports are
00486         // special because they're accessible to ALL software on the PC,
00487         // including older LedWiz-only software such as Future Pinball.
00488         // Ports above 32 are accessible only to modern DOF software,
00489         // like Visual Pinball and PinballX.
00490         //
00491         //   Main board
00492         //     TLC ports 0-15  -> flashers
00493         //     TLC ports 16    -> strobe
00494         //     TLC ports 17-31 -> flippers
00495         //     Dig GPIO PTC8   -> knocker (timer-protected outputs)
00496         //
00497         //   Power board:
00498         //     TLC ports 32-63 -> general purpose outputs
00499         //
00500         //   Chime board:
00501         //     HC595 ports 0-7 -> timer-protected outputs
00502         //
00503         {
00504             int n = 0;
00505             
00506             // 1-15 = flashers (TLC ports 0-15)
00507             // 16   = strobe   (TLC port 15)
00508             for (int i = 0 ; i < 16 ; ++i)
00509                 outPort[n++].set(PortTypeTLC5940, i, PortFlagGamma);
00510             
00511             // 17 = knocker (PTC8)
00512             outPort[n++].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC8));
00513             
00514             // 18-49 = power board outputs 1-32 (TLC ports 32-63)
00515             for (int i = 0 ; i < 32 ; ++i)
00516                 outPort[n++].set(PortTypeTLC5940, i+32);
00517             
00518             // 50-65 = flipper RGB (TLC ports 16-31)
00519             for (int i = 0 ; i < 16 ; ++i)
00520                 outPort[n++].set(PortTypeTLC5940, i+16, PortFlagGamma);
00521                 
00522             // 66-73 = chime board ports 1-8 (74HC595 ports 0-7)
00523             for (int i = 0 ; i < 8 ; ++i)
00524                 outPort[n++].set(PortType74HC595, i);
00525                 
00526             // set Disabled to signify end of configured outputs
00527             outPort[n].typ = PortTypeDisabled;
00528         }
00529 #endif
00530 
00531 #if STANDARD_CONFIG
00532         //
00533         // For the standard build, set up the original complement
00534         // of 22 ports from the v1 default onfiguration.  
00535         //
00536         // IMPORTANT!  As mentioned above, don't edit this file to
00537         // customize this for your machine.  Instead, use the unmodified
00538         // standard build, and customize your installation using the
00539         // Pinscape Config Tool on Windows.
00540         //
00541 #if TEST_KEEP_PRINTF
00542         outPort[ 0].set(PortTypeVirtual, PINNAME_TO_WIRE(NC));       // port 1  = NC to keep debug printf (PTA1 is SDA UART)
00543         outPort[ 1].set(PortTypeVirtual, PINNAME_TO_WIRE(NC));       // port 2  = NC to keep debug printf (PTA2 is SDA UART)
00544 #else
00545         outPort[ 0].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA1));     // port 1  = PTA1
00546         outPort[ 1].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA2));     // port 2  = PTA2
00547 #endif
00548         outPort[ 2].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTD4));     // port 3  = PTD4
00549         outPort[ 3].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA12));    // port 4  = PTA12
00550         outPort[ 4].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA4));     // port 5  = PTA4
00551         outPort[ 5].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA5));     // port 6  = PTA5
00552         outPort[ 6].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTA13));    // port 7  = PTA13
00553         outPort[ 7].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTD5));     // port 8  = PTD5
00554         outPort[ 8].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTD0));     // port 9  = PTD0
00555         outPort[ 9].set(PortTypeGPIOPWM, PINNAME_TO_WIRE(PTD3));     // port 10 = PTD3
00556         outPort[10].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTD2));     // port 11 = PTD2
00557         outPort[11].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC8));     // port 12 = PTC8
00558         outPort[12].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC9));     // port 13 = PTC9
00559         outPort[13].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC7));     // port 14 = PTC7
00560         outPort[14].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC0));     // port 15 = PTC0
00561         outPort[15].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC3));     // port 16 = PTC3
00562         outPort[16].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC4));     // port 17 = PTC4
00563         outPort[17].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC5));     // port 18 = PTC5
00564         outPort[18].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC6));     // port 19 = PTC6
00565         outPort[19].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC10));    // port 20 = PTC10
00566         outPort[20].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTC11));    // port 21 = PTC11
00567         outPort[21].set(PortTypeGPIODig, PINNAME_TO_WIRE(PTE0));     // port 22 = PTE0
00568 #endif
00569     }        
00570     
00571     // --- USB DEVICE CONFIGURATION ---
00572     
00573     // USB device identification - vendor ID and product ID.  For LedLWiz
00574     // emulation, use vendor ID 0xFAFA and product ID 0x00EF + unit#, where
00575     // unit# is the nominal LedWiz unit number from 1 to 16.  Alternatively,
00576     // if LedWiz emulation isn't desired or causes any driver conflicts on
00577     // the host, we have a private Pinscape assignment as vendor ID 0x1209 
00578     // and product ID 0xEAEA (registered with http://pid.codes, a registry
00579     // for open-source USB projects).
00580     uint16_t usbVendorID;
00581     uint16_t usbProductID;
00582     
00583     // Pinscape Controller unit number.  This is the nominal unit number,
00584     // from 1 to 16.  We report this in the status query; DOF uses it to
00585     // distinguish among Pinscape units.  Note that this doesn't affect 
00586     // the LedWiz unit numbering, which is implied by the USB Product ID.
00587     uint8_t psUnitNo;
00588             
00589     // Are joystick reports enabled?  Joystick reports can be turned off, to
00590     // use the device as purely an output controller.
00591     uint8_t joystickEnabled;
00592     
00593     // Joystick axis report format, as a USBJoystick::AXIS_FORMAT_xxx value.
00594     uint8_t joystickAxisFormat;
00595     
00596     // Joystick report timing.  This is the minimum time between joystick
00597     // reports, in microseconds. 
00598     uint32_t jsReportInterval_us;
00599     
00600     // Timeout for rebooting the KL25Z when the connection is lost.  On some
00601     // hosts, the mbed USB stack has problems reconnecting after an initial
00602     // connection is dropped.  As a workaround, we can automatically reboot
00603     // the KL25Z when it detects that it's no longer connected, after the
00604     // interval set here expires.  The timeout is in seconds; setting this
00605     // to 0 disables the automatic reboot.
00606     uint8_t disconnectRebootTimeout;
00607     
00608     // --- ACCELEROMETER ---
00609     struct
00610     {
00611         // accelerometer orientation (OrientationXxx value)
00612         uint8_t orientation;
00613     
00614         // dynamic range (AccelRangeXxx value)
00615         uint8_t range;
00616     
00617         // Auto-centering mode:
00618         //   0 = auto-centering on, 5-second timer
00619         //   1-60 = auto-centering on with the given timer in seconds
00620         //   255 = auto-centering off
00621         uint8_t autoCenterTime;
00622         
00623         // Accelerometer report "stuttering".  This is the number of times 
00624         // that each accelerometer reading is repeated in the joystick 
00625         // reports.  If this is set to 1 (or 0), a new accelerometer reading 
00626         // is taken on every joystick report.  If set to 2, a new reading 
00627         // is taken on every other report, and the previous reading is 
00628         // repeated on the alternating reports.  If set to 3, we take a 
00629         // new  reading on each third report, and so on.  The purpose is 
00630         // to slow down accelerometer readings for the benefit of Visual
00631         // Pinball, which will miss readings if taken faster than the 
00632         // video refresh rate, while sending joystick reports at a
00633         // faster rate for lower button input latency.
00634         uint8_t stutter;
00635     
00636     } accel;
00637     
00638     
00639     // --- EXPANSION BOARDS ---
00640     struct
00641     {
00642         uint8_t typ;        // expansion board set type:
00643                             //    1 -> Pinscape Expansion Boards
00644                             //    2 -> Pinscape All-In-One (AIO)
00645         uint8_t vsn;        // board set interface version
00646         uint8_t ext[3];     // board set type-specific extended data
00647         
00648     } expan;
00649     
00650     
00651     // --- PLUNGER CONFIGURATION ---
00652     struct
00653     {
00654         // Plunger enabled/disabled.  Note that we use the status flag
00655         // bit 0x01 if enabled, 0x00 if disabled.  This conveniently
00656         // can be tested as though it's a bool, but should always be
00657         // stored as 0x01 or 0x00 so that it can be OR'ed into the
00658         // status report flag bits.
00659         uint8_t enabled;
00660 
00661         // plunger sensor type
00662         uint8_t sensorType;
00663     
00664         // Plunger sensor pins.  To accommodate a wide range of sensor types,
00665         // we keep a generic list of 4 pin assignments.  The use of each pin
00666         // varies by sensor.  The lists below are in order of the generic
00667         // pins; NC means that the pin isn't used by the sensor.  Each pin's
00668         // GPIO usage is also listed.  Certain usages limit which physical
00669         // pins can be assigned (e.g., AnalogIn or PwmOut).
00670         //
00671         // TSL1410R/1412S/1401CL:     SI (GPIO),       CLK (GPIO),       AO (AnalogIn),  NC
00672         // Potentiometer:             AO (AnalogIn),   NC,               NC,             NC
00673         // AEDR8300:                  A (InterruptIn), B (InterruptIn),  NC,             NC
00674         // AS5304:                    A (InterruptIn), B (InterruptIn),  NC,             NC
00675         // VL6180X:                   SDA (GPIO),      SCL (GPIO),       GPIO0/CE (GPIO)
00676         //
00677         // Note!  These are stored in uint8_t WIRE format, not PinName format.
00678         uint8_t sensorPin[4];
00679         
00680         // Automatic zeroing.  If enabled, we'll reset the plunger position to
00681         // the park position after a period of inactivity.  This only applies
00682         // to certain sensor types; sensors that don't use it simply ignore it.  
00683         struct
00684         {
00685             uint8_t flags;  // flags bits - combination of PlungerAutoZeroXxx flags
00686             uint8_t t;      // inactivity time in seconds
00687         } autoZero;
00688         
00689         // Jitter filter.  This is the size of the hysteresis window, in joystick
00690         // units (-4095..+4095).  One joystick unit is approximately 1/10000" of
00691         // physical travel.  Zero disables the jitter filter.
00692         uint16_t jitterWindow;
00693         
00694         // Plunger sensor reverse orientation flags.  This is a bit mask:
00695         //
00696         //  0x01 = Reverse orientation enabled.  We invert the plunger sensor
00697         //         readings, as though the sensor were physically flipped
00698         //         around.  This can be used to correct for installing the
00699         //         sensor backwards without having to change the hardware.
00700         //
00701         //  0x80 = READ-ONLY feature flag.  This always reads as set if the
00702         //         feature is enabled.  Note that the USB data exchanger always
00703         //         sets the bit on read, so it's not necessary to actually
00704         //         store it.
00705         //
00706         uint8_t reverseOrientation;
00707         
00708         // bar code sensor parameters
00709         struct
00710         {
00711             uint16_t startPix;  // starting pixel offset
00712         } barCode;
00713         
00714         // ZB LAUNCH BALL button setup.
00715         //
00716         // This configures the "ZB Launch Ball" feature in DOF, based on Zeb's (of 
00717         // zebsboards.com) scheme for using a mechanical plunger as a Launch button.
00718         // Set the port to 0 to disable the feature.
00719         //
00720         // The port number is an LedWiz port number that we monitor for activation.
00721         // This port isn't meant to be connected to a physical device, although it
00722         // can be if desired.  It's primarily to let the host tell the controller
00723         // when the ZB Launch feature is active.  The port numbering starts at 1;
00724         // set this to zero to disable the feature.
00725         //
00726         // The key type and code has the same meaning as for a button mapping.  This
00727         // sets the key input sent to the PC when the plunger triggers a launch when
00728         // the mode is active.  For example, set keytype=2 and keycode=0x28 to send
00729         // the Enter key (which is the key almost all PC pinball software uses for
00730         // plunger and Launch button input).
00731         //
00732         // The "push distance" is the distance, in 1/1000 inch units, for registering a 
00733         // push on the plunger as a button push.  If the player pushes the plunger 
00734         // forward of the rest position by this amount, we'll treat it as pushing the 
00735         // button, even if the player didn't pull back the plunger first.  This lets 
00736         // the player treat the plunger knob as a button for games where it's meaningful
00737         // to hold down the Launch button for specific intervals (e.g., "Championship 
00738         // Pub").
00739         struct
00740         {
00741             uint8_t port;
00742             uint8_t keytype;
00743             uint8_t keycode;
00744             uint16_t pushDistance;
00745         
00746         } zbLaunchBall;
00747            
00748         // --- PLUNGER CALIBRATION ---
00749         struct
00750         {
00751             // has the plunger been calibrated?
00752             bool calibrated;
00753             
00754             // Feature enable mask:
00755             //
00756             //  0x01 = calibration button enabled
00757             //  0x02 = indicator light enabled
00758             uint8_t features;
00759         
00760             // calibration button switch pin
00761             uint8_t btn;
00762         
00763             // calibration button indicator light pin
00764             uint8_t led;
00765             
00766             // Plunger calibration min, zero, and max.  These are in terms of the
00767             // unsigned 16-bit scale (0x0000..0xffff) that we use for the raw sensor
00768             // readings.
00769             //
00770             // The zero point is the rest position (aka park position), where the
00771             // plunger is in equilibrium between the main spring and the barrel 
00772             // spring.  In the standard setup, the plunger can travel a small 
00773             // distance forward of the rest position, because the barrel spring 
00774             // can be compressed a bit.  The minimum is the maximum forward point 
00775             // where the barrel spring can't be compressed any further.
00776             uint16_t min;
00777             uint16_t zero;
00778             uint16_t max;
00779             
00780             // Raw calibration data.  Some sensors need to keep track of raw
00781             // sensor data for calibration, in addition to the processed
00782             // range information that the generic code maintains.  We 
00783             // provide three uint16 slots for the specific sensor subclass's
00784             // use, with the meanings defined by the subclass.
00785             uint16_t raw0;
00786             uint16_t raw1;
00787             uint16_t raw2;
00788             
00789             // Measured release time, in milliseconds.
00790             uint8_t tRelease;
00791     
00792             // Reset the plunger calibration
00793             void setDefaults()
00794             {
00795                 calibrated = false;       // not calibrated
00796                 min = 0;                  // assume we can go all the way forward...
00797                 max = 0xffff;             // ...and all the way back
00798                 zero = max/6;             // the rest position is usually around 1/2" back = 1/6 of total travel
00799                 tRelease = 65;            // standard 65ms release time
00800                 raw0 = raw1 = raw2 = 0;   // clear the raw sensor data items
00801             }
00802             
00803             // Begin calibration.  This sets each limit to the worst
00804             // case point - for example, we set the retracted position
00805             // to all the way forward.  Each actual reading that comes
00806             // in is then checked against the current limit, and if it's
00807             // outside of the limit, we reset the limit to the new reading.
00808             void begin()
00809             {
00810                 min = 0;                  // we don't calibrate the maximum forward position, so keep this at zero
00811                 zero = 0xffff;            // set the zero position all the way back
00812                 max = 0;                  // set the retracted position all the way forward
00813                 tRelease = 65;            // revert to a default release time
00814             }
00815 
00816         } cal;
00817 
00818     } plunger;
00819 
00820     
00821     // --- TV ON SWITCH ---
00822     //
00823     // To use the TV ON switch feature, the special power sensing circuitry
00824     // implemented on the Expansion Board must be attached (or an equivalent
00825     // circuit, as described in the Build Guide).  The circuitry lets us
00826     // detect power state changes on the secondary power supply.
00827     struct 
00828     {
00829         // PSU2 power status sense (DigitalIn pin).  This pin goes LOW when the
00830         // secondary power supply is turned off, and remains LOW until the LATCH
00831         // pin is raised high AND the secondary PSU is turned on.  Once HIGH,
00832         // it remains HIGH as long as the secondary PSU is on.
00833         uint8_t statusPin;
00834     
00835         // PSU2 power status latch (DigitalOut pin)
00836         uint8_t latchPin;
00837         
00838         // TV ON relay pin (DigitalOut pin).  This pin controls the TV switch 
00839         // relay.  Raising the pin HIGH turns the relay ON (energizes the coil).
00840         uint8_t relayPin;
00841         
00842         // TV ON delay time, in 1/100 second units.  This is the interval between 
00843         // sensing that the secondary power supply has turned on and pulsing the 
00844         // TV ON switch relay.  
00845         int delayTime;
00846     
00847     } TVON;
00848     
00849     // --- Night Mode ---
00850     struct
00851     {
00852         uint8_t btn;        // night mode button number (1..MAX_BUTTONS, 0 = no button)
00853         uint8_t flags;      // flags:
00854                             //    0x01 = on/off switch (if not set, it's a momentary button)
00855         uint8_t port;       // indicator output port number (1..MAX_OUT_PORTS, 0 = no indicator)
00856     } nightMode;
00857     
00858 
00859     // --- TLC5940NT PWM Controller Chip Setup ---
00860     struct
00861     {
00862         // number of TLC5940NT chips connected in daisy chain
00863         uint8_t nchips;
00864         
00865         // pin connections (wire pin IDs)
00866         uint8_t sin;        // Serial data - must connect to SPIO MOSI -> PTC6 or PTD2
00867         uint8_t sclk;       // Serial clock - must connect to SPIO SCLK -> PTC5 or PTD1
00868                             // (but don't use PTD1, since it's hard-wired to the on-board blue LED)
00869         uint8_t xlat;       // XLAT (latch) signal - connect to any GPIO pin
00870         uint8_t blank;      // BLANK signal - connect to any GPIO pin
00871         uint8_t gsclk;      // Grayscale clock - must connect to a PWM-out capable pin
00872 
00873     } tlc5940; 
00874     
00875 
00876     // --- 74HC595 Shift Register Setup ---
00877     struct
00878     {
00879         // number of 74HC595 chips attached in daisy chain
00880         uint8_t nchips;
00881         
00882         // pin connections
00883         uint8_t sin;        // Serial data - use any GPIO pin
00884         uint8_t sclk;       // Serial clock - use any GPIO pin
00885         uint8_t latch;      // Latch - use any GPIO pin
00886         uint8_t ena;        // Enable signal - use any GPIO pin
00887     
00888     } hc595;
00889     
00890     // --- TLC59116 PWM Controller Chip Setup --
00891     struct
00892     {
00893         // Chip mask.  Each bit represents an enabled chip at the
00894         // corresponding 4-bit address (i.e., bit 1<<addr represents
00895         // the chip at 'addr').
00896         uint16_t chipMask;
00897         
00898         // pin connections
00899         uint8_t sda;        // I2C SDA
00900         uint8_t scl;        // I2C SCL
00901         uint8_t reset;      // !RESET (hardware reset line, active low)
00902         
00903     } tlc59116;
00904     
00905     
00906     // --- IR Remote Control Hardware Setup ---
00907     struct
00908     {
00909         // sensor (receiver) GPIO input pin; must be interrupt-capable
00910         uint8_t sensor;
00911         
00912         // IR emitter LED GPIO output pin; must be PWM-capable
00913         uint8_t emitter;
00914     } IR;
00915     
00916     
00917     // --- Button Input Setup ---
00918     ButtonCfg button[MAX_BUTTONS + VIRTUAL_BUTTONS] __attribute__((packed));
00919     
00920     // Shift button.  This can be used to give each physical button a
00921     // second meaning.
00922     struct
00923     {
00924         // Shift button index, 1..MAX_BUTTONS.  If this is zero, there's
00925         // no shift button.
00926         uint8_t idx;
00927         
00928         // Shift button mode.  If the shift button has a key mapping or
00929         // IR command assigned, this determines what happens when the 
00930         // shift button is pressed in combination with another key.
00931         //
00932         // 0 = Shift OR Key mode.  In this mode, when you initially press
00933         // the shift button, nothing happens.  Instead, we wait to see if
00934         // any other buttons are pressed.  If so, we use the shifted meaning
00935         // of the other button, and we DON'T send the shift button's key or
00936         // IR command at all.  
00937         //
00938         // 1 = Shift AND Key mode.  In this mode, the shift button acts like
00939         // any other button: its assigned key is sent to the PC as soon as
00940         // you press it.  If you also press another button while the shift
00941         // button is down, the shifted meaning of the other button is used.
00942         //
00943         // Mode 0, the "OR" mode, is the default.  This allows a button with
00944         // a key assignment to do double duty as the shift button without
00945         // creating any confusing situations where the shift button's own
00946         // key is also sent to the PC during shift usage.  
00947         uint8_t mode;
00948     
00949     } shiftButton;
00950 
00951     // --- LedWiz Output Port Setup ---
00952     LedWizPortCfg outPort[MAX_OUT_PORTS] __attribute__ ((packed));  // LedWiz & extended output ports 
00953 
00954     // --- IR Command Slots ---
00955     IRCommandCfg IRCommand[MAX_IR_CODES] __attribute__ ((packed));
00956 };
00957 
00958 #endif