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