The codebase to run the *spark d-fuser controller www.sparkav.co.uk/dvimixer

Dependencies:   SPK-TVOne DMX DmxArtNet NetServicesMin OSC PinDetect mRotaryEncoder iniparser mbed spk_oled_ssd1305 filter

Committer:
tobyspark
Date:
Mon Apr 23 09:30:50 2012 +0000
Revision:
4:d5ff91b66357
Parent:
3:033d2b7768f3
Child:
5:f8b285ca41ba
pinouts for board v3.0b3

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