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