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

Files at this revision

API Documentation at this revision

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

SPK-TVOne.lib Show annotated file Show diff for this revision Revisions of this file
SPKDF_ini.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
spk_settings.h Show annotated file Show diff for this revision Revisions of this file
--- 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)