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:
Tue Dec 11 18:05:32 2012 +0000
Revision:
49:16309f39cead
Parent:
48:c0fedfa8c525
Child:
50:e98220a71065
v25 - UX and robustness

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 47:ff6b98459548 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 35:d5d9f0838f99 41 * v22 - EDID passthrough override and EDID upload from USB mass storage
tobyspark 49:16309f39cead 42 * v23 - Set keying values from controller
tobyspark 44:723e65413ebe 43 * v24 - Conform uploads SIS image; now once firmware is loaded controller is all that is required
tobyspark 49:16309f39cead 44 * v25 - UX work
tobyspark 36:8b5c75c8bc23 45 * vxx - TODO: Writes back to .ini on USB mass storage: keyer updates, comms, hdcp, edid internal/passthrough, ...?
tobyspark 8:d46cc49f0f37 46 * vxx - TODO: EDID creation from resolution
tobyspark 8:d46cc49f0f37 47 */
tobyspark 8:d46cc49f0f37 48
tobyspark 0:87aab40d5806 49 #include "mbed.h"
tobyspark 0:87aab40d5806 50
tobyspark 0:87aab40d5806 51 #include "spk_tvone_mbed.h"
tobyspark 0:87aab40d5806 52 #include "spk_utils.h"
tobyspark 0:87aab40d5806 53 #include "spk_mRotaryEncoder.h"
tobyspark 0:87aab40d5806 54 #include "spk_oled_ssd1305.h"
tobyspark 2:50043054e4f7 55 #include "spk_oled_gfx.h"
tobyspark 11:0783cfbeb746 56 #include "spk_settings.h"
tobyspark 1:f9fca21102e0 57 #include "EthernetNetIf.h"
tobyspark 1:f9fca21102e0 58 #include "mbedOSC.h"
tobyspark 3:033d2b7768f3 59 #include "DmxArtNet.h"
tobyspark 5:f8b285ca41ba 60 #include "DMX.h"
tobyspark 17:fc68d40b8b1f 61 #include "filter.h"
tobyspark 0:87aab40d5806 62
tobyspark 49:16309f39cead 63 #define kSPKDFSoftwareVersion "25"
tobyspark 13:3796bde6ba8f 64
tobyspark 5:f8b285ca41ba 65 // MBED PINS
tobyspark 5:f8b285ca41ba 66
tobyspark 5:f8b285ca41ba 67 #define kMBED_AIN_XFADE p20
tobyspark 5:f8b285ca41ba 68 #define kMBED_AIN_FADEUP p19
tobyspark 5:f8b285ca41ba 69 #define kMBED_DIN_TAP_L p24
tobyspark 5:f8b285ca41ba 70 #define kMBED_DIN_TAP_R p23
tobyspark 5:f8b285ca41ba 71 #define kMBED_ENC_SW p15
tobyspark 5:f8b285ca41ba 72 #define kMBED_ENC_A p16
tobyspark 5:f8b285ca41ba 73 #define kMBED_ENC_B p17
tobyspark 5:f8b285ca41ba 74
tobyspark 5:f8b285ca41ba 75 #define kMBED_RS232_TTLTX p13
tobyspark 5:f8b285ca41ba 76 #define kMBED_RS232_TTLRX p14
tobyspark 5:f8b285ca41ba 77
tobyspark 5:f8b285ca41ba 78 #define kMBED_OLED_MOSI p5
tobyspark 5:f8b285ca41ba 79 #define kMBED_OLED_SCK p7
tobyspark 5:f8b285ca41ba 80 #define kMBED_OLED_CS p8
tobyspark 5:f8b285ca41ba 81 #define kMBED_OLED_RES p9
tobyspark 5:f8b285ca41ba 82 #define kMBED_OLED_DC p10
tobyspark 5:f8b285ca41ba 83
tobyspark 5:f8b285ca41ba 84 #define kMBED_DIN_ETHLO_DMXHI p30
tobyspark 5:f8b285ca41ba 85 #define kMBED_DOUT_RS485_TXHI_RXLO p29
tobyspark 5:f8b285ca41ba 86 #define kMBED_RS485_TTLTX p28
tobyspark 5:f8b285ca41ba 87 #define kMBED_RS485_TTLRX p27
tobyspark 5:f8b285ca41ba 88
tobyspark 5:f8b285ca41ba 89 // DISPLAY
tobyspark 5:f8b285ca41ba 90
tobyspark 1:f9fca21102e0 91 #define kMenuLine1 3
tobyspark 1:f9fca21102e0 92 #define kMenuLine2 4
tobyspark 1:f9fca21102e0 93 #define kCommsStatusLine 6
tobyspark 1:f9fca21102e0 94 #define kTVOneStatusLine 7
tobyspark 48:c0fedfa8c525 95 #define kTVOneStatusMessageHoldTime 5
tobyspark 1:f9fca21102e0 96
tobyspark 5:f8b285ca41ba 97 // NETWORKING
tobyspark 5:f8b285ca41ba 98
tobyspark 1:f9fca21102e0 99 #define kOSCMbedPort 10000
tobyspark 1:f9fca21102e0 100 #define kOSCMbedIPAddress 10,0,0,2
tobyspark 1:f9fca21102e0 101 #define kOSCMbedSubnetMask 255,255,255,0
tobyspark 1:f9fca21102e0 102 #define kOSCMbedGateway 10,0,0,1
tobyspark 1:f9fca21102e0 103 #define kOSCMbedDNS 10,0,0,1
tobyspark 0:87aab40d5806 104
tobyspark 3:033d2b7768f3 105 #define kArtNetBindIPAddress 2,0,0,100
tobyspark 3:033d2b7768f3 106 #define kArtNetBroadcastAddress 2,255,255,255
tobyspark 3:033d2b7768f3 107
tobyspark 5:f8b285ca41ba 108 #define kDMXInChannelXFade 0
tobyspark 5:f8b285ca41ba 109 #define kDMXInChannelFadeUp 1
tobyspark 5:f8b285ca41ba 110 #define kDMXOutChannelXFade 0
tobyspark 5:f8b285ca41ba 111 #define kDMXOutChannelFadeUp 1
tobyspark 5:f8b285ca41ba 112
tobyspark 13:3796bde6ba8f 113 // 8.3 format filename only, no subdirs
tobyspark 13:3796bde6ba8f 114 #define kSPKDFSettingsFilename "SPKDF.ini"
tobyspark 11:0783cfbeb746 115
tobyspark 26:0299f8760715 116 #define kStringBufferLength 30
tobyspark 26:0299f8760715 117
tobyspark 0:87aab40d5806 118 //// DEBUG
tobyspark 0:87aab40d5806 119
tobyspark 0:87aab40d5806 120 // Comment out one or the other...
tobyspark 41:00d1cd3b2af2 121 //Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial
tobyspark 37:744bef2e8be8 122 Serial *debug = NULL; // For release (no debugging)
tobyspark 0:87aab40d5806 123
tobyspark 15:4b394c64b461 124 //// SOFT RESET
tobyspark 15:4b394c64b461 125
tobyspark 15:4b394c64b461 126 extern "C" void mbed_reset();
tobyspark 15:4b394c64b461 127
tobyspark 0:87aab40d5806 128 //// mBED PIN ASSIGNMENTS
tobyspark 0:87aab40d5806 129
tobyspark 0:87aab40d5806 130 // Inputs
tobyspark 5:f8b285ca41ba 131 AnalogIn xFadeAIN(kMBED_AIN_XFADE);
tobyspark 5:f8b285ca41ba 132 AnalogIn fadeUpAIN(kMBED_AIN_FADEUP);
tobyspark 5:f8b285ca41ba 133 DigitalIn tapLeftDIN(kMBED_DIN_TAP_L);
tobyspark 5:f8b285ca41ba 134 DigitalIn tapRightDIN(kMBED_DIN_TAP_R);
tobyspark 17:fc68d40b8b1f 135 medianFilter xFadeFilter(9);
tobyspark 17:fc68d40b8b1f 136 medianFilter fadeUpFilter(9);
tobyspark 0:87aab40d5806 137
tobyspark 5:f8b285ca41ba 138 SPKRotaryEncoder menuEnc(kMBED_ENC_A, kMBED_ENC_B, kMBED_ENC_SW);
tobyspark 5:f8b285ca41ba 139
tobyspark 5:f8b285ca41ba 140 DigitalIn rj45ModeDIN(kMBED_DIN_ETHLO_DMXHI);
tobyspark 0:87aab40d5806 141
tobyspark 0:87aab40d5806 142 // Outputs
tobyspark 0:87aab40d5806 143 PwmOut fadeAPO(LED1);
tobyspark 0:87aab40d5806 144 PwmOut fadeBPO(LED2);
tobyspark 0:87aab40d5806 145
tobyspark 5:f8b285ca41ba 146 DigitalOut dmxDirectionDOUT(kMBED_DOUT_RS485_TXHI_RXLO);
tobyspark 5:f8b285ca41ba 147
tobyspark 0:87aab40d5806 148 // SPKTVOne(PinName txPin, PinName rxPin, PinName signWritePin, PinName signErrorPin, Serial *debugSerial)
tobyspark 5:f8b285ca41ba 149 SPKTVOne tvOne(kMBED_RS232_TTLTX, kMBED_RS232_TTLRX, LED3, LED4, debug);
tobyspark 0:87aab40d5806 150
tobyspark 0:87aab40d5806 151 // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL);
tobyspark 5:f8b285ca41ba 152 SPKDisplay screen(kMBED_OLED_MOSI, kMBED_OLED_SCK, kMBED_OLED_CS, kMBED_OLED_DC, kMBED_OLED_RES, debug);
tobyspark 48:c0fedfa8c525 153 SPKMessageHold tvOneStatusMessage;
tobyspark 0:87aab40d5806 154
tobyspark 11:0783cfbeb746 155 // Saved Settings
tobyspark 11:0783cfbeb746 156 SPKSettings settings;
tobyspark 11:0783cfbeb746 157
tobyspark 0:87aab40d5806 158 // Menu
tobyspark 0:87aab40d5806 159 SPKMenu *selectedMenu;
tobyspark 23:909928cafb95 160 SPKMenu mainMenu;
tobyspark 23:909928cafb95 161 SPKMenu resolutionMenu;
tobyspark 12:c270870bdd23 162
tobyspark 24:49c6624119ae 163 SPKMenu mixModeMenu;
tobyspark 36:8b5c75c8bc23 164 SPKMenu mixModeAdditiveMenu;
tobyspark 49:16309f39cead 165 SPKMenu mixModeUpdateKeyMenu;
tobyspark 36:8b5c75c8bc23 166 enum { mixBlend, mixAdditive, mixKey };
tobyspark 36:8b5c75c8bc23 167 int mixKeyStartIndex = 1; // need this hard coded as mixBlend and mixAdditive are now combined into the same menu item
tobyspark 30:873979018850 168 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 49:16309f39cead 169 int mixModeOld = mixMode;
tobyspark 29:95a7efe30527 170 float fadeCurve = 0.0f; // 0 = "X", ie. as per blend, 1 = "/\", ie. as per additive <-- pictograms!
tobyspark 22:90054fe6d86c 171
tobyspark 23:909928cafb95 172 SPKMenu commsMenu;
tobyspark 5:f8b285ca41ba 173 enum { commsNone, commsOSC, commsArtNet, commsDMXIn, commsDMXOut};
tobyspark 5:f8b285ca41ba 174 int commsMode = commsNone;
tobyspark 22:90054fe6d86c 175
tobyspark 23:909928cafb95 176 SPKMenu advancedMenu;
tobyspark 49:16309f39cead 177 SPKMenu advancedMenuHDCP;
tobyspark 49:16309f39cead 178 SPKMenu advancedMenuEDID;
tobyspark 41:00d1cd3b2af2 179 enum { advancedHDCPOn, advancedHDCPOff, advancedEDIDPassthrough, advancedEDIDInternal, advancedTestSources, advancedConformProcessor, advancedConformUploadProcessor, advancedLoadDefaults, advancedSetResolutions };
tobyspark 1:f9fca21102e0 180
tobyspark 5:f8b285ca41ba 181 // RJ45 Comms
tobyspark 5:f8b285ca41ba 182 enum { rj45Ethernet = 0, rj45DMX = 1}; // These values from circuit
tobyspark 5:f8b285ca41ba 183 int rj45Mode = -1;
tobyspark 1:f9fca21102e0 184 EthernetNetIf *ethernet = NULL;
tobyspark 1:f9fca21102e0 185 OSCClass *osc = NULL;
tobyspark 33:e6672a9bd571 186 OSCMessage sendMessage;
tobyspark 33:e6672a9bd571 187 OSCMessage receiveMessage;
tobyspark 3:033d2b7768f3 188 DmxArtNet *artNet = NULL;
tobyspark 5:f8b285ca41ba 189 DMX *dmx = NULL;
tobyspark 0:87aab40d5806 190
tobyspark 3:033d2b7768f3 191 // Fade logic constants
tobyspark 0:87aab40d5806 192 const float xFadeTolerance = 0.05;
tobyspark 0:87aab40d5806 193 const float fadeUpTolerance = 0.05;
tobyspark 0:87aab40d5806 194
tobyspark 0:87aab40d5806 195 // A&B Fade as resolved percent
tobyspark 0:87aab40d5806 196 int fadeAPercent = 0;
tobyspark 0:87aab40d5806 197 int fadeBPercent = 0;
tobyspark 17:fc68d40b8b1f 198 int oldFadeAPercent = 0;
tobyspark 17:fc68d40b8b1f 199 int oldFadeBPercent = 0;
tobyspark 0:87aab40d5806 200
tobyspark 0:87aab40d5806 201 // Tap button states
tobyspark 5:f8b285ca41ba 202 bool tapLeftWasFirstPressed = false;
tobyspark 0:87aab40d5806 203
tobyspark 0:87aab40d5806 204 // Key mode parameters
tobyspark 0:87aab40d5806 205 int keyerParamsSet = -1; // last keyParams index uploaded to unit
tobyspark 0:87aab40d5806 206
tobyspark 30:873979018850 207 // TVOne input sources stable flag
tobyspark 34:69dfe64e7e6b 208 bool tvOneRGB1Stable = false;
tobyspark 34:69dfe64e7e6b 209 bool tvOneRGB2Stable = false;
tobyspark 30:873979018850 210
tobyspark 31:01845a2347ff 211 // TVOne behaviour flags
tobyspark 31:01845a2347ff 212 bool tvOneHDCPOn = false;
tobyspark 34:69dfe64e7e6b 213 bool tvOneEDIDPassthrough = false;
tobyspark 31:01845a2347ff 214 const int32_t EDIDPassthroughSlot = 7;
tobyspark 31:01845a2347ff 215
tobyspark 34:69dfe64e7e6b 216
tobyspark 33:e6672a9bd571 217 void processOSCIn(float &xFade, float &fadeUp) {
tobyspark 25:3b519ef70341 218 string statusMessage;
tobyspark 3:033d2b7768f3 219
tobyspark 33:e6672a9bd571 220 if (!strcmp( receiveMessage.getTopAddress() , "dvimxr" ))
tobyspark 3:033d2b7768f3 221 {
tobyspark 25:3b519ef70341 222 statusMessage = "OSC: /dvimxr";
tobyspark 33:e6672a9bd571 223 if (!strcmp( receiveMessage.getSubAddress() , "xFade" ))
tobyspark 25:3b519ef70341 224 {
tobyspark 33:e6672a9bd571 225 if (receiveMessage.getArgNum() == 1)
tobyspark 33:e6672a9bd571 226 if (receiveMessage.getTypeTag(0) == 'f')
tobyspark 25:3b519ef70341 227 {
tobyspark 33:e6672a9bd571 228 xFade = receiveMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 229 char buffer[15];
tobyspark 26:0299f8760715 230 snprintf(buffer, kStringBufferLength, "/xFade %1.2f", xFade);
tobyspark 25:3b519ef70341 231 statusMessage += buffer;
tobyspark 25:3b519ef70341 232 }
tobyspark 25:3b519ef70341 233 }
tobyspark 33:e6672a9bd571 234 else if (!strcmp( receiveMessage.getSubAddress() , "fadeUp" ))
tobyspark 25:3b519ef70341 235 {
tobyspark 33:e6672a9bd571 236 if (receiveMessage.getArgNum() == 1)
tobyspark 33:e6672a9bd571 237 if (receiveMessage.getTypeTag(0) == 'f')
tobyspark 3:033d2b7768f3 238 {
tobyspark 33:e6672a9bd571 239 fadeUp = receiveMessage.getArgFloat(0);
tobyspark 25:3b519ef70341 240 char buffer[15];
tobyspark 26:0299f8760715 241 snprintf(buffer, kStringBufferLength, "/fadeUp %1.2f", fadeUp);
tobyspark 25:3b519ef70341 242 statusMessage += buffer;
tobyspark 3:033d2b7768f3 243 }
tobyspark 25:3b519ef70341 244 }
tobyspark 25:3b519ef70341 245 else
tobyspark 25:3b519ef70341 246 {
tobyspark 33:e6672a9bd571 247 statusMessage += receiveMessage.getSubAddress();
tobyspark 25:3b519ef70341 248 statusMessage += " - Ignoring";
tobyspark 25:3b519ef70341 249 }
tobyspark 3:033d2b7768f3 250 }
tobyspark 3:033d2b7768f3 251 else
tobyspark 3:033d2b7768f3 252 {
tobyspark 25:3b519ef70341 253 statusMessage = "OSC: ";
tobyspark 33:e6672a9bd571 254 statusMessage += receiveMessage.getTopAddress();
tobyspark 25:3b519ef70341 255 statusMessage += " - Ignoring";
tobyspark 3:033d2b7768f3 256 }
tobyspark 3:033d2b7768f3 257
tobyspark 3:033d2b7768f3 258 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 259 screen.textToBuffer(statusMessage, kCommsStatusLine);
tobyspark 33:e6672a9bd571 260
tobyspark 25:3b519ef70341 261 if (debug) debug->printf("%s \r\n", statusMessage.c_str());
tobyspark 3:033d2b7768f3 262
tobyspark 3:033d2b7768f3 263 }
tobyspark 3:033d2b7768f3 264
tobyspark 33:e6672a9bd571 265 void processOSCOut(float &xFade, float &fadeUp)
tobyspark 33:e6672a9bd571 266 {
tobyspark 33:e6672a9bd571 267 char statusMessageBuffer[kStringBufferLength];
tobyspark 33:e6672a9bd571 268
tobyspark 33:e6672a9bd571 269 sendMessage.setAddress("dvimxr", "xFadeFadeUp");
tobyspark 33:e6672a9bd571 270 sendMessage.setArgs("ff", &xFade, &fadeUp);
tobyspark 33:e6672a9bd571 271 osc->sendOsc(&sendMessage);
tobyspark 33:e6672a9bd571 272
tobyspark 33:e6672a9bd571 273 screen.clearBufferRow(kCommsStatusLine);
tobyspark 33:e6672a9bd571 274 snprintf(statusMessageBuffer, kStringBufferLength, "OSC Out: xF %.2f fUp %.2f", xFade, fadeUp);
tobyspark 33:e6672a9bd571 275 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 33:e6672a9bd571 276
tobyspark 33:e6672a9bd571 277 if (debug) debug->printf(statusMessageBuffer);
tobyspark 33:e6672a9bd571 278 }
tobyspark 33:e6672a9bd571 279
tobyspark 33:e6672a9bd571 280 void processArtNetIn(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 281 {
tobyspark 3:033d2b7768f3 282 screen.clearBufferRow(kCommsStatusLine);
tobyspark 3:033d2b7768f3 283 screen.textToBuffer("ArtNet activity", kCommsStatusLine);
tobyspark 33:e6672a9bd571 284
tobyspark 3:033d2b7768f3 285 if (debug) debug->printf("ArtNet activity");
tobyspark 3:033d2b7768f3 286 }
tobyspark 0:87aab40d5806 287
tobyspark 33:e6672a9bd571 288 void processArtNetOut(float &xFade, float &fadeUp)
tobyspark 33:e6672a9bd571 289 {
tobyspark 33:e6672a9bd571 290 char statusMessageBuffer[kStringBufferLength];
tobyspark 33:e6672a9bd571 291
tobyspark 33:e6672a9bd571 292 int xFadeDMX = xFade*255;
tobyspark 33:e6672a9bd571 293 int fadeUpDMX = fadeUp*255;
tobyspark 33:e6672a9bd571 294
tobyspark 33:e6672a9bd571 295 // Universe 0, Channel 0 = xFade, Channel 1 = fadeUp
tobyspark 33:e6672a9bd571 296 char dmxData[2] = {xFadeDMX, fadeUpDMX};
tobyspark 33:e6672a9bd571 297 artNet->Send_ArtDmx(0, 0, dmxData, 2);
tobyspark 33:e6672a9bd571 298
tobyspark 33:e6672a9bd571 299 screen.clearBufferRow(kCommsStatusLine);
tobyspark 33:e6672a9bd571 300 snprintf(statusMessageBuffer, kStringBufferLength, "A'Net Out: xF%3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 33:e6672a9bd571 301 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 33:e6672a9bd571 302
tobyspark 33:e6672a9bd571 303 if (debug) debug->printf(statusMessageBuffer);
tobyspark 33:e6672a9bd571 304 }
tobyspark 33:e6672a9bd571 305
tobyspark 8:d46cc49f0f37 306 void processDMXIn(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 307 {
tobyspark 26:0299f8760715 308 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 309
tobyspark 5:f8b285ca41ba 310 int xFadeDMX = dmx->get(kDMXInChannelXFade);
tobyspark 7:e6717468c18d 311 int fadeUpDMX = dmx->get(kDMXInChannelFadeUp);
tobyspark 5:f8b285ca41ba 312
tobyspark 5:f8b285ca41ba 313 xFade = (float)xFadeDMX/255;
tobyspark 5:f8b285ca41ba 314 fadeUp = (float)fadeUpDMX/255;
tobyspark 5:f8b285ca41ba 315
tobyspark 5:f8b285ca41ba 316 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 317 snprintf(statusMessageBuffer, kStringBufferLength, "DMX In: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 318 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 33:e6672a9bd571 319
tobyspark 25:3b519ef70341 320 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 321 }
tobyspark 5:f8b285ca41ba 322
tobyspark 8:d46cc49f0f37 323 void processDMXOut(float &xFade, float &fadeUp)
tobyspark 8:d46cc49f0f37 324 {
tobyspark 26:0299f8760715 325 char statusMessageBuffer[kStringBufferLength];
tobyspark 5:f8b285ca41ba 326
tobyspark 5:f8b285ca41ba 327 int xFadeDMX = xFade*255;
tobyspark 5:f8b285ca41ba 328 int fadeUpDMX = fadeUp*255;
tobyspark 5:f8b285ca41ba 329
tobyspark 5:f8b285ca41ba 330 dmx->put(kDMXOutChannelXFade, xFadeDMX);
tobyspark 5:f8b285ca41ba 331 dmx->put(kDMXOutChannelFadeUp, fadeUpDMX);
tobyspark 5:f8b285ca41ba 332
tobyspark 5:f8b285ca41ba 333 screen.clearBufferRow(kCommsStatusLine);
tobyspark 26:0299f8760715 334 snprintf(statusMessageBuffer, kStringBufferLength, "DMX Out: xF %3i fUp %3i", xFadeDMX, fadeUpDMX);
tobyspark 25:3b519ef70341 335 screen.textToBuffer(statusMessageBuffer, kCommsStatusLine);
tobyspark 33:e6672a9bd571 336
tobyspark 25:3b519ef70341 337 if (debug) debug->printf(statusMessageBuffer);
tobyspark 5:f8b285ca41ba 338 }
tobyspark 0:87aab40d5806 339
tobyspark 8:d46cc49f0f37 340 inline float fadeCalc (const float AIN, const float tolerance)
tobyspark 8:d46cc49f0f37 341 {
tobyspark 0:87aab40d5806 342 float pos ;
tobyspark 0:87aab40d5806 343 if (AIN < tolerance) pos = 0;
tobyspark 0:87aab40d5806 344 else if (AIN > 1.0 - tolerance) pos = 1;
tobyspark 0:87aab40d5806 345 else pos = (AIN - tolerance) / (1 - 2*tolerance);
tobyspark 0:87aab40d5806 346 if (debug && false) debug->printf("fadeCalc in: %f out: %f \r\n", AIN, pos);
tobyspark 0:87aab40d5806 347 return pos;
tobyspark 0:87aab40d5806 348 }
tobyspark 0:87aab40d5806 349
tobyspark 34:69dfe64e7e6b 350 bool handleTVOneSources()
tobyspark 30:873979018850 351 {
tobyspark 49:16309f39cead 352 static int notOKCounter = 0;
tobyspark 49:16309f39cead 353
tobyspark 30:873979018850 354 bool ok = true;
tobyspark 30:873979018850 355
tobyspark 30:873979018850 356 int32_t payload = 0;
tobyspark 30:873979018850 357
tobyspark 30:873979018850 358 ok = ok && tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 34:69dfe64e7e6b 359 bool RGB1 = (payload == 1);
tobyspark 30:873979018850 360
tobyspark 30:873979018850 361 ok = ok && tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload);
tobyspark 30:873979018850 362 bool RGB2 = (payload == 1);
tobyspark 30:873979018850 363
tobyspark 34:69dfe64e7e6b 364 ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, payload);
tobyspark 34:69dfe64e7e6b 365 int sourceA = payload;
tobyspark 34:69dfe64e7e6b 366
tobyspark 34:69dfe64e7e6b 367 ok = ok && tvOne.readCommand(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, payload);
tobyspark 34:69dfe64e7e6b 368 int sourceB = payload;
tobyspark 34:69dfe64e7e6b 369
tobyspark 44:723e65413ebe 370 if (debug) debug->printf("HandleTVOneSources: RGB1: %i, RGB2: %i, sourceA: %#x, sourceB: %#x \r\n", RGB1, RGB2, sourceA, sourceB);
tobyspark 45:cf8c2400be5c 371
tobyspark 45:cf8c2400be5c 372 string tvOneDetectString = "TVOne: ";
tobyspark 45:cf8c2400be5c 373
tobyspark 45:cf8c2400be5c 374 if (ok)
tobyspark 30:873979018850 375 {
tobyspark 45:cf8c2400be5c 376 string right = RGB1 ? "Live" : (tvOneRGB1Stable ? "Hold" : "Logo");
tobyspark 45:cf8c2400be5c 377 string left = RGB2 ? "Live" : (tvOneRGB2Stable ? "Hold" : "Logo");
tobyspark 45:cf8c2400be5c 378
tobyspark 45:cf8c2400be5c 379 tvOneDetectString += "L: ";
tobyspark 45:cf8c2400be5c 380 tvOneDetectString += left;
tobyspark 45:cf8c2400be5c 381 tvOneDetectString += " R: ";
tobyspark 45:cf8c2400be5c 382 tvOneDetectString += right;
tobyspark 30:873979018850 383 }
tobyspark 49:16309f39cead 384
tobyspark 48:c0fedfa8c525 385 tvOneStatusMessage.addMessage(tvOneDetectString, 0);
tobyspark 34:69dfe64e7e6b 386
tobyspark 34:69dfe64e7e6b 387 // Assign appropriate source depending on whether DVI input is good
tobyspark 34:69dfe64e7e6b 388 // If that assign command completes ok, and the DVI input is good, finally flag the unit has had a live source
tobyspark 34:69dfe64e7e6b 389 // 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 390 if (ok && !tvOneRGB1Stable)
tobyspark 30:873979018850 391 {
tobyspark 34:69dfe64e7e6b 392 if (RGB1 && (sourceB != kTV1SourceRGB1)) ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 34:69dfe64e7e6b 393 if (!RGB1 && (sourceB != kTV1SourceSIS2)) ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2); // Wierd: Can't set to SIS1 sometimes.
tobyspark 34:69dfe64e7e6b 394 if (ok && RGB1) tvOneRGB1Stable = true;
tobyspark 30:873979018850 395 }
tobyspark 34:69dfe64e7e6b 396 if (ok && !tvOneRGB2Stable)
tobyspark 34:69dfe64e7e6b 397 {
tobyspark 34:69dfe64e7e6b 398 if (RGB2 && (sourceA != kTV1SourceRGB2)) ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 34:69dfe64e7e6b 399 if (!RGB2 && (sourceA != kTV1SourceSIS2)) ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2);
tobyspark 34:69dfe64e7e6b 400 if (ok && RGB2) tvOneRGB2Stable = true;
tobyspark 34:69dfe64e7e6b 401 }
tobyspark 48:c0fedfa8c525 402
tobyspark 49:16309f39cead 403 // It seems there is an occasional RS232 choke around power-on of the processor.
tobyspark 49:16309f39cead 404 // Hard to reproduce, doubly so when in debug mode, this may fix.
tobyspark 49:16309f39cead 405 if (ok)
tobyspark 49:16309f39cead 406 {
tobyspark 49:16309f39cead 407 notOKCounter = 0;
tobyspark 49:16309f39cead 408 tvOne.resetCommandPeriods();
tobyspark 49:16309f39cead 409 }
tobyspark 49:16309f39cead 410 else if (++notOKCounter == 5)
tobyspark 49:16309f39cead 411 {
tobyspark 49:16309f39cead 412 printf("Handling 5x Not OK: increasing command periods\r\n");
tobyspark 49:16309f39cead 413 tvOne.increaseCommandPeriods(1500);
tobyspark 49:16309f39cead 414 }
tobyspark 49:16309f39cead 415
tobyspark 30:873979018850 416 return ok;
tobyspark 30:873979018850 417 }
tobyspark 30:873979018850 418
tobyspark 8:d46cc49f0f37 419 bool setKeyParamsTo(int index)
tobyspark 8:d46cc49f0f37 420 {
tobyspark 0:87aab40d5806 421 // Only spend the time uploading six parameters if we need to
tobyspark 0:87aab40d5806 422 // Might want to bounds check here
tobyspark 0:87aab40d5806 423
tobyspark 9:f83eadd8917a 424 bool ok;
tobyspark 0:87aab40d5806 425
tobyspark 0:87aab40d5806 426 if (index != keyerParamsSet)
tobyspark 0:87aab40d5806 427 {
tobyspark 31:01845a2347ff 428 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, settings.keyerParamSet(index)[SPKSettings::minY]);
tobyspark 31:01845a2347ff 429 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, settings.keyerParamSet(index)[SPKSettings::maxY]);
tobyspark 31:01845a2347ff 430 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, settings.keyerParamSet(index)[SPKSettings::minU]);
tobyspark 31:01845a2347ff 431 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, settings.keyerParamSet(index)[SPKSettings::maxU]);
tobyspark 31:01845a2347ff 432 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, settings.keyerParamSet(index)[SPKSettings::minV]);
tobyspark 31:01845a2347ff 433 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, settings.keyerParamSet(index)[SPKSettings::maxV]);
tobyspark 0:87aab40d5806 434
tobyspark 0:87aab40d5806 435 keyerParamsSet = index;
tobyspark 9:f83eadd8917a 436 }
tobyspark 9:f83eadd8917a 437 else
tobyspark 9:f83eadd8917a 438 {
tobyspark 9:f83eadd8917a 439 ok = true;
tobyspark 9:f83eadd8917a 440 }
tobyspark 0:87aab40d5806 441
tobyspark 0:87aab40d5806 442 return ok;
tobyspark 0:87aab40d5806 443 }
tobyspark 0:87aab40d5806 444
tobyspark 24:49c6624119ae 445 void actionMixMode()
tobyspark 24:49c6624119ae 446 {
tobyspark 31:01845a2347ff 447 if (debug) debug->printf("Changing mix mode \r\n");
tobyspark 31:01845a2347ff 448
tobyspark 24:49c6624119ae 449 bool ok = true;
tobyspark 25:3b519ef70341 450 string sentOK;
tobyspark 26:0299f8760715 451 char sentMSGBuffer[kStringBufferLength];
tobyspark 24:49c6624119ae 452
tobyspark 24:49c6624119ae 453 // Set Keyer
tobyspark 39:7d9a5eef93c9 454 if (mixMode < mixKey)
tobyspark 24:49c6624119ae 455 {
tobyspark 31:01845a2347ff 456 // Set Keyer Off. Quicker to set and fail than to test for on and then turn off
tobyspark 35:d5d9f0838f99 457 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false);
tobyspark 31:01845a2347ff 458
tobyspark 31:01845a2347ff 459 if (mixMode == mixBlend)
tobyspark 24:49c6624119ae 460 {
tobyspark 31:01845a2347ff 461 // Turn off Additive Mixing on output
tobyspark 31:01845a2347ff 462 ok = tvOne.command(0, kTV1WindowIDA, 0x298, 0);
tobyspark 31:01845a2347ff 463 snprintf(sentMSGBuffer, kStringBufferLength, "Blend");
tobyspark 24:49c6624119ae 464 }
tobyspark 31:01845a2347ff 465 if (mixMode == mixAdditive)
tobyspark 31:01845a2347ff 466 {
tobyspark 31:01845a2347ff 467 // 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 468 ok = tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 31:01845a2347ff 469 // Then turn on Additive Mixing
tobyspark 31:01845a2347ff 470 ok = ok && tvOne.command(0, kTV1WindowIDA, 0x298, 1);
tobyspark 31:01845a2347ff 471 snprintf(sentMSGBuffer, kStringBufferLength, "Additive");
tobyspark 31:01845a2347ff 472 }
tobyspark 24:49c6624119ae 473 }
tobyspark 24:49c6624119ae 474 else
tobyspark 24:49c6624119ae 475 {
tobyspark 39:7d9a5eef93c9 476 int index = mixModeMenu.selectedIndex() - mixKeyStartIndex;
tobyspark 49:16309f39cead 477
tobyspark 49:16309f39cead 478 // Turn off Additive Mixing on output
tobyspark 49:16309f39cead 479 ok = tvOne.command(0, kTV1WindowIDA, 0x298, 0);
tobyspark 49:16309f39cead 480 // Turn on Keyer
tobyspark 49:16309f39cead 481 ok = ok && setKeyParamsTo(index);
tobyspark 24:49c6624119ae 482 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true);
tobyspark 49:16309f39cead 483
tobyspark 26:0299f8760715 484 snprintf(sentMSGBuffer, kStringBufferLength, "Keyer On with %i", index);
tobyspark 24:49c6624119ae 485 }
tobyspark 49:16309f39cead 486
tobyspark 49:16309f39cead 487 mixModeOld = mixMode;
tobyspark 24:49c6624119ae 488
tobyspark 24:49c6624119ae 489 if (ok) sentOK = "Sent:";
tobyspark 24:49c6624119ae 490 else sentOK = "Send Error:";
tobyspark 24:49c6624119ae 491
tobyspark 48:c0fedfa8c525 492 tvOneStatusMessage.addMessage(sentOK + sentMSGBuffer, kTVOneStatusMessageHoldTime);
tobyspark 24:49c6624119ae 493 }
tobyspark 24:49c6624119ae 494
tobyspark 49:16309f39cead 495 bool checkTVOneMixStatus()
tobyspark 49:16309f39cead 496 {
tobyspark 49:16309f39cead 497 bool ok = true;
tobyspark 49:16309f39cead 498
tobyspark 49:16309f39cead 499 int32_t payload;
tobyspark 49:16309f39cead 500
tobyspark 49:16309f39cead 501 // Mix Mode
tobyspark 49:16309f39cead 502 bool mixModeNeedsAction = false;
tobyspark 49:16309f39cead 503 bool additiveOn = false, keyerOn = false;
tobyspark 49:16309f39cead 504
tobyspark 49:16309f39cead 505 if (mixMode == mixBlend) { additiveOn = false; keyerOn = false;}
tobyspark 49:16309f39cead 506 if (mixMode == mixAdditive) { additiveOn = true; keyerOn = false;}
tobyspark 49:16309f39cead 507 if (mixMode >= mixKey) { additiveOn = false; keyerOn = true; }
tobyspark 49:16309f39cead 508
tobyspark 49:16309f39cead 509 payload = -1;
tobyspark 49:16309f39cead 510 ok = ok && tvOne.readCommand(0, kTV1WindowIDA, 0x298, payload);
tobyspark 49:16309f39cead 511 if (payload != additiveOn) mixModeNeedsAction = true;
tobyspark 49:16309f39cead 512
tobyspark 49:16309f39cead 513 payload = -1;
tobyspark 49:16309f39cead 514 ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, payload);
tobyspark 49:16309f39cead 515 if (payload != keyerOn) mixModeNeedsAction = true;
tobyspark 49:16309f39cead 516
tobyspark 49:16309f39cead 517 if (ok && mixModeNeedsAction)
tobyspark 49:16309f39cead 518 {
tobyspark 49:16309f39cead 519 if (debug) debug->printf("Check TVOne Mix Status requiring mixMode action. mixMode: %i \r\n", mixMode);
tobyspark 49:16309f39cead 520 actionMixMode();
tobyspark 49:16309f39cead 521 }
tobyspark 49:16309f39cead 522
tobyspark 49:16309f39cead 523 // Check Fade
tobyspark 49:16309f39cead 524 payload = -1;
tobyspark 49:16309f39cead 525 ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, payload);
tobyspark 49:16309f39cead 526 if (ok && (payload != fadeAPercent))
tobyspark 49:16309f39cead 527 {
tobyspark 49:16309f39cead 528 if (debug) debug->printf("Check TVOne Mix Status requiring fadeA action");
tobyspark 49:16309f39cead 529 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 49:16309f39cead 530 }
tobyspark 49:16309f39cead 531
tobyspark 49:16309f39cead 532 payload = -1;
tobyspark 49:16309f39cead 533 ok = ok && tvOne.readCommand(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, payload);
tobyspark 49:16309f39cead 534 if (ok && (payload != fadeBPercent))
tobyspark 49:16309f39cead 535 {
tobyspark 49:16309f39cead 536 if (debug) debug->printf("Check TVOne Mix Status requiring fadeB action");
tobyspark 49:16309f39cead 537 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 49:16309f39cead 538 }
tobyspark 49:16309f39cead 539
tobyspark 49:16309f39cead 540 return ok;
tobyspark 49:16309f39cead 541 }
tobyspark 24:49c6624119ae 542
tobyspark 17:fc68d40b8b1f 543 bool conformProcessor()
tobyspark 17:fc68d40b8b1f 544 {
tobyspark 44:723e65413ebe 545 bool ok;
tobyspark 17:fc68d40b8b1f 546
tobyspark 17:fc68d40b8b1f 547 int32_t on = 1;
tobyspark 17:fc68d40b8b1f 548 int32_t off = 0;
tobyspark 17:fc68d40b8b1f 549 int32_t fit = 1;
tobyspark 38:2701101dcd56 550 int32_t oneToOne = 4;
tobyspark 17:fc68d40b8b1f 551
tobyspark 44:723e65413ebe 552 for (int i=0; i < 3; i++)
tobyspark 44:723e65413ebe 553 {
tobyspark 44:723e65413ebe 554 // Independent output
tobyspark 44:723e65413ebe 555 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionMode, 2);
tobyspark 44:723e65413ebe 556 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputEnable, on);
tobyspark 44:723e65413ebe 557 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsLockMethod, off);
tobyspark 44:723e65413ebe 558
tobyspark 44:723e65413ebe 559 // Make sure our windows exist
tobyspark 44:723e65413ebe 560 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 44:723e65413ebe 561 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsEnable, on);
tobyspark 44:723e65413ebe 562 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsLayerPriority, 0);
tobyspark 44:723e65413ebe 563 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsLayerPriority, 1);
tobyspark 44:723e65413ebe 564
tobyspark 44:723e65413ebe 565 // Assign inputs to windows, so that left on the crossfader is left on the processor viewed from front
tobyspark 44:723e65413ebe 566 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2);
tobyspark 44:723e65413ebe 567 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1);
tobyspark 44:723e65413ebe 568
tobyspark 44:723e65413ebe 569 // Set scaling to fit source within output, maintaining aspect ratio
tobyspark 44:723e65413ebe 570 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 44:723e65413ebe 571 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsZoomLevel, 100);
tobyspark 44:723e65413ebe 572 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 44:723e65413ebe 573 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsShrinkEnable, off);
tobyspark 44:723e65413ebe 574 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 44:723e65413ebe 575 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, fit);
tobyspark 44:723e65413ebe 576 ok = ok && tvOne.command(kTV1SourceSIS2, kTV1WindowIDA, kTV1FunctionAdjustSourceTestCard, 1);
tobyspark 44:723e65413ebe 577 ok = ok && tvOne.command(kTV1SourceSIS2, kTV1WindowIDA, kTV1FunctionAdjustSourceAspectCorrect, oneToOne);
tobyspark 44:723e65413ebe 578
tobyspark 44:723e65413ebe 579 // On source loss, hold on the last frame received.
tobyspark 44:723e65413ebe 580 int32_t freeze = 1;
tobyspark 44:723e65413ebe 581 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 44:723e65413ebe 582 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceOnSourceLoss, freeze);
tobyspark 44:723e65413ebe 583
tobyspark 44:723e65413ebe 584 // Set resolution and fade levels for maximum chance of being seen
tobyspark 44:723e65413ebe 585 ok = ok && tvOne.setResolution(kTV1ResolutionVGA, tvOneEDIDPassthrough ? EDIDPassthroughSlot : 5);
tobyspark 48:c0fedfa8c525 586 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, 50);
tobyspark 44:723e65413ebe 587 ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, 100);
tobyspark 44:723e65413ebe 588
tobyspark 44:723e65413ebe 589 // Set evil, evil HDCP off
tobyspark 44:723e65413ebe 590 ok = ok && tvOne.setHDCPOn(false);
tobyspark 30:873979018850 591
tobyspark 44:723e65413ebe 592 if (ok) break;
tobyspark 44:723e65413ebe 593 else tvOne.increaseCommandPeriods(500);
tobyspark 44:723e65413ebe 594 }
tobyspark 40:bfddeb2a7fcf 595
tobyspark 44:723e65413ebe 596 if (ok)
tobyspark 44:723e65413ebe 597 {
tobyspark 44:723e65413ebe 598 // Save current state in preset one
tobyspark 44:723e65413ebe 599 tvOne.command(0, kTV1WindowIDA, kTV1FunctionPreset, 1); // Set Preset 1
tobyspark 44:723e65413ebe 600 tvOne.command(0, kTV1WindowIDA, kTV1FunctionPresetStore, 1); // Store
tobyspark 44:723e65413ebe 601
tobyspark 44:723e65413ebe 602 // Save current state for power on
tobyspark 44:723e65413ebe 603 tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 44:723e65413ebe 604 }
tobyspark 41:00d1cd3b2af2 605
tobyspark 44:723e65413ebe 606 tvOne.resetCommandPeriods();
tobyspark 41:00d1cd3b2af2 607
tobyspark 41:00d1cd3b2af2 608 return ok;
tobyspark 41:00d1cd3b2af2 609 }
tobyspark 41:00d1cd3b2af2 610
tobyspark 41:00d1cd3b2af2 611 bool uploadToProcessor()
tobyspark 41:00d1cd3b2af2 612 {
tobyspark 41:00d1cd3b2af2 613 bool ok = true;
tobyspark 41:00d1cd3b2af2 614
tobyspark 41:00d1cd3b2af2 615 LocalFileSystem local("local");
tobyspark 41:00d1cd3b2af2 616 FILE *file;
tobyspark 41:00d1cd3b2af2 617
tobyspark 34:69dfe64e7e6b 618 // Upload Matrox EDID to mem4 (ie. index 3). Use this EDID slot when setting Matrox resolutions.
tobyspark 44:723e65413ebe 619 if (tvOne.getProcessorType().version < 415)
tobyspark 44:723e65413ebe 620 {
tobyspark 44:723e65413ebe 621 if (debug) debug->printf("Skipping EDID upload as unsupported on detected TV One firmware\r\n");
tobyspark 44:723e65413ebe 622 }
tobyspark 44:723e65413ebe 623 else
tobyspark 34:69dfe64e7e6b 624 {
tobyspark 41:00d1cd3b2af2 625 file = fopen("/local/matroxe.did", "r"); // 8.3, avoid .bin as mbed executable extension
tobyspark 35:d5d9f0838f99 626 if (file)
tobyspark 34:69dfe64e7e6b 627 {
tobyspark 41:00d1cd3b2af2 628 ok = ok && tvOne.uploadEDID(file, 3);
tobyspark 35:d5d9f0838f99 629 fclose(file);
tobyspark 34:69dfe64e7e6b 630 }
tobyspark 35:d5d9f0838f99 631 else
tobyspark 35:d5d9f0838f99 632 {
tobyspark 44:723e65413ebe 633 if (debug) debug->printf("Could not open Matrox EDID file 'matroxe.did'\r\n");
tobyspark 35:d5d9f0838f99 634 }
tobyspark 34:69dfe64e7e6b 635 }
tobyspark 41:00d1cd3b2af2 636
tobyspark 41:00d1cd3b2af2 637 // Upload Logo to SIS2. Use this (minimal) image when no sources are connected.
tobyspark 41:00d1cd3b2af2 638 {
tobyspark 41:00d1cd3b2af2 639 file = fopen("/local/spark.dat", "r"); // 8.3, avoid .bin as mbed executable extension
tobyspark 41:00d1cd3b2af2 640 if (file)
tobyspark 41:00d1cd3b2af2 641 {
tobyspark 41:00d1cd3b2af2 642 ok = ok && tvOne.uploadImage(file, 1);
tobyspark 41:00d1cd3b2af2 643 fclose(file);
tobyspark 41:00d1cd3b2af2 644 }
tobyspark 41:00d1cd3b2af2 645 else
tobyspark 41:00d1cd3b2af2 646 {
tobyspark 41:00d1cd3b2af2 647 if (debug) debug->printf("Could not open image file 'spark.dat'");
tobyspark 41:00d1cd3b2af2 648 }
tobyspark 41:00d1cd3b2af2 649 }
tobyspark 17:fc68d40b8b1f 650
tobyspark 17:fc68d40b8b1f 651 return ok;
tobyspark 17:fc68d40b8b1f 652 }
tobyspark 17:fc68d40b8b1f 653
tobyspark 27:27851d3d2bba 654 void setResolutionMenuItems()
tobyspark 27:27851d3d2bba 655 {
tobyspark 27:27851d3d2bba 656 resolutionMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 657 for (int i=0; i < settings.resolutionsCount(); i++)
tobyspark 27:27851d3d2bba 658 {
tobyspark 27:27851d3d2bba 659 resolutionMenu.addMenuItem(SPKMenuItem(settings.resolutionName(i), settings.resolutionIndex(i), settings.resolutionEDIDIndex(i)));
tobyspark 27:27851d3d2bba 660 }
tobyspark 27:27851d3d2bba 661 resolutionMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 662 }
tobyspark 27:27851d3d2bba 663
tobyspark 27:27851d3d2bba 664 void setMixModeMenuItems()
tobyspark 27:27851d3d2bba 665 {
tobyspark 27:27851d3d2bba 666 mixModeMenu.clearMenuItems();
tobyspark 44:723e65413ebe 667
tobyspark 46:491229c97336 668 if (tvOne.getProcessorType().version == 423 || tvOne.getProcessorType().version == -1)
tobyspark 44:723e65413ebe 669 {
tobyspark 44:723e65413ebe 670 mixModeMenu.addMenuItem(SPKMenuItem("Crossfade", &mixModeAdditiveMenu));
tobyspark 44:723e65413ebe 671 }
tobyspark 44:723e65413ebe 672 else
tobyspark 44:723e65413ebe 673 {
tobyspark 44:723e65413ebe 674 mixModeMenu.addMenuItem(SPKMenuItem("Blend", mixBlend));
tobyspark 44:723e65413ebe 675 }
tobyspark 44:723e65413ebe 676
tobyspark 27:27851d3d2bba 677 for (int i=0; i < settings.keyerSetCount(); i++)
tobyspark 27:27851d3d2bba 678 {
tobyspark 49:16309f39cead 679 mixModeMenu.addMenuItem(SPKMenuItem(settings.keyerParamName(i), mixKeyStartIndex + i));
tobyspark 27:27851d3d2bba 680 }
tobyspark 27:27851d3d2bba 681 mixModeMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 27:27851d3d2bba 682 }
tobyspark 27:27851d3d2bba 683
tobyspark 27:27851d3d2bba 684 void setCommsMenuItems()
tobyspark 27:27851d3d2bba 685 {
tobyspark 27:27851d3d2bba 686 if (rj45Mode == rj45Ethernet)
tobyspark 27:27851d3d2bba 687 {
tobyspark 27:27851d3d2bba 688 commsMenu.title = "Network Mode [Ethernet]";
tobyspark 27:27851d3d2bba 689 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 690 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 691 commsMenu.addMenuItem(SPKMenuItem("OSC", commsOSC));
tobyspark 27:27851d3d2bba 692 commsMenu.addMenuItem(SPKMenuItem("ArtNet", commsArtNet));
tobyspark 27:27851d3d2bba 693 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 33:e6672a9bd571 694 commsMenu = 0;
tobyspark 27:27851d3d2bba 695 }
tobyspark 27:27851d3d2bba 696 else if (rj45Mode == rj45DMX)
tobyspark 27:27851d3d2bba 697 {
tobyspark 27:27851d3d2bba 698 commsMenu.title = "Network Mode [DMX]";
tobyspark 27:27851d3d2bba 699 commsMenu.clearMenuItems();
tobyspark 27:27851d3d2bba 700 commsMenu.addMenuItem(SPKMenuItem("None", commsNone));
tobyspark 27:27851d3d2bba 701 commsMenu.addMenuItem(SPKMenuItem("DMX In", commsDMXIn));
tobyspark 27:27851d3d2bba 702 commsMenu.addMenuItem(SPKMenuItem("DMX Out", commsDMXOut));
tobyspark 27:27851d3d2bba 703 commsMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 33:e6672a9bd571 704 commsMenu = 0;
tobyspark 27:27851d3d2bba 705 }
tobyspark 27:27851d3d2bba 706 }
tobyspark 27:27851d3d2bba 707
tobyspark 49:16309f39cead 708 void mixModeAdditiveMenuHandler(int change, bool action)
tobyspark 49:16309f39cead 709 {
tobyspark 49:16309f39cead 710 fadeCurve += change * 0.05f;
tobyspark 49:16309f39cead 711 if (fadeCurve > 1.0f) fadeCurve = 1.0f;
tobyspark 49:16309f39cead 712 if (fadeCurve < 0.0f) fadeCurve = 0.0f;
tobyspark 49:16309f39cead 713
tobyspark 49:16309f39cead 714 mixMode = (fadeCurve > 0.001f) ? mixAdditive: mixBlend;
tobyspark 49:16309f39cead 715
tobyspark 49:16309f39cead 716 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 717 screen.textToBuffer("Blend [ ----- ] Add", kMenuLine2);
tobyspark 49:16309f39cead 718 screen.characterToBuffer('X', 38 + fadeCurve*20.0f, kMenuLine2);
tobyspark 49:16309f39cead 719
tobyspark 49:16309f39cead 720 if (debug) debug->printf("Fade curve changed by %i to %f \r\n", change, fadeCurve);
tobyspark 49:16309f39cead 721
tobyspark 49:16309f39cead 722 if (action)
tobyspark 49:16309f39cead 723 {
tobyspark 49:16309f39cead 724 selectedMenu = &mixModeMenu;
tobyspark 49:16309f39cead 725
tobyspark 49:16309f39cead 726 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 727 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 728 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 729 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 49:16309f39cead 730 }
tobyspark 49:16309f39cead 731 }
tobyspark 49:16309f39cead 732
tobyspark 49:16309f39cead 733 void advancedMenuHDCPHandler(int change, bool action)
tobyspark 49:16309f39cead 734 {
tobyspark 49:16309f39cead 735 static int currentHDCP;
tobyspark 49:16309f39cead 736 static unsigned int state = 1;
tobyspark 49:16309f39cead 737
tobyspark 49:16309f39cead 738 if (change == 0 && !action)
tobyspark 49:16309f39cead 739 {
tobyspark 49:16309f39cead 740 // We check the control not the status, as status depends on connection etc.
tobyspark 49:16309f39cead 741
tobyspark 49:16309f39cead 742 int32_t payloadOutput = -1;
tobyspark 49:16309f39cead 743 tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsHDCPRequired, payloadOutput);
tobyspark 49:16309f39cead 744
tobyspark 49:16309f39cead 745 int32_t payload1 = -1;
tobyspark 49:16309f39cead 746 tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceHDCPAdvertize, payload1);
tobyspark 49:16309f39cead 747
tobyspark 49:16309f39cead 748 int32_t payload2 = -1;
tobyspark 49:16309f39cead 749 tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceHDCPAdvertize, payload2);
tobyspark 49:16309f39cead 750
tobyspark 49:16309f39cead 751 if ((payloadOutput == payload1) && (payload1 == payload2) && (payload2 == 0))
tobyspark 49:16309f39cead 752 {
tobyspark 49:16309f39cead 753 currentHDCP = 0; // Change to on
tobyspark 49:16309f39cead 754 }
tobyspark 49:16309f39cead 755 else if ((payloadOutput == payload1) && (payload1 == payload2) && (payload2 == 1))
tobyspark 49:16309f39cead 756 {
tobyspark 49:16309f39cead 757 currentHDCP = 1; // Change to off
tobyspark 49:16309f39cead 758 }
tobyspark 49:16309f39cead 759 else
tobyspark 49:16309f39cead 760 {
tobyspark 49:16309f39cead 761 currentHDCP = -1; // Change to off
tobyspark 49:16309f39cead 762 }
tobyspark 49:16309f39cead 763
tobyspark 49:16309f39cead 764 if (debug) debug->printf("HDCP detected O: %i 1: %i 2: %i", payloadOutput, payload1, payload2);
tobyspark 49:16309f39cead 765 }
tobyspark 49:16309f39cead 766
tobyspark 49:16309f39cead 767 state += change;
tobyspark 49:16309f39cead 768
tobyspark 49:16309f39cead 769 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 770 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 771
tobyspark 49:16309f39cead 772 const char* current = currentHDCP == -1 ? "Mixed" : ( currentHDCP == 1 ? "On" : "Off");
tobyspark 49:16309f39cead 773
tobyspark 49:16309f39cead 774 if (state % 2) snprintf(paramLine, kStringBufferLength, "%s. Set: [%s/ ]?", current, currentHDCP == 0 ? "On " : "Off" );
tobyspark 49:16309f39cead 775 else snprintf(paramLine, kStringBufferLength, "%s. Set: [ /Cancel]?", current);
tobyspark 49:16309f39cead 776 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 777
tobyspark 49:16309f39cead 778 if (action)
tobyspark 49:16309f39cead 779 {
tobyspark 49:16309f39cead 780 if (state % 2)
tobyspark 49:16309f39cead 781 {
tobyspark 49:16309f39cead 782 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 49:16309f39cead 783 screen.textToBuffer("Setting HDCP...", kTVOneStatusLine);
tobyspark 49:16309f39cead 784 screen.sendBuffer();
tobyspark 49:16309f39cead 785
tobyspark 49:16309f39cead 786 // Do the action
tobyspark 49:16309f39cead 787 bool ok = tvOne.setHDCPOn(currentHDCP == 0);
tobyspark 49:16309f39cead 788
tobyspark 49:16309f39cead 789 if (ok) tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 49:16309f39cead 790
tobyspark 49:16309f39cead 791 std::string sendOK = ok ? "Sent: HDCP " : "Send Error: HDCP ";
tobyspark 49:16309f39cead 792 sendOK += currentHDCP == 0 ? "On" : "Off";
tobyspark 49:16309f39cead 793
tobyspark 49:16309f39cead 794 tvOneStatusMessage.addMessage(sendOK, kTVOneStatusMessageHoldTime);
tobyspark 49:16309f39cead 795 }
tobyspark 49:16309f39cead 796
tobyspark 49:16309f39cead 797 // Get back to menu
tobyspark 49:16309f39cead 798 selectedMenu = &advancedMenu;
tobyspark 49:16309f39cead 799
tobyspark 49:16309f39cead 800 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 801 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 802 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 803 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 49:16309f39cead 804 }
tobyspark 49:16309f39cead 805 }
tobyspark 49:16309f39cead 806
tobyspark 49:16309f39cead 807 void advancedMenuEDIDHandler(int change, bool action)
tobyspark 49:16309f39cead 808 {
tobyspark 49:16309f39cead 809 static int currentEDIDPassthrough;
tobyspark 49:16309f39cead 810 static unsigned int state = 1;
tobyspark 49:16309f39cead 811
tobyspark 49:16309f39cead 812 if (change == 0 && !action)
tobyspark 49:16309f39cead 813 {
tobyspark 49:16309f39cead 814 int32_t payload1 = -1;
tobyspark 49:16309f39cead 815 tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, payload1);
tobyspark 49:16309f39cead 816
tobyspark 49:16309f39cead 817 int32_t payload2 = -1;
tobyspark 49:16309f39cead 818 tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, payload2);
tobyspark 49:16309f39cead 819
tobyspark 49:16309f39cead 820 if ((payload1 == payload2) && (payload2 == EDIDPassthroughSlot))
tobyspark 49:16309f39cead 821 {
tobyspark 49:16309f39cead 822 currentEDIDPassthrough = 1;
tobyspark 49:16309f39cead 823 }
tobyspark 49:16309f39cead 824 else if ((payload1 == payload2) && (payload2 != EDIDPassthroughSlot))
tobyspark 49:16309f39cead 825 {
tobyspark 49:16309f39cead 826 currentEDIDPassthrough = 0;
tobyspark 49:16309f39cead 827 }
tobyspark 49:16309f39cead 828 else
tobyspark 49:16309f39cead 829 {
tobyspark 49:16309f39cead 830 currentEDIDPassthrough = -1;
tobyspark 49:16309f39cead 831 }
tobyspark 49:16309f39cead 832 }
tobyspark 49:16309f39cead 833
tobyspark 49:16309f39cead 834 state += change;
tobyspark 49:16309f39cead 835
tobyspark 49:16309f39cead 836 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 837 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 838
tobyspark 49:16309f39cead 839 const char* current = currentEDIDPassthrough == -1 ? "Mixed" : ( currentEDIDPassthrough == 1 ? "Thru" : "Int");
tobyspark 49:16309f39cead 840
tobyspark 49:16309f39cead 841 if (state % 2) snprintf(paramLine, kStringBufferLength, "%s. Set: [%s/ ]?", current, currentEDIDPassthrough == 0 ? "Thru" : "Int");
tobyspark 49:16309f39cead 842 else snprintf(paramLine, kStringBufferLength, "%s. Set: [ /Cancel]?", current);
tobyspark 49:16309f39cead 843 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 844
tobyspark 49:16309f39cead 845 if (action)
tobyspark 49:16309f39cead 846 {
tobyspark 49:16309f39cead 847 if (state % 2)
tobyspark 49:16309f39cead 848 {
tobyspark 49:16309f39cead 849 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 49:16309f39cead 850 screen.textToBuffer("Setting EDID...", kTVOneStatusLine);
tobyspark 49:16309f39cead 851 screen.sendBuffer();
tobyspark 49:16309f39cead 852
tobyspark 49:16309f39cead 853 // Do the action
tobyspark 49:16309f39cead 854 tvOneEDIDPassthrough = currentEDIDPassthrough == 0;
tobyspark 49:16309f39cead 855
tobyspark 49:16309f39cead 856 bool ok = true;
tobyspark 49:16309f39cead 857
tobyspark 49:16309f39cead 858 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : resolutionMenu.selectedItem().payload.command[1];
tobyspark 49:16309f39cead 859
tobyspark 49:16309f39cead 860 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 49:16309f39cead 861 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, slot);
tobyspark 49:16309f39cead 862
tobyspark 49:16309f39cead 863 if (ok) tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 49:16309f39cead 864
tobyspark 49:16309f39cead 865 std::string sendOK = ok ? "Sent: EDID " : "Send Error: EDID ";
tobyspark 49:16309f39cead 866 sendOK += tvOneEDIDPassthrough ? "Passthrough" : "Internal";
tobyspark 49:16309f39cead 867
tobyspark 49:16309f39cead 868 tvOneStatusMessage.addMessage(sendOK, kTVOneStatusMessageHoldTime);
tobyspark 49:16309f39cead 869 }
tobyspark 49:16309f39cead 870
tobyspark 49:16309f39cead 871 // Get back to menu
tobyspark 49:16309f39cead 872 selectedMenu = &advancedMenu;
tobyspark 49:16309f39cead 873
tobyspark 49:16309f39cead 874 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 875 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 876 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 877 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 49:16309f39cead 878 }
tobyspark 49:16309f39cead 879 }
tobyspark 49:16309f39cead 880
tobyspark 49:16309f39cead 881 void mixModeUpdateKeyMenuHandler(int menuChange, bool action)
tobyspark 49:16309f39cead 882 {
tobyspark 49:16309f39cead 883 static int actionCount = 0;
tobyspark 49:16309f39cead 884 static unsigned int state = 0;
tobyspark 49:16309f39cead 885
tobyspark 49:16309f39cead 886 if (action) actionCount++;
tobyspark 49:16309f39cead 887
tobyspark 49:16309f39cead 888 if (actionCount == 0)
tobyspark 49:16309f39cead 889 {
tobyspark 49:16309f39cead 890 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 891 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 892 screen.textToBuffer("Edit current key?", kMenuLine1);
tobyspark 49:16309f39cead 893
tobyspark 49:16309f39cead 894 state += menuChange;
tobyspark 49:16309f39cead 895 switch (state % 3)
tobyspark 49:16309f39cead 896 {
tobyspark 49:16309f39cead 897 case 0: screen.textToBuffer("[Tweak/ / ]", kMenuLine2); break;
tobyspark 49:16309f39cead 898 case 1: screen.textToBuffer("[ /Start Over/ ]", kMenuLine2); break;
tobyspark 49:16309f39cead 899 case 2: screen.textToBuffer("[ / /Cancel]", kMenuLine2); break;
tobyspark 49:16309f39cead 900 }
tobyspark 49:16309f39cead 901 }
tobyspark 49:16309f39cead 902 if (actionCount == 1)
tobyspark 49:16309f39cead 903 {
tobyspark 49:16309f39cead 904 state = state % 3;
tobyspark 49:16309f39cead 905
tobyspark 49:16309f39cead 906 if (state == 0)
tobyspark 49:16309f39cead 907 {
tobyspark 49:16309f39cead 908 settings.editingKeyerSetIndex = mixModeMenu.selectedIndex() - mixKeyStartIndex;
tobyspark 49:16309f39cead 909 actionCount++;
tobyspark 49:16309f39cead 910 }
tobyspark 49:16309f39cead 911 else if (state == 1)
tobyspark 49:16309f39cead 912 {
tobyspark 49:16309f39cead 913 settings.editingKeyerSetIndex = mixModeMenu.selectedIndex() - mixKeyStartIndex;
tobyspark 49:16309f39cead 914 settings.setEditingKeyerSetValue(SPKSettings::minY, 0);
tobyspark 49:16309f39cead 915 settings.setEditingKeyerSetValue(SPKSettings::maxY, 255);
tobyspark 49:16309f39cead 916 settings.setEditingKeyerSetValue(SPKSettings::minU, 0);
tobyspark 49:16309f39cead 917 settings.setEditingKeyerSetValue(SPKSettings::maxU, 255);
tobyspark 49:16309f39cead 918 settings.setEditingKeyerSetValue(SPKSettings::minV, 0);
tobyspark 49:16309f39cead 919 settings.setEditingKeyerSetValue(SPKSettings::maxV, 255);
tobyspark 49:16309f39cead 920 actionCount++;
tobyspark 49:16309f39cead 921 state = 0;
tobyspark 49:16309f39cead 922 }
tobyspark 49:16309f39cead 923 else if (state == 2)
tobyspark 49:16309f39cead 924 {
tobyspark 49:16309f39cead 925 settings.editingKeyerSetIndex = -1;
tobyspark 49:16309f39cead 926
tobyspark 49:16309f39cead 927 // Get back to menu
tobyspark 49:16309f39cead 928 actionCount = 0;
tobyspark 49:16309f39cead 929 state = 0;
tobyspark 49:16309f39cead 930 selectedMenu = &mixModeMenu;
tobyspark 49:16309f39cead 931 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 932 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 933 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 934 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 49:16309f39cead 935
tobyspark 49:16309f39cead 936 return;
tobyspark 49:16309f39cead 937 }
tobyspark 49:16309f39cead 938 }
tobyspark 49:16309f39cead 939 if (actionCount == 2)
tobyspark 49:16309f39cead 940 {
tobyspark 49:16309f39cead 941 int value = settings.editingKeyerSetValue(SPKSettings::maxY);
tobyspark 49:16309f39cead 942 value += menuChange;
tobyspark 49:16309f39cead 943 if (value < 0) value = 0;
tobyspark 49:16309f39cead 944 if (value > 255) value = 255;
tobyspark 49:16309f39cead 945 settings.setEditingKeyerSetValue(SPKSettings::maxY, value);
tobyspark 49:16309f39cead 946
tobyspark 49:16309f39cead 947 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 948 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 949 screen.textToBuffer("Down until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 950
tobyspark 49:16309f39cead 951 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 952 snprintf(paramLine, kStringBufferLength, "[ /%3i][ / ][ / ]", value);
tobyspark 49:16309f39cead 953 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 954
tobyspark 49:16309f39cead 955 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, value);
tobyspark 49:16309f39cead 956 }
tobyspark 49:16309f39cead 957 else if (actionCount == 3)
tobyspark 49:16309f39cead 958 {
tobyspark 49:16309f39cead 959 int value = settings.editingKeyerSetValue(SPKSettings::minY);
tobyspark 49:16309f39cead 960 value += menuChange;
tobyspark 49:16309f39cead 961 if (value < 0) value = 0;
tobyspark 49:16309f39cead 962 if (value > settings.editingKeyerSetValue(SPKSettings::maxY)) value = settings.editingKeyerSetValue(SPKSettings::maxY);
tobyspark 49:16309f39cead 963 settings.setEditingKeyerSetValue(SPKSettings::minY, value);
tobyspark 49:16309f39cead 964
tobyspark 49:16309f39cead 965 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 966 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 967 screen.textToBuffer("Up until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 968
tobyspark 49:16309f39cead 969 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 970 snprintf(paramLine, kStringBufferLength, "[%3i/%3i][ / ][ / ]", value,
tobyspark 49:16309f39cead 971 settings.editingKeyerSetValue(SPKSettings::maxY));
tobyspark 49:16309f39cead 972 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 973
tobyspark 49:16309f39cead 974 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, value);
tobyspark 49:16309f39cead 975 }
tobyspark 49:16309f39cead 976 else if (actionCount == 4)
tobyspark 49:16309f39cead 977 {
tobyspark 49:16309f39cead 978 int value = settings.editingKeyerSetValue(SPKSettings::maxU);
tobyspark 49:16309f39cead 979 value += menuChange;
tobyspark 49:16309f39cead 980 if (value < 0) value = 0;
tobyspark 49:16309f39cead 981 if (value > 255) value = 255;
tobyspark 49:16309f39cead 982 settings.setEditingKeyerSetValue(SPKSettings::maxU, value);
tobyspark 49:16309f39cead 983
tobyspark 49:16309f39cead 984 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 985 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 986 screen.textToBuffer("Down until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 987
tobyspark 49:16309f39cead 988 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 989 snprintf(paramLine, kStringBufferLength, "[%3i/%3i][ /%3i][ / ]", settings.editingKeyerSetValue(SPKSettings::minY),
tobyspark 49:16309f39cead 990 settings.editingKeyerSetValue(SPKSettings::maxY),
tobyspark 49:16309f39cead 991 value);
tobyspark 49:16309f39cead 992 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 993
tobyspark 49:16309f39cead 994 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, value);
tobyspark 49:16309f39cead 995 }
tobyspark 49:16309f39cead 996 else if (actionCount == 5)
tobyspark 49:16309f39cead 997 {
tobyspark 49:16309f39cead 998 int value = settings.editingKeyerSetValue(SPKSettings::minU);
tobyspark 49:16309f39cead 999 value += menuChange;
tobyspark 49:16309f39cead 1000 if (value < 0) value = 0;
tobyspark 49:16309f39cead 1001 if (value > settings.editingKeyerSetValue(SPKSettings::maxU)) value = settings.editingKeyerSetValue(SPKSettings::maxU);
tobyspark 49:16309f39cead 1002 settings.setEditingKeyerSetValue(SPKSettings::minU, value);
tobyspark 49:16309f39cead 1003
tobyspark 49:16309f39cead 1004 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 1005 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 1006 screen.textToBuffer("Up until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 1007
tobyspark 49:16309f39cead 1008 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 1009 snprintf(paramLine, kStringBufferLength, "[%3i/%3i][%3i/%3i][ / ]", settings.editingKeyerSetValue(SPKSettings::minY),
tobyspark 49:16309f39cead 1010 settings.editingKeyerSetValue(SPKSettings::maxY),
tobyspark 49:16309f39cead 1011 value,
tobyspark 49:16309f39cead 1012 settings.editingKeyerSetValue(SPKSettings::maxU));
tobyspark 49:16309f39cead 1013 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 1014
tobyspark 49:16309f39cead 1015 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, value);
tobyspark 49:16309f39cead 1016 }
tobyspark 49:16309f39cead 1017 else if (actionCount == 6)
tobyspark 49:16309f39cead 1018 {
tobyspark 49:16309f39cead 1019 int value = settings.editingKeyerSetValue(SPKSettings::maxV);
tobyspark 49:16309f39cead 1020 value += menuChange;
tobyspark 49:16309f39cead 1021 if (value < 0) value = 0;
tobyspark 49:16309f39cead 1022 if (value > 255) value = 255;
tobyspark 49:16309f39cead 1023 settings.setEditingKeyerSetValue(SPKSettings::maxV, value);
tobyspark 49:16309f39cead 1024
tobyspark 49:16309f39cead 1025 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 1026 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 1027 screen.textToBuffer("Down until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 1028
tobyspark 49:16309f39cead 1029 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 1030 snprintf(paramLine, kStringBufferLength, "[%3i/%3i][%3i/%3i][ /%3i]", settings.editingKeyerSetValue(SPKSettings::minY),
tobyspark 49:16309f39cead 1031 settings.editingKeyerSetValue(SPKSettings::maxY),
tobyspark 49:16309f39cead 1032 settings.editingKeyerSetValue(SPKSettings::minU),
tobyspark 49:16309f39cead 1033 settings.editingKeyerSetValue(SPKSettings::maxU),
tobyspark 49:16309f39cead 1034 value);
tobyspark 49:16309f39cead 1035 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 1036
tobyspark 49:16309f39cead 1037 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, value);
tobyspark 49:16309f39cead 1038 }
tobyspark 49:16309f39cead 1039 else if (actionCount == 7)
tobyspark 49:16309f39cead 1040 {
tobyspark 49:16309f39cead 1041 int value = settings.editingKeyerSetValue(SPKSettings::minV);
tobyspark 49:16309f39cead 1042 value += menuChange;
tobyspark 49:16309f39cead 1043 if (value < 0) value = 0;
tobyspark 49:16309f39cead 1044 if (value > settings.editingKeyerSetValue(SPKSettings::maxV)) value = settings.editingKeyerSetValue(SPKSettings::maxV);
tobyspark 49:16309f39cead 1045 settings.setEditingKeyerSetValue(SPKSettings::minV, value);
tobyspark 49:16309f39cead 1046
tobyspark 49:16309f39cead 1047 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 1048 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 1049 screen.textToBuffer("Up until unmasked", kMenuLine1);
tobyspark 49:16309f39cead 1050
tobyspark 49:16309f39cead 1051 char paramLine[kStringBufferLength];
tobyspark 49:16309f39cead 1052 snprintf(paramLine, kStringBufferLength, "[%3i/%3i][%3i/%3i][%3i/%3i]", settings.editingKeyerSetValue(SPKSettings::minY),
tobyspark 49:16309f39cead 1053 settings.editingKeyerSetValue(SPKSettings::maxY),
tobyspark 49:16309f39cead 1054 settings.editingKeyerSetValue(SPKSettings::minU),
tobyspark 49:16309f39cead 1055 settings.editingKeyerSetValue(SPKSettings::maxU),
tobyspark 49:16309f39cead 1056 value,
tobyspark 49:16309f39cead 1057 settings.editingKeyerSetValue(SPKSettings::maxV));
tobyspark 49:16309f39cead 1058 screen.textToBuffer(paramLine, kMenuLine2);
tobyspark 49:16309f39cead 1059
tobyspark 49:16309f39cead 1060 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, value);
tobyspark 49:16309f39cead 1061 }
tobyspark 49:16309f39cead 1062 else if (actionCount == 8)
tobyspark 49:16309f39cead 1063 {
tobyspark 49:16309f39cead 1064 // A save dialog would go here
tobyspark 49:16309f39cead 1065
tobyspark 49:16309f39cead 1066 // Get back to menu
tobyspark 49:16309f39cead 1067 actionCount = 0;
tobyspark 49:16309f39cead 1068 selectedMenu = &mixModeMenu;
tobyspark 49:16309f39cead 1069 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 1070 screen.clearBufferRow(kMenuLine2);
tobyspark 49:16309f39cead 1071 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 1072 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 49:16309f39cead 1073 }
tobyspark 49:16309f39cead 1074 }
tobyspark 49:16309f39cead 1075
tobyspark 0:87aab40d5806 1076 int main()
tobyspark 0:87aab40d5806 1077 {
tobyspark 0:87aab40d5806 1078 if (debug)
tobyspark 0:87aab40d5806 1079 {
tobyspark 0:87aab40d5806 1080 debug->printf("\r\n\r\n");
tobyspark 0:87aab40d5806 1081 debug->printf("*spark d-fuser -----------\r\n");
tobyspark 0:87aab40d5806 1082 debug->printf(" debug channel\r\n");
tobyspark 0:87aab40d5806 1083 }
tobyspark 2:50043054e4f7 1084
tobyspark 2:50043054e4f7 1085 // Set display font
tobyspark 2:50043054e4f7 1086 screen.fontStartCharacter = &characterBytesStartChar;
tobyspark 2:50043054e4f7 1087 screen.fontEndCharacter = &characterBytesEndChar;
tobyspark 2:50043054e4f7 1088 screen.fontCharacters = characterBytes;
tobyspark 2:50043054e4f7 1089
tobyspark 0:87aab40d5806 1090 // Splash screen
tobyspark 30:873979018850 1091 string softwareLine = "SW ";
tobyspark 30:873979018850 1092 softwareLine += kSPKDFSoftwareVersion;
tobyspark 2:50043054e4f7 1093 screen.imageToBuffer(spkDisplayLogo);
tobyspark 0:87aab40d5806 1094 screen.textToBuffer("SPK:D-Fuser",0);
tobyspark 30:873979018850 1095 screen.textToBuffer(softwareLine,1);
tobyspark 5:f8b285ca41ba 1096 screen.sendBuffer();
tobyspark 0:87aab40d5806 1097
tobyspark 11:0783cfbeb746 1098 // Load saved settings
tobyspark 16:52484666b323 1099 bool settingsAreCustom = false;
tobyspark 16:52484666b323 1100 settingsAreCustom = settings.load(kSPKDFSettingsFilename);
tobyspark 30:873979018850 1101 if (settingsAreCustom)
tobyspark 30:873979018850 1102 {
tobyspark 30:873979018850 1103 softwareLine += "; ini OK";
tobyspark 30:873979018850 1104 screen.textToBuffer(softwareLine, 1);
tobyspark 30:873979018850 1105 }
tobyspark 30:873979018850 1106
tobyspark 0:87aab40d5806 1107 // Set menu structure
tobyspark 0:87aab40d5806 1108 mixModeMenu.title = "Mix Mode";
tobyspark 27:27851d3d2bba 1109 setMixModeMenuItems();
tobyspark 24:49c6624119ae 1110
tobyspark 29:95a7efe30527 1111 mixModeAdditiveMenu.title = "Crossfade";
tobyspark 49:16309f39cead 1112 mixModeAdditiveMenu.addMenuItem(SPKMenuItem(&mixModeAdditiveMenuHandler));
tobyspark 36:8b5c75c8bc23 1113
tobyspark 49:16309f39cead 1114 mixModeUpdateKeyMenu.title = "Update Keyer Settings?";
tobyspark 49:16309f39cead 1115 mixModeUpdateKeyMenu.addMenuItem(SPKMenuItem(mixModeUpdateKeyMenuHandler));
tobyspark 36:8b5c75c8bc23 1116
tobyspark 0:87aab40d5806 1117 resolutionMenu.title = "Resolution";
tobyspark 27:27851d3d2bba 1118 setResolutionMenuItems();
tobyspark 0:87aab40d5806 1119
tobyspark 27:27851d3d2bba 1120 commsMenu.title = "Network Mode";
tobyspark 27:27851d3d2bba 1121 setCommsMenuItems();
tobyspark 23:909928cafb95 1122
tobyspark 15:4b394c64b461 1123 advancedMenu.title = "Troubleshooting";
tobyspark 49:16309f39cead 1124 advancedMenuHDCP.title = "HDCP - Can Block DVI";
tobyspark 49:16309f39cead 1125 advancedMenuHDCP.addMenuItem(SPKMenuItem(&advancedMenuHDCPHandler));
tobyspark 49:16309f39cead 1126 advancedMenu.addMenuItem(SPKMenuItem(advancedMenuHDCP.title, &advancedMenuHDCP));
tobyspark 49:16309f39cead 1127 advancedMenuEDID.title = "EDID - Advertises Res's";
tobyspark 49:16309f39cead 1128 advancedMenuEDID.addMenuItem(SPKMenuItem(advancedMenuEDIDHandler));
tobyspark 49:16309f39cead 1129 advancedMenu.addMenuItem(SPKMenuItem(advancedMenuEDID.title, &advancedMenuEDID));
tobyspark 45:cf8c2400be5c 1130 //advancedMenu.addMenuItem(SPKMenuItem("Test Processor Sources", advancedTestSources));
tobyspark 45:cf8c2400be5c 1131 //if (settingsAreCustom) advancedMenu.addMenuItem(SPKMenuItem("Revert Controller", advancedLoadDefaults));
tobyspark 41:00d1cd3b2af2 1132 advancedMenu.addMenuItem(SPKMenuItem("Revert Processor", advancedConformProcessor));
tobyspark 41:00d1cd3b2af2 1133 advancedMenu.addMenuItem(SPKMenuItem("Conform Processor", advancedConformUploadProcessor));
tobyspark 24:49c6624119ae 1134 advancedMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu));
tobyspark 23:909928cafb95 1135
tobyspark 0:87aab40d5806 1136 mainMenu.title = "Main Menu";
tobyspark 24:49c6624119ae 1137 mainMenu.addMenuItem(SPKMenuItem(mixModeMenu.title, &mixModeMenu));
tobyspark 24:49c6624119ae 1138 mainMenu.addMenuItem(SPKMenuItem(resolutionMenu.title, &resolutionMenu));
tobyspark 24:49c6624119ae 1139 mainMenu.addMenuItem(SPKMenuItem(commsMenu.title, &commsMenu));
tobyspark 24:49c6624119ae 1140 mainMenu.addMenuItem(SPKMenuItem(advancedMenu.title, &advancedMenu));
tobyspark 23:909928cafb95 1141
tobyspark 0:87aab40d5806 1142 selectedMenu = &mainMenu;
tobyspark 23:909928cafb95 1143
tobyspark 0:87aab40d5806 1144 // Misc I/O stuff
tobyspark 0:87aab40d5806 1145
tobyspark 0:87aab40d5806 1146 fadeAPO.period(0.001);
tobyspark 0:87aab40d5806 1147 fadeBPO.period(0.001);
tobyspark 48:c0fedfa8c525 1148
tobyspark 48:c0fedfa8c525 1149 // If we do not have two solid sources, act on this as we rely on the window having a source for crossfade behaviour
tobyspark 48:c0fedfa8c525 1150 // 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 49:16309f39cead 1151 handleTVOneSources();
tobyspark 49:16309f39cead 1152
tobyspark 49:16309f39cead 1153 // Processor can have been power-on saved with a keyer on, lets revert
tobyspark 49:16309f39cead 1154 actionMixMode();
tobyspark 0:87aab40d5806 1155
tobyspark 12:c270870bdd23 1156 // Display menu and framing lines
tobyspark 0:87aab40d5806 1157 screen.horizLineToBuffer(kMenuLine1*pixInPage - 1);
tobyspark 0:87aab40d5806 1158 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 1159 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 1160 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 1161 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 1162 screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage);
tobyspark 1:f9fca21102e0 1163 screen.horizLineToBuffer(kCommsStatusLine*pixInPage - 1);
tobyspark 1:f9fca21102e0 1164 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 48:c0fedfa8c525 1165 screen.textToBuffer(tvOneStatusMessage.message(), kTVOneStatusLine);
tobyspark 33:e6672a9bd571 1166 screen.sendBuffer();
tobyspark 33:e6672a9bd571 1167
tobyspark 0:87aab40d5806 1168 //// CONTROLS TEST
tobyspark 0:87aab40d5806 1169
tobyspark 0:87aab40d5806 1170 while (0) {
tobyspark 0:87aab40d5806 1171 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 1172 }
tobyspark 0:87aab40d5806 1173
tobyspark 0:87aab40d5806 1174 //// MIXER RUN
tobyspark 0:87aab40d5806 1175
tobyspark 8:d46cc49f0f37 1176 while (1)
tobyspark 49:16309f39cead 1177 {
tobyspark 1:f9fca21102e0 1178 //// Task background things
tobyspark 33:e6672a9bd571 1179 if ((osc || artNet) && rj45Mode == rj45Ethernet)
tobyspark 5:f8b285ca41ba 1180 {
tobyspark 5:f8b285ca41ba 1181 Net::poll();
tobyspark 5:f8b285ca41ba 1182 }
tobyspark 5:f8b285ca41ba 1183
tobyspark 5:f8b285ca41ba 1184 //// RJ45 SWITCH
tobyspark 5:f8b285ca41ba 1185
tobyspark 5:f8b285ca41ba 1186 if (rj45ModeDIN != rj45Mode)
tobyspark 1:f9fca21102e0 1187 {
tobyspark 23:909928cafb95 1188 if (debug) debug->printf("Handling RJ45 mode change\r\n");
tobyspark 27:27851d3d2bba 1189
tobyspark 5:f8b285ca41ba 1190 // update state
tobyspark 5:f8b285ca41ba 1191 rj45Mode = rj45ModeDIN;
tobyspark 27:27851d3d2bba 1192
tobyspark 27:27851d3d2bba 1193 setCommsMenuItems();
tobyspark 5:f8b285ca41ba 1194
tobyspark 5:f8b285ca41ba 1195 // cancel old comms
tobyspark 5:f8b285ca41ba 1196 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 1197 commsMenu = commsMode;
tobyspark 5:f8b285ca41ba 1198
tobyspark 5:f8b285ca41ba 1199 // refresh display
tobyspark 23:909928cafb95 1200 if (selectedMenu == &commsMenu)
tobyspark 23:909928cafb95 1201 {
tobyspark 33:e6672a9bd571 1202 screen.clearBufferRow(kMenuLine1);
tobyspark 33:e6672a9bd571 1203 screen.clearBufferRow(kMenuLine2);
tobyspark 23:909928cafb95 1204 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 23:909928cafb95 1205 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 23:909928cafb95 1206 }
tobyspark 5:f8b285ca41ba 1207 if (rj45Mode == rj45Ethernet) screen.textToBuffer("RJ45: Ethernet Engaged", kCommsStatusLine);
tobyspark 5:f8b285ca41ba 1208 if (rj45Mode == rj45DMX) screen.textToBuffer("RJ45: DMX Engaged", kCommsStatusLine);
tobyspark 1:f9fca21102e0 1209 }
tobyspark 1:f9fca21102e0 1210
tobyspark 0:87aab40d5806 1211 //// MENU
tobyspark 0:87aab40d5806 1212
tobyspark 0:87aab40d5806 1213 int menuChange = menuEnc.getChange();
tobyspark 0:87aab40d5806 1214
tobyspark 0:87aab40d5806 1215 // Update GUI
tobyspark 0:87aab40d5806 1216 if (menuChange != 0)
tobyspark 0:87aab40d5806 1217 {
tobyspark 49:16309f39cead 1218 if (selectedMenu->selectedItem().type == SPKMenuItem::hasHandler)
tobyspark 24:49c6624119ae 1219 {
tobyspark 49:16309f39cead 1220 selectedMenu->selectedItem().payload.handler(menuChange, false);
tobyspark 24:49c6624119ae 1221 }
tobyspark 24:49c6624119ae 1222 else
tobyspark 24:49c6624119ae 1223 {
tobyspark 24:49c6624119ae 1224 if (debug) debug->printf("Menu changed by %i\r\n", menuChange);
tobyspark 24:49c6624119ae 1225
tobyspark 24:49c6624119ae 1226 *selectedMenu = selectedMenu->selectedIndex() + menuChange;
tobyspark 24:49c6624119ae 1227
tobyspark 24:49c6624119ae 1228 // update OLED line 2 here
tobyspark 24:49c6624119ae 1229 screen.clearBufferRow(kMenuLine2);
tobyspark 24:49c6624119ae 1230 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 24:49c6624119ae 1231
tobyspark 24:49c6624119ae 1232 if (debug) debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 24:49c6624119ae 1233 }
tobyspark 0:87aab40d5806 1234 }
tobyspark 0:87aab40d5806 1235
tobyspark 0:87aab40d5806 1236 // Action menu item
tobyspark 0:87aab40d5806 1237 if (menuEnc.hasPressed())
tobyspark 0:87aab40d5806 1238 {
tobyspark 0:87aab40d5806 1239 if (debug) debug->printf("Action Menu Item!\r\n");
tobyspark 21:f9d63cb7cedb 1240
tobyspark 0:87aab40d5806 1241 // Are we changing menus?
tobyspark 23:909928cafb95 1242 if (selectedMenu->selectedItem().type == SPKMenuItem::changesToMenu)
tobyspark 0:87aab40d5806 1243 {
tobyspark 31:01845a2347ff 1244 // If we're exiting the menu, we should set its selected index back to the menu's beginning...
tobyspark 31:01845a2347ff 1245 SPKMenu* menuToReset = selectedMenu->selectedItem().payload.menu == &mainMenu? selectedMenu : NULL;
tobyspark 31:01845a2347ff 1246
tobyspark 31:01845a2347ff 1247 // point selected menu pointer to the new menu pointer
tobyspark 23:909928cafb95 1248 selectedMenu = selectedMenu->selectedItem().payload.menu;
tobyspark 0:87aab40d5806 1249
tobyspark 31:01845a2347ff 1250 // ...doing this, of course, after we've used the value
tobyspark 31:01845a2347ff 1251 if (menuToReset) *menuToReset = 0;
tobyspark 31:01845a2347ff 1252
tobyspark 0:87aab40d5806 1253 // update OLED lines 1&2
tobyspark 0:87aab40d5806 1254 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 1255 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 1256 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 1257 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 1258
tobyspark 49:16309f39cead 1259 if (selectedMenu->selectedItem().type == SPKMenuItem::hasHandler)
tobyspark 49:16309f39cead 1260 {
tobyspark 49:16309f39cead 1261 selectedMenu->selectedItem().payload.handler(0, false);
tobyspark 49:16309f39cead 1262 }
tobyspark 49:16309f39cead 1263
tobyspark 0:87aab40d5806 1264 if (debug)
tobyspark 0:87aab40d5806 1265 {
tobyspark 0:87aab40d5806 1266 debug->printf("\r\n");
tobyspark 0:87aab40d5806 1267 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 1268 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 1269 }
tobyspark 49:16309f39cead 1270 }
tobyspark 49:16309f39cead 1271 else if (selectedMenu->selectedItem().type == SPKMenuItem::hasHandler)
tobyspark 49:16309f39cead 1272 {
tobyspark 49:16309f39cead 1273 selectedMenu->selectedItem().payload.handler(0, true);
tobyspark 0:87aab40d5806 1274 }
tobyspark 0:87aab40d5806 1275 // With that out of the way, we should be actioning a specific menu's payload?
tobyspark 44:723e65413ebe 1276 else if (selectedMenu == &mixModeMenu)
tobyspark 44:723e65413ebe 1277 {
tobyspark 44:723e65413ebe 1278 mixMode = mixModeMenu.selectedItem().payload.command[0];
tobyspark 49:16309f39cead 1279
tobyspark 49:16309f39cead 1280 // the spanner in the works: mixBlend and mixAdditive are now both index 0 in the menu
tobyspark 49:16309f39cead 1281 if (mixMode >= mixKeyStartIndex)
tobyspark 49:16309f39cead 1282 {
tobyspark 49:16309f39cead 1283 // adjust for the two-into-one spanner
tobyspark 49:16309f39cead 1284 mixMode += 1;
tobyspark 49:16309f39cead 1285
tobyspark 49:16309f39cead 1286 // if its the second click on the keying mode, lets edit the parameters
tobyspark 49:16309f39cead 1287 if (mixMode == mixModeOld)
tobyspark 49:16309f39cead 1288 {
tobyspark 49:16309f39cead 1289 selectedMenu = &mixModeUpdateKeyMenu;
tobyspark 49:16309f39cead 1290
tobyspark 49:16309f39cead 1291 screen.clearBufferRow(kMenuLine1);
tobyspark 49:16309f39cead 1292 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 49:16309f39cead 1293
tobyspark 49:16309f39cead 1294 selectedMenu->selectedItem().payload.handler(0, false);
tobyspark 49:16309f39cead 1295 }
tobyspark 49:16309f39cead 1296 }
tobyspark 44:723e65413ebe 1297 }
tobyspark 0:87aab40d5806 1298 else if (selectedMenu == &resolutionMenu)
tobyspark 0:87aab40d5806 1299 {
tobyspark 49:16309f39cead 1300 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 49:16309f39cead 1301 screen.textToBuffer("Setting Resolution...", kTVOneStatusLine);
tobyspark 49:16309f39cead 1302 screen.sendBuffer();
tobyspark 49:16309f39cead 1303
tobyspark 44:723e65413ebe 1304 bool ok;
tobyspark 31:01845a2347ff 1305 int32_t slot = tvOneEDIDPassthrough ? EDIDPassthroughSlot : resolutionMenu.selectedItem().payload.command[1];
tobyspark 31:01845a2347ff 1306
tobyspark 44:723e65413ebe 1307 ok = tvOne.setResolution(resolutionMenu.selectedItem().payload.command[0], slot);
tobyspark 0:87aab40d5806 1308
tobyspark 35:d5d9f0838f99 1309 // Save new resolution and EDID into TV One unit for power-on. Cycling TV One power sometimes needed for EDID. Pffft.
tobyspark 44:723e65413ebe 1310 if (ok) tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1);
tobyspark 35:d5d9f0838f99 1311
tobyspark 25:3b519ef70341 1312 string sentOK;
tobyspark 0:87aab40d5806 1313 if (ok) sentOK = "Sent: ";
tobyspark 0:87aab40d5806 1314 else sentOK = "Send Error: ";
tobyspark 0:87aab40d5806 1315
tobyspark 26:0299f8760715 1316 char sentMSGBuffer[kStringBufferLength];
tobyspark 26:0299f8760715 1317 snprintf(sentMSGBuffer, kStringBufferLength,"Res %i, EDID %i", resolutionMenu.selectedItem().payload.command[0], resolutionMenu.selectedItem().payload.command[1]);
tobyspark 0:87aab40d5806 1318
tobyspark 48:c0fedfa8c525 1319 tvOneStatusMessage.addMessage(sentOK + sentMSGBuffer, kTVOneStatusMessageHoldTime);
tobyspark 0:87aab40d5806 1320
tobyspark 0:87aab40d5806 1321 if (debug) { debug->printf("Changing resolution"); }
tobyspark 0:87aab40d5806 1322 }
tobyspark 1:f9fca21102e0 1323 else if (selectedMenu == &commsMenu)
tobyspark 1:f9fca21102e0 1324 {
tobyspark 26:0299f8760715 1325 string commsTypeString = "Network:";
tobyspark 26:0299f8760715 1326 char commsStatusBuffer[kStringBufferLength] = "--";
tobyspark 1:f9fca21102e0 1327
tobyspark 1:f9fca21102e0 1328 // Tear down any existing comms
tobyspark 1:f9fca21102e0 1329 // This is the action of commsNone
tobyspark 1:f9fca21102e0 1330 // And also clears the way for other comms actions
tobyspark 26:0299f8760715 1331 commsMode = commsNone;
tobyspark 5:f8b285ca41ba 1332 if (osc) {delete osc; osc = NULL;}
tobyspark 5:f8b285ca41ba 1333 if (ethernet) {delete ethernet; ethernet = NULL;}
tobyspark 33:e6672a9bd571 1334 if (artNet)
tobyspark 33:e6672a9bd571 1335 {
tobyspark 33:e6672a9bd571 1336 artNet->ArtPollReply.NumPorts = 0;
tobyspark 33:e6672a9bd571 1337 strcpy(artNet->ArtPollReply.NodeReport, "Shutdown");
tobyspark 33:e6672a9bd571 1338 artNet->SendArtPollReply();
tobyspark 33:e6672a9bd571 1339 artNet->Done();
tobyspark 33:e6672a9bd571 1340 delete artNet;
tobyspark 33:e6672a9bd571 1341 artNet = NULL;
tobyspark 33:e6672a9bd571 1342 }
tobyspark 5:f8b285ca41ba 1343 if (dmx) {delete dmx; dmx = NULL;}
tobyspark 5:f8b285ca41ba 1344
tobyspark 5:f8b285ca41ba 1345 // Ensure we can't change to comms modes the hardware isn't switched to
tobyspark 23:909928cafb95 1346 if (rj45Mode == rj45DMX && (commsMenu.selectedItem().payload.command[0] == commsOSC || commsMenu.selectedItem().payload.command[0] == commsArtNet))
tobyspark 1:f9fca21102e0 1347 {
tobyspark 5:f8b285ca41ba 1348 commsTypeString = "RJ45 not in Ethernet mode";
tobyspark 5:f8b285ca41ba 1349 }
tobyspark 23:909928cafb95 1350 else if (rj45Mode == rj45Ethernet && (commsMenu.selectedItem().payload.command[0] == commsDMXIn || commsMenu.selectedItem().payload.command[0] == commsDMXOut))
tobyspark 5:f8b285ca41ba 1351 {
tobyspark 5:f8b285ca41ba 1352 commsTypeString = "RJ45 not in DMX mode";
tobyspark 5:f8b285ca41ba 1353 }
tobyspark 5:f8b285ca41ba 1354 // Action!
tobyspark 23:909928cafb95 1355 else if (commsMenu.selectedItem().payload.command[0] == commsOSC)
tobyspark 5:f8b285ca41ba 1356 {
tobyspark 5:f8b285ca41ba 1357 commsMode = commsOSC;
tobyspark 5:f8b285ca41ba 1358 commsTypeString = "OSC: ";
tobyspark 1:f9fca21102e0 1359
tobyspark 1:f9fca21102e0 1360 ethernet = new EthernetNetIf(
tobyspark 1:f9fca21102e0 1361 IpAddr(kOSCMbedIPAddress),
tobyspark 1:f9fca21102e0 1362 IpAddr(kOSCMbedSubnetMask),
tobyspark 1:f9fca21102e0 1363 IpAddr(kOSCMbedGateway),
tobyspark 1:f9fca21102e0 1364 IpAddr(kOSCMbedDNS)
tobyspark 1:f9fca21102e0 1365 );
tobyspark 3:033d2b7768f3 1366
tobyspark 1:f9fca21102e0 1367 EthernetErr ethError = ethernet->setup();
tobyspark 1:f9fca21102e0 1368 if(ethError)
tobyspark 1:f9fca21102e0 1369 {
tobyspark 1:f9fca21102e0 1370 if (debug) debug->printf("Ethernet setup error, %d", ethError);
tobyspark 26:0299f8760715 1371 snprintf(commsStatusBuffer, kStringBufferLength, "Ethernet setup failed");
tobyspark 5:f8b285ca41ba 1372 commsMenu = commsNone;
tobyspark 1:f9fca21102e0 1373 // break out of here. this setup should be a function that returns a boolean
tobyspark 1:f9fca21102e0 1374 }
tobyspark 1:f9fca21102e0 1375
tobyspark 1:f9fca21102e0 1376 osc = new OSCClass();
tobyspark 33:e6672a9bd571 1377 osc->setReceiveMessage(&receiveMessage);
tobyspark 1:f9fca21102e0 1378 osc->begin(kOSCMbedPort);
tobyspark 1:f9fca21102e0 1379
tobyspark 26:0299f8760715 1380 snprintf(commsStatusBuffer, kStringBufferLength, "Listening on %i", kOSCMbedPort);
tobyspark 1:f9fca21102e0 1381 }
tobyspark 23:909928cafb95 1382 else if (commsMenu.selectedItem().payload.command[0] == commsArtNet)
tobyspark 1:f9fca21102e0 1383 {
tobyspark 5:f8b285ca41ba 1384 commsMode = commsArtNet;
tobyspark 5:f8b285ca41ba 1385 commsTypeString = "ArtNet: ";
tobyspark 3:033d2b7768f3 1386
tobyspark 3:033d2b7768f3 1387 artNet = new DmxArtNet();
tobyspark 1:f9fca21102e0 1388
tobyspark 3:033d2b7768f3 1389 artNet->BindIpAddress = IpAddr(kArtNetBindIPAddress);
tobyspark 3:033d2b7768f3 1390 artNet->BCastAddress = IpAddr(kArtNetBroadcastAddress);
tobyspark 3:033d2b7768f3 1391
tobyspark 3:033d2b7768f3 1392 artNet->InitArtPollReplyDefaults();
tobyspark 3:033d2b7768f3 1393
tobyspark 33:e6672a9bd571 1394 artNet->ArtPollReply.PortType[0] = 128; // Bit 7 = Set is this channel can output data from the Art-Net Network.
tobyspark 33:e6672a9bd571 1395 artNet->ArtPollReply.GoodOutput[0] = 128; // Bit 7 = Set – Data is being transmitted.
tobyspark 33:e6672a9bd571 1396 artNet->ArtPollReply.PortType[2] = 64; // Bit 6 = Set if this channel can input onto the Art-NetNetwork.
tobyspark 33:e6672a9bd571 1397 artNet->ArtPollReply.GoodInput[2] = 128; // Bit 7 = Set – Data received.
tobyspark 3:033d2b7768f3 1398
tobyspark 3:033d2b7768f3 1399 artNet->Init();
tobyspark 3:033d2b7768f3 1400 artNet->SendArtPollReply(); // announce to art-net nodes
tobyspark 3:033d2b7768f3 1401
tobyspark 26:0299f8760715 1402 snprintf(commsStatusBuffer, kStringBufferLength, "Listening");
tobyspark 1:f9fca21102e0 1403 }
tobyspark 23:909928cafb95 1404 else if (commsMenu.selectedItem().payload.command[0] == commsDMXIn)
tobyspark 1:f9fca21102e0 1405 {
tobyspark 5:f8b285ca41ba 1406 commsMode = commsDMXIn;
tobyspark 5:f8b285ca41ba 1407 commsTypeString = "DMX In: ";
tobyspark 1:f9fca21102e0 1408
tobyspark 5:f8b285ca41ba 1409 dmxDirectionDOUT = 0;
tobyspark 5:f8b285ca41ba 1410
tobyspark 5:f8b285ca41ba 1411 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 1:f9fca21102e0 1412 }
tobyspark 23:909928cafb95 1413 else if (commsMenu.selectedItem().payload.command[0] == commsDMXOut)
tobyspark 5:f8b285ca41ba 1414 {
tobyspark 5:f8b285ca41ba 1415 commsMode = commsDMXOut;
tobyspark 5:f8b285ca41ba 1416 commsTypeString = "DMX Out: ";
tobyspark 5:f8b285ca41ba 1417
tobyspark 5:f8b285ca41ba 1418 dmxDirectionDOUT = 1;
tobyspark 5:f8b285ca41ba 1419
tobyspark 5:f8b285ca41ba 1420 dmx = new DMX(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
tobyspark 5:f8b285ca41ba 1421 }
tobyspark 5:f8b285ca41ba 1422
tobyspark 1:f9fca21102e0 1423 screen.clearBufferRow(kCommsStatusLine);
tobyspark 25:3b519ef70341 1424 screen.textToBuffer(commsTypeString + commsStatusBuffer, kCommsStatusLine);
tobyspark 1:f9fca21102e0 1425 }
tobyspark 12:c270870bdd23 1426 else if (selectedMenu == &advancedMenu)
tobyspark 12:c270870bdd23 1427 {
tobyspark 23:909928cafb95 1428 if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOff)
tobyspark 12:c270870bdd23 1429 {
tobyspark 49:16309f39cead 1430 // Has handler
tobyspark 12:c270870bdd23 1431 }
tobyspark 23:909928cafb95 1432 else if (advancedMenu.selectedItem().payload.command[0] == advancedHDCPOn)
tobyspark 15:4b394c64b461 1433 {
tobyspark 49:16309f39cead 1434 // Has handler
tobyspark 15:4b394c64b461 1435 }
tobyspark 31:01845a2347ff 1436 else if (advancedMenu.selectedItem().payload.command[0] == advancedEDIDPassthrough)
tobyspark 31:01845a2347ff 1437 {
tobyspark 49:16309f39cead 1438 // Has handler
tobyspark 31:01845a2347ff 1439 }
tobyspark 31:01845a2347ff 1440 else if (advancedMenu.selectedItem().payload.command[0] == advancedEDIDInternal)
tobyspark 31:01845a2347ff 1441 {
tobyspark 49:16309f39cead 1442 // Has handler
tobyspark 31:01845a2347ff 1443 }
tobyspark 30:873979018850 1444 else if (advancedMenu.selectedItem().payload.command[0] == advancedTestSources)
tobyspark 34:69dfe64e7e6b 1445 {
tobyspark 34:69dfe64e7e6b 1446 tvOneRGB1Stable = false;
tobyspark 34:69dfe64e7e6b 1447 tvOneRGB2Stable = false;
tobyspark 34:69dfe64e7e6b 1448 handleTVOneSources();
tobyspark 29:95a7efe30527 1449 }
tobyspark 23:909928cafb95 1450 else if (advancedMenu.selectedItem().payload.command[0] == advancedConformProcessor)
tobyspark 17:fc68d40b8b1f 1451 {
tobyspark 20:8b92d7922c48 1452 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 41:00d1cd3b2af2 1453 screen.textToBuffer("Reverting...", kTVOneStatusLine);
tobyspark 41:00d1cd3b2af2 1454 screen.sendBuffer();
tobyspark 41:00d1cd3b2af2 1455
tobyspark 41:00d1cd3b2af2 1456 bool ok = conformProcessor();
tobyspark 41:00d1cd3b2af2 1457
tobyspark 41:00d1cd3b2af2 1458 std::string sendOK = ok ? "Reverting success" : "Send Error: Revert";
tobyspark 41:00d1cd3b2af2 1459
tobyspark 48:c0fedfa8c525 1460 tvOneStatusMessage.addMessage(sendOK, kTVOneStatusMessageHoldTime);
tobyspark 41:00d1cd3b2af2 1461 }
tobyspark 41:00d1cd3b2af2 1462 else if (advancedMenu.selectedItem().payload.command[0] == advancedConformUploadProcessor)
tobyspark 41:00d1cd3b2af2 1463 {
tobyspark 41:00d1cd3b2af2 1464 bool ok = true;
tobyspark 41:00d1cd3b2af2 1465
tobyspark 41:00d1cd3b2af2 1466 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 41:00d1cd3b2af2 1467 screen.textToBuffer("Uploading...", kTVOneStatusLine);
tobyspark 41:00d1cd3b2af2 1468 screen.sendBuffer();
tobyspark 41:00d1cd3b2af2 1469
tobyspark 41:00d1cd3b2af2 1470 ok = ok && uploadToProcessor();
tobyspark 41:00d1cd3b2af2 1471
tobyspark 41:00d1cd3b2af2 1472 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 20:8b92d7922c48 1473 screen.textToBuffer("Conforming...", kTVOneStatusLine);
tobyspark 20:8b92d7922c48 1474 screen.sendBuffer();
tobyspark 20:8b92d7922c48 1475
tobyspark 41:00d1cd3b2af2 1476 ok = ok && conformProcessor();
tobyspark 17:fc68d40b8b1f 1477
tobyspark 17:fc68d40b8b1f 1478 std::string sendOK = ok ? "Conform success" : "Send Error: Conform";
tobyspark 17:fc68d40b8b1f 1479
tobyspark 48:c0fedfa8c525 1480 tvOneStatusMessage.addMessage(sendOK, kTVOneStatusMessageHoldTime);
tobyspark 17:fc68d40b8b1f 1481 }
tobyspark 23:909928cafb95 1482 else if (advancedMenu.selectedItem().payload.command[0] == advancedLoadDefaults)
tobyspark 16:52484666b323 1483 {
tobyspark 16:52484666b323 1484 settings.loadDefaults();
tobyspark 27:27851d3d2bba 1485 setMixModeMenuItems();
tobyspark 27:27851d3d2bba 1486 setResolutionMenuItems();
tobyspark 16:52484666b323 1487
tobyspark 48:c0fedfa8c525 1488 tvOneStatusMessage.addMessage("Controller Reverted", kTVOneStatusMessageHoldTime);
tobyspark 16:52484666b323 1489 }
tobyspark 23:909928cafb95 1490 else if (advancedMenu.selectedItem().payload.command[0] == advancedSetResolutions)
tobyspark 21:f9d63cb7cedb 1491 {
tobyspark 21:f9d63cb7cedb 1492 bool ok;
tobyspark 44:723e65413ebe 1493 ok = tvOne.uploadCustomResolutions();
tobyspark 21:f9d63cb7cedb 1494
tobyspark 48:c0fedfa8c525 1495 tvOneStatusMessage.addMessage(ok ? "Resolutions set" : "Res' could not be set", kTVOneStatusMessageHoldTime);
tobyspark 21:f9d63cb7cedb 1496 }
tobyspark 12:c270870bdd23 1497 }
tobyspark 0:87aab40d5806 1498 else
tobyspark 0:87aab40d5806 1499 {
tobyspark 0:87aab40d5806 1500 if (debug) { debug->printf("Warning: No action identified"); }
tobyspark 0:87aab40d5806 1501 }
tobyspark 0:87aab40d5806 1502 }
tobyspark 0:87aab40d5806 1503
tobyspark 34:69dfe64e7e6b 1504 // Send any updates to the display
tobyspark 48:c0fedfa8c525 1505 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 48:c0fedfa8c525 1506 screen.textToBuffer(tvOneStatusMessage.message(), kTVOneStatusLine);
tobyspark 34:69dfe64e7e6b 1507 screen.sendBuffer();
tobyspark 0:87aab40d5806 1508
tobyspark 5:f8b285ca41ba 1509 //// MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIXMIX MIX MIXMIX MIX MIX MIX MIX MIXMIX MIX MIX
tobyspark 0:87aab40d5806 1510
tobyspark 0:87aab40d5806 1511 bool updateFade = false;
tobyspark 3:033d2b7768f3 1512 float xFade = 0;
tobyspark 3:033d2b7768f3 1513 float fadeUp = 1;
tobyspark 3:033d2b7768f3 1514
tobyspark 3:033d2b7768f3 1515 //// TASK: Process control surface
tobyspark 3:033d2b7768f3 1516
tobyspark 0:87aab40d5806 1517 // Get new states of tap buttons, remembering at end of loop() assign these current values to the previous variables
tobyspark 5:f8b285ca41ba 1518 const bool tapLeft = !tapLeftDIN;
tobyspark 5:f8b285ca41ba 1519 const bool tapRight = !tapRightDIN;
tobyspark 0:87aab40d5806 1520
tobyspark 17:fc68d40b8b1f 1521 // We're taking a further median of the AINs on top of mbed libs v29.
tobyspark 17:fc68d40b8b1f 1522 // This takes some values from last passes and most from now. With debug off, seem to need median size > 5
tobyspark 17:fc68d40b8b1f 1523 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1524 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1525 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1526 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1527 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1528 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1529 xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1530 fadeUpFilter.process(fadeUpAIN.read());
tobyspark 17:fc68d40b8b1f 1531 const float xFadeAINCached = xFadeFilter.process(xFadeAIN.read());
tobyspark 17:fc68d40b8b1f 1532 const float fadeUpAINCached = fadeUpFilter.process(fadeUpAIN.read());
tobyspark 0:87aab40d5806 1533
tobyspark 0:87aab40d5806 1534 // When a tap is depressed, we can ignore any move of the crossfader but not fade to black
tobyspark 0:87aab40d5806 1535 if (tapLeft || tapRight)
tobyspark 0:87aab40d5806 1536 {
tobyspark 5:f8b285ca41ba 1537 // If both are pressed, take to the one that is new, ie. not the first pressed.
tobyspark 0:87aab40d5806 1538 if (tapLeft && tapRight)
tobyspark 0:87aab40d5806 1539 {
tobyspark 5:f8b285ca41ba 1540 xFade = tapLeftWasFirstPressed ? 1 : 0;
tobyspark 0:87aab40d5806 1541 }
tobyspark 5:f8b285ca41ba 1542 // If just one is pressed, take to that and remember which is pressed
tobyspark 5:f8b285ca41ba 1543 else if (tapLeft)
tobyspark 5:f8b285ca41ba 1544 {
tobyspark 5:f8b285ca41ba 1545 xFade = 0;
tobyspark 5:f8b285ca41ba 1546 tapLeftWasFirstPressed = 1;
tobyspark 5:f8b285ca41ba 1547 }
tobyspark 5:f8b285ca41ba 1548 else if (tapRight)
tobyspark 5:f8b285ca41ba 1549 {
tobyspark 5:f8b285ca41ba 1550 xFade = 1;
tobyspark 5:f8b285ca41ba 1551 tapLeftWasFirstPressed = 0;
tobyspark 5:f8b285ca41ba 1552 }
tobyspark 5:f8b285ca41ba 1553 }
tobyspark 18:ebe5da639a6a 1554 else xFade = 1.0 - fadeCalc(xFadeAINCached, xFadeTolerance);
tobyspark 0:87aab40d5806 1555
tobyspark 0:87aab40d5806 1556 fadeUp = 1.0 - fadeCalc(fadeUpAINCached, fadeUpTolerance);
tobyspark 0:87aab40d5806 1557
tobyspark 33:e6672a9bd571 1558 //// TASK: Process Network Comms In, ie. modify TVOne state
tobyspark 5:f8b285ca41ba 1559 if (commsMode == commsOSC)
tobyspark 3:033d2b7768f3 1560 {
tobyspark 3:033d2b7768f3 1561 if (osc->newMessage)
tobyspark 3:033d2b7768f3 1562 {
tobyspark 3:033d2b7768f3 1563 osc->newMessage = false; // fixme!
tobyspark 33:e6672a9bd571 1564 processOSCIn(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1565 }
tobyspark 3:033d2b7768f3 1566 }
tobyspark 3:033d2b7768f3 1567
tobyspark 5:f8b285ca41ba 1568 if (commsMode == commsArtNet)
tobyspark 3:033d2b7768f3 1569 {
tobyspark 33:e6672a9bd571 1570 if (artNet->Work()) processArtNetIn(xFade, fadeUp);
tobyspark 3:033d2b7768f3 1571 }
tobyspark 3:033d2b7768f3 1572
tobyspark 5:f8b285ca41ba 1573 if (commsMode == commsDMXIn)
tobyspark 5:f8b285ca41ba 1574 {
tobyspark 5:f8b285ca41ba 1575 processDMXIn(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1576 }
tobyspark 5:f8b285ca41ba 1577
tobyspark 5:f8b285ca41ba 1578 if (commsMode == commsDMXOut)
tobyspark 5:f8b285ca41ba 1579 {
tobyspark 5:f8b285ca41ba 1580 processDMXOut(xFade, fadeUp);
tobyspark 5:f8b285ca41ba 1581 }
tobyspark 0:87aab40d5806 1582
tobyspark 0:87aab40d5806 1583 // Calculate new A&B fade percents
tobyspark 0:87aab40d5806 1584 int newFadeAPercent = 0;
tobyspark 0:87aab40d5806 1585 int newFadeBPercent = 0;
tobyspark 0:87aab40d5806 1586
tobyspark 30:873979018850 1587 if (mixMode == mixBlend)
tobyspark 11:0783cfbeb746 1588 {
tobyspark 49:16309f39cead 1589 // window A occludes B. this is fast as only A changes with xFade.
tobyspark 49:16309f39cead 1590 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 49:16309f39cead 1591 newFadeBPercent = fadeUp * 100.0;
tobyspark 11:0783cfbeb746 1592 }
tobyspark 15:4b394c64b461 1593 else if (mixMode == mixAdditive)
tobyspark 11:0783cfbeb746 1594 {
tobyspark 22:90054fe6d86c 1595 // we need to set fade level of both windows according to the fade curve profile
tobyspark 22:90054fe6d86c 1596 float newFadeA = (1.0-xFade) * (1.0 + fadeCurve);
tobyspark 22:90054fe6d86c 1597 float newFadeB = xFade * (1 + fadeCurve);
tobyspark 22:90054fe6d86c 1598 if (newFadeA > 1.0) newFadeA = 1.0;
tobyspark 22:90054fe6d86c 1599 if (newFadeB > 1.0) newFadeB = 1.0;
tobyspark 22:90054fe6d86c 1600
tobyspark 22:90054fe6d86c 1601 newFadeAPercent = newFadeA * fadeUp * 100.0;
tobyspark 22:90054fe6d86c 1602 newFadeBPercent = newFadeB * fadeUp * 100.0;
tobyspark 11:0783cfbeb746 1603 }
tobyspark 36:8b5c75c8bc23 1604 else if (mixMode >= mixKeyStartIndex)
tobyspark 11:0783cfbeb746 1605 {
tobyspark 0:87aab40d5806 1606 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 1607 newFadeBPercent = fadeUp * 100.0;
tobyspark 0:87aab40d5806 1608 }
tobyspark 0:87aab40d5806 1609
tobyspark 17:fc68d40b8b1f 1610 //// TASK: Send to TVOne if percents have changed
tobyspark 17:fc68d40b8b1f 1611
tobyspark 17:fc68d40b8b1f 1612 // No amount of median filtering is stopping flipflopping between two adjacent percents, so...
tobyspark 17:fc68d40b8b1f 1613 bool fadeAPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1614 bool fadeBPercentHasChanged;
tobyspark 17:fc68d40b8b1f 1615 if (oldFadeAPercent == newFadeAPercent && (newFadeAPercent == fadeAPercent - 1 || newFadeAPercent == fadeAPercent + 1))
tobyspark 17:fc68d40b8b1f 1616 fadeAPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1617 else
tobyspark 17:fc68d40b8b1f 1618 fadeAPercentHasChanged = newFadeAPercent != fadeAPercent;
tobyspark 17:fc68d40b8b1f 1619 if (oldFadeBPercent == newFadeBPercent && (newFadeBPercent == fadeBPercent - 1 || newFadeBPercent == fadeBPercent + 1))
tobyspark 17:fc68d40b8b1f 1620 fadeBPercentHasChanged = false;
tobyspark 17:fc68d40b8b1f 1621 else
tobyspark 17:fc68d40b8b1f 1622 fadeBPercentHasChanged = newFadeBPercent != fadeBPercent;
tobyspark 17:fc68d40b8b1f 1623
tobyspark 35:d5d9f0838f99 1624 // If changing mixMode from additive, we want to do this before updating fade values
tobyspark 49:16309f39cead 1625 if (mixMode != mixModeOld && mixModeOld == mixAdditive) actionMixMode();
tobyspark 35:d5d9f0838f99 1626
tobyspark 9:f83eadd8917a 1627 // We want to send the higher first, otherwise black flashes can happen on taps
tobyspark 17:fc68d40b8b1f 1628 if (fadeAPercentHasChanged && newFadeAPercent >= newFadeBPercent)
tobyspark 8:d46cc49f0f37 1629 {
tobyspark 17:fc68d40b8b1f 1630 oldFadeAPercent = fadeAPercent;
tobyspark 0:87aab40d5806 1631 fadeAPercent = newFadeAPercent;
tobyspark 0:87aab40d5806 1632 updateFade = true;
tobyspark 0:87aab40d5806 1633
tobyspark 0:87aab40d5806 1634 fadeAPO = fadeAPercent / 100.0;
tobyspark 0:87aab40d5806 1635 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 0:87aab40d5806 1636 }
tobyspark 17:fc68d40b8b1f 1637 if (fadeBPercentHasChanged)
tobyspark 8:d46cc49f0f37 1638 {
tobyspark 17:fc68d40b8b1f 1639 oldFadeBPercent = fadeBPercent;
tobyspark 0:87aab40d5806 1640 fadeBPercent = newFadeBPercent;
tobyspark 0:87aab40d5806 1641 updateFade = true;
tobyspark 0:87aab40d5806 1642
tobyspark 0:87aab40d5806 1643 fadeBPO = fadeBPercent / 100.0;
tobyspark 0:87aab40d5806 1644 tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 0:87aab40d5806 1645 }
tobyspark 17:fc68d40b8b1f 1646 if (fadeAPercentHasChanged && newFadeAPercent < newFadeBPercent)
tobyspark 9:f83eadd8917a 1647 {
tobyspark 17:fc68d40b8b1f 1648 oldFadeAPercent = fadeAPercent;
tobyspark 9:f83eadd8917a 1649 fadeAPercent = newFadeAPercent;
tobyspark 9:f83eadd8917a 1650 updateFade = true;
tobyspark 9:f83eadd8917a 1651
tobyspark 9:f83eadd8917a 1652 fadeAPO = fadeAPercent / 100.0;
tobyspark 9:f83eadd8917a 1653 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 9:f83eadd8917a 1654 }
tobyspark 8:d46cc49f0f37 1655 if (updateFade && debug)
tobyspark 8:d46cc49f0f37 1656 {
tobyspark 0:87aab40d5806 1657 //debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAIN.read(), fadeUpAIN.read());
tobyspark 0:87aab40d5806 1658 debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAINCached, fadeUpAINCached);
tobyspark 0:87aab40d5806 1659 debug->printf("xFade = %3f fadeUp = %3f fadeA% = %i fadeB% = %i \r\n", xFade, fadeUp, fadeAPercent, fadeBPercent);
tobyspark 18:ebe5da639a6a 1660 debug->printf("\r\n");
tobyspark 0:87aab40d5806 1661 }
tobyspark 30:873979018850 1662
tobyspark 49:16309f39cead 1663 // If changing mixMode to additive, we want to do this after updating fade values
tobyspark 49:16309f39cead 1664 if (mixMode != mixModeOld) actionMixMode();
tobyspark 35:d5d9f0838f99 1665
tobyspark 33:e6672a9bd571 1666 //// TASK: Process Network Comms Out, ie. send out any fade updates
tobyspark 33:e6672a9bd571 1667 if (commsMode == commsOSC && updateFade)
tobyspark 33:e6672a9bd571 1668 {
tobyspark 33:e6672a9bd571 1669 processOSCOut(xFade, fadeUp);
tobyspark 33:e6672a9bd571 1670 }
tobyspark 33:e6672a9bd571 1671
tobyspark 33:e6672a9bd571 1672 if (commsMode == commsArtNet && updateFade)
tobyspark 33:e6672a9bd571 1673 {
tobyspark 33:e6672a9bd571 1674 processArtNetOut(xFade, fadeUp);
tobyspark 33:e6672a9bd571 1675 }
tobyspark 33:e6672a9bd571 1676
tobyspark 33:e6672a9bd571 1677 if (commsMode == commsDMXOut && updateFade)
tobyspark 33:e6672a9bd571 1678 {
tobyspark 33:e6672a9bd571 1679 processDMXOut(xFade, fadeUp);
tobyspark 33:e6672a9bd571 1680 }
tobyspark 33:e6672a9bd571 1681
tobyspark 45:cf8c2400be5c 1682 //// TASK: Housekeeping
tobyspark 45:cf8c2400be5c 1683
tobyspark 49:16309f39cead 1684 if (tvOne.millisSinceLastCommandSent() > tvOne.getCommandTimeoutPeriod() + 1000)
tobyspark 30:873979018850 1685 {
tobyspark 45:cf8c2400be5c 1686 // Lets check on our sources
tobyspark 45:cf8c2400be5c 1687 handleTVOneSources();
tobyspark 49:16309f39cead 1688
tobyspark 49:16309f39cead 1689 // Lets check on our fade levels
tobyspark 49:16309f39cead 1690 checkTVOneMixStatus();
tobyspark 30:873979018850 1691 }
tobyspark 0:87aab40d5806 1692 }
tobyspark 30:873979018850 1693 }