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:
Sat Nov 03 20:12:22 2012 +0000
Revision:
31:01845a2347ff
Parent:
30:873979018850
Child:
32:9f9eb3583bfa
Additive done; EDID first pass; Settings major fix

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 31:01845a2347ff 119 Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial
tobyspark 31:01845a2347ff 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 31:01845a2347ff 202 // TVOne behaviour flags
tobyspark 31:01845a2347ff 203 bool tvOneHDCPOn = false;
tobyspark 31:01845a2347ff 204 bool tvOneEDIDPassthrough = true;
tobyspark 31:01845a2347ff 205 const int32_t EDIDPassthroughSlot = 7;
tobyspark 31:01845a2347ff 206
tobyspark 3:033d2b7768f3 207 void processOSC(float &xFade, float &fadeUp) {
tobyspark 25:3b519ef70341 208 string statusMessage;
tobyspark 3:033d2b7768f3 209
tobyspark 3:033d2b7768f3 210 if (!strcmp( recMessage.getTopAddress() , "dvimxr" ))
tobyspark 3:033d2b7768f3 211 {
tobyspark 25:3b519ef70341 212 statusMessage = "OSC: /dvimxr";
tobyspark 3:033d2b7768f3 213 if (!strcmp( recMessage.getSubAddress() , "xFade" ))
tobyspark 25:3b519ef70341 214 {
tobyspark 25:3b519ef70341 215 if (recMessage.getArgNum() == 1)
tobyspark 25:3b519ef70341 216 if (recMessage.getTypeTag(0) == 'f')
tobyspark 25:3b519ef70341 217 {
tobyspark 25:3b519ef70341 218 xFade = recMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 219 char buffer[15];
tobyspark 26:0299f8760715 220 snprintf(buffer, kStringBufferLength, "/xFade %1.2f", xFade);
tobyspark 25:3b519ef70341 221 statusMessage += buffer;
tobyspark 25:3b519ef70341 222 }
tobyspark 25:3b519ef70341 223 }
tobyspark 25:3b519ef70341 224 else if (!strcmp( recMessage.getSubAddress() , "fadeUp" ))
tobyspark 25:3b519ef70341 225 {
tobyspark 3:033d2b7768f3 226 if (recMessage.getArgNum() == 1)
tobyspark 3:033d2b7768f3 227 if (recMessage.getTypeTag(0) == 'f')
tobyspark 3:033d2b7768f3 228 {
tobyspark 25:3b519ef70341 229 fadeUp = recMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 230 char buffer[15];
tobyspark 26:0299f8760715 231 snprintf(buffer, kStringBufferLength, "/fadeUp %1.2f", fadeUp);
tobyspark 25:3b519ef70341 232 statusMessage += buffer;
tobyspark 3:033d2b7768f3 233 }
tobyspark 25:3b519ef70341 234 }
tobyspark 25:3b519ef70341 235 else
tobyspark 25:3b519ef70341 236 {
tobyspark 25:3b519ef70341 237 statusMessage += recMessage.getSubAddress();
tobyspark 25:3b519ef70341 238 statusMessage += " - Ignoring";
tobyspark 25:3b519ef70341 239 }
tobyspark 3:033d2b7768f3 240 }
tobyspark 3:033d2b7768f3 241 else
tobyspark 3:033d2b7768f3 242 {
tobyspark 25:3b519ef70341 243 statusMessage = "OSC: ";
tobyspark 25:3b519ef70341 244 statusMessage += recMessage.getTopAddress();
tobyspark 25:3b519ef70341 245 statusMessage += " - Ignoring";
tobyspark 3:033d2b7768f3 246 }
tobyspark 3:033d2b7768f3 247
tobyspark 3:033d2b7768f3 248 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 249 screen.textToBuffer(statusMessage, kCommsStatusLine);
tobyspark 3:033d2b7768f3 250 screen.sendBuffer();
tobyspark 25:3b519ef70341 251 if (debug) debug->printf("%s \r\n", statusMessage.c_str());
tobyspark 3:033d2b7768f3 252
tobyspark 3:033d2b7768f3 253 }
tobyspark 3:033d2b7768f3 254
tobyspark 8:d46cc49f0f37 255 void processArtNet(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 256 {
tobyspark 3:033d2b7768f3 257 screen.clearBufferRow(kCommsStatusLine);
tobyspark 3:033d2b7768f3 258 screen.textToBuffer("ArtNet activity", kCommsStatusLine);
tobyspark 3:033d2b7768f3 259 screen.sendBuffer();
tobyspark 3:033d2b7768f3 260 if (debug) debug->printf("ArtNet activity");
tobyspark 3:033d2b7768f3 261 }
tobyspark 0:87aab40d5806 262
tobyspark 8:d46cc49f0f37 263 void processDMXIn(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 264 {
tobyspark 26:0299f8760715 265 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 266
tobyspark 5:f8b285ca41ba 267 int xFadeDMX = dmx->get(kDMXInChannelXFade);
tobyspark 7:e6717468c18d 268 int fadeUpDMX = dmx->get(kDMXInChannelFadeUp);
tobyspark 5:f8b285ca41ba 269
tobyspark 5:f8b285ca41ba 270 xFade = (float)xFadeDMX/255;
tobyspark 5:f8b285ca41ba 271 fadeUp = (float)fadeUpDMX/255;
tobyspark 5:f8b285ca41ba 272
tobyspark 5:f8b285ca41ba 273 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 274 snprintf(statusMessageBuffer, kStringBufferLength, "DMX In: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 275 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 5:f8b285ca41ba 276 screen.sendBuffer();
tobyspark 25:3b519ef70341 277 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 278 }
tobyspark 5:f8b285ca41ba 279
tobyspark 8:d46cc49f0f37 280 void processDMXOut(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 281 {
tobyspark 26:0299f8760715 282 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 283
tobyspark 5:f8b285ca41ba 284 int xFadeDMX = xFade*255;
tobyspark 5:f8b285ca41ba 285 int fadeUpDMX = fadeUp*255;
tobyspark 5:f8b285ca41ba 286
tobyspark 5:f8b285ca41ba 287 dmx->put(kDMXOutChannelXFade, xFadeDMX);
tobyspark 5:f8b285ca41ba 288 dmx->put(kDMXOutChannelFadeUp, fadeUpDMX);
tobyspark 5:f8b285ca41ba 289
tobyspark 5:f8b285ca41ba 290 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 291 snprintf(statusMessageBuffer, kStringBufferLength, "DMX Out: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 292 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 5:f8b285ca41ba 293 screen.sendBuffer();
tobyspark 25:3b519ef70341 294 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 295 }
tobyspark 0:87aab40d5806 296
tobyspark 8:d46cc49f0f37 297 inline float fadeCalc (const float AIN, const float tolerance)
tobyspark 8:d46cc49f0f37 298 {
tobyspark 0:87aab40d5806 299 float pos ;
tobyspark 0:87aab40d5806 300 if (AIN < tolerance) pos = 0;
tobyspark 0:87aab40d5806 301 else if (AIN > 1.0 - tolerance) pos = 1;
tobyspark 0:87aab40d5806 302 else pos = (AIN - tolerance) / (1 - 2*tolerance);
tobyspark 0:87aab40d5806 303 if (debug && false) debug->printf("fadeCalc in: %f out: %f \r\n", AIN, pos);
tobyspark 0:87aab40d5806 304 return pos;
tobyspark 0:87aab40d5806 305 }
tobyspark 0:87aab40d5806 306
tobyspark 31:01845a2347ff 307 bool handleTVOneSources(bool updateScreenOverride = false)
tobyspark 30:873979018850 308 {
tobyspark 30:873979018850 309 bool ok = true;
tobyspark 30:873979018850 310
tobyspark 30:873979018850 311 int32_t payload = 0;
tobyspark 30:873979018850 312
tobyspark 30:873979018850 313 ok = ok && tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 30:873979018850 314 bool RGB1 = (payload == 1);
tobyspark 30:873979018850 315
tobyspark 30:873979018850 316 ok = ok && tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 30:873979018850 317 bool RGB2 = (payload == 1);
tobyspark 30:873979018850 318
tobyspark 30:873979018850 319 string tvOneDetectString;
tobyspark 30:873979018850 320 if (!ok)
tobyspark 30:873979018850 321 {
tobyspark 30:873979018850 322 tvOneDetectString = "TVOne: link failed";
tobyspark 30:873979018850 323 }
tobyspark 30:873979018850 324 else if (!RGB1 || !RGB2)
tobyspark 30:873979018850 325 {
tobyspark 30:873979018850 326 if (!RGB1 && !RGB2) tvOneDetectString = "TVOne: no sources";
tobyspark 30:873979018850 327 else if (!RGB1) tvOneDetectString = "TVOne: no right source";
tobyspark 30:873979018850 328 else if (!RGB2) tvOneDetectString = "TVOne: no left source";
tobyspark 30:873979018850 329 }
tobyspark 30:873979018850 330 else
tobyspark 30:873979018850 331 {
tobyspark 30:873979018850 332 tvOneDetectString = "TVOne: OK";
tobyspark 30:873979018850 333 }
tobyspark 30:873979018850 334
tobyspark 30:873979018850 335 if (RGB1 && !tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 30:873979018850 336 if (RGB2 && !tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 30:873979018850 337 if (!RGB1 && tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS1);
tobyspark 30:873979018850 338 if (!RGB2 && tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2);
tobyspark 31:01845a2347ff 339
tobyspark 31:01845a2347ff 340 if (updateScreenOverride || (RGB1 != tvOneRGB1Stable || RGB2 != tvOneRGB2Stable))
tobyspark 30:873979018850 341 {
tobyspark 30:873979018850 342 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 30:873979018850 343 screen.textToBuffer(tvOneDetectString, kTVOneStatusLine);
tobyspark 30:873979018850 344 screen.sendBuffer();
tobyspark 30:873979018850 345 }
tobyspark 30:873979018850 346
tobyspark 30:873979018850 347 tvOneRGB1Stable = RGB1;
tobyspark 30:873979018850 348 tvOneRGB2Stable = RGB2;
tobyspark 30:873979018850 349
tobyspark 30:873979018850 350 return ok;
tobyspark 30:873979018850 351 }
tobyspark 30:873979018850 352
tobyspark 8:d46cc49f0f37 353 bool setKeyParamsTo(int index)
tobyspark 8:d46cc49f0f37 354 {
tobyspark 0:87aab40d5806 355 // Only spend the time uploading six parameters if we need to
tobyspark 0:87aab40d5806 356 // Might want to bounds check here
tobyspark 0:87aab40d5806 357
tobyspark 9:f83eadd8917a 358 bool ok;
tobyspark 0:87aab40d5806 359
tobyspark 0:87aab40d5806 360 if (index != keyerParamsSet)
tobyspark 0:87aab40d5806 361 {
tobyspark 31:01845a2347ff 362 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, settings.keyerParamSet(index)[SPKSettings::minY]);
tobyspark 31:01845a2347ff 363 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, settings.keyerParamSet(index)[SPKSettings::maxY]);
tobyspark 31:01845a2347ff 364 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, settings.keyerParamSet(index)[SPKSettings::minU]);
tobyspark 31:01845a2347ff 365 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, settings.keyerParamSet(index)[SPKSettings::maxU]);
tobyspark 31:01845a2347ff 366 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, settings.keyerParamSet(index)[SPKSettings::minV]);
tobyspark 31:01845a2347ff 367 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, settings.keyerParamSet(index)[SPKSettings::maxV]);
tobyspark 0:87aab40d5806 368
tobyspark 0:87aab40d5806 369 keyerParamsSet = index;
tobyspark 9:f83eadd8917a 370 }
tobyspark 9:f83eadd8917a 371 else
tobyspark 9:f83eadd8917a 372 {
tobyspark 9:f83eadd8917a 373 ok = true;
tobyspark 9:f83eadd8917a 374 }
tobyspark 0:87aab40d5806 375
tobyspark 0:87aab40d5806 376 return ok;
tobyspark 0:87aab40d5806 377 }
tobyspark 0:87aab40d5806 378
tobyspark 24:49c6624119ae 379 void actionMixMode()
tobyspark 24:49c6624119ae 380 {
tobyspark 31:01845a2347ff 381 if (debug) debug->printf("Changing mix mode \r\n");
tobyspark 31:01845a2347ff 382
tobyspark 24:49c6624119ae 383 bool ok = true;
tobyspark 25:3b519ef70341 384 string sentOK;
tobyspark 26:0299f8760715 385 char sentMSGBuffer[kStringBufferLength];
tobyspark 24:49c6624119ae 386
tobyspark 24:49c6624119ae 387 // Set Keyer
tobyspark 24:49c6624119ae 388 if (mixMode < mixKey)
tobyspark 24:49c6624119ae 389 {
tobyspark 31:01845a2347ff 390 // Set Keyer Off. Quicker to set and fail than to test for on and then turn off
tobyspark 31:01845a2347ff 391 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false);
tobyspark 31:01845a2347ff 392
tobyspark 31:01845a2347ff 393 if (mixMode == mixBlend)
tobyspark 24:49c6624119ae 394 {
tobyspark 31:01845a2347ff 395 // Turn off Additive Mixing on output
tobyspark 31:01845a2347ff 396 ok = tvOne.command(0, kTV1WindowIDA, 0x298, 0);
tobyspark 31:01845a2347ff 397 snprintf(sentMSGBuffer, kStringBufferLength, "Blend");
tobyspark 24:49c6624119ae 398 }
tobyspark 31:01845a2347ff 399 if (mixMode == mixAdditive)
tobyspark 31:01845a2347ff 400 {
tobyspark 31:01845a2347ff 401 // First set B to what you'd expect for additive; it may be left at 100 if optimised blend mixing was previous mixmode.
tobyspark 31:01845a2347ff 402 ok = tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 31:01845a2347ff 403 // Then turn on Additive Mixing
tobyspark 31:01845a2347ff 404 ok = ok && tvOne.command(0, kTV1WindowIDA, 0x298, 1);
tobyspark 31:01845a2347ff 405 snprintf(sentMSGBuffer, kStringBufferLength, "Additive");
tobyspark 31:01845a2347ff 406 }
tobyspark 24:49c6624119ae 407 }
tobyspark 24:49c6624119ae 408 else
tobyspark 24:49c6624119ae 409 {
tobyspark 25:3b519ef70341 410 int index = mixMode - mixKey;
tobyspark 25:3b519ef70341 411
tobyspark 24:49c6624119ae 412 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true);
tobyspark 24:49c6624119ae 413 ok = ok && setKeyParamsTo(index);
tobyspark 25:3b519ef70341 414
tobyspark 26:0299f8760715 415 snprintf(sentMSGBuffer, kStringBufferLength, "Keyer On with %i", index);
tobyspark 24:49c6624119ae 416 }
tobyspark 24:49c6624119ae 417
tobyspark 24:49c6624119ae 418 if (ok) sentOK = "Sent:";
tobyspark 24:49c6624119ae 419 else sentOK = "Send Error:";
tobyspark 24:49c6624119ae 420
tobyspark 24:49c6624119ae 421 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 25:3b519ef70341 422 screen.textToBuffer(sentOK + sentMSGBuffer, kTVOneStatusLine);
tobyspark 24:49c6624119ae 423 }
tobyspark 24:49c6624119ae 424
tobyspark 24:49c6624119ae 425
tobyspark 17:fc68d40b8b1f 426 bool conformProcessor()
tobyspark 17:fc68d40b8b1f 427 {
tobyspark 17:fc68d40b8b1f 428 bool ok = true;
tobyspark 17:fc68d40b8b1f 429
tobyspark 17:fc68d40b8b1f 430 int32_t on = 1;
tobyspark 17:fc68d40b8b1f 431 int32_t off = 0;
tobyspark 20:8b92d7922c48 432
tobyspark 20:8b92d7922c48 433 // Independent output
tobyspark 30:873979018850 434 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionMode, 2);
tobyspark 20:8b92d7922c48 435 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputEnable, on);
tobyspark 20:8b92d7922c48 436 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsLockMethod, off);
tobyspark 17:fc68d40b8b1f 437
tobyspark 17:fc68d40b8b1f 438 // Make sure our windows exist
tobyspark 17:fc68d40b8b1f 439 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 17:fc68d40b8b1f 440 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 18:ebe5da639a6a 441 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsLayerPriority, 0);
tobyspark 18:ebe5da639a6a 442 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsLayerPriority, 1);
tobyspark 17:fc68d40b8b1f 443
tobyspark 17:fc68d40b8b1f 444 // Assign inputs to windows, so that left on the crossfader is left on the processor viewed from front
tobyspark 17:fc68d40b8b1f 445 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 17:fc68d40b8b1f 446 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 17:fc68d40b8b1f 447
tobyspark 17:fc68d40b8b1f 448 // Set scaling to fit source within output, maintaining aspect ratio
tobyspark 17:fc68d40b8b1f 449 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 17:fc68d40b8b1f 450 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDB, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 17:fc68d40b8b1f 451 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 17:fc68d40b8b1f 452 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDB, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 17:fc68d40b8b1f 453 int32_t fit = 1;
tobyspark 17:fc68d40b8b1f 454 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 17:fc68d40b8b1f 455 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 17:fc68d40b8b1f 456
tobyspark 17:fc68d40b8b1f 457 // On source loss, hold on the last frame received.
tobyspark 17:fc68d40b8b1f 458 int32_t freeze = 1;
tobyspark 17:fc68d40b8b1f 459 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 17:fc68d40b8b1f 460 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 17:fc68d40b8b1f 461
tobyspark 30:873979018850 462 // Set resolution and fade levels for maximum chance of being seen
tobyspark 31:01845a2347ff 463 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : 5;
tobyspark 30:873979018850 464 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, kTV1ResolutionVGA);
tobyspark 31:01845a2347ff 465 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 466 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 30:873979018850 467 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, 100);
tobyspark 30:873979018850 468 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, 100);
tobyspark 30:873979018850 469
tobyspark 30:873979018850 470 // Save current state for power on
tobyspark 30:873979018850 471 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 17:fc68d40b8b1f 472
tobyspark 17:fc68d40b8b1f 473 return ok;
tobyspark 17:fc68d40b8b1f 474 }
tobyspark 17:fc68d40b8b1f 475
tobyspark 17:fc68d40b8b1f 476 void selfTest()
tobyspark 17:fc68d40b8b1f 477 {
tobyspark 17:fc68d40b8b1f 478 /* SELF TEST - Pixels
tobyspark 17:fc68d40b8b1f 479 * Clicking &#65533;self-test&#65533; menu will display a solid lit screen. Check all pixels lit.
tobyspark 17:fc68d40b8b1f 480 * Verified: Display
tobyspark 17:fc68d40b8b1f 481 */
tobyspark 17:fc68d40b8b1f 482
tobyspark 17:fc68d40b8b1f 483 screen.imageToBuffer(spkDisplayAllPixelsOn);
tobyspark 17:fc68d40b8b1f 484 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 485
tobyspark 17:fc68d40b8b1f 486 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 487 {
tobyspark 17:fc68d40b8b1f 488 // do nothing, wait for press
tobyspark 17:fc68d40b8b1f 489 }
tobyspark 17:fc68d40b8b1f 490
tobyspark 17:fc68d40b8b1f 491 /* SELF TEST - Mixing Controls
tobyspark 17:fc68d40b8b1f 492 * 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 493 * Verified: Mixing controls.
tobyspark 17:fc68d40b8b1f 494 */
tobyspark 17:fc68d40b8b1f 495
tobyspark 17:fc68d40b8b1f 496 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 497 screen.textToBuffer("Self test - Mixing Controls", 0);
tobyspark 17:fc68d40b8b1f 498
tobyspark 17:fc68d40b8b1f 499 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 500 {
tobyspark 26:0299f8760715 501 char xFadeReadOut[kStringBufferLength];
tobyspark 26:0299f8760715 502 char fadeToBlackReadOut[kStringBufferLength];
tobyspark 26:0299f8760715 503 char tapsReadOut[kStringBufferLength];
tobyspark 17:fc68d40b8b1f 504
tobyspark 26:0299f8760715 505 snprintf(xFadeReadOut, kStringBufferLength, "Crossfade: %1.3f", xFadeAIN.read());
tobyspark 26:0299f8760715 506 snprintf(fadeToBlackReadOut, kStringBufferLength, "Fade to black: %1.3f", fadeUpAIN.read());
tobyspark 26:0299f8760715 507 snprintf(tapsReadOut, kStringBufferLength, "Tap left: %i, right: %i", tapLeftDIN.read(), tapRightDIN.read());
tobyspark 17:fc68d40b8b1f 508
tobyspark 17:fc68d40b8b1f 509 screen.clearBufferRow(1);
tobyspark 17:fc68d40b8b1f 510 screen.clearBufferRow(2);
tobyspark 17:fc68d40b8b1f 511 screen.clearBufferRow(3);
tobyspark 17:fc68d40b8b1f 512
tobyspark 25:3b519ef70341 513 screen.textToBuffer(xFadeReadOut, 1);
tobyspark 25:3b519ef70341 514 screen.textToBuffer(fadeToBlackReadOut, 2);
tobyspark 25:3b519ef70341 515 screen.textToBuffer(tapsReadOut, 3);
tobyspark 17:fc68d40b8b1f 516 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 517 }
tobyspark 17:fc68d40b8b1f 518
tobyspark 17:fc68d40b8b1f 519 /* SELF TEST - RS232
tobyspark 17:fc68d40b8b1f 520 * 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 521 * Verified: RS232 connection.
tobyspark 17:fc68d40b8b1f 522 */
tobyspark 17:fc68d40b8b1f 523
tobyspark 17:fc68d40b8b1f 524 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 525 screen.textToBuffer("Self test - RS232", 0);
tobyspark 17:fc68d40b8b1f 526 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 527
tobyspark 17:fc68d40b8b1f 528 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 529 {
tobyspark 17:fc68d40b8b1f 530 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 531 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 532 }
tobyspark 17:fc68d40b8b1f 533
tobyspark 17:fc68d40b8b1f 534 /* SELF TEST - DMX
tobyspark 17:fc68d40b8b1f 535 * 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 536 * Verified: RS485 connection and DMX library.
tobyspark 17:fc68d40b8b1f 537 */
tobyspark 17:fc68d40b8b1f 538
tobyspark 17:fc68d40b8b1f 539 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 540 screen.textToBuffer("Self test - DMX", 0);
tobyspark 17:fc68d40b8b1f 541 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 542
tobyspark 17:fc68d40b8b1f 543 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 544 {
tobyspark 17:fc68d40b8b1f 545 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 546 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 547 }
tobyspark 17:fc68d40b8b1f 548
tobyspark 17:fc68d40b8b1f 549 /* SELF TEST - OSC
tobyspark 17:fc68d40b8b1f 550 * 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 551 * Verified: Ethernet connection and OSC library.
tobyspark 17:fc68d40b8b1f 552 */
tobyspark 17:fc68d40b8b1f 553
tobyspark 17:fc68d40b8b1f 554 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 555 screen.textToBuffer("Self test - DMX", 0);
tobyspark 17:fc68d40b8b1f 556 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 557
tobyspark 17:fc68d40b8b1f 558 while(!menuEnc.hasPressed())
tobyspark 17:fc68d40b8b1f 559 {
tobyspark 17:fc68d40b8b1f 560 screen.textToBuffer("TODO!", 1);
tobyspark 17:fc68d40b8b1f 561 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 562 }
tobyspark 17:fc68d40b8b1f 563
tobyspark 17:fc68d40b8b1f 564 /* SELF TEST - Exit!
tobyspark 17:fc68d40b8b1f 565 * To do this, we could just do nothing but we'd need to recreate screen and comms as they were.
tobyspark 17:fc68d40b8b1f 566 * Instead, lets just restart the mbed
tobyspark 17:fc68d40b8b1f 567 */
tobyspark 17:fc68d40b8b1f 568
tobyspark 17:fc68d40b8b1f 569 screen.clearBuffer();
tobyspark 17:fc68d40b8b1f 570 screen.textToBuffer("Self test complete", 0);
tobyspark 17:fc68d40b8b1f 571 screen.textToBuffer("Press to restart controller", 1);
tobyspark 17:fc68d40b8b1f 572 screen.sendBuffer();
tobyspark 17:fc68d40b8b1f 573
tobyspark 17:fc68d40b8b1f 574 while(!menuEnc.hasPressed()) {}
tobyspark 17:fc68d40b8b1f 575
tobyspark 17:fc68d40b8b1f 576 mbed_reset();
tobyspark 17:fc68d40b8b1f 577 }
tobyspark 17:fc68d40b8b1f 578
tobyspark 27:27851d3d2bba 579 void setResolutionMenuItems()
tobyspark 27:27851d3d2bba 580 {
tobyspark 27:27851d3d2bba 581 resolutionMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 582 for (int i=0; i < settings.resolutionsCount(); i++)
tobyspark 27:27851d3d2bba 583 {
tobyspark 27:27851d3d2bba 584 resolutionMenu.addMenuItem(SPKMenuItem(settings.resolutionName(i), settings.resolutionIndex(i), settings.resolutionEDIDIndex(i)));
tobyspark 27:27851d3d2bba 585 }
tobyspark 27:27851d3d2bba 586 resolutionMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 587 }
tobyspark 27:27851d3d2bba 588
tobyspark 27:27851d3d2bba 589 void setMixModeMenuItems()
tobyspark 27:27851d3d2bba 590 {
tobyspark 27:27851d3d2bba 591 mixModeMenu.clearMenuItems();
tobyspark 29:95a7efe30527 592 mixModeMenu.addMenuItem(SPKMenuItem("Crossfade", &mixModeAdditiveMenu));
tobyspark 27:27851d3d2bba 593 for (int i=0; i < settings.keyerSetCount(); i++)
tobyspark 27:27851d3d2bba 594 {
tobyspark 27:27851d3d2bba 595 mixModeMenu.addMenuItem(SPKMenuItem(settings.keyerParamName(i), mixKey+i));
tobyspark 27:27851d3d2bba 596 }
tobyspark 27:27851d3d2bba 597 mixModeMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 598 }
tobyspark 27:27851d3d2bba 599
tobyspark 27:27851d3d2bba 600 void setCommsMenuItems()
tobyspark 27:27851d3d2bba 601 {
tobyspark 27:27851d3d2bba 602 if (rj45Mode == rj45Ethernet)
tobyspark 27:27851d3d2bba 603 {
tobyspark 27:27851d3d2bba 604 commsMenu.title = "Network Mode [Ethernet]";
tobyspark 27:27851d3d2bba 605 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 606 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 607 commsMenu.addMenuItem(SPKMenuItem("OSC", commsOSC));
tobyspark 27:27851d3d2bba 608 commsMenu.addMenuItem(SPKMenuItem("ArtNet", commsArtNet));
tobyspark 27:27851d3d2bba 609 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 610 }
tobyspark 27:27851d3d2bba 611 else if (rj45Mode == rj45DMX)
tobyspark 27:27851d3d2bba 612 {
tobyspark 27:27851d3d2bba 613 commsMenu.title = "Network Mode [DMX]";
tobyspark 27:27851d3d2bba 614 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 615 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 616 commsMenu.addMenuItem(SPKMenuItem("DMX In", commsDMXIn));
tobyspark 27:27851d3d2bba 617 commsMenu.addMenuItem(SPKMenuItem("DMX Out", commsDMXOut));
tobyspark 27:27851d3d2bba 618 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 619 }
tobyspark 27:27851d3d2bba 620 }
tobyspark 27:27851d3d2bba 621
tobyspark 0:87aab40d5806 622 int main()
tobyspark 0:87aab40d5806 623 {
tobyspark 0:87aab40d5806 624 if (debug)
tobyspark 0:87aab40d5806 625 {
tobyspark 0:87aab40d5806 626 debug->printf("\r\n\r\n");
tobyspark 0:87aab40d5806 627 debug->printf("*spark d-fuser -----------\r\n");
tobyspark 0:87aab40d5806 628 debug->printf(" debug channel\r\n");
tobyspark 0:87aab40d5806 629 }
tobyspark 2:50043054e4f7 630
tobyspark 2:50043054e4f7 631 // Set display font
tobyspark 2:50043054e4f7 632 screen.fontStartCharacter = &characterBytesStartChar;
tobyspark 2:50043054e4f7 633 screen.fontEndCharacter = &characterBytesEndChar;
tobyspark 2:50043054e4f7 634 screen.fontCharacters = characterBytes;
tobyspark 2:50043054e4f7 635
tobyspark 0:87aab40d5806 636 // Splash screen
tobyspark 30:873979018850 637 string softwareLine = "SW ";
tobyspark 30:873979018850 638 softwareLine += kSPKDFSoftwareVersion;
tobyspark 2:50043054e4f7 639 screen.imageToBuffer(spkDisplayLogo);
tobyspark 0:87aab40d5806 640 screen.textToBuffer("SPK:D-Fuser",0);
tobyspark 30:873979018850 641 screen.textToBuffer(softwareLine,1);
tobyspark 5:f8b285ca41ba 642 screen.sendBuffer();
tobyspark 0:87aab40d5806 643
tobyspark 11:0783cfbeb746 644 // Load saved settings
tobyspark 16:52484666b323 645 bool settingsAreCustom = false;
tobyspark 16:52484666b323 646 settingsAreCustom = settings.load(kSPKDFSettingsFilename);
tobyspark 30:873979018850 647 if (settingsAreCustom)
tobyspark 30:873979018850 648 {
tobyspark 30:873979018850 649 softwareLine += "; ini OK";
tobyspark 30:873979018850 650 screen.textToBuffer(softwareLine, 1);
tobyspark 30:873979018850 651 }
tobyspark 30:873979018850 652
tobyspark 0:87aab40d5806 653 // Set menu structure
tobyspark 0:87aab40d5806 654 mixModeMenu.title = "Mix Mode";
tobyspark 27:27851d3d2bba 655 setMixModeMenuItems();
tobyspark 24:49c6624119ae 656
tobyspark 29:95a7efe30527 657 mixModeAdditiveMenu.title = "Crossfade";
tobyspark 30:873979018850 658 mixModeAdditiveMenu.addMenuItem(SPKMenuItem("[title overridden]", &mixModeMenu, true));
tobyspark 0:87aab40d5806 659
tobyspark 0:87aab40d5806 660 resolutionMenu.title = "Resolution";
tobyspark 27:27851d3d2bba 661 setResolutionMenuItems();
tobyspark 0:87aab40d5806 662
tobyspark 27:27851d3d2bba 663 commsMenu.title = "Network Mode";
tobyspark 27:27851d3d2bba 664 setCommsMenuItems();
tobyspark 23:909928cafb95 665
tobyspark 15:4b394c64b461 666 advancedMenu.title = "Troubleshooting";
tobyspark 23:909928cafb95 667 advancedMenu.addMenuItem(SPKMenuItem("HDCP Off", advancedHDCPOff));
tobyspark 23:909928cafb95 668 advancedMenu.addMenuItem(SPKMenuItem("HDCP On", advancedHDCPOn));
tobyspark 31:01845a2347ff 669 advancedMenu.addMenuItem(SPKMenuItem("EDID Passthrough", advancedEDIDPassthrough)); // have global setting of passthrough that overrides resolution sets and is saved with conform processor
tobyspark 31:01845a2347ff 670 advancedMenu.addMenuItem(SPKMenuItem("EDID Internal", advancedEDIDInternal));
tobyspark 30:873979018850 671 advancedMenu.addMenuItem(SPKMenuItem("Test Processor Sources", advancedTestSources));
tobyspark 23:909928cafb95 672 advancedMenu.addMenuItem(SPKMenuItem("Conform Processor", advancedConformProcessor));
tobyspark 30:873979018850 673 if (settingsAreCustom) advancedMenu.addMenuItem(SPKMenuItem("Revert Controller", advancedLoadDefaults));
tobyspark 23:909928cafb95 674 advancedMenu.addMenuItem(SPKMenuItem("Start Self-Test", advancedSelfTest));
tobyspark 24:49c6624119ae 675 advancedMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 23:909928cafb95 676
tobyspark 0:87aab40d5806 677 mainMenu.title = "Main Menu";
tobyspark 24:49c6624119ae 678 mainMenu.addMenuItem(SPKMenuItem(mixModeMenu.title, &mixModeMenu));
tobyspark 24:49c6624119ae 679 mainMenu.addMenuItem(SPKMenuItem(resolutionMenu.title, &resolutionMenu));
tobyspark 24:49c6624119ae 680 mainMenu.addMenuItem(SPKMenuItem(commsMenu.title, &commsMenu));
tobyspark 24:49c6624119ae 681 mainMenu.addMenuItem(SPKMenuItem(advancedMenu.title, &advancedMenu));
tobyspark 23:909928cafb95 682
tobyspark 0:87aab40d5806 683 selectedMenu = &mainMenu;
tobyspark 23:909928cafb95 684
tobyspark 0:87aab40d5806 685 // Misc I/O stuff
tobyspark 0:87aab40d5806 686
tobyspark 0:87aab40d5806 687 fadeAPO.period(0.001);
tobyspark 0:87aab40d5806 688 fadeBPO.period(0.001);
tobyspark 0:87aab40d5806 689
tobyspark 20:8b92d7922c48 690 // Test for TV One connectivity and determine unit type
tobyspark 30:873979018850 691 // TODO: Determine and fall back if not dfuser firmware?
tobyspark 30:873979018850 692 // TODO: Use software version to select resolution slots?
tobyspark 30:873979018850 693 // TODO: Use product / board type to select TVOne conform type?
tobyspark 21:f9d63cb7cedb 694 // kTV1FunctionReadSoftwareVersion
tobyspark 21:f9d63cb7cedb 695 // kTV1FunctionReadProductType
tobyspark 21:f9d63cb7cedb 696 // kTV1FunctionReadBoardType
tobyspark 21:f9d63cb7cedb 697
tobyspark 12:c270870bdd23 698 // Display menu and framing lines
tobyspark 0:87aab40d5806 699 screen.horizLineToBuffer(kMenuLine1*pixInPage - 1);
tobyspark 0:87aab40d5806 700 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 701 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 702 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 703 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 704 screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage);
tobyspark 1:f9fca21102e0 705 screen.horizLineToBuffer(kCommsStatusLine*pixInPage - 1);
tobyspark 1:f9fca21102e0 706 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 30:873979018850 707 screen.textToBuffer("TVOne: OK", kTVOneStatusLine); // handleTVOneSources may update this
tobyspark 30:873979018850 708
tobyspark 30:873979018850 709 // 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 710 // 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 31:01845a2347ff 711 // This is set to update kTVOneStatusLine and sendBuffer regardless
tobyspark 31:01845a2347ff 712 bool ok = handleTVOneSources(true);
tobyspark 0:87aab40d5806 713
tobyspark 0:87aab40d5806 714 //// CONTROLS TEST
tobyspark 0:87aab40d5806 715
tobyspark 0:87aab40d5806 716 while (0) {
tobyspark 0:87aab40d5806 717 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 718 }
tobyspark 0:87aab40d5806 719
tobyspark 0:87aab40d5806 720 //// MIXER RUN
tobyspark 0:87aab40d5806 721
tobyspark 8:d46cc49f0f37 722 while (1)
tobyspark 8:d46cc49f0f37 723 {
tobyspark 1:f9fca21102e0 724 //// Task background things
tobyspark 5:f8b285ca41ba 725 if (ethernet && rj45Mode == rj45Ethernet)
tobyspark 5:f8b285ca41ba 726 {
tobyspark 5:f8b285ca41ba 727 Net::poll();
tobyspark 5:f8b285ca41ba 728 }
tobyspark 5:f8b285ca41ba 729
tobyspark 5:f8b285ca41ba 730 //// RJ45 SWITCH
tobyspark 5:f8b285ca41ba 731
tobyspark 5:f8b285ca41ba 732 if (rj45ModeDIN != rj45Mode)
tobyspark 1:f9fca21102e0 733 {
tobyspark 23:909928cafb95 734 if (debug) debug->printf("Handling RJ45 mode change\r\n");
tobyspark 27:27851d3d2bba 735
tobyspark 5:f8b285ca41ba 736 // update state
tobyspark 5:f8b285ca41ba 737 rj45Mode = rj45ModeDIN;
tobyspark 27:27851d3d2bba 738
tobyspark 27:27851d3d2bba 739 setCommsMenuItems();
tobyspark 5:f8b285ca41ba 740
tobyspark 5:f8b285ca41ba 741 // cancel old comms
tobyspark 5:f8b285ca41ba 742 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 743 commsMenu = commsMode;
tobyspark 5:f8b285ca41ba 744
tobyspark 5:f8b285ca41ba 745 // refresh display
tobyspark 23:909928cafb95 746 if (selectedMenu == &commsMenu)
tobyspark 23:909928cafb95 747 {
tobyspark 23:909928cafb95 748 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 23:909928cafb95 749 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 23:909928cafb95 750 }
tobyspark 5:f8b285ca41ba 751 if (rj45Mode == rj45Ethernet) screen.textToBuffer("RJ45: Ethernet Engaged", kCommsStatusLine);
tobyspark 5:f8b285ca41ba 752 if (rj45Mode == rj45DMX) screen.textToBuffer("RJ45: DMX Engaged", kCommsStatusLine);
tobyspark 1:f9fca21102e0 753 }
tobyspark 1:f9fca21102e0 754
tobyspark 0:87aab40d5806 755 //// MENU
tobyspark 0:87aab40d5806 756
tobyspark 0:87aab40d5806 757 int menuChange = menuEnc.getChange();
tobyspark 0:87aab40d5806 758
tobyspark 0:87aab40d5806 759 // Update GUI
tobyspark 0:87aab40d5806 760 if (menuChange != 0)
tobyspark 0:87aab40d5806 761 {
tobyspark 24:49c6624119ae 762 if (selectedMenu->selectedItem().handlingControls)
tobyspark 24:49c6624119ae 763 {
tobyspark 24:49c6624119ae 764 if (selectedMenu == &mixModeAdditiveMenu)
tobyspark 24:49c6624119ae 765 {
tobyspark 24:49c6624119ae 766 fadeCurve += menuChange * 0.05;
tobyspark 24:49c6624119ae 767 if (fadeCurve > 1.0f) fadeCurve = 1.0f;
tobyspark 24:49c6624119ae 768 if (fadeCurve < 0.0f) fadeCurve = 0.0f;
tobyspark 29:95a7efe30527 769
tobyspark 31:01845a2347ff 770 int newMixMode = (fadeCurve > 0.0f) ? mixAdditive: mixBlend;
tobyspark 31:01845a2347ff 771
tobyspark 31:01845a2347ff 772 if (newMixMode != mixMode)
tobyspark 31:01845a2347ff 773 {
tobyspark 31:01845a2347ff 774 mixMode = newMixMode;
tobyspark 31:01845a2347ff 775 actionMixMode();
tobyspark 31:01845a2347ff 776 }
tobyspark 29:95a7efe30527 777
tobyspark 24:49c6624119ae 778 screen.clearBufferRow(kMenuLine2);
tobyspark 29:95a7efe30527 779 screen.textToBuffer("Blend [ ----- ] Add", kMenuLine2);
tobyspark 29:95a7efe30527 780 screen.characterToBuffer('X', 38 + fadeCurve*20.0f, kMenuLine2);
tobyspark 24:49c6624119ae 781
tobyspark 31:01845a2347ff 782 if (debug) debug->printf("Fade curve changed by %i to %f \r\n", menuChange, fadeCurve);
tobyspark 24:49c6624119ae 783 }
tobyspark 24:49c6624119ae 784 }
tobyspark 24:49c6624119ae 785 else
tobyspark 24:49c6624119ae 786 {
tobyspark 24:49c6624119ae 787 if (debug) debug->printf("Menu changed by %i\r\n", menuChange);
tobyspark 24:49c6624119ae 788
tobyspark 24:49c6624119ae 789 *selectedMenu = selectedMenu->selectedIndex() + menuChange;
tobyspark 24:49c6624119ae 790
tobyspark 24:49c6624119ae 791 // update OLED line 2 here
tobyspark 24:49c6624119ae 792 screen.clearBufferRow(kMenuLine2);
tobyspark 24:49c6624119ae 793 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 24:49c6624119ae 794
tobyspark 24:49c6624119ae 795 if (debug) debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 24:49c6624119ae 796 }
tobyspark 0:87aab40d5806 797 }
tobyspark 0:87aab40d5806 798
tobyspark 0:87aab40d5806 799 // Action menu item
tobyspark 0:87aab40d5806 800 if (menuEnc.hasPressed())
tobyspark 0:87aab40d5806 801 {
tobyspark 0:87aab40d5806 802 if (debug) debug->printf("Action Menu Item!\r\n");
tobyspark 21:f9d63cb7cedb 803
tobyspark 0:87aab40d5806 804 // Are we changing menus?
tobyspark 23:909928cafb95 805 if (selectedMenu->selectedItem().type == SPKMenuItem::changesToMenu)
tobyspark 0:87aab40d5806 806 {
tobyspark 31:01845a2347ff 807 // If we're exiting the menu, we should set its selected index back to the menu's beginning...
tobyspark 31:01845a2347ff 808 SPKMenu* menuToReset = selectedMenu->selectedItem().payload.menu == &mainMenu? selectedMenu : NULL;
tobyspark 31:01845a2347ff 809
tobyspark 31:01845a2347ff 810 // point selected menu pointer to the new menu pointer
tobyspark 23:909928cafb95 811 selectedMenu = selectedMenu->selectedItem().payload.menu;
tobyspark 0:87aab40d5806 812
tobyspark 31:01845a2347ff 813 // ...doing this, of course, after we've used the value
tobyspark 31:01845a2347ff 814 if (menuToReset) *menuToReset = 0;
tobyspark 31:01845a2347ff 815
tobyspark 0:87aab40d5806 816 // update OLED lines 1&2
tobyspark 0:87aab40d5806 817 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 818 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 819 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 820 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 821
tobyspark 0:87aab40d5806 822 if (debug)
tobyspark 0:87aab40d5806 823 {
tobyspark 0:87aab40d5806 824 debug->printf("\r\n");
tobyspark 0:87aab40d5806 825 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 826 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 827 }
tobyspark 24:49c6624119ae 828
tobyspark 24:49c6624119ae 829 // Are we changing menus that should have a command attached?
tobyspark 24:49c6624119ae 830 if (selectedMenu == &mixModeAdditiveMenu)
tobyspark 24:49c6624119ae 831 {
tobyspark 29:95a7efe30527 832 screen.clearBufferRow(kMenuLine2);
tobyspark 29:95a7efe30527 833 screen.textToBuffer("Blend [ ----- ] Add", kMenuLine2);
tobyspark 29:95a7efe30527 834 screen.characterToBuffer('X', 38 + fadeCurve*20.0f, kMenuLine2);
tobyspark 29:95a7efe30527 835
tobyspark 29:95a7efe30527 836 mixMode = fadeCurve > 0 ? mixAdditive : mixBlend;
tobyspark 24:49c6624119ae 837 actionMixMode();
tobyspark 24:49c6624119ae 838 }
tobyspark 0:87aab40d5806 839 }
tobyspark 0:87aab40d5806 840 // With that out of the way, we should be actioning a specific menu's payload?
tobyspark 0:87aab40d5806 841 else if (selectedMenu == &mixModeMenu)
tobyspark 0:87aab40d5806 842 {
tobyspark 23:909928cafb95 843 mixMode = mixModeMenu.selectedItem().payload.command[0];
tobyspark 24:49c6624119ae 844 actionMixMode();
tobyspark 0:87aab40d5806 845 }
tobyspark 0:87aab40d5806 846 else if (selectedMenu == &resolutionMenu)
tobyspark 0:87aab40d5806 847 {
tobyspark 9:f83eadd8917a 848 bool ok = true;
tobyspark 0:87aab40d5806 849
tobyspark 23:909928cafb95 850 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, resolutionMenu.selectedItem().payload.command[0]);
tobyspark 31:01845a2347ff 851
tobyspark 31:01845a2347ff 852 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : resolutionMenu.selectedItem().payload.command[1];
tobyspark 31:01845a2347ff 853
tobyspark 31:01845a2347ff 854 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 855 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 0:87aab40d5806 856
tobyspark 25:3b519ef70341 857 string sentOK;
tobyspark 0:87aab40d5806 858 if (ok) sentOK = "Sent: ";
tobyspark 0:87aab40d5806 859 else sentOK = "Send Error: ";
tobyspark 0:87aab40d5806 860
tobyspark 26:0299f8760715 861 char sentMSGBuffer[kStringBufferLength];
tobyspark 26:0299f8760715 862 snprintf(sentMSGBuffer, kStringBufferLength,"Res %i, EDID %i", resolutionMenu.selectedItem().payload.command[0], resolutionMenu.selectedItem().payload.command[1]);
tobyspark 0:87aab40d5806 863
tobyspark 1:f9fca21102e0 864 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 25:3b519ef70341 865 screen.textToBuffer(sentOK + sentMSGBuffer, kTVOneStatusLine);
tobyspark 0:87aab40d5806 866
tobyspark 0:87aab40d5806 867 if (debug) { debug->printf("Changing resolution"); }
tobyspark 0:87aab40d5806 868 }
tobyspark 1:f9fca21102e0 869 else if (selectedMenu == &commsMenu)
tobyspark 1:f9fca21102e0 870 {
tobyspark 26:0299f8760715 871 string commsTypeString = "Network:";
tobyspark 26:0299f8760715 872 char commsStatusBuffer[kStringBufferLength] = "--";
tobyspark 1:f9fca21102e0 873
tobyspark 1:f9fca21102e0 874 // Tear down any existing comms
tobyspark 1:f9fca21102e0 875 // This is the action of commsNone
tobyspark 1:f9fca21102e0 876 // And also clears the way for other comms actions
tobyspark 26:0299f8760715 877 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 878 if (osc) {delete osc; osc = NULL;}
tobyspark 5:f8b285ca41ba 879 if (ethernet) {delete ethernet; ethernet = NULL;}
tobyspark 5:f8b285ca41ba 880 if (artNet) {delete artNet; artNet = NULL;}
tobyspark 5:f8b285ca41ba 881 if (dmx) {delete dmx; dmx = NULL;}
tobyspark 5:f8b285ca41ba 882
tobyspark 5:f8b285ca41ba 883 // Ensure we can't change to comms modes the hardware isn't switched to
tobyspark 23:909928cafb95 884 if (rj45Mode == rj45DMX && (commsMenu.selectedItem().payload.command[0] == commsOSC || commsMenu.selectedItem().payload.command[0] == commsArtNet))
tobyspark 1:f9fca21102e0 885 {
tobyspark 5:f8b285ca41ba 886 commsTypeString = "RJ45 not in Ethernet mode";
tobyspark 5:f8b285ca41ba 887 }
tobyspark 23:909928cafb95 888 else if (rj45Mode == rj45Ethernet && (commsMenu.selectedItem().payload.command[0] == commsDMXIn || commsMenu.selectedItem().payload.command[0] == commsDMXOut))
tobyspark 5:f8b285ca41ba 889 {
tobyspark 5:f8b285ca41ba 890 commsTypeString = "RJ45 not in DMX mode";
tobyspark 5:f8b285ca41ba 891 }
tobyspark 5:f8b285ca41ba 892 // Action!
tobyspark 23:909928cafb95 893 else if (commsMenu.selectedItem().payload.command[0] == commsOSC)
tobyspark 5:f8b285ca41ba 894 {
tobyspark 5:f8b285ca41ba 895 commsMode = commsOSC;
tobyspark 5:f8b285ca41ba 896 commsTypeString = "OSC: ";
tobyspark 1:f9fca21102e0 897
tobyspark 1:f9fca21102e0 898 ethernet = new EthernetNetIf(
tobyspark 1:f9fca21102e0 899 IpAddr(kOSCMbedIPAddress),
tobyspark 1:f9fca21102e0 900 IpAddr(kOSCMbedSubnetMask),
tobyspark 1:f9fca21102e0 901 IpAddr(kOSCMbedGateway),
tobyspark 1:f9fca21102e0 902 IpAddr(kOSCMbedDNS)
tobyspark 1:f9fca21102e0 903 );
tobyspark 3:033d2b7768f3 904
tobyspark 1:f9fca21102e0 905 EthernetErr ethError = ethernet->setup();
tobyspark 1:f9fca21102e0 906 if(ethError)
tobyspark 1:f9fca21102e0 907 {
tobyspark 1:f9fca21102e0 908 if (debug) debug->printf("Ethernet setup error, %d", ethError);
tobyspark 26:0299f8760715 909 snprintf(commsStatusBuffer, kStringBufferLength, "Ethernet setup failed");
tobyspark 5:f8b285ca41ba 910 commsMenu = commsNone;
tobyspark 1:f9fca21102e0 911 // break out of here. this setup should be a function that returns a boolean
tobyspark 1:f9fca21102e0 912 }
tobyspark 1:f9fca21102e0 913
tobyspark 1:f9fca21102e0 914 osc = new OSCClass();
tobyspark 3:033d2b7768f3 915 osc->setReceiveMessage(&recMessage);
tobyspark 1:f9fca21102e0 916 osc->begin(kOSCMbedPort);
tobyspark 1:f9fca21102e0 917
tobyspark 26:0299f8760715 918 snprintf(commsStatusBuffer, kStringBufferLength, "Listening on %i", kOSCMbedPort);
tobyspark 1:f9fca21102e0 919 }
tobyspark 23:909928cafb95 920 else if (commsMenu.selectedItem().payload.command[0] == commsArtNet)
tobyspark 1:f9fca21102e0 921 {
tobyspark 5:f8b285ca41ba 922 commsMode = commsArtNet;
tobyspark 5:f8b285ca41ba 923 commsTypeString = "ArtNet: ";
tobyspark 3:033d2b7768f3 924
tobyspark 3:033d2b7768f3 925 artNet = new DmxArtNet();
tobyspark 1:f9fca21102e0 926
tobyspark 3:033d2b7768f3 927 artNet->BindIpAddress = IpAddr(kArtNetBindIPAddress);
tobyspark 3:033d2b7768f3 928 artNet->BCastAddress = IpAddr(kArtNetBroadcastAddress);
tobyspark 3:033d2b7768f3 929
tobyspark 3:033d2b7768f3 930 artNet->InitArtPollReplyDefaults();
tobyspark 3:033d2b7768f3 931
tobyspark 3:033d2b7768f3 932 artNet->ArtPollReply.PortType[0] = 128; // output
tobyspark 3:033d2b7768f3 933 artNet->ArtPollReply.PortType[2] = 64; // input
tobyspark 3:033d2b7768f3 934 artNet->ArtPollReply.GoodInput[2] = 4;
tobyspark 3:033d2b7768f3 935
tobyspark 3:033d2b7768f3 936 artNet->Init();
tobyspark 3:033d2b7768f3 937 artNet->SendArtPollReply(); // announce to art-net nodes
tobyspark 3:033d2b7768f3 938
tobyspark 26:0299f8760715 939 snprintf(commsStatusBuffer, kStringBufferLength, "Listening");
tobyspark 1:f9fca21102e0 940 }
tobyspark 23:909928cafb95 941 else if (commsMenu.selectedItem().payload.command[0] == commsDMXIn)
tobyspark 1:f9fca21102e0 942 {
tobyspark 5:f8b285ca41ba 943 commsMode = commsDMXIn;
tobyspark 5:f8b285ca41ba 944 commsTypeString = "DMX In: ";
tobyspark 1:f9fca21102e0 945
tobyspark 5:f8b285ca41ba 946 dmxDirectionDOUT = 0;
tobyspark 5:f8b285ca41ba 947
tobyspark 5:f8b285ca41ba 948 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 1:f9fca21102e0 949 }
tobyspark 23:909928cafb95 950 else if (commsMenu.selectedItem().payload.command[0] == commsDMXOut)
tobyspark 5:f8b285ca41ba 951 {
tobyspark 5:f8b285ca41ba 952 commsMode = commsDMXOut;
tobyspark 5:f8b285ca41ba 953 commsTypeString = "DMX Out: ";
tobyspark 5:f8b285ca41ba 954
tobyspark 5:f8b285ca41ba 955 dmxDirectionDOUT = 1;
tobyspark 5:f8b285ca41ba 956
tobyspark 5:f8b285ca41ba 957 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 5:f8b285ca41ba 958 }
tobyspark 5:f8b285ca41ba 959
tobyspark 1:f9fca21102e0 960 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 961 screen.textToBuffer(commsTypeString + commsStatusBuffer, kCommsStatusLine);
tobyspark 1:f9fca21102e0 962 }
tobyspark 12:c270870bdd23 963 else if (selectedMenu == &advancedMenu)
tobyspark 12:c270870bdd23 964 {
tobyspark 23:909928cafb95 965 if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOff)
tobyspark 12:c270870bdd23 966 {
tobyspark 31:01845a2347ff 967 bool ok;
tobyspark 12:c270870bdd23 968
tobyspark 15:4b394c64b461 969 ok = tvOne.setHDCPOn(false);
tobyspark 12:c270870bdd23 970
tobyspark 12:c270870bdd23 971 std::string sendOK = ok ? "Sent: HDCP Off" : "Send Error: HDCP Off";
tobyspark 12:c270870bdd23 972
tobyspark 12:c270870bdd23 973 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 12:c270870bdd23 974 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 12:c270870bdd23 975 }
tobyspark 23:909928cafb95 976 else if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOn)
tobyspark 15:4b394c64b461 977 {
tobyspark 31:01845a2347ff 978 bool ok;
tobyspark 15:4b394c64b461 979
tobyspark 15:4b394c64b461 980 ok = tvOne.setHDCPOn(true);
tobyspark 15:4b394c64b461 981
tobyspark 15:4b394c64b461 982 std::string sendOK = ok ? "Sent: HDCP On" : "Send Error: HDCP On";
tobyspark 15:4b394c64b461 983
tobyspark 15:4b394c64b461 984 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 15:4b394c64b461 985 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 15:4b394c64b461 986 }
tobyspark 31:01845a2347ff 987 else if (advancedMenu.selectedItem().payload.command[0] == advancedEDIDPassthrough)
tobyspark 31:01845a2347ff 988 {
tobyspark 31:01845a2347ff 989 tvOneEDIDPassthrough = true;
tobyspark 31:01845a2347ff 990
tobyspark 31:01845a2347ff 991 bool ok = true;
tobyspark 31:01845a2347ff 992
tobyspark 31:01845a2347ff 993 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : resolutionMenu.selectedItem().payload.command[1];
tobyspark 31:01845a2347ff 994
tobyspark 31:01845a2347ff 995 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 996 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 997
tobyspark 31:01845a2347ff 998 std::string sendOK = ok ? "Sent: EDID. Next:conform?" : "Send Error: EDID";
tobyspark 31:01845a2347ff 999
tobyspark 31:01845a2347ff 1000 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 31:01845a2347ff 1001 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 31:01845a2347ff 1002 }
tobyspark 31:01845a2347ff 1003 else if (advancedMenu.selectedItem().payload.command[0] == advancedEDIDInternal)
tobyspark 31:01845a2347ff 1004 {
tobyspark 31:01845a2347ff 1005 tvOneEDIDPassthrough = false;
tobyspark 31:01845a2347ff 1006
tobyspark 31:01845a2347ff 1007 bool ok = true;
tobyspark 31:01845a2347ff 1008
tobyspark 31:01845a2347ff 1009 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : resolutionMenu.selectedItem().payload.command[1];
tobyspark 31:01845a2347ff 1010
tobyspark 31:01845a2347ff 1011 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 1012 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 31:01845a2347ff 1013
tobyspark 31:01845a2347ff 1014 std::string sendOK = ok ? "Sent: EDID. Next:conform?" : "Send Error: EDID";
tobyspark 31:01845a2347ff 1015
tobyspark 31:01845a2347ff 1016 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 31:01845a2347ff 1017 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 31:01845a2347ff 1018 }
tobyspark 30:873979018850 1019 else if (advancedMenu.selectedItem().payload.command[0] == advancedTestSources)
tobyspark 29:95a7efe30527 1020 {
tobyspark 31:01845a2347ff 1021 handleTVOneSources(true);
tobyspark 29:95a7efe30527 1022 }
tobyspark 23:909928cafb95 1023 else if (advancedMenu.selectedItem().payload.command[0] == advancedConformProcessor)
tobyspark 17:fc68d40b8b1f 1024 {
tobyspark 20:8b92d7922c48 1025 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 20:8b92d7922c48 1026 screen.textToBuffer("Conforming...", kTVOneStatusLine);
tobyspark 20:8b92d7922c48 1027 screen.sendBuffer();
tobyspark 20:8b92d7922c48 1028
tobyspark 17:fc68d40b8b1f 1029 bool ok = conformProcessor();
tobyspark 17:fc68d40b8b1f 1030
tobyspark 17:fc68d40b8b1f 1031 std::string sendOK = ok ? "Conform success" : "Send Error: Conform";
tobyspark 17:fc68d40b8b1f 1032
tobyspark 17:fc68d40b8b1f 1033 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 17:fc68d40b8b1f 1034 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 17:fc68d40b8b1f 1035 }
tobyspark 23:909928cafb95 1036 else if (advancedMenu.selectedItem().payload.command[0] == advancedLoadDefaults)
tobyspark 16:52484666b323 1037 {
tobyspark 16:52484666b323 1038 settings.loadDefaults();
tobyspark 27:27851d3d2bba 1039 setMixModeMenuItems();
tobyspark 27:27851d3d2bba 1040 setResolutionMenuItems();
tobyspark 16:52484666b323 1041
tobyspark 16:52484666b323 1042 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 16:52484666b323 1043 screen.textToBuffer("Controller reverted", kTVOneStatusLine);
tobyspark 16:52484666b323 1044 }
tobyspark 23:909928cafb95 1045 else if (advancedMenu.selectedItem().payload.command[0] == advancedSelfTest)
tobyspark 15:4b394c64b461 1046 {
tobyspark 17:fc68d40b8b1f 1047 selfTest();
tobyspark 15:4b394c64b461 1048 }
tobyspark 23:909928cafb95 1049 else if (advancedMenu.selectedItem().payload.command[0] == advancedSetResolutions)
tobyspark 21:f9d63cb7cedb 1050 {
tobyspark 21:f9d63cb7cedb 1051 bool ok;
tobyspark 21:f9d63cb7cedb 1052 ok = tvOne.setCustomResolutions();
tobyspark 21:f9d63cb7cedb 1053
tobyspark 21:f9d63cb7cedb 1054 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 21:f9d63cb7cedb 1055 screen.textToBuffer(ok ? "Resolutions set" : "Res' could not be set", kTVOneStatusLine);
tobyspark 21:f9d63cb7cedb 1056 }
tobyspark 12:c270870bdd23 1057 }
tobyspark 0:87aab40d5806 1058 else
tobyspark 0:87aab40d5806 1059 {
tobyspark 0:87aab40d5806 1060 if (debug) { debug->printf("Warning: No action identified"); }
tobyspark 0:87aab40d5806 1061 }
tobyspark 0:87aab40d5806 1062 }
tobyspark 0:87aab40d5806 1063
tobyspark 2:50043054e4f7 1064 // Send any updates to the display
tobyspark 2:50043054e4f7 1065 screen.sendBuffer();
tobyspark 5:f8b285ca41ba 1066
tobyspark 0:87aab40d5806 1067
tobyspark 5:f8b285ca41ba 1068 //// MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIXMIX MIX MIXMIX MIX MIX MIX MIX MIXMIX MIX MIX
tobyspark 0:87aab40d5806 1069
tobyspark 0:87aab40d5806 1070 bool updateFade = false;
tobyspark 3:033d2b7768f3 1071 float xFade = 0;
tobyspark 3:033d2b7768f3 1072 float fadeUp = 1;
tobyspark 3:033d2b7768f3 1073
tobyspark 3:033d2b7768f3 1074 //// TASK: Process control surface
tobyspark 3:033d2b7768f3 1075
tobyspark 0:87aab40d5806 1076 // Get new states of tap buttons, remembering at end of loop() assign these current values to the previous variables
tobyspark 5:f8b285ca41ba 1077 const bool tapLeft = !tapLeftDIN;
tobyspark 5:f8b285ca41ba 1078 const bool tapRight = !tapRightDIN;
tobyspark 0:87aab40d5806 1079
tobyspark 17:fc68d40b8b1f 1080 // We're taking a further median of the AINs on top of mbed libs v29.
tobyspark 17:fc68d40b8b1f 1081 // This takes some values from last passes and most from now. With debug off, seem to need median size > 5
tobyspark 17:fc68d40b8b1f 1082 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1083 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1084 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1085 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1086 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1087 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1088 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1089 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1090 const float xFadeAINCached = xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1091 const float fadeUpAINCached = fadeUpFilter.process(fadeUpAIN.read());
tobyspark 0:87aab40d5806 1092
tobyspark 0:87aab40d5806 1093 // When a tap is depressed, we can ignore any move of the crossfader but not fade to black
tobyspark 0:87aab40d5806 1094 if (tapLeft || tapRight)
tobyspark 0:87aab40d5806 1095 {
tobyspark 5:f8b285ca41ba 1096 // If both are pressed, take to the one that is new, ie. not the first pressed.
tobyspark 0:87aab40d5806 1097 if (tapLeft && tapRight)
tobyspark 0:87aab40d5806 1098 {
tobyspark 5:f8b285ca41ba 1099 xFade = tapLeftWasFirstPressed ? 1 : 0;
tobyspark 0:87aab40d5806 1100 }
tobyspark 5:f8b285ca41ba 1101 // If just one is pressed, take to that and remember which is pressed
tobyspark 5:f8b285ca41ba 1102 else if (tapLeft)
tobyspark 5:f8b285ca41ba 1103 {
tobyspark 5:f8b285ca41ba 1104 xFade = 0;
tobyspark 5:f8b285ca41ba 1105 tapLeftWasFirstPressed = 1;
tobyspark 5:f8b285ca41ba 1106 }
tobyspark 5:f8b285ca41ba 1107 else if (tapRight)
tobyspark 5:f8b285ca41ba 1108 {
tobyspark 5:f8b285ca41ba 1109 xFade = 1;
tobyspark 5:f8b285ca41ba 1110 tapLeftWasFirstPressed = 0;
tobyspark 5:f8b285ca41ba 1111 }
tobyspark 5:f8b285ca41ba 1112 }
tobyspark 18:ebe5da639a6a 1113 else xFade = 1.0 - fadeCalc(xFadeAINCached, xFadeTolerance);
tobyspark 0:87aab40d5806 1114
tobyspark 0:87aab40d5806 1115 fadeUp = 1.0 - fadeCalc(fadeUpAINCached, fadeUpTolerance);
tobyspark 0:87aab40d5806 1116
tobyspark 3:033d2b7768f3 1117 //// TASK: Process Network Comms
tobyspark 5:f8b285ca41ba 1118 if (commsMode == commsOSC)
tobyspark 3:033d2b7768f3 1119 {
tobyspark 3:033d2b7768f3 1120 if (osc->newMessage)
tobyspark 3:033d2b7768f3 1121 {
tobyspark 3:033d2b7768f3 1122 osc->newMessage = false; // fixme!
tobyspark 3:033d2b7768f3 1123 processOSC(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1124 }
tobyspark 3:033d2b7768f3 1125 }
tobyspark 3:033d2b7768f3 1126
tobyspark 5:f8b285ca41ba 1127 if (commsMode == commsArtNet)
tobyspark 3:033d2b7768f3 1128 {
tobyspark 3:033d2b7768f3 1129 if (artNet->Work()) processArtNet(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1130 }
tobyspark 3:033d2b7768f3 1131
tobyspark 5:f8b285ca41ba 1132 if (commsMode == commsDMXIn)
tobyspark 5:f8b285ca41ba 1133 {
tobyspark 5:f8b285ca41ba 1134 processDMXIn(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1135 }
tobyspark 5:f8b285ca41ba 1136
tobyspark 5:f8b285ca41ba 1137 if (commsMode == commsDMXOut)
tobyspark 5:f8b285ca41ba 1138 {
tobyspark 5:f8b285ca41ba 1139 processDMXOut(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1140 }
tobyspark 0:87aab40d5806 1141
tobyspark 0:87aab40d5806 1142 // Calculate new A&B fade percents
tobyspark 0:87aab40d5806 1143 int newFadeAPercent = 0;
tobyspark 0:87aab40d5806 1144 int newFadeBPercent = 0;
tobyspark 0:87aab40d5806 1145
tobyspark 30:873979018850 1146 if (mixMode == mixBlend)
tobyspark 11:0783cfbeb746 1147 {
tobyspark 30:873979018850 1148 if (fadeUp < 1.0)
tobyspark 30:873979018850 1149 {
tobyspark 30:873979018850 1150 // 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 1151 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 30:873979018850 1152 newFadeBPercent = xFade * fadeUp * 100.0;
tobyspark 30:873979018850 1153 }
tobyspark 30:873979018850 1154 else
tobyspark 30:873979018850 1155 {
tobyspark 30:873979018850 1156 // 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 1157 newFadeAPercent = (1.0-xFade) * 100.0;
tobyspark 30:873979018850 1158 newFadeBPercent = 100.0;
tobyspark 30:873979018850 1159 }
tobyspark 11:0783cfbeb746 1160 }
tobyspark 15:4b394c64b461 1161 else if (mixMode == mixAdditive)
tobyspark 11:0783cfbeb746 1162 {
tobyspark 22:90054fe6d86c 1163 // we need to set fade level of both windows according to the fade curve profile
tobyspark 22:90054fe6d86c 1164 float newFadeA = (1.0-xFade) * (1.0 + fadeCurve);
tobyspark 22:90054fe6d86c 1165 float newFadeB = xFade * (1 + fadeCurve);
tobyspark 22:90054fe6d86c 1166 if (newFadeA > 1.0) newFadeA = 1.0;
tobyspark 22:90054fe6d86c 1167 if (newFadeB > 1.0) newFadeB = 1.0;
tobyspark 22:90054fe6d86c 1168
tobyspark 22:90054fe6d86c 1169 newFadeAPercent = newFadeA * fadeUp * 100.0;
tobyspark 22:90054fe6d86c 1170 newFadeBPercent = newFadeB * fadeUp * 100.0;
tobyspark 11:0783cfbeb746 1171 }
tobyspark 15:4b394c64b461 1172 else if (mixMode >= mixKey)
tobyspark 11:0783cfbeb746 1173 {
tobyspark 0:87aab40d5806 1174 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 1175 newFadeBPercent = fadeUp * 100.0;
tobyspark 0:87aab40d5806 1176 }
tobyspark 0:87aab40d5806 1177
tobyspark 17:fc68d40b8b1f 1178 //// TASK: Send to TVOne if percents have changed
tobyspark 17:fc68d40b8b1f 1179
tobyspark 17:fc68d40b8b1f 1180 // No amount of median filtering is stopping flipflopping between two adjacent percents, so...
tobyspark 17:fc68d40b8b1f 1181 bool fadeAPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1182 bool fadeBPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1183 if (oldFadeAPercent == newFadeAPercent && (newFadeAPercent == fadeAPercent - 1 || newFadeAPercent == fadeAPercent + 1))
tobyspark 17:fc68d40b8b1f 1184 fadeAPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1185 else
tobyspark 17:fc68d40b8b1f 1186 fadeAPercentHasChanged = newFadeAPercent != fadeAPercent;
tobyspark 17:fc68d40b8b1f 1187 if (oldFadeBPercent == newFadeBPercent && (newFadeBPercent == fadeBPercent - 1 || newFadeBPercent == fadeBPercent + 1))
tobyspark 17:fc68d40b8b1f 1188 fadeBPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1189 else
tobyspark 17:fc68d40b8b1f 1190 fadeBPercentHasChanged = newFadeBPercent != fadeBPercent;
tobyspark 17:fc68d40b8b1f 1191
tobyspark 9:f83eadd8917a 1192 // We want to send the higher first, otherwise black flashes can happen on taps
tobyspark 17:fc68d40b8b1f 1193 if (fadeAPercentHasChanged && newFadeAPercent >= newFadeBPercent)
tobyspark 8:d46cc49f0f37 1194 {
tobyspark 17:fc68d40b8b1f 1195 oldFadeAPercent = fadeAPercent;
tobyspark 0:87aab40d5806 1196 fadeAPercent = newFadeAPercent;
tobyspark 0:87aab40d5806 1197 updateFade = true;
tobyspark 0:87aab40d5806 1198
tobyspark 0:87aab40d5806 1199 fadeAPO = fadeAPercent / 100.0;
tobyspark 0:87aab40d5806 1200 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 0:87aab40d5806 1201 }
tobyspark 17:fc68d40b8b1f 1202 if (fadeBPercentHasChanged)
tobyspark 8:d46cc49f0f37 1203 {
tobyspark 17:fc68d40b8b1f 1204 oldFadeBPercent = fadeBPercent;
tobyspark 0:87aab40d5806 1205 fadeBPercent = newFadeBPercent;
tobyspark 0:87aab40d5806 1206 updateFade = true;
tobyspark 0:87aab40d5806 1207
tobyspark 0:87aab40d5806 1208 fadeBPO = fadeBPercent / 100.0;
tobyspark 0:87aab40d5806 1209 tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 0:87aab40d5806 1210 }
tobyspark 17:fc68d40b8b1f 1211 if (fadeAPercentHasChanged && newFadeAPercent < newFadeBPercent)
tobyspark 9:f83eadd8917a 1212 {
tobyspark 17:fc68d40b8b1f 1213 oldFadeAPercent = fadeAPercent;
tobyspark 9:f83eadd8917a 1214 fadeAPercent = newFadeAPercent;
tobyspark 9:f83eadd8917a 1215 updateFade = true;
tobyspark 9:f83eadd8917a 1216
tobyspark 9:f83eadd8917a 1217 fadeAPO = fadeAPercent / 100.0;
tobyspark 9:f83eadd8917a 1218 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 9:f83eadd8917a 1219 }
tobyspark 8:d46cc49f0f37 1220 if (updateFade && debug)
tobyspark 8:d46cc49f0f37 1221 {
tobyspark 0:87aab40d5806 1222 //debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAIN.read(), fadeUpAIN.read());
tobyspark 0:87aab40d5806 1223 debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAINCached, fadeUpAINCached);
tobyspark 0:87aab40d5806 1224 debug->printf("xFade = %3f fadeUp = %3f fadeA% = %i fadeB% = %i \r\n", xFade, fadeUp, fadeAPercent, fadeBPercent);
tobyspark 18:ebe5da639a6a 1225 debug->printf("\r\n");
tobyspark 0:87aab40d5806 1226 }
tobyspark 30:873979018850 1227
tobyspark 30:873979018850 1228 // If we're not actively mixing, we can do any housekeeping...
tobyspark 30:873979018850 1229 if (!updateFade)
tobyspark 30:873979018850 1230 {
tobyspark 30:873979018850 1231 // We should check up on any source flagged unstable
tobyspark 30:873979018850 1232 if (!tvOneRGB1Stable || !tvOneRGB2Stable) handleTVOneSources();
tobyspark 30:873979018850 1233 }
tobyspark 0:87aab40d5806 1234 }
tobyspark 30:873979018850 1235 }