Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Diff: main.cpp
- Revision:
- 63:5cd1a5f3a41b
- Parent:
- 60:f38da020aa13
- Child:
- 64:ef7ca92dff36
--- a/main.cpp Thu Jun 02 22:52:25 2016 +0000 +++ b/main.cpp Tue Jun 14 20:24:34 2016 +0000 @@ -988,10 +988,11 @@ // lower of 32 or the actual number of outputs. static int numLwOutputs; -// Current absolute brightness level for an output. This is a DOF -// brightness level value, from 0 for fully off to 255 for fully on. -// This is used for all extended ports (33 and above), and for any -// LedWiz port with wizVal == 255. +// Current absolute brightness levels for all outputs. These are +// DOF brightness level value, from 0 for fully off to 255 for fully +// on. These are always used for extended ports (33 and above), and +// are used for LedWiz ports (1-32) when we're in extended protocol +// mode (i.e., ledWizMode == false). static uint8_t *outLevel; // create a single output pin @@ -1146,6 +1147,42 @@ lwPin[i] = createLwPin(i, cfg.outPort[i], cfg); } +// LedWiz/Extended protocol mode. +// +// We implement output port control using both the legacy LedWiz +// protocol and a private extended protocol (which is 100% backwards +// compatible with the LedWiz protocol: we recognize all valid legacy +// protocol commands and handle them the same way a real LedWiz does). +// The legacy protocol can access the first 32 ports; the extended +// protocol can access all ports, including the first 32 as well as +// the higher numbered ports. This means that the first 32 ports +// can be addressed with either protocol, which muddies the waters +// a bit because of the different approaches the two protocols take. +// The legacy protocol separates the brightness/flash state of an +// output (which it calls the "profile" state) from the on/off state. +// The extended protocol doesn't; "off" is simply represented as +// brightness 0. +// +// To deal with the different approaches, we use this flag to keep +// track of the global protocol state. Each time we get an output +// port command, we switch the protocol state to the protocol that +// was used in the command. On a legacy SBA or PBA, we switch to +// LedWiz mode; on an extended output set message, we switch to +// extended mode. We remember the LedWiz and extended output state +// for each LW ports (1-32) separately. Any time the mode changes, +// we set ports 1-32 back to the state for the new mode. +// +// The reasoning here is that any given client (on the PC) will use +// one mode or the other, and won't mix the two. An older program +// that only knows about the LedWiz protocol will use the legacy +// protocol only, and never send us an extended command. A DOF-based +// program might use one or the other, according to how the user has +// configured DOF. We have to be able to switch seamlessly between +// the protocols to accommodate switching from one type of program +// on the PC to the other, but we shouldn't have to worry about one +// program switching back and forth. +static uint8_t ledWizMode = true; + // LedWiz output states. // // The LedWiz protocol has two separate control axes for each output. @@ -1171,10 +1208,6 @@ // 131 = on / ramp down // 132 = ramp up / on // -// If the output was last updated through an extended protocol message, -// it will have the special value 255. This means that we use the -// outLevel[] value for the port instead of an LedWiz setting. -// // (Note that value 49 isn't documented in the LedWiz spec, but real // LedWiz units treat it as equivalent to 48, and some PC software uses // it, so we need to accept it for compatibility.) @@ -1208,9 +1241,9 @@ // Translate an LedWiz output (ports 1-32) to a DOF brightness level. static uint8_t wizState(int idx) { - // if the output was last set with an extended protocol message, - // use the value set there, ignoring the output's LedWiz state - if (wizVal[idx] == 255) + // If we're in extended protocol mode, ignore the LedWiz setting + // for the port and use the new protocol setting instead. + if (!ledWizMode) return outLevel[idx]; // if it's off, show at zero intensity @@ -1354,7 +1387,7 @@ lwPin[i]->set(wizState(i)); // update each extended output - for (int i = 33 ; i < numOutputs ; ++i) + for (int i = numLwOutputs ; i < numOutputs ; ++i) lwPin[i]->set(outLevel[i]); // flush 74HC595 changes, if necessary @@ -3782,6 +3815,9 @@ //printf("LWZ-SBA %02x %02x %02x %02x ; %02x\r\n", // data[1], data[2], data[3], data[4], data[5]); + // switch to LedWiz protocol mode + ledWizMode = true; + // update all on/off states for (int i = 0, bit = 1, ri = 1 ; i < numLwOutputs ; ++i, bit <<= 1) { @@ -3793,19 +3829,6 @@ // set the on/off state wizOn[i] = ((data[ri] & bit) != 0); - - // If the wizVal setting is 255, it means that this - // output was last set to a brightness value with the - // extended protocol. Return it to LedWiz control by - // rescaling the brightness setting to the LedWiz range - // and updating wizVal with the result. If it's any - // other value, it was previously set by a PBA message, - // so simply retain the last setting - in the normal - // LedWiz protocol, the "profile" (brightness) and on/off - // states are independent, so an SBA just turns an output - // on or off but retains its last brightness level. - if (wizVal[i] == 255) - wizVal[i] = (uint8_t)round(outLevel[i]/255.0 * 48.0); } // set the flash speed - enforce the value range 1-7 @@ -3977,19 +4000,21 @@ // most recent message of either type takes precedence. For // outputs above the LedWiz range, PBA/SBA messages can't // address those ports anyway. + + // flag that we're in extended protocol mode + ledWizMode = false; + + // figure the block of 7 ports covered in the message int i0 = (data[0] - 200)*7; int i1 = i0 + 7 < numOutputs ? i0 + 7 : numOutputs; + + // update each port for (int i = i0 ; i < i1 ; ++i) { // set the brightness level for the output uint8_t b = data[i-i0+1]; outLevel[i] = b; - // if it's in the basic LedWiz output set, set the LedWiz - // profile value to 255, which means "use outLevel" - if (i < 32) - wizVal[i] = 255; - // set the output lwPin[i]->set(b); } @@ -4015,11 +4040,15 @@ // Note that a PBA implicitly overrides our extended profile // messages (message prefix 200-219), because this sets the // wizVal[] entry for each output, and that takes precedence - // over the extended protocol settings. + // over the extended protocol settings when we're in LedWiz + // protocol mode. // //printf("LWZ-PBA[%d] %02x %02x %02x %02x %02x %02x %02x %02x\r\n", // pbaIdx, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); + // flag that we received an LedWiz message + ledWizMode = true; + // Update all output profile settings for (int i = 0 ; i < 8 ; ++i) wizVal[pbaIdx + i] = data[i];