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:
Sun Apr 15 21:22:39 2012 +0000
Revision:
2:50043054e4f7
Parent:
1:f9fca21102e0
Child:
3:033d2b7768f3
More librarified

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 0:87aab40d5806 1 // *SPARK D-FUSER
tobyspark 0:87aab40d5806 2 // A project by *spark audio-visual
tobyspark 0:87aab40d5806 3 //
tobyspark 0:87aab40d5806 4 // 'DJ' controller styke RS232 Control for TV-One products
tobyspark 0:87aab40d5806 5 // Good for 1T-C2-750, others will need some extra work
tobyspark 0:87aab40d5806 6 //
tobyspark 0:87aab40d5806 7 // Copyright *spark audio-visual 2009-2011
tobyspark 0:87aab40d5806 8 //
tobyspark 0:87aab40d5806 9 // v10 - Port to mBed, keying redux - Apr'11
tobyspark 0:87aab40d5806 10 // v11 - Sign callbacks, code clean-up - Apr'11
tobyspark 0:87aab40d5806 11 // 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 0:87aab40d5806 12 // v13 - Menu system for Resolution + Keying implemented, it writing to debug, it sending TVOne commands - Apr'11
tobyspark 0:87aab40d5806 13 // v14 - Fixes for new PCB - Oct'11
tobyspark 0:87aab40d5806 14 // v15 - TBZ PCB, OLED - Mar'12
tobyspark 1:f9fca21102e0 15 // v16 - Comms menu, OSC. There in theory: lots of trouble from EthernetNetIf. NetServices better. But still silently crashes on creation of EthernetNetIf, despite (now) ample memory and code tested elsewhere (inc OSC + spkOLED).
tobyspark 1:f9fca21102e0 16 // vxx - TODO: EDID upload from USB mass storage
tobyspark 1:f9fca21102e0 17 // vxx - TODO: EDID creation from resolution
tobyspark 0:87aab40d5806 18
tobyspark 0:87aab40d5806 19 #include "mbed.h"
tobyspark 0:87aab40d5806 20
tobyspark 0:87aab40d5806 21 #include "spk_tvone_mbed.h"
tobyspark 0:87aab40d5806 22 #include "spk_utils.h"
tobyspark 0:87aab40d5806 23 #include "spk_mRotaryEncoder.h"
tobyspark 0:87aab40d5806 24 #include "spk_oled_ssd1305.h"
tobyspark 2:50043054e4f7 25 #include "spk_oled_gfx.h"
tobyspark 1:f9fca21102e0 26 #include "EthernetNetIf.h"
tobyspark 1:f9fca21102e0 27 #include "mbedOSC.h"
tobyspark 0:87aab40d5806 28
tobyspark 0:87aab40d5806 29 #include <sstream>
tobyspark 0:87aab40d5806 30
tobyspark 1:f9fca21102e0 31 #define kMenuLine1 3
tobyspark 1:f9fca21102e0 32 #define kMenuLine2 4
tobyspark 1:f9fca21102e0 33 #define kCommsStatusLine 6
tobyspark 1:f9fca21102e0 34 #define kTVOneStatusLine 7
tobyspark 1:f9fca21102e0 35
tobyspark 1:f9fca21102e0 36 #define kOSCMbedPort 10000
tobyspark 1:f9fca21102e0 37 #define kOSCMbedIPAddress 10,0,0,2
tobyspark 1:f9fca21102e0 38 #define kOSCMbedSubnetMask 255,255,255,0
tobyspark 1:f9fca21102e0 39 #define kOSCMbedGateway 10,0,0,1
tobyspark 1:f9fca21102e0 40 #define kOSCMbedDNS 10,0,0,1
tobyspark 0:87aab40d5806 41
tobyspark 0:87aab40d5806 42 //// DEBUG
tobyspark 0:87aab40d5806 43
tobyspark 0:87aab40d5806 44 // Comment out one or the other...
tobyspark 0:87aab40d5806 45 Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial
tobyspark 0:87aab40d5806 46 // Serial *debug = NULL; // For release (no debugging)
tobyspark 0:87aab40d5806 47
tobyspark 0:87aab40d5806 48 //// mBED PIN ASSIGNMENTS
tobyspark 0:87aab40d5806 49
tobyspark 0:87aab40d5806 50 // Inputs
tobyspark 0:87aab40d5806 51 AnalogIn xFadeAIN(p19);
tobyspark 0:87aab40d5806 52 AnalogIn fadeUpAIN(p20);
tobyspark 0:87aab40d5806 53 DigitalIn tapLeftDIN(p24);
tobyspark 0:87aab40d5806 54 DigitalIn tapRightDIN(p21);
tobyspark 0:87aab40d5806 55
tobyspark 0:87aab40d5806 56 SPKRotaryEncoder menuEnc(p17, p16, p15);
tobyspark 0:87aab40d5806 57
tobyspark 0:87aab40d5806 58 // Outputs
tobyspark 0:87aab40d5806 59 PwmOut fadeAPO(LED1);
tobyspark 0:87aab40d5806 60 PwmOut fadeBPO(LED2);
tobyspark 0:87aab40d5806 61
tobyspark 0:87aab40d5806 62 // SPKTVOne(PinName txPin, PinName rxPin, PinName signWritePin, PinName signErrorPin, Serial *debugSerial)
tobyspark 0:87aab40d5806 63 SPKTVOne tvOne(p28, p27, LED3, LED4, debug);
tobyspark 0:87aab40d5806 64 //SPKTVOne tvOne(p28, p27, LED3, LED4);
tobyspark 0:87aab40d5806 65
tobyspark 0:87aab40d5806 66 // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL);
tobyspark 0:87aab40d5806 67 SPKDisplay screen(p5, p7, p8, p10, p9, debug);
tobyspark 0:87aab40d5806 68
tobyspark 0:87aab40d5806 69 // Menu
tobyspark 0:87aab40d5806 70
tobyspark 0:87aab40d5806 71 SPKMenu *selectedMenu;
tobyspark 0:87aab40d5806 72 SPKMenu *lastSelectedMenu;
tobyspark 0:87aab40d5806 73 SPKMenuOfMenus mainMenu;
tobyspark 0:87aab40d5806 74 SPKMenuPayload resolutionMenu;
tobyspark 0:87aab40d5806 75 SPKMenuPayload mixModeMenu;
tobyspark 1:f9fca21102e0 76 SPKMenuPayload commsMenu;
tobyspark 1:f9fca21102e0 77
tobyspark 1:f9fca21102e0 78 // Comms Objects
tobyspark 1:f9fca21102e0 79 EthernetNetIf *ethernet = NULL;
tobyspark 1:f9fca21102e0 80 OSCClass *osc = NULL;
tobyspark 0:87aab40d5806 81
tobyspark 0:87aab40d5806 82 // Fade logic constants + variables
tobyspark 0:87aab40d5806 83 const float xFadeTolerance = 0.05;
tobyspark 0:87aab40d5806 84 const float fadeUpTolerance = 0.05;
tobyspark 0:87aab40d5806 85 float xFade = 0;
tobyspark 0:87aab40d5806 86 float fadeUp = 1;
tobyspark 0:87aab40d5806 87
tobyspark 0:87aab40d5806 88 // A&B Fade as resolved percent
tobyspark 0:87aab40d5806 89 int fadeAPercent = 0;
tobyspark 0:87aab40d5806 90 int fadeBPercent = 0;
tobyspark 0:87aab40d5806 91
tobyspark 0:87aab40d5806 92 // Tap button states
tobyspark 0:87aab40d5806 93 bool tapLeftPrevious = false;
tobyspark 0:87aab40d5806 94 bool tapRightPrevious = false;
tobyspark 0:87aab40d5806 95
tobyspark 0:87aab40d5806 96 // Key mode parameters
tobyspark 0:87aab40d5806 97 int keyerParamsSet = -1; // last keyParams index uploaded to unit
tobyspark 0:87aab40d5806 98 // {lumakey, chroma on blue [, to be extended as needed] }
tobyspark 0:87aab40d5806 99 // {minY, maxY, minU, maxU, minV, maxV }
tobyspark 0:87aab40d5806 100 int keyerParams[2][6] =
tobyspark 0:87aab40d5806 101 {
tobyspark 0:87aab40d5806 102 {0, 18, 128, 129, 128, 129}, // lumakey
tobyspark 0:87aab40d5806 103 {41, 42, 240, 241, 109, 110} // chroma on blue
tobyspark 0:87aab40d5806 104 // ...
tobyspark 0:87aab40d5806 105 };
tobyspark 0:87aab40d5806 106
tobyspark 0:87aab40d5806 107
tobyspark 0:87aab40d5806 108
tobyspark 0:87aab40d5806 109 inline float fadeCalc (const float AIN, const float tolerance) {
tobyspark 0:87aab40d5806 110 float pos ;
tobyspark 0:87aab40d5806 111 if (AIN < tolerance) pos = 0;
tobyspark 0:87aab40d5806 112 else if (AIN > 1.0 - tolerance) pos = 1;
tobyspark 0:87aab40d5806 113 else pos = (AIN - tolerance) / (1 - 2*tolerance);
tobyspark 0:87aab40d5806 114 if (debug && false) debug->printf("fadeCalc in: %f out: %f \r\n", AIN, pos);
tobyspark 0:87aab40d5806 115 return pos;
tobyspark 0:87aab40d5806 116 }
tobyspark 0:87aab40d5806 117
tobyspark 0:87aab40d5806 118 bool setKeyParamsTo(int index) {
tobyspark 0:87aab40d5806 119 // Only spend the time uploading six parameters if we need to
tobyspark 0:87aab40d5806 120 // Might want to bounds check here
tobyspark 0:87aab40d5806 121
tobyspark 0:87aab40d5806 122 bool ok = false;
tobyspark 0:87aab40d5806 123
tobyspark 0:87aab40d5806 124 if (index != keyerParamsSet)
tobyspark 0:87aab40d5806 125 {
tobyspark 0:87aab40d5806 126 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, keyerParams[index][0]);
tobyspark 0:87aab40d5806 127 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, keyerParams[index][1]);
tobyspark 0:87aab40d5806 128 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, keyerParams[index][2]);
tobyspark 0:87aab40d5806 129 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, keyerParams[index][3]);
tobyspark 0:87aab40d5806 130 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, keyerParams[index][4]);
tobyspark 0:87aab40d5806 131 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, keyerParams[index][5]);
tobyspark 0:87aab40d5806 132
tobyspark 0:87aab40d5806 133 keyerParamsSet = index;
tobyspark 0:87aab40d5806 134 }
tobyspark 0:87aab40d5806 135
tobyspark 0:87aab40d5806 136 return ok;
tobyspark 0:87aab40d5806 137 }
tobyspark 0:87aab40d5806 138
tobyspark 1:f9fca21102e0 139 void oscCallback() {
tobyspark 1:f9fca21102e0 140 screen.clearBufferRow(kCommsStatusLine);
tobyspark 1:f9fca21102e0 141 screen.textToBuffer("OSC message received", kCommsStatusLine);
tobyspark 1:f9fca21102e0 142 screen.sendBuffer();
tobyspark 1:f9fca21102e0 143 }
tobyspark 1:f9fca21102e0 144
tobyspark 0:87aab40d5806 145 int main()
tobyspark 0:87aab40d5806 146 {
tobyspark 0:87aab40d5806 147 if (debug)
tobyspark 0:87aab40d5806 148 {
tobyspark 0:87aab40d5806 149 debug->printf("\r\n\r\n");
tobyspark 0:87aab40d5806 150 debug->printf("*spark d-fuser -----------\r\n");
tobyspark 0:87aab40d5806 151 debug->printf(" debug channel\r\n");
tobyspark 0:87aab40d5806 152 }
tobyspark 2:50043054e4f7 153
tobyspark 2:50043054e4f7 154 // Set display font
tobyspark 2:50043054e4f7 155 screen.fontStartCharacter = &characterBytesStartChar;
tobyspark 2:50043054e4f7 156 screen.fontEndCharacter = &characterBytesEndChar;
tobyspark 2:50043054e4f7 157 screen.fontCharacters = characterBytes;
tobyspark 2:50043054e4f7 158
tobyspark 0:87aab40d5806 159 // Splash screen
tobyspark 2:50043054e4f7 160 screen.imageToBuffer(spkDisplayLogo);
tobyspark 0:87aab40d5806 161 screen.textToBuffer("SPK:D-Fuser",0);
tobyspark 0:87aab40d5806 162 screen.textToBuffer("SW beta.15",1);
tobyspark 0:87aab40d5806 163
tobyspark 0:87aab40d5806 164 // Set menu structure
tobyspark 0:87aab40d5806 165 mixModeMenu.title = "Mix Mode";
tobyspark 0:87aab40d5806 166 enum { blend, additive, lumaKey, chromaKey1, chromaKey2, chromaKey3 }; // additive will require custom TVOne firmware.
tobyspark 0:87aab40d5806 167 mixModeMenu.addMenuItem("Blend", blend, 0);
tobyspark 0:87aab40d5806 168 mixModeMenu.addMenuItem("LumaKey", lumaKey, 0);
tobyspark 0:87aab40d5806 169 mixModeMenu.addMenuItem("ChromaKey - Blue", chromaKey1, 0);
tobyspark 0:87aab40d5806 170
tobyspark 0:87aab40d5806 171 resolutionMenu.title = "Resolution";
tobyspark 0:87aab40d5806 172 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionVGA, kTV1ResolutionVGA, 5);
tobyspark 0:87aab40d5806 173 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionSVGA, kTV1ResolutionSVGA, 5);
tobyspark 0:87aab40d5806 174 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionXGAp60, kTV1ResolutionXGAp60, 5);
tobyspark 0:87aab40d5806 175 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionWSXGAPLUSp60, kTV1ResolutionWSXGAPLUSp60, 5);
tobyspark 0:87aab40d5806 176 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionWUXGAp60, kTV1ResolutionWUXGAp60, 5);
tobyspark 0:87aab40d5806 177 resolutionMenu.addMenuItem(kTV1ResolutionDescription720p60, kTV1Resolution720p60, 5);
tobyspark 0:87aab40d5806 178 resolutionMenu.addMenuItem(kTV1ResolutionDescription1080p60, kTV1Resolution1080p60, 5);
tobyspark 0:87aab40d5806 179 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionDualHeadSVGAp60, kTV1ResolutionDualHeadSVGAp60, 0);
tobyspark 0:87aab40d5806 180 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionDualHeadXGAp60, kTV1ResolutionDualHeadXGAp60, 0);
tobyspark 0:87aab40d5806 181 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionTripleHeadVGAp60, kTV1ResolutionTripleHeadVGAp60, 0);
tobyspark 0:87aab40d5806 182
tobyspark 1:f9fca21102e0 183 commsMenu.title = "Network Mode";
tobyspark 1:f9fca21102e0 184 enum { commsNone, commsOSC, commsArtNet, commsDMX};
tobyspark 1:f9fca21102e0 185 commsMenu.addMenuItem("None", commsNone, 0);
tobyspark 1:f9fca21102e0 186 commsMenu.addMenuItem("OSC", commsOSC, 0);
tobyspark 1:f9fca21102e0 187 commsMenu.addMenuItem("ArtNet", commsArtNet, 0);
tobyspark 1:f9fca21102e0 188 commsMenu.addMenuItem("DMX", commsDMX, 0);
tobyspark 1:f9fca21102e0 189
tobyspark 0:87aab40d5806 190 mainMenu.title = "Main Menu";
tobyspark 0:87aab40d5806 191 mainMenu.addMenuItem(&mixModeMenu);
tobyspark 0:87aab40d5806 192 mainMenu.addMenuItem(&resolutionMenu);
tobyspark 1:f9fca21102e0 193 mainMenu.addMenuItem(&commsMenu);
tobyspark 0:87aab40d5806 194
tobyspark 0:87aab40d5806 195 selectedMenu = &mainMenu;
tobyspark 0:87aab40d5806 196 lastSelectedMenu = &mainMenu;
tobyspark 0:87aab40d5806 197
tobyspark 0:87aab40d5806 198 // Misc I/O stuff
tobyspark 0:87aab40d5806 199
tobyspark 0:87aab40d5806 200 fadeAPO.period(0.001);
tobyspark 0:87aab40d5806 201 fadeBPO.period(0.001);
tobyspark 0:87aab40d5806 202
tobyspark 0:87aab40d5806 203 // TVOne setup
tobyspark 0:87aab40d5806 204
tobyspark 0:87aab40d5806 205 bool ok = false;
tobyspark 0:87aab40d5806 206
tobyspark 0:87aab40d5806 207 // horrid, horrid HDCP
tobyspark 0:87aab40d5806 208 ok = tvOne.setHDCPOff();
tobyspark 0:87aab40d5806 209
tobyspark 0:87aab40d5806 210 std::string sendOK = ok ? "Sent: HDCP Off" : "Send Error: HDCP Off";
tobyspark 0:87aab40d5806 211
tobyspark 0:87aab40d5806 212 // display menu and framing lines
tobyspark 0:87aab40d5806 213 screen.horizLineToBuffer(kMenuLine1*pixInPage - 1);
tobyspark 0:87aab40d5806 214 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 215 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 216 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 217 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 218 screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage);
tobyspark 1:f9fca21102e0 219 screen.horizLineToBuffer(kCommsStatusLine*pixInPage - 1);
tobyspark 1:f9fca21102e0 220 screen.clearBufferRow(kCommsStatusLine);
tobyspark 1:f9fca21102e0 221 screen.textToBuffer(commsMenu.selectedString(), kCommsStatusLine);
tobyspark 1:f9fca21102e0 222 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 1:f9fca21102e0 223 screen.textToBuffer(sendOK, kTVOneStatusLine);
tobyspark 0:87aab40d5806 224 screen.sendBuffer();
tobyspark 0:87aab40d5806 225
tobyspark 0:87aab40d5806 226
tobyspark 0:87aab40d5806 227 //// CONTROLS TEST
tobyspark 0:87aab40d5806 228
tobyspark 0:87aab40d5806 229 while (0) {
tobyspark 0:87aab40d5806 230 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 231 }
tobyspark 0:87aab40d5806 232
tobyspark 0:87aab40d5806 233 //// MIXER RUN
tobyspark 0:87aab40d5806 234
tobyspark 0:87aab40d5806 235 while (1) {
tobyspark 0:87aab40d5806 236
tobyspark 1:f9fca21102e0 237 //// Task background things
tobyspark 1:f9fca21102e0 238 if (commsMenu.selectedPayload1() == commsOSC)
tobyspark 1:f9fca21102e0 239 {
tobyspark 1:f9fca21102e0 240 Net::poll();
tobyspark 1:f9fca21102e0 241 }
tobyspark 1:f9fca21102e0 242
tobyspark 0:87aab40d5806 243 //// MENU
tobyspark 0:87aab40d5806 244
tobyspark 0:87aab40d5806 245 int menuChange = menuEnc.getChange();
tobyspark 0:87aab40d5806 246
tobyspark 0:87aab40d5806 247 // Update GUI
tobyspark 0:87aab40d5806 248 if (menuChange != 0)
tobyspark 0:87aab40d5806 249 {
tobyspark 0:87aab40d5806 250 if (debug) debug->printf("Menu changed by %i\r\n", menuChange);
tobyspark 0:87aab40d5806 251
tobyspark 0:87aab40d5806 252 *selectedMenu = selectedMenu->selectedIndex() + menuChange;
tobyspark 0:87aab40d5806 253
tobyspark 0:87aab40d5806 254 // update OLED line 2 here
tobyspark 0:87aab40d5806 255 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 256 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 257
tobyspark 0:87aab40d5806 258 if (debug) debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 259
tobyspark 0:87aab40d5806 260 }
tobyspark 0:87aab40d5806 261
tobyspark 0:87aab40d5806 262 // Action menu item
tobyspark 0:87aab40d5806 263 if (menuEnc.hasPressed())
tobyspark 0:87aab40d5806 264 {
tobyspark 0:87aab40d5806 265 if (debug) debug->printf("Action Menu Item!\r\n");
tobyspark 0:87aab40d5806 266
tobyspark 0:87aab40d5806 267 // Are we changing menus?
tobyspark 0:87aab40d5806 268 if (selectedMenu->type() == menuOfMenus)
tobyspark 0:87aab40d5806 269 {
tobyspark 0:87aab40d5806 270 // point selected menu to the new menu
tobyspark 0:87aab40d5806 271 // FIXME. Make this function abstract virtual of base class or get dynamic_cast working. BTW: C++ sucks / Obj-c rocks / Right now.
tobyspark 0:87aab40d5806 272 if (selectedMenu == &mainMenu) selectedMenu = mainMenu.selectedMenu();
tobyspark 0:87aab40d5806 273 else if (debug) debug->printf("FIXME: You've missed a SPKMenuOfMenus");
tobyspark 0:87aab40d5806 274
tobyspark 0:87aab40d5806 275 // reset the selection within that menu to the first position
tobyspark 0:87aab40d5806 276 (*selectedMenu) = 0;
tobyspark 0:87aab40d5806 277
tobyspark 0:87aab40d5806 278 // update OLED lines 1&2
tobyspark 0:87aab40d5806 279 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 280 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 281 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 282 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 283
tobyspark 0:87aab40d5806 284 if (debug)
tobyspark 0:87aab40d5806 285 {
tobyspark 0:87aab40d5806 286 debug->printf("\r\n");
tobyspark 0:87aab40d5806 287 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 288 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 289 }
tobyspark 0:87aab40d5806 290 }
tobyspark 0:87aab40d5806 291 // Are we cancelling?
tobyspark 0:87aab40d5806 292 else if (selectedMenu->type() == payload && selectedMenu->selectedIndex() == 0)
tobyspark 0:87aab40d5806 293 {
tobyspark 0:87aab40d5806 294 selectedMenu = lastSelectedMenu;
tobyspark 0:87aab40d5806 295
tobyspark 0:87aab40d5806 296 // update OLED lines 1&2
tobyspark 0:87aab40d5806 297 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 298 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 299 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 300 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 301
tobyspark 0:87aab40d5806 302 if (debug)
tobyspark 0:87aab40d5806 303 {
tobyspark 0:87aab40d5806 304 debug->printf("\r\n");
tobyspark 0:87aab40d5806 305 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 306 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 307 }
tobyspark 0:87aab40d5806 308 }
tobyspark 0:87aab40d5806 309 // With that out of the way, we should be actioning a specific menu's payload?
tobyspark 0:87aab40d5806 310 else if (selectedMenu == &mixModeMenu)
tobyspark 0:87aab40d5806 311 {
tobyspark 0:87aab40d5806 312 bool ok = false;
tobyspark 0:87aab40d5806 313 std::string sentOK;
tobyspark 0:87aab40d5806 314 std::stringstream sentMSG;
tobyspark 0:87aab40d5806 315
tobyspark 0:87aab40d5806 316 // Set keying parameters
tobyspark 0:87aab40d5806 317 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 318 case lumaKey:
tobyspark 0:87aab40d5806 319 ok = setKeyParamsTo(0);
tobyspark 0:87aab40d5806 320 sentMSG << "Keyer Params 0, ";
tobyspark 0:87aab40d5806 321 break;
tobyspark 0:87aab40d5806 322 case chromaKey1:
tobyspark 0:87aab40d5806 323 ok = setKeyParamsTo(1);
tobyspark 0:87aab40d5806 324 sentMSG << "Keyer Params 1, ";
tobyspark 0:87aab40d5806 325 break;
tobyspark 0:87aab40d5806 326 }
tobyspark 0:87aab40d5806 327
tobyspark 0:87aab40d5806 328 // Set keying on or off
tobyspark 0:87aab40d5806 329 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 330 case blend:
tobyspark 0:87aab40d5806 331 case additive:
tobyspark 0:87aab40d5806 332 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false);
tobyspark 0:87aab40d5806 333 sentMSG << "Keyer Off";
tobyspark 0:87aab40d5806 334 break;
tobyspark 0:87aab40d5806 335 case lumaKey:
tobyspark 0:87aab40d5806 336 case chromaKey1:
tobyspark 0:87aab40d5806 337 case chromaKey2:
tobyspark 0:87aab40d5806 338 case chromaKey3:
tobyspark 0:87aab40d5806 339 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true);
tobyspark 0:87aab40d5806 340 sentMSG << "Keyer On";
tobyspark 0:87aab40d5806 341 break;
tobyspark 0:87aab40d5806 342 }
tobyspark 0:87aab40d5806 343
tobyspark 0:87aab40d5806 344 if (ok) sentOK = "Sent:";
tobyspark 0:87aab40d5806 345 else sentOK = "Send Error:";
tobyspark 0:87aab40d5806 346
tobyspark 1:f9fca21102e0 347 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 1:f9fca21102e0 348 screen.textToBuffer(sentOK + sentMSG.str(), kTVOneStatusLine);
tobyspark 0:87aab40d5806 349
tobyspark 0:87aab40d5806 350 if (debug) { debug->printf("Changing mix mode"); }
tobyspark 0:87aab40d5806 351 }
tobyspark 0:87aab40d5806 352 else if (selectedMenu == &resolutionMenu)
tobyspark 0:87aab40d5806 353 {
tobyspark 0:87aab40d5806 354 bool ok = false;
tobyspark 0:87aab40d5806 355
tobyspark 0:87aab40d5806 356 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, resolutionMenu.selectedPayload1());
tobyspark 0:87aab40d5806 357 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedPayload2());
tobyspark 0:87aab40d5806 358 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedPayload2());
tobyspark 0:87aab40d5806 359
tobyspark 0:87aab40d5806 360 std::string sentOK;
tobyspark 0:87aab40d5806 361 if (ok) sentOK = "Sent: ";
tobyspark 0:87aab40d5806 362 else sentOK = "Send Error: ";
tobyspark 0:87aab40d5806 363
tobyspark 0:87aab40d5806 364 std::stringstream sentMSG;
tobyspark 0:87aab40d5806 365 sentMSG << "Res " << resolutionMenu.selectedPayload1() << ", EDID " << resolutionMenu.selectedPayload2();
tobyspark 0:87aab40d5806 366
tobyspark 1:f9fca21102e0 367 screen.clearBufferRow(kTVOneStatusLine);
tobyspark 1:f9fca21102e0 368 screen.textToBuffer(sentOK + sentMSG.str(), kTVOneStatusLine);
tobyspark 0:87aab40d5806 369
tobyspark 0:87aab40d5806 370 if (debug) { debug->printf("Changing resolution"); }
tobyspark 0:87aab40d5806 371 }
tobyspark 1:f9fca21102e0 372 else if (selectedMenu == &commsMenu)
tobyspark 1:f9fca21102e0 373 {
tobyspark 1:f9fca21102e0 374 std::string commsType = "Network: --";
tobyspark 1:f9fca21102e0 375 std::stringstream commsStatus;
tobyspark 1:f9fca21102e0 376
tobyspark 1:f9fca21102e0 377 // Tear down any existing comms
tobyspark 1:f9fca21102e0 378 // This is the action of commsNone
tobyspark 1:f9fca21102e0 379 // And also clears the way for other comms actions
tobyspark 1:f9fca21102e0 380 if (osc) {delete osc; osc = NULL;}
tobyspark 1:f9fca21102e0 381 if (ethernet) {delete ethernet; ethernet = NULL;}
tobyspark 1:f9fca21102e0 382
tobyspark 1:f9fca21102e0 383 if (commsMenu.selectedPayload1() == commsOSC)
tobyspark 1:f9fca21102e0 384 {
tobyspark 1:f9fca21102e0 385 commsType = "OSC: ";
tobyspark 1:f9fca21102e0 386
tobyspark 1:f9fca21102e0 387 ethernet = new EthernetNetIf(
tobyspark 1:f9fca21102e0 388 IpAddr(kOSCMbedIPAddress),
tobyspark 1:f9fca21102e0 389 IpAddr(kOSCMbedSubnetMask),
tobyspark 1:f9fca21102e0 390 IpAddr(kOSCMbedGateway),
tobyspark 1:f9fca21102e0 391 IpAddr(kOSCMbedDNS)
tobyspark 1:f9fca21102e0 392 );
tobyspark 2:50043054e4f7 393 printf("ethernet created");
tobyspark 1:f9fca21102e0 394 EthernetErr ethError = ethernet->setup();
tobyspark 1:f9fca21102e0 395 if(ethError)
tobyspark 1:f9fca21102e0 396 {
tobyspark 1:f9fca21102e0 397 if (debug) debug->printf("Ethernet setup error, %d", ethError);
tobyspark 1:f9fca21102e0 398 commsStatus << "Ethernet setup failed";
tobyspark 1:f9fca21102e0 399 // commsMenu = commsNone; //FIXME: this should set the selected menu item to none, but errors. wtf?
tobyspark 1:f9fca21102e0 400 // break out of here. this setup should be a function that returns a boolean
tobyspark 1:f9fca21102e0 401 }
tobyspark 1:f9fca21102e0 402
tobyspark 1:f9fca21102e0 403 printf("ethernet setup done");
tobyspark 1:f9fca21102e0 404
tobyspark 1:f9fca21102e0 405 osc = new OSCClass();
tobyspark 1:f9fca21102e0 406 osc->messageReceivedCallback.attach(&oscCallback);
tobyspark 1:f9fca21102e0 407 osc->begin(kOSCMbedPort);
tobyspark 1:f9fca21102e0 408
tobyspark 2:50043054e4f7 409 commsStatus << "Listening " << kOSCMbedPort;
tobyspark 1:f9fca21102e0 410
tobyspark 1:f9fca21102e0 411 printf("osc done");
tobyspark 1:f9fca21102e0 412 }
tobyspark 1:f9fca21102e0 413 else if (commsMenu.selectedPayload1() == commsArtNet)
tobyspark 1:f9fca21102e0 414 {
tobyspark 1:f9fca21102e0 415
tobyspark 1:f9fca21102e0 416 }
tobyspark 1:f9fca21102e0 417 else if (commsMenu.selectedPayload1() == commsDMX)
tobyspark 1:f9fca21102e0 418 {
tobyspark 1:f9fca21102e0 419
tobyspark 1:f9fca21102e0 420 }
tobyspark 1:f9fca21102e0 421
tobyspark 1:f9fca21102e0 422 screen.clearBufferRow(kCommsStatusLine);
tobyspark 1:f9fca21102e0 423 screen.textToBuffer(commsType + commsStatus.str(), kCommsStatusLine);
tobyspark 1:f9fca21102e0 424 }
tobyspark 0:87aab40d5806 425 else
tobyspark 0:87aab40d5806 426 {
tobyspark 0:87aab40d5806 427 if (debug) { debug->printf("Warning: No action identified"); }
tobyspark 0:87aab40d5806 428 }
tobyspark 0:87aab40d5806 429 }
tobyspark 0:87aab40d5806 430
tobyspark 2:50043054e4f7 431 // Send any updates to the display
tobyspark 2:50043054e4f7 432 screen.sendBuffer();
tobyspark 1:f9fca21102e0 433
tobyspark 0:87aab40d5806 434
tobyspark 0:87aab40d5806 435 //// MIX
tobyspark 0:87aab40d5806 436
tobyspark 0:87aab40d5806 437 bool updateFade = false;
tobyspark 0:87aab40d5806 438
tobyspark 0:87aab40d5806 439 // Get new states of tap buttons, remembering at end of loop() assign these current values to the previous variables
tobyspark 0:87aab40d5806 440 const bool tapLeft = (tapLeftDIN) ? false : true;
tobyspark 0:87aab40d5806 441 const bool tapRight = (tapRightDIN) ? false : true;
tobyspark 0:87aab40d5806 442
tobyspark 0:87aab40d5806 443 // We're going to cache the analog in reads, as have seen wierdness otherwise
tobyspark 0:87aab40d5806 444 const float xFadeAINCached = xFadeAIN.read();
tobyspark 0:87aab40d5806 445 const float fadeUpAINCached = fadeUpAIN.read();
tobyspark 0:87aab40d5806 446
tobyspark 0:87aab40d5806 447 // When a tap is depressed, we can ignore any move of the crossfader but not fade to black
tobyspark 0:87aab40d5806 448 if (tapLeft || tapRight)
tobyspark 0:87aab40d5806 449 {
tobyspark 0:87aab40d5806 450 // If both are pressed, which was not pressed in the last loop?
tobyspark 0:87aab40d5806 451 if (tapLeft && tapRight)
tobyspark 0:87aab40d5806 452 {
tobyspark 0:87aab40d5806 453 if (!tapLeftPrevious) xFade = 0;
tobyspark 0:87aab40d5806 454 if (!tapRightPrevious) xFade = 1;
tobyspark 0:87aab40d5806 455 }
tobyspark 0:87aab40d5806 456 // If just one is pressed, is this it going high or the other going low?
tobyspark 0:87aab40d5806 457 else if (tapLeft && (!tapLeftPrevious || tapRightPrevious)) xFade = 0;
tobyspark 0:87aab40d5806 458 else if (tapRight && (!tapRightPrevious || tapLeftPrevious)) xFade = 1;
tobyspark 0:87aab40d5806 459 }
tobyspark 0:87aab40d5806 460 else xFade = fadeCalc(xFadeAINCached, xFadeTolerance);
tobyspark 0:87aab40d5806 461
tobyspark 0:87aab40d5806 462 fadeUp = 1.0 - fadeCalc(fadeUpAINCached, fadeUpTolerance);
tobyspark 0:87aab40d5806 463
tobyspark 0:87aab40d5806 464 // WISH: Really, we should have B at 100% and A fading in over that, with fade to black implemented as a fade in black layer on top of that correct mix.
tobyspark 0:87aab40d5806 465 // There is no way to implement that though, and the alphas get messy, so this is the only way (afaik).
tobyspark 0:87aab40d5806 466
tobyspark 0:87aab40d5806 467 // Calculate new A&B fade percents
tobyspark 0:87aab40d5806 468 int newFadeAPercent = 0;
tobyspark 0:87aab40d5806 469 int newFadeBPercent = 0;
tobyspark 0:87aab40d5806 470
tobyspark 0:87aab40d5806 471 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 472 case blend:
tobyspark 0:87aab40d5806 473 case additive:
tobyspark 0:87aab40d5806 474 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 475 newFadeBPercent = xFade * fadeUp * 100.0;
tobyspark 0:87aab40d5806 476 break;
tobyspark 0:87aab40d5806 477 case lumaKey:
tobyspark 0:87aab40d5806 478 case chromaKey1:
tobyspark 0:87aab40d5806 479 case chromaKey2:
tobyspark 0:87aab40d5806 480 case chromaKey3:
tobyspark 0:87aab40d5806 481 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 482 newFadeBPercent = fadeUp * 100.0;
tobyspark 0:87aab40d5806 483 break;
tobyspark 0:87aab40d5806 484 }
tobyspark 0:87aab40d5806 485
tobyspark 0:87aab40d5806 486 // Send to TVOne if percents have changed
tobyspark 0:87aab40d5806 487 if (newFadeAPercent != fadeAPercent) {
tobyspark 0:87aab40d5806 488 fadeAPercent = newFadeAPercent;
tobyspark 0:87aab40d5806 489 updateFade = true;
tobyspark 0:87aab40d5806 490
tobyspark 0:87aab40d5806 491 fadeAPO = fadeAPercent / 100.0;
tobyspark 0:87aab40d5806 492 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 0:87aab40d5806 493 }
tobyspark 0:87aab40d5806 494
tobyspark 0:87aab40d5806 495 if (newFadeBPercent != fadeBPercent) {
tobyspark 0:87aab40d5806 496 fadeBPercent = newFadeBPercent;
tobyspark 0:87aab40d5806 497 updateFade = true;
tobyspark 0:87aab40d5806 498
tobyspark 0:87aab40d5806 499 fadeBPO = fadeBPercent / 100.0;
tobyspark 0:87aab40d5806 500 tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 0:87aab40d5806 501 }
tobyspark 0:87aab40d5806 502
tobyspark 0:87aab40d5806 503 if (updateFade && debug) {
tobyspark 0:87aab40d5806 504 debug->printf("\r\n");
tobyspark 0:87aab40d5806 505 //debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAIN.read(), fadeUpAIN.read());
tobyspark 0:87aab40d5806 506 debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAINCached, fadeUpAINCached);
tobyspark 0:87aab40d5806 507 debug->printf("xFade = %3f fadeUp = %3f fadeA% = %i fadeB% = %i \r\n", xFade, fadeUp, fadeAPercent, fadeBPercent);
tobyspark 0:87aab40d5806 508 }
tobyspark 0:87aab40d5806 509
tobyspark 0:87aab40d5806 510 // END OF LOOP - Reset
tobyspark 0:87aab40d5806 511 tapLeftPrevious = tapLeft;
tobyspark 0:87aab40d5806 512 tapRightPrevious = tapRight;
tobyspark 0:87aab40d5806 513 }
tobyspark 0:87aab40d5806 514 }