Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
USBProtocol.h@116:7a67265d7c19, 2021-10-01 (annotated)
- Committer:
- arnoz
- Date:
- Fri Oct 01 08:19:46 2021 +0000
- Revision:
- 116:7a67265d7c19
- Parent:
- 115:39d2eb4b1830
- Correct information regarding your last merge
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 35:e959ffba78fd | 1 | // USB Message Protocol |
mjr | 35:e959ffba78fd | 2 | // |
mjr | 74:822a92bc11d2 | 3 | // This file is purely for documentation, to describe our USB protocol |
mjr | 74:822a92bc11d2 | 4 | // for incoming messages (host to device). We use the standard HID setup |
mjr | 74:822a92bc11d2 | 5 | // with one endpoint in each direction. See USBJoystick.cpp and .h for |
mjr | 74:822a92bc11d2 | 6 | // the USB descriptors. |
mjr | 74:822a92bc11d2 | 7 | // |
mjr | 74:822a92bc11d2 | 8 | // Our incoming message protocol is an extended version of the protocol |
mjr | 74:822a92bc11d2 | 9 | // used by the LedWiz. Our protocol is designed to be 100% backwards |
mjr | 74:822a92bc11d2 | 10 | // compatible with clients using the original LedWiz wire protocol, as long |
mjr | 74:822a92bc11d2 | 11 | // as they only send well-formed messages in the original protocol. The |
mjr | 74:822a92bc11d2 | 12 | // "well-formed" part is an important condition, because our extensions to |
mjr | 74:822a92bc11d2 | 13 | // the original protocol all consist of messages that aren't defined in the |
mjr | 74:822a92bc11d2 | 14 | // original protocol and are meaningless to a real LedWiz. |
mjr | 35:e959ffba78fd | 15 | // |
mjr | 74:822a92bc11d2 | 16 | // The protocol compatibility ensures that all original LedWiz clients can |
mjr | 74:822a92bc11d2 | 17 | // also transparently access a Pinscape unit. Clients will simply think the |
mjr | 74:822a92bc11d2 | 18 | // Pinscape unit is an LedWiz, thus they'll be able to operate 32 of our |
mjr | 74:822a92bc11d2 | 19 | // ports. We designate the first 32 ports (ports 1-32) as the ones accessible |
mjr | 74:822a92bc11d2 | 20 | // through the LedWiz protocol. |
mjr | 74:822a92bc11d2 | 21 | // |
mjr | 74:822a92bc11d2 | 22 | // In addition the wire-level protocol compatibility, we can provide legacy |
mjr | 74:822a92bc11d2 | 23 | // LedWiz clients with access to more than 32 ports by emulating multiple |
mjr | 74:822a92bc11d2 | 24 | // virtual LedWiz units. We can't do this across the wire protocol, since |
mjr | 74:822a92bc11d2 | 25 | // the KL25Z USB interface constrains us to a single VID/PID (which is how |
mjr | 74:822a92bc11d2 | 26 | // LedWiz clients distinguish units). However, virtuall all legacy LedWiz |
mjr | 74:822a92bc11d2 | 27 | // clients access the device through a shared library, LEDWIZ.DLL, rather |
mjr | 74:822a92bc11d2 | 28 | // than directly through USB. LEDWIZ.DLL is distributed by the LedWiz's |
mjr | 74:822a92bc11d2 | 29 | // manufacturer and has a published client interface. We can thus provide |
mjr | 74:822a92bc11d2 | 30 | // a replacement DLL that contains the logic needed to recognize a Pinscape |
mjr | 74:822a92bc11d2 | 31 | // unit and represent it to clients as multiple LedWiz devices. This allows |
mjr | 74:822a92bc11d2 | 32 | // old clients to access our full complement of ports without any changes |
mjr | 74:822a92bc11d2 | 33 | // to the clients. We define some extended message types (SBX and PBX) |
mjr | 74:822a92bc11d2 | 34 | // specifically to support this DLL feature. |
mjr | 74:822a92bc11d2 | 35 | // |
mjr | 74:822a92bc11d2 | 36 | |
mjr | 35:e959ffba78fd | 37 | |
mjr | 35:e959ffba78fd | 38 | // ------ OUTGOING MESSAGES (DEVICE TO HOST) ------ |
mjr | 35:e959ffba78fd | 39 | // |
mjr | 47:df7a88cd249c | 40 | // General note: 16-bit and 32-bit fields in our reports are little-endian |
mjr | 47:df7a88cd249c | 41 | // unless otherwise specified. |
mjr | 47:df7a88cd249c | 42 | // |
mjr | 39:b3815a1c3802 | 43 | // 1. Joystick reports |
mjr | 35:e959ffba78fd | 44 | // In most cases, our outgoing messages are HID joystick reports, using the |
mjr | 35:e959ffba78fd | 45 | // format defined in USBJoystick.cpp. This allows us to be installed on |
mjr | 35:e959ffba78fd | 46 | // Windows as a standard USB joystick, which all versions of Windows support |
mjr | 35:e959ffba78fd | 47 | // using in-the-box drivers. This allows a completely transparent, driverless, |
mjr | 39:b3815a1c3802 | 48 | // plug-and-play installation experience on Windows. Our joystick report |
mjr | 39:b3815a1c3802 | 49 | // looks like this (see USBJoystick.cpp for the formal HID report descriptor): |
mjr | 35:e959ffba78fd | 50 | // |
mjr | 55:4db125cd11a0 | 51 | // ss status bits: |
mjr | 55:4db125cd11a0 | 52 | // 0x01 -> plunger enabled |
mjr | 55:4db125cd11a0 | 53 | // 0x02 -> night mode engaged |
mjr | 73:4e8ce0b18915 | 54 | // 0x04,0x08,0x10 -> power sense status: meaningful only when |
mjr | 73:4e8ce0b18915 | 55 | // the TV-on timer is used. Figure (ss>>2) & 0x07 to |
mjr | 73:4e8ce0b18915 | 56 | // isolate the status bits. The resulting value is: |
mjr | 73:4e8ce0b18915 | 57 | // 1 -> latch was on at last check |
mjr | 73:4e8ce0b18915 | 58 | // 2 -> latch was off at last check, SET pin high |
mjr | 73:4e8ce0b18915 | 59 | // 3 -> latch off, SET pin low, ready to check status |
mjr | 73:4e8ce0b18915 | 60 | // 4 -> TV timer countdown in progress |
mjr | 73:4e8ce0b18915 | 61 | // 5 -> TV relay is on |
mjr | 77:0b96f6867312 | 62 | // 6 -> sending IR signals designated as TV ON signals |
mjr | 77:0b96f6867312 | 63 | // 0x20 -> IR learning mode in progress |
mjr | 79:682ae3171a08 | 64 | // 0x40 -> configuration saved successfully (see below) |
mjr | 40:cc0d9814522b | 65 | // 00 2nd byte of status (reserved) |
mjr | 40:cc0d9814522b | 66 | // 00 3rd byte of status (reserved) |
mjr | 39:b3815a1c3802 | 67 | // 00 always zero for joystick reports |
mjr | 40:cc0d9814522b | 68 | // bb joystick buttons, low byte (buttons 1-8, 1 bit per button) |
mjr | 40:cc0d9814522b | 69 | // bb joystick buttons, 2nd byte (buttons 9-16) |
mjr | 40:cc0d9814522b | 70 | // bb joystick buttons, 3rd byte (buttons 17-24) |
mjr | 40:cc0d9814522b | 71 | // bb joystick buttons, high byte (buttons 25-32) |
mjr | 39:b3815a1c3802 | 72 | // xx low byte of X position = nudge/accelerometer X axis |
mjr | 39:b3815a1c3802 | 73 | // xx high byte of X position |
mjr | 39:b3815a1c3802 | 74 | // yy low byte of Y position = nudge/accelerometer Y axis |
mjr | 39:b3815a1c3802 | 75 | // yy high byte of Y position |
mjr | 39:b3815a1c3802 | 76 | // zz low byte of Z position = plunger position |
mjr | 39:b3815a1c3802 | 77 | // zz high byte of Z position |
mjr | 39:b3815a1c3802 | 78 | // |
mjr | 39:b3815a1c3802 | 79 | // The X, Y, and Z values are 16-bit signed integers. The accelerometer |
mjr | 39:b3815a1c3802 | 80 | // values are on an abstract scale, where 0 represents no acceleration, |
mjr | 39:b3815a1c3802 | 81 | // negative maximum represents -1g on that axis, and positive maximum |
mjr | 39:b3815a1c3802 | 82 | // represents +1g on that axis. For the plunger position, 0 is the park |
mjr | 39:b3815a1c3802 | 83 | // position (the rest position of the plunger) and positive values represent |
mjr | 39:b3815a1c3802 | 84 | // retracted (pulled back) positions. A negative value means that the plunger |
mjr | 39:b3815a1c3802 | 85 | // is pushed forward of the park position. |
mjr | 39:b3815a1c3802 | 86 | // |
mjr | 79:682ae3171a08 | 87 | // Status bit 0x40 is set after a successful configuration update via special |
mjr | 79:682ae3171a08 | 88 | // command 65 6 (save config to flash). The device always reboots after this |
mjr | 79:682ae3171a08 | 89 | // command, so if the host wants to receive a status update verifying the |
mjr | 79:682ae3171a08 | 90 | // save, it has to request a non-zero reboot delay in the message to allow |
mjr | 79:682ae3171a08 | 91 | // us time to send at least one of these status reports after the save. |
mjr | 79:682ae3171a08 | 92 | // This bit is only sent after a successful save, which means that the flash |
mjr | 79:682ae3171a08 | 93 | // write succeeded and the written sectors verified as correct. |
mjr | 82:4f6209cb5c33 | 94 | // NOTE: older firmware versions didn't support this status bit, so clients |
mjr | 82:4f6209cb5c33 | 95 | // can't interpret the lack of a response as a failure for older versions. |
mjr | 82:4f6209cb5c33 | 96 | // To determine if the flag is supported, check the config report feature |
mjr | 82:4f6209cb5c33 | 97 | // flags. |
mjr | 82:4f6209cb5c33 | 98 | // |
mjr | 79:682ae3171a08 | 99 | // |
mjr | 39:b3815a1c3802 | 100 | // 2. Special reports |
mjr | 35:e959ffba78fd | 101 | // We subvert the joystick report format in certain cases to report other |
mjr | 35:e959ffba78fd | 102 | // types of information, when specifically requested by the host. This allows |
mjr | 35:e959ffba78fd | 103 | // our custom configuration UI on the Windows side to query additional |
mjr | 35:e959ffba78fd | 104 | // information that we don't normally send via the joystick reports. We |
mjr | 35:e959ffba78fd | 105 | // define a custom vendor-specific "status" field in the reports that we |
mjr | 35:e959ffba78fd | 106 | // use to identify these special reports, as described below. |
mjr | 35:e959ffba78fd | 107 | // |
mjr | 39:b3815a1c3802 | 108 | // Normal joystick reports always have 0 in the high bit of the 2nd byte |
mjr | 35:e959ffba78fd | 109 | // of the report. Special non-joystick reports always have 1 in the high bit |
mjr | 35:e959ffba78fd | 110 | // of the first byte. (This byte is defined in the HID Report Descriptor |
mjr | 35:e959ffba78fd | 111 | // as an opaque vendor-defined value, so the joystick interface on the |
mjr | 35:e959ffba78fd | 112 | // Windows side simply ignores it.) |
mjr | 35:e959ffba78fd | 113 | // |
mjr | 52:8298b2a73eb2 | 114 | // 2A. Plunger sensor status report |
mjr | 52:8298b2a73eb2 | 115 | // Software on the PC can request a detailed status report from the plunger |
mjr | 52:8298b2a73eb2 | 116 | // sensor. The status information is meant as an aid to installing and |
mjr | 52:8298b2a73eb2 | 117 | // adjusting the sensor device for proper performance. For imaging sensor |
mjr | 52:8298b2a73eb2 | 118 | // types, the status report includes a complete current image snapshot |
mjr | 52:8298b2a73eb2 | 119 | // (an array of all of the pixels the sensor is currently imaging). For |
mjr | 52:8298b2a73eb2 | 120 | // all sensor types, it includes the current plunger position registered |
mjr | 52:8298b2a73eb2 | 121 | // on the sensor, and some timing information. |
mjr | 52:8298b2a73eb2 | 122 | // |
mjr | 52:8298b2a73eb2 | 123 | // To request the sensor status, the host sends custom protocol message 65 3 |
mjr | 52:8298b2a73eb2 | 124 | // (see below). The device replies with a message in this format: |
mjr | 52:8298b2a73eb2 | 125 | // |
mjr | 52:8298b2a73eb2 | 126 | // bytes 0:1 = 0x87FF |
mjr | 86:e30a1f60f783 | 127 | // byte 2 = 0 -> first status report packet |
mjr | 52:8298b2a73eb2 | 128 | // bytes 3:4 = number of pixels to be sent in following messages, as |
mjr | 52:8298b2a73eb2 | 129 | // an unsigned 16-bit little-endian integer. This is 0 if |
mjr | 52:8298b2a73eb2 | 130 | // the sensor isn't an imaging type. |
mjr | 86:e30a1f60f783 | 131 | // bytes 5:6 = current plunger position registered on the sensor. This |
mjr | 86:e30a1f60f783 | 132 | // is on the *native* scale for the sensor, which might be |
mjr | 86:e30a1f60f783 | 133 | // different from joystick units. By default, the native |
mjr | 86:e30a1f60f783 | 134 | // scale is the number of pixels for an imaging sensor, or |
mjr | 86:e30a1f60f783 | 135 | // 4096 for other sensor types. The actual native scale can |
mjr | 86:e30a1f60f783 | 136 | // be reported separately via a second status report message |
mjr | 86:e30a1f60f783 | 137 | // (see below). |
mjr | 52:8298b2a73eb2 | 138 | // byte 7 = bit flags: |
mjr | 52:8298b2a73eb2 | 139 | // 0x01 = normal orientation detected |
mjr | 52:8298b2a73eb2 | 140 | // 0x02 = reversed orientation detected |
mjr | 52:8298b2a73eb2 | 141 | // 0x04 = calibration mode is active (no pixel packets |
mjr | 52:8298b2a73eb2 | 142 | // are sent for this reading) |
mjr | 52:8298b2a73eb2 | 143 | // bytes 8:9:10 = average time for each sensor read, in 10us units. |
mjr | 52:8298b2a73eb2 | 144 | // This is the average time it takes to complete the I/O |
mjr | 52:8298b2a73eb2 | 145 | // operation to read the sensor, to obtain the raw sensor |
mjr | 52:8298b2a73eb2 | 146 | // data for instantaneous plunger position reading. For |
mjr | 52:8298b2a73eb2 | 147 | // an imaging sensor, this is the time it takes for the |
mjr | 52:8298b2a73eb2 | 148 | // sensor to capture the image and transfer it to the |
mjr | 52:8298b2a73eb2 | 149 | // microcontroller. For an analog sensor (e.g., an LVDT |
mjr | 52:8298b2a73eb2 | 150 | // or potentiometer), it's the time to complete an ADC |
mjr | 52:8298b2a73eb2 | 151 | // sample. |
mjr | 52:8298b2a73eb2 | 152 | // bytes 11:12:13 = time it took to process the current frame, in 10us |
mjr | 52:8298b2a73eb2 | 153 | // units. This is the software processing time that was |
mjr | 52:8298b2a73eb2 | 154 | // needed to analyze the raw data read from the sensor. |
mjr | 52:8298b2a73eb2 | 155 | // This is typically only non-zero for imaging sensors, |
mjr | 52:8298b2a73eb2 | 156 | // where it reflects the time required to scan the pixel |
mjr | 52:8298b2a73eb2 | 157 | // array to find the indicated plunger position. The time |
mjr | 52:8298b2a73eb2 | 158 | // is usually zero or negligible for analog sensor types, |
mjr | 52:8298b2a73eb2 | 159 | // since the only "analysis" is a multiplication to rescale |
mjr | 52:8298b2a73eb2 | 160 | // the ADC sample. |
mjr | 52:8298b2a73eb2 | 161 | // |
mjr | 86:e30a1f60f783 | 162 | // An optional second message provides additional information: |
mjr | 86:e30a1f60f783 | 163 | // |
mjr | 86:e30a1f60f783 | 164 | // bytes 0:1 = 0x87FF |
mjr | 86:e30a1f60f783 | 165 | // byte 2 = 1 -> second status report packet |
mjr | 86:e30a1f60f783 | 166 | // bytes 3:4 = Native sensor scale. This is the actual native scale |
mjr | 86:e30a1f60f783 | 167 | // used for the position report in the first status report |
mjr | 86:e30a1f60f783 | 168 | // packet above. |
mjr | 86:e30a1f60f783 | 169 | // bytes 5:6 = Jitter window lower bound, in native sensor scale units. |
mjr | 86:e30a1f60f783 | 170 | // bytes 7:8 = Jitter window upper bound, in native sensor scale units. |
mjr | 86:e30a1f60f783 | 171 | // The jitter window bounds reflect the current jitter filter |
mjr | 86:e30a1f60f783 | 172 | // status as of this reading. |
mjr | 86:e30a1f60f783 | 173 | // bytes 9:10 = Raw sensor reading before jitter filter was applied. |
mjr | 86:e30a1f60f783 | 174 | // bytes 11:12 = Auto-exposure time in microseconds |
mjr | 87:8d35c74403af | 175 | // |
mjr | 87:8d35c74403af | 176 | // An optional third message provides additional information specifically |
mjr | 87:8d35c74403af | 177 | // for bar-code sensors: |
mjr | 87:8d35c74403af | 178 | // |
mjr | 87:8d35c74403af | 179 | // bytes 0:1 = 0x87FF |
mjr | 113:7330439f2ffc | 180 | // byte 2 = 2 -> bar code sensor extra status report |
mjr | 87:8d35c74403af | 181 | // byte 3 = number of bits in bar code |
mjr | 87:8d35c74403af | 182 | // byte 4 = bar code type: |
mjr | 87:8d35c74403af | 183 | // 1 = Gray code/Manchester bit coding |
mjr | 87:8d35c74403af | 184 | // bytes 5:6 = pixel offset of first bit |
mjr | 87:8d35c74403af | 185 | // byte 7 = width in pixels of each bit |
mjr | 87:8d35c74403af | 186 | // bytes 8:9 = raw bar code bits |
mjr | 87:8d35c74403af | 187 | // bytes 10:11 = mask of successfully read bar code bits; a '1' bit means |
mjr | 87:8d35c74403af | 188 | // that the bit was read successfully, '0' means the bit was |
mjr | 87:8d35c74403af | 189 | // unreadable |
mjr | 108:bd5d4bd4383b | 190 | // |
mjr | 113:7330439f2ffc | 191 | // Another optional third message provides additional information |
mjr | 113:7330439f2ffc | 192 | // specifically for digital quadrature sensors: |
mjr | 108:bd5d4bd4383b | 193 | // |
mjr | 108:bd5d4bd4383b | 194 | // bytes 0:1 = 0x87FF |
mjr | 113:7330439f2ffc | 195 | // byte 2 = 3 -> digital quadrature sensor extra status report |
mjr | 108:bd5d4bd4383b | 196 | // byte 3 = "A" channel reading (0 or 1) |
mjr | 108:bd5d4bd4383b | 197 | // byte 4 = "B" channel reading (0 or 1) |
mjr | 113:7330439f2ffc | 198 | // |
mjr | 113:7330439f2ffc | 199 | // Yet another optional third message provides additional information for |
mjr | 113:7330439f2ffc | 200 | // VCNL4010 sensors: |
mjr | 86:e30a1f60f783 | 201 | // |
mjr | 113:7330439f2ffc | 202 | // bytes 0:1 = 0x87FF |
mjr | 113:7330439f2ffc | 203 | // bytes 2 = 4 -> VCNL4010 extra status report |
mjr | 113:7330439f2ffc | 204 | // bytes 3:4 = last proximity count reading (16-bit, little-endian), jitter filtered |
mjr | 113:7330439f2ffc | 205 | // bytes 5:6 = last proximity count reading, original unfiltered value |
mjr | 113:7330439f2ffc | 206 | // |
mjr | 113:7330439f2ffc | 207 | // If the sensor is an imaging sensor type, the first and second sensor |
mjr | 113:7330439f2ffc | 208 | // reports will be followed by a series of pixel reports giving the live |
mjr | 113:7330439f2ffc | 209 | // image view on the sensor. The imaging sensor types have too many pixels |
mjr | 52:8298b2a73eb2 | 210 | // to send in a single USB transaction, so the device breaks up the array |
mjr | 52:8298b2a73eb2 | 211 | // into as many packets as needed and sends them in sequence. For non- |
mjr | 52:8298b2a73eb2 | 212 | // imaging sensors, the "number of pixels" field in the lead packet is |
mjr | 52:8298b2a73eb2 | 213 | // zero, so obviously no pixel packets will follow. If the "calibration |
mjr | 52:8298b2a73eb2 | 214 | // active" bit in the flags byte is set, no pixel packets are sent even |
mjr | 52:8298b2a73eb2 | 215 | // if the sensor is an imaging type, since the transmission time for the |
mjr | 87:8d35c74403af | 216 | // pixels would interfere with the calibration process. If pixels are sent, |
mjr | 52:8298b2a73eb2 | 217 | // they're sent in order starting at the first pixel. The format of each |
mjr | 52:8298b2a73eb2 | 218 | // pixel packet is: |
mjr | 35:e959ffba78fd | 219 | // |
mjr | 35:e959ffba78fd | 220 | // bytes 0:1 = 11-bit index, with high 5 bits set to 10000. For |
mjr | 48:058ace2aed1d | 221 | // example, 0x8004 (encoded little endian as 0x04 0x80) |
mjr | 48:058ace2aed1d | 222 | // indicates index 4. This is the starting pixel number |
mjr | 48:058ace2aed1d | 223 | // in the report. The first report will be 0x00 0x80 to |
mjr | 48:058ace2aed1d | 224 | // indicate pixel #0. |
mjr | 47:df7a88cd249c | 225 | // bytes 2 = 8-bit unsigned int brightness level of pixel at index |
mjr | 47:df7a88cd249c | 226 | // bytes 3 = brightness of pixel at index+1 |
mjr | 35:e959ffba78fd | 227 | // etc for the rest of the packet |
mjr | 35:e959ffba78fd | 228 | // |
mjr | 52:8298b2a73eb2 | 229 | // Note that we currently only support one-dimensional imaging sensors |
mjr | 52:8298b2a73eb2 | 230 | // (i.e., pixel arrays that are 1 pixel wide). The report format doesn't |
mjr | 52:8298b2a73eb2 | 231 | // have any provision for a two-dimensional layout. The KL25Z probably |
mjr | 52:8298b2a73eb2 | 232 | // isn't powerful enough to do real-time image analysis on a 2D image |
mjr | 52:8298b2a73eb2 | 233 | // anyway, so it's unlikely that we'd be able to make 2D sensors work at |
mjr | 52:8298b2a73eb2 | 234 | // all, but if we ever add such a thing we'll have to upgrade the report |
mjr | 52:8298b2a73eb2 | 235 | // format here accordingly. |
mjr | 51:57eb311faafa | 236 | // |
mjr | 51:57eb311faafa | 237 | // |
mjr | 53:9b2611964afc | 238 | // 2B. Configuration report. |
mjr | 39:b3815a1c3802 | 239 | // This is requested by sending custom protocol message 65 4 (see below). |
mjr | 39:b3815a1c3802 | 240 | // In reponse, the device sends one report to the host using this format: |
mjr | 35:e959ffba78fd | 241 | // |
mjr | 35:e959ffba78fd | 242 | // bytes 0:1 = 0x8800. This has the bit pattern 10001 in the high |
mjr | 35:e959ffba78fd | 243 | // 5 bits, which distinguishes it from regular joystick |
mjr | 40:cc0d9814522b | 244 | // reports and from other special report types. |
mjr | 74:822a92bc11d2 | 245 | // bytes 2:3 = total number of configured outputs, little endian. This |
mjr | 74:822a92bc11d2 | 246 | // is the number of outputs with assigned functions in the |
mjr | 74:822a92bc11d2 | 247 | // active configuration. |
mjr | 98:4df3c0f7e707 | 248 | // byte 4 = Pinscape unit number (0-15) |
mjr | 75:677892300e7a | 249 | // byte 5 = reserved (currently always zero) |
mjr | 40:cc0d9814522b | 250 | // bytes 6:7 = plunger calibration zero point, little endian |
mjr | 40:cc0d9814522b | 251 | // bytes 8:9 = plunger calibration maximum point, little endian |
mjr | 52:8298b2a73eb2 | 252 | // byte 10 = plunger calibration release time, in milliseconds |
mjr | 52:8298b2a73eb2 | 253 | // byte 11 = bit flags: |
mjr | 40:cc0d9814522b | 254 | // 0x01 -> configuration loaded; 0 in this bit means that |
mjr | 40:cc0d9814522b | 255 | // the firmware has been loaded but no configuration |
mjr | 40:cc0d9814522b | 256 | // has been sent from the host |
mjr | 74:822a92bc11d2 | 257 | // 0x02 -> SBX/PBX extension features: 1 in this bit means |
mjr | 74:822a92bc11d2 | 258 | // that these features are present in this version. |
mjr | 78:1e00b3fa11af | 259 | // 0x04 -> new accelerometer features supported (adjustable |
mjr | 78:1e00b3fa11af | 260 | // dynamic range, auto-centering on/off, adjustable |
mjr | 78:1e00b3fa11af | 261 | // auto-centering time) |
mjr | 82:4f6209cb5c33 | 262 | // 0x08 -> flash write status flag supported (see flag 0x40 |
mjr | 82:4f6209cb5c33 | 263 | // in normal joystick status report) |
mjr | 92:f264fbaa1be5 | 264 | // 0x10 -> joystick report timing features supports |
mjr | 92:f264fbaa1be5 | 265 | // (configurable joystick report interval, acceler- |
mjr | 92:f264fbaa1be5 | 266 | // ometer stutter counter) |
mjr | 99:8139b0c274f4 | 267 | // 0x20 -> chime logic is supported |
mjr | 73:4e8ce0b18915 | 268 | // bytes 12:13 = available RAM, in bytes, little endian. This is the amount |
mjr | 73:4e8ce0b18915 | 269 | // of unused heap (malloc'able) memory. The firmware generally |
mjr | 73:4e8ce0b18915 | 270 | // allocates all of the dynamic memory it needs during startup, |
mjr | 73:4e8ce0b18915 | 271 | // so the free memory figure doesn't tend to fluctuate during |
mjr | 73:4e8ce0b18915 | 272 | // normal operation. The dynamic memory used is a function of |
mjr | 73:4e8ce0b18915 | 273 | // the set of features enabled. |
mjr | 35:e959ffba78fd | 274 | // |
mjr | 53:9b2611964afc | 275 | // 2C. Device ID report. |
mjr | 40:cc0d9814522b | 276 | // This is requested by sending custom protocol message 65 7 (see below). |
mjr | 40:cc0d9814522b | 277 | // In response, the device sends one report to the host using this format: |
mjr | 40:cc0d9814522b | 278 | // |
mjr | 52:8298b2a73eb2 | 279 | // bytes 0:1 = 0x9000. This has bit pattern 10010 in the high 5 bits |
mjr | 52:8298b2a73eb2 | 280 | // to distinguish this from other report types. |
mjr | 53:9b2611964afc | 281 | // byte 2 = ID type. This is the same ID type sent in the request. |
mjr | 53:9b2611964afc | 282 | // bytes 3-12 = requested ID. The ID is 80 bits in big-endian byte |
mjr | 53:9b2611964afc | 283 | // order. For IDs longer than 80 bits, we truncate to the |
mjr | 53:9b2611964afc | 284 | // low-order 80 bits (that is, the last 80 bits). |
mjr | 53:9b2611964afc | 285 | // |
mjr | 53:9b2611964afc | 286 | // ID type 1 = CPU ID. This is the globally unique CPU ID |
mjr | 53:9b2611964afc | 287 | // stored in the KL25Z CPU. |
mjr | 35:e959ffba78fd | 288 | // |
mjr | 53:9b2611964afc | 289 | // ID type 2 = OpenSDA ID. This is the globally unique ID |
mjr | 53:9b2611964afc | 290 | // for the connected OpenSDA controller, if known. This |
mjr | 53:9b2611964afc | 291 | // allow the host to figure out which USB MSD (virtual |
mjr | 53:9b2611964afc | 292 | // disk drive), if any, represents the OpenSDA module for |
mjr | 53:9b2611964afc | 293 | // this Pinscape USB interface. This is primarily useful |
mjr | 53:9b2611964afc | 294 | // to determine which MSD to write in order to update the |
mjr | 53:9b2611964afc | 295 | // firmware on a given Pinscape unit. |
mjr | 53:9b2611964afc | 296 | // |
mjr | 53:9b2611964afc | 297 | // 2D. Configuration variable report. |
mjr | 52:8298b2a73eb2 | 298 | // This is requested by sending custom protocol message 65 9 (see below). |
mjr | 52:8298b2a73eb2 | 299 | // In response, the device sends one report to the host using this format: |
mjr | 52:8298b2a73eb2 | 300 | // |
mjr | 52:8298b2a73eb2 | 301 | // bytes 0:1 = 0x9800. This has bit pattern 10011 in the high 5 bits |
mjr | 52:8298b2a73eb2 | 302 | // to distinguish this from other report types. |
mjr | 52:8298b2a73eb2 | 303 | // byte 2 = Variable ID. This is the same variable ID sent in the |
mjr | 52:8298b2a73eb2 | 304 | // query message, to relate the reply to the request. |
mjr | 52:8298b2a73eb2 | 305 | // bytes 3-8 = Current value of the variable, in the format for the |
mjr | 52:8298b2a73eb2 | 306 | // individual variable type. The variable formats are |
mjr | 52:8298b2a73eb2 | 307 | // described in the CONFIGURATION VARIABLES section below. |
mjr | 52:8298b2a73eb2 | 308 | // |
mjr | 53:9b2611964afc | 309 | // 2E. Software build information report. |
mjr | 53:9b2611964afc | 310 | // This is requested by sending custom protocol message 65 10 (see below). |
mjr | 53:9b2611964afc | 311 | // In response, the device sends one report using this format: |
mjr | 53:9b2611964afc | 312 | // |
mjr | 73:4e8ce0b18915 | 313 | // bytes 0:1 = 0xA000. This has bit pattern 10100 in the high 5 bits |
mjr | 77:0b96f6867312 | 314 | // (and 10100000 in the high 8 bits) to distinguish it from |
mjr | 77:0b96f6867312 | 315 | // other report types. |
mjr | 53:9b2611964afc | 316 | // bytes 2:5 = Build date. This is returned as a 32-bit integer, |
mjr | 53:9b2611964afc | 317 | // little-endian as usual, encoding a decimal value |
mjr | 53:9b2611964afc | 318 | // in the format YYYYMMDD giving the date of the build. |
mjr | 53:9b2611964afc | 319 | // E.g., Feb 16 2016 is encoded as 20160216 (decimal). |
mjr | 53:9b2611964afc | 320 | // bytes 6:9 = Build time. This is a 32-bit integer, little-endian, |
mjr | 53:9b2611964afc | 321 | // encoding a decimal value in the format HHMMSS giving |
mjr | 53:9b2611964afc | 322 | // build time on a 24-hour clock. |
mjr | 53:9b2611964afc | 323 | // |
mjr | 73:4e8ce0b18915 | 324 | // 2F. Button status report. |
mjr | 73:4e8ce0b18915 | 325 | // This is requested by sending custom protocol message 65 13 (see below). |
mjr | 73:4e8ce0b18915 | 326 | // In response, the device sends one report using this format: |
mjr | 73:4e8ce0b18915 | 327 | // |
mjr | 77:0b96f6867312 | 328 | // bytes 0:1 = 0xA1. This has bit pattern 10100 in the high 5 bits (and |
mjr | 77:0b96f6867312 | 329 | // 10100001 in the high 8 bits) to distinguish it from other |
mjr | 77:0b96f6867312 | 330 | // report types. |
mjr | 73:4e8ce0b18915 | 331 | // byte 2 = number of button reports |
mjr | 73:4e8ce0b18915 | 332 | // byte 3 = Physical status of buttons 1-8, 1 bit each. The low-order |
mjr | 73:4e8ce0b18915 | 333 | // bit (0x01) is button 1. Each bit is 0 if the button is off, |
mjr | 73:4e8ce0b18915 | 334 | // 1 if on. This reflects the physical status of the button |
mjr | 73:4e8ce0b18915 | 335 | // input pins, after debouncing but before any logical state |
mjr | 73:4e8ce0b18915 | 336 | // processing. Pulse mode and shifting have no effect on the |
mjr | 73:4e8ce0b18915 | 337 | // physical state; this simply indicates whether the button is |
mjr | 73:4e8ce0b18915 | 338 | // electrically on (shorted to GND) or off (open circuit). |
mjr | 73:4e8ce0b18915 | 339 | // byte 4 = buttons 9-16 |
mjr | 73:4e8ce0b18915 | 340 | // byte 5 = buttons 17-24 |
mjr | 73:4e8ce0b18915 | 341 | // byte 6 = buttons 25-32 |
mjr | 73:4e8ce0b18915 | 342 | // byte 7 = buttons 33-40 |
mjr | 73:4e8ce0b18915 | 343 | // byte 8 = buttons 41-48 |
mjr | 73:4e8ce0b18915 | 344 | // |
mjr | 77:0b96f6867312 | 345 | // 2G. IR sensor data report. |
mjr | 77:0b96f6867312 | 346 | // This is requested by sending custom protocol message 65 12 (see below). |
mjr | 77:0b96f6867312 | 347 | // That command puts controller in IR learning mode for a short time, during |
mjr | 77:0b96f6867312 | 348 | // which it monitors the IR sensor and send these special reports to relay the |
mjr | 77:0b96f6867312 | 349 | // readings. The reports contain the raw data, plus the decoded command code |
mjr | 77:0b96f6867312 | 350 | // and protocol information if the controller is able to recognize and decode |
mjr | 77:0b96f6867312 | 351 | // the command. |
mjr | 52:8298b2a73eb2 | 352 | // |
mjr | 77:0b96f6867312 | 353 | // bytes 0:1 = 0xA2. This has bit pattern 10100 in the high 5 bits (and |
mjr | 77:0b96f6867312 | 354 | // 10100010 in the high 8 bits to distinguish it from other |
mjr | 77:0b96f6867312 | 355 | // report types. |
mjr | 77:0b96f6867312 | 356 | // byte 2 = number of raw reports that follow |
mjr | 77:0b96f6867312 | 357 | // bytes 3:4 = first raw report, as a little-endian 16-bit int. The |
mjr | 77:0b96f6867312 | 358 | // value represents the time of an IR "space" or "mark" in |
mjr | 77:0b96f6867312 | 359 | // 2us units. The low bit is 0 for a space and 1 for a mark. |
mjr | 77:0b96f6867312 | 360 | // To recover the time in microseconds, mask our the low bit |
mjr | 77:0b96f6867312 | 361 | // and multiply the result by 2. Received codes always |
mjr | 77:0b96f6867312 | 362 | // alternate between spaces and marks. A space is an interval |
mjr | 77:0b96f6867312 | 363 | // where the IR is off, and a mark is an interval with IR on. |
mjr | 77:0b96f6867312 | 364 | // If the value is 0xFFFE (after masking out the low bit), it |
mjr | 77:0b96f6867312 | 365 | // represents a timeout, that is, a time greater than or equal |
mjr | 77:0b96f6867312 | 366 | // to the maximum that can be represented in this format, |
mjr | 77:0b96f6867312 | 367 | // which is 131068us. None of the IR codes we can parse have |
mjr | 77:0b96f6867312 | 368 | // any internal signal component this long, so a timeout value |
mjr | 77:0b96f6867312 | 369 | // is generally seen only during a gap between codes where |
mjr | 77:0b96f6867312 | 370 | // nothing is being transmitted. |
mjr | 77:0b96f6867312 | 371 | // bytes 4:5 = second raw report |
mjr | 77:0b96f6867312 | 372 | // (etc for remaining reports) |
mjr | 77:0b96f6867312 | 373 | // |
mjr | 77:0b96f6867312 | 374 | // If byte 2 is 0x00, it indicates that learning mode has expired without |
mjr | 77:0b96f6867312 | 375 | // a code being received, so it's the last report sent for the learning |
mjr | 77:0b96f6867312 | 376 | // session. |
mjr | 77:0b96f6867312 | 377 | // |
mjr | 77:0b96f6867312 | 378 | // If byte 2 is 0xFF, it indicates that a code has been successfully |
mjr | 77:0b96f6867312 | 379 | // learned. The rest of the report contains the learned code instead |
mjr | 77:0b96f6867312 | 380 | // of the raw data: |
mjr | 77:0b96f6867312 | 381 | // |
mjr | 77:0b96f6867312 | 382 | // byte 3 = protocol ID, which is an integer giving an internal code |
mjr | 77:0b96f6867312 | 383 | // identifying the IR protocol that was recognized for the |
mjr | 77:0b96f6867312 | 384 | // received data. See IRProtocolID.h for a list of the IDs. |
mjr | 77:0b96f6867312 | 385 | // byte 4 = bit flags: |
mjr | 77:0b96f6867312 | 386 | // 0x02 -> the protocol uses "dittos" |
mjr | 77:0b96f6867312 | 387 | // bytes 5:6:7:8:9:10:11:12 = a little-endian 64-bit int containing |
mjr | 77:0b96f6867312 | 388 | // the code received. The code is essentially the data payload |
mjr | 77:0b96f6867312 | 389 | // of the IR packet, after removing bits that are purely |
mjr | 77:0b96f6867312 | 390 | // structural, such as toggle bits and error correction bits. |
mjr | 77:0b96f6867312 | 391 | // The mapping between the IR bit stream and our 64-bit is |
mjr | 77:0b96f6867312 | 392 | // essentially arbitrary and varies by protocol, but it always |
mjr | 77:0b96f6867312 | 393 | // has round-trip fidelity: using the 64-bit code value + |
mjr | 77:0b96f6867312 | 394 | // protocol ID + flags to send an IR command will result in |
mjr | 77:0b96f6867312 | 395 | // the same IR bit sequence being sent, modulo structural bits |
mjr | 77:0b96f6867312 | 396 | // that need to be updates in the reconstruction (such as toggle |
mjr | 77:0b96f6867312 | 397 | // bits or sequencing codes). |
mjr | 77:0b96f6867312 | 398 | // |
mjr | 77:0b96f6867312 | 399 | // |
mjr | 77:0b96f6867312 | 400 | // WHY WE USE A HACKY APPROACH TO DIFFERENT REPORT TYPES |
mjr | 35:e959ffba78fd | 401 | // |
mjr | 35:e959ffba78fd | 402 | // The HID report system was specifically designed to provide a clean, |
mjr | 35:e959ffba78fd | 403 | // structured way for devices to describe the data they send to the host. |
mjr | 35:e959ffba78fd | 404 | // Our approach isn't clean or structured; it ignores the promises we |
mjr | 35:e959ffba78fd | 405 | // make about the contents of our report via the HID Report Descriptor |
mjr | 35:e959ffba78fd | 406 | // and stuffs our own different data format into the same structure. |
mjr | 35:e959ffba78fd | 407 | // |
mjr | 77:0b96f6867312 | 408 | // We use this hacky approach only because we can't use the standard USB |
mjr | 77:0b96f6867312 | 409 | // HID mechanism for varying report types, which is to provide multiple |
mjr | 77:0b96f6867312 | 410 | // report descriptors and tag each report with a type byte that indicates |
mjr | 77:0b96f6867312 | 411 | // which descriptor applies. We can't use that standard approach because |
mjr | 77:0b96f6867312 | 412 | // we want to be 100% LedWiz compatible. The snag is that some Windows |
mjr | 77:0b96f6867312 | 413 | // LedWiz clients parse the USB HID descriptors as part of identifying a |
mjr | 77:0b96f6867312 | 414 | // USB HID device as a valid LedWiz unit, and will only recognize the device |
mjr | 77:0b96f6867312 | 415 | // if certain properties of the HID descriptors match those of a real LedWiz. |
mjr | 77:0b96f6867312 | 416 | // One of the features that's important to some clients is the descriptor |
mjr | 77:0b96f6867312 | 417 | // link structure, which is affected by the layout of HID Report Descriptor |
mjr | 77:0b96f6867312 | 418 | // entries. In order to match the expected layout, we can only define a |
mjr | 77:0b96f6867312 | 419 | // single kind of output report. Since we have to use Joystick reports for |
mjr | 77:0b96f6867312 | 420 | // the sake of VP and other pinball software, and we're only allowed the |
mjr | 77:0b96f6867312 | 421 | // one report type, we have to make that one report type the Joystick type. |
mjr | 77:0b96f6867312 | 422 | // That's why we overload the joystick reports with other meanings. It's a |
mjr | 77:0b96f6867312 | 423 | // hack, but at least it's a fairly reliable and isolated hack, in that our |
mjr | 77:0b96f6867312 | 424 | // special reports are only generated when clients specifically ask for |
mjr | 77:0b96f6867312 | 425 | // them. Plus, even if a client who doesn't ask for a special report |
mjr | 77:0b96f6867312 | 426 | // somehow gets one, the worst that happens is that they get a momentary |
mjr | 77:0b96f6867312 | 427 | // spurious reading from the accelerometer and plunger. |
mjr | 35:e959ffba78fd | 428 | |
mjr | 35:e959ffba78fd | 429 | |
mjr | 35:e959ffba78fd | 430 | |
mjr | 35:e959ffba78fd | 431 | // ------- INCOMING MESSAGES (HOST TO DEVICE) ------- |
mjr | 35:e959ffba78fd | 432 | // |
mjr | 35:e959ffba78fd | 433 | // For LedWiz compatibility, our incoming message format conforms to the |
mjr | 35:e959ffba78fd | 434 | // basic USB format used by real LedWiz units. This is simply 8 data |
mjr | 35:e959ffba78fd | 435 | // bytes, all private vendor-specific values (meaning that the Windows HID |
mjr | 35:e959ffba78fd | 436 | // driver treats them as opaque and doesn't attempt to parse them). |
mjr | 35:e959ffba78fd | 437 | // |
mjr | 35:e959ffba78fd | 438 | // Within this basic 8-byte format, we recognize the full protocol used |
mjr | 35:e959ffba78fd | 439 | // by real LedWiz units, plus an extended protocol that we define privately. |
mjr | 35:e959ffba78fd | 440 | // The LedWiz protocol leaves a large part of the potential protocol space |
mjr | 35:e959ffba78fd | 441 | // undefined, so we take advantage of this undefined region for our |
mjr | 35:e959ffba78fd | 442 | // extensions. This ensures that we can properly recognize all messages |
mjr | 35:e959ffba78fd | 443 | // intended for a real LedWiz unit, as well as messages from custom host |
mjr | 35:e959ffba78fd | 444 | // software that knows it's talking to a Pinscape unit. |
mjr | 35:e959ffba78fd | 445 | |
mjr | 35:e959ffba78fd | 446 | // --- REAL LED WIZ MESSAGES --- |
mjr | 35:e959ffba78fd | 447 | // |
mjr | 74:822a92bc11d2 | 448 | // The real LedWiz protocol has two message types, "SBA" and "PBA". The |
mjr | 74:822a92bc11d2 | 449 | // message type can be determined from the first byte of the 8-byte message |
mjr | 74:822a92bc11d2 | 450 | // packet: if the first byte 64 (0x40), it's an SBA message. If the first |
mjr | 74:822a92bc11d2 | 451 | // byte is 0-49 or 129-132, it's a PBA message. All other byte values are |
mjr | 74:822a92bc11d2 | 452 | // invalid in the original protocol and have undefined behavior if sent to |
mjr | 74:822a92bc11d2 | 453 | // a real LedWiz. We take advantage of this to extend the protocol with |
mjr | 74:822a92bc11d2 | 454 | // our new features by assigning new meanings to byte patterns that have no |
mjr | 74:822a92bc11d2 | 455 | // meaning in the original protocol. |
mjr | 35:e959ffba78fd | 456 | // |
mjr | 74:822a92bc11d2 | 457 | // "SBA" message: 64 xx xx xx xx ss 00 00 |
mjr | 74:822a92bc11d2 | 458 | // xx = on/off bit mask for 8 outputs |
mjr | 74:822a92bc11d2 | 459 | // ss = global flash speed setting (valid values 1-7) |
mjr | 74:822a92bc11d2 | 460 | // 00 = unused/reserved; client should set to zero (not enforced, but |
mjr | 74:822a92bc11d2 | 461 | // strongly recommended in case of future additions) |
mjr | 35:e959ffba78fd | 462 | // |
mjr | 35:e959ffba78fd | 463 | // If the first byte has value 64 (0x40), it's an SBA message. This type of |
mjr | 35:e959ffba78fd | 464 | // message sets all 32 outputs individually ON or OFF according to the next |
mjr | 35:e959ffba78fd | 465 | // 32 bits (4 bytes) of the message, and sets the flash speed to the value in |
mjr | 74:822a92bc11d2 | 466 | // the sixth byte. The flash speed sets the global cycle rate for flashing |
mjr | 74:822a92bc11d2 | 467 | // outputs - outputs with their values set to the range 128-132. The speed |
mjr | 74:822a92bc11d2 | 468 | // parameter is in ad hoc units that aren't documented in the LedWiz API, but |
mjr | 74:822a92bc11d2 | 469 | // observations of real LedWiz units show that the "speed" is actually the |
mjr | 74:822a92bc11d2 | 470 | // period, each unit representing 0.25s: so speed 1 is a 0.25s period, or 4Hz, |
mjr | 74:822a92bc11d2 | 471 | // speed 2 is a 0.5s period or 2Hz, etc., up to speed 7 as a 1.75s period or |
mjr | 74:822a92bc11d2 | 472 | // 0.57Hz. The period is the full waveform cycle time. |
mjr | 74:822a92bc11d2 | 473 | // |
mjr | 35:e959ffba78fd | 474 | // |
mjr | 74:822a92bc11d2 | 475 | // "PBA" message: bb bb bb bb bb bb bb bb |
mjr | 74:822a92bc11d2 | 476 | // bb = brightness level, 0-49 or 128-132 |
mjr | 35:e959ffba78fd | 477 | // |
mjr | 74:822a92bc11d2 | 478 | // Note that there's no prefix byte indicating this message type. This |
mjr | 74:822a92bc11d2 | 479 | // message is indicated simply by the first byte being in one of the valid |
mjr | 74:822a92bc11d2 | 480 | // ranges. |
mjr | 74:822a92bc11d2 | 481 | // |
mjr | 74:822a92bc11d2 | 482 | // Each byte gives the new brightness level or flash pattern for one part. |
mjr | 74:822a92bc11d2 | 483 | // The valid values are: |
mjr | 35:e959ffba78fd | 484 | // |
mjr | 35:e959ffba78fd | 485 | // 0-48 = fixed brightness level, linearly from 0% to 100% intensity |
mjr | 35:e959ffba78fd | 486 | // 49 = fixed brightness level at 100% intensity (same as 48) |
mjr | 35:e959ffba78fd | 487 | // 129 = flashing pattern, fade up / fade down (sawtooth wave) |
mjr | 35:e959ffba78fd | 488 | // 130 = flashing pattern, on / off (square wave) |
mjr | 35:e959ffba78fd | 489 | // 131 = flashing pattern, on for 50% duty cycle / fade down |
mjr | 35:e959ffba78fd | 490 | // 132 = flashing pattern, fade up / on for 50% duty cycle |
mjr | 35:e959ffba78fd | 491 | // |
mjr | 74:822a92bc11d2 | 492 | // This message sets new brightness/flash settings for 8 ports. There's |
mjr | 74:822a92bc11d2 | 493 | // no port number specified in the message; instead, the port is given by |
mjr | 74:822a92bc11d2 | 494 | // the protocol state. Specifically, the device has an internal register |
mjr | 74:822a92bc11d2 | 495 | // containing the base port for PBA messages. On reset AND after any SBA |
mjr | 74:822a92bc11d2 | 496 | // message is received, the base port is set to 0. After any PBA message |
mjr | 74:822a92bc11d2 | 497 | // is received and processed, the base port is incremented by 8, resetting |
mjr | 74:822a92bc11d2 | 498 | // to 0 when it reaches 32. The bytes of the message set the brightness |
mjr | 74:822a92bc11d2 | 499 | // levels for the base port, base port + 1, ..., base port + 7 respectively. |
mjr | 35:e959ffba78fd | 500 | // |
mjr | 74:822a92bc11d2 | 501 | // |
mjr | 35:e959ffba78fd | 502 | |
mjr | 35:e959ffba78fd | 503 | // --- PRIVATE EXTENDED MESSAGES --- |
mjr | 35:e959ffba78fd | 504 | // |
mjr | 35:e959ffba78fd | 505 | // All of our extended protocol messages are identified by the first byte: |
mjr | 35:e959ffba78fd | 506 | // |
mjr | 35:e959ffba78fd | 507 | // 65 -> Miscellaneous control message. The second byte specifies the specific |
mjr | 35:e959ffba78fd | 508 | // operation: |
mjr | 35:e959ffba78fd | 509 | // |
mjr | 39:b3815a1c3802 | 510 | // 0 -> No Op - does nothing. (This can be used to send a test message on the |
mjr | 39:b3815a1c3802 | 511 | // USB endpoint.) |
mjr | 39:b3815a1c3802 | 512 | // |
mjr | 88:98bce687e6c0 | 513 | // 1 -> Set the device's LedWiz unit number and plunger status, and save the |
mjr | 88:98bce687e6c0 | 514 | // changes to flash. The device automatically reboots after the changes |
mjr | 88:98bce687e6c0 | 515 | // are saved if the unit number is changed, since this changes the USB |
mjr | 88:98bce687e6c0 | 516 | // product ID code. The additional bytes of the message give the |
mjr | 88:98bce687e6c0 | 517 | // parameters: |
mjr | 35:e959ffba78fd | 518 | // |
mjr | 88:98bce687e6c0 | 519 | // third byte = new LedWiz unit number (0-15, corresponding to nominal |
mjr | 88:98bce687e6c0 | 520 | // LedWiz unit numbers 1-16) |
mjr | 35:e959ffba78fd | 521 | // fourth byte = plunger on/off (0=disabled, 1=enabled) |
mjr | 35:e959ffba78fd | 522 | // |
mjr | 88:98bce687e6c0 | 523 | // Note that this command is from the original version and isn't typically |
mjr | 88:98bce687e6c0 | 524 | // used any more, since the same information has been subsumed into more |
mjr | 88:98bce687e6c0 | 525 | // generalized option settings via the config variable system. |
mjr | 88:98bce687e6c0 | 526 | // |
mjr | 35:e959ffba78fd | 527 | // 2 -> Begin plunger calibration mode. The device stays in this mode for about |
mjr | 35:e959ffba78fd | 528 | // 15 seconds, and sets the zero point and maximum retraction points to the |
mjr | 35:e959ffba78fd | 529 | // observed endpoints of sensor readings while the mode is running. After |
mjr | 35:e959ffba78fd | 530 | // the time limit elapses, the device automatically stores the results in |
mjr | 35:e959ffba78fd | 531 | // non-volatile flash memory and exits the mode. |
mjr | 35:e959ffba78fd | 532 | // |
mjr | 51:57eb311faafa | 533 | // 3 -> Send pixel dump. The device sends one complete image snapshot from the |
mjr | 51:57eb311faafa | 534 | // plunger sensor, as as series of pixel dump messages. (The message format |
mjr | 51:57eb311faafa | 535 | // isn't big enough to allow the whole image to be sent in one message, so |
mjr | 53:9b2611964afc | 536 | // the image is broken up into as many messages as necessary.) The device |
mjr | 53:9b2611964afc | 537 | // then resumes sending normal joystick messages. If the plunger sensor |
mjr | 53:9b2611964afc | 538 | // isn't an imaging type, or no sensor is installed, no pixel messages are |
mjr | 53:9b2611964afc | 539 | // sent. Parameters: |
mjr | 48:058ace2aed1d | 540 | // |
mjr | 48:058ace2aed1d | 541 | // third byte = bit flags: |
mjr | 51:57eb311faafa | 542 | // 0x01 = low res mode. The device rescales the sensor pixel array |
mjr | 51:57eb311faafa | 543 | // sent in the dump messages to a low-resolution subset. The |
mjr | 51:57eb311faafa | 544 | // size of the subset is determined by the device. This has |
mjr | 51:57eb311faafa | 545 | // no effect on the sensor operation; it merely reduces the |
mjr | 51:57eb311faafa | 546 | // USB transmission time to allow for a faster frame rate for |
mjr | 51:57eb311faafa | 547 | // viewing in the config tool. |
mjr | 35:e959ffba78fd | 548 | // |
mjr | 53:9b2611964afc | 549 | // fourth byte = extra exposure time in 100us (.1ms) increments. For |
mjr | 53:9b2611964afc | 550 | // imaging sensors, we'll add this delay to the minimum exposure |
mjr | 53:9b2611964afc | 551 | // time. This allows the caller to explicitly adjust the exposure |
mjr | 53:9b2611964afc | 552 | // level for calibration purposes. |
mjr | 53:9b2611964afc | 553 | // |
mjr | 35:e959ffba78fd | 554 | // 4 -> Query configuration. The device sends a special configuration report, |
mjr | 40:cc0d9814522b | 555 | // (see above; see also USBJoystick.cpp), then resumes sending normal |
mjr | 40:cc0d9814522b | 556 | // joystick reports. |
mjr | 35:e959ffba78fd | 557 | // |
mjr | 74:822a92bc11d2 | 558 | // 5 -> Turn all outputs off and restore LedWiz defaults. Sets all output |
mjr | 74:822a92bc11d2 | 559 | // ports to OFF and LedWiz brightness/mode setting 48, and sets the LedWiz |
mjr | 74:822a92bc11d2 | 560 | // global flash speed to 2. |
mjr | 35:e959ffba78fd | 561 | // |
mjr | 35:e959ffba78fd | 562 | // 6 -> Save configuration to flash. This saves all variable updates sent via |
mjr | 85:3c28aee81cde | 563 | // type 66 messages since the last reboot, then optionally reboots the |
mjr | 82:4f6209cb5c33 | 564 | // device to put the changes into effect. If the flash write succeeds, |
mjr | 82:4f6209cb5c33 | 565 | // we set the "flash write OK" bit in our status reports, which we |
mjr | 82:4f6209cb5c33 | 566 | // continue sending between the successful write and the delayed reboot. |
mjr | 85:3c28aee81cde | 567 | // We don't set the bit or reboot if the write fails. If the "do not |
mjr | 85:3c28aee81cde | 568 | // reboot" flag is set, we still set the flag on success for the delay |
mjr | 85:3c28aee81cde | 569 | // time, then clear the flag. |
mjr | 35:e959ffba78fd | 570 | // |
mjr | 53:9b2611964afc | 571 | // third byte = delay time in seconds. The device will wait this long |
mjr | 82:4f6209cb5c33 | 572 | // before disconnecting, to allow the PC to test for the success bit |
mjr | 82:4f6209cb5c33 | 573 | // in the status report, and to perform any cleanup tasks while the |
mjr | 82:4f6209cb5c33 | 574 | // device is still attached (e.g., modifying Windows device driver |
mjr | 82:4f6209cb5c33 | 575 | // settings) |
mjr | 53:9b2611964afc | 576 | // |
mjr | 85:3c28aee81cde | 577 | // fourth byte = flags: |
mjr | 85:3c28aee81cde | 578 | // 0x01 -> do not reboot |
mjr | 85:3c28aee81cde | 579 | // |
mjr | 40:cc0d9814522b | 580 | // 7 -> Query device ID. The device replies with a special device ID report |
mjr | 40:cc0d9814522b | 581 | // (see above; see also USBJoystick.cpp), then resumes sending normal |
mjr | 40:cc0d9814522b | 582 | // joystick reports. |
mjr | 40:cc0d9814522b | 583 | // |
mjr | 53:9b2611964afc | 584 | // The third byte of the message is the ID index to retrieve: |
mjr | 53:9b2611964afc | 585 | // |
mjr | 53:9b2611964afc | 586 | // 1 = CPU ID: returns the KL25Z globally unique CPU ID. |
mjr | 53:9b2611964afc | 587 | // |
mjr | 53:9b2611964afc | 588 | // 2 = OpenSDA ID: returns the OpenSDA TUID. This must be patched |
mjr | 53:9b2611964afc | 589 | // into the firmware by the PC host when the .bin file is |
mjr | 53:9b2611964afc | 590 | // installed onto the device. This will return all 'X' bytes |
mjr | 53:9b2611964afc | 591 | // if the value wasn't patched at install time. |
mjr | 53:9b2611964afc | 592 | // |
mjr | 40:cc0d9814522b | 593 | // 8 -> Engage/disengage night mode. The third byte of the message is 1 to |
mjr | 55:4db125cd11a0 | 594 | // engage night mode, 0 to disengage night mode. The current mode isn't |
mjr | 55:4db125cd11a0 | 595 | // stored persistently; night mode is always off after a reset. |
mjr | 40:cc0d9814522b | 596 | // |
mjr | 52:8298b2a73eb2 | 597 | // 9 -> Query configuration variable. The second byte is the config variable |
mjr | 52:8298b2a73eb2 | 598 | // number (see the CONFIGURATION VARIABLES section below). For the array |
mjr | 52:8298b2a73eb2 | 599 | // variables (button assignments, output ports), the third byte is the |
mjr | 52:8298b2a73eb2 | 600 | // array index. The device replies with a configuration variable report |
mjr | 52:8298b2a73eb2 | 601 | // (see above) with the current setting for the requested variable. |
mjr | 52:8298b2a73eb2 | 602 | // |
mjr | 53:9b2611964afc | 603 | // 10 -> Query software build information. No parameters. This replies with |
mjr | 53:9b2611964afc | 604 | // the software build information report (see above). |
mjr | 53:9b2611964afc | 605 | // |
mjr | 73:4e8ce0b18915 | 606 | // 11 -> TV ON relay manual control. This allows testing and operating the |
mjr | 73:4e8ce0b18915 | 607 | // relay from the PC. This doesn't change the power-up configuration; |
mjr | 88:98bce687e6c0 | 608 | // it merely allows the relay to be controlled directly. The third |
mjr | 88:98bce687e6c0 | 609 | // byte specifies the relay operation to perform: |
mjr | 73:4e8ce0b18915 | 610 | // |
mjr | 73:4e8ce0b18915 | 611 | // 0 = turn relay off |
mjr | 73:4e8ce0b18915 | 612 | // 1 = turn relay on |
mjr | 73:4e8ce0b18915 | 613 | // 2 = pulse the relay as though the power-on delay timer fired |
mjr | 73:4e8ce0b18915 | 614 | // |
mjr | 77:0b96f6867312 | 615 | // 12 -> Learn IR code. The device enters "IR learning mode". While in |
mjr | 77:0b96f6867312 | 616 | // learning mode, the device reports the raw signals read through |
mjr | 77:0b96f6867312 | 617 | // the IR sensor to the PC through the special IR learning report |
mjr | 77:0b96f6867312 | 618 | // (see "2G" above). If a signal can be decoded through a known |
mjr | 77:0b96f6867312 | 619 | // protocol, the device sends a final "2G" report with the decoded |
mjr | 77:0b96f6867312 | 620 | // command, then terminates learning mode. If no signal can be |
mjr | 77:0b96f6867312 | 621 | // decoded within a timeout period, the mode automatically ends, |
mjr | 77:0b96f6867312 | 622 | // and the device sends a final IR learning report with zero raw |
mjr | 77:0b96f6867312 | 623 | // signals to indicate termination. After initiating IR learning |
mjr | 77:0b96f6867312 | 624 | // mode, the user should point the remote control with the key to |
mjr | 77:0b96f6867312 | 625 | // be learned at the IR sensor on the KL25Z, and press and hold the |
mjr | 77:0b96f6867312 | 626 | // key on the remote for a few seconds. Holding the key for a few |
mjr | 77:0b96f6867312 | 627 | // moments is important because it lets the decoder sense the type |
mjr | 77:0b96f6867312 | 628 | // of auto-repeat coding the remote uses. The learned code can be |
mjr | 77:0b96f6867312 | 629 | // written to an IR config variable slot to program the controller |
mjr | 77:0b96f6867312 | 630 | // to send the learned command on events like TV ON or a button |
mjr | 77:0b96f6867312 | 631 | // press. |
mjr | 77:0b96f6867312 | 632 | // |
mjr | 78:1e00b3fa11af | 633 | // 13 -> Get button status report. The device sends one button status |
mjr | 78:1e00b3fa11af | 634 | // report in response (see section "2F" above). |
mjr | 78:1e00b3fa11af | 635 | // |
mjr | 78:1e00b3fa11af | 636 | // 14 -> Manually center the accelerometer. This sets the accelerometer |
mjr | 78:1e00b3fa11af | 637 | // zero point to the running average of readings over the past few |
mjr | 78:1e00b3fa11af | 638 | // seconds. |
mjr | 78:1e00b3fa11af | 639 | // |
mjr | 78:1e00b3fa11af | 640 | // 15 -> Set up ad hoc IR command, part 1. This sets up the first part |
mjr | 78:1e00b3fa11af | 641 | // of an IR command to transmit. The device stores the data in an |
mjr | 78:1e00b3fa11af | 642 | // internal register for later use in message 65 16. Send the |
mjr | 78:1e00b3fa11af | 643 | // remainder of the command data with 65 16. |
mjr | 78:1e00b3fa11af | 644 | // |
mjr | 78:1e00b3fa11af | 645 | // byte 3 = IR protocol ID |
mjr | 78:1e00b3fa11af | 646 | // byte 4 = flags (IRFlagXxx bit flags) |
mjr | 78:1e00b3fa11af | 647 | // byte 5-8 = low-order 32 bits of command code, little-endian |
mjr | 78:1e00b3fa11af | 648 | // |
mjr | 78:1e00b3fa11af | 649 | // 16 -> Finish and send an ad hoc IR command. Use message 65 15 first |
mjr | 78:1e00b3fa11af | 650 | // to set up the start of the command data, then send this message |
mjr | 78:1e00b3fa11af | 651 | // to fill in the rest of the data and transmit the command. Upon |
mjr | 78:1e00b3fa11af | 652 | // receiving this message, the device performs the transmission. |
mjr | 78:1e00b3fa11af | 653 | // |
mjr | 78:1e00b3fa11af | 654 | // byte 3-6 = high-order 32 bits of command code, little-endian |
mjr | 88:98bce687e6c0 | 655 | // |
mjr | 88:98bce687e6c0 | 656 | // 17 -> Send a pre-programmed IR command. This immediately transmits an |
mjr | 88:98bce687e6c0 | 657 | // IR code stored in a command slot. |
mjr | 88:98bce687e6c0 | 658 | // |
mjr | 88:98bce687e6c0 | 659 | // byte 3 = command number (1..MAX_IR_CODES) |
mjr | 78:1e00b3fa11af | 660 | // |
mjr | 73:4e8ce0b18915 | 661 | // |
mjr | 35:e959ffba78fd | 662 | // 66 -> Set configuration variable. The second byte of the message is the config |
mjr | 35:e959ffba78fd | 663 | // variable number, and the remaining bytes give the new value for the variable. |
mjr | 53:9b2611964afc | 664 | // The value format is specific to each variable; see the CONFIGURATION VARIABLES |
mjr | 53:9b2611964afc | 665 | // section below for a list of the variables and their formats. This command |
mjr | 53:9b2611964afc | 666 | // only sets the value in RAM; it doesn't write the value to flash and doesn't |
mjr | 53:9b2611964afc | 667 | // put the change into effect. To save the new settings, the host must send a |
mjr | 53:9b2611964afc | 668 | // type 65 subtype 6 message (see above). That saves the settings to flash and |
mjr | 53:9b2611964afc | 669 | // reboots the device, which makes the new settings active. |
mjr | 35:e959ffba78fd | 670 | // |
mjr | 74:822a92bc11d2 | 671 | // 67 -> "SBX". This is an extended form of the original LedWiz SBA message. This |
mjr | 74:822a92bc11d2 | 672 | // version is specifically designed to support a replacement LEDWIZ.DLL on the |
mjr | 74:822a92bc11d2 | 673 | // host that exposes one Pinscape device as multiple virtual LedWiz devices, |
mjr | 74:822a92bc11d2 | 674 | // in order to give legacy clients access to more than 32 ports. Each virtual |
mjr | 74:822a92bc11d2 | 675 | // LedWiz represents a block of 32 ports. The format of this message is the |
mjr | 74:822a92bc11d2 | 676 | // same as for the original SBA, with the addition of one byte: |
mjr | 74:822a92bc11d2 | 677 | // |
mjr | 74:822a92bc11d2 | 678 | // 67 xx xx xx xx ss pp 00 |
mjr | 74:822a92bc11d2 | 679 | // xx = on/off switches for 8 ports, one bit per port |
mjr | 74:822a92bc11d2 | 680 | // ss = global flash speed setting for this bank of ports, 1-7 |
mjr | 74:822a92bc11d2 | 681 | // pp = port group: 0 for ports 1-32, 1 for ports 33-64, etc |
mjr | 74:822a92bc11d2 | 682 | // 00 = unused/reserved; client should set to zero |
mjr | 74:822a92bc11d2 | 683 | // |
mjr | 74:822a92bc11d2 | 684 | // As with SBA, this sets the on/off switch states for a block of 32 ports. |
mjr | 74:822a92bc11d2 | 685 | // SBA always addresses ports 1-32; SBX can address any set of 32 ports. |
mjr | 74:822a92bc11d2 | 686 | // |
mjr | 74:822a92bc11d2 | 687 | // We keep a separate speed setting for each group of 32 ports. The purpose |
mjr | 74:822a92bc11d2 | 688 | // of the SBX extension is to allow a custom LEDWIZ.DLL to expose multiple |
mjr | 74:822a92bc11d2 | 689 | // virtual LedWiz units to legacy clients, so clients will expect each unit |
mjr | 74:822a92bc11d2 | 690 | // to have its separate flash speed setting. Each block of 32 ports maps to |
mjr | 74:822a92bc11d2 | 691 | // a virtual unit on the client side, so each block needs its own speed state. |
mjr | 74:822a92bc11d2 | 692 | // |
mjr | 74:822a92bc11d2 | 693 | // 68 -> "PBX". This is an extended form of the original LedWiz PBA message; it's |
mjr | 74:822a92bc11d2 | 694 | // the PBA equivalent of our SBX extension above. |
mjr | 74:822a92bc11d2 | 695 | // |
mjr | 74:822a92bc11d2 | 696 | // 68 pp ee ee ee ee ee ee |
mjr | 74:822a92bc11d2 | 697 | // pp = port group: 0 for ports 1-8, 1 for 9-16, etc |
mjr | 74:822a92bc11d2 | 698 | // qq = sequence number: 0 for the first 8 ports in the group, etc |
mjr | 74:822a92bc11d2 | 699 | // ee = brightness/flash values, 6 bits per port, packed into the bytes |
mjr | 74:822a92bc11d2 | 700 | // |
mjr | 74:822a92bc11d2 | 701 | // The port group 'pp' selects a group of 8 ports. Note that, unlike PBA, |
mjr | 74:822a92bc11d2 | 702 | // the port group being updated is explicitly coded in the message, which makes |
mjr | 74:822a92bc11d2 | 703 | // the message stateless. This eliminates any possibility of the client and |
mjr | 74:822a92bc11d2 | 704 | // host getting out of sync as to which ports they're talking about. This |
mjr | 74:822a92bc11d2 | 705 | // message doesn't affect the PBA port address state. |
mjr | 74:822a92bc11d2 | 706 | // |
mjr | 74:822a92bc11d2 | 707 | // The brightness values are *almost* the same as in PBA, but not quite. We |
mjr | 74:822a92bc11d2 | 708 | // remap the flashing state values as follows: |
mjr | 74:822a92bc11d2 | 709 | // |
mjr | 74:822a92bc11d2 | 710 | // 0-48 = brightness level, 0% to 100%, on a linear scale |
mjr | 74:822a92bc11d2 | 711 | // 49 = brightness level 100% (redundant with 48) |
mjr | 74:822a92bc11d2 | 712 | // 60 = PBA 129 equivalent, sawtooth |
mjr | 74:822a92bc11d2 | 713 | // 61 = PBA 130 equivalent, square wave (on/off) |
mjr | 74:822a92bc11d2 | 714 | // 62 = PBA 131 equivalent, on/fade down |
mjr | 74:822a92bc11d2 | 715 | // 63 = PBA 132 equivalent, fade up/on |
mjr | 74:822a92bc11d2 | 716 | // |
mjr | 74:822a92bc11d2 | 717 | // We reassign the brightness levels like this because it allows us to pack |
mjr | 74:822a92bc11d2 | 718 | // every possible value into 6 bits. This allows us to fit 8 port settings |
mjr | 74:822a92bc11d2 | 719 | // into six bytes. The 6-bit fields are packed into the 8 bytes consecutively |
mjr | 74:822a92bc11d2 | 720 | // starting with the low-order bit of the first byte. An efficient way to |
mjr | 74:822a92bc11d2 | 721 | // pack the 'ee' fields given the brightness values is to shift each group of |
mjr | 74:822a92bc11d2 | 722 | // four bytes into a uint, then shift the uint into three 'ee' bytes: |
mjr | 74:822a92bc11d2 | 723 | // |
mjr | 74:822a92bc11d2 | 724 | // unsigned int tmp1 = bri[0] | (bri[1]<<6) | (bri[2]<<12) | (bri[3]<<18); |
mjr | 74:822a92bc11d2 | 725 | // unsigned int tmp2 = bri[4] | (bri[5]<<6) | (bri[6]<<12) | (bri[7]<<18); |
mjr | 74:822a92bc11d2 | 726 | // unsigned char port_group = FIRST_PORT_TO_ADDRESS / 8; |
mjr | 74:822a92bc11d2 | 727 | // unsigned char msg[8] = { |
mjr | 74:822a92bc11d2 | 728 | // 68, pp, |
mjr | 74:822a92bc11d2 | 729 | // tmp1 & 0xFF, (tmp1 >> 8) & 0xFF, (tmp1 >> 16) & 0xFF, |
mjr | 74:822a92bc11d2 | 730 | // tmp2 & 0xFF, (tmp2 >> 8) & 0xFF, (tmp2 >> 16) & 0xFF |
mjr | 74:822a92bc11d2 | 731 | // }; |
mjr | 74:822a92bc11d2 | 732 | // |
mjr | 35:e959ffba78fd | 733 | // 200-228 -> Set extended output brightness. This sets outputs N to N+6 to the |
mjr | 35:e959ffba78fd | 734 | // respective brightness values in the 2nd through 8th bytes of the message |
mjr | 35:e959ffba78fd | 735 | // (output N is set to the 2nd byte value, N+1 is set to the 3rd byte value, |
mjr | 35:e959ffba78fd | 736 | // etc). Each brightness level is a linear brightness level from 0-255, |
mjr | 35:e959ffba78fd | 737 | // where 0 is 0% brightness and 255 is 100% brightness. N is calculated as |
mjr | 35:e959ffba78fd | 738 | // (first byte - 200)*7 + 1: |
mjr | 35:e959ffba78fd | 739 | // |
mjr | 35:e959ffba78fd | 740 | // 200 = outputs 1-7 |
mjr | 35:e959ffba78fd | 741 | // 201 = outputs 8-14 |
mjr | 35:e959ffba78fd | 742 | // 202 = outputs 15-21 |
mjr | 35:e959ffba78fd | 743 | // ... |
mjr | 35:e959ffba78fd | 744 | // 228 = outputs 197-203 |
mjr | 35:e959ffba78fd | 745 | // |
mjr | 53:9b2611964afc | 746 | // This message is the way to address ports 33 and higher. Original LedWiz |
mjr | 53:9b2611964afc | 747 | // protocol messages can't access ports above 32, since the protocol is |
mjr | 53:9b2611964afc | 748 | // hard-wired for exactly 32 ports. |
mjr | 35:e959ffba78fd | 749 | // |
mjr | 53:9b2611964afc | 750 | // Note that the extended output messages differ from regular LedWiz commands |
mjr | 35:e959ffba78fd | 751 | // in two ways. First, the brightness is the ONLY attribute when an output is |
mjr | 53:9b2611964afc | 752 | // set using this mode. There's no separate ON/OFF state per output as there |
mjr | 35:e959ffba78fd | 753 | // is with the SBA/PBA messages. To turn an output OFF with this message, set |
mjr | 35:e959ffba78fd | 754 | // the intensity to 0. Setting a non-zero intensity turns it on immediately |
mjr | 35:e959ffba78fd | 755 | // without regard to the SBA status for the port. Second, the brightness is |
mjr | 35:e959ffba78fd | 756 | // on a full 8-bit scale (0-255) rather than the LedWiz's approximately 5-bit |
mjr | 35:e959ffba78fd | 757 | // scale, because there are no parts of the range reserved for flashing modes. |
mjr | 35:e959ffba78fd | 758 | // |
mjr | 35:e959ffba78fd | 759 | // Outputs 1-32 can be controlled by EITHER the regular LedWiz SBA/PBA messages |
mjr | 35:e959ffba78fd | 760 | // or by the extended messages. The latest setting for a given port takes |
mjr | 35:e959ffba78fd | 761 | // precedence. If an SBA/PBA message was the last thing sent to a port, the |
mjr | 35:e959ffba78fd | 762 | // normal LedWiz combination of ON/OFF and brightness/flash mode status is used |
mjr | 35:e959ffba78fd | 763 | // to determine the port's physical output setting. If an extended brightness |
mjr | 35:e959ffba78fd | 764 | // message was the last thing sent to a port, the LedWiz ON/OFF status and |
mjr | 35:e959ffba78fd | 765 | // flash modes are ignored, and the fixed brightness is set. Outputs 33 and |
mjr | 35:e959ffba78fd | 766 | // higher inherently can't be addressed or affected by SBA/PBA messages. |
mjr | 53:9b2611964afc | 767 | // |
mjr | 53:9b2611964afc | 768 | // (The precedence scheme is designed to accommodate a mix of legacy and DOF |
mjr | 53:9b2611964afc | 769 | // software transparently. The behavior described is really just to ensure |
mjr | 53:9b2611964afc | 770 | // transparent interoperability; it's not something that host software writers |
mjr | 53:9b2611964afc | 771 | // should have to worry about. We expect that anyone writing new software will |
mjr | 53:9b2611964afc | 772 | // just use the extended protocol and ignore the old LedWiz commands, since |
mjr | 53:9b2611964afc | 773 | // the extended protocol is easier to use and more powerful.) |
mjr | 35:e959ffba78fd | 774 | |
mjr | 35:e959ffba78fd | 775 | |
mjr | 35:e959ffba78fd | 776 | // ------- CONFIGURATION VARIABLES ------- |
mjr | 35:e959ffba78fd | 777 | // |
mjr | 35:e959ffba78fd | 778 | // Message type 66 (see above) sets one configuration variable. The second byte |
mjr | 35:e959ffba78fd | 779 | // of the message is the variable ID, and the rest of the bytes give the new |
mjr | 35:e959ffba78fd | 780 | // value, in a variable-specific format. 16-bit values are little endian. |
mjr | 55:4db125cd11a0 | 781 | // Any bytes at the end of the message not otherwise specified are reserved |
mjr | 55:4db125cd11a0 | 782 | // for future use and should always be set to 0 in the message data. |
mjr | 35:e959ffba78fd | 783 | // |
mjr | 77:0b96f6867312 | 784 | // Variable IDs: |
mjr | 77:0b96f6867312 | 785 | // |
mjr | 53:9b2611964afc | 786 | // 0 -> QUERY ONLY: Describe the configuration variables. The device |
mjr | 53:9b2611964afc | 787 | // sends a config variable query report with the following fields: |
mjr | 53:9b2611964afc | 788 | // |
mjr | 53:9b2611964afc | 789 | // byte 3 -> number of scalar (non-array) variables (these are |
mjr | 53:9b2611964afc | 790 | // numbered sequentially from 1 to N) |
mjr | 53:9b2611964afc | 791 | // byte 4 -> number of array variables (these are numbered |
mjr | 53:9b2611964afc | 792 | // sequentially from 256-N to 255) |
mjr | 53:9b2611964afc | 793 | // |
mjr | 53:9b2611964afc | 794 | // The description query is meant to allow the host to capture all |
mjr | 53:9b2611964afc | 795 | // configuration settings on the device without having to know what |
mjr | 53:9b2611964afc | 796 | // the variables mean or how many there are. This is useful for |
mjr | 53:9b2611964afc | 797 | // backing up the settings in a file on the PC, for example, or for |
mjr | 53:9b2611964afc | 798 | // capturing them to restore after a firmware update. This allows |
mjr | 53:9b2611964afc | 799 | // more flexible interoperability between unsynchronized versions |
mjr | 53:9b2611964afc | 800 | // of the firmware and the host software. |
mjr | 53:9b2611964afc | 801 | // |
mjr | 53:9b2611964afc | 802 | // 1 -> USB device ID. This sets the USB vendor and product ID codes |
mjr | 53:9b2611964afc | 803 | // to use when connecting to the PC. For LedWiz emulation, use |
mjr | 35:e959ffba78fd | 804 | // vendor 0xFAFA and product 0x00EF + unit# (where unit# is the |
mjr | 53:9b2611964afc | 805 | // nominal LedWiz unit number, from 1 to 16). If you have any |
mjr | 53:9b2611964afc | 806 | // REAL LedWiz units in your system, we recommend starting the |
mjr | 53:9b2611964afc | 807 | // Pinscape LedWiz numbering at 8 to avoid conflicts with the |
mjr | 53:9b2611964afc | 808 | // real LedWiz units. If you don't have any real LedWiz units, |
mjr | 53:9b2611964afc | 809 | // you can number your Pinscape units starting from 1. |
mjr | 35:e959ffba78fd | 810 | // |
mjr | 53:9b2611964afc | 811 | // If LedWiz emulation isn't desired or causes host conflicts, |
mjr | 53:9b2611964afc | 812 | // use our private ID: Vendor 0x1209, product 0xEAEA. (These IDs |
mjr | 53:9b2611964afc | 813 | // are registered with http://pid.codes, a registry for open-source |
mjr | 53:9b2611964afc | 814 | // USB devices, so they're guaranteed to be free of conflicts with |
mjr | 53:9b2611964afc | 815 | // other properly registered devices). The device will NOT appear |
mjr | 53:9b2611964afc | 816 | // as an LedWiz if you use the private ID codes, but DOF (R3 or |
mjr | 53:9b2611964afc | 817 | // later) will still recognize it as a Pinscape controller. |
mjr | 53:9b2611964afc | 818 | // |
mjr | 53:9b2611964afc | 819 | // bytes 3:4 -> USB Vendor ID |
mjr | 53:9b2611964afc | 820 | // bytes 5:6 -> USB Product ID |
mjr | 53:9b2611964afc | 821 | // |
mjr | 53:9b2611964afc | 822 | // 2 -> Pinscape Controller unit number for DOF. The Pinscape unit |
mjr | 53:9b2611964afc | 823 | // number is independent of the LedWiz unit number, and indepedent |
mjr | 53:9b2611964afc | 824 | // of the USB vendor/product IDs. DOF (R3 and later) uses this to |
mjr | 53:9b2611964afc | 825 | // identify the unit for the extended Pinscape functionality. |
mjr | 53:9b2611964afc | 826 | // For easiest DOF configuration, we recommend numbering your |
mjr | 53:9b2611964afc | 827 | // units sequentially starting at 1 (regardless of whether or not |
mjr | 53:9b2611964afc | 828 | // you have any real LedWiz units). |
mjr | 53:9b2611964afc | 829 | // |
mjr | 53:9b2611964afc | 830 | // byte 3 -> unit number, from 1 to 16 |
mjr | 35:e959ffba78fd | 831 | // |
mjr | 90:aa4e571da8e8 | 832 | // 3 -> Joystick report settings. |
mjr | 55:4db125cd11a0 | 833 | // |
mjr | 92:f264fbaa1be5 | 834 | // byte 3 -> Enable joystick interface: 1 to enable, 0 to disable |
mjr | 92:f264fbaa1be5 | 835 | // byte 4 -> Joystick axis format, as a USBJoystick::AXIS_FORMAT_XXX value |
mjr | 92:f264fbaa1be5 | 836 | // bytes 5:8 -> Reporting interval in microseconds |
mjr | 35:e959ffba78fd | 837 | // |
mjr | 55:4db125cd11a0 | 838 | // When joystick reports are disabled, the device registers as a generic HID |
mjr | 55:4db125cd11a0 | 839 | // device, and only sends the private report types used by the Windows config |
mjr | 55:4db125cd11a0 | 840 | // tool. It won't appear to Windows as a USB game controller or joystick. |
mjr | 55:4db125cd11a0 | 841 | // |
mjr | 55:4db125cd11a0 | 842 | // Note that this doesn't affect whether the device also registers a keyboard |
mjr | 55:4db125cd11a0 | 843 | // interface. A keyboard interface will appear if and only if any buttons |
mjr | 55:4db125cd11a0 | 844 | // (including virtual buttons, such as the ZB Launch Ball feature) are assigned |
mjr | 55:4db125cd11a0 | 845 | // to generate keyboard key input. |
mjr | 55:4db125cd11a0 | 846 | // |
mjr | 77:0b96f6867312 | 847 | // 4 -> Accelerometer settings |
mjr | 35:e959ffba78fd | 848 | // |
mjr | 55:4db125cd11a0 | 849 | // byte 3 -> orientation: |
mjr | 55:4db125cd11a0 | 850 | // 0 = ports at front (USB ports pointing towards front of cabinet) |
mjr | 55:4db125cd11a0 | 851 | // 1 = ports at left |
mjr | 55:4db125cd11a0 | 852 | // 2 = ports at right |
mjr | 55:4db125cd11a0 | 853 | // 3 = ports at rear |
mjr | 77:0b96f6867312 | 854 | // byte 4 -> dynamic range |
mjr | 78:1e00b3fa11af | 855 | // 0 = +/- 1G (2G hardware mode, but rescales joystick reports to 1G |
mjr | 78:1e00b3fa11af | 856 | // range; compatible with older versions) |
mjr | 77:0b96f6867312 | 857 | // 1 = +/- 2G (2G hardware mode) |
mjr | 77:0b96f6867312 | 858 | // 2 = +/- 4G (4G hardware mode) |
mjr | 77:0b96f6867312 | 859 | // 3 = +/- 8G (8G hardware mode) |
mjr | 78:1e00b3fa11af | 860 | // byte 5 -> Auto-centering mode |
mjr | 78:1e00b3fa11af | 861 | // 0 = auto-centering on, 5 second timer (default, compatible |
mjr | 78:1e00b3fa11af | 862 | // with older versions) |
mjr | 78:1e00b3fa11af | 863 | // 1-60 = auto-centering on with the given time in seconds |
mjr | 78:1e00b3fa11af | 864 | // 61-245 = reserved |
mjr | 78:1e00b3fa11af | 865 | // 255 = auto-centering off; manual centering only |
mjr | 92:f264fbaa1be5 | 866 | // byte 6 -> joystick report stutter count: 1 (or 0) means that we |
mjr | 92:f264fbaa1be5 | 867 | // take a fresh accelerometer on every joystick report; 2 means |
mjr | 92:f264fbaa1be5 | 868 | // that we take a new reading on every other report, and repeat |
mjr | 92:f264fbaa1be5 | 869 | // the prior readings on alternate reports; etc |
mjr | 55:4db125cd11a0 | 870 | // |
mjr | 55:4db125cd11a0 | 871 | // 5 -> Plunger sensor type. |
mjr | 35:e959ffba78fd | 872 | // |
mjr | 55:4db125cd11a0 | 873 | // byte 3 -> plunger type: |
mjr | 55:4db125cd11a0 | 874 | // 0 = none (disabled) |
mjr | 82:4f6209cb5c33 | 875 | // 1 = TSL1410R linear image sensor, 1280x1 pixels, serial mode, edge detection |
mjr | 82:4f6209cb5c33 | 876 | // 3 = TSL1412R linear image sensor, 1536x1 pixels, serial mode, edge detection |
mjr | 55:4db125cd11a0 | 877 | // 5 = Potentiometer with linear taper, or any other device that |
mjr | 55:4db125cd11a0 | 878 | // represents the position reading with a single analog voltage |
mjr | 82:4f6209cb5c33 | 879 | // 6 = AEDR8300 optical quadrature sensor, 75lpi |
mjr | 55:4db125cd11a0 | 880 | // *7 = AS5304 magnetic quadrature sensor, 160 steps per 2mm |
mjr | 82:4f6209cb5c33 | 881 | // 8 = TSL1401CL linear image sensor, 128x1 pixel, bar code detection |
mjr | 82:4f6209cb5c33 | 882 | // 9 = VL6180X time-of-flight distance sensor |
mjr | 100:1ff35c07217c | 883 | // **10 = AEAT-6012-A06 magnetic rotary encoder |
mjr | 100:1ff35c07217c | 884 | // **11 = TCD1103GFG Toshiba linear CCD, 1500x1 pixels, edge detection |
mjr | 111:42dc75fbe623 | 885 | // **12 = VCNL4010 Vishay IR proximity sensor |
mjr | 55:4db125cd11a0 | 886 | // |
mjr | 113:7330439f2ffc | 887 | // byte 4 -> extra sensor-speicifc parameter data |
mjr | 113:7330439f2ffc | 888 | // VCNL4010 - IRED current, in units of 10mA, valid range 1..20 |
mjr | 113:7330439f2ffc | 889 | // |
mjr | 55:4db125cd11a0 | 890 | // * The sensor types marked with asterisks (*) are reserved for types |
mjr | 55:4db125cd11a0 | 891 | // that aren't currently implemented but could be added in the future. |
mjr | 100:1ff35c07217c | 892 | // Selecting these types will effectively disable the plunger. |
mjr | 100:1ff35c07217c | 893 | // |
mjr | 113:7330439f2ffc | 894 | // ** The sensor types marked with double asterisks (**) are |
mjr | 113:7330439f2ffc | 895 | // Experimental, meaning that the code isn't finished yet and isn't |
mjr | 113:7330439f2ffc | 896 | // meant for use in a live pin cab. |
mjr | 100:1ff35c07217c | 897 | // |
mjr | 100:1ff35c07217c | 898 | // Sensor types 2 and 4 were formerly reserved for TSL14xx sensors in |
mjr | 100:1ff35c07217c | 899 | // parallel wiring mode, but support for these is no longer planned, as |
mjr | 100:1ff35c07217c | 900 | // the KL25Z's single ADC sampler negates any speed advantage from using |
mjr | 100:1ff35c07217c | 901 | // the sensors' parallel mode. Those slots could be reassigned for |
mjr | 100:1ff35c07217c | 902 | // other sensors, since they were never enabled in any release version. |
mjr | 55:4db125cd11a0 | 903 | // |
mjr | 55:4db125cd11a0 | 904 | // 6 -> Plunger pin assignments. |
mjr | 47:df7a88cd249c | 905 | // |
mjr | 55:4db125cd11a0 | 906 | // byte 3 -> pin assignment 1 |
mjr | 55:4db125cd11a0 | 907 | // byte 4 -> pin assignment 2 |
mjr | 113:7330439f2ffc | 908 | // byte 5 -> pin assignment 3/misc |
mjr | 113:7330439f2ffc | 909 | // byte 6 -> pin assignment 4/misc |
mjr | 55:4db125cd11a0 | 910 | // |
mjr | 55:4db125cd11a0 | 911 | // All of the pins use the standard GPIO port format (see "GPIO pin number |
mjr | 55:4db125cd11a0 | 912 | // mappings" below). The actual use of the four pins depends on the plunger |
mjr | 55:4db125cd11a0 | 913 | // type, as shown below. "NC" means that the pin isn't used at all for the |
mjr | 82:4f6209cb5c33 | 914 | // corresponding plunger type. "GPIO" means that any GPIO pin will work. |
mjr | 100:1ff35c07217c | 915 | // AnalogIn, InterruptIn, and PWM mean that only pins with the respective |
mjr | 82:4f6209cb5c33 | 916 | // capabilities can be chosen. |
mjr | 35:e959ffba78fd | 917 | // |
mjr | 113:7330439f2ffc | 918 | // Plunger Type Pin 1 Pin 2 Pin 3/Misc Pin 4 |
mjr | 35:e959ffba78fd | 919 | // |
mjr | 82:4f6209cb5c33 | 920 | // TSL1410R/1412R/1401CL SI (GPIO) CLK (GPIO) AO (AnalogIn) NC |
mjr | 55:4db125cd11a0 | 921 | // Potentiometer AO (AnalogIn) NC NC NC |
mjr | 55:4db125cd11a0 | 922 | // AEDR8300 A (InterruptIn) B (InterruptIn) NC NC |
mjr | 55:4db125cd11a0 | 923 | // AS5304 A (InterruptIn) B (InterruptIn) NC NC |
mjr | 82:4f6209cb5c33 | 924 | // VL6180X SDA (GPIO) SCL (GPIO) GPIO0/CE (GPIO) NC |
mjr | 100:1ff35c07217c | 925 | // AEAT-6012-A06 CS (GPIO) CLK (GPIO) DO (GPIO) NC |
mjr | 100:1ff35c07217c | 926 | // TCD1103GFG fM (PWM) OS (AnalogIn) ICG (GPIO) SH (GPIO) |
mjr | 111:42dc75fbe623 | 927 | // VCNL4010 SDA (GPIO) SCL (GPIO) NC NC |
mjr | 55:4db125cd11a0 | 928 | // |
mjr | 55:4db125cd11a0 | 929 | // 7 -> Plunger calibration button pin assignments. |
mjr | 35:e959ffba78fd | 930 | // |
mjr | 55:4db125cd11a0 | 931 | // byte 3 -> features enabled/disabled: bit mask consisting of: |
mjr | 55:4db125cd11a0 | 932 | // 0x01 button input is enabled |
mjr | 55:4db125cd11a0 | 933 | // 0x02 lamp output is enabled |
mjr | 55:4db125cd11a0 | 934 | // byte 4 -> DigitalIn pin for the button switch |
mjr | 55:4db125cd11a0 | 935 | // byte 5 -> DigitalOut pin for the indicator lamp |
mjr | 55:4db125cd11a0 | 936 | // |
mjr | 55:4db125cd11a0 | 937 | // Note that setting a pin to NC (Not Connected) will disable it even if the |
mjr | 55:4db125cd11a0 | 938 | // corresponding feature enable bit (in byte 3) is set. |
mjr | 35:e959ffba78fd | 939 | // |
mjr | 55:4db125cd11a0 | 940 | // 8 -> ZB Launch Ball setup. This configures the ZB Launch Ball feature. |
mjr | 55:4db125cd11a0 | 941 | // |
mjr | 55:4db125cd11a0 | 942 | // byte 3 -> LedWiz port number (1-255) mapped to "ZB Launch Ball" in DOF |
mjr | 55:4db125cd11a0 | 943 | // byte 4 -> key type |
mjr | 55:4db125cd11a0 | 944 | // byte 5 -> key code |
mjr | 55:4db125cd11a0 | 945 | // bytes 6:7 -> "push" distance, in 1/1000 inch increments (16 bit little endian) |
mjr | 55:4db125cd11a0 | 946 | // |
mjr | 55:4db125cd11a0 | 947 | // Set the port number to 0 to disable the feature. The key type and key code |
mjr | 55:4db125cd11a0 | 948 | // fields use the same conventions as for a button mapping (see below). The |
mjr | 55:4db125cd11a0 | 949 | // recommended push distance is 63, which represents .063" ~ 1/16". |
mjr | 35:e959ffba78fd | 950 | // |
mjr | 35:e959ffba78fd | 951 | // 9 -> TV ON relay setup. This requires external circuitry implemented on the |
mjr | 35:e959ffba78fd | 952 | // Expansion Board (or an equivalent circuit as described in the Build Guide). |
mjr | 55:4db125cd11a0 | 953 | // |
mjr | 55:4db125cd11a0 | 954 | // byte 3 -> "power status" input pin (DigitalIn) |
mjr | 55:4db125cd11a0 | 955 | // byte 4 -> "latch" output (DigitalOut) |
mjr | 55:4db125cd11a0 | 956 | // byte 5 -> relay trigger output (DigitalOut) |
mjr | 55:4db125cd11a0 | 957 | // bytes 6:7 -> delay time in 10ms increments (16 bit little endian); |
mjr | 55:4db125cd11a0 | 958 | // e.g., 550 (0x26 0x02) represents 5.5 seconds |
mjr | 55:4db125cd11a0 | 959 | // |
mjr | 55:4db125cd11a0 | 960 | // Set the delay time to 0 to disable the feature. The pin assignments will |
mjr | 55:4db125cd11a0 | 961 | // be ignored if the feature is disabled. |
mjr | 35:e959ffba78fd | 962 | // |
mjr | 77:0b96f6867312 | 963 | // If an IR remote control transmitter is installed (see variable 17), we'll |
mjr | 77:0b96f6867312 | 964 | // also transmit any IR codes designated as TV ON codes when the startup timer |
mjr | 77:0b96f6867312 | 965 | // finishes. This allows TVs to be turned on via IR remotes codes rather than |
mjr | 77:0b96f6867312 | 966 | // hard-wiring them through the relay. The relay can be omitted in this case. |
mjr | 77:0b96f6867312 | 967 | // |
mjr | 87:8d35c74403af | 968 | // 10 -> TLC5940NT setup. This chip is an external PWM controller, with 16 outputs |
mjr | 35:e959ffba78fd | 969 | // per chip and a serial data interface that allows the chips to be daisy- |
mjr | 35:e959ffba78fd | 970 | // chained. We can use these chips to add an arbitrary number of PWM output |
mjr | 55:4db125cd11a0 | 971 | // ports for the LedWiz emulation. |
mjr | 55:4db125cd11a0 | 972 | // |
mjr | 35:e959ffba78fd | 973 | // byte 3 = number of chips attached (connected in daisy chain) |
mjr | 35:e959ffba78fd | 974 | // byte 4 = SIN pin - Serial data (must connect to SPIO MOSI -> PTC6 or PTD2) |
mjr | 35:e959ffba78fd | 975 | // byte 5 = SCLK pin - Serial clock (must connect to SPIO SCLK -> PTC5 or PTD1) |
mjr | 35:e959ffba78fd | 976 | // byte 6 = XLAT pin - XLAT (latch) signal (any GPIO pin) |
mjr | 35:e959ffba78fd | 977 | // byte 7 = BLANK pin - BLANK signal (any GPIO pin) |
mjr | 35:e959ffba78fd | 978 | // byte 8 = GSCLK pin - Grayscale clock signal (must be a PWM-out capable pin) |
mjr | 35:e959ffba78fd | 979 | // |
mjr | 55:4db125cd11a0 | 980 | // Set the number of chips to 0 to disable the feature. The pin assignments are |
mjr | 55:4db125cd11a0 | 981 | // ignored if the feature is disabled. |
mjr | 55:4db125cd11a0 | 982 | // |
mjr | 35:e959ffba78fd | 983 | // 11 -> 74HC595 setup. This chip is an external shift register, with 8 outputs per |
mjr | 35:e959ffba78fd | 984 | // chip and a serial data interface that allows daisy-chaining. We use this |
mjr | 35:e959ffba78fd | 985 | // chips to add extra digital outputs for the LedWiz emulation. In particular, |
mjr | 35:e959ffba78fd | 986 | // the Chime Board (part of the Expansion Board suite) uses these to add timer- |
mjr | 55:4db125cd11a0 | 987 | // protected outputs for coil devices (knockers, chimes, bells, etc). |
mjr | 55:4db125cd11a0 | 988 | // |
mjr | 35:e959ffba78fd | 989 | // byte 3 = number of chips attached (connected in daisy chain) |
mjr | 35:e959ffba78fd | 990 | // byte 4 = SIN pin - Serial data (any GPIO pin) |
mjr | 35:e959ffba78fd | 991 | // byte 5 = SCLK pin - Serial clock (any GPIO pin) |
mjr | 35:e959ffba78fd | 992 | // byte 6 = LATCH pin - LATCH signal (any GPIO pin) |
mjr | 35:e959ffba78fd | 993 | // byte 7 = ENA pin - ENABLE signal (any GPIO pin) |
mjr | 35:e959ffba78fd | 994 | // |
mjr | 55:4db125cd11a0 | 995 | // Set the number of chips to 0 to disable the feature. The pin assignments are |
mjr | 55:4db125cd11a0 | 996 | // ignored if the feature is disabled. |
mjr | 55:4db125cd11a0 | 997 | // |
mjr | 53:9b2611964afc | 998 | // 12 -> Disconnect reboot timeout. The reboot timeout allows the controller software |
mjr | 51:57eb311faafa | 999 | // to automatically reboot the KL25Z after it detects that the USB connection is |
mjr | 51:57eb311faafa | 1000 | // broken. On some hosts, the device isn't able to reconnect after the initial |
mjr | 51:57eb311faafa | 1001 | // connection is lost. The reboot timeout is a workaround for these cases. When |
mjr | 51:57eb311faafa | 1002 | // the software detects that the connection is no longer active, it will reboot |
mjr | 51:57eb311faafa | 1003 | // the KL25Z automatically if a new connection isn't established within the |
mjr | 55:4db125cd11a0 | 1004 | // timeout period. Set the timeout to 0 to disable the feature (i.e., the device |
mjr | 55:4db125cd11a0 | 1005 | // will never automatically reboot itself on a broken connection). |
mjr | 55:4db125cd11a0 | 1006 | // |
mjr | 55:4db125cd11a0 | 1007 | // byte 3 -> reboot timeout in seconds; 0 = disabled |
mjr | 51:57eb311faafa | 1008 | // |
mjr | 53:9b2611964afc | 1009 | // 13 -> Plunger calibration. In most cases, the calibration is set internally by the |
mjr | 52:8298b2a73eb2 | 1010 | // device by running the calibration procedure. However, it's sometimes useful |
mjr | 52:8298b2a73eb2 | 1011 | // for the host to be able to get and set the calibration, such as to back up |
mjr | 52:8298b2a73eb2 | 1012 | // the device settings on the PC, or to save and restore the current settings |
mjr | 52:8298b2a73eb2 | 1013 | // when installing a software update. |
mjr | 52:8298b2a73eb2 | 1014 | // |
mjr | 52:8298b2a73eb2 | 1015 | // bytes 3:4 = rest position (unsigned 16-bit little-endian) |
mjr | 52:8298b2a73eb2 | 1016 | // bytes 5:6 = maximum retraction point (unsigned 16-bit little-endian) |
mjr | 52:8298b2a73eb2 | 1017 | // byte 7 = measured plunger release travel time in milliseconds |
mjr | 52:8298b2a73eb2 | 1018 | // |
mjr | 53:9b2611964afc | 1019 | // 14 -> Expansion board configuration. This doesn't affect the controller behavior |
mjr | 52:8298b2a73eb2 | 1020 | // directly; the individual options related to the expansion boards (such as |
mjr | 52:8298b2a73eb2 | 1021 | // the TLC5940 and 74HC595 setup) still need to be set separately. This is |
mjr | 52:8298b2a73eb2 | 1022 | // stored so that the PC config UI can store and recover the information to |
mjr | 52:8298b2a73eb2 | 1023 | // present in the UI. For the "classic" KL25Z-only configuration, simply set |
mjr | 52:8298b2a73eb2 | 1024 | // all of the fields to zero. |
mjr | 52:8298b2a73eb2 | 1025 | // |
mjr | 53:9b2611964afc | 1026 | // byte 3 = board set type. At the moment, the Pinscape expansion boards |
mjr | 53:9b2611964afc | 1027 | // are the only ones supported in the software. This allows for |
mjr | 53:9b2611964afc | 1028 | // adding new designs or independent designs in the future. |
mjr | 53:9b2611964afc | 1029 | // 0 = Standalone KL25Z (no expansion boards) |
mjr | 105:6a25bbfae1e4 | 1030 | // 1 = Pinscape Expansion Boards |
mjr | 115:39d2eb4b1830 | 1031 | // 2 = Oak Micros Pinscape All-In-One (AIO) Board |
mjr | 115:39d2eb4b1830 | 1032 | // 3 = Oak Micros Pinscape Lite Board |
arnoz | 116:7a67265d7c19 | 1033 | // 4 = Arnoz RigMaster Board |
arnoz | 116:7a67265d7c19 | 1034 | // 5 = Arnoz KLShield Board |
mjr | 53:9b2611964afc | 1035 | // |
mjr | 53:9b2611964afc | 1036 | // byte 4 = board set interface revision. This *isn't* the version number |
mjr | 53:9b2611964afc | 1037 | // of the board itself, but rather of its software interface. In |
mjr | 53:9b2611964afc | 1038 | // other words, this doesn't change every time the EAGLE layout |
mjr | 53:9b2611964afc | 1039 | // for the board changes. It only changes when a revision is made |
mjr | 53:9b2611964afc | 1040 | // that affects the software, such as a GPIO pin assignment. |
mjr | 53:9b2611964afc | 1041 | // |
mjr | 115:39d2eb4b1830 | 1042 | // For Pinscape Expansion Boards (board set type 1): |
mjr | 55:4db125cd11a0 | 1043 | // 0 = first release (Feb 2016) |
mjr | 53:9b2611964afc | 1044 | // |
mjr | 115:39d2eb4b1830 | 1045 | // For Oak Micros AIO (type 2): |
mjr | 105:6a25bbfae1e4 | 1046 | // 0 = first release (2019) |
mjr | 105:6a25bbfae1e4 | 1047 | // |
mjr | 115:39d2eb4b1830 | 1048 | // For Oak Micros Lite (type 3): |
mjr | 115:39d2eb4b1830 | 1049 | // 0 = first release |
mjr | 115:39d2eb4b1830 | 1050 | // |
arnoz | 116:7a67265d7c19 | 1051 | // For Arnoz RigMaster (type 4): |
arnoz | 116:7a67265d7c19 | 1052 | // 0 = first release (2021) |
arnoz | 116:7a67265d7c19 | 1053 | // |
arnoz | 116:7a67265d7c19 | 1054 | // For Arnoz KLShield (type 5): |
mjr | 115:39d2eb4b1830 | 1055 | // 0 = first release (2021) |
mjr | 115:39d2eb4b1830 | 1056 | // |
mjr | 55:4db125cd11a0 | 1057 | // bytes 5:8 = additional hardware-specific data. These slots are used |
mjr | 55:4db125cd11a0 | 1058 | // to store extra data specific to the expansion boards selected. |
mjr | 55:4db125cd11a0 | 1059 | // |
arnoz | 116:7a67265d7c19 | 1060 | // For Pinscape Expansion Boards (board set type 1), |
arnoz | 116:7a67265d7c19 | 1061 | // Oak Micros AIO (type 2), Arnoz RigMaster (type 4), and |
arnoz | 116:7a67265d7c19 | 1062 | // Arnoz KLShield (type 5): |
mjr | 105:6a25bbfae1e4 | 1063 | // byte 5 = number of main interface or AIO boards (always 1) |
mjr | 55:4db125cd11a0 | 1064 | // byte 6 = number of MOSFET power boards |
mjr | 55:4db125cd11a0 | 1065 | // byte 7 = number of chime boards |
arnoz | 116:7a67265d7c19 | 1066 | // byte 8 = number of Mollusk boards |
mjr | 105:6a25bbfae1e4 | 1067 | // |
mjr | 53:9b2611964afc | 1068 | // |
mjr | 53:9b2611964afc | 1069 | // 15 -> Night mode setup. |
mjr | 53:9b2611964afc | 1070 | // |
mjr | 53:9b2611964afc | 1071 | // byte 3 = button number - 1..MAX_BUTTONS, or 0 for none. This selects |
mjr | 53:9b2611964afc | 1072 | // a physically wired button that can be used to control night mode. |
mjr | 53:9b2611964afc | 1073 | // The button can also be used as normal for PC input if desired. |
mjr | 55:4db125cd11a0 | 1074 | // Note that night mode can still be activated via a USB command |
mjr | 55:4db125cd11a0 | 1075 | // even if no button is assigned. |
mjr | 55:4db125cd11a0 | 1076 | // |
mjr | 53:9b2611964afc | 1077 | // byte 4 = flags: |
mjr | 66:2e3583fbd2f4 | 1078 | // |
mjr | 66:2e3583fbd2f4 | 1079 | // 0x01 -> The wired input is an on/off switch: night mode will be |
mjr | 53:9b2611964afc | 1080 | // active when the input is switched on. If this bit isn't |
mjr | 66:2e3583fbd2f4 | 1081 | // set, the input is a momentary button: pushing the button |
mjr | 53:9b2611964afc | 1082 | // toggles night mode. |
mjr | 55:4db125cd11a0 | 1083 | // |
mjr | 66:2e3583fbd2f4 | 1084 | // 0x02 -> Night Mode is assigned to the SHIFTED button (see Shift |
mjr | 66:2e3583fbd2f4 | 1085 | // Button setup at variable 16). This can only be used |
mjr | 66:2e3583fbd2f4 | 1086 | // in momentary mode; it's ignored if flag bit 0x01 is set. |
mjr | 66:2e3583fbd2f4 | 1087 | // When the shift flag is set, the button only toggles |
mjr | 66:2e3583fbd2f4 | 1088 | // night mode when you press it while also holding down |
mjr | 66:2e3583fbd2f4 | 1089 | // the Shift button. |
mjr | 66:2e3583fbd2f4 | 1090 | // |
mjr | 53:9b2611964afc | 1091 | // byte 5 = indicator output number - 1..MAX_OUT_PORTS, or 0 for none. This |
mjr | 53:9b2611964afc | 1092 | // selects an output port that will be turned on when night mode is |
mjr | 53:9b2611964afc | 1093 | // activated. Night mode activation overrides any setting made by |
mjr | 53:9b2611964afc | 1094 | // the host. |
mjr | 53:9b2611964afc | 1095 | // |
mjr | 66:2e3583fbd2f4 | 1096 | // 16 -> Shift Button setup. One button can be designated as a "Local Shift |
mjr | 66:2e3583fbd2f4 | 1097 | // Button" that can be pressed to select a secondary meaning for other |
mjr | 78:1e00b3fa11af | 1098 | // buttons. This isn't the same as the PC keyboard Shift keys; those can |
mjr | 66:2e3583fbd2f4 | 1099 | // be programmed using the USB key codes for Left Shift and Right Shift. |
mjr | 66:2e3583fbd2f4 | 1100 | // Rather, this applies a LOCAL shift feature in the cabinet button that |
mjr | 66:2e3583fbd2f4 | 1101 | // lets you select a secondary meaning. For example, you could assign |
mjr | 66:2e3583fbd2f4 | 1102 | // the Start button to the "1" key (VP "Start Game") normally, but have |
mjr | 66:2e3583fbd2f4 | 1103 | // its meaning change to the "5" key ("Insert Coin") when the shift |
mjr | 66:2e3583fbd2f4 | 1104 | // button is pressed. This provides access to more control functions |
mjr | 66:2e3583fbd2f4 | 1105 | // without adding more physical buttons. |
mjr | 66:2e3583fbd2f4 | 1106 | // |
mjr | 78:1e00b3fa11af | 1107 | // byte 3 = button number - 1..MAX_BUTTONS, or 0 for none |
mjr | 78:1e00b3fa11af | 1108 | // byte 4 = mode (default is 0): |
mjr | 66:2e3583fbd2f4 | 1109 | // |
mjr | 78:1e00b3fa11af | 1110 | // 0 -> Shift OR Key mode. In this mode, the Shift button doesn't |
mjr | 78:1e00b3fa11af | 1111 | // send its assigned key or IR command when initially pressed. |
mjr | 78:1e00b3fa11af | 1112 | // Instead, we wait to see if another button is pressed while |
mjr | 78:1e00b3fa11af | 1113 | // the Shift button is held down. If so, this Shift button |
mjr | 78:1e00b3fa11af | 1114 | // press ONLY counts as the Shift function, and its own assigned |
mjr | 78:1e00b3fa11af | 1115 | // key is NOT sent to the PC. On the other hand, if you press |
mjr | 78:1e00b3fa11af | 1116 | // the Shift button and then release it without having pressed |
mjr | 78:1e00b3fa11af | 1117 | // any other key in the meantime, this press counts as a regular |
mjr | 78:1e00b3fa11af | 1118 | // key press, so we send the assigned key to the PC. |
mjr | 78:1e00b3fa11af | 1119 | // |
mjr | 78:1e00b3fa11af | 1120 | // 1 -> Shift AND Key mode. In this mode, the Shift button sends its |
mjr | 78:1e00b3fa11af | 1121 | // assigned key when pressed, just like a normal button. If you |
mjr | 78:1e00b3fa11af | 1122 | // press another button while the Shift key is pressed, the |
mjr | 78:1e00b3fa11af | 1123 | // shifted meaning of the other key is used. |
mjr | 66:2e3583fbd2f4 | 1124 | // |
mjr | 77:0b96f6867312 | 1125 | // 17 -> IR Remote Control physical device setup. We support IR remotes for |
mjr | 77:0b96f6867312 | 1126 | // both sending and receiving. On the receive side, we can read from a |
mjr | 77:0b96f6867312 | 1127 | // sensor such as a TSOP384xx. The sensor requires one GPIO pin with |
mjr | 77:0b96f6867312 | 1128 | // interrupt support, so any PTAxx or PTDxx pin will work. On the send |
mjr | 77:0b96f6867312 | 1129 | // side, we can transmit through any IR LED. This requires one PWM |
mjr | 77:0b96f6867312 | 1130 | // output pin. To enable send and/or receive, specify a valid pin; to |
mjr | 77:0b96f6867312 | 1131 | // disable, set the pin NC (not connected). Send and receive can be |
mjr | 77:0b96f6867312 | 1132 | // enabled and disabled independently; it's not necessary to enable |
mjr | 77:0b96f6867312 | 1133 | // the transmit function to use the receive function, or vice versa. |
mjr | 77:0b96f6867312 | 1134 | // |
mjr | 77:0b96f6867312 | 1135 | // byte 3 = receiver input GPIO pin ID. Must be interrupt-capable. |
mjr | 77:0b96f6867312 | 1136 | // byte 4 = transmitter pin. Must be PWM-capable. |
mjr | 77:0b96f6867312 | 1137 | // |
mjr | 82:4f6209cb5c33 | 1138 | // 18 -> Plunger auto-zeroing. This only applies to sensor types with |
mjr | 82:4f6209cb5c33 | 1139 | // relative positioning, such as quadrature sensors. Other sensor |
mjr | 82:4f6209cb5c33 | 1140 | // types simply ignore this. |
mjr | 82:4f6209cb5c33 | 1141 | // |
mjr | 82:4f6209cb5c33 | 1142 | // byte 3 = bit flags: |
mjr | 82:4f6209cb5c33 | 1143 | // 0x01 -> auto-zeroing enabled |
mjr | 82:4f6209cb5c33 | 1144 | // byte 4 = auto-zeroing time in seconds |
mjr | 82:4f6209cb5c33 | 1145 | // |
mjr | 91:ae9be42652bf | 1146 | // 19 -> Plunger filters. There are two filters that can be applied: |
mjr | 85:3c28aee81cde | 1147 | // |
mjr | 91:ae9be42652bf | 1148 | // - Jitter filter. This sets a hysteresis window size, to reduce jitter |
mjr | 91:ae9be42652bf | 1149 | // jitter in the plunger reading. Most sensors aren't perfectly accurate; |
mjr | 91:ae9be42652bf | 1150 | // consecutive readings at the same physical plunger position vary |
mjr | 91:ae9be42652bf | 1151 | // slightly, wandering in a range near the true reading. Over time, the |
mjr | 91:ae9be42652bf | 1152 | // readings will usually average the true value, but that's not much of a |
mjr | 91:ae9be42652bf | 1153 | // consolation to us because we want to display the position in real time. |
mjr | 91:ae9be42652bf | 1154 | // To reduce the visible jitter, we can apply a hysteresis filter that |
mjr | 91:ae9be42652bf | 1155 | // hides random variations within the specified window. The window is in |
mjr | 91:ae9be42652bf | 1156 | // the sensor's native units, so the effect of a given window size |
mjr | 91:ae9be42652bf | 1157 | // depends on the sensor type. A value of zero disables the filter. |
mjr | 91:ae9be42652bf | 1158 | // |
mjr | 91:ae9be42652bf | 1159 | // - Reversed orientation. If set, this inverts the sensor readings, as |
mjr | 91:ae9be42652bf | 1160 | // though the sensor were physically flipped to the opposite direction. |
mjr | 91:ae9be42652bf | 1161 | // This allows for correcting a reversed physical sensor installation in |
mjr | 91:ae9be42652bf | 1162 | // software without having to mess with the hardware. |
mjr | 91:ae9be42652bf | 1163 | // |
mjr | 91:ae9be42652bf | 1164 | // byte 3:4 = jitter window size in native sensor units, little-endian |
mjr | 91:ae9be42652bf | 1165 | // byte 5 = orientation filter bit mask: |
mjr | 91:ae9be42652bf | 1166 | // 0x01 -> set if reversed orientation, clear if normal |
mjr | 91:ae9be42652bf | 1167 | // 0x80 -> Read-only: this bit is set if the feature is supported |
mjr | 85:3c28aee81cde | 1168 | // |
mjr | 87:8d35c74403af | 1169 | // 20 -> Plunger bar code setup. Sets parameters applicable only to bar code |
mjr | 87:8d35c74403af | 1170 | // sensor types. |
mjr | 87:8d35c74403af | 1171 | // |
mjr | 87:8d35c74403af | 1172 | // bytes 3:4 = Starting pixel offset of bar code (margin width) |
mjr | 87:8d35c74403af | 1173 | // |
mjr | 87:8d35c74403af | 1174 | // 21 -> TLC59116 setup. This chip is an external PWM controller with 16 |
mjr | 87:8d35c74403af | 1175 | // outputs per chip and an I2C bus interface. Up to 14 of the chips |
mjr | 87:8d35c74403af | 1176 | // can be connected to a single bus. This chip is a successor to the |
mjr | 87:8d35c74403af | 1177 | // TLC5940 with a more modern design and some nice improvements, such |
mjr | 87:8d35c74403af | 1178 | // as glitch-free startup and a standard (I2C) physical interface. |
mjr | 87:8d35c74403af | 1179 | // |
mjr | 87:8d35c74403af | 1180 | // Each chip has a 7-bit I2C address. The top three bits of the |
mjr | 87:8d35c74403af | 1181 | // address are fixed in the chip itself and can't be configured, but |
mjr | 87:8d35c74403af | 1182 | // the low four bits are configurable via the address line pins on |
mjr | 87:8d35c74403af | 1183 | // the chip, A3 A2 A1 A0. Our convention here is to ignore the fixed |
mjr | 87:8d35c74403af | 1184 | // three bits and refer to the chip address as just the A3 A2 A1 A0 |
mjr | 87:8d35c74403af | 1185 | // bits. This gives each chip an address from 0 to 15. |
mjr | 87:8d35c74403af | 1186 | // |
mjr | 87:8d35c74403af | 1187 | // I2C allows us to discover the attached chips automatically, so in |
mjr | 87:8d35c74403af | 1188 | // principle we don't need to know which chips will be present. |
mjr | 87:8d35c74403af | 1189 | // However, it's useful for the config tool to know which chips are |
mjr | 87:8d35c74403af | 1190 | // expected so that it can offer them in the output port setup UI. |
mjr | 87:8d35c74403af | 1191 | // We therefore provide a bit mask specifying the enabled chips. Each |
mjr | 87:8d35c74403af | 1192 | // bit specifies whether the chip at the corresponding address is |
mjr | 87:8d35c74403af | 1193 | // present: 0x0001 is the chip at address 0, 0x0002 is the chip at |
mjr | 87:8d35c74403af | 1194 | // address 1, etc. This is mostly for the config tool's use; we only |
mjr | 87:8d35c74403af | 1195 | // use it to determine if TLC59116 support should be enabled at all, |
mjr | 87:8d35c74403af | 1196 | // by checking if it's non-zero. |
mjr | 87:8d35c74403af | 1197 | // |
mjr | 87:8d35c74403af | 1198 | // To disable support, set the populated chip mask to 0. The pin |
mjr | 87:8d35c74403af | 1199 | // assignments are all ignored in this case. |
mjr | 87:8d35c74403af | 1200 | // |
mjr | 87:8d35c74403af | 1201 | // bytes 3:4 = populated chips, as a bit mask (OR in 1<<address |
mjr | 87:8d35c74403af | 1202 | // each populated address) |
mjr | 87:8d35c74403af | 1203 | // byte 5 = SDA (any GPIO pin) |
mjr | 87:8d35c74403af | 1204 | // byte 6 = SCL (any GPIO pin) |
mjr | 87:8d35c74403af | 1205 | // byte 7 = RESET (any GPIO pin) |
mjr | 87:8d35c74403af | 1206 | // |
mjr | 100:1ff35c07217c | 1207 | // 22 -> Plunger raw calibration data. Some sensor types need to store |
mjr | 100:1ff35c07217c | 1208 | // additional raw calibration. We provide three uint16 slots for |
mjr | 100:1ff35c07217c | 1209 | // use by the sensor, with the meaning defined by the sensor subclass. |
mjr | 100:1ff35c07217c | 1210 | // |
mjr | 100:1ff35c07217c | 1211 | // bytes 3:4 = raw data 0 |
mjr | 100:1ff35c07217c | 1212 | // bytes 5:6 = raw data 1 |
mjr | 100:1ff35c07217c | 1213 | // bytes 7:8 = raw data 2 |
mjr | 100:1ff35c07217c | 1214 | // |
mjr | 53:9b2611964afc | 1215 | // |
mjr | 74:822a92bc11d2 | 1216 | // SPECIAL DIAGNOSTICS VARIABLES: These work like the array variables below, |
mjr | 74:822a92bc11d2 | 1217 | // the only difference being that we don't report these in the number of array |
mjr | 74:822a92bc11d2 | 1218 | // variables reported in the "variable 0" query. |
mjr | 74:822a92bc11d2 | 1219 | // |
mjr | 74:822a92bc11d2 | 1220 | // 220 -> Performance/diagnostics variables. Items marked "read only" can't |
mjr | 74:822a92bc11d2 | 1221 | // be written; any SET VARIABLE messages on these are ignored. Items |
mjr | 74:822a92bc11d2 | 1222 | // marked "diagnostic only" refer to counters or statistics that are |
mjr | 74:822a92bc11d2 | 1223 | // collected only when the diagnostics are enabled via the diags.h |
mjr | 74:822a92bc11d2 | 1224 | // macro ENABLE_DIAGNOSTICS. These will simply return zero otherwise. |
mjr | 74:822a92bc11d2 | 1225 | // |
mjr | 74:822a92bc11d2 | 1226 | // byte 3 = diagnostic index (see below) |
mjr | 74:822a92bc11d2 | 1227 | // |
mjr | 74:822a92bc11d2 | 1228 | // Diagnostic index values: |
mjr | 74:822a92bc11d2 | 1229 | // |
mjr | 74:822a92bc11d2 | 1230 | // 1 -> Main loop cycle time [read only, diagnostic only] |
mjr | 74:822a92bc11d2 | 1231 | // Retrieves the average time of one iteration of the main |
mjr | 74:822a92bc11d2 | 1232 | // loop, in microseconds, as a uint32. This excludes the |
mjr | 74:822a92bc11d2 | 1233 | // time spent processing incoming messages, as well as any |
mjr | 74:822a92bc11d2 | 1234 | // time spent waiting for a dropped USB connection to be |
mjr | 74:822a92bc11d2 | 1235 | // restored. This includes all subroutine time and polled |
mjr | 74:822a92bc11d2 | 1236 | // task time, such as processing button and plunger input, |
mjr | 74:822a92bc11d2 | 1237 | // sending USB joystick reports, etc. |
mjr | 74:822a92bc11d2 | 1238 | // |
mjr | 74:822a92bc11d2 | 1239 | // 2 -> Main loop message read time [read only, diagnostic only] |
mjr | 74:822a92bc11d2 | 1240 | // Retrieves the average time spent processing incoming USB |
mjr | 74:822a92bc11d2 | 1241 | // messages per iteration of the main loop, in microseconds, |
mjr | 74:822a92bc11d2 | 1242 | // as a uint32. This only counts the processing time when |
mjr | 74:822a92bc11d2 | 1243 | // messages are actually present, so the average isn't reduced |
mjr | 74:822a92bc11d2 | 1244 | // by iterations of the main loop where no messages are found. |
mjr | 74:822a92bc11d2 | 1245 | // That is, if we run a million iterations of the main loop, |
mjr | 74:822a92bc11d2 | 1246 | // and only five of them have messages at all, the average time |
mjr | 74:822a92bc11d2 | 1247 | // includes only those five cycles with messages to process. |
mjr | 74:822a92bc11d2 | 1248 | // |
mjr | 74:822a92bc11d2 | 1249 | // 3 -> PWM update polling time [read only, diagnostic only] |
mjr | 74:822a92bc11d2 | 1250 | // Retrieves the average time, as a uint32 in microseconds, |
mjr | 74:822a92bc11d2 | 1251 | // spent in the PWM update polling routine. |
mjr | 74:822a92bc11d2 | 1252 | // |
mjr | 74:822a92bc11d2 | 1253 | // 4 -> LedWiz update polling time [read only, diagnostic only] |
mjr | 74:822a92bc11d2 | 1254 | // Retrieves the average time, as a uint32 in microseconds, |
mjr | 74:822a92bc11d2 | 1255 | // units, spent in the LedWiz flash cycle update routine. |
mjr | 74:822a92bc11d2 | 1256 | // |
mjr | 74:822a92bc11d2 | 1257 | // |
mjr | 53:9b2611964afc | 1258 | // ARRAY VARIABLES: Each variable below is an array. For each get/set message, |
mjr | 53:9b2611964afc | 1259 | // byte 3 gives the array index. These are grouped at the top end of the variable |
mjr | 53:9b2611964afc | 1260 | // ID range to distinguish this special feature. On QUERY, set the index byte to 0 |
mjr | 53:9b2611964afc | 1261 | // to query the number of slots; the reply will be a report for the array index |
mjr | 53:9b2611964afc | 1262 | // variable with index 0, with the first (and only) byte after that indicating |
mjr | 53:9b2611964afc | 1263 | // the maximum array index. |
mjr | 53:9b2611964afc | 1264 | // |
mjr | 77:0b96f6867312 | 1265 | // 250 -> IR remote control commands - code part 2. This stores the high-order |
mjr | 77:0b96f6867312 | 1266 | // 32 bits of the remote control for each slot. These are combined with |
mjr | 77:0b96f6867312 | 1267 | // the low-order 32 bits from variable 251 below to form a 64-bit code. |
mjr | 77:0b96f6867312 | 1268 | // |
mjr | 77:0b96f6867312 | 1269 | // byte 3 = Command slot number (1..MAX_IR_CODES) |
mjr | 77:0b96f6867312 | 1270 | // byte 4 = bits 32..39 of remote control command code |
mjr | 77:0b96f6867312 | 1271 | // byte 5 = bits 40..47 |
mjr | 77:0b96f6867312 | 1272 | // byte 6 = bits 48..55 |
mjr | 77:0b96f6867312 | 1273 | // byte 7 = bits 56..63 |
mjr | 77:0b96f6867312 | 1274 | // |
mjr | 77:0b96f6867312 | 1275 | // 251 -> IR remote control commands - code part 1. This stores the protocol |
mjr | 77:0b96f6867312 | 1276 | // identifier and low-order 32 bits of the remote control code for each |
mjr | 77:0b96f6867312 | 1277 | // remote control command slot. The code represents a key press on a |
mjr | 77:0b96f6867312 | 1278 | // remote, and is usually determined by reading it from the device's |
mjr | 77:0b96f6867312 | 1279 | // actual remote via the IR sensor input feature. These codes combine |
mjr | 77:0b96f6867312 | 1280 | // with variable 250 above to form a 64-bit code for each slot. |
mjr | 77:0b96f6867312 | 1281 | // See IRRemote/IRProtocolID.h for the protocol ID codes. |
mjr | 77:0b96f6867312 | 1282 | // |
mjr | 77:0b96f6867312 | 1283 | // byte 3 = Command slot number (1..MAX_IR_CODES) |
mjr | 77:0b96f6867312 | 1284 | // byte 4 = protocol ID |
mjr | 77:0b96f6867312 | 1285 | // byte 5 = bits 0..7 of remote control command code |
mjr | 77:0b96f6867312 | 1286 | // byte 6 = bits 8..15 |
mjr | 77:0b96f6867312 | 1287 | // byte 7 = bits 16..23 |
mjr | 77:0b96f6867312 | 1288 | // byte 8 = bits 24..31 |
mjr | 77:0b96f6867312 | 1289 | // |
mjr | 77:0b96f6867312 | 1290 | // 252 -> IR remote control commands - control information. This stores |
mjr | 77:0b96f6867312 | 1291 | // descriptive information for each remote control command slot. |
mjr | 77:0b96f6867312 | 1292 | // The IR code for each slot is stored in the corresponding array |
mjr | 77:0b96f6867312 | 1293 | // entry in variables 251 & 250 above; the information is split over |
mjr | 77:0b96f6867312 | 1294 | // several variables like this because of the 8-byte command message |
mjr | 77:0b96f6867312 | 1295 | // size in our USB protocol (which we use for LedWiz compatibility). |
mjr | 77:0b96f6867312 | 1296 | // |
mjr | 77:0b96f6867312 | 1297 | // byte 3 = Command slot number (1..MAX_IR_CODES) |
mjr | 77:0b96f6867312 | 1298 | // byte 4 = bit flags: |
mjr | 77:0b96f6867312 | 1299 | // 0x01 -> send this code as a TV ON signal at system start |
mjr | 77:0b96f6867312 | 1300 | // 0x02 -> use "ditto" codes when sending the command |
mjr | 77:0b96f6867312 | 1301 | // byte 5 = key type; same as the key type in an input button variable |
mjr | 77:0b96f6867312 | 1302 | // byte 6 = key code; same as the key code in an input button variable |
mjr | 77:0b96f6867312 | 1303 | // |
mjr | 77:0b96f6867312 | 1304 | // Each IR command slot can serve three purposes: |
mjr | 77:0b96f6867312 | 1305 | // |
mjr | 77:0b96f6867312 | 1306 | // - First, it can be used as part of the TV ON sequence when the |
mjr | 77:0b96f6867312 | 1307 | // system powers up, to turn on cabinet TVs that don't power up by |
mjr | 77:0b96f6867312 | 1308 | // themselves. To use this feature, set the TV ON bit in the flags. |
mjr | 77:0b96f6867312 | 1309 | // |
mjr | 77:0b96f6867312 | 1310 | // - Second, when the IR sensor receives a command in a given slot, we |
mjr | 77:0b96f6867312 | 1311 | // can translate it into a keyboard key or joystick button press sent |
mjr | 77:0b96f6867312 | 1312 | // to the PC. This lets you use any IR remote to send commands to the |
mjr | 77:0b96f6867312 | 1313 | // PC, allowing access to additional control inputs without any extra |
mjr | 77:0b96f6867312 | 1314 | // buttons on the cabinet. To use this feature, assign the key to |
mjr | 77:0b96f6867312 | 1315 | // send in the key type and key code bytes. |
mjr | 77:0b96f6867312 | 1316 | // |
mjr | 77:0b96f6867312 | 1317 | // - Third, we can send a given IR command when a physical cabinet |
mjr | 77:0b96f6867312 | 1318 | // button is pressed. This lets you use cabinet buttons to send IR |
mjr | 77:0b96f6867312 | 1319 | // commands to other devices in your system. For example, you could |
mjr | 77:0b96f6867312 | 1320 | // assign cabinet buttons to control the volume on a cab TV. To use |
mjr | 77:0b96f6867312 | 1321 | // this feature, assign an IR slot as a button function in the button |
mjr | 77:0b96f6867312 | 1322 | // setup. |
mjr | 77:0b96f6867312 | 1323 | // |
mjr | 66:2e3583fbd2f4 | 1324 | // 253 -> Extended input button setup. This adds on to the information set by |
mjr | 66:2e3583fbd2f4 | 1325 | // variable 254 below, accessing additional fields. The "shifted" key |
mjr | 66:2e3583fbd2f4 | 1326 | // type and code fields assign a secondary meaning to the button that's |
mjr | 66:2e3583fbd2f4 | 1327 | // used when the local Shift button is being held down. See variable 16 |
mjr | 66:2e3583fbd2f4 | 1328 | // above for more details on the Shift button. |
mjr | 66:2e3583fbd2f4 | 1329 | // |
mjr | 77:0b96f6867312 | 1330 | // byte 3 = Button number (1..MAX_BUTTONS) |
mjr | 66:2e3583fbd2f4 | 1331 | // byte 4 = shifted key type (same codes as "key type" in var 254) |
mjr | 77:0b96f6867312 | 1332 | // byte 5 = shifted key code (same codes as "key code" in var 254) |
mjr | 77:0b96f6867312 | 1333 | // byte 6 = shifted IR command (see "IR command" in var 254) |
mjr | 66:2e3583fbd2f4 | 1334 | // |
mjr | 53:9b2611964afc | 1335 | // 254 -> Input button setup. This sets up one button; it can be repeated for each |
mjr | 64:ef7ca92dff36 | 1336 | // button to be configured. There are MAX_EXT_BUTTONS button slots (see |
mjr | 64:ef7ca92dff36 | 1337 | // config.h for the constant definition), numbered 1..MAX_EXT_BUTTONS. Each |
mjr | 53:9b2611964afc | 1338 | // slot can be configured as a joystick button, a regular keyboard key, or a |
mjr | 53:9b2611964afc | 1339 | // media control key (mute, volume up, volume down). |
mjr | 53:9b2611964afc | 1340 | // |
mjr | 53:9b2611964afc | 1341 | // The bytes of the message are: |
mjr | 66:2e3583fbd2f4 | 1342 | // byte 3 = Button number (1..MAX_BUTTONS) |
mjr | 64:ef7ca92dff36 | 1343 | // byte 4 = GPIO pin for the button input; mapped as a DigitalIn port |
mjr | 53:9b2611964afc | 1344 | // byte 5 = key type reported to PC when button is pushed: |
mjr | 53:9b2611964afc | 1345 | // 0 = none (no PC input reported when button pushed) |
mjr | 53:9b2611964afc | 1346 | // 1 = joystick button -> byte 6 is the button number, 1-32 |
mjr | 53:9b2611964afc | 1347 | // 2 = regular keyboard key -> byte 6 is the USB key code (see below) |
mjr | 67:c39e66c4e000 | 1348 | // 3 = media key -> byte 6 is the USB media control code (see below) |
mjr | 53:9b2611964afc | 1349 | // byte 6 = key code, which depends on the key type in byte 5 |
mjr | 53:9b2611964afc | 1350 | // byte 7 = flags - a combination of these bit values: |
mjr | 53:9b2611964afc | 1351 | // 0x01 = pulse mode. This reports a physical on/off switch's state |
mjr | 53:9b2611964afc | 1352 | // to the host as a brief key press whenever the switch changes |
mjr | 53:9b2611964afc | 1353 | // state. This is useful for the VPinMAME Coin Door button, |
mjr | 53:9b2611964afc | 1354 | // which requires the End key to be pressed each time the |
mjr | 53:9b2611964afc | 1355 | // door changes state. |
mjr | 77:0b96f6867312 | 1356 | // byte 8 = IR command to transmit when unshifted button is pressed. This |
mjr | 77:0b96f6867312 | 1357 | // contains an IR slot number (1..MAX_IR_CODES), or 0 if no code |
mjr | 77:0b96f6867312 | 1358 | // is associated with the button. |
mjr | 53:9b2611964afc | 1359 | // |
mjr | 53:9b2611964afc | 1360 | // 255 -> LedWiz output port setup. This sets up one output port; it can be repeated |
mjr | 53:9b2611964afc | 1361 | // for each port to be configured. There are 128 possible slots for output ports, |
mjr | 53:9b2611964afc | 1362 | // numbered 1 to 128. The number of ports atcually active is determined by |
mjr | 53:9b2611964afc | 1363 | // the first DISABLED port (type 0). For example, if ports 1-32 are set as GPIO |
mjr | 53:9b2611964afc | 1364 | // outputs and port 33 is disabled, we'll report to the host that we have 32 ports, |
mjr | 53:9b2611964afc | 1365 | // regardless of the settings for post 34 and higher. |
mjr | 53:9b2611964afc | 1366 | // |
mjr | 53:9b2611964afc | 1367 | // The bytes of the message are: |
mjr | 87:8d35c74403af | 1368 | // |
mjr | 53:9b2611964afc | 1369 | // byte 3 = LedWiz port number (1 to MAX_OUT_PORTS) |
mjr | 87:8d35c74403af | 1370 | // |
mjr | 53:9b2611964afc | 1371 | // byte 4 = physical output type: |
mjr | 87:8d35c74403af | 1372 | // |
mjr | 53:9b2611964afc | 1373 | // 0 = Disabled. This output isn't used, and isn't visible to the |
mjr | 53:9b2611964afc | 1374 | // LedWiz/DOF software on the host. The FIRST disabled port |
mjr | 53:9b2611964afc | 1375 | // determines the number of ports visible to the host - ALL ports |
mjr | 53:9b2611964afc | 1376 | // after the first disabled port are also implicitly disabled. |
mjr | 87:8d35c74403af | 1377 | // |
mjr | 53:9b2611964afc | 1378 | // 1 = GPIO PWM output: connected to GPIO pin specified in byte 5, |
mjr | 53:9b2611964afc | 1379 | // operating in PWM mode. Note that only a subset of KL25Z GPIO |
mjr | 53:9b2611964afc | 1380 | // ports are PWM-capable. |
mjr | 87:8d35c74403af | 1381 | // |
mjr | 53:9b2611964afc | 1382 | // 2 = GPIO Digital output: connected to GPIO pin specified in byte 5, |
mjr | 53:9b2611964afc | 1383 | // operating in digital mode. Digital ports can only be set ON |
mjr | 53:9b2611964afc | 1384 | // or OFF, with no brightness/intensity control. All pins can be |
mjr | 53:9b2611964afc | 1385 | // used in this mode. |
mjr | 87:8d35c74403af | 1386 | // |
mjr | 53:9b2611964afc | 1387 | // 3 = TLC5940 port: connected to TLC5940 output port number specified |
mjr | 53:9b2611964afc | 1388 | // in byte 5. Ports are numbered sequentially starting from port 0 |
mjr | 53:9b2611964afc | 1389 | // for the first output (OUT0) on the first chip in the daisy chain. |
mjr | 87:8d35c74403af | 1390 | // |
mjr | 53:9b2611964afc | 1391 | // 4 = 74HC595 port: connected to 74HC595 output port specified in byte 5. |
mjr | 53:9b2611964afc | 1392 | // As with the TLC5940 outputs, ports are numbered sequentially from 0 |
mjr | 53:9b2611964afc | 1393 | // for the first output on the first chip in the daisy chain. |
mjr | 87:8d35c74403af | 1394 | // |
mjr | 53:9b2611964afc | 1395 | // 5 = Virtual output: this output port exists for the purposes of the |
mjr | 53:9b2611964afc | 1396 | // LedWiz/DOF software on the host, but isn't physically connected |
mjr | 53:9b2611964afc | 1397 | // to any output device. This can be used to create a virtual output |
mjr | 53:9b2611964afc | 1398 | // for the DOF ZB Launch Ball signal, for example, or simply as a |
mjr | 53:9b2611964afc | 1399 | // placeholder in the LedWiz port numbering. The physical output ID |
mjr | 53:9b2611964afc | 1400 | // (byte 5) is ignored for this port type. |
mjr | 87:8d35c74403af | 1401 | // |
mjr | 87:8d35c74403af | 1402 | // 6 = TLC59116 output: connected to the TLC59116 output port specified |
mjr | 87:8d35c74403af | 1403 | // in byte 5. The high four bits of this value give the chip's |
mjr | 87:8d35c74403af | 1404 | // I2C address, specifically the A3 A2 A1 A0 bits configured in |
mjr | 87:8d35c74403af | 1405 | // the hardware. (A chip's I2C address is actually 7 bits, but |
mjr | 87:8d35c74403af | 1406 | // the three high-order bits are fixed, so we don't bother including |
mjr | 87:8d35c74403af | 1407 | // those in the byte 5 value). The low four bits of this value |
mjr | 87:8d35c74403af | 1408 | // give the output port number on the chip. For example, 0x37 |
mjr | 87:8d35c74403af | 1409 | // specifies chip 3 (the one with A3 A2 A1 A0 wired as 0 0 1 1), |
mjr | 87:8d35c74403af | 1410 | // output #7 on that chip. Note that outputs are numbered from 0 |
mjr | 87:8d35c74403af | 1411 | // to 15 (0xF) on each chip. |
mjr | 87:8d35c74403af | 1412 | // |
mjr | 53:9b2611964afc | 1413 | // byte 5 = physical output port, interpreted according to the value in byte 4 |
mjr | 87:8d35c74403af | 1414 | // |
mjr | 53:9b2611964afc | 1415 | // byte 6 = flags: a combination of these bit values: |
mjr | 53:9b2611964afc | 1416 | // 0x01 = active-high output (0V on output turns attached device ON) |
mjr | 53:9b2611964afc | 1417 | // 0x02 = noisemaker device: disable this output when "night mode" is engaged |
mjr | 89:c43cd923401c | 1418 | // 0x04 = apply gamma correction to this output (PWM outputs only) |
mjr | 98:4df3c0f7e707 | 1419 | // 0x08 = "Flipper Logic" enabled for this output |
mjr | 99:8139b0c274f4 | 1420 | // 0x10 = "Chime Logic" enabled for this port |
mjr | 89:c43cd923401c | 1421 | // |
mjr | 99:8139b0c274f4 | 1422 | // byte 7 = Flipper Logic OR Chime Logic parameters. If flags bit 0x08 is set, |
mjr | 99:8139b0c274f4 | 1423 | // this is the Flipper Logic settings. If flags bit 0x10 is is set, |
mjr | 99:8139b0c274f4 | 1424 | // it's the Chime Logic settings. The two are mutually exclusive. |
mjr | 99:8139b0c274f4 | 1425 | // |
mjr | 99:8139b0c274f4 | 1426 | // For flipper logic: (full power time << 4) | (hold power level) |
mjr | 99:8139b0c274f4 | 1427 | // For chime logic: (max on time << 4) | (min on time) |
mjr | 99:8139b0c274f4 | 1428 | // |
mjr | 98:4df3c0f7e707 | 1429 | // Flipper logic uses PWM to reduce the power level on the port after an |
mjr | 98:4df3c0f7e707 | 1430 | // initial timed interval at full power. This is designed for pinball |
mjr | 98:4df3c0f7e707 | 1431 | // coils, which are designed to be energized only in short bursts. In |
mjr | 98:4df3c0f7e707 | 1432 | // a pinball machine, most coils are used this way naturally: bumpers, |
mjr | 89:c43cd923401c | 1433 | // slingshots, kickers, knockers, chimes, etc. are only fired in brief |
mjr | 89:c43cd923401c | 1434 | // bursts. Some coils are left on for long periods, though, particularly |
mjr | 89:c43cd923401c | 1435 | // the flippers. The Flipper Logic feature is designed to handle this |
mjr | 89:c43cd923401c | 1436 | // in a way similar to how real pinball machines solve the same problem. |
mjr | 89:c43cd923401c | 1437 | // When Flipper Logic is enabled, the software gives the output full |
mjr | 89:c43cd923401c | 1438 | // power when initially turned on, but reduces the power to a lower |
mjr | 89:c43cd923401c | 1439 | // level (via PWM) after a short time elapses. The point is to reduce |
mjr | 89:c43cd923401c | 1440 | // the power to a level low enough that the coil can safely dissipate |
mjr | 89:c43cd923401c | 1441 | // the generated heat indefinitely, but still high enough to keep the |
mjr | 89:c43cd923401c | 1442 | // solenoid mechanically actuated. This is possible because solenoids |
mjr | 89:c43cd923401c | 1443 | // generally need much less power to "hold" than to actuate initially. |
mjr | 89:c43cd923401c | 1444 | // |
mjr | 98:4df3c0f7e707 | 1445 | // The high-order 4 bits of this byte give the initial full power time, |
mjr | 98:4df3c0f7e707 | 1446 | // using the following mapping for 0..15: 1ms, 2ms, 5ms, 10ms, 20ms, 40ms |
mjr | 98:4df3c0f7e707 | 1447 | // 80ms, 100ms, 150ms, 200ms, 300ms, 400ms, 500ms, 600ms, 700ms, 800ms. |
mjr | 98:4df3c0f7e707 | 1448 | // |
mjr | 98:4df3c0f7e707 | 1449 | // Note that earlier versions prior to 3/2019 used a scale of (X+1)*50ms. |
mjr | 98:4df3c0f7e707 | 1450 | // We changed to this pseudo-logarithmic scale for finer gradations at the |
mjr | 98:4df3c0f7e707 | 1451 | // low end of the time scale, for coils that need fast on/off cycling. |
mjr | 53:9b2611964afc | 1452 | // |
mjr | 89:c43cd923401c | 1453 | // The low-order 4 bits of the byte give the percentage power, in 6.66% |
mjr | 89:c43cd923401c | 1454 | // increments: 0 = 0% (off), 1 = 6.66%, ..., 15 = 100%. |
mjr | 89:c43cd923401c | 1455 | // |
mjr | 89:c43cd923401c | 1456 | // A hold power of 0 provides a software equivalent of the timer-protected |
mjr | 89:c43cd923401c | 1457 | // output logic of the Pinscape expansion boards used in the main board's |
mjr | 89:c43cd923401c | 1458 | // replay knocker output and all of the chime board outputs. This is |
mjr | 89:c43cd923401c | 1459 | // suitable for devices that shouldn't ever fire for long periods to |
mjr | 89:c43cd923401c | 1460 | // start with. |
mjr | 89:c43cd923401c | 1461 | // |
mjr | 89:c43cd923401c | 1462 | // Non-zero hold powers are suitable for devices that do need to stay on |
mjr | 89:c43cd923401c | 1463 | // for long periods, such as flippers. The "right" level will vary by |
mjr | 89:c43cd923401c | 1464 | // device; you should experiment to find the lowest setting where the |
mjr | 89:c43cd923401c | 1465 | // device stays mechanically actuated. Once you find the level, you |
mjr | 89:c43cd923401c | 1466 | // should confirm that the device won't overheat at that level by turning |
mjr | 89:c43cd923401c | 1467 | // it on at the selected level and carefully monitoring it for heating. |
mjr | 89:c43cd923401c | 1468 | // If the coil stays cool for a minute or two, it should be safe to assume |
mjr | 89:c43cd923401c | 1469 | // that it's in thermal equilibrium, meaning it should be able to sustain |
mjr | 89:c43cd923401c | 1470 | // the power level indefinitely. |
mjr | 89:c43cd923401c | 1471 | // |
mjr | 98:4df3c0f7e707 | 1472 | // Note that this feature can be used with any port, but it's only fully |
mjr | 98:4df3c0f7e707 | 1473 | // functional with a PWM port. A digital output port can only be set to |
mjr | 98:4df3c0f7e707 | 1474 | // 0% or 100%, so the only meaningful reduced hold power is 0%. This |
mjr | 98:4df3c0f7e707 | 1475 | // makes the feature a simple time limiter - basically a software version |
mjr | 98:4df3c0f7e707 | 1476 | // of the Chime Board from the expansion board set. |
mjr | 98:4df3c0f7e707 | 1477 | // |
mjr | 99:8139b0c274f4 | 1478 | // Chime Logic encodes a minimum and maximum ON time for the port. It |
mjr | 99:8139b0c274f4 | 1479 | // doesn't use PWM; it simply forces the port on or off in specified |
mjr | 99:8139b0c274f4 | 1480 | // durations. The low 4 bits encode the minimum ON time, as an index |
mjr | 99:8139b0c274f4 | 1481 | // into the table below. The high 4 bits encode the maximum ON time, |
mjr | 99:8139b0c274f4 | 1482 | // with the special case that 0 means "infinite". |
mjr | 99:8139b0c274f4 | 1483 | // |
mjr | 99:8139b0c274f4 | 1484 | // Chime logic time table: 0ms, 1ms, 2ms, 5ms, 10ms, 20ms, 40ms, 80ms, |
mjr | 99:8139b0c274f4 | 1485 | // 100ms, 200ms, 300ms, 400ms, 500ms, 600ms, 700ms, 800ms. |
mjr | 99:8139b0c274f4 | 1486 | // |
mjr | 89:c43cd923401c | 1487 | // |
mjr | 89:c43cd923401c | 1488 | // Note that the KL25Z's on-board LEDs can be used as LedWiz output ports, simply |
mjr | 89:c43cd923401c | 1489 | // by assigning the LED GPIO pins as output ports. This is useful for testing a new |
mjr | 89:c43cd923401c | 1490 | // installation without having to connect any external devices. Assigning the |
mjr | 89:c43cd923401c | 1491 | // on-board LEDs as output ports automatically overrides their normal status and |
mjr | 89:c43cd923401c | 1492 | // diagnostic display use, so be aware that the normal status flash pattern won't |
mjr | 89:c43cd923401c | 1493 | // appear when they're used this way. |
mjr | 52:8298b2a73eb2 | 1494 | // |
mjr | 35:e959ffba78fd | 1495 | |
mjr | 35:e959ffba78fd | 1496 | |
mjr | 55:4db125cd11a0 | 1497 | // --- GPIO PIN NUMBER MAPPINGS --- |
mjr | 35:e959ffba78fd | 1498 | // |
mjr | 53:9b2611964afc | 1499 | // In USB messages that specify GPIO pin assignments, pins are identified by |
mjr | 53:9b2611964afc | 1500 | // 8-bit integers. The special value 0xFF means NC (not connected). All actual |
mjr | 53:9b2611964afc | 1501 | // pins are mapped with the port number in the top 3 bits and the pin number in |
mjr | 53:9b2611964afc | 1502 | // the bottom 5 bits. Port A=0, B=1, ..., E=4. For example, PTC7 is port C (2) |
mjr | 53:9b2611964afc | 1503 | // pin 7, so it's represented as (2 << 5) | 7. |
mjr | 53:9b2611964afc | 1504 | |
mjr | 35:e959ffba78fd | 1505 | |
mjr | 35:e959ffba78fd | 1506 | // --- USB KEYBOARD SCAN CODES --- |
mjr | 35:e959ffba78fd | 1507 | // |
mjr | 53:9b2611964afc | 1508 | // For regular keyboard keys, we use the standard USB HID scan codes |
mjr | 53:9b2611964afc | 1509 | // for the US keyboard layout. The scan codes are defined by the USB |
mjr | 53:9b2611964afc | 1510 | // HID specifications; you can find a full list in the official USB |
mjr | 53:9b2611964afc | 1511 | // specs. Some common codes are listed below as a quick reference. |
mjr | 35:e959ffba78fd | 1512 | // |
mjr | 53:9b2611964afc | 1513 | // Key name -> USB scan code (hex) |
mjr | 53:9b2611964afc | 1514 | // A-Z -> 04-1D |
mjr | 53:9b2611964afc | 1515 | // top row 1!->0) -> 1E-27 |
mjr | 53:9b2611964afc | 1516 | // Return -> 28 |
mjr | 53:9b2611964afc | 1517 | // Escape -> 29 |
mjr | 53:9b2611964afc | 1518 | // Backspace -> 2A |
mjr | 53:9b2611964afc | 1519 | // Tab -> 2B |
mjr | 53:9b2611964afc | 1520 | // Spacebar -> 2C |
mjr | 53:9b2611964afc | 1521 | // -_ -> 2D |
mjr | 53:9b2611964afc | 1522 | // =+ -> 2E |
mjr | 53:9b2611964afc | 1523 | // [{ -> 2F |
mjr | 53:9b2611964afc | 1524 | // ]} -> 30 |
mjr | 53:9b2611964afc | 1525 | // \| -> 31 |
mjr | 53:9b2611964afc | 1526 | // ;: -> 33 |
mjr | 53:9b2611964afc | 1527 | // '" -> 34 |
mjr | 53:9b2611964afc | 1528 | // `~ -> 35 |
mjr | 53:9b2611964afc | 1529 | // ,< -> 36 |
mjr | 53:9b2611964afc | 1530 | // .> -> 37 |
mjr | 53:9b2611964afc | 1531 | // /? -> 38 |
mjr | 53:9b2611964afc | 1532 | // Caps Lock -> 39 |
mjr | 53:9b2611964afc | 1533 | // F1-F12 -> 3A-45 |
mjr | 53:9b2611964afc | 1534 | // F13-F24 -> 68-73 |
mjr | 53:9b2611964afc | 1535 | // Print Screen -> 46 |
mjr | 53:9b2611964afc | 1536 | // Scroll Lock -> 47 |
mjr | 53:9b2611964afc | 1537 | // Pause -> 48 |
mjr | 53:9b2611964afc | 1538 | // Insert -> 49 |
mjr | 53:9b2611964afc | 1539 | // Home -> 4A |
mjr | 53:9b2611964afc | 1540 | // Page Up -> 4B |
mjr | 53:9b2611964afc | 1541 | // Del -> 4C |
mjr | 53:9b2611964afc | 1542 | // End -> 4D |
mjr | 53:9b2611964afc | 1543 | // Page Down -> 4E |
mjr | 53:9b2611964afc | 1544 | // Right Arrow -> 4F |
mjr | 53:9b2611964afc | 1545 | // Left Arrow -> 50 |
mjr | 53:9b2611964afc | 1546 | // Down Arrow -> 51 |
mjr | 53:9b2611964afc | 1547 | // Up Arrow -> 52 |
mjr | 53:9b2611964afc | 1548 | // Num Lock/Clear -> 53 |
mjr | 53:9b2611964afc | 1549 | // Keypad / * - + -> 54 55 56 57 |
mjr | 53:9b2611964afc | 1550 | // Keypad Enter -> 58 |
mjr | 53:9b2611964afc | 1551 | // Keypad 1-9 -> 59-61 |
mjr | 53:9b2611964afc | 1552 | // Keypad 0 -> 62 |
mjr | 53:9b2611964afc | 1553 | // Keypad . -> 63 |
mjr | 53:9b2611964afc | 1554 | // Mute -> 7F |
mjr | 53:9b2611964afc | 1555 | // Volume Up -> 80 |
mjr | 53:9b2611964afc | 1556 | // Volume Down -> 81 |
mjr | 53:9b2611964afc | 1557 | // Left Control -> E0 |
mjr | 53:9b2611964afc | 1558 | // Left Shift -> E1 |
mjr | 53:9b2611964afc | 1559 | // Left Alt -> E2 |
mjr | 53:9b2611964afc | 1560 | // Left GUI -> E3 |
mjr | 53:9b2611964afc | 1561 | // Right Control -> E4 |
mjr | 53:9b2611964afc | 1562 | // Right Shift -> E5 |
mjr | 53:9b2611964afc | 1563 | // Right Alt -> E6 |
mjr | 53:9b2611964afc | 1564 | // Right GUI -> E7 |
mjr | 53:9b2611964afc | 1565 | // |
mjr | 66:2e3583fbd2f4 | 1566 | // Due to limitations in Windows, there's a limit of 6 regular keys |
mjr | 66:2e3583fbd2f4 | 1567 | // pressed at the same time. The shift keys in the E0-E7 range don't |
mjr | 66:2e3583fbd2f4 | 1568 | // count against this limit, though, since they're encoded as modifier |
mjr | 66:2e3583fbd2f4 | 1569 | // keys; all of these can be pressed at the same time in addition to 6 |
mjr | 67:c39e66c4e000 | 1570 | // regular keys. |
mjr | 67:c39e66c4e000 | 1571 | |
mjr | 67:c39e66c4e000 | 1572 | // --- USB MEDIA CONTROL SCAN CODES --- |
mjr | 67:c39e66c4e000 | 1573 | // |
mjr | 67:c39e66c4e000 | 1574 | // Buttons mapped to type 3 are Media Control buttons. These select |
mjr | 67:c39e66c4e000 | 1575 | // a small set of common media control functions. We recognize the |
mjr | 67:c39e66c4e000 | 1576 | // following type codes only: |
mjr | 67:c39e66c4e000 | 1577 | // |
mjr | 67:c39e66c4e000 | 1578 | // Mute -> E2 |
mjr | 67:c39e66c4e000 | 1579 | // Volume up -> E9 |
mjr | 67:c39e66c4e000 | 1580 | // Volume Down -> EA |
mjr | 67:c39e66c4e000 | 1581 | // Next Track -> B5 |
mjr | 67:c39e66c4e000 | 1582 | // Previous Track -> B6 |
mjr | 67:c39e66c4e000 | 1583 | // Stop -> B7 |
mjr | 67:c39e66c4e000 | 1584 | // Play/Pause -> CD |