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 Nov 05 20:06:20 2012 +0000
Revision:
34:69dfe64e7e6b
Parent:
33:e6672a9bd571
Child:
35:d5d9f0838f99
EDID Internal Sorted: Uploads Matrox EDID and sets either that, HDMI or DVI. Improved missing source handling.

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