diseqc 1.1 should be working now
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 19 May 2005 18:21:52 +0000 (18:21 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 19 May 2005 18:21:52 +0000 (18:21 +0000)
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/dvb/idvb.h
lib/dvb/sec.cpp
lib/dvb/sec.h

index cdbf8a58f4cfebbc6a760def4d387888bf584e43..a27309622558d79880d9e8b7c791914086257b3d 100644 (file)
@@ -284,6 +284,8 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1)
        m_tuneTimer = new eTimer(eApp);
        CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
 
+       memset(m_data, 0xFFFF, sizeof(m_data));
+
        return;
 }
 
@@ -656,6 +658,8 @@ RESULT eDVBFrontend::setTone(int t)
 
 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
 {
+       eDebug("send %02x %02x %02x %02x",
+               diseqc.data[0], diseqc.data[1], diseqc.data[2], diseqc.data[3]);
 #if HAVE_DVB_API_VERSION < 3
        struct secCommand cmd;
        cmd.type = SEC_CMDTYPE_DISEQC_RAW;
@@ -703,3 +707,24 @@ RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
        m_sec_sequence = list;
        return 0;
 }
+
+RESULT eDVBFrontend::getData(int num, int &data)
+{
+       if ( num < 4 )
+       {
+               data = m_data[num];
+               return 0;
+       }
+       return -EINVAL;
+}
+
+RESULT eDVBFrontend::setData(int num, int val)
+{
+       if ( num < 4 )
+       {
+               m_data[num] = val;
+               return 0;
+       }
+       return -EINVAL;
+}
+
index 1a68f89e2e1d61578fc3b8eafd7c2fc00d5aa469..fce94e5eeb107b1d8c9ab4a64a31758adf579977 100644 (file)
@@ -51,9 +51,16 @@ class eDVBFrontend: public iDVBFrontend, public Object
        eTimer *m_timeout;
        eTimer *m_tuneTimer;
 
+       eSecCommandList m_sec_sequence;
+
+       int m_data[4]; /* when satellite frontend then
+               data[0] = lastcsw -> state of the committed switch
+               data[1] = lastucsw -> state of the uncommitted switch
+               data[2] = lastToneburst -> current state of toneburst switch
+               data[3] = prevRotorPos -> current Rotor Position */
+
        void feEvent(int);
        void timeout();
-       eSecCommandList m_sec_sequence;
        void tuneLoop();  // called by m_tuneTimer
        void setFrontend();
 public:
@@ -70,6 +77,8 @@ public:
        RESULT sendToneburst(int burst);
        RESULT setSEC(iDVBSatelliteEquipmentControl *sec);
        RESULT setSecSequence(const eSecCommandList &list);
+       RESULT getData(int num, int &data);
+       RESULT setData(int num, int val);
 };
 
 #endif
index 638aef91a42e47c39df4cc8b2cedfd3cfe8cba92..9393d0e23bb2eb914c139c0f2587bd689e06952a 100644 (file)
@@ -391,6 +391,8 @@ public:
        virtual RESULT sendToneburst(int burst)=0;
        virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
        virtual RESULT setSecSequence(const eSecCommandList &list)=0;
+       virtual RESULT getData(int num, int &data)=0;
+       virtual RESULT setData(int num, int val)=0;
 };
 
 class iDVBSatelliteEquipmentControl: public iObject
index 78e5949e4e7be3bcbe933fb09958965c3efeb674..c59f9280c27fced977c8a11f0d93f140e9e5ab04 100644 (file)
@@ -28,7 +28,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl()
        lnb_ref.m_lof_threshold = 11700000;
 
        diseqc_ref.m_diseqc_mode = eDVBSatelliteDiseqcParameters::V1_0;
-       diseqc_ref.m_commited_cmd = eDVBSatelliteDiseqcParameters::BB;
+       diseqc_ref.m_committed_cmd = eDVBSatelliteDiseqcParameters::BB;
        diseqc_ref.m_repeats = 0;
        diseqc_ref.m_seq_repeat = false;
        diseqc_ref.m_swap_cmds = false;
@@ -50,12 +50,23 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        lnb_param.m_satellites.find(sat.orbital_position);
                if ( sit != lnb_param.m_satellites.end())
                {
-                       int hi=0;
-                       int voltage = iDVBFrontend::voltageOff;
-                       int tone = iDVBFrontend::toneOff;
-
                        eDVBSatelliteDiseqcParameters &di_param = sit->second.m_diseqc_parameters;
                        eDVBSatelliteSwitchParameters &sw_param = sit->second.m_switch_parameters;
+                       int hi=0,
+                               voltage = iDVBFrontend::voltageOff,
+                               tone = iDVBFrontend::toneOff,
+                               csw = di_param.m_committed_cmd,
+                               ucsw = di_param.m_uncommitted_cmd,
+                               toneburst = di_param.m_toneburst_param,
+                               lastcsw = -1,
+                               lastucsw = -1,
+                               lastToneburst = -1,
+                               curRotorPos = -1;
+
+                       frontend.getData(0, lastcsw);
+                       frontend.getData(1, lastucsw);
+                       frontend.getData(2, lastToneburst);
+                       frontend.getData(3, curRotorPos);
 
                        if ( sat.frequency > lnb_param.m_lof_threshold )
                                hi = 1;
@@ -69,11 +80,27 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
 
                        switch (sat.fec)
                        {
-               //              case 1:
-               //              case ...:
-                       default:
-                               parm.u.qpsk.FEC_INNER = FEC_AUTO;
-                               break;
+                               default:
+                               case eDVBFrontendParametersSatellite::FEC::fNone:
+                                       eDebug("no fec set.. assume auto");
+                               case eDVBFrontendParametersSatellite::FEC::fAuto:
+                                       parm.u.qpsk.FEC_INNER = FEC_AUTO;
+                                       break;
+                               case eDVBFrontendParametersSatellite::FEC::f1_2:
+                                       parm.u.qpsk.FEC_INNER = FEC_1_2;
+                                       break;
+                               case eDVBFrontendParametersSatellite::FEC::f2_3:
+                                       parm.u.qpsk.FEC_INNER = FEC_2_3;
+                                       break;
+                               case eDVBFrontendParametersSatellite::FEC::f3_4:
+                                       parm.u.qpsk.FEC_INNER = FEC_3_4;
+                                       break;
+                               case eDVBFrontendParametersSatellite::FEC::f5_6:
+                                       parm.u.qpsk.FEC_INNER = FEC_5_6;
+                                       break;
+                               case eDVBFrontendParametersSatellite::FEC::f7_8: 
+                                       parm.u.qpsk.FEC_INNER = FEC_7_8;
+                                       break;
                        }
 
                        parm.u.qpsk.SYMBOLRATE = sat.symbol_rate;
@@ -96,40 +123,109 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
 
                        eSecCommandList sec_sequence;
 
-                       if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 )
-                       {
-                               eDebug("rotor...");
-                       }
-                       else if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
+                       if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
                        {
-                               if ( di_param.m_commited_cmd < eDVBSatelliteDiseqcParameters::SENDNO ||
-                                       di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
+                               if ( di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO )
                                {
-                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
-                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+                                       csw = 0xF0 | (csw << 2);
+                                       if (hi)
+                                               csw |= 1;
+                                       if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal)
+                                               csw |= 2;
                                }
 
-                               if ( di_param.m_commited_cmd < eDVBSatelliteDiseqcParameters::SENDNO )
-                               {
-                                       eDVBDiseqcCommand diseqc;
-                                       diseqc.len = 4;
-                                       diseqc.data[0] = 0xe0;
-                                       diseqc.data[1] = 0x10;
-                                       diseqc.data[2] = 0x38;
-                                       diseqc.data[3] = 0xF0 | (di_param.m_commited_cmd << 2);
+                               bool send_csw =
+                                       (di_param.m_committed_cmd != eDVBSatelliteDiseqcParameters::SENDNO);
+                               bool changed_csw = send_csw && csw != lastcsw;
 
-                                       if (hi)
-                                               diseqc.data[3] |= 1;
+                               bool send_ucsw =
+                                       (di_param.m_uncommitted_cmd && di_param.m_diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
+                               bool changed_ucsw = send_ucsw && ucsw != lastucsw;
 
-                                       if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal)
-                                               diseqc.data[3] |= 2;
+                               bool send_burst =
+                                       (di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO);
+                               bool changed_burst = send_burst && toneburst != lastToneburst;
 
-                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+                               bool send_diseqc = changed_ucsw;
+                               if (!send_diseqc)
+                                       send_diseqc = changed_burst && (send_ucsw || send_csw);
+                               if (!send_diseqc)
+                               {
+                                       send_diseqc = changed_csw;
+                                       if ( send_diseqc && di_param.m_use_fast && (csw & 0xF0) && (lastcsw & 0xF0) && ((csw / 4) == (lastcsw / 4)) )
+                                               send_diseqc = false;
                                }
 
-                               if ( di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
+                               if ( send_diseqc || changed_burst )
+                               {
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );  // standard says 15 msek here
+                               }
+
+                               if ( send_diseqc )
+                               {
+                                       int loops=0;
+
+                                       if ( send_csw )
+                                               ++loops;
+                                       if ( send_ucsw )
+                                               ++loops;
+
+                                       for ( int i=0; i < di_param.m_repeats; ++i )
+                                               loops *= 2;
+
+                                       for ( int i = 0; i < loops;)  // fill commands...
+                                       {
+                                               eDVBDiseqcCommand diseqc;
+                                               diseqc.len = 4;
+                                               diseqc.data[0] = i ? 0xE1 : 0xE0;
+                                               diseqc.data[1] = 0x10;
+
+                                               if ( !send_csw || (di_param.m_swap_cmds && send_ucsw) )
+                                               {
+                                                       diseqc.data[2] = 0x39;
+                                                       diseqc.data[3] = ucsw;
+                                               }
+                                               else
+                                               {
+                                                       diseqc.data[2] = 0x38;
+                                                       diseqc.data[3] = csw;
+                                               }
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+
+                                               i++;
+                                               if ( i < loops )
+                                               {
+                                                       int cmd=0;
+                                                       if (diseqc.data[2] == 0x38 && send_ucsw)
+                                                               cmd=0x39;
+                                                       else if (diseqc.data[2] == 0x39 && send_csw)
+                                                               cmd=0x38;
+                                                       if (cmd)
+                                                       {
+                                                               static int delay = (120 - 54) / 2;  // standard says 100msek between two repeated commands
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay) );
+                                                               diseqc.data[2]=cmd;
+                                                               diseqc.data[3]=(cmd==0x38) ? csw : ucsw;
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                                                               ++i;
+                                                               if ( i < loops )
+                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay ) );
+                                                               else
+                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+                                                       }
+                                                       else  // delay 120msek when no command is in repeat gap
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 120) );
+                                               }
+                                               else
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+                                       }
+                               }
+                               if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 && curRotorPos != sat.orbital_position )
+                               {
+                               }
+                               if ( (changed_burst || send_diseqc) && di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
                                {
                                        sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
                                        sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
index 6b205a9dceb7bb9ee3459c9fd169c0c6def9d0ba..7b5e5b2b6cb1e6b5bc1ebb8e20604623819b3033 100644 (file)
@@ -79,7 +79,7 @@ class eDVBSatelliteDiseqcParameters
 {
 public:
        enum { AA=0, AB=1, BA=2, BB=3, SENDNO=4 /* and 0xF0 .. 0xFF*/  };       // DiSEqC Parameter
-       int m_commited_cmd;
+       int m_committed_cmd;
 
        enum t_diseqc_mode { NONE=0, V1_0=1, V1_1=2, V1_2=3, SMATV=4 }; // DiSEqC Mode
        t_diseqc_mode m_diseqc_mode;