Opened 14 years ago

Closed 14 years ago

#973 closed patch (invalid)

DiSEqC switch support behind a positioner

Reported by: zdzisekg@… Owned by: danielk
Priority: minor Milestone: 0.20
Component: mythtv Version: head
Severity: low Keywords: diseqc positioner
Cc: Ticket locked: no

Description

This patch was created by me out of necessity. It supports a diseqc switch behind a positioner as well as it fixes one or two other things that I thought were incorrect (refer to the comments within the patch). It also changes/removes some functions, but all current functionality is preserved. The diseqc port behind the positioner can be configured from within the "input connection" menu. I'm hardly a c++ coder so this patch could use some additional testing or to be beutified, but it does work for me so I thought I share it.

diff -Naur mythtv/libs/libmythtv/dvbdiseqc.cpp mythtv-diseqc/libs/libmythtv/dvbdiseqc.cpp
--- mythtv/libs/libmythtv/dvbdiseqc.cpp	2006-01-07 15:19:28.000000000 -0600
+++ mythtv-diseqc/libs/libmythtv/dvbdiseqc.cpp	2006-01-07 22:12:10.000000000 -0600
@@ -13,6 +13,8 @@
  *          - DiSEqC 1.0 - 1.1.
  *      Kenneth Aafloy (ke-aa at frisurf.no)
  *          - Initial framework.
+ *      Zdzislaw Gorlicki (zdzisekg at yahoo.com
+ *          - DiSEqC 1.2/1.3 + switch
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -84,22 +86,29 @@
             break;
         case 6: // 1.2 Positioner (HH Motor)
             if (!PositionerGoto(tuning,reset,havetuned))
-		return false;
+                return false;
             break;
         case 7: // 1.3 Positioner (HH Motor with USALS)
             if (!PositionerGotoAngular(tuning,reset,havetuned))
-		return false;
+                return false;
             break;
         case 8: // v1.1 10 Way
             if (!Diseqc1xSwitch(tuning, reset, havetuned, 10))
                 return false;
             break;
- 
+        case 10: // 1.2 Positioner (HH Motor with a switch behind it)
+            if (!PositionerGoto(tuning,reset,havetuned))
+                return false;
+            break;
+        case 11: // 1.3 Positioner (HH Motor with USALS and with a switch behind it)
+            if (!PositionerGotoAngular(tuning, reset, havetuned))
+                return false;
+            break;
         default:
             VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported DiSEqC type("
                     <<tuning.diseqc_type<<")");
     }
-    
+
     return true;
 }
 
@@ -156,8 +165,9 @@
             VERBOSE(VB_IMPORTANT, LOC_ERR +
                     "Tone Switches only support two ports.");
 
+        // I think SEC_MINI_A is 0 in DB so we should compare against that. right?
         if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST,
-                  (tuning.diseqc_port == 1 ? SEC_MINI_A : SEC_MINI_B )) < 0)
+                  (tuning.diseqc_port == 0 ? SEC_MINI_A : SEC_MINI_B )) < 0)
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR +
                     "Setting Tone Switch failed." + ENO);
@@ -175,36 +185,85 @@
 /*****************************************************************************
                     Diseqc 1.x Compatible Methods
  ****************************************************************************/
+bool DVBDiSEqC::DiseqcReset()
+{
+    struct dvb_diseqc_master_cmd reset_cmd =
+        {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3};
+ 
+    struct dvb_diseqc_master_cmd init_cmd =
+        {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3};
 
-bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd)
+    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "Setup: Sending init command failed." + ENO);
+        return false;
+    }
+    usleep(DISEQC_LONG_WAIT);
+
+    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "Setup: Sending reset command failed." + ENO);
+        return false;
+    }
+    usleep(DISEQC_LONG_WAIT);
+
+    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "Setup: Sending init command failed." + ENO);
+        return false;
+    }
+    usleep(DISEQC_LONG_WAIT);
+
+    return true;
+}
+
+
+bool DVBDiSEqC::SendDiSEqCPrepareBus(DVBTuning& tuning, bool reset)
 {
-    // Turn off tone burst
-    if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 
+    // Reset "visible" DiSEqC switches or LNBs
+    if (reset)
+    {
+        if (!DiseqcReset())
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
+            return false;
+        }
+    }
+
+    // Turn off Continuous tone
+    if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
         return false;
     }
+    else
+    {
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Continuous Tone set to: OFF"));
+    }
 
-/* 
-   Old version of the code set the voltage to 13V everytime.
-   After looking at the EutelSat specs I saw no reason that
-   this was done. I have tested this with my DiSEqC switch
-   and all is fine. 
-*/
-
-    if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) == -1) 
+    //  Set Voltage
+    if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) == -1)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_VOLTAGE failed" + ENO);
         return false;
-    }   
+    }
+    else
+    {
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Voltage set to: %1")
+                .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
+    }
 
-    usleep(DISEQC_SHORT_WAIT);
+    return true;
+}
 
-    VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
-            .arg(cmd.msg[0], 2, 16)
-            .arg(cmd.msg[1], 2, 16)
-            .arg(cmd.msg[2], 2, 16)
-            .arg(cmd.msg[3], 2, 16));
+
+bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd)
+{
+    // Send the DiSEqC command
+    usleep(DISEQC_SHORT_WAIT);
 
     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
     {
@@ -212,160 +271,121 @@
                 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
         return false;
     }
+    else
+    {
+        if ((tuning.diseqc_type == 7) || (tuning.diseqc_type == 11)) 
+        {
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Sent 1.3 Command: %1 %2 %3 %4 %5")
+                .arg(cmd.msg[FRAME], 2, 16)
+                .arg(cmd.msg[ADDRESS], 2, 16)
+                .arg(cmd.msg[COMMAND], 2, 16)
+                .arg(cmd.msg[DATA_1], 2, 16)
+                .arg(cmd.msg[DATA_2], 2, 16));
+        }
+        else
+        {
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Sent 1.0 Command: %1 %2 %3 %4")
+                .arg(cmd.msg[FRAME], 2, 16)
+                .arg(cmd.msg[ADDRESS], 2, 16)
+                .arg(cmd.msg[COMMAND], 2, 16)
+                .arg(cmd.msg[DATA_1], 2, 16));
+        }
+    }
 
-    usleep(DISEQC_SHORT_WAIT);
-
-    // Check to see if its a 1.1 or 1.2 device. If so repeat the message repeats times.
+    // Check to see if its a 1.1, 1.2 or 1.3 device. If so repeat the message repeats times.
     if ((tuning.diseqc_type == 3) || (tuning.diseqc_type == 5) || 
-        (tuning.diseqc_type == 6) || (tuning.diseqc_type == 7)) 
+        (tuning.diseqc_type == 6) || (tuning.diseqc_type == 7) || 
+        (tuning.diseqc_type == 10) || (tuning.diseqc_type == 11))
     {
+        int repeats;
+        if((tuning.diseqc_type == 10) || (tuning.diseqc_type == 11))
+        {
+            repeats = repeat + 1;
+        }
+        else
+        {
+            repeats = repeat;
+        }
 
-        int repeats = repeat;
         while (repeats--) 
         {
-
-            if (tuning.diseqc_type == 7)
-            {
-                VERBOSE(VB_CHANNEL, LOC +
-                        QString("Sending 1.3 Repeat Command: %1 %2 %3 %4 %5")
-                        .arg(cmd.msg[0],2,16)
-                        .arg(cmd.msg[1],2,16)
-                        .arg(cmd.msg[2],2,16)
-                        .arg(cmd.msg[3],2,16)
-                        .arg(cmd.msg[4],2,16));
-            }
-            else
-            {
-                VERBOSE(VB_CHANNEL, LOC +
-                        QString("Sending 1.1/1.2 Repeat Command: %1 %2 %3 %4")
-                        .arg(cmd.msg[0],2,16)
-                        .arg(cmd.msg[1],2,16)
-                        .arg(cmd.msg[2],2,16)
-                        .arg(cmd.msg[3],2,16));
-            }
-
-            cmd.msg[0] = CMD_REPEAT;      
+            usleep(DISEQC_SHORT_WAIT);
+            cmd.msg[FRAME] = CMD_REPEAT;
             if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
             {
                 VERBOSE(VB_IMPORTANT, LOC_ERR +
                         "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
                 return false;
             }
-            usleep(DISEQC_SHORT_WAIT);
-     
-            cmd.msg[0] = CMD_FIRST;      
-            if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
+            else
             {
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-                return false;
+                if ((tuning.diseqc_type == 7) || (tuning.diseqc_type == 11)) 
+                {
+                    VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Sent 1.3 Repeat Command: %1 %2 %3 %4 %5")
+                            .arg(cmd.msg[FRAME], 2, 16)
+                            .arg(cmd.msg[ADDRESS], 2, 16)
+                            .arg(cmd.msg[COMMAND], 2, 16)
+                            .arg(cmd.msg[DATA_1], 2, 16)
+                            .arg(cmd.msg[DATA_2], 2, 16));
+                }
+                else
+                {
+                    VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Sent 1.0 Repeat Command: %1 %2 %3 %4")
+                            .arg(cmd.msg[FRAME], 2, 16)
+                            .arg(cmd.msg[ADDRESS], 2, 16)
+                            .arg(cmd.msg[COMMAND], 2, 16)
+                            .arg(cmd.msg[DATA_1], 2, 16));
+                }
             }
-            usleep(DISEQC_SHORT_WAIT);
         }
     }
 
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "FE_DISEQC_SEND_BURST failed" + ENO);
-        return false;
-    }
-
     usleep(DISEQC_SHORT_WAIT);
 
-    if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
-        return false;
-    }
-
     return true;
 }
 
 
-bool DVBDiSEqC::SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd)
+bool DVBDiSEqC::SendDiSEqCSetupBus(DVBTuning& tuning)
 {
-    // Turn off tone burst
-    if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 
+    //Determin the Tone Burst for switches with more then 2 ports and send it
+    //This one I had hard time figuring out from the specs at eutelsat
+    //I guess the tone burst can be interpreted differently for different setups
+    //but in our case (with pure diseqc) it may only affect the LNB
+    if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, 
+              ((tuning.diseqc_port % 2) == 0 ? SEC_MINI_A : SEC_MINI_B )) < 0)
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "FE_DISEQC_SEND_BURST failed" + ENO);
         return false;
     }
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
-            .arg(cmd.msg[0], 2, 16)
-            .arg(cmd.msg[1], 2, 16)
-            .arg(cmd.msg[2], 2, 16)
-            .arg(cmd.msg[3], 2, 16));
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
+    else
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-        return false;
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Tone Burst set to: %1")
+                .arg((tuning.diseqc_port % 2) ? "A" : "B"));
     }
 
     usleep(DISEQC_SHORT_WAIT);
-  
-    int repeats = repeat;
-    while (repeats--) 
-    {
-        VERBOSE(VB_CHANNEL, LOC +
-                QString("Sending 1.1/1.2/1.3 Repeat Command: %1 %2 %3 %4")
-                .arg(cmd.msg[0], 2, 16)
-                .arg(cmd.msg[1], 2, 16)
-                .arg(cmd.msg[2], 2, 16)
-                .arg(cmd.msg[3], 2, 16));
 
-        cmd.msg[0] = CMD_REPEAT;      
-        if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-            return false;
-        }
-        usleep(DISEQC_SHORT_WAIT);
-    
-        cmd.msg[0] = CMD_FIRST;      
-        if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-            return false;
-        }
-        usleep(DISEQC_SHORT_WAIT); 
-    }
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 
+    //finally, set the continuous tone
+    if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1) 
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_DISEQC_SEND_BURST failed" + ENO);
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
         return false;
     }
+    else
+    {
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Continuous Tone set to: %1")
+                .arg(tuning.tone == 0 ? "OFF" : "ON"));
+    }
 
     return true;
 }
 
+
 bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset, 
                                bool& havetuned, uint ports)
 {
-    if (reset) 
-    {
-      	if (!DiseqcReset()) 
-        {
-      	    VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-      	    return false;
-      	}
-    }
-
-    VERBOSE(VB_CHANNEL, LOC +
-            QString("1.1 Switch (%1 ports) - Port %2 - %3 %4")
-            .arg(ports)
-            .arg(tuning.diseqc_port)
-            .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")
-            .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
-
     if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
          prev_tuning.tone != tuning.tone                ||
          prev_tuning.voltage != tuning.voltage        ) || reset)
@@ -399,9 +418,21 @@
                         "Unsupported number of ports for DiSEqC 1.1 Switch");
         }
 
+        if (!SendDiSEqCPrepareBus(tuning, reset)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment I");
+            return false;
+        }
+
         if (!SendDiSEqCMessage(tuning,cmd)) 
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed. -> Segment II");
+            return false;
+        }
+
+        if (!SendDiSEqCSetupBus(tuning)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment III");
             return false;
         }
 
@@ -420,45 +451,13 @@
     return true;
 }
 
-bool DVBDiSEqC::DiseqcReset()
-{
-    struct dvb_diseqc_master_cmd reset_cmd =
-        {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3};
- 
-    struct dvb_diseqc_master_cmd init_cmd =
-        {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3};
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending init command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending reset command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending init command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    return true;
-}
 
 /*****************************************************************************
                             Positioner Control
  *****************************************************************************/
-
+/*
+// Currently not used so not needed, also will need to be modified
+// to be used with current way of sending DiSEqC messages
 bool DVBDiSEqC::PositionerDriveEast(int timestep)
 {
     if (!DiseqcReset()) 
@@ -475,7 +474,7 @@
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
         return false;
     }
-    
+
     return true;
 }
 
@@ -499,45 +498,6 @@
     return true;
 }
 
-bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned)
-{
-    // A reset seems to be required for my positioner to work consistently
-    VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Goto Stored Position %1")
-            .arg(tuning.diseqc_port));
-
-    if ((prev_tuning.diseqc_port != tuning.diseqc_port ||
-         prev_tuning.tone != tuning.tone ||
-         prev_tuning.voltage != tuning.voltage) || reset)
-    {
-        if (!DiseqcReset()) 
-        {
-      	    VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	    return false;
-        }
-        
-        dvb_diseqc_master_cmd cmd = 
-            {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_port, 
-              0x00, 0x00}, 4};
-
-        if (!SendDiSEqCMessage(tuning,cmd)) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-            return false;
-        }
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-        prev_tuning.tone = tuning.tone;
-        prev_tuning.voltage = tuning.voltage;
-    }
-
-    havetuned |=
-        (prev_tuning.diseqc_port == tuning.diseqc_port) &&
-        (prev_tuning.voltage     == tuning.voltage)     &&
-        (prev_tuning.tone        == tuning.tone);
-
-    return true;
-}
-
 bool DVBDiSEqC::PositionerStore(DVBTuning& tuning)
 {
     if (!DiseqcReset()) 
@@ -649,18 +609,90 @@
 
     return true;
 }
+*/
 
 /*****************************************************************************
-                                Diseqc v1.3 (Goto X)
+                             Diseqc Psitioner v1.2
+ ****************************************************************************/
+bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned)
+{
+    if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
+         prev_tuning.tone        != tuning.tone         ||
+         prev_tuning.diseqc_pos  != tuning.diseqc_pos   ||
+         prev_tuning.voltage     != tuning.voltage    ) || reset)
+    {
+        dvb_diseqc_master_cmd cmd_1 = 
+            {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_pos, 
+              0x00, 0x00}, 4};
+
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Goto Stored Position %1")
+                .arg(tuning.diseqc_pos));
+
+        if (!SendDiSEqCPrepareBus(tuning, reset)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment I");
+            return false;
+        }
+
+        if (!SendDiSEqCMessage(tuning,cmd_1)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed. -> Segment II");
+            return false;
+        }
+
+        if (tuning.diseqc_type == 10)
+        {
+            dvb_diseqc_master_cmd cmd_2 =
+                {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4};
+
+            cmd_2.msg[DATA_1] =
+                0xF0 |
+                (((tuning.diseqc_port) * 4) & 0x0F)          |
+                ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) |
+                ((tuning.tone == SEC_TONE_ON) ? 1 : 0);
+
+            if (!SendDiSEqCMessage(tuning,cmd_2)) 
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed. -> Segment II");
+                return false;
+            }
+        }
+
+        if (!SendDiSEqCSetupBus(tuning)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment III");
+            return false;
+        }
+
+        prev_tuning.diseqc_port = tuning.diseqc_port;
+        prev_tuning.diseqc_pos = tuning.diseqc_pos;
+        prev_tuning.tone = tuning.tone;
+        prev_tuning.voltage = tuning.voltage;
+    }
+
+    havetuned |=
+        (prev_tuning.diseqc_port == tuning.diseqc_port) &&
+        (prev_tuning.diseqc_pos  == tuning.diseqc_pos)  &&
+        (prev_tuning.voltage     == tuning.voltage)     &&
+        (prev_tuning.tone        == tuning.tone);
+
+    return true;
+}
+
+
+/*****************************************************************************
+                                Diseqc Positioner v1.3 (Goto X)
  ****************************************************************************/
 
 bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset, 
                                       bool& havetuned) 
 {
+/*
     // TODO: Send information here to FE saying motor is moving and
     //       to expect a longer than average tuning delay
     if (prev_tuning.diseqc_pos != tuning.diseqc_pos)
         VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving");
+*/
 
     int CMD1=0x00 , CMD2=0x00;        // Bytes sent to motor
     double USALS=0.0;
@@ -679,55 +711,76 @@
     double el = atan( (cos(x) - 0.1513 ) /sin(x) );
     double Azimuth = atan((-cos(el)*sin(az))/(sin(el)*cos(P)-cos(el)*sin(P)*cos(az)))* TO_DEC;
 
-//    printf("Offset = %f\n",Azimuth);
-
     if (Azimuth > 0.0)
         CMD1=0xE0;    // East
     else 
         CMD1=0xD0;      // West
 
     USALS = fabs(Azimuth);
- 
+
     while (USALS > 16) 
     {
         CMD1++;
-   	USALS -=16;
+        USALS -=16;
     }
 
     while (USALS >= 1.0) 
     {
-   	CMD2+=0x10;
+        CMD2+=0x10;
         USALS--;
     }
 
     CMD2 += DecimalLookup[(int)round(USALS*10)];
-  
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
 
     // required db changes - get lat and lon for ground station location in db 
     // and added to tuning
     // sat_pos be passed into tuning, and be a float not an int./
 
-    VERBOSE(VB_CHANNEL, LOC + QString("1.3 Motor - Goto Angular Position %1")
-            .arg(tuning.diseqc_pos));
-
     if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
          prev_tuning.tone        != tuning.tone         ||
          prev_tuning.diseqc_pos  != tuning.diseqc_pos   ||
          prev_tuning.voltage     != tuning.voltage    ) || reset)
     {
-
-        dvb_diseqc_master_cmd cmd = 
+        dvb_diseqc_master_cmd cmd_1 = 
             {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, CMD1 , CMD2 , 
               0x00}, 5};
 
-        if (!SendDiSEqCMessage(tuning,cmd)) 
+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Goto Angular Position %1")
+                .arg(tuning.diseqc_pos));
+
+        if (!SendDiSEqCPrepareBus(tuning, reset)) 
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment I");
+            return false;
+        }
+
+        if (!SendDiSEqCMessage(tuning,cmd_1)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed. -> Segment II");
+            return false;
+        }
+
+        if (tuning.diseqc_type == 11)
+        {
+            dvb_diseqc_master_cmd cmd_2 =
+                {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4};
+
+            cmd_2.msg[DATA_1] =
+                0xF0 |
+                (((tuning.diseqc_port) * 4) & 0x0F)          |
+                ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) |
+                ((tuning.tone == SEC_TONE_ON) ? 1 : 0);
+
+            if (!SendDiSEqCMessage(tuning,cmd_2)) 
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed. -> Segment II");
+                return false;
+            }
+        }
+
+        if (!SendDiSEqCSetupBus(tuning)) 
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed -> Segment III");
             return false;
         }
 
@@ -744,4 +797,4 @@
         (prev_tuning.tone        == tuning.tone);
 
     return true;
-}
+}
\ No newline at end of file
diff -Naur mythtv/libs/libmythtv/dvbdiseqc.h mythtv-diseqc/libs/libmythtv/dvbdiseqc.h
--- mythtv/libs/libmythtv/dvbdiseqc.h	2006-01-07 15:19:28.000000000 -0600
+++ mythtv-diseqc/libs/libmythtv/dvbdiseqc.h	2006-01-07 22:04:55.000000000 -0600
@@ -31,27 +31,30 @@
     DVBTuning prev_tuning;
     int repeat;
 
-    
-    bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd);
-    bool SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd);
-    
     bool ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned);
     bool ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned);
+
+    bool SendDiSEqCPrepareBus(DVBTuning& tuning, bool reset);
+    bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd);
+    bool SendDiSEqCSetupBus(DVBTuning& tuning);
+
     bool Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned,
                         uint ports);
     bool PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned);
+    bool PositionerGotoAngular(DVBTuning& tuning, bool reset, 
+                               bool& havetuned);
+/*
+//currently not used
     bool PositionerStore(DVBTuning& tuning);
     bool PositionerStopMovement();
     bool PositionerStoreEastLimit();
     bool PositionerStoreWestLimit();
-    bool PositionerDisableLimits();   
+    bool PositionerDisableLimits();
     bool PositionerDriveEast(int timestep);
     bool PositionerDriveWest(int timestep);
-    bool PositionerGotoAngular(DVBTuning& tuning, bool reset, 
-                               bool& havetuned);
-
     // Still need to be written
     bool Positioner_Status();
+*/
 
     enum diseqc_cmd_bytes {
         FRAME               = 0x0,
@@ -72,7 +75,7 @@
         REPLY_CRCERR_RPT    = 0xe6,
         REPLY_CMDERR_RPT    = 0xe7
     };
-        
+
     enum diseqc_address {
         MASTER_TO_ALL        = 0x00,
         MASTER_TO_LSS        = 0x10,
diff -Naur mythtv/libs/libmythtv/videosource.cpp mythtv-diseqc/libs/libmythtv/videosource.cpp
--- mythtv/libs/libmythtv/videosource.cpp	2006-01-07 15:19:28.000000000 -0600
+++ mythtv-diseqc/libs/libmythtv/videosource.cpp	2006-01-07 15:43:52.000000000 -0600
@@ -1238,6 +1238,8 @@
         addSelection("DiSEqC v1.2 Positioner","6");
         addSelection("DiSEqC v1.3 Positioner (Goto X)","7");
         addSelection("DiSEqC v1.1 or 2.1 (10-way method2)","8");
+        addSelection("DiSEqC v1.2 Positioner with a DiSEqC switch behind it.","10");
+        addSelection("DiSEqC v1.3 Positioner (Goto X) with a DiSEqC switch behind it.","11");
         setHelpText(QObject::tr("Select the input type for DVB-S cards. "
                     "Leave as Single LNB/Input for DVB-C or DVB-T. "
                     "The inputs are mapped from Input Connections option "
@@ -1683,9 +1685,9 @@
     {
         setLabel(QObject::tr("DiSEqC Satellite Location"));
         setValue("0.0");
-        setHelpText(QObject::tr("The longitude of the satellite "
-                    "you are aiming at.  For western hemisphere use "
-                    "a negative value.  Value is in decimal."));
+        setHelpText(QObject::tr("For 1.2 positioner enter the number as it is stored in the positioner for this satellite"
+                    "or for the GotoX (DiSEqC 1.3/USALS) positioner, this is a longitude of the satellite "
+                    "you are aiming at.  For western hemisphere use a negative value.  Value is in decimal."));
 //        setVisible(false);
     };
 //    void fillSelections(const QString& pos) {
@@ -1708,6 +1710,19 @@
 };
 
 
+class DiSEqCPortPos: public SpinBoxSetting, public CISetting {
+  public:
+    DiSEqCPortPos(const CardInput& parent):
+        SpinBoxSetting(0,4,0),
+        CISetting(parent, "diseqc_port") {
+        setLabel(QObject::tr("DiSEqC Port"));
+        setValue(0);
+        setHelpText(QObject::tr("Port umber of a DiSEqC switch "
+                    "behind a positioner. "));
+    };
+};
+
+
 class FreeToAir: public CheckBoxSetting, public CISetting {
   public:
     FreeToAir(const CardInput& parent):
@@ -1880,6 +1895,7 @@
     {
         group->addChild(diseqcpos    = new DiSEqCPos(*this));
         group->addChild(diseqcport   = new DiSEqCPort(*this));
+        group->addChild(diseqcportpos = new DiSEqCPortPos(*this));
         group->addChild(lnblofswitch = new LNBLofSwitch(*this));
         group->addChild(lnblofhi = new LNBLofHi(*this));
         group->addChild(lnbloflo = new LNBLofLo(*this));
@@ -1990,22 +2006,33 @@
         {
             if (dvbType == CardUtil::QPSK)
             {
-                //Check for DiSEqC type
-                diseqcpos->setVisible(true);
-                lnblofswitch->setVisible(true);
-                lnbloflo->setVisible(true);
-                lnblofhi->setVisible(true);
-                if (CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X)
-                    diseqcpos->setEnabled(true);
-                else
-                    diseqcpos->setEnabled(false);
-            }
-            else
-            {
-                diseqcpos->setVisible(false);
-                lnblofswitch->setVisible(false);
-                lnbloflo->setVisible(false);
-                lnblofhi->setVisible(false);
+                 //Check for DiSEqC type
+                 diseqcpos->setVisible(true);
+                 diseqcportpos->setVisible(true);
+                 lnblofswitch->setVisible(true);
+                 lnbloflo->setVisible(true);
+                 lnblofhi->setVisible(true);
+                 if (CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_1_2 || 
+                      CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_1_2_SWITCH || 
+                      CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X || 
+                      CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X_SWITCH)
+                 {
+                     diseqcpos->setEnabled(true);
+                     diseqcportpos->setEnabled(true);
+                 }
+                 else
+                 {
+                     diseqcpos->setEnabled(false);
+                     diseqcportpos->setEnabled(false);
+                 }
+             }
+             else
+             {
+                 diseqcpos->setVisible(false);
+                 diseqcportpos->setVisible(false);
+                 lnblofswitch->setVisible(false);
+                 lnbloflo->setVisible(false);
+                 lnblofhi->setVisible(false);
             }
         }
     }
@@ -2429,6 +2456,17 @@
                 list.append(DVBDiSEqCInputList(
                                 stxt.arg(i+1,2), QString::number(i), ""));
             break;
+        case 10:
+            for (i = 1; i < 50; ++i)
+                list.append(DVBDiSEqCInputList(
+                                mtxt.arg(i), "", QString::number(i)));
+            break;
+        case 11:
+            for (i = 1; i < 100; ++i)
+                list.append(DVBDiSEqCInputList(
+                                itxt.arg(i), "", QString::number(i)));
+            break;
+
         default:
             list.append(DVBDiSEqCInputList(
                             QString("DVBInput"), QString(""), QString("")));
diff -Naur mythtv/libs/libmythtv/videosource.h mythtv-diseqc/libs/libmythtv/videosource.h
--- mythtv/libs/libmythtv/videosource.h	2006-01-07 15:19:28.000000000 -0600
+++ mythtv-diseqc/libs/libmythtv/videosource.h	2006-01-07 15:34:51.000000000 -0600
@@ -53,6 +53,8 @@
         POSITIONER_X,
         POSITIONER_1_2_SWITCH_2,
         POSITIONER_X_SWITCH_2,
+        POSITIONER_1_2_SWITCH,
+        POSITIONER_X_SWITCH,
     };
     /// \brief dvb card type
     static const QString DVB;
@@ -522,6 +524,7 @@
 class DVBLNBChooser;
 class DiSEqCPos;
 class DiSEqCPort;
+class DiSEqCPortPos;
 class LNBLofSwitch;
 class LNBLofLo;
 class LNBLofHi;
@@ -573,6 +576,7 @@
     DVBLNBChooser   *lnbsettings;
     DiSEqCPos       *diseqcpos;
     DiSEqCPort      *diseqcport;
+    DiSEqCPortPos   *diseqcportpos;
     LNBLofSwitch    *lnblofswitch;
     LNBLofLo        *lnbloflo;
     LNBLofHi        *lnblofhi;

Attachments (4)

5-mythtv_multilnb_positioner_rev2.diff (31.3 KB) - added by zdzisekg@… 14 years ago.
mythtv_multilnb_positioner_rev3.diff (39.3 KB) - added by zdzisekg@… 14 years ago.
this is the latest version, cleaned up some code and corrected few other issues.
mythtv_multilnb_positioner_rev4.diff (40.2 KB) - added by zdzisekg@… 14 years ago.
just a minor logging fix
mythtv_multilnb_positioner_rev5.diff (40.0 KB) - added by zdzisekg@… 14 years ago.
one more small error corrected

Download all attachments as: .zip

Change History (10)

comment:1 Changed 14 years ago by Isaac Richards

Please use an attachment, and not include the patch in the description.

comment:2 Changed 14 years ago by zdzisekg@…

There is a tiny misteak in the patch. here is the correction:

+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Tone Burst set to: %1")
+                .arg((tuning.diseqc_port % 2) ? "A" : "B"));

need to ba changed to:

+        VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Tone Burst set to: %1")
+                .arg((tuning.diseqc_port % 2) == 0 ? "A" : "B"));

my apologies

Changed 14 years ago by zdzisekg@…

comment:3 Changed 14 years ago by Isaac Richards

Owner: changed from Isaac Richards to danielk

comment:4 Changed 14 years ago by danielk

Milestone: 0.190.20

Changed 14 years ago by zdzisekg@…

this is the latest version, cleaned up some code and corrected few other issues.

Changed 14 years ago by zdzisekg@…

just a minor logging fix

Changed 14 years ago by zdzisekg@…

one more small error corrected

comment:5 Changed 14 years ago by danielk

Please break this up into three patches:

1/ one with any trivial changes. 2/ one with the new feature "DiSEqC switch support behind a positioner". 3/ one with the any other significant changes.

comment:6 Changed 14 years ago by danielk

Resolution: invalid
Status: newclosed

no response from ticket submitter, closing ticket.

Note: See TracTickets for help on using tickets.