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:
Wed Mar 14 00:35:15 2012 +0000
Revision:
1:f9fca21102e0
Parent:
0:87aab40d5806
Child:
2:50043054e4f7
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). ;

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