The codebase to run the *spark d-fuser controller www.sparkav.co.uk/dvimixer

Dependencies:   SPK-TVOne DMX DmxArtNet NetServicesMin OSC PinDetect mRotaryEncoder iniparser mbed spk_oled_ssd1305 filter

Committer:
tobyspark
Date:
Mon Oct 29 13:18:52 2012 +0000
Revision:
30:873979018850
Parent:
29:95a7efe30527
Child:
31:01845a2347ff
v21 - And no beta in the version! Handles missing sources

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 8:d46cc49f0f37 1 /* *SPARK D-FUSER
tobyspark 8:d46cc49f0f37 2 * A project by Toby Harris
tobyspark 8:d46cc49f0f37 3 *
tobyspark 8:d46cc49f0f37 4 * 'DJ' controller styke RS232 Control for TV-One products
tobyspark 8:d46cc49f0f37 5 * Good for 1T-C2-750, others will need some extra work
tobyspark 8:d46cc49f0f37 6 *
tobyspark 8:d46cc49f0f37 7 * www.sparkav.co.uk/dvimixer
tobyspark 8:d46cc49f0f37 8 */
tobyspark 0:87aab40d5806 9
tobyspark 8:d46cc49f0f37 10 /* Copyright (c) 2011 Toby Harris, MIT License
tobyspark 8:d46cc49f0f37 11 *
tobyspark 8:d46cc49f0f37 12 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tobyspark 8:d46cc49f0f37 13 * and associated documentation files (the "Software"), to deal in the Software without restriction,
tobyspark 8:d46cc49f0f37 14 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
tobyspark 8:d46cc49f0f37 15 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
tobyspark 8:d46cc49f0f37 16 * furnished to do so, subject to the following conditions:
tobyspark 8:d46cc49f0f37 17 *
tobyspark 8:d46cc49f0f37 18 * The above copyright notice and this permission notice shall be included in all copies or
tobyspark 8:d46cc49f0f37 19 * substantial portions of the Software.
tobyspark 8:d46cc49f0f37 20 *
tobyspark 8:d46cc49f0f37 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
tobyspark 8:d46cc49f0f37 22 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
tobyspark 8:d46cc49f0f37 23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
tobyspark 8:d46cc49f0f37 24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tobyspark 8:d46cc49f0f37 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tobyspark 8:d46cc49f0f37 26 */
tobyspark 8:d46cc49f0f37 27
tobyspark 8:d46cc49f0f37 28 /* ROADMAP / HISTORY
tobyspark 8:d46cc49f0f37 29 * v10 - Port to mBed, keying redux - Apr'11
tobyspark 8:d46cc49f0f37 30 * v11 - Sign callbacks, code clean-up - Apr'11
tobyspark 8:d46cc49f0f37 31 * v12 - TVOne header split into two: defines and mbed class. v002 header updates pulled down. Removed sign callbacks, rewrite of debug and signing. - Apr'11
tobyspark 8:d46cc49f0f37 32 * v13 - Menu system for Resolution + Keying implemented, it writing to debug, it sending TVOne commands - Apr'11
tobyspark 8:d46cc49f0f37 33 * v14 - Fixes for new PCB - Oct'11
tobyspark 8:d46cc49f0f37 34 * v15 - TBZ PCB, OLED - Mar'12
tobyspark 8:d46cc49f0f37 35 * v16 - Comms menu, OSC, ArtNet - April'12
tobyspark 8:d46cc49f0f37 36 * v17 - RJ45 - May'12
tobyspark 8:d46cc49f0f37 37 * v18 - DMX - July'12
tobyspark 13:3796bde6ba8f 38 * v19 - TVOne mixing comms further optimised - August'12
tobyspark 30:873979018850 39 * v20 - Keying values and resolutions load from USB mass storage - September'12
tobyspark 30:873979018850 40 * v21 - Mixing behaviour upgrade: blend-additive as continuum, test cards on startup if no valid source - October'12
tobyspark 10:c011b0e5c17e 41 * vxx - TODO: Set keying values from controller, requires a guided, step-through process for user
tobyspark 8:d46cc49f0f37 42 * vxx - TODO: Defaults load/save from USB mass storage
tobyspark 30:873979018850 43 * vxx - TODO: EDID passthrough override
tobyspark 8:d46cc49f0f37 44 * vxx - TODO: EDID upload from USB mass storage
tobyspark 8:d46cc49f0f37 45 * vxx - TODO: EDID creation from resolution
tobyspark 8:d46cc49f0f37 46 */
tobyspark 8:d46cc49f0f37 47
tobyspark 0:87aab40d5806 48 #include "mbed.h"
tobyspark 0:87aab40d5806 49
tobyspark 0:87aab40d5806 50 #include "spk_tvone_mbed.h"
tobyspark 0:87aab40d5806 51 #include "spk_utils.h"
tobyspark 0:87aab40d5806 52 #include "spk_mRotaryEncoder.h"
tobyspark 0:87aab40d5806 53 #include "spk_oled_ssd1305.h"
tobyspark 2:50043054e4f7 54 #include "spk_oled_gfx.h"
tobyspark 11:0783cfbeb746 55 #include "spk_settings.h"
tobyspark 1:f9fca21102e0 56 #include "EthernetNetIf.h"
tobyspark 1:f9fca21102e0 57 #include "mbedOSC.h"
tobyspark 3:033d2b7768f3 58 #include "DmxArtNet.h"
tobyspark 5:f8b285ca41ba 59 #include "DMX.h"
tobyspark 17:fc68d40b8b1f 60 #include "filter.h"
tobyspark 0:87aab40d5806 61
tobyspark 30:873979018850 62 #define kSPKDFSoftwareVersion "21"
tobyspark 13:3796bde6ba8f 63
tobyspark 5:f8b285ca41ba 64 // MBED PINS
tobyspark 5:f8b285ca41ba 65
tobyspark 5:f8b285ca41ba 66 #define kMBED_AIN_XFADE p20
tobyspark 5:f8b285ca41ba 67 #define kMBED_AIN_FADEUP p19
tobyspark 5:f8b285ca41ba 68 #define kMBED_DIN_TAP_L p24
tobyspark 5:f8b285ca41ba 69 #define kMBED_DIN_TAP_R p23
tobyspark 5:f8b285ca41ba 70 #define kMBED_ENC_SW p15
tobyspark 5:f8b285ca41ba 71 #define kMBED_ENC_A p16
tobyspark 5:f8b285ca41ba 72 #define kMBED_ENC_B p17
tobyspark 5:f8b285ca41ba 73
tobyspark 5:f8b285ca41ba 74 #define kMBED_RS232_TTLTX p13
tobyspark 5:f8b285ca41ba 75 #define kMBED_RS232_TTLRX p14
tobyspark 5:f8b285ca41ba 76
tobyspark 5:f8b285ca41ba 77 #define kMBED_OLED_MOSI p5
tobyspark 5:f8b285ca41ba 78 #define kMBED_OLED_SCK p7
tobyspark 5:f8b285ca41ba 79 #define kMBED_OLED_CS p8
tobyspark 5:f8b285ca41ba 80 #define kMBED_OLED_RES p9
tobyspark 5:f8b285ca41ba 81 #define kMBED_OLED_DC p10
tobyspark 5:f8b285ca41ba 82
tobyspark 5:f8b285ca41ba 83 #define kMBED_DIN_ETHLO_DMXHI p30
tobyspark 5:f8b285ca41ba 84 #define kMBED_DOUT_RS485_TXHI_RXLO p29
tobyspark 5:f8b285ca41ba 85 #define kMBED_RS485_TTLTX p28
tobyspark 5:f8b285ca41ba 86 #define kMBED_RS485_TTLRX p27
tobyspark 5:f8b285ca41ba 87
tobyspark 5:f8b285ca41ba 88 // DISPLAY
tobyspark 5:f8b285ca41ba 89
tobyspark 1:f9fca21102e0 90 #define kMenuLine1 3
tobyspark 1:f9fca21102e0 91 #define kMenuLine2 4
tobyspark 1:f9fca21102e0 92 #define kCommsStatusLine 6
tobyspark 1:f9fca21102e0 93 #define kTVOneStatusLine 7
tobyspark 1:f9fca21102e0 94
tobyspark 5:f8b285ca41ba 95 // NETWORKING
tobyspark 5:f8b285ca41ba 96
tobyspark 1:f9fca21102e0 97 #define kOSCMbedPort 10000
tobyspark 1:f9fca21102e0 98 #define kOSCMbedIPAddress 10,0,0,2
tobyspark 1:f9fca21102e0 99 #define kOSCMbedSubnetMask 255,255,255,0
tobyspark 1:f9fca21102e0 100 #define kOSCMbedGateway 10,0,0,1
tobyspark 1:f9fca21102e0 101 #define kOSCMbedDNS 10,0,0,1
tobyspark 0:87aab40d5806 102
tobyspark 3:033d2b7768f3 103 #define kArtNetBindIPAddress 2,0,0,100
tobyspark 3:033d2b7768f3 104 #define kArtNetBroadcastAddress 2,255,255,255
tobyspark 3:033d2b7768f3 105
tobyspark 5:f8b285ca41ba 106 #define kDMXInChannelXFade 0
tobyspark 5:f8b285ca41ba 107 #define kDMXInChannelFadeUp 1
tobyspark 5:f8b285ca41ba 108 #define kDMXOutChannelXFade 0
tobyspark 5:f8b285ca41ba 109 #define kDMXOutChannelFadeUp 1
tobyspark 5:f8b285ca41ba 110
tobyspark 13:3796bde6ba8f 111 // 8.3 format filename only, no subdirs
tobyspark 13:3796bde6ba8f 112 #define kSPKDFSettingsFilename "SPKDF.ini"
tobyspark 11:0783cfbeb746 113
tobyspark 26:0299f8760715 114 #define kStringBufferLength 30
tobyspark 26:0299f8760715 115
tobyspark 0:87aab40d5806 116 //// DEBUG
tobyspark 0:87aab40d5806 117
tobyspark 0:87aab40d5806 118 // Comment out one or the other...
tobyspark 29:95a7efe30527 119 //Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial
tobyspark 29:95a7efe30527 120 Serial *debug = NULL; // For release (no debugging)
tobyspark 0:87aab40d5806 121
tobyspark 15:4b394c64b461 122 //// SOFT RESET
tobyspark 15:4b394c64b461 123
tobyspark 15:4b394c64b461 124 extern "C" void mbed_reset();
tobyspark 15:4b394c64b461 125
tobyspark 0:87aab40d5806 126 //// mBED PIN ASSIGNMENTS
tobyspark 0:87aab40d5806 127
tobyspark 0:87aab40d5806 128 // Inputs
tobyspark 5:f8b285ca41ba 129 AnalogIn xFadeAIN(kMBED_AIN_XFADE);
tobyspark 5:f8b285ca41ba 130 AnalogIn fadeUpAIN(kMBED_AIN_FADEUP);
tobyspark 5:f8b285ca41ba 131 DigitalIn tapLeftDIN(kMBED_DIN_TAP_L);
tobyspark 5:f8b285ca41ba 132 DigitalIn tapRightDIN(kMBED_DIN_TAP_R);
tobyspark 17:fc68d40b8b1f 133 medianFilter xFadeFilter(9);
tobyspark 17:fc68d40b8b1f 134 medianFilter fadeUpFilter(9);
tobyspark 0:87aab40d5806 135
tobyspark 5:f8b285ca41ba 136 SPKRotaryEncoder menuEnc(kMBED_ENC_A, kMBED_ENC_B, kMBED_ENC_SW);
tobyspark 5:f8b285ca41ba 137
tobyspark 5:f8b285ca41ba 138 DigitalIn rj45ModeDIN(kMBED_DIN_ETHLO_DMXHI);
tobyspark 0:87aab40d5806 139
tobyspark 0:87aab40d5806 140 // Outputs
tobyspark 0:87aab40d5806 141 PwmOut fadeAPO(LED1);
tobyspark 0:87aab40d5806 142 PwmOut fadeBPO(LED2);
tobyspark 0:87aab40d5806 143
tobyspark 5:f8b285ca41ba 144 DigitalOut dmxDirectionDOUT(kMBED_DOUT_RS485_TXHI_RXLO);
tobyspark 5:f8b285ca41ba 145
tobyspark 0:87aab40d5806 146 // SPKTVOne(PinName txPin, PinName rxPin, PinName signWritePin, PinName signErrorPin, Serial *debugSerial)
tobyspark 5:f8b285ca41ba 147 SPKTVOne tvOne(kMBED_RS232_TTLTX, kMBED_RS232_TTLRX, LED3, LED4, debug);
tobyspark 0:87aab40d5806 148
tobyspark 0:87aab40d5806 149 // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL);
tobyspark 5:f8b285ca41ba 150 SPKDisplay screen(kMBED_OLED_MOSI, kMBED_OLED_SCK, kMBED_OLED_CS, kMBED_OLED_DC, kMBED_OLED_RES, debug);
tobyspark 0:87aab40d5806 151
tobyspark 11:0783cfbeb746 152 // Saved Settings
tobyspark 11:0783cfbeb746 153 SPKSettings settings;
tobyspark 11:0783cfbeb746 154
tobyspark 0:87aab40d5806 155 // Menu
tobyspark 0:87aab40d5806 156 SPKMenu *selectedMenu;
tobyspark 23:909928cafb95 157 SPKMenu mainMenu;
tobyspark 23:909928cafb95 158 SPKMenu resolutionMenu;
tobyspark 12:c270870bdd23 159
tobyspark 24:49c6624119ae 160 SPKMenu mixModeMenu;
tobyspark 24:49c6624119ae 161 SPKMenu mixModeAdditiveMenu;
tobyspark 30:873979018850 162 enum { mixBlend, mixAdditive, mixKey }; // additive will require custom TVOne firmware.
tobyspark 30:873979018850 163 int mixMode = mixBlend; // Start with safe mix mode, and test to get out of it. Safe mode will work with inputs missing and without hold frames.
tobyspark 29:95a7efe30527 164 float fadeCurve = 0.0f; // 0 = "X", ie. as per blend, 1 = "/\", ie. as per additive <-- pictograms!
tobyspark 22:90054fe6d86c 165
tobyspark 23:909928cafb95 166 SPKMenu commsMenu;
tobyspark 5:f8b285ca41ba 167 enum { commsNone, commsOSC, commsArtNet, commsDMXIn, commsDMXOut};
tobyspark 5:f8b285ca41ba 168 int commsMode = commsNone;
tobyspark 22:90054fe6d86c 169
tobyspark 23:909928cafb95 170 SPKMenu advancedMenu;
tobyspark 30:873979018850 171 enum { advancedHDCPOn, advancedHDCPOff, advancedEDIDPassthrough, advancedEDIDInternal, advancedTestSources, advancedConformProcessor, advancedLoadDefaults, advancedSelfTest, advancedSetResolutions };
tobyspark 1:f9fca21102e0 172
tobyspark 5:f8b285ca41ba 173 // RJ45 Comms
tobyspark 5:f8b285ca41ba 174 enum { rj45Ethernet = 0, rj45DMX = 1}; // These values from circuit
tobyspark 5:f8b285ca41ba 175 int rj45Mode = -1;
tobyspark 1:f9fca21102e0 176 EthernetNetIf *ethernet = NULL;
tobyspark 1:f9fca21102e0 177 OSCClass *osc = NULL;
tobyspark 3:033d2b7768f3 178 OSCMessage recMessage;
tobyspark 3:033d2b7768f3 179 DmxArtNet *artNet = NULL;
tobyspark 5:f8b285ca41ba 180 DMX *dmx = NULL;
tobyspark 0:87aab40d5806 181
tobyspark 3:033d2b7768f3 182 // Fade logic constants
tobyspark 0:87aab40d5806 183 const float xFadeTolerance = 0.05;
tobyspark 0:87aab40d5806 184 const float fadeUpTolerance = 0.05;
tobyspark 0:87aab40d5806 185
tobyspark 0:87aab40d5806 186 // A&B Fade as resolved percent
tobyspark 0:87aab40d5806 187 int fadeAPercent = 0;
tobyspark 0:87aab40d5806 188 int fadeBPercent = 0;
tobyspark 17:fc68d40b8b1f 189 int oldFadeAPercent = 0;
tobyspark 17:fc68d40b8b1f 190 int oldFadeBPercent = 0;
tobyspark 0:87aab40d5806 191
tobyspark 0:87aab40d5806 192 // Tap button states
tobyspark 5:f8b285ca41ba 193 bool tapLeftWasFirstPressed = false;
tobyspark 0:87aab40d5806 194
tobyspark 0:87aab40d5806 195 // Key mode parameters
tobyspark 0:87aab40d5806 196 int keyerParamsSet = -1; // last keyParams index uploaded to unit
tobyspark 0:87aab40d5806 197
tobyspark 30:873979018850 198 // TVOne input sources stable flag
tobyspark 30:873979018850 199 bool tvOneRGB1Stable = true; // init true as this is conformed state of mixer, ie. RGB1 not SIS1
tobyspark 30:873979018850 200 bool tvOneRGB2Stable = true;
tobyspark 30:873979018850 201
tobyspark 3:033d2b7768f3 202 void processOSC(float &xFade, float &fadeUp) {
tobyspark 25:3b519ef70341 203 string statusMessage;
tobyspark 3:033d2b7768f3 204
tobyspark 3:033d2b7768f3 205 if (!strcmp( recMessage.getTopAddress() , "dvimxr" ))
tobyspark 3:033d2b7768f3 206 {
tobyspark 25:3b519ef70341 207 statusMessage = "OSC: /dvimxr";
tobyspark 3:033d2b7768f3 208 if (!strcmp( recMessage.getSubAddress() , "xFade" ))
tobyspark 25:3b519ef70341 209 {
tobyspark 25:3b519ef70341 210 if (recMessage.getArgNum() == 1)
tobyspark 25:3b519ef70341 211 if (recMessage.getTypeTag(0) == 'f')
tobyspark 25:3b519ef70341 212 {
tobyspark 25:3b519ef70341 213 xFade = recMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 214 char buffer[15];
tobyspark 26:0299f8760715 215 snprintf(buffer, kStringBufferLength, "/xFade %1.2f", xFade);
tobyspark 25:3b519ef70341 216 statusMessage += buffer;
tobyspark 25:3b519ef70341 217 }
tobyspark 25:3b519ef70341 218 }
tobyspark 25:3b519ef70341 219 else if (!strcmp( recMessage.getSubAddress() , "fadeUp" ))
tobyspark 25:3b519ef70341 220 {
tobyspark 3:033d2b7768f3 221 if (recMessage.getArgNum() == 1)
tobyspark 3:033d2b7768f3 222 if (recMessage.getTypeTag(0) == 'f')
tobyspark 3:033d2b7768f3 223 {
tobyspark 25:3b519ef70341 224 fadeUp = recMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 225 char buffer[15];
tobyspark 26:0299f8760715 226 snprintf(buffer, kStringBufferLength, "/fadeUp %1.2f", fadeUp);
tobyspark 25:3b519ef70341 227 statusMessage += buffer;
tobyspark 3:033d2b7768f3 228 }
tobyspark 25:3b519ef70341 229 }
tobyspark 25:3b519ef70341 230 else
tobyspark 25:3b519ef70341 231 {
tobyspark 25:3b519ef70341 232 statusMessage += recMessage.getSubAddress();
tobyspark 25:3b519ef70341 233 statusMessage += " - Ignoring";
tobyspark 25:3b519ef70341 234 }
tobyspark 3:033d2b7768f3 235 }
tobyspark 3:033d2b7768f3 236 else
tobyspark 3:033d2b7768f3 237 {
tobyspark 25:3b519ef70341 238 statusMessage = "OSC: ";
tobyspark 25:3b519ef70341 239 statusMessage += recMessage.getTopAddress();
tobyspark 25:3b519ef70341 240 statusMessage += " - Ignoring";
tobyspark 3:033d2b7768f3 241 }
tobyspark 3:033d2b7768f3 242
tobyspark 3:033d2b7768f3 243 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 244 screen.textToBuffer(statusMessage, kCommsStatusLine);
tobyspark 3:033d2b7768f3 245 screen.sendBuffer();
tobyspark 25:3b519ef70341 246 if (debug) debug->printf("%s \r\n", statusMessage.c_str());
tobyspark 3:033d2b7768f3 247
tobyspark 3:033d2b7768f3 248 }
tobyspark 3:033d2b7768f3 249
tobyspark 8:d46cc49f0f37 250 void processArtNet(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 251 {
tobyspark 3:033d2b7768f3 252 screen.clearBufferRow(kCommsStatusLine);
tobyspark 3:033d2b7768f3 253 screen.textToBuffer("ArtNet activity", kCommsStatusLine);
tobyspark 3:033d2b7768f3 254 screen.sendBuffer();
tobyspark 3:033d2b7768f3 255 if (debug) debug->printf("ArtNet activity");
tobyspark 3:033d2b7768f3 256 }
tobyspark 0:87aab40d5806 257
tobyspark 8:d46cc49f0f37 258 void processDMXIn(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 259 {
tobyspark 26:0299f8760715 260 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 261
tobyspark 5:f8b285ca41ba 262 int xFadeDMX = dmx->get(kDMXInChannelXFade);
tobyspark 7:e6717468c18d 263 int fadeUpDMX = dmx->get(kDMXInChannelFadeUp);
tobyspark 5:f8b285ca41ba 264
tobyspark 5:f8b285ca41ba 265 xFade = (float)xFadeDMX/255;
tobyspark 5:f8b285ca41ba 266 fadeUp = (float)fadeUpDMX/255;
tobyspark 5:f8b285ca41ba 267
tobyspark 5:f8b285ca41ba 268 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 269 snprintf(statusMessageBuffer, kStringBufferLength, "DMX In: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 270 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 5:f8b285ca41ba 271 screen.sendBuffer();
tobyspark 25:3b519ef70341 272 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 273 }
tobyspark 5:f8b285ca41ba 274
tobyspark 8:d46cc49f0f37 275 void processDMXOut(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 276 {
tobyspark 26:0299f8760715 277 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 278
tobyspark 5:f8b285ca41ba 279 int xFadeDMX = xFade*255;
tobyspark 5:f8b285ca41ba 280 int fadeUpDMX = fadeUp*255;
tobyspark 5:f8b285ca41ba 281
tobyspark 5:f8b285ca41ba 282 dmx->put(kDMXOutChannelXFade, xFadeDMX);
tobyspark 5:f8b285ca41ba 283 dmx->put(kDMXOutChannelFadeUp, fadeUpDMX);
tobyspark 5:f8b285ca41ba 284
tobyspark 5:f8b285ca41ba 285 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 286 snprintf(statusMessageBuffer, kStringBufferLength, "DMX Out: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 287 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 5:f8b285ca41ba 288 screen.sendBuffer();
tobyspark 25:3b519ef70341 289 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 290 }
tobyspark 0:87aab40d5806 291
tobyspark 8:d46cc49f0f37 292 inline float fadeCalc (const float AIN, const float tolerance)
tobyspark 8:d46cc49f0f37 293 {
tobyspark 0:87aab40d5806 294 float pos ;
tobyspark 0:87aab40d5806 295 if (AIN < tolerance) pos = 0;
tobyspark 0:87aab40d5806 296 else if (AIN > 1.0 - tolerance) pos = 1;
tobyspark 0:87aab40d5806 297 else pos = (AIN - tolerance) / (1 - 2*tolerance);
tobyspark 0:87aab40d5806 298 if (debug && false) debug->printf("fadeCalc in: %f out: %f \r\n", AIN, pos);
tobyspark 0:87aab40d5806 299 return pos;
tobyspark 0:87aab40d5806 300 }
tobyspark 0:87aab40d5806 301
tobyspark 30:873979018850 302 bool handleTVOneSources()
tobyspark 30:873979018850 303 {
tobyspark 30:873979018850 304 bool ok = true;
tobyspark 30:873979018850 305
tobyspark 30:873979018850 306 int32_t payload = 0;
tobyspark 30:873979018850 307
tobyspark 30:873979018850 308 ok = ok && tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 30:873979018850 309 bool RGB1 = (payload == 1);
tobyspark 30:873979018850 310
tobyspark 30:873979018850 311 ok = ok && tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 30:873979018850 312 bool RGB2 = (payload == 1);
tobyspark 30:873979018850 313
tobyspark 30:873979018850 314 string tvOneDetectString;
tobyspark 30:873979018850 315 if (!ok)
tobyspark 30:873979018850 316 {
tobyspark 30:873979018850 317 tvOneDetectString = "TVOne: link failed";
tobyspark 30:873979018850 318 }
tobyspark 30:873979018850 319 else if (!RGB1 || !RGB2)
tobyspark 30:873979018850 320 {
tobyspark 30:873979018850 321 if (!RGB1 && !RGB2) tvOneDetectString = "TVOne: no sources";
tobyspark 30:873979018850 322 else if (!RGB1) tvOneDetectString = "TVOne: no right source";
tobyspark 30:873979018850 323 else if (!RGB2) tvOneDetectString = "TVOne: no left source";
tobyspark 30:873979018850 324 }
tobyspark 30:873979018850 325 else
tobyspark 30:873979018850 326 {
tobyspark 30:873979018850 327 tvOneDetectString = "TVOne: OK";
tobyspark 30:873979018850 328 }
tobyspark 30:873979018850 329
tobyspark 30:873979018850 330 if (RGB1 && !tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 30:873979018850 331 if (RGB2 && !tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 30:873979018850 332 if (!RGB1 && tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS1);
tobyspark 30:873979018850 333 if (!RGB2 && tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2);
tobyspark 30:873979018850 334
tobyspark 30:873979018850 335 if (RGB1 != tvOneRGB1Stable || RGB2 != tvOneRGB2Stable)
tobyspark 30:873979018850 336 {
tobyspark 30:873979018850 337 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 30:873979018850 338 screen.textToBuffer(tvOneDetectString, kTVOneStatusLine);
tobyspark 30:873979018850 339 screen.sendBuffer();
tobyspark 30:873979018850 340 }
tobyspark 30:873979018850 341
tobyspark 30:873979018850 342 tvOneRGB1Stable = RGB1;
tobyspark 30:873979018850 343 tvOneRGB2Stable = RGB2;
tobyspark 30:873979018850 344
tobyspark 30:873979018850 345 return ok;
tobyspark 30:873979018850 346 }
tobyspark 30:873979018850 347
tobyspark 8:d46cc49f0f37 348 bool setKeyParamsTo(int index)
tobyspark 8:d46cc49f0f37 349 {
tobyspark 0:87aab40d5806 350 // Only spend the time uploading six parameters if we need to
tobyspark 0:87aab40d5806 351 // Might want to bounds check here
tobyspark 0:87aab40d5806 352
tobyspark 9:f83eadd8917a 353 bool ok;
tobyspark 0:87aab40d5806 354
tobyspark 0:87aab40d5806 355 if (index != keyerParamsSet)
tobyspark 0:87aab40d5806 356 {
tobyspark 11:0783cfbeb746 357 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, settings.keyerParamSet(index)[0]);
tobyspark 11:0783cfbeb746 358 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, settings.keyerParamSet(index)[1]);
tobyspark 11:0783cfbeb746 359 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, settings.keyerParamSet(index)[2]);
tobyspark 11:0783cfbeb746 360 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, settings.keyerParamSet(index)[3]);
tobyspark 11:0783cfbeb746 361 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, settings.keyerParamSet(index)[4]);
tobyspark 11:0783cfbeb746 362 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, settings.keyerParamSet(index)[5]);
tobyspark 0:87aab40d5806 363
tobyspark 0:87aab40d5806 364 keyerParamsSet = index;
tobyspark 9:f83eadd8917a 365 }
tobyspark 9:f83eadd8917a 366 else
tobyspark 9:f83eadd8917a 367 {
tobyspark 9:f83eadd8917a 368 ok = true;
tobyspark 9:f83eadd8917a 369 }
tobyspark 0:87aab40d5806 370
tobyspark 0:87aab40d5806 371 return ok;
tobyspark 0:87aab40d5806 372 }
tobyspark 0:87aab40d5806 373
tobyspark 24:49c6624119ae 374 void actionMixMode()
tobyspark 24:49c6624119ae 375 {
tobyspark 24:49c6624119ae 376 bool ok = true;
tobyspark 25:3b519ef70341 377 string sentOK;
tobyspark 26:0299f8760715 378 char sentMSGBuffer[kStringBufferLength];
tobyspark 24:49c6624119ae 379
tobyspark 24:49c6624119ae 380 // Set Keyer
tobyspark 24:49c6624119ae 381 if (mixMode < mixKey)
tobyspark 24:49c6624119ae 382 {
tobyspark 30:873979018850 383 if (mixMode == mixBlend)
tobyspark 24:49c6624119ae 384 {
tobyspark 24:49c6624119ae 385 // Waiting on TV One...
tobyspark 24:49c6624119ae 386 }
tobyspark 24:49c6624119ae 387 else if (mixMode == mixAdditive)
tobyspark 24:49c6624119ae 388 {
tobyspark 24:49c6624119ae 389 // Waiting on TV One...
tobyspark 24:49c6624119ae 390 }
tobyspark 24:49c6624119ae 391
tobyspark 24:49c6624119ae 392 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false);
tobyspark 26:0299f8760715 393 snprintf(sentMSGBuffer, kStringBufferLength, "Keyer Off");
tobyspark 24:49c6624119ae 394 }
tobyspark 24:49c6624119ae 395 else
tobyspark 24:49c6624119ae 396 {
tobyspark 25:3b519ef70341 397 int index = mixMode - mixKey;
tobyspark 25:3b519ef70341 398
tobyspark 24:49c6624119ae 399 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true);
tobyspark 24:49c6624119ae 400 ok = ok && setKeyParamsTo(index);
tobyspark 25:3b519ef70341 401
tobyspark 26:0299f8760715 402 snprintf(sentMSGBuffer, kStringBufferLength, "Keyer On with %i", index);
tobyspark 24:49c6624119ae 403 }
tobyspark 24:49c6624119ae 404
tobyspark 24:49c6624119ae 405 if (ok) sentOK = "Sent:";
tobyspark 24:49c6624119ae 406 else sentOK = "Send Error:";
tobyspark 24:49c6624119ae 407
tobyspark 24:49c6624119ae 408 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 25:3b519ef70341 409 screen.textToBuffer(sentOK + sentMSGBuffer, kTVOneStatusLine);
tobyspark 24:49c6624119ae 410
tobyspark 24:49c6624119ae 411 if (debug) { debug->printf("Changing mix mode"); }
tobyspark 24:49c6624119ae 412 }
tobyspark 24:49c6624119ae 413
tobyspark 24:49c6624119ae 414
tobyspark 17:fc68d40b8b1f 415 bool conformProcessor()
tobyspark 17:fc68d40b8b1f 416 {
tobyspark 17:fc68d40b8b1f 417 bool ok = true;
tobyspark 17:fc68d40b8b1f 418
tobyspark 17:fc68d40b8b1f 419 int32_t on = 1;
tobyspark 17:fc68d40b8b1f 420 int32_t off = 0;
tobyspark 20:8b92d7922c48 421
tobyspark 20:8b92d7922c48 422 // Independent output
tobyspark 30:873979018850 423 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionMode, 2);
tobyspark 20:8b92d7922c48 424 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputEnable, on);
tobyspark 20:8b92d7922c48 425 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsLockMethod, off);
tobyspark 17:fc68d40b8b1f 426
tobyspark 17:fc68d40b8b1f 427 // Make sure our windows exist
tobyspark 17:fc68d40b8b1f 428 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 17:fc68d40b8b1f 429 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 18:ebe5da639a6a 430 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsLayerPriority, 0);
tobyspark 18:ebe5da639a6a 431 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsLayerPriority, 1);
tobyspark 17:fc68d40b8b1f 432
tobyspark 17:fc68d40b8b1f 433 // Assign inputs to windows, so that left on the crossfader is left on the processor viewed from front
tobyspark 17:fc68d40b8b1f 434 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 17:fc68d40b8b1f 435 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 17:fc68d40b8b1f 436
tobyspark 17:fc68d40b8b1f 437 // Set scaling to fit source within output, maintaining aspect ratio
tobyspark 17:fc68d40b8b1f 438 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 17:fc68d40b8b1f 439 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDB, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 17:fc68d40b8b1f 440 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 17:fc68d40b8b1f 441 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDB, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 17:fc68d40b8b1f 442 int32_t fit = 1;
tobyspark 17:fc68d40b8b1f 443 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 17:fc68d40b8b1f 444 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 17:fc68d40b8b1f 445
tobyspark 17:fc68d40b8b1f 446 // On source loss, hold on the last frame received.
tobyspark 17:fc68d40b8b1f 447 int32_t freeze = 1;
tobyspark 17:fc68d40b8b1f 448 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 17:fc68d40b8b1f 449 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 17:fc68d40b8b1f 450
tobyspark 30:873979018850 451 // Set resolution and fade levels for maximum chance of being seen
tobyspark 30:873979018850 452 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, kTV1ResolutionVGA);
tobyspark 30:873979018850 453 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, 7);
tobyspark 30:873979018850 454 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, 7);
tobyspark 30:873979018850 455 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, 100);
tobyspark 30:873979018850 456 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, 100);
tobyspark 30:873979018850 457
tobyspark 30:873979018850 458 // Save current state for power on
tobyspark 30:873979018850 459 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 17:fc68d40b8b1f 460
tobyspark 17:fc68d40b8b1f 461 return ok;
tobyspark 17:fc68d40b8b1f 462 }
tobyspark 17:fc68d40b8b1f 463
tobyspark 17:fc68d40b8b1f 464 void selfTest()
tobyspark 17:fc68d40b8b1f 465 {
tobyspark 17:fc68d40b8b1f 466 /* SELF TEST - Pixels
tobyspark 17:fc68d40b8b1f 467 * Clicking &#65533;self-test&#65533; menu will display a solid lit screen. Check all pixels lit.
tobyspark 17:fc68d40b8b1f 468 * Verified: Display
tobyspark 17:fc68d40b8b1f 469 */
tobyspark 17:fc68d40b8b1f 470
tobyspark 17:fc68d40b8b1f 471 screen.imageToBuffer(spkDisplayAllPixelsOn);
tobyspark 17:fc68d40b8b1f 472 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 473
tobyspark 17:fc68d40b8b1f 474 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 475 {
tobyspark 17:fc68d40b8b1f 476 // do nothing, wait for press
tobyspark 17:fc68d40b8b1f 477 }
tobyspark 17:fc68d40b8b1f 478
tobyspark 17:fc68d40b8b1f 479 /* SELF TEST - Mixing Controls
tobyspark 17:fc68d40b8b1f 480 * Clicking again will prompt to check crossfader, fade to black and tap buttons. Check movement of physical controls against 0.0-1.0 values on- screen.
tobyspark 17:fc68d40b8b1f 481 * Verified: Mixing controls.
tobyspark 17:fc68d40b8b1f 482 */
tobyspark 17:fc68d40b8b1f 483
tobyspark 17:fc68d40b8b1f 484 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 485 screen.textToBuffer("Self test - Mixing Controls", 0);
tobyspark 17:fc68d40b8b1f 486
tobyspark 17:fc68d40b8b1f 487 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 488 {
tobyspark 26:0299f8760715 489 char xFadeReadOut[kStringBufferLength];
tobyspark 26:0299f8760715 490 char fadeToBlackReadOut[kStringBufferLength];
tobyspark 26:0299f8760715 491 char tapsReadOut[kStringBufferLength];
tobyspark 17:fc68d40b8b1f 492
tobyspark 26:0299f8760715 493 snprintf(xFadeReadOut, kStringBufferLength, "Crossfade: %1.3f", xFadeAIN.read());
tobyspark 26:0299f8760715 494 snprintf(fadeToBlackReadOut, kStringBufferLength, "Fade to black: %1.3f", fadeUpAIN.read());
tobyspark 26:0299f8760715 495 snprintf(tapsReadOut, kStringBufferLength, "Tap left: %i, right: %i", tapLeftDIN.read(), tapRightDIN.read());
tobyspark 17:fc68d40b8b1f 496
tobyspark 17:fc68d40b8b1f 497 screen.clearBufferRow(1);
tobyspark 17:fc68d40b8b1f 498 screen.clearBufferRow(2);
tobyspark 17:fc68d40b8b1f 499 screen.clearBufferRow(3);
tobyspark 17:fc68d40b8b1f 500
tobyspark 25:3b519ef70341 501 screen.textToBuffer(xFadeReadOut, 1);
tobyspark 25:3b519ef70341 502 screen.textToBuffer(fadeToBlackReadOut, 2);
tobyspark 25:3b519ef70341 503 screen.textToBuffer(tapsReadOut, 3);
tobyspark 17:fc68d40b8b1f 504 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 505 }
tobyspark 17:fc68d40b8b1f 506
tobyspark 17:fc68d40b8b1f 507 /* SELF TEST - RS232
tobyspark 17:fc68d40b8b1f 508 * Click the controller menu control. Should see &#65533;RS232 test&#65533; prompt and test message. Ensure PC is displaying the test message.
tobyspark 17:fc68d40b8b1f 509 * Verified: RS232 connection.
tobyspark 17:fc68d40b8b1f 510 */
tobyspark 17:fc68d40b8b1f 511
tobyspark 17:fc68d40b8b1f 512 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 513 screen.textToBuffer("Self test - RS232", 0);
tobyspark 17:fc68d40b8b1f 514 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 515
tobyspark 17:fc68d40b8b1f 516 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 517 {
tobyspark 17:fc68d40b8b1f 518 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 519 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 520 }
tobyspark 17:fc68d40b8b1f 521
tobyspark 17:fc68d40b8b1f 522 /* SELF TEST - DMX
tobyspark 17:fc68d40b8b1f 523 * Click the controller menu control. Should see &#65533;DMX test&#65533; prompt and test message. Ensure PC is displaying the test message.
tobyspark 17:fc68d40b8b1f 524 * Verified: RS485 connection and DMX library.
tobyspark 17:fc68d40b8b1f 525 */
tobyspark 17:fc68d40b8b1f 526
tobyspark 17:fc68d40b8b1f 527 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 528 screen.textToBuffer("Self test - DMX", 0);
tobyspark 17:fc68d40b8b1f 529 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 530
tobyspark 17:fc68d40b8b1f 531 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 532 {
tobyspark 17:fc68d40b8b1f 533 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 534 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 535 }
tobyspark 17:fc68d40b8b1f 536
tobyspark 17:fc68d40b8b1f 537 /* SELF TEST - OSC
tobyspark 17:fc68d40b8b1f 538 * Click the controller menu control. Should see &#65533;OSC test&#65533; prompt and test message. Ensure PC is displaying the test message.
tobyspark 17:fc68d40b8b1f 539 * Verified: Ethernet connection and OSC library.
tobyspark 17:fc68d40b8b1f 540 */
tobyspark 17:fc68d40b8b1f 541
tobyspark 17:fc68d40b8b1f 542 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 543 screen.textToBuffer("Self test - DMX", 0);
tobyspark 17:fc68d40b8b1f 544 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 545
tobyspark 17:fc68d40b8b1f 546 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 547 {
tobyspark 17:fc68d40b8b1f 548 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 549 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 550 }
tobyspark 17:fc68d40b8b1f 551
tobyspark 17:fc68d40b8b1f 552 /* SELF TEST - Exit!
tobyspark 17:fc68d40b8b1f 553 * To do this, we could just do nothing but we'd need to recreate screen and comms as they were.
tobyspark 17:fc68d40b8b1f 554 * Instead, lets just restart the mbed
tobyspark 17:fc68d40b8b1f 555 */
tobyspark 17:fc68d40b8b1f 556
tobyspark 17:fc68d40b8b1f 557 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 558 screen.textToBuffer("Self test complete", 0);
tobyspark 17:fc68d40b8b1f 559 screen.textToBuffer("Press to restart controller", 1);
tobyspark 17:fc68d40b8b1f 560 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 561
tobyspark 17:fc68d40b8b1f 562 while(!menuEnc.hasPressed()) {}
tobyspark 17:fc68d40b8b1f 563
tobyspark 17:fc68d40b8b1f 564 mbed_reset();
tobyspark 17:fc68d40b8b1f 565 }
tobyspark 17:fc68d40b8b1f 566
tobyspark 27:27851d3d2bba 567 void setResolutionMenuItems()
tobyspark 27:27851d3d2bba 568 {
tobyspark 27:27851d3d2bba 569 resolutionMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 570 for (int i=0; i < settings.resolutionsCount(); i++)
tobyspark 27:27851d3d2bba 571 {
tobyspark 27:27851d3d2bba 572 resolutionMenu.addMenuItem(SPKMenuItem(settings.resolutionName(i), settings.resolutionIndex(i), settings.resolutionEDIDIndex(i)));
tobyspark 27:27851d3d2bba 573 }
tobyspark 27:27851d3d2bba 574 resolutionMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 575 }
tobyspark 27:27851d3d2bba 576
tobyspark 27:27851d3d2bba 577 void setMixModeMenuItems()
tobyspark 27:27851d3d2bba 578 {
tobyspark 27:27851d3d2bba 579 mixModeMenu.clearMenuItems();
tobyspark 29:95a7efe30527 580 mixModeMenu.addMenuItem(SPKMenuItem("Crossfade", &mixModeAdditiveMenu));
tobyspark 27:27851d3d2bba 581 for (int i=0; i < settings.keyerSetCount(); i++)
tobyspark 27:27851d3d2bba 582 {
tobyspark 27:27851d3d2bba 583 mixModeMenu.addMenuItem(SPKMenuItem(settings.keyerParamName(i), mixKey+i));
tobyspark 27:27851d3d2bba 584 }
tobyspark 27:27851d3d2bba 585 mixModeMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 586 }
tobyspark 27:27851d3d2bba 587
tobyspark 27:27851d3d2bba 588 void setCommsMenuItems()
tobyspark 27:27851d3d2bba 589 {
tobyspark 27:27851d3d2bba 590 if (rj45Mode == rj45Ethernet)
tobyspark 27:27851d3d2bba 591 {
tobyspark 27:27851d3d2bba 592 commsMenu.title = "Network Mode [Ethernet]";
tobyspark 27:27851d3d2bba 593 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 594 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 595 commsMenu.addMenuItem(SPKMenuItem("OSC", commsOSC));
tobyspark 27:27851d3d2bba 596 commsMenu.addMenuItem(SPKMenuItem("ArtNet", commsArtNet));
tobyspark 27:27851d3d2bba 597 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 598 }
tobyspark 27:27851d3d2bba 599 else if (rj45Mode == rj45DMX)
tobyspark 27:27851d3d2bba 600 {
tobyspark 27:27851d3d2bba 601 commsMenu.title = "Network Mode [DMX]";
tobyspark 27:27851d3d2bba 602 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 603 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 604 commsMenu.addMenuItem(SPKMenuItem("DMX In", commsDMXIn));
tobyspark 27:27851d3d2bba 605 commsMenu.addMenuItem(SPKMenuItem("DMX Out", commsDMXOut));
tobyspark 27:27851d3d2bba 606 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 607 }
tobyspark 27:27851d3d2bba 608 }
tobyspark 27:27851d3d2bba 609
tobyspark 0:87aab40d5806 610 int main()
tobyspark 0:87aab40d5806 611 {
tobyspark 0:87aab40d5806 612 if (debug)
tobyspark 0:87aab40d5806 613 {
tobyspark 0:87aab40d5806 614 debug->printf("\r\n\r\n");
tobyspark 0:87aab40d5806 615 debug->printf("*spark d-fuser -----------\r\n");
tobyspark 0:87aab40d5806 616 debug->printf(" debug channel\r\n");
tobyspark 0:87aab40d5806 617 }
tobyspark 2:50043054e4f7 618
tobyspark 2:50043054e4f7 619 // Set display font
tobyspark 2:50043054e4f7 620 screen.fontStartCharacter = &characterBytesStartChar;
tobyspark 2:50043054e4f7 621 screen.fontEndCharacter = &characterBytesEndChar;
tobyspark 2:50043054e4f7 622 screen.fontCharacters = characterBytes;
tobyspark 2:50043054e4f7 623
tobyspark 0:87aab40d5806 624 // Splash screen
tobyspark 30:873979018850 625 string softwareLine = "SW ";
tobyspark 30:873979018850 626 softwareLine += kSPKDFSoftwareVersion;
tobyspark 2:50043054e4f7 627 screen.imageToBuffer(spkDisplayLogo);
tobyspark 0:87aab40d5806 628 screen.textToBuffer("SPK:D-Fuser",0);
tobyspark 30:873979018850 629 screen.textToBuffer(softwareLine,1);
tobyspark 5:f8b285ca41ba 630 screen.sendBuffer();
tobyspark 0:87aab40d5806 631
tobyspark 11:0783cfbeb746 632 // Load saved settings
tobyspark 16:52484666b323 633 bool settingsAreCustom = false;
tobyspark 16:52484666b323 634 settingsAreCustom = settings.load(kSPKDFSettingsFilename);
tobyspark 30:873979018850 635 if (settingsAreCustom)
tobyspark 30:873979018850 636 {
tobyspark 30:873979018850 637 softwareLine += "; ini OK";
tobyspark 30:873979018850 638 screen.textToBuffer(softwareLine, 1);
tobyspark 30:873979018850 639 }
tobyspark 30:873979018850 640
tobyspark 0:87aab40d5806 641 // Set menu structure
tobyspark 0:87aab40d5806 642 mixModeMenu.title = "Mix Mode";
tobyspark 27:27851d3d2bba 643 setMixModeMenuItems();
tobyspark 24:49c6624119ae 644
tobyspark 29:95a7efe30527 645 mixModeAdditiveMenu.title = "Crossfade";
tobyspark 30:873979018850 646 mixModeAdditiveMenu.addMenuItem(SPKMenuItem("[title overridden]", &mixModeMenu, true));
tobyspark 0:87aab40d5806 647
tobyspark 0:87aab40d5806 648 resolutionMenu.title = "Resolution";
tobyspark 27:27851d3d2bba 649 setResolutionMenuItems();
tobyspark 0:87aab40d5806 650
tobyspark 27:27851d3d2bba 651 commsMenu.title = "Network Mode";
tobyspark 27:27851d3d2bba 652 setCommsMenuItems();
tobyspark 23:909928cafb95 653
tobyspark 15:4b394c64b461 654 advancedMenu.title = "Troubleshooting";
tobyspark 23:909928cafb95 655 advancedMenu.addMenuItem(SPKMenuItem("HDCP Off", advancedHDCPOff));
tobyspark 23:909928cafb95 656 advancedMenu.addMenuItem(SPKMenuItem("HDCP On", advancedHDCPOn));
tobyspark 30:873979018850 657 advancedMenu.addMenuItem(SPKMenuItem("Test Processor Sources", advancedTestSources));
tobyspark 23:909928cafb95 658 advancedMenu.addMenuItem(SPKMenuItem("Conform Processor", advancedConformProcessor));
tobyspark 30:873979018850 659 //advancedMenu.addMenuItem(SPKMenuItem("EDID Passthrough", advancedEDIDPassthrough)); // have global setting of passthrough that overrides resolution sets and is saved with conform processor
tobyspark 30:873979018850 660 //advancedMenu.addMenuItem(SPKMenuItem("EDID Internal", advancedEDIDInternal));
tobyspark 30:873979018850 661 if (settingsAreCustom) advancedMenu.addMenuItem(SPKMenuItem("Revert Controller", advancedLoadDefaults));
tobyspark 23:909928cafb95 662 advancedMenu.addMenuItem(SPKMenuItem("Start Self-Test", advancedSelfTest));
tobyspark 24:49c6624119ae 663 advancedMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 23:909928cafb95 664
tobyspark 0:87aab40d5806 665 mainMenu.title = "Main Menu";
tobyspark 24:49c6624119ae 666 mainMenu.addMenuItem(SPKMenuItem(mixModeMenu.title, &mixModeMenu));
tobyspark 24:49c6624119ae 667 mainMenu.addMenuItem(SPKMenuItem(resolutionMenu.title, &resolutionMenu));
tobyspark 24:49c6624119ae 668 mainMenu.addMenuItem(SPKMenuItem(commsMenu.title, &commsMenu));
tobyspark 24:49c6624119ae 669 mainMenu.addMenuItem(SPKMenuItem(advancedMenu.title, &advancedMenu));
tobyspark 23:909928cafb95 670
tobyspark 0:87aab40d5806 671 selectedMenu = &mainMenu;
tobyspark 23:909928cafb95 672
tobyspark 0:87aab40d5806 673 // Misc I/O stuff
tobyspark 0:87aab40d5806 674
tobyspark 0:87aab40d5806 675 fadeAPO.period(0.001);
tobyspark 0:87aab40d5806 676 fadeBPO.period(0.001);
tobyspark 0:87aab40d5806 677
tobyspark 20:8b92d7922c48 678 // Test for TV One connectivity and determine unit type
tobyspark 30:873979018850 679 // TODO: Determine and fall back if not dfuser firmware?
tobyspark 30:873979018850 680 // TODO: Use software version to select resolution slots?
tobyspark 30:873979018850 681 // TODO: Use product / board type to select TVOne conform type?
tobyspark 21:f9d63cb7cedb 682 // kTV1FunctionReadSoftwareVersion
tobyspark 21:f9d63cb7cedb 683 // kTV1FunctionReadProductType
tobyspark 21:f9d63cb7cedb 684 // kTV1FunctionReadBoardType
tobyspark 21:f9d63cb7cedb 685
tobyspark 12:c270870bdd23 686 // Display menu and framing lines
tobyspark 0:87aab40d5806 687 screen.horizLineToBuffer(kMenuLine1*pixInPage - 1);
tobyspark 0:87aab40d5806 688 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 689 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 690 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 691 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 692 screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage);
tobyspark 1:f9fca21102e0 693 screen.horizLineToBuffer(kCommsStatusLine*pixInPage - 1);
tobyspark 1:f9fca21102e0 694 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 30:873979018850 695 screen.textToBuffer("TVOne: OK", kTVOneStatusLine); // handleTVOneSources may update this
tobyspark 30:873979018850 696
tobyspark 30:873979018850 697 // If we do not have two solid sources, act on this as we rely on the window having a source for crossfade behaviour
tobyspark 30:873979018850 698 // Once we've had two solid inputs, don't check any more as we're ok as the unit is set to hold on last frame.
tobyspark 30:873979018850 699 // This will update kTVOneStatusLine if necessary
tobyspark 30:873979018850 700 bool ok = handleTVOneSources();
tobyspark 30:873979018850 701
tobyspark 0:87aab40d5806 702 screen.sendBuffer();
tobyspark 0:87aab40d5806 703
tobyspark 0:87aab40d5806 704 //// CONTROLS TEST
tobyspark 0:87aab40d5806 705
tobyspark 0:87aab40d5806 706 while (0) {
tobyspark 0:87aab40d5806 707 if (debug) debug->printf("xFade: %f, fadeOut: %f, tapLeft %i, tapRight: %i encPos: %i encChange:%i encHasPressed:%i \r\n" , xFadeAIN.read(), fadeUpAIN.read(), tapLeftDIN.read(), tapRightDIN.read(), menuEnc.getPos(), menuEnc.getChange(), menuEnc.hasPressed());
tobyspark 0:87aab40d5806 708 }
tobyspark 0:87aab40d5806 709
tobyspark 0:87aab40d5806 710 //// MIXER RUN
tobyspark 0:87aab40d5806 711
tobyspark 8:d46cc49f0f37 712 while (1)
tobyspark 8:d46cc49f0f37 713 {
tobyspark 1:f9fca21102e0 714 //// Task background things
tobyspark 5:f8b285ca41ba 715 if (ethernet && rj45Mode == rj45Ethernet)
tobyspark 5:f8b285ca41ba 716 {
tobyspark 5:f8b285ca41ba 717 Net::poll();
tobyspark 5:f8b285ca41ba 718 }
tobyspark 5:f8b285ca41ba 719
tobyspark 5:f8b285ca41ba 720 //// RJ45 SWITCH
tobyspark 5:f8b285ca41ba 721
tobyspark 5:f8b285ca41ba 722 if (rj45ModeDIN != rj45Mode)
tobyspark 1:f9fca21102e0 723 {
tobyspark 23:909928cafb95 724 if (debug) debug->printf("Handling RJ45 mode change\r\n");
tobyspark 27:27851d3d2bba 725
tobyspark 5:f8b285ca41ba 726 // update state
tobyspark 5:f8b285ca41ba 727 rj45Mode = rj45ModeDIN;
tobyspark 27:27851d3d2bba 728
tobyspark 27:27851d3d2bba 729 setCommsMenuItems();
tobyspark 5:f8b285ca41ba 730
tobyspark 5:f8b285ca41ba 731 // cancel old comms
tobyspark 5:f8b285ca41ba 732 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 733 commsMenu = commsMode;
tobyspark 5:f8b285ca41ba 734
tobyspark 5:f8b285ca41ba 735 // refresh display
tobyspark 23:909928cafb95 736 if (selectedMenu == &commsMenu)
tobyspark 23:909928cafb95 737 {
tobyspark 23:909928cafb95 738 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 23:909928cafb95 739 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 23:909928cafb95 740 }
tobyspark 5:f8b285ca41ba 741 if (rj45Mode == rj45Ethernet) screen.textToBuffer("RJ45: Ethernet Engaged", kCommsStatusLine);
tobyspark 5:f8b285ca41ba 742 if (rj45Mode == rj45DMX) screen.textToBuffer("RJ45: DMX Engaged", kCommsStatusLine);
tobyspark 1:f9fca21102e0 743 }
tobyspark 1:f9fca21102e0 744
tobyspark 0:87aab40d5806 745 //// MENU
tobyspark 0:87aab40d5806 746
tobyspark 0:87aab40d5806 747 int menuChange = menuEnc.getChange();
tobyspark 0:87aab40d5806 748
tobyspark 0:87aab40d5806 749 // Update GUI
tobyspark 0:87aab40d5806 750 if (menuChange != 0)
tobyspark 0:87aab40d5806 751 {
tobyspark 24:49c6624119ae 752 if (selectedMenu->selectedItem().handlingControls)
tobyspark 24:49c6624119ae 753 {
tobyspark 24:49c6624119ae 754 if (selectedMenu == &mixModeAdditiveMenu)
tobyspark 24:49c6624119ae 755 {
tobyspark 24:49c6624119ae 756 fadeCurve += menuChange * 0.05;
tobyspark 24:49c6624119ae 757 if (fadeCurve > 1.0f) fadeCurve = 1.0f;
tobyspark 24:49c6624119ae 758 if (fadeCurve < 0.0f) fadeCurve = 0.0f;
tobyspark 29:95a7efe30527 759
tobyspark 29:95a7efe30527 760 mixMode = (fadeCurve > 0.0f) ? mixAdditive: mixBlend;
tobyspark 29:95a7efe30527 761
tobyspark 24:49c6624119ae 762 screen.clearBufferRow(kMenuLine2);
tobyspark 29:95a7efe30527 763 screen.textToBuffer("Blend [ ----- ] Add", kMenuLine2);
tobyspark 29:95a7efe30527 764 screen.characterToBuffer('X', 38 + fadeCurve*20.0f, kMenuLine2);
tobyspark 24:49c6624119ae 765
tobyspark 24:49c6624119ae 766 if (debug) debug->printf("Fade curve changed by %i to %f", menuChange, fadeCurve);
tobyspark 24:49c6624119ae 767 }
tobyspark 24:49c6624119ae 768 }
tobyspark 24:49c6624119ae 769 else
tobyspark 24:49c6624119ae 770 {
tobyspark 24:49c6624119ae 771 if (debug) debug->printf("Menu changed by %i\r\n", menuChange);
tobyspark 24:49c6624119ae 772
tobyspark 24:49c6624119ae 773 *selectedMenu = selectedMenu->selectedIndex() + menuChange;
tobyspark 24:49c6624119ae 774
tobyspark 24:49c6624119ae 775 // update OLED line 2 here
tobyspark 24:49c6624119ae 776 screen.clearBufferRow(kMenuLine2);
tobyspark 24:49c6624119ae 777 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 24:49c6624119ae 778
tobyspark 24:49c6624119ae 779 if (debug) debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 24:49c6624119ae 780 }
tobyspark 0:87aab40d5806 781 }
tobyspark 0:87aab40d5806 782
tobyspark 0:87aab40d5806 783 // Action menu item
tobyspark 0:87aab40d5806 784 if (menuEnc.hasPressed())
tobyspark 0:87aab40d5806 785 {
tobyspark 0:87aab40d5806 786 if (debug) debug->printf("Action Menu Item!\r\n");
tobyspark 21:f9d63cb7cedb 787
tobyspark 0:87aab40d5806 788 // Are we changing menus?
tobyspark 23:909928cafb95 789 if (selectedMenu->selectedItem().type == SPKMenuItem::changesToMenu)
tobyspark 0:87aab40d5806 790 {
tobyspark 0:87aab40d5806 791 // point selected menu to the new menu
tobyspark 23:909928cafb95 792 selectedMenu = selectedMenu->selectedItem().payload.menu;
tobyspark 0:87aab40d5806 793
tobyspark 0:87aab40d5806 794 // update OLED lines 1&2
tobyspark 0:87aab40d5806 795 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 796 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 797 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 798 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 799
tobyspark 0:87aab40d5806 800 if (debug)
tobyspark 0:87aab40d5806 801 {
tobyspark 0:87aab40d5806 802 debug->printf("\r\n");
tobyspark 0:87aab40d5806 803 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 804 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 805 }
tobyspark 24:49c6624119ae 806
tobyspark 24:49c6624119ae 807 // Are we changing menus that should have a command attached?
tobyspark 24:49c6624119ae 808 if (selectedMenu == &mixModeAdditiveMenu)
tobyspark 24:49c6624119ae 809 {
tobyspark 29:95a7efe30527 810 screen.clearBufferRow(kMenuLine2);
tobyspark 29:95a7efe30527 811 screen.textToBuffer("Blend [ ----- ] Add", kMenuLine2);
tobyspark 29:95a7efe30527 812 screen.characterToBuffer('X', 38 + fadeCurve*20.0f, kMenuLine2);
tobyspark 29:95a7efe30527 813
tobyspark 29:95a7efe30527 814 mixMode = fadeCurve > 0 ? mixAdditive : mixBlend;
tobyspark 24:49c6624119ae 815 actionMixMode();
tobyspark 24:49c6624119ae 816 }
tobyspark 0:87aab40d5806 817 }
tobyspark 0:87aab40d5806 818 // With that out of the way, we should be actioning a specific menu's payload?
tobyspark 0:87aab40d5806 819 else if (selectedMenu == &mixModeMenu)
tobyspark 0:87aab40d5806 820 {
tobyspark 23:909928cafb95 821 mixMode = mixModeMenu.selectedItem().payload.command[0];
tobyspark 24:49c6624119ae 822 actionMixMode();
tobyspark 0:87aab40d5806 823 }
tobyspark 0:87aab40d5806 824 else if (selectedMenu == &resolutionMenu)
tobyspark 0:87aab40d5806 825 {
tobyspark 9:f83eadd8917a 826 bool ok = true;
tobyspark 0:87aab40d5806 827
tobyspark 23:909928cafb95 828 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, resolutionMenu.selectedItem().payload.command[0]);
tobyspark 23:909928cafb95 829 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedItem().payload.command[1]);
tobyspark 23:909928cafb95 830 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedItem().payload.command[1]);
tobyspark 0:87aab40d5806 831
tobyspark 25:3b519ef70341 832 string sentOK;
tobyspark 0:87aab40d5806 833 if (ok) sentOK = "Sent: ";
tobyspark 0:87aab40d5806 834 else sentOK = "Send Error: ";
tobyspark 0:87aab40d5806 835
tobyspark 26:0299f8760715 836 char sentMSGBuffer[kStringBufferLength];
tobyspark 26:0299f8760715 837 snprintf(sentMSGBuffer, kStringBufferLength,"Res %i, EDID %i", resolutionMenu.selectedItem().payload.command[0], resolutionMenu.selectedItem().payload.command[1]);
tobyspark 0:87aab40d5806 838
tobyspark 1:f9fca21102e0 839 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 25:3b519ef70341 840 screen.textToBuffer(sentOK + sentMSGBuffer, kTVOneStatusLine);
tobyspark 0:87aab40d5806 841
tobyspark 0:87aab40d5806 842 if (debug) { debug->printf("Changing resolution"); }
tobyspark 0:87aab40d5806 843 }
tobyspark 1:f9fca21102e0 844 else if (selectedMenu == &commsMenu)
tobyspark 1:f9fca21102e0 845 {
tobyspark 26:0299f8760715 846 string commsTypeString = "Network:";
tobyspark 26:0299f8760715 847 char commsStatusBuffer[kStringBufferLength] = "--";
tobyspark 1:f9fca21102e0 848
tobyspark 1:f9fca21102e0 849 // Tear down any existing comms
tobyspark 1:f9fca21102e0 850 // This is the action of commsNone
tobyspark 1:f9fca21102e0 851 // And also clears the way for other comms actions
tobyspark 26:0299f8760715 852 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 853 if (osc) {delete osc; osc = NULL;}
tobyspark 5:f8b285ca41ba 854 if (ethernet) {delete ethernet; ethernet = NULL;}
tobyspark 5:f8b285ca41ba 855 if (artNet) {delete artNet; artNet = NULL;}
tobyspark 5:f8b285ca41ba 856 if (dmx) {delete dmx; dmx = NULL;}
tobyspark 5:f8b285ca41ba 857
tobyspark 5:f8b285ca41ba 858 // Ensure we can't change to comms modes the hardware isn't switched to
tobyspark 23:909928cafb95 859 if (rj45Mode == rj45DMX && (commsMenu.selectedItem().payload.command[0] == commsOSC || commsMenu.selectedItem().payload.command[0] == commsArtNet))
tobyspark 1:f9fca21102e0 860 {
tobyspark 5:f8b285ca41ba 861 commsTypeString = "RJ45 not in Ethernet mode";
tobyspark 5:f8b285ca41ba 862 }
tobyspark 23:909928cafb95 863 else if (rj45Mode == rj45Ethernet && (commsMenu.selectedItem().payload.command[0] == commsDMXIn || commsMenu.selectedItem().payload.command[0] == commsDMXOut))
tobyspark 5:f8b285ca41ba 864 {
tobyspark 5:f8b285ca41ba 865 commsTypeString = "RJ45 not in DMX mode";
tobyspark 5:f8b285ca41ba 866 }
tobyspark 5:f8b285ca41ba 867 // Action!
tobyspark 23:909928cafb95 868 else if (commsMenu.selectedItem().payload.command[0] == commsOSC)
tobyspark 5:f8b285ca41ba 869 {
tobyspark 5:f8b285ca41ba 870 commsMode = commsOSC;
tobyspark 5:f8b285ca41ba 871 commsTypeString = "OSC: ";
tobyspark 1:f9fca21102e0 872
tobyspark 1:f9fca21102e0 873 ethernet = new EthernetNetIf(
tobyspark 1:f9fca21102e0 874 IpAddr(kOSCMbedIPAddress),
tobyspark 1:f9fca21102e0 875 IpAddr(kOSCMbedSubnetMask),
tobyspark 1:f9fca21102e0 876 IpAddr(kOSCMbedGateway),
tobyspark 1:f9fca21102e0 877 IpAddr(kOSCMbedDNS)
tobyspark 1:f9fca21102e0 878 );
tobyspark 3:033d2b7768f3 879
tobyspark 1:f9fca21102e0 880 EthernetErr ethError = ethernet->setup();
tobyspark 1:f9fca21102e0 881 if(ethError)
tobyspark 1:f9fca21102e0 882 {
tobyspark 1:f9fca21102e0 883 if (debug) debug->printf("Ethernet setup error, %d", ethError);
tobyspark 26:0299f8760715 884 snprintf(commsStatusBuffer, kStringBufferLength, "Ethernet setup failed");
tobyspark 5:f8b285ca41ba 885 commsMenu = commsNone;
tobyspark 1:f9fca21102e0 886 // break out of here. this setup should be a function that returns a boolean
tobyspark 1:f9fca21102e0 887 }
tobyspark 1:f9fca21102e0 888
tobyspark 1:f9fca21102e0 889 osc = new OSCClass();
tobyspark 3:033d2b7768f3 890 osc->setReceiveMessage(&recMessage);
tobyspark 1:f9fca21102e0 891 osc->begin(kOSCMbedPort);
tobyspark 1:f9fca21102e0 892
tobyspark 26:0299f8760715 893 snprintf(commsStatusBuffer, kStringBufferLength, "Listening on %i", kOSCMbedPort);
tobyspark 1:f9fca21102e0 894 }
tobyspark 23:909928cafb95 895 else if (commsMenu.selectedItem().payload.command[0] == commsArtNet)
tobyspark 1:f9fca21102e0 896 {
tobyspark 5:f8b285ca41ba 897 commsMode = commsArtNet;
tobyspark 5:f8b285ca41ba 898 commsTypeString = "ArtNet: ";
tobyspark 3:033d2b7768f3 899
tobyspark 3:033d2b7768f3 900 artNet = new DmxArtNet();
tobyspark 1:f9fca21102e0 901
tobyspark 3:033d2b7768f3 902 artNet->BindIpAddress = IpAddr(kArtNetBindIPAddress);
tobyspark 3:033d2b7768f3 903 artNet->BCastAddress = IpAddr(kArtNetBroadcastAddress);
tobyspark 3:033d2b7768f3 904
tobyspark 3:033d2b7768f3 905 artNet->InitArtPollReplyDefaults();
tobyspark 3:033d2b7768f3 906
tobyspark 3:033d2b7768f3 907 artNet->ArtPollReply.PortType[0] = 128; // output
tobyspark 3:033d2b7768f3 908 artNet->ArtPollReply.PortType[2] = 64; // input
tobyspark 3:033d2b7768f3 909 artNet->ArtPollReply.GoodInput[2] = 4;
tobyspark 3:033d2b7768f3 910
tobyspark 3:033d2b7768f3 911 artNet->Init();
tobyspark 3:033d2b7768f3 912 artNet->SendArtPollReply(); // announce to art-net nodes
tobyspark 3:033d2b7768f3 913
tobyspark 26:0299f8760715 914 snprintf(commsStatusBuffer, kStringBufferLength, "Listening");
tobyspark 1:f9fca21102e0 915 }
tobyspark 23:909928cafb95 916 else if (commsMenu.selectedItem().payload.command[0] == commsDMXIn)
tobyspark 1:f9fca21102e0 917 {
tobyspark 5:f8b285ca41ba 918 commsMode = commsDMXIn;
tobyspark 5:f8b285ca41ba 919 commsTypeString = "DMX In: ";
tobyspark 1:f9fca21102e0 920
tobyspark 5:f8b285ca41ba 921 dmxDirectionDOUT = 0;
tobyspark 5:f8b285ca41ba 922
tobyspark 5:f8b285ca41ba 923 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 1:f9fca21102e0 924 }
tobyspark 23:909928cafb95 925 else if (commsMenu.selectedItem().payload.command[0] == commsDMXOut)
tobyspark 5:f8b285ca41ba 926 {
tobyspark 5:f8b285ca41ba 927 commsMode = commsDMXOut;
tobyspark 5:f8b285ca41ba 928 commsTypeString = "DMX Out: ";
tobyspark 5:f8b285ca41ba 929
tobyspark 5:f8b285ca41ba 930 dmxDirectionDOUT = 1;
tobyspark 5:f8b285ca41ba 931
tobyspark 5:f8b285ca41ba 932 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 5:f8b285ca41ba 933 }
tobyspark 5:f8b285ca41ba 934
tobyspark 1:f9fca21102e0 935 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 936 screen.textToBuffer(commsTypeString + commsStatusBuffer, kCommsStatusLine);
tobyspark 1:f9fca21102e0 937 }
tobyspark 12:c270870bdd23 938 else if (selectedMenu == &advancedMenu)
tobyspark 12:c270870bdd23 939 {
tobyspark 23:909928cafb95 940 if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOff)
tobyspark 12:c270870bdd23 941 {
tobyspark 12:c270870bdd23 942 bool ok = false;
tobyspark 12:c270870bdd23 943
tobyspark 15:4b394c64b461 944 ok = tvOne.setHDCPOn(false);
tobyspark 12:c270870bdd23 945
tobyspark 12:c270870bdd23 946 std::string sendOK = ok ? "Sent: HDCP Off" : "Send Error: HDCP Off";
tobyspark 12:c270870bdd23 947
tobyspark 12:c270870bdd23 948 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 12:c270870bdd23 949 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 12:c270870bdd23 950 }
tobyspark 23:909928cafb95 951 else if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOn)
tobyspark 15:4b394c64b461 952 {
tobyspark 15:4b394c64b461 953 bool ok = false;
tobyspark 15:4b394c64b461 954
tobyspark 15:4b394c64b461 955 ok = tvOne.setHDCPOn(true);
tobyspark 15:4b394c64b461 956
tobyspark 15:4b394c64b461 957 std::string sendOK = ok ? "Sent: HDCP On" : "Send Error: HDCP On";
tobyspark 15:4b394c64b461 958
tobyspark 15:4b394c64b461 959 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 15:4b394c64b461 960 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 15:4b394c64b461 961 }
tobyspark 30:873979018850 962 else if (advancedMenu.selectedItem().payload.command[0] == advancedTestSources)
tobyspark 29:95a7efe30527 963 {
tobyspark 30:873979018850 964 handleTVOneSources();
tobyspark 29:95a7efe30527 965 }
tobyspark 23:909928cafb95 966 else if (advancedMenu.selectedItem().payload.command[0] == advancedConformProcessor)
tobyspark 17:fc68d40b8b1f 967 {
tobyspark 20:8b92d7922c48 968 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 20:8b92d7922c48 969 screen.textToBuffer("Conforming...", kTVOneStatusLine);
tobyspark 20:8b92d7922c48 970 screen.sendBuffer();
tobyspark 20:8b92d7922c48 971
tobyspark 17:fc68d40b8b1f 972 bool ok = conformProcessor();
tobyspark 17:fc68d40b8b1f 973
tobyspark 17:fc68d40b8b1f 974 std::string sendOK = ok ? "Conform success" : "Send Error: Conform";
tobyspark 17:fc68d40b8b1f 975
tobyspark 17:fc68d40b8b1f 976 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 17:fc68d40b8b1f 977 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 17:fc68d40b8b1f 978 }
tobyspark 23:909928cafb95 979 else if (advancedMenu.selectedItem().payload.command[0] == advancedLoadDefaults)
tobyspark 16:52484666b323 980 {
tobyspark 16:52484666b323 981 settings.loadDefaults();
tobyspark 27:27851d3d2bba 982 setMixModeMenuItems();
tobyspark 27:27851d3d2bba 983 setResolutionMenuItems();
tobyspark 16:52484666b323 984
tobyspark 16:52484666b323 985 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 16:52484666b323 986 screen.textToBuffer("Controller reverted", kTVOneStatusLine);
tobyspark 16:52484666b323 987 }
tobyspark 23:909928cafb95 988 else if (advancedMenu.selectedItem().payload.command[0] == advancedSelfTest)
tobyspark 15:4b394c64b461 989 {
tobyspark 17:fc68d40b8b1f 990 selfTest();
tobyspark 15:4b394c64b461 991 }
tobyspark 23:909928cafb95 992 else if (advancedMenu.selectedItem().payload.command[0] == advancedSetResolutions)
tobyspark 21:f9d63cb7cedb 993 {
tobyspark 21:f9d63cb7cedb 994 bool ok;
tobyspark 21:f9d63cb7cedb 995 ok = tvOne.setCustomResolutions();
tobyspark 21:f9d63cb7cedb 996
tobyspark 21:f9d63cb7cedb 997 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 21:f9d63cb7cedb 998 screen.textToBuffer(ok ? "Resolutions set" : "Res' could not be set", kTVOneStatusLine);
tobyspark 21:f9d63cb7cedb 999 }
tobyspark 12:c270870bdd23 1000 }
tobyspark 0:87aab40d5806 1001 else
tobyspark 0:87aab40d5806 1002 {
tobyspark 0:87aab40d5806 1003 if (debug) { debug->printf("Warning: No action identified"); }
tobyspark 0:87aab40d5806 1004 }
tobyspark 0:87aab40d5806 1005 }
tobyspark 0:87aab40d5806 1006
tobyspark 2:50043054e4f7 1007 // Send any updates to the display
tobyspark 2:50043054e4f7 1008 screen.sendBuffer();
tobyspark 5:f8b285ca41ba 1009
tobyspark 0:87aab40d5806 1010
tobyspark 5:f8b285ca41ba 1011 //// MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIXMIX MIX MIXMIX MIX MIX MIX MIX MIXMIX MIX MIX
tobyspark 0:87aab40d5806 1012
tobyspark 0:87aab40d5806 1013 bool updateFade = false;
tobyspark 3:033d2b7768f3 1014 float xFade = 0;
tobyspark 3:033d2b7768f3 1015 float fadeUp = 1;
tobyspark 3:033d2b7768f3 1016
tobyspark 3:033d2b7768f3 1017 //// TASK: Process control surface
tobyspark 3:033d2b7768f3 1018
tobyspark 0:87aab40d5806 1019 // Get new states of tap buttons, remembering at end of loop() assign these current values to the previous variables
tobyspark 5:f8b285ca41ba 1020 const bool tapLeft = !tapLeftDIN;
tobyspark 5:f8b285ca41ba 1021 const bool tapRight = !tapRightDIN;
tobyspark 0:87aab40d5806 1022
tobyspark 17:fc68d40b8b1f 1023 // We're taking a further median of the AINs on top of mbed libs v29.
tobyspark 17:fc68d40b8b1f 1024 // This takes some values from last passes and most from now. With debug off, seem to need median size > 5
tobyspark 17:fc68d40b8b1f 1025 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1026 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1027 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1028 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1029 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1030 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1031 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1032 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1033 const float xFadeAINCached = xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1034 const float fadeUpAINCached = fadeUpFilter.process(fadeUpAIN.read());
tobyspark 0:87aab40d5806 1035
tobyspark 0:87aab40d5806 1036 // When a tap is depressed, we can ignore any move of the crossfader but not fade to black
tobyspark 0:87aab40d5806 1037 if (tapLeft || tapRight)
tobyspark 0:87aab40d5806 1038 {
tobyspark 5:f8b285ca41ba 1039 // If both are pressed, take to the one that is new, ie. not the first pressed.
tobyspark 0:87aab40d5806 1040 if (tapLeft && tapRight)
tobyspark 0:87aab40d5806 1041 {
tobyspark 5:f8b285ca41ba 1042 xFade = tapLeftWasFirstPressed ? 1 : 0;
tobyspark 0:87aab40d5806 1043 }
tobyspark 5:f8b285ca41ba 1044 // If just one is pressed, take to that and remember which is pressed
tobyspark 5:f8b285ca41ba 1045 else if (tapLeft)
tobyspark 5:f8b285ca41ba 1046 {
tobyspark 5:f8b285ca41ba 1047 xFade = 0;
tobyspark 5:f8b285ca41ba 1048 tapLeftWasFirstPressed = 1;
tobyspark 5:f8b285ca41ba 1049 }
tobyspark 5:f8b285ca41ba 1050 else if (tapRight)
tobyspark 5:f8b285ca41ba 1051 {
tobyspark 5:f8b285ca41ba 1052 xFade = 1;
tobyspark 5:f8b285ca41ba 1053 tapLeftWasFirstPressed = 0;
tobyspark 5:f8b285ca41ba 1054 }
tobyspark 5:f8b285ca41ba 1055 }
tobyspark 18:ebe5da639a6a 1056 else xFade = 1.0 - fadeCalc(xFadeAINCached, xFadeTolerance);
tobyspark 0:87aab40d5806 1057
tobyspark 0:87aab40d5806 1058 fadeUp = 1.0 - fadeCalc(fadeUpAINCached, fadeUpTolerance);
tobyspark 0:87aab40d5806 1059
tobyspark 3:033d2b7768f3 1060 //// TASK: Process Network Comms
tobyspark 5:f8b285ca41ba 1061 if (commsMode == commsOSC)
tobyspark 3:033d2b7768f3 1062 {
tobyspark 3:033d2b7768f3 1063 if (osc->newMessage)
tobyspark 3:033d2b7768f3 1064 {
tobyspark 3:033d2b7768f3 1065 osc->newMessage = false; // fixme!
tobyspark 3:033d2b7768f3 1066 processOSC(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1067 }
tobyspark 3:033d2b7768f3 1068 }
tobyspark 3:033d2b7768f3 1069
tobyspark 5:f8b285ca41ba 1070 if (commsMode == commsArtNet)
tobyspark 3:033d2b7768f3 1071 {
tobyspark 3:033d2b7768f3 1072 if (artNet->Work()) processArtNet(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1073 }
tobyspark 3:033d2b7768f3 1074
tobyspark 5:f8b285ca41ba 1075 if (commsMode == commsDMXIn)
tobyspark 5:f8b285ca41ba 1076 {
tobyspark 5:f8b285ca41ba 1077 processDMXIn(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1078 }
tobyspark 5:f8b285ca41ba 1079
tobyspark 5:f8b285ca41ba 1080 if (commsMode == commsDMXOut)
tobyspark 5:f8b285ca41ba 1081 {
tobyspark 5:f8b285ca41ba 1082 processDMXOut(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1083 }
tobyspark 0:87aab40d5806 1084
tobyspark 0:87aab40d5806 1085 // Calculate new A&B fade percents
tobyspark 0:87aab40d5806 1086 int newFadeAPercent = 0;
tobyspark 0:87aab40d5806 1087 int newFadeBPercent = 0;
tobyspark 0:87aab40d5806 1088
tobyspark 30:873979018850 1089 if (mixMode == mixBlend)
tobyspark 11:0783cfbeb746 1090 {
tobyspark 30:873979018850 1091 if (fadeUp < 1.0)
tobyspark 30:873979018850 1092 {
tobyspark 30:873979018850 1093 // we need to set fade level of both windows as there is no way AFAIK to implement fade to black as a further window on top of A&B
tobyspark 30:873979018850 1094 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 30:873979018850 1095 newFadeBPercent = xFade * fadeUp * 100.0;
tobyspark 30:873979018850 1096 }
tobyspark 30:873979018850 1097 else
tobyspark 30:873979018850 1098 {
tobyspark 30:873979018850 1099 // we can optimise and just fade A in and out over a fully up B, doubling the rate of fadeA commands sent.
tobyspark 30:873979018850 1100 newFadeAPercent = (1.0-xFade) * 100.0;
tobyspark 30:873979018850 1101 newFadeBPercent = 100.0;
tobyspark 30:873979018850 1102 }
tobyspark 11:0783cfbeb746 1103 }
tobyspark 15:4b394c64b461 1104 else if (mixMode == mixAdditive)
tobyspark 11:0783cfbeb746 1105 {
tobyspark 22:90054fe6d86c 1106 // we need to set fade level of both windows according to the fade curve profile
tobyspark 22:90054fe6d86c 1107 float newFadeA = (1.0-xFade) * (1.0 + fadeCurve);
tobyspark 22:90054fe6d86c 1108 float newFadeB = xFade * (1 + fadeCurve);
tobyspark 22:90054fe6d86c 1109 if (newFadeA > 1.0) newFadeA = 1.0;
tobyspark 22:90054fe6d86c 1110 if (newFadeB > 1.0) newFadeB = 1.0;
tobyspark 22:90054fe6d86c 1111
tobyspark 22:90054fe6d86c 1112 newFadeAPercent = newFadeA * fadeUp * 100.0;
tobyspark 22:90054fe6d86c 1113 newFadeBPercent = newFadeB * fadeUp * 100.0;
tobyspark 11:0783cfbeb746 1114 }
tobyspark 15:4b394c64b461 1115 else if (mixMode >= mixKey)
tobyspark 11:0783cfbeb746 1116 {
tobyspark 0:87aab40d5806 1117 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 1118 newFadeBPercent = fadeUp * 100.0;
tobyspark 0:87aab40d5806 1119 }
tobyspark 0:87aab40d5806 1120
tobyspark 17:fc68d40b8b1f 1121 //// TASK: Send to TVOne if percents have changed
tobyspark 17:fc68d40b8b1f 1122
tobyspark 17:fc68d40b8b1f 1123 // No amount of median filtering is stopping flipflopping between two adjacent percents, so...
tobyspark 17:fc68d40b8b1f 1124 bool fadeAPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1125 bool fadeBPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1126 if (oldFadeAPercent == newFadeAPercent && (newFadeAPercent == fadeAPercent - 1 || newFadeAPercent == fadeAPercent + 1))
tobyspark 17:fc68d40b8b1f 1127 fadeAPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1128 else
tobyspark 17:fc68d40b8b1f 1129 fadeAPercentHasChanged = newFadeAPercent != fadeAPercent;
tobyspark 17:fc68d40b8b1f 1130 if (oldFadeBPercent == newFadeBPercent && (newFadeBPercent == fadeBPercent - 1 || newFadeBPercent == fadeBPercent + 1))
tobyspark 17:fc68d40b8b1f 1131 fadeBPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1132 else
tobyspark 17:fc68d40b8b1f 1133 fadeBPercentHasChanged = newFadeBPercent != fadeBPercent;
tobyspark 17:fc68d40b8b1f 1134
tobyspark 9:f83eadd8917a 1135 // We want to send the higher first, otherwise black flashes can happen on taps
tobyspark 17:fc68d40b8b1f 1136 if (fadeAPercentHasChanged && newFadeAPercent >= newFadeBPercent)
tobyspark 8:d46cc49f0f37 1137 {
tobyspark 17:fc68d40b8b1f 1138 oldFadeAPercent = fadeAPercent;
tobyspark 0:87aab40d5806 1139 fadeAPercent = newFadeAPercent;
tobyspark 0:87aab40d5806 1140 updateFade = true;
tobyspark 0:87aab40d5806 1141
tobyspark 0:87aab40d5806 1142 fadeAPO = fadeAPercent / 100.0;
tobyspark 0:87aab40d5806 1143 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 0:87aab40d5806 1144 }
tobyspark 17:fc68d40b8b1f 1145 if (fadeBPercentHasChanged)
tobyspark 8:d46cc49f0f37 1146 {
tobyspark 17:fc68d40b8b1f 1147 oldFadeBPercent = fadeBPercent;
tobyspark 0:87aab40d5806 1148 fadeBPercent = newFadeBPercent;
tobyspark 0:87aab40d5806 1149 updateFade = true;
tobyspark 0:87aab40d5806 1150
tobyspark 0:87aab40d5806 1151 fadeBPO = fadeBPercent / 100.0;
tobyspark 0:87aab40d5806 1152 tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 0:87aab40d5806 1153 }
tobyspark 17:fc68d40b8b1f 1154 if (fadeAPercentHasChanged && newFadeAPercent < newFadeBPercent)
tobyspark 9:f83eadd8917a 1155 {
tobyspark 17:fc68d40b8b1f 1156 oldFadeAPercent = fadeAPercent;
tobyspark 9:f83eadd8917a 1157 fadeAPercent = newFadeAPercent;
tobyspark 9:f83eadd8917a 1158 updateFade = true;
tobyspark 9:f83eadd8917a 1159
tobyspark 9:f83eadd8917a 1160 fadeAPO = fadeAPercent / 100.0;
tobyspark 9:f83eadd8917a 1161 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 9:f83eadd8917a 1162 }
tobyspark 8:d46cc49f0f37 1163 if (updateFade && debug)
tobyspark 8:d46cc49f0f37 1164 {
tobyspark 0:87aab40d5806 1165 //debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAIN.read(), fadeUpAIN.read());
tobyspark 0:87aab40d5806 1166 debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAINCached, fadeUpAINCached);
tobyspark 0:87aab40d5806 1167 debug->printf("xFade = %3f fadeUp = %3f fadeA% = %i fadeB% = %i \r\n", xFade, fadeUp, fadeAPercent, fadeBPercent);
tobyspark 18:ebe5da639a6a 1168 debug->printf("\r\n");
tobyspark 0:87aab40d5806 1169 }
tobyspark 30:873979018850 1170
tobyspark 30:873979018850 1171 // If we're not actively mixing, we can do any housekeeping...
tobyspark 30:873979018850 1172 if (!updateFade)
tobyspark 30:873979018850 1173 {
tobyspark 30:873979018850 1174 // We should check up on any source flagged unstable
tobyspark 30:873979018850 1175 if (!tvOneRGB1Stable || !tvOneRGB2Stable) handleTVOneSources();
tobyspark 30:873979018850 1176 }
tobyspark 0:87aab40d5806 1177 }
tobyspark 30:873979018850 1178 }