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
Revision 34:69dfe64e7e6b, committed 2012-11-05
- Comitter:
- tobyspark
- Date:
- Mon Nov 05 20:06:20 2012 +0000
- Parent:
- 33:e6672a9bd571
- Child:
- 35:d5d9f0838f99
- Commit message:
- EDID Internal Sorted: Uploads Matrox EDID and sets either that, HDMI or DVI. Improved missing source handling.
Changed in this revision
--- a/SPK-TVOne.lib Sun Nov 04 13:35:46 2012 +0000 +++ b/SPK-TVOne.lib Mon Nov 05 20:06:20 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/tobyspark/code/SPK-TVOne/#4d659b89a457 +http://mbed.org/users/tobyspark/code/SPK-TVOne/#da403a01f9ef
--- a/SPKDF_ini.h Sun Nov 04 13:35:46 2012 +0000 +++ b/SPKDF_ini.h Mon Nov 05 20:06:20 2012 +0000 @@ -1,3 +1,17 @@ +########################################################################## +# _____ _____ _____ _____ _____ ____ _____ _____ _____ _____ _____ # +# | __| _ | _ | __ | | | | \| __| | | __| __| __ | # +# |__ | __| | -| -| | | | __| | |__ | __| -| # +# |_____|__| |__|__|__|__|__|__| |____/|__| |_____|_____|_____|__|__| # +# # +######################################### A PROJECT BY TOBY HARRIS ####### + +### KEYS +# +# Name = What is shown in menu +# MinY...MaxV = As per TVOne keyer settings. +# Note these are super sensitive, one laptop will have slightly different numbers to another to acheive otherwise the same -- ie. pure blue -- key. + [Key1] Name = Lumakey MinY = 0 @@ -16,30 +30,43 @@ MinV = 114 MaxV = 121 +# Edit the above, or add your own keys here, up to Key99 + +### RESOLUTIONS +# +# Name = What is shown in menu +# Number = Resolution number in TVOne. ie. what would be set in Menu > Outputs > Set Resolution +# EDID Number = The EDID to use on the inputs, which what your computer will think its connected to. ie. what would be set in Menu > Windows > Display Emul. EDID +# +# EDID numbers are as follows +# 0 = Mem1, 1 = Mem2, 2 = Mem3, +# 3 = Mem4 which we use for Matrox EDID, its uploaded by the controller as part of 'Conform Processor' +# 4 = 3D, 5 = HDMI, 6 = DVI, 7 = Monitor Passthrough + [Resolution1] Name = VGA (640x480) Number = 8 -EDIDNumber = 5 +EDIDNumber = 6 [Resolution2] Name = SVGA (800x600) Number = 18 -EDIDNumber = 5 +EDIDNumber = 6 [Resolution3] Name = XGA (1024x768) Number = 28 -EDIDNumber = 5 +EDIDNumber = 6 [Resolution4] Name = WSXGA+ (1650x1050) -Number = 83 -EDIDNumber = 5 +Number = 85 +EDIDNumber = 6 [Resolution5] Name = WUXGA (1920x1200) -Number = 105 -EDIDNumber = 5 +Number = 115 +EDIDNumber = 6 [Resolution6] Name = HD 720P60 (1280x720) @@ -52,16 +79,18 @@ EDIDNumber = 5 [Resolution8] -Name = Dual head SVGA (1600*600) -Number = 123 -EDIDNumber = 5 +Name = Dual head SVGA (1600x600) +Number = 75 +EDIDNumber = 3 [Resolution9] Name = Dual head XGA (2048x768) -Number = 124 -EDIDNumber = 5 +Number = 123 +EDIDNumber = 3 [Resolution10] Name = Triple head VGA (1920x480) -Number = 125 -EDIDNumber = 5 +Number = 90 +EDIDNumber = 3 + +# Edit the above, or add your own keys here, up to Resolution99 \ No newline at end of file
--- a/main.cpp Sun Nov 04 13:35:46 2012 +0000 +++ b/main.cpp Mon Nov 05 20:06:20 2012 +0000 @@ -116,8 +116,8 @@ //// DEBUG // Comment out one or the other... -//Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial -Serial *debug = NULL; // For release (no debugging) +Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial +//Serial *debug = NULL; // For release (no debugging) //// SOFT RESET @@ -197,14 +197,15 @@ int keyerParamsSet = -1; // last keyParams index uploaded to unit // TVOne input sources stable flag -bool tvOneRGB1Stable = true; // init true as this is conformed state of mixer, ie. RGB1 not SIS1 -bool tvOneRGB2Stable = true; +bool tvOneRGB1Stable = false; +bool tvOneRGB2Stable = false; // TVOne behaviour flags bool tvOneHDCPOn = false; -bool tvOneEDIDPassthrough = true; +bool tvOneEDIDPassthrough = false; const int32_t EDIDPassthroughSlot = 7; + void processOSCIn(float &xFade, float &fadeUp) { string statusMessage; @@ -338,18 +339,26 @@ return pos; } -bool handleTVOneSources(bool updateScreenOverride = false) +bool handleTVOneSources() { bool ok = true; int32_t payload = 0; ok = ok && tvOne.readCommand(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload); - bool RGB1 = (payload == 1); + bool RGB1 = (payload == 1); ok = ok && tvOne.readCommand(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceSourceStable, payload); bool RGB2 = (payload == 1); + ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, payload); + int sourceA = payload; + + ok = ok && tvOne.readCommand(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, payload); + int sourceB = payload; + + if (debug) debug->printf("HandleTVOneSources: RGB1: %i, RGB2: %i, sourceA: %#x, sourceB: %#i \r\n", RGB1, RGB2, sourceA, sourceB); + string tvOneDetectString; if (!ok) { @@ -366,19 +375,24 @@ tvOneDetectString = "TVOne: OK"; } - if (RGB1 && !tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1); - if (RGB2 && !tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2); - if (!RGB1 && tvOneRGB1Stable) tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS1); - if (!RGB2 && tvOneRGB2Stable) tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2); - - if (updateScreenOverride || (RGB1 != tvOneRGB1Stable || RGB2 != tvOneRGB2Stable)) + screen.clearBufferRow(kTVOneStatusLine); + screen.textToBuffer(tvOneDetectString, kTVOneStatusLine); + + // Assign appropriate source depending on whether DVI input is good + // If that assign command completes ok, and the DVI input is good, finally flag the unit has had a live source + // Note any further losses on this input will be handled by the unit holding the last frame, so we don't need to switch back to SIS. + if (ok && !tvOneRGB1Stable) { - screen.clearBufferRow(kTVOneStatusLine); - screen.textToBuffer(tvOneDetectString, kTVOneStatusLine); + if (RGB1 && (sourceB != kTV1SourceRGB1)) ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB1); + if (!RGB1 && (sourceB != kTV1SourceSIS2)) ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2); // Wierd: Can't set to SIS1 sometimes. + if (ok && RGB1) tvOneRGB1Stable = true; } - - tvOneRGB1Stable = RGB1; - tvOneRGB2Stable = RGB2; + if (ok && !tvOneRGB2Stable) + { + if (RGB2 && (sourceA != kTV1SourceRGB2)) ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceRGB2); + if (!RGB2 && (sourceA != kTV1SourceSIS2)) ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsWindowSource, kTV1SourceSIS2); + if (ok && RGB2) tvOneRGB2Stable = true; + } return ok; } @@ -500,6 +514,22 @@ ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, 100); ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, 100); + // Upload Matrox EDID to mem4 (ie. index 3). Use this EDID slot when setting Matrox resolutions. + char edidData[256]; + int i; + { + LocalFileSystem local("local"); + FILE *file = fopen("/local/matroxe.did", "r"); // 8.3, avoid .bin as mbed executable + for ( i=0; i<256; i++) + { + int edidByte = fgetc(file); + if (edidByte == EOF) break; + else edidData[i] = edidByte; + } + fclose(file); + } + ok = ok && tvOne.uploadEDID(edidData, i, 3); + // Save current state for power on ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1); @@ -635,12 +665,11 @@ screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage); screen.horizLineToBuffer(kCommsStatusLine*pixInPage - 1); screen.clearBufferRow(kTVOneStatusLine); - screen.textToBuffer("TVOne: OK", kTVOneStatusLine); // handleTVOneSources may update this + screen.textToBuffer("TVOne: OK", kTVOneStatusLine); // handleTVOneSources will update this // If we do not have two solid sources, act on this as we rely on the window having a source for crossfade behaviour // Once we've had two solid inputs, don't check any more as we're ok as the unit is set to hold on last frame. - // This is set to update kTVOneStatusLine regardless - bool ok = handleTVOneSources(true); + bool ok = handleTVOneSources(); // Update display before starting mixer loop screen.sendBuffer(); @@ -962,8 +991,10 @@ screen.textToBuffer(sendOK, kTVOneStatusLine); } else if (advancedMenu.selectedItem().payload.command[0] == advancedTestSources) - { - handleTVOneSources(true); + { + tvOneRGB1Stable = false; + tvOneRGB2Stable = false; + handleTVOneSources(); } else if (advancedMenu.selectedItem().payload.command[0] == advancedConformProcessor) { @@ -1002,6 +1033,8 @@ } } + // Send any updates to the display + screen.sendBuffer(); //// MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIX MIXMIX MIX MIXMIX MIX MIX MIX MIX MIXMIX MIX MIX @@ -1180,14 +1213,11 @@ processDMXOut(xFade, fadeUp); } - // If we're not actively mixing, we can do any housekeeping... - if (!updateFade) + // Housekeeping + if (tvOne.millisSinceLastCommandSent() > 1500) { - // We should check up on any source flagged unstable + // We should check up on any source that hasn't ever been stable if (!tvOneRGB1Stable || !tvOneRGB2Stable) handleTVOneSources(); } - - // Send any updates to the display - screen.sendBuffer(); } } \ No newline at end of file
--- a/spk_settings.h Sun Nov 04 13:35:46 2012 +0000 +++ b/spk_settings.h Mon Nov 05 20:06:20 2012 +0000 @@ -50,23 +50,23 @@ resolutionNames.push_back(kTV1ResolutionDescriptionVGA); resolutionIndexes.push_back(kTV1ResolutionVGA); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(6); resolutionNames.push_back(kTV1ResolutionDescriptionSVGA); resolutionIndexes.push_back(kTV1ResolutionSVGA); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(6); resolutionNames.push_back(kTV1ResolutionDescriptionXGAp60); resolutionIndexes.push_back(kTV1ResolutionXGAp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(6); resolutionNames.push_back(kTV1ResolutionDescriptionWSXGAPLUSp60); resolutionIndexes.push_back(kTV1ResolutionWSXGAPLUSp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(6); resolutionNames.push_back(kTV1ResolutionDescriptionWUXGAp60); resolutionIndexes.push_back(kTV1ResolutionWUXGAp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(6); resolutionNames.push_back(kTV1ResolutionDescription720p60); resolutionIndexes.push_back(kTV1Resolution720p60); @@ -78,15 +78,15 @@ resolutionNames.push_back(kTV1ResolutionDescriptionDualHeadSVGAp60); resolutionIndexes.push_back(kTV1ResolutionDualHeadSVGAp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(4); resolutionNames.push_back(kTV1ResolutionDescriptionDualHeadXGAp60); resolutionIndexes.push_back(kTV1ResolutionDualHeadXGAp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(4); resolutionNames.push_back(kTV1ResolutionDescriptionTripleHeadVGAp60); resolutionIndexes.push_back(kTV1ResolutionTripleHeadVGAp60); - resolutionEDIDIndexes.push_back(5); + resolutionEDIDIndexes.push_back(4); } string keyerParamName (int index)