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

USBProtocol.h

00001 // USB Message Protocol
00002 //
00003 // This file is purely for documentation, to describe our USB protocol
00004 // for incoming messages (host to device).  We use the standard HID setup 
00005 // with one endpoint in each direction.  See USBJoystick.cpp and .h for
00006 // the USB descriptors.
00007 //
00008 // Our incoming message protocol is an extended version of the protocol 
00009 // used by the LedWiz.  Our protocol is designed to be 100% backwards
00010 // compatible with clients using the original LedWiz wire protocol, as long 
00011 // as they only send well-formed messages in the original protocol.  The
00012 // "well-formed" part is an important condition, because our extensions to
00013 // the original protocol all consist of messages that aren't defined in the
00014 // original protocol and are meaningless to a real LedWiz.
00015 //
00016 // The protocol compatibility ensures that all original LedWiz clients can
00017 // also transparently access a Pinscape unit.  Clients will simply think the
00018 // Pinscape unit is an LedWiz, thus they'll be able to operate 32 of our
00019 // ports.  We designate the first 32 ports (ports 1-32) as the ones accessible
00020 // through the LedWiz protocol.
00021 //
00022 // In addition the wire-level protocol compatibility, we can provide legacy
00023 // LedWiz clients with access to more than 32 ports by emulating multiple
00024 // virtual LedWiz units.  We can't do this across the wire protocol, since
00025 // the KL25Z USB interface constrains us to a single VID/PID (which is how
00026 // LedWiz clients distinguish units).  However, virtuall all legacy LedWiz
00027 // clients access the device through a shared library, LEDWIZ.DLL, rather
00028 // than directly through USB.  LEDWIZ.DLL is distributed by the LedWiz's
00029 // manufacturer and has a published client interface.  We can thus provide
00030 // a replacement DLL that contains the logic needed to recognize a Pinscape
00031 // unit and represent it to clients as multiple LedWiz devices.  This allows
00032 // old clients to access our full complement of ports without any changes
00033 // to the clients.  We define some extended message types (SBX and PBX)
00034 // specifically to support this DLL feature.
00035 //
00036 
00037 
00038 // ------ OUTGOING MESSAGES (DEVICE TO HOST) ------
00039 //
00040 // General note: 16-bit and 32-bit fields in our reports are little-endian
00041 // unless otherwise specified.
00042 //
00043 // 1. Joystick reports
00044 // In most cases, our outgoing messages are HID joystick reports, using the
00045 // format defined in USBJoystick.cpp.  This allows us to be installed on
00046 // Windows as a standard USB joystick, which all versions of Windows support
00047 // using in-the-box drivers.  This allows a completely transparent, driverless,
00048 // plug-and-play installation experience on Windows.  Our joystick report
00049 // looks like this (see USBJoystick.cpp for the formal HID report descriptor):
00050 //
00051 //    ss     status bits:  
00052 //              0x01 -> plunger enabled
00053 //              0x02 -> night mode engaged
00054 //              0x04,0x08,0x10 -> power sense status: meaningful only when
00055 //                      the TV-on timer is used.  Figure (ss>>2) & 0x07 to
00056 //                      isolate the status bits.  The resulting value is:
00057 //                         1 -> latch was on at last check
00058 //                         2 -> latch was off at last check, SET pin high
00059 //                         3 -> latch off, SET pin low, ready to check status
00060 //                         4 -> TV timer countdown in progress
00061 //                         5 -> TV relay is on
00062 //                         6 -> sending IR signals designated as TV ON signals
00063 //              0x20 -> IR learning mode in progress
00064 //              0x40 -> configuration saved successfully (see below)
00065 //    00     2nd byte of status (reserved)
00066 //    00     3rd byte of status (reserved)
00067 //    00     always zero for joystick reports
00068 //    bb     joystick buttons, low byte (buttons 1-8, 1 bit per button)
00069 //    bb     joystick buttons, 2nd byte (buttons 9-16)
00070 //    bb     joystick buttons, 3rd byte (buttons 17-24)
00071 //    bb     joystick buttons, high byte (buttons 25-32)
00072 //    xx     low byte of X position = nudge/accelerometer X axis
00073 //    xx     high byte of X position
00074 //    yy     low byte of Y position = nudge/accelerometer Y axis
00075 //    yy     high byte of Y position
00076 //    zz     low byte of Z position = plunger position
00077 //    zz     high byte of Z position
00078 //
00079 // The X, Y, and Z values are 16-bit signed integers.  The accelerometer
00080 // values are on an abstract scale, where 0 represents no acceleration,
00081 // negative maximum represents -1g on that axis, and positive maximum
00082 // represents +1g on that axis.  For the plunger position, 0 is the park
00083 // position (the rest position of the plunger) and positive values represent
00084 // retracted (pulled back) positions.  A negative value means that the plunger
00085 // is pushed forward of the park position.
00086 //
00087 // Status bit 0x40 is set after a successful configuration update via special
00088 // command 65 6 (save config to flash).  The device always reboots after this
00089 // command, so if the host wants to receive a status update verifying the 
00090 // save, it has to request a non-zero reboot delay in the message to allow
00091 // us time to send at least one of these status reports after the save.
00092 // This bit is only sent after a successful save, which means that the flash
00093 // write succeeded and the written sectors verified as correct.
00094 // NOTE: older firmware versions didn't support this status bit, so clients
00095 // can't interpret the lack of a response as a failure for older versions.
00096 // To determine if the flag is supported, check the config report feature
00097 // flags.
00098 //
00099 //
00100 // 2. Special reports
00101 // We subvert the joystick report format in certain cases to report other 
00102 // types of information, when specifically requested by the host.  This allows
00103 // our custom configuration UI on the Windows side to query additional 
00104 // information that we don't normally send via the joystick reports.  We
00105 // define a custom vendor-specific "status" field in the reports that we
00106 // use to identify these special reports, as described below.
00107 //
00108 // Normal joystick reports always have 0 in the high bit of the 2nd byte
00109 // of the report.  Special non-joystick reports always have 1 in the high bit 
00110 // of the first byte.  (This byte is defined in the HID Report Descriptor
00111 // as an opaque vendor-defined value, so the joystick interface on the
00112 // Windows side simply ignores it.)
00113 //
00114 // 2A. Plunger sensor status report
00115 // Software on the PC can request a detailed status report from the plunger
00116 // sensor.  The status information is meant as an aid to installing and
00117 // adjusting the sensor device for proper performance.  For imaging sensor
00118 // types, the status report includes a complete current image snapshot
00119 // (an array of all of the pixels the sensor is currently imaging).  For
00120 // all sensor types, it includes the current plunger position registered
00121 // on the sensor, and some timing information.
00122 //
00123 // To request the sensor status, the host sends custom protocol message 65 3
00124 // (see below).  The device replies with a message in this format:
00125 //
00126 //    bytes 0:1 = 0x87FF
00127 //    byte  2   = 0 -> first status report packet
00128 //    bytes 3:4 = number of pixels to be sent in following messages, as
00129 //                an unsigned 16-bit little-endian integer.  This is 0 if 
00130 //                the sensor isn't an imaging type.
00131 //    bytes 5:6 = current plunger position registered on the sensor.  This
00132 //                is on the *native* scale for the sensor, which might be
00133 //                different from joystick units.  By default, the native
00134 //                scale is the number of pixels for an imaging sensor, or
00135 //                4096 for other sensor types.  The actual native scale can
00136 //                be reported separately via a second status report message
00137 //                (see below).
00138 //    byte  7   = bit flags: 
00139 //                   0x01 = normal orientation detected
00140 //                   0x02 = reversed orientation detected
00141 //                   0x04 = calibration mode is active (no pixel packets
00142 //                          are sent for this reading)
00143 //    bytes 8:9:10 = average time for each sensor read, in 10us units.
00144 //                This is the average time it takes to complete the I/O
00145 //                operation to read the sensor, to obtain the raw sensor
00146 //                data for instantaneous plunger position reading.  For 
00147 //                an imaging sensor, this is the time it takes for the 
00148 //                sensor to capture the image and transfer it to the
00149 //                microcontroller.  For an analog sensor (e.g., an LVDT
00150 //                or potentiometer), it's the time to complete an ADC
00151 //                sample.
00152 //    bytes 11:12:13 = time it took to process the current frame, in 10us 
00153 //                units.  This is the software processing time that was
00154 //                needed to analyze the raw data read from the sensor.
00155 //                This is typically only non-zero for imaging sensors,
00156 //                where it reflects the time required to scan the pixel
00157 //                array to find the indicated plunger position.  The time
00158 //                is usually zero or negligible for analog sensor types, 
00159 //                since the only "analysis" is a multiplication to rescale 
00160 //                the ADC sample.
00161 //
00162 // An optional second message provides additional information:
00163 //
00164 //    bytes 0:1 = 0x87FF
00165 //    byte  2   = 1 -> second status report packet
00166 //    bytes 3:4 = Native sensor scale.  This is the actual native scale
00167 //                used for the position report in the first status report
00168 //                packet above.
00169 //    bytes 5:6 = Jitter window lower bound, in native sensor scale units.
00170 //    bytes 7:8 = Jitter window upper bound, in native sensor scale units.
00171 //                The jitter window bounds reflect the current jitter filter
00172 //                status as of this reading.
00173 //    bytes 9:10 = Raw sensor reading before jitter filter was applied.
00174 //    bytes 11:12 = Auto-exposure time in microseconds
00175 //
00176 // An optional third message provides additional information specifically
00177 // for bar-code sensors:
00178 //
00179 //    bytes 0:1 = 0x87FF
00180 //    byte  2   = 2 -> bar code sensor extra status report
00181 //    byte  3   = number of bits in bar code
00182 //    byte  4   = bar code type:
00183 //                  1 = Gray code/Manchester bit coding
00184 //    bytes 5:6 = pixel offset of first bit
00185 //    byte  7   = width in pixels of each bit
00186 //    bytes 8:9 = raw bar code bits
00187 //    bytes 10:11 = mask of successfully read bar code bits; a '1' bit means
00188 //                that the bit was read successfully, '0' means the bit was
00189 //                unreadable
00190 //
00191 // Another optional third message provides additional information
00192 // specifically for digital quadrature sensors:
00193 //
00194 //    bytes 0:1 = 0x87FF
00195 //    byte  2   = 3 -> digital quadrature sensor extra status report
00196 //    byte  3   = "A" channel reading (0 or 1)
00197 //    byte  4   = "B" channel reading (0 or 1)
00198 //
00199 // Yet another optional third message provides additional information for
00200 // VCNL4010 sensors:
00201 //
00202 //    bytes 0:1 = 0x87FF
00203 //    bytes 2   = 4 -> VCNL4010 extra status report
00204 //    bytes 3:4 = last proximity count reading (16-bit, little-endian), jitter filtered
00205 //    bytes 5:6 = last proximity count reading, original unfiltered value
00206 //
00207 // If the sensor is an imaging sensor type, the first and second sensor
00208 // reports will be followed by a series of pixel reports giving the live
00209 // image view on the sensor.  The imaging sensor types have too many pixels
00210 // to send in a single USB transaction, so the device breaks up the array
00211 // into as many packets as needed and sends them in sequence.  For non-
00212 // imaging sensors, the "number of pixels" field in the lead packet is
00213 // zero, so obviously no pixel packets will follow.  If the "calibration
00214 // active" bit in the flags byte is set, no pixel packets are sent even
00215 // if the sensor is an imaging type, since the transmission time for the
00216 // pixels would interfere with the calibration process.  If pixels are sent,
00217 // they're sent in order starting at the first pixel.  The format of each 
00218 // pixel packet is:
00219 //
00220 //    bytes 0:1 = 11-bit index, with high 5 bits set to 10000.  For 
00221 //                example, 0x8004 (encoded little endian as 0x04 0x80) 
00222 //                indicates index 4.  This is the starting pixel number 
00223 //                in the report.  The first report will be 0x00 0x80 to 
00224 //                indicate pixel #0.  
00225 //    bytes 2   = 8-bit unsigned int brightness level of pixel at index
00226 //    bytes 3   = brightness of pixel at index+1
00227 //    etc for the rest of the packet
00228 //
00229 // Note that we currently only support one-dimensional imaging sensors
00230 // (i.e., pixel arrays that are 1 pixel wide).  The report format doesn't
00231 // have any provision for a two-dimensional layout.  The KL25Z probably
00232 // isn't powerful enough to do real-time image analysis on a 2D image
00233 // anyway, so it's unlikely that we'd be able to make 2D sensors work at
00234 // all, but if we ever add such a thing we'll have to upgrade the report 
00235 // format here accordingly.
00236 // 
00237 //
00238 // 2B. Configuration report.
00239 // This is requested by sending custom protocol message 65 4 (see below).
00240 // In reponse, the device sends one report to the host using this format:
00241 //
00242 //    bytes 0:1 = 0x8800.  This has the bit pattern 10001 in the high
00243 //                5 bits, which distinguishes it from regular joystick
00244 //                reports and from other special report types.
00245 //    bytes 2:3 = total number of configured outputs, little endian.  This
00246 //                is the number of outputs with assigned functions in the
00247 //                active configuration.
00248 //    byte  4   = Pinscape unit number (0-15)
00249 //    byte  5   = reserved (currently always zero)
00250 //    bytes 6:7 = plunger calibration zero point, little endian
00251 //    bytes 8:9 = plunger calibration maximum point, little endian
00252 //    byte  10  = plunger calibration release time, in milliseconds
00253 //    byte  11  = bit flags: 
00254 //                 0x01 -> configuration loaded; 0 in this bit means that
00255 //                         the firmware has been loaded but no configuration
00256 //                         has been sent from the host
00257 //                 0x02 -> SBX/PBX extension features: 1 in this bit means
00258 //                         that these features are present in this version.
00259 //                 0x04 -> new accelerometer features supported (adjustable
00260 //                         dynamic range, auto-centering on/off, adjustable
00261 //                         auto-centering time)
00262 //                 0x08 -> flash write status flag supported (see flag 0x40
00263 //                         in normal joystick status report)
00264 //                 0x10 -> joystick report timing features supports
00265 //                         (configurable joystick report interval, acceler-
00266 //                         ometer stutter counter)
00267 //                 0x20 -> chime logic is supported
00268 //    bytes 12:13 = available RAM, in bytes, little endian.  This is the amount
00269 //                of unused heap (malloc'able) memory.  The firmware generally
00270 //                allocates all of the dynamic memory it needs during startup,
00271 //                so the free memory figure doesn't tend to fluctuate during 
00272 //                normal operation.  The dynamic memory used is a function of 
00273 //                the set of features enabled.
00274 //
00275 // 2C. Device ID report.
00276 // This is requested by sending custom protocol message 65 7 (see below).
00277 // In response, the device sends one report to the host using this format:
00278 //
00279 //    bytes 0:1 = 0x9000.  This has bit pattern 10010 in the high 5 bits
00280 //                to distinguish this from other report types.
00281 //    byte 2    = ID type.  This is the same ID type sent in the request.
00282 //    bytes 3-12 = requested ID.  The ID is 80 bits in big-endian byte
00283 //                order.  For IDs longer than 80 bits, we truncate to the
00284 //                low-order 80 bits (that is, the last 80 bits).
00285 //
00286 //                ID type 1 = CPU ID.  This is the globally unique CPU ID
00287 //                  stored in the KL25Z CPU.
00288 //
00289 //                ID type 2 = OpenSDA ID.  This is the globally unique ID
00290 //                  for the connected OpenSDA controller, if known.  This
00291 //                  allow the host to figure out which USB MSD (virtual
00292 //                  disk drive), if any, represents the OpenSDA module for
00293 //                  this Pinscape USB interface.  This is primarily useful
00294 //                  to determine which MSD to write in order to update the
00295 //                  firmware on a given Pinscape unit.
00296 //
00297 // 2D. Configuration variable report.
00298 // This is requested by sending custom protocol message 65 9 (see below).
00299 // In response, the device sends one report to the host using this format:
00300 //
00301 //   bytes 0:1 = 0x9800.  This has bit pattern 10011 in the high 5 bits
00302 //               to distinguish this from other report types.
00303 //   byte  2   = Variable ID.  This is the same variable ID sent in the
00304 //               query message, to relate the reply to the request.
00305 //   bytes 3-8 = Current value of the variable, in the format for the
00306 //               individual variable type.  The variable formats are
00307 //               described in the CONFIGURATION VARIABLES section below.
00308 //
00309 // 2E. Software build information report.
00310 // This is requested by sending custom protocol message 65 10 (see below).
00311 // In response, the device sends one report using this format:
00312 //
00313 //   bytes 0:1 = 0xA000.  This has bit pattern 10100 in the high 5 bits
00314 //               (and 10100000 in the high 8 bits) to distinguish it from 
00315 //               other report types.
00316 //   bytes 2:5 = Build date.  This is returned as a 32-bit integer,
00317 //               little-endian as usual, encoding a decimal value
00318 //               in the format YYYYMMDD giving the date of the build.
00319 //               E.g., Feb 16 2016 is encoded as 20160216 (decimal).
00320 //   bytes 6:9 = Build time.  This is a 32-bit integer, little-endian,
00321 //               encoding a decimal value in the format HHMMSS giving
00322 //               build time on a 24-hour clock.
00323 //
00324 // 2F. Button status report.
00325 // This is requested by sending custom protocol message 65 13 (see below).
00326 // In response, the device sends one report using this format:
00327 //
00328 //   bytes 0:1 = 0xA1.  This has bit pattern 10100 in the high 5 bits (and
00329 //               10100001 in the high 8 bits) to distinguish it from other 
00330 //               report types.
00331 //   byte 2    = number of button reports
00332 //   byte 3    = Physical status of buttons 1-8, 1 bit each.  The low-order
00333 //               bit (0x01) is button 1.  Each bit is 0 if the button is off,
00334 //               1 if on.  This reflects the physical status of the button
00335 //               input pins, after debouncing but before any logical state
00336 //               processing.  Pulse mode and shifting have no effect on the
00337 //               physical state; this simply indicates whether the button is
00338 //               electrically on (shorted to GND) or off (open circuit).
00339 //   byte 4    = buttons 9-16
00340 //   byte 5    = buttons 17-24
00341 //   byte 6    = buttons 25-32
00342 //   byte 7    = buttons 33-40
00343 //   byte 8    = buttons 41-48
00344 //
00345 // 2G. IR sensor data report.
00346 // This is requested by sending custom protocol message 65 12 (see below).
00347 // That command puts controller in IR learning mode for a short time, during
00348 // which it monitors the IR sensor and send these special reports to relay the
00349 // readings.  The reports contain the raw data, plus the decoded command code
00350 // and protocol information if the controller is able to recognize and decode
00351 // the command.
00352 //
00353 //   bytes 0:1 = 0xA2.  This has bit pattern 10100 in the high 5 bits (and
00354 //               10100010 in the high 8 bits to distinguish it from other 
00355 //               report types.
00356 //   byte 2    = number of raw reports that follow
00357 //   bytes 3:4 = first raw report, as a little-endian 16-bit int.  The
00358 //               value represents the time of an IR "space" or "mark" in
00359 //               2us units.  The low bit is 0 for a space and 1 for a mark.
00360 //               To recover the time in microseconds, mask our the low bit
00361 //               and multiply the result by 2.  Received codes always
00362 //               alternate between spaces and marks.  A space is an interval
00363 //               where the IR is off, and a mark is an interval with IR on.
00364 //               If the value is 0xFFFE (after masking out the low bit), it
00365 //               represents a timeout, that is, a time greater than or equal
00366 //               to the maximum that can be represented in this format,
00367 //               which is 131068us.  None of the IR codes we can parse have
00368 //               any internal signal component this long, so a timeout value 
00369 //               is generally seen only during a gap between codes where 
00370 //               nothing is being transmitted.
00371 //   bytes 4:5 = second raw report
00372 //   (etc for remaining reports)
00373 //
00374 //   If byte 2 is 0x00, it indicates that learning mode has expired without
00375 //   a code being received, so it's the last report sent for the learning
00376 //   session.
00377 //
00378 //   If byte 2 is 0xFF, it indicates that a code has been successfully 
00379 //   learned.  The rest of the report contains the learned code instead
00380 //   of the raw data:
00381 //
00382 //   byte 3 = protocol ID, which is an integer giving an internal code
00383 //            identifying the IR protocol that was recognized for the 
00384 //            received data.  See IRProtocolID.h for a list of the IDs.
00385 //   byte 4 = bit flags:
00386 //            0x02 -> the protocol uses "dittos"
00387 //   bytes 5:6:7:8:9:10:11:12 = a little-endian 64-bit int containing
00388 //            the code received.  The code is essentially the data payload 
00389 //            of the IR packet, after removing bits that are purely
00390 //            structural, such as toggle bits and error correction bits.
00391 //            The mapping between the IR bit stream and our 64-bit is 
00392 //            essentially arbitrary and varies by protocol, but it always
00393 //            has round-trip fidelity: using the 64-bit code value +
00394 //            protocol ID + flags to send an IR command will result in
00395 //            the same IR bit sequence being sent, modulo structural bits 
00396 //            that need to be updates in the reconstruction (such as toggle
00397 //            bits or sequencing codes).
00398 //
00399 //
00400 // WHY WE USE A HACKY APPROACH TO DIFFERENT REPORT TYPES
00401 //
00402 // The HID report system was specifically designed to provide a clean,
00403 // structured way for devices to describe the data they send to the host.
00404 // Our approach isn't clean or structured; it ignores the promises we
00405 // make about the contents of our report via the HID Report Descriptor
00406 // and stuffs our own different data format into the same structure.
00407 //
00408 // We use this hacky approach only because we can't use the standard USB
00409 // HID mechanism for varying report types, which is to provide multiple
00410 // report descriptors and tag each report with a type byte that indicates 
00411 // which descriptor applies.  We can't use that standard approach because
00412 // we want to be 100% LedWiz compatible.  The snag is that some Windows
00413 // LedWiz clients parse the USB HID descriptors as part of identifying a
00414 // USB HID device as a valid LedWiz unit, and will only recognize the device
00415 // if certain properties of the HID descriptors match those of a real LedWiz.
00416 // One of the features that's important to some clients is the descriptor 
00417 // link structure, which is affected by the layout of HID Report Descriptor 
00418 // entries.  In order to match the expected layout, we can only define a 
00419 // single kind of output report.  Since we have to use Joystick reports for 
00420 // the sake of VP and other pinball software, and we're only allowed the 
00421 // one report type, we have to make that one report type the Joystick type.  
00422 // That's why we overload the joystick reports with other meanings.  It's a
00423 // hack, but at least it's a fairly reliable and isolated hack, in that our 
00424 // special reports are only generated when clients specifically ask for 
00425 // them.  Plus, even if a client who doesn't ask for a special report 
00426 // somehow gets one, the worst that happens is that they get a momentary 
00427 // spurious reading from the accelerometer and plunger.
00428 
00429 
00430 
00431 // ------- INCOMING MESSAGES (HOST TO DEVICE) -------
00432 //
00433 // For LedWiz compatibility, our incoming message format conforms to the
00434 // basic USB format used by real LedWiz units.  This is simply 8 data
00435 // bytes, all private vendor-specific values (meaning that the Windows HID
00436 // driver treats them as opaque and doesn't attempt to parse them).
00437 //
00438 // Within this basic 8-byte format, we recognize the full protocol used
00439 // by real LedWiz units, plus an extended protocol that we define privately.
00440 // The LedWiz protocol leaves a large part of the potential protocol space 
00441 // undefined, so we take advantage of this undefined region for our 
00442 // extensions.  This ensures that we can properly recognize all messages 
00443 // intended for a real LedWiz unit, as well as messages from custom host 
00444 // software that knows it's talking to a Pinscape unit.
00445 
00446 // --- REAL LED WIZ MESSAGES ---
00447 //
00448 // The real LedWiz protocol has two message types, "SBA" and "PBA".  The
00449 // message type can be determined from the first byte of the 8-byte message
00450 // packet: if the first byte 64 (0x40), it's an SBA message.  If the first
00451 // byte is 0-49 or 129-132, it's a PBA message.  All other byte values are
00452 // invalid in the original protocol and have undefined behavior if sent to
00453 // a real LedWiz.  We take advantage of this to extend the protocol with
00454 // our new features by assigning new meanings to byte patterns that have no 
00455 // meaning in the original protocol.
00456 //
00457 // "SBA" message:   64 xx xx xx xx ss 00 00
00458 //     xx = on/off bit mask for 8 outputs
00459 //     ss = global flash speed setting (valid values 1-7)
00460 //     00 = unused/reserved; client should set to zero (not enforced, but
00461 //          strongly recommended in case of future additions)
00462 //
00463 // If the first byte has value 64 (0x40), it's an SBA message.  This type of 
00464 // message sets all 32 outputs individually ON or OFF according to the next 
00465 // 32 bits (4 bytes) of the message, and sets the flash speed to the value in 
00466 // the sixth byte.  The flash speed sets the global cycle rate for flashing
00467 // outputs - outputs with their values set to the range 128-132.  The speed
00468 // parameter is in ad hoc units that aren't documented in the LedWiz API, but
00469 // observations of real LedWiz units show that the "speed" is actually the
00470 // period, each unit representing 0.25s: so speed 1 is a 0.25s period, or 4Hz,
00471 // speed 2 is a 0.5s period or 2Hz, etc., up to speed 7 as a 1.75s period or
00472 // 0.57Hz.  The period is the full waveform cycle time.
00473 //
00474 //
00475 // "PBA" message:  bb bb bb bb bb bb bb bb
00476 //     bb = brightness level, 0-49 or 128-132
00477 //
00478 // Note that there's no prefix byte indicating this message type.  This
00479 // message is indicated simply by the first byte being in one of the valid
00480 // ranges.
00481 //
00482 // Each byte gives the new brightness level or flash pattern for one part.
00483 // The valid values are:
00484 //
00485 //     0-48 = fixed brightness level, linearly from 0% to 100% intensity
00486 //     49   = fixed brightness level at 100% intensity (same as 48)
00487 //     129  = flashing pattern, fade up / fade down (sawtooth wave)
00488 //     130  = flashing pattern, on / off (square wave)
00489 //     131  = flashing pattern, on for 50% duty cycle / fade down
00490 //     132  = flashing pattern, fade up / on for 50% duty cycle
00491 //
00492 // This message sets new brightness/flash settings for 8 ports.  There's
00493 // no port number specified in the message; instead, the port is given by
00494 // the protocol state.  Specifically, the device has an internal register
00495 // containing the base port for PBA messages.  On reset AND after any SBA
00496 // message is received, the base port is set to 0.  After any PBA message
00497 // is received and processed, the base port is incremented by 8, resetting
00498 // to 0 when it reaches 32.  The bytes of the message set the brightness
00499 // levels for the base port, base port + 1, ..., base port + 7 respectively.
00500 //
00501 //
00502 
00503 // --- PRIVATE EXTENDED MESSAGES ---
00504 //
00505 // All of our extended protocol messages are identified by the first byte:
00506 //
00507 // 65  -> Miscellaneous control message.  The second byte specifies the specific
00508 //        operation:
00509 //
00510 //        0 -> No Op - does nothing.  (This can be used to send a test message on the
00511 //             USB endpoint.)
00512 //
00513 //        1 -> Set the device's LedWiz unit number and plunger status, and save the 
00514 //             changes to flash.  The device automatically reboots after the changes 
00515 //             are saved if the unit number is changed, since this changes the USB
00516 //             product ID code.  The additional bytes of the message give the 
00517 //             parameters:
00518 //
00519 //               third byte  = new LedWiz unit number (0-15, corresponding to nominal 
00520 //                             LedWiz unit numbers 1-16)
00521 //               fourth byte = plunger on/off (0=disabled, 1=enabled)
00522 //
00523 //             Note that this command is from the original version and isn't typically
00524 //             used any more, since the same information has been subsumed into more
00525 //             generalized option settings via the config variable system.
00526 //
00527 //        2 -> Begin plunger calibration mode.  The device stays in this mode for about
00528 //             15 seconds, and sets the zero point and maximum retraction points to the
00529 //             observed endpoints of sensor readings while the mode is running.  After
00530 //             the time limit elapses, the device automatically stores the results in
00531 //             non-volatile flash memory and exits the mode.
00532 //
00533 //        3 -> Send pixel dump.  The device sends one complete image snapshot from the
00534 //             plunger sensor, as as series of pixel dump messages.  (The message format
00535 //             isn't big enough to allow the whole image to be sent in one message, so
00536 //             the image is broken up into as many messages as necessary.)  The device
00537 //             then resumes sending normal joystick messages.  If the plunger sensor 
00538 //             isn't an imaging type, or no sensor is installed, no pixel messages are 
00539 //             sent.  Parameters:
00540 //
00541 //               third byte = bit flags:
00542 //                  0x01 = low res mode.  The device rescales the sensor pixel array
00543 //                         sent in the dump messages to a low-resolution subset.  The
00544 //                         size of the subset is determined by the device.  This has
00545 //                         no effect on the sensor operation; it merely reduces the
00546 //                         USB transmission time to allow for a faster frame rate for
00547 //                         viewing in the config tool.
00548 //
00549 //               fourth byte = extra exposure time in 100us (.1ms) increments.  For
00550 //                  imaging sensors, we'll add this delay to the minimum exposure 
00551 //                  time.  This allows the caller to explicitly adjust the exposure
00552 //                  level for calibration purposes.
00553 //
00554 //        4 -> Query configuration.  The device sends a special configuration report,
00555 //             (see above; see also USBJoystick.cpp), then resumes sending normal 
00556 //             joystick reports.
00557 //
00558 //        5 -> Turn all outputs off and restore LedWiz defaults.  Sets all output 
00559 //             ports to OFF and LedWiz brightness/mode setting 48, and sets the LedWiz
00560 //             global flash speed to 2.
00561 //
00562 //        6 -> Save configuration to flash.  This saves all variable updates sent via
00563 //             type 66 messages since the last reboot, then optionally reboots the
00564 //             device to put the changes into effect.  If the flash write succeeds,
00565 //             we set the "flash write OK" bit in our status reports, which we 
00566 //             continue sending between the successful write and the delayed reboot.
00567 //             We don't set the bit or reboot if the write fails.  If the "do not
00568 //             reboot" flag is set, we still set the flag on success for the delay 
00569 //             time, then clear the flag.
00570 //
00571 //               third byte = delay time in seconds.  The device will wait this long
00572 //               before disconnecting, to allow the PC to test for the success bit
00573 //               in the status report, and to perform any cleanup tasks while the 
00574 //               device is still attached (e.g., modifying Windows device driver 
00575 //               settings)
00576 //
00577 //               fourth byte = flags:
00578 //                 0x01 -> do not reboot
00579 //
00580 //        7 -> Query device ID.  The device replies with a special device ID report
00581 //             (see above; see also USBJoystick.cpp), then resumes sending normal
00582 //             joystick reports.
00583 //
00584 //             The third byte of the message is the ID index to retrieve:
00585 //
00586 //                 1 = CPU ID: returns the KL25Z globally unique CPU ID.
00587 //
00588 //                 2 = OpenSDA ID: returns the OpenSDA TUID.  This must be patched
00589 //                     into the firmware by the PC host when the .bin file is
00590 //                     installed onto the device.  This will return all 'X' bytes
00591 //                     if the value wasn't patched at install time.
00592 //
00593 //        8 -> Engage/disengage night mode.  The third byte of the message is 1 to
00594 //             engage night mode, 0 to disengage night mode.  The current mode isn't 
00595 //             stored persistently; night mode is always off after a reset.
00596 //
00597 //        9 -> Query configuration variable.  The second byte is the config variable
00598 //             number (see the CONFIGURATION VARIABLES section below).  For the array
00599 //             variables (button assignments, output ports), the third byte is the
00600 //             array index.  The device replies with a configuration variable report
00601 //             (see above) with the current setting for the requested variable.
00602 //
00603 //       10 -> Query software build information.  No parameters.  This replies with
00604 //             the software build information report (see above).
00605 //
00606 //       11 -> TV ON relay manual control.  This allows testing and operating the
00607 //             relay from the PC.  This doesn't change the power-up configuration;
00608 //             it merely allows the relay to be controlled directly.  The third
00609 //             byte specifies the relay operation to perform:
00610 //              
00611 //                 0 = turn relay off
00612 //                 1 = turn relay on
00613 //                 2 = pulse the relay as though the power-on delay timer fired
00614 //
00615 //       12 -> Learn IR code.  The device enters "IR learning mode".  While in 
00616 //             learning mode, the device reports the raw signals read through 
00617 //             the IR sensor to the PC through the special IR learning report 
00618 //             (see "2G" above).  If a signal can be decoded through a known 
00619 //             protocol, the device sends a final "2G" report with the decoded 
00620 //             command, then terminates learning mode.  If no signal can be 
00621 //             decoded within a timeout period, the mode automatically ends,
00622 //             and the device sends a final IR learning report with zero raw 
00623 //             signals to indicate termination.  After initiating IR learning 
00624 //             mode, the user should point the remote control with the key to 
00625 //             be learned at the IR sensor on the KL25Z, and press and hold the 
00626 //             key on the remote for a few seconds.  Holding the key for a few
00627 //             moments is important because it lets the decoder sense the type
00628 //             of auto-repeat coding the remote uses.  The learned code can be
00629 //             written to an IR config variable slot to program the controller
00630 //             to send the learned command on events like TV ON or a button
00631 //             press.
00632 //             
00633 //       13 -> Get button status report.  The device sends one button status 
00634 //             report in response (see section "2F" above).
00635 //
00636 //       14 -> Manually center the accelerometer.  This sets the accelerometer
00637 //             zero point to the running average of readings over the past few
00638 //             seconds.
00639 //
00640 //       15 -> Set up ad hoc IR command, part 1.  This sets up the first part 
00641 //             of an IR command to transmit.  The device stores the data in an
00642 //             internal register for later use in message 65 16.  Send the
00643 //             remainder of the command data with 65 16.
00644 //
00645 //               byte 3 = IR protocol ID
00646 //               byte 4 = flags (IRFlagXxx bit flags)
00647 //               byte 5-8 = low-order 32 bits of command code, little-endian
00648 //
00649 //       16 -> Finish and send an ad hoc IR command.  Use message 65 15 first
00650 //             to set up the start of the command data, then send this message 
00651 //             to fill in the rest of the data and transmit the command.  Upon
00652 //             receiving this message, the device performs the transmission.
00653 //
00654 //               byte 3-6 = high-order 32 bits of command code, little-endian
00655 //
00656 //       17 -> Send a pre-programmed IR command.  This immediately transmits an
00657 //             IR code stored in a command slot.
00658 //
00659 //               byte 3 = command number (1..MAX_IR_CODES)
00660 //               
00661 //
00662 // 66  -> Set configuration variable.  The second byte of the message is the config
00663 //        variable number, and the remaining bytes give the new value for the variable.
00664 //        The value format is specific to each variable; see the CONFIGURATION VARIABLES
00665 //        section below for a list of the variables and their formats.  This command
00666 //        only sets the value in RAM; it doesn't write the value to flash and doesn't 
00667 //        put the change into effect.  To save the new settings, the host must send a 
00668 //        type 65 subtype 6 message (see above).  That saves the settings to flash and
00669 //        reboots the device, which makes the new settings active.
00670 //
00671 // 67  -> "SBX".  This is an extended form of the original LedWiz SBA message.  This
00672 //        version is specifically designed to support a replacement LEDWIZ.DLL on the
00673 //        host that exposes one Pinscape device as multiple virtual LedWiz devices,
00674 //        in order to give legacy clients access to more than 32 ports.  Each virtual
00675 //        LedWiz represents a block of 32 ports.  The format of this message is the
00676 //        same as for the original SBA, with the addition of one byte:
00677 //
00678 //            67 xx xx xx xx ss pp 00
00679 //               xx = on/off switches for 8 ports, one bit per port
00680 //               ss = global flash speed setting for this bank of ports, 1-7
00681 //               pp = port group: 0 for ports 1-32, 1 for ports 33-64, etc
00682 //               00 = unused/reserved; client should set to zero
00683 //
00684 //        As with SBA, this sets the on/off switch states for a block of 32 ports.
00685 //        SBA always addresses ports 1-32; SBX can address any set of 32 ports.
00686 //
00687 //        We keep a separate speed setting for each group of 32 ports.  The purpose
00688 //        of the SBX extension is to allow a custom LEDWIZ.DLL to expose multiple
00689 //        virtual LedWiz units to legacy clients, so clients will expect each unit
00690 //        to have its separate flash speed setting.  Each block of 32 ports maps to
00691 //        a virtual unit on the client side, so each block needs its own speed state.
00692 //
00693 // 68  -> "PBX".  This is an extended form of the original LedWiz PBA message; it's
00694 //        the PBA equivalent of our SBX extension above.
00695 //
00696 //            68 pp ee ee ee ee ee ee
00697 //               pp = port group: 0 for ports 1-8, 1 for 9-16, etc
00698 //               qq = sequence number: 0 for the first 8 ports in the group, etc
00699 //               ee = brightness/flash values, 6 bits per port, packed into the bytes
00700 //
00701 //        The port group 'pp' selects a group of 8 ports.  Note that, unlike PBA,
00702 //        the port group being updated is explicitly coded in the message, which makes
00703 //        the message stateless.  This eliminates any possibility of the client and
00704 //        host getting out of sync as to which ports they're talking about.  This
00705 //        message doesn't affect the PBA port address state.
00706 //
00707 //        The brightness values are *almost* the same as in PBA, but not quite.  We
00708 //        remap the flashing state values as follows:
00709 //
00710 //            0-48 = brightness level, 0% to 100%, on a linear scale
00711 //            49   = brightness level 100% (redundant with 48)
00712 //            60   = PBA 129 equivalent, sawtooth
00713 //            61   = PBA 130 equivalent, square wave (on/off)
00714 //            62   = PBA 131 equivalent, on/fade down
00715 //            63   = PBA 132 equivalent, fade up/on
00716 //
00717 //        We reassign the brightness levels like this because it allows us to pack
00718 //        every possible value into 6 bits.  This allows us to fit 8 port settings
00719 //        into six bytes.  The 6-bit fields are packed into the 8 bytes consecutively
00720 //        starting with the low-order bit of the first byte.  An efficient way to
00721 //        pack the 'ee' fields given the brightness values is to shift each group of 
00722 //        four bytes  into a uint, then shift the uint into three 'ee' bytes:
00723 //
00724 //           unsigned int tmp1 = bri[0] | (bri[1]<<6) | (bri[2]<<12) | (bri[3]<<18);
00725 //           unsigned int tmp2 = bri[4] | (bri[5]<<6) | (bri[6]<<12) | (bri[7]<<18);
00726 //           unsigned char port_group = FIRST_PORT_TO_ADDRESS / 8;
00727 //           unsigned char msg[8] = {
00728 //               68, pp, 
00729 //               tmp1 & 0xFF, (tmp1 >> 8) & 0xFF, (tmp1 >> 16) & 0xFF,
00730 //               tmp2 & 0xFF, (tmp2 >> 8) & 0xFF, (tmp2 >> 16) & 0xFF
00731 //           };
00732 //        
00733 // 200-228 -> Set extended output brightness.  This sets outputs N to N+6 to the
00734 //        respective brightness values in the 2nd through 8th bytes of the message
00735 //        (output N is set to the 2nd byte value, N+1 is set to the 3rd byte value, 
00736 //        etc).  Each brightness level is a linear brightness level from 0-255,
00737 //        where 0 is 0% brightness and 255 is 100% brightness.  N is calculated as
00738 //        (first byte - 200)*7 + 1:
00739 //
00740 //               200 = outputs 1-7
00741 //               201 = outputs 8-14
00742 //               202 = outputs 15-21
00743 //               ...
00744 //               228 = outputs 197-203
00745 //
00746 //        This message is the way to address ports 33 and higher.  Original LedWiz
00747 //        protocol messages can't access ports above 32, since the protocol is
00748 //        hard-wired for exactly 32 ports.
00749 //
00750 //        Note that the extended output messages differ from regular LedWiz commands
00751 //        in two ways.  First, the brightness is the ONLY attribute when an output is
00752 //        set using this mode.  There's no separate ON/OFF state per output as there 
00753 //        is with the SBA/PBA messages.  To turn an output OFF with this message, set
00754 //        the intensity to 0.  Setting a non-zero intensity turns it on immediately
00755 //        without regard to the SBA status for the port.  Second, the brightness is
00756 //        on a full 8-bit scale (0-255) rather than the LedWiz's approximately 5-bit
00757 //        scale, because there are no parts of the range reserved for flashing modes.
00758 //
00759 //        Outputs 1-32 can be controlled by EITHER the regular LedWiz SBA/PBA messages
00760 //        or by the extended messages.  The latest setting for a given port takes
00761 //        precedence.  If an SBA/PBA message was the last thing sent to a port, the
00762 //        normal LedWiz combination of ON/OFF and brightness/flash mode status is used
00763 //        to determine the port's physical output setting.  If an extended brightness
00764 //        message was the last thing sent to a port, the LedWiz ON/OFF status and
00765 //        flash modes are ignored, and the fixed brightness is set.  Outputs 33 and
00766 //        higher inherently can't be addressed or affected by SBA/PBA messages.
00767 //
00768 //        (The precedence scheme is designed to accommodate a mix of legacy and DOF
00769 //        software transparently.  The behavior described is really just to ensure
00770 //        transparent interoperability; it's not something that host software writers
00771 //        should have to worry about.  We expect that anyone writing new software will
00772 //        just use the extended protocol and ignore the old LedWiz commands, since
00773 //        the extended protocol is easier to use and more powerful.)
00774 
00775 
00776 // ------- CONFIGURATION VARIABLES -------
00777 //
00778 // Message type 66 (see above) sets one configuration variable.  The second byte
00779 // of the message is the variable ID, and the rest of the bytes give the new
00780 // value, in a variable-specific format.  16-bit values are little endian.
00781 // Any bytes at the end of the message not otherwise specified are reserved
00782 // for future use and should always be set to 0 in the message data.
00783 //
00784 // Variable IDs:
00785 //
00786 // 0  -> QUERY ONLY: Describe the configuration variables.  The device
00787 //       sends a config variable query report with the following fields:
00788 //         
00789 //         byte 3  -> number of scalar (non-array) variables (these are
00790 //                    numbered sequentially from 1 to N)
00791 //         byte 4  -> number of array variables (these are numbered
00792 //                    sequentially from 256-N to 255)
00793 //          
00794 //       The description query is meant to allow the host to capture all
00795 //       configuration settings on the device without having to know what
00796 //       the variables mean or how many there are.  This is useful for
00797 //       backing up the settings in a file on the PC, for example, or for
00798 //       capturing them to restore after a firmware update.  This allows
00799 //       more flexible interoperability between unsynchronized versions 
00800 //       of the firmware and the host software.
00801 //
00802 // 1  -> USB device ID.  This sets the USB vendor and product ID codes
00803 //       to use when connecting to the PC.  For LedWiz emulation, use
00804 //       vendor 0xFAFA and product 0x00EF + unit# (where unit# is the
00805 //       nominal LedWiz unit number, from 1 to 16).  If you have any
00806 //       REAL LedWiz units in your system, we recommend starting the
00807 //       Pinscape LedWiz numbering at 8 to avoid conflicts with the 
00808 //       real LedWiz units.  If you don't have any real LedWiz units,
00809 //       you can number your Pinscape units starting from 1.
00810 //
00811 //       If LedWiz emulation isn't desired or causes host conflicts, 
00812 //       use our private ID: Vendor 0x1209, product 0xEAEA.  (These IDs
00813 //       are registered with http://pid.codes, a registry for open-source 
00814 //       USB devices, so they're guaranteed to be free of conflicts with
00815 //       other properly registered devices).  The device will NOT appear
00816 //       as an LedWiz if you use the private ID codes, but DOF (R3 or 
00817 //       later) will still recognize it as a Pinscape controller.
00818 //
00819 //         bytes 3:4 -> USB Vendor ID
00820 //         bytes 5:6 -> USB Product ID
00821 //
00822 // 2  -> Pinscape Controller unit number for DOF.  The Pinscape unit
00823 //       number is independent of the LedWiz unit number, and indepedent
00824 //       of the USB vendor/product IDs.  DOF (R3 and later) uses this to 
00825 //       identify the unit for the extended Pinscape functionality.
00826 //       For easiest DOF configuration, we recommend numbering your
00827 //       units sequentially starting at 1 (regardless of whether or not
00828 //       you have any real LedWiz units).
00829 //
00830 //         byte 3 -> unit number, from 1 to 16
00831 //
00832 // 3  -> Joystick report settings.
00833 //
00834 //         byte 3 -> Enable joystick interface: 1 to enable, 0 to disable
00835 //         byte 4 -> Joystick axis format, as a USBJoystick::AXIS_FORMAT_XXX value
00836 //         bytes 5:8 -> Reporting interval in microseconds
00837 //
00838 //       When joystick reports are disabled, the device registers as a generic HID 
00839 //       device, and only sends the private report types used by the Windows config 
00840 //       tool.  It won't appear to Windows as a USB game controller or joystick.
00841 //
00842 //       Note that this doesn't affect whether the device also registers a keyboard
00843 //       interface.  A keyboard interface will appear if and only if any buttons
00844 //       (including virtual buttons, such as the ZB Launch Ball feature) are assigned 
00845 //       to generate keyboard key input.
00846 //
00847 // 4  -> Accelerometer settings
00848 //
00849 //        byte 3 -> orientation:
00850 //           0 = ports at front (USB ports pointing towards front of cabinet)
00851 //           1 = ports at left
00852 //           2 = ports at right
00853 //           3 = ports at rear
00854 //        byte 4 -> dynamic range
00855 //           0 = +/- 1G (2G hardware mode, but rescales joystick reports to 1G 
00856 //                   range; compatible with older versions)
00857 //           1 = +/- 2G (2G hardware mode)
00858 //           2 = +/- 4G (4G hardware mode)
00859 //           3 = +/- 8G (8G hardware mode)
00860 //        byte 5 -> Auto-centering mode
00861 //           0      = auto-centering on, 5 second timer (default, compatible 
00862 //                    with older versions)
00863 //           1-60   = auto-centering on with the given time in seconds
00864 //           61-245 = reserved
00865 //           255    = auto-centering off; manual centering only
00866 //        byte 6 -> joystick report stutter count: 1 (or 0) means that we
00867 //           take a fresh accelerometer on every joystick report; 2 means
00868 //           that we take a new reading on every other report, and repeat
00869 //           the prior readings on alternate reports; etc
00870 //
00871 // 5  -> Plunger sensor type.
00872 //
00873 //        byte 3 -> plunger type:
00874 //           0 = none (disabled)
00875 //           1 = TSL1410R linear image sensor, 1280x1 pixels, serial mode, edge detection
00876 //           3 = TSL1412R linear image sensor, 1536x1 pixels, serial mode, edge detection
00877 //           5 = Potentiometer with linear taper, or any other device that
00878 //               represents the position reading with a single analog voltage
00879 //           6 = AEDR8300 optical quadrature sensor, 75lpi
00880 //          *7 = AS5304 magnetic quadrature sensor, 160 steps per 2mm
00881 //           8 = TSL1401CL linear image sensor, 128x1 pixel, bar code detection
00882 //           9 = VL6180X time-of-flight distance sensor
00883 //        **10 = AEAT-6012-A06 magnetic rotary encoder
00884 //        **11 = TCD1103GFG Toshiba linear CCD, 1500x1 pixels, edge detection
00885 //        **12 = VCNL4010 Vishay IR proximity sensor
00886 //
00887 //        byte 4 -> extra sensor-speicifc parameter data
00888 //          VCNL4010 - IRED current, in units of 10mA, valid range 1..20
00889 //
00890 //       * The sensor types marked with asterisks (*) are reserved for types
00891 //       that aren't currently implemented but could be added in the future.  
00892 //       Selecting these types will effectively disable the plunger.
00893 //
00894 //       ** The sensor types marked with double asterisks (**) are
00895 //       Experimental, meaning that the code isn't finished yet and isn't
00896 //       meant for use in a live pin cab.
00897 //
00898 //       Sensor types 2 and 4 were formerly reserved for TSL14xx sensors in
00899 //       parallel wiring mode, but support for these is no longer planned, as
00900 //       the KL25Z's single ADC sampler negates any speed advantage from using
00901 //       the sensors' parallel mode.  Those slots could be reassigned for 
00902 //       other sensors, since they were never enabled in any release version.
00903 //
00904 // 6  -> Plunger pin assignments.
00905 //
00906 //         byte 3 -> pin assignment 1
00907 //         byte 4 -> pin assignment 2
00908 //         byte 5 -> pin assignment 3/misc
00909 //         byte 6 -> pin assignment 4/misc
00910 //
00911 //       All of the pins use the standard GPIO port format (see "GPIO pin number
00912 //       mappings" below).  The actual use of the four pins depends on the plunger
00913 //       type, as shown below.  "NC" means that the pin isn't used at all for the
00914 //       corresponding plunger type.  "GPIO" means that any GPIO pin will work.
00915 //       AnalogIn, InterruptIn, and PWM mean that only pins with the respective 
00916 //       capabilities can be chosen.
00917 //
00918 //         Plunger Type              Pin 1            Pin 2             Pin 3/Misc      Pin 4
00919 //
00920 //         TSL1410R/1412R/1401CL     SI (GPIO)        CLK (GPIO)        AO (AnalogIn)   NC
00921 //         Potentiometer             AO (AnalogIn)    NC                NC              NC
00922 //         AEDR8300                  A (InterruptIn)  B (InterruptIn)   NC              NC
00923 //         AS5304                    A (InterruptIn)  B (InterruptIn)   NC              NC
00924 //         VL6180X                   SDA (GPIO)       SCL (GPIO)        GPIO0/CE (GPIO) NC
00925 //         AEAT-6012-A06             CS (GPIO)        CLK (GPIO)        DO (GPIO)       NC
00926 //         TCD1103GFG                fM (PWM)         OS (AnalogIn)     ICG (GPIO)      SH (GPIO)
00927 //         VCNL4010                  SDA (GPIO)       SCL (GPIO)        NC              NC
00928 //
00929 // 7  -> Plunger calibration button pin assignments.
00930 //
00931 //         byte 3 -> features enabled/disabled: bit mask consisting of:
00932 //                   0x01  button input is enabled
00933 //                   0x02  lamp output is enabled
00934 //         byte 4 -> DigitalIn pin for the button switch
00935 //         byte 5 -> DigitalOut pin for the indicator lamp
00936 //
00937 //       Note that setting a pin to NC (Not Connected) will disable it even if the
00938 //       corresponding feature enable bit (in byte 3) is set.
00939 //
00940 // 8  -> ZB Launch Ball setup.  This configures the ZB Launch Ball feature.
00941 //
00942 //         byte 3    -> LedWiz port number (1-255) mapped to "ZB Launch Ball" in DOF
00943 //         byte 4    -> key type
00944 //         byte 5    -> key code
00945 //         bytes 6:7 -> "push" distance, in 1/1000 inch increments (16 bit little endian)
00946 //
00947 //       Set the port number to 0 to disable the feature.  The key type and key code
00948 //       fields use the same conventions as for a button mapping (see below).  The
00949 //       recommended push distance is 63, which represents .063" ~ 1/16".
00950 //
00951 // 9  -> TV ON relay setup.  This requires external circuitry implemented on the
00952 //       Expansion Board (or an equivalent circuit as described in the Build Guide).
00953 //
00954 //         byte 3    -> "power status" input pin (DigitalIn)
00955 //         byte 4    -> "latch" output (DigitalOut)
00956 //         byte 5    -> relay trigger output (DigitalOut)
00957 //         bytes 6:7 -> delay time in 10ms increments (16 bit little endian);
00958 //                      e.g., 550 (0x26 0x02) represents 5.5 seconds
00959 //
00960 //       Set the delay time to 0 to disable the feature.  The pin assignments will
00961 //       be ignored if the feature is disabled.
00962 //
00963 //       If an IR remote control transmitter is installed (see variable 17), we'll
00964 //       also transmit any IR codes designated as TV ON codes when the startup timer
00965 //       finishes.  This allows TVs to be turned on via IR remotes codes rather than
00966 //       hard-wiring them through the relay.  The relay can be omitted in this case.
00967 //
00968 // 10 -> TLC5940NT setup.  This chip is an external PWM controller, with 16 outputs
00969 //       per chip and a serial data interface that allows the chips to be daisy-
00970 //       chained.  We can use these chips to add an arbitrary number of PWM output 
00971 //       ports for the LedWiz emulation.
00972 //
00973 //          byte 3 = number of chips attached (connected in daisy chain)
00974 //          byte 4 = SIN pin - Serial data (must connect to SPIO MOSI -> PTC6 or PTD2)
00975 //          byte 5 = SCLK pin - Serial clock (must connect to SPIO SCLK -> PTC5 or PTD1)
00976 //          byte 6 = XLAT pin - XLAT (latch) signal (any GPIO pin)
00977 //          byte 7 = BLANK pin - BLANK signal (any GPIO pin)
00978 //          byte 8 = GSCLK pin - Grayscale clock signal (must be a PWM-out capable pin)
00979 //
00980 //       Set the number of chips to 0 to disable the feature.  The pin assignments are 
00981 //       ignored if the feature is disabled.
00982 //
00983 // 11 -> 74HC595 setup.  This chip is an external shift register, with 8 outputs per
00984 //       chip and a serial data interface that allows daisy-chaining.  We use this
00985 //       chips to add extra digital outputs for the LedWiz emulation.  In particular,
00986 //       the Chime Board (part of the Expansion Board suite) uses these to add timer-
00987 //       protected outputs for coil devices (knockers, chimes, bells, etc).
00988 //
00989 //          byte 3 = number of chips attached (connected in daisy chain)
00990 //          byte 4 = SIN pin - Serial data (any GPIO pin)
00991 //          byte 5 = SCLK pin - Serial clock (any GPIO pin)
00992 //          byte 6 = LATCH pin - LATCH signal (any GPIO pin)
00993 //          byte 7 = ENA pin - ENABLE signal (any GPIO pin)
00994 //
00995 //       Set the number of chips to 0 to disable the feature.  The pin assignments are
00996 //       ignored if the feature is disabled.
00997 //
00998 // 12 -> Disconnect reboot timeout.  The reboot timeout allows the controller software
00999 //       to automatically reboot the KL25Z after it detects that the USB connection is
01000 //       broken.  On some hosts, the device isn't able to reconnect after the initial
01001 //       connection is lost.  The reboot timeout is a workaround for these cases.  When
01002 //       the software detects that the connection is no longer active, it will reboot
01003 //       the KL25Z automatically if a new connection isn't established within the
01004 //       timeout period.  Set the timeout to 0 to disable the feature (i.e., the device
01005 //       will never automatically reboot itself on a broken connection).
01006 //
01007 //          byte 3 -> reboot timeout in seconds; 0 = disabled
01008 //
01009 // 13 -> Plunger calibration.  In most cases, the calibration is set internally by the
01010 //       device by running the calibration procedure.  However, it's sometimes useful
01011 //       for the host to be able to get and set the calibration, such as to back up
01012 //       the device settings on the PC, or to save and restore the current settings
01013 //       when installing a software update.
01014 //
01015 //         bytes 3:4 = rest position (unsigned 16-bit little-endian)
01016 //         bytes 5:6 = maximum retraction point (unsigned 16-bit little-endian)
01017 //         byte  7   = measured plunger release travel time in milliseconds
01018 //
01019 // 14 -> Expansion board configuration.  This doesn't affect the controller behavior
01020 //       directly; the individual options related to the expansion boards (such as 
01021 //       the TLC5940 and 74HC595 setup) still need to be set separately.  This is
01022 //       stored so that the PC config UI can store and recover the information to
01023 //       present in the UI.  For the "classic" KL25Z-only configuration, simply set 
01024 //       all of the fields to zero.
01025 //
01026 //         byte 3 = board set type.  At the moment, the Pinscape expansion boards
01027 //                  are the only ones supported in the software.  This allows for
01028 //                  adding new designs or independent designs in the future.
01029 //                    0 = Standalone KL25Z (no expansion boards)
01030 //                    1 = Pinscape Expansion Boards
01031 //                    2 = Oak Micros Pinscape All-In-One (AIO) Board
01032 //                    3 = Oak Micros Pinscape Lite Board
01033 //                    4 = Arnoz RigMaster board
01034 //                    5 = Arnoz KLShield Board
01035 //
01036 //         byte 4 = board set interface revision.  This *isn't* the version number
01037 //                  of the board itself, but rather of its software interface.  In
01038 //                  other words, this doesn't change every time the EAGLE layout
01039 //                  for the board changes.  It only changes when a revision is made
01040 //                  that affects the software, such as a GPIO pin assignment.
01041 //
01042 //                  For Pinscape Expansion Boards (board set type 1):
01043 //                    0 = first release (Feb 2016)
01044 //
01045 //                  For Oak Micros AIO (type 2):
01046 //                    0 = first release (2019)
01047 //
01048 //                  For Oak Micros Lite (type 3):
01049 //                    0 = first release
01050 //
01051 //                  For Arnoz RigMaster (type 4):
01052 //                    0 = first release (2021)
01053 //
01054 //                  For Arnoz KLShield (type 5):
01055 //                    0 = first release (2021)
01056 //
01057 //         bytes 5:8 = additional hardware-specific data.  These slots are used
01058 //                  to store extra data specific to the expansion boards selected.
01059 //
01060 //                  For Pinscape Expansion Boards (board set type 1), and
01061 //                  Oak Micros AIO (type = 2):
01062 //                    byte 5 = number of main interface or AIO boards (always 1)
01063 //                    byte 6 = number of MOSFET power boards
01064 //                    byte 7 = number of chime boards
01065 //                    byte 8 = not used
01066 //
01067 //                  For Arnoz RigMaster (board set type 4) and KLShield (type 5):
01068 //                    byte 5 = number of main baords (always 1)
01069 //                    byte 6 = number of Mollusk PWM add-on boards
01070 //
01071 //
01072 // 15 -> Night mode setup.  
01073 //
01074 //       byte 3 = button number - 1..MAX_BUTTONS, or 0 for none.  This selects
01075 //                a physically wired button that can be used to control night mode.
01076 //                The button can also be used as normal for PC input if desired.
01077 //                Note that night mode can still be activated via a USB command
01078 //                even if no button is assigned.
01079 //
01080 //       byte 4 = flags:
01081 //
01082 //                0x01 -> The wired input is an on/off switch: night mode will be
01083 //                        active when the input is switched on.  If this bit isn't
01084 //                        set, the input is a momentary button: pushing the button
01085 //                        toggles night mode.
01086 //
01087 //                0x02 -> Night Mode is assigned to the SHIFTED button (see Shift
01088 //                        Button setup at variable 16).  This can only be used
01089 //                        in momentary mode; it's ignored if flag bit 0x01 is set.
01090 //                        When the shift flag is set, the button only toggles
01091 //                        night mode when you press it while also holding down
01092 //                        the Shift button.                        
01093 //
01094 //       byte 5 = indicator output number - 1..MAX_OUT_PORTS, or 0 for none.  This
01095 //                selects an output port that will be turned on when night mode is
01096 //                activated.  Night mode activation overrides any setting made by
01097 //                the host.
01098 //
01099 // 16 -> Shift Button setup.  One button can be designated as a "Local Shift
01100 //       Button" that can be pressed to select a secondary meaning for other
01101 //       buttons.  This isn't the same as the PC keyboard Shift keys; those can
01102 //       be programmed using the USB key codes for Left Shift and Right Shift.
01103 //       Rather, this applies a LOCAL shift feature in the cabinet button that
01104 //       lets you select a secondary meaning.  For example, you could assign
01105 //       the Start button to the "1" key (VP "Start Game") normally, but have
01106 //       its meaning change to the "5" key ("Insert Coin") when the shift
01107 //       button is pressed.  This provides access to more control functions
01108 //       without adding more physical buttons.
01109 //
01110 //       byte 3 = button number - 1..MAX_BUTTONS, or 0 for none
01111 //       byte 4 = mode (default is 0):
01112 //
01113 //          0 -> Shift OR Key mode.  In this mode, the Shift button doesn't
01114 //               send its assigned key or IR command when initially pressed.
01115 //               Instead, we wait to see if another button is pressed while
01116 //               the Shift button is held down.  If so, this Shift button 
01117 //               press ONLY counts as the Shift function, and its own assigned
01118 //               key is NOT sent to the PC.  On the other hand, if you press
01119 //               the Shift button and then release it without having pressed
01120 //               any other key in the meantime, this press counts as a regular
01121 //               key press, so we send the assigned key to the PC.
01122 //
01123 //          1 -> Shift AND Key mode.  In this mode, the Shift button sends its
01124 //               assigned key when pressed, just like a normal button.  If you
01125 //               press another button while the Shift key is pressed, the
01126 //               shifted meaning of the other key is used.
01127 //
01128 // 17 -> IR Remote Control physical device setup.  We support IR remotes for
01129 //       both sending and receiving.  On the receive side, we can read from a 
01130 //       sensor such as a TSOP384xx.  The sensor requires one GPIO pin with 
01131 //       interrupt support, so any PTAxx or PTDxx pin will work.  On the send 
01132 //       side, we can transmit through any IR LED.  This requires one PWM 
01133 //       output pin.  To enable send and/or receive, specify a valid pin; to
01134 //       disable, set the pin NC (not connected).  Send and receive can be
01135 //       enabled and disabled independently; it's not necessary to enable
01136 //       the transmit function to use the receive function, or vice versa.
01137 //
01138 //       byte 3 = receiver input GPIO pin ID.  Must be interrupt-capable.
01139 //       byte 4 = transmitter pin.  Must be PWM-capable.
01140 //
01141 // 18 -> Plunger auto-zeroing.  This only applies to sensor types with
01142 //       relative positioning, such as quadrature sensors.  Other sensor
01143 //       types simply ignore this.
01144 //
01145 //       byte 3 = bit flags:
01146 //                0x01 -> auto-zeroing enabled
01147 //       byte 4 = auto-zeroing time in seconds
01148 //
01149 // 19 -> Plunger filters.  There are two filters that can be applied:
01150 //
01151 //       - Jitter filter.  This sets a hysteresis window size, to reduce jitter
01152 //       jitter in the plunger reading.  Most sensors aren't perfectly accurate;
01153 //       consecutive readings at the same physical plunger position vary 
01154 //       slightly, wandering in a range near the true reading.  Over time, the 
01155 //       readings will usually average the true value, but that's not much of a 
01156 //       consolation to us because we want to display the position in real time.
01157 //       To reduce the visible jitter, we can apply a hysteresis filter that 
01158 //       hides random variations within the specified window.  The window is in 
01159 //       the sensor's native units, so the effect of a given window size 
01160 //       depends on the sensor type.  A value of zero disables the filter.
01161 //
01162 //       - Reversed orientation.  If set, this inverts the sensor readings, as
01163 //       though the sensor were physically flipped to the opposite direction.
01164 //       This allows for correcting a reversed physical sensor installation in
01165 //       software without having to mess with the hardware.
01166 //
01167 //       byte 3:4 = jitter window size in native sensor units, little-endian
01168 //       byte 5   = orientation filter bit mask:
01169 //                  0x01  -> set if reversed orientation, clear if normal
01170 //                  0x80  -> Read-only: this bit is set if the feature is supported
01171 //
01172 // 20 -> Plunger bar code setup.  Sets parameters applicable only to bar code
01173 //       sensor types.
01174 //
01175 //       bytes 3:4 = Starting pixel offset of bar code (margin width)
01176 //
01177 // 21 -> TLC59116 setup.  This chip is an external PWM controller with 16
01178 //       outputs per chip and an I2C bus interface.  Up to 14 of the chips
01179 //       can be connected to a single bus.  This chip is a successor to the 
01180 //       TLC5940 with a more modern design and some nice improvements, such 
01181 //       as glitch-free startup and a standard (I2C) physical interface.
01182 //
01183 //       Each chip has a 7-bit I2C address.  The top three bits of the
01184 //       address are fixed in the chip itself and can't be configured, but
01185 //       the low four bits are configurable via the address line pins on
01186 //       the chip, A3 A2 A1 A0.  Our convention here is to ignore the fixed
01187 //       three bits and refer to the chip address as just the A3 A2 A1 A0
01188 //       bits.  This gives each chip an address from 0 to 15.
01189 //
01190 //       I2C allows us to discover the attached chips automatically, so in
01191 //       principle we don't need to know which chips will be present.  
01192 //       However, it's useful for the config tool to know which chips are
01193 //       expected so that it can offer them in the output port setup UI.
01194 //       We therefore provide a bit mask specifying the enabled chips.  Each
01195 //       bit specifies whether the chip at the corresponding address is
01196 //       present: 0x0001 is the chip at address 0, 0x0002 is the chip at
01197 //       address 1, etc.  This is mostly for the config tool's use; we only
01198 //       use it to determine if TLC59116 support should be enabled at all,
01199 //       by checking if it's non-zero.
01200 //
01201 //       To disable support, set the populated chip mask to 0.  The pin
01202 //       assignments are all ignored in this case.
01203 //
01204 //          bytes 3:4 = populated chips, as a bit mask (OR in 1<<address
01205 //                   each populated address)
01206 //          byte 5 = SDA (any GPIO pin)
01207 //          byte 6 = SCL (any GPIO pin)
01208 //          byte 7 = RESET (any GPIO pin)
01209 //
01210 // 22 -> Plunger raw calibration data.  Some sensor types need to store
01211 //       additional raw calibration.  We provide three uint16 slots for
01212 //       use by the sensor, with the meaning defined by the sensor subclass.
01213 //
01214 //          bytes 3:4 = raw data 0
01215 //          bytes 5:6 = raw data 1
01216 //          bytes 7:8 = raw data 2
01217 //
01218 //
01219 // SPECIAL DIAGNOSTICS VARIABLES:  These work like the array variables below,
01220 // the only difference being that we don't report these in the number of array
01221 // variables reported in the "variable 0" query.
01222 //
01223 // 220 -> Performance/diagnostics variables.  Items marked "read only" can't
01224 //        be written; any SET VARIABLE messages on these are ignored.  Items
01225 //        marked "diagnostic only" refer to counters or statistics that are
01226 //        collected only when the diagnostics are enabled via the diags.h
01227 //        macro ENABLE_DIAGNOSTICS.  These will simply return zero otherwise.
01228 //
01229 //          byte 3 = diagnostic index (see below)
01230 //
01231 //        Diagnostic index values:
01232 //
01233 //          1 -> Main loop cycle time [read only, diagnostic only]
01234 //               Retrieves the average time of one iteration of the main
01235 //               loop, in microseconds, as a uint32.  This excludes the
01236 //               time spent processing incoming messages, as well as any
01237 //               time spent waiting for a dropped USB connection to be
01238 //               restored.  This includes all subroutine time and polled
01239 //               task time, such as processing button and plunger input,
01240 //               sending USB joystick reports, etc.
01241 //
01242 //          2 -> Main loop message read time [read only, diagnostic only]
01243 //               Retrieves the average time spent processing incoming USB
01244 //               messages per iteration of the main loop, in microseconds, 
01245 //               as a uint32.  This only counts the processing time when 
01246 //               messages are actually present, so the average isn't reduced
01247 //               by iterations of the main loop where no messages are found.
01248 //               That is, if we run a million iterations of the main loop,
01249 //               and only five of them have messages at all, the average time
01250 //               includes only those five cycles with messages to process.
01251 //
01252 //          3 -> PWM update polling time [read only, diagnostic only]
01253 //               Retrieves the average time, as a uint32 in microseconds,
01254 //               spent in the PWM update polling routine.
01255 //
01256 //          4 -> LedWiz update polling time [read only, diagnostic only]
01257 //               Retrieves the average time, as a uint32 in microseconds,
01258 //               units, spent in the LedWiz flash cycle update routine.
01259 //
01260 //
01261 // ARRAY VARIABLES:  Each variable below is an array.  For each get/set message,
01262 // byte 3 gives the array index.  These are grouped at the top end of the variable 
01263 // ID range to distinguish this special feature.  On QUERY, set the index byte to 0 
01264 // to query the number of slots; the reply will be a report for the array index
01265 // variable with index 0, with the first (and only) byte after that indicating
01266 // the maximum array index.
01267 //
01268 // 250 -> IR remote control commands - code part 2.  This stores the high-order
01269 //        32 bits of the remote control for each slot.  These are combined with
01270 //        the low-order 32 bits from variable 251 below to form a 64-bit code.
01271 //        
01272 //          byte 3 = Command slot number (1..MAX_IR_CODES)
01273 //          byte 4 = bits 32..39 of remote control command code
01274 //          byte 5 = bits 40..47
01275 //          byte 6 = bits 48..55
01276 //          byte 7 = bits 56..63
01277 //
01278 // 251 -> IR remote control commands - code part 1.  This stores the protocol
01279 //        identifier and low-order 32 bits of the remote control code for each
01280 //        remote control command slot.  The code represents a key press on a
01281 //        remote, and is usually determined by reading it from the device's
01282 //        actual remote via the IR sensor input feature.  These codes combine
01283 //        with variable 250 above to form a 64-bit code for each slot.
01284 //        See IRRemote/IRProtocolID.h for the protocol ID codes.
01285 //
01286 //          byte 3 = Command slot number (1..MAX_IR_CODES)
01287 //          byte 4 = protocol ID
01288 //          byte 5 = bits 0..7 of remote control command code
01289 //          byte 6 = bits 8..15
01290 //          byte 7 = bits 16..23
01291 //          byte 8 = bits 24..31
01292 //
01293 // 252 -> IR remote control commands - control information.  This stores
01294 //        descriptive information for each remote control command slot.
01295 //        The IR code for each slot is stored in the corresponding array
01296 //        entry in variables 251 & 250 above; the information is split over
01297 //        several variables like this because of the 8-byte command message 
01298 //        size in our USB protocol (which we use for LedWiz compatibility).
01299 //
01300 //          byte 3 = Command slot number (1..MAX_IR_CODES)
01301 //          byte 4 = bit flags:
01302 //                     0x01 -> send this code as a TV ON signal at system start
01303 //                     0x02 -> use "ditto" codes when sending the command
01304 //          byte 5 = key type; same as the key type in an input button variable
01305 //          byte 6 = key code; same as the key code in an input button variable
01306 //
01307 //        Each IR command slot can serve three purposes:
01308 //
01309 //        - First, it can be used as part of the TV ON sequence when the 
01310 //          system powers up, to turn on cabinet TVs that don't power up by 
01311 //          themselves.  To use this feature, set the TV ON bit in the flags.  
01312 //
01313 //        - Second, when the IR sensor receives a command in a given slot, we 
01314 //          can translate it into a keyboard key or joystick button press sent
01315 //          to the PC.  This lets you use any IR remote to send commands to the
01316 //          PC, allowing access to additional control inputs without any extra
01317 //          buttons on the cabinet.  To use this feature, assign the key to
01318 //          send in the key type and key code bytes.
01319 //
01320 //        - Third, we can send a given IR command when a physical cabinet
01321 //          button is pressed.  This lets you use cabinet buttons to send IR 
01322 //          commands to other devices in your system.  For example, you could 
01323 //          assign cabinet buttons to control the volume on a cab TV.  To use
01324 //          this feature, assign an IR slot as a button function in the button
01325 //          setup.
01326 //
01327 // 253 -> Extended input button setup.  This adds on to the information set by 
01328 //        variable 254 below, accessing additional fields.  The "shifted" key
01329 //        type and code fields assign a secondary meaning to the button that's
01330 //        used when the local Shift button is being held down.  See variable 16 
01331 //        above for more details on the Shift button.
01332 //
01333 //          byte 3 = Button number (1..MAX_BUTTONS)
01334 //          byte 4 = shifted key type (same codes as "key type" in var 254)
01335 //          byte 5 = shifted key code (same codes as "key code" in var 254)
01336 //          byte 6 = shifted IR command (see "IR command" in var 254)
01337 //
01338 // 254 -> Input button setup.  This sets up one button; it can be repeated for each
01339 //        button to be configured.  There are MAX_EXT_BUTTONS button slots (see
01340 //        config.h for the constant definition), numbered 1..MAX_EXT_BUTTONS.  Each
01341 //        slot can be configured as a joystick button, a regular keyboard key, or a
01342 //        media control key (mute, volume up, volume down).
01343 //
01344 //        The bytes of the message are:
01345 //          byte 3 = Button number (1..MAX_BUTTONS)
01346 //          byte 4 = GPIO pin for the button input; mapped as a DigitalIn port
01347 //          byte 5 = key type reported to PC when button is pushed:
01348 //                    0 = none (no PC input reported when button pushed)
01349 //                    1 = joystick button -> byte 6 is the button number, 1-32
01350 //                    2 = regular keyboard key -> byte 6 is the USB key code (see below)
01351 //                    3 = media key -> byte 6 is the USB media control code (see below)
01352 //          byte 6 = key code, which depends on the key type in byte 5
01353 //          byte 7 = flags - a combination of these bit values:
01354 //                    0x01 = pulse mode.  This reports a physical on/off switch's state
01355 //                           to the host as a brief key press whenever the switch changes
01356 //                           state.  This is useful for the VPinMAME Coin Door button,
01357 //                           which requires the End key to be pressed each time the
01358 //                           door changes state.
01359 //          byte 8 = IR command to transmit when unshifted button is pressed.  This
01360 //                   contains an IR slot number (1..MAX_IR_CODES), or 0 if no code
01361 //                   is associated with the button.
01362 //
01363 // 255 -> LedWiz output port setup.  This sets up one output port; it can be repeated
01364 //        for each port to be configured.  There are 128 possible slots for output ports, 
01365 //        numbered 1 to 128.  The number of ports atcually active is determined by
01366 //        the first DISABLED port (type 0).  For example, if ports 1-32 are set as GPIO
01367 //        outputs and port 33 is disabled, we'll report to the host that we have 32 ports,
01368 //        regardless of the settings for post 34 and higher.
01369 //
01370 //        The bytes of the message are:
01371 //
01372 //          byte 3 = LedWiz port number (1 to MAX_OUT_PORTS)
01373 //
01374 //          byte 4 = physical output type:
01375 //
01376 //                    0 = Disabled.  This output isn't used, and isn't visible to the
01377 //                        LedWiz/DOF software on the host.  The FIRST disabled port
01378 //                        determines the number of ports visible to the host - ALL ports
01379 //                        after the first disabled port are also implicitly disabled.
01380 //
01381 //                    1 = GPIO PWM output: connected to GPIO pin specified in byte 5,
01382 //                        operating in PWM mode.  Note that only a subset of KL25Z GPIO
01383 //                        ports are PWM-capable.
01384 //
01385 //                    2 = GPIO Digital output: connected to GPIO pin specified in byte 5,
01386 //                        operating in digital mode.  Digital ports can only be set ON
01387 //                        or OFF, with no brightness/intensity control.  All pins can be
01388 //                        used in this mode.
01389 //
01390 //                    3 = TLC5940 port: connected to TLC5940 output port number specified 
01391 //                        in byte 5.  Ports are numbered sequentially starting from port 0
01392 //                        for the first output (OUT0) on the first chip in the daisy chain.
01393 //
01394 //                    4 = 74HC595 port: connected to 74HC595 output port specified in byte 5.
01395 //                        As with the TLC5940 outputs, ports are numbered sequentially from 0
01396 //                        for the first output on the first chip in the daisy chain.
01397 //
01398 //                    5 = Virtual output: this output port exists for the purposes of the
01399 //                        LedWiz/DOF software on the host, but isn't physically connected
01400 //                        to any output device.  This can be used to create a virtual output
01401 //                        for the DOF ZB Launch Ball signal, for example, or simply as a
01402 //                        placeholder in the LedWiz port numbering.  The physical output ID 
01403 //                        (byte 5) is ignored for this port type.
01404 //
01405 //                    6 = TLC59116 output: connected to the TLC59116 output port specified
01406 //                        in byte 5.  The high four bits of this value give the chip's
01407 //                        I2C address, specifically the A3 A2 A1 A0 bits configured in
01408 //                        the hardware.  (A chip's I2C address is actually 7 bits, but
01409 //                        the three high-order bits are fixed, so we don't bother including
01410 //                        those in the byte 5 value).  The low four bits of this value
01411 //                        give the output port number on the chip.  For example, 0x37
01412 //                        specifies chip 3 (the one with A3 A2 A1 A0 wired as 0 0 1 1),
01413 //                        output #7 on that chip.  Note that outputs are numbered from 0
01414 //                        to 15 (0xF) on each chip.
01415 //
01416 //          byte 5 = physical output port, interpreted according to the value in byte 4
01417 //
01418 //          byte 6 = flags: a combination of these bit values:
01419 //                    0x01 = active-high output (0V on output turns attached device ON)
01420 //                    0x02 = noisemaker device: disable this output when "night mode" is engaged
01421 //                    0x04 = apply gamma correction to this output (PWM outputs only)
01422 //                    0x08 = "Flipper Logic" enabled for this output
01423 //                    0x10 = "Chime Logic" enabled for this port
01424 //
01425 //          byte 7 = Flipper Logic OR Chime Logic parameters.  If flags bit 0x08 is set,
01426 //                   this is the Flipper Logic settings.  If flags bit 0x10 is is set, 
01427 //                   it's the Chime Logic settings.  The two are mutually exclusive.
01428 //
01429 //                   For flipper logic: (full power time << 4) | (hold power level)
01430 //                   For chime logic:   (max on time << 4)     | (min on time)
01431 //
01432 //                   Flipper logic uses PWM to reduce the power level on the port after an
01433 //                   initial timed interval at full power.  This is designed for pinball
01434 //                   coils, which are designed to be energized only in short bursts.  In
01435 //                   a pinball machine, most coils are used this way naturally: bumpers,
01436 //                   slingshots, kickers, knockers, chimes, etc. are only fired in brief
01437 //                   bursts.  Some coils are left on for long periods, though, particularly
01438 //                   the flippers.  The Flipper Logic feature is designed to handle this
01439 //                   in a way similar to how real pinball machines solve the same problem.
01440 //                   When Flipper Logic is enabled, the software gives the output full
01441 //                   power when initially turned on, but reduces the power to a lower
01442 //                   level (via PWM) after a short time elapses.  The point is to reduce
01443 //                   the power to a level low enough that the coil can safely dissipate
01444 //                   the generated heat indefinitely, but still high enough to keep the 
01445 //                   solenoid mechanically actuated.  This is possible because solenoids 
01446 //                   generally need much less power to "hold" than to actuate initially.
01447 //
01448 //                   The high-order 4 bits of this byte give the initial full power time,
01449 //                   using the following mapping for 0..15:  1ms, 2ms, 5ms, 10ms, 20ms, 40ms
01450 //                   80ms, 100ms, 150ms, 200ms, 300ms, 400ms, 500ms, 600ms, 700ms, 800ms.
01451 //                   
01452 //                   Note that earlier versions prior to 3/2019 used a scale of (X+1)*50ms. 
01453 //                   We changed to this pseudo-logarithmic scale for finer gradations at the
01454 //                   low end of the time scale, for coils that need fast on/off cycling.
01455 //
01456 //                   The low-order 4 bits of the byte give the percentage power, in 6.66%
01457 //                   increments: 0 = 0% (off), 1 = 6.66%, ..., 15 = 100%.
01458 //
01459 //                   A hold power of 0 provides a software equivalent of the timer-protected
01460 //                   output logic of the Pinscape expansion boards used in the main board's
01461 //                   replay knocker output and all of the chime board outputs.  This is
01462 //                   suitable for devices that shouldn't ever fire for long periods to
01463 //                   start with.  
01464 //
01465 //                   Non-zero hold powers are suitable for devices that do need to stay on 
01466 //                   for long periods, such as flippers.  The "right" level will vary by
01467 //                   device; you should experiment to find the lowest setting where the
01468 //                   device stays mechanically actuated.  Once you find the level, you
01469 //                   should confirm that the device won't overheat at that level by turning
01470 //                   it on at the selected level and carefully monitoring it for heating.
01471 //                   If the coil stays cool for a minute or two, it should be safe to assume
01472 //                   that it's in thermal equilibrium, meaning it should be able to sustain
01473 //                   the power level indefinitely.
01474 //
01475 //                   Note that this feature can be used with any port, but it's only fully
01476 //                   functional with a PWM port.  A digital output port can only be set to
01477 //                   0% or 100%, so the only meaningful reduced hold power is 0%.  This
01478 //                   makes the feature a simple time limiter - basically a software version
01479 //                   of the Chime Board from the expansion board set.
01480 //
01481 //                   Chime Logic encodes a minimum and maximum ON time for the port.  It
01482 //                   doesn't use PWM; it simply forces the port on or off in specified
01483 //                   durations.  The low 4 bits encode the minimum ON time, as an index
01484 //                   into the table below.  The high 4 bits encode the maximum ON time,
01485 //                   with the special case that 0 means "infinite".
01486 //
01487 //                   Chime logic time table: 0ms, 1ms, 2ms, 5ms, 10ms, 20ms, 40ms, 80ms,
01488 //                   100ms, 200ms, 300ms, 400ms, 500ms, 600ms, 700ms, 800ms.
01489 //
01490 //
01491 //        Note that the KL25Z's on-board LEDs can be used as LedWiz output ports, simply
01492 //        by assigning the LED GPIO pins as output ports.  This is useful for testing a new 
01493 //        installation without having to connect any external devices.  Assigning the 
01494 //        on-board LEDs as output ports automatically overrides their normal status and
01495 //        diagnostic display use, so be aware that the normal status flash pattern won't
01496 //        appear when they're used this way.
01497 //
01498 
01499 
01500 // --- GPIO PIN NUMBER MAPPINGS ---
01501 //
01502 // In USB messages that specify GPIO pin assignments, pins are identified by
01503 // 8-bit integers.  The special value 0xFF means NC (not connected).  All actual
01504 // pins are mapped with the port number in the top 3 bits and the pin number in
01505 // the bottom 5 bits.  Port A=0, B=1, ..., E=4.  For example, PTC7 is port C (2)
01506 // pin 7, so it's represented as (2 << 5) | 7.
01507 
01508 
01509 // --- USB KEYBOARD SCAN CODES ---
01510 //
01511 // For regular keyboard keys, we use the standard USB HID scan codes
01512 // for the US keyboard layout.  The scan codes are defined by the USB
01513 // HID specifications; you can find a full list in the official USB
01514 // specs.  Some common codes are listed below as a quick reference.
01515 //
01516 //    Key name         -> USB scan code (hex)
01517 //    A-Z              -> 04-1D
01518 //    top row 1!->0)   -> 1E-27
01519 //    Return           -> 28
01520 //    Escape           -> 29
01521 //    Backspace        -> 2A
01522 //    Tab              -> 2B
01523 //    Spacebar         -> 2C
01524 //    -_               -> 2D
01525 //    =+               -> 2E
01526 //    [{               -> 2F
01527 //    ]}               -> 30
01528 //    \|               -> 31
01529 //    ;:               -> 33
01530 //    '"               -> 34
01531 //    `~               -> 35
01532 //    ,<               -> 36
01533 //    .>               -> 37
01534 //    /?               -> 38
01535 //    Caps Lock        -> 39
01536 //    F1-F12           -> 3A-45
01537 //    F13-F24          -> 68-73
01538 //    Print Screen     -> 46
01539 //    Scroll Lock      -> 47
01540 //    Pause            -> 48
01541 //    Insert           -> 49
01542 //    Home             -> 4A
01543 //    Page Up          -> 4B
01544 //    Del              -> 4C
01545 //    End              -> 4D
01546 //    Page Down        -> 4E
01547 //    Right Arrow      -> 4F
01548 //    Left Arrow       -> 50
01549 //    Down Arrow       -> 51
01550 //    Up Arrow         -> 52
01551 //    Num Lock/Clear   -> 53
01552 //    Keypad / * - +   -> 54 55 56 57
01553 //    Keypad Enter     -> 58
01554 //    Keypad 1-9       -> 59-61
01555 //    Keypad 0         -> 62
01556 //    Keypad .         -> 63
01557 //    Mute             -> 7F
01558 //    Volume Up        -> 80
01559 //    Volume Down      -> 81
01560 //    Left Control     -> E0
01561 //    Left Shift       -> E1
01562 //    Left Alt         -> E2
01563 //    Left GUI         -> E3
01564 //    Right Control    -> E4
01565 //    Right Shift      -> E5
01566 //    Right Alt        -> E6
01567 //    Right GUI        -> E7
01568 //
01569 // Due to limitations in Windows, there's a limit of 6 regular keys
01570 // pressed at the same time.  The shift keys in the E0-E7 range don't
01571 // count against this limit, though, since they're encoded as modifier
01572 // keys; all of these can be pressed at the same time in addition to 6
01573 // regular keys.
01574 
01575 // --- USB MEDIA CONTROL SCAN CODES ---
01576 //
01577 // Buttons mapped to type 3 are Media Control buttons.  These select
01578 // a small set of common media control functions.  We recognize the
01579 // following type codes only:
01580 //
01581 //   Mute              -> E2
01582 //   Volume up         -> E9
01583 //   Volume Down       -> EA
01584 //   Next Track        -> B5
01585 //   Previous Track    -> B6
01586 //   Stop              -> B7
01587 //   Play/Pause        -> CD