fix non working "2nd lnb from motorized dish"
[enigma2.git] / lib / dvb / sec.cpp
index 3d8084c84d2f0d3a0bf8624fa326393560bc421b..a409f43dffea4f162deb77e51a747dc7fbafd0e1 100644 (file)
@@ -114,9 +114,12 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
        setRotorPosNum(1); // stored pos 1
 }
 
-int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite &sat, iDVBFrontend *fe, int slot_id )
+int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite &sat, iDVBFrontend *fe, int slot_id, int *highest_score_lnb)
 {
-       int ret=0, satcount=0;
+       int score=0, satcount=0;
+
+       if (highest_score_lnb)
+               *highest_score_lnb = -1;
 
        for (int idx=0; idx <= m_lnbidx; ++idx )
        {
@@ -124,6 +127,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx];
                if ( lnb_param.slot_mask & slot_id ) // lnb for correct tuner?
                {
+                       int ret = 0;
                        eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
 
                        satcount += lnb_param.m_satellites.size();
@@ -132,6 +136,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                lnb_param.m_satellites.find(sat.orbital_position);
                        if ( sit != lnb_param.m_satellites.end())
                        {
+                               bool diseqc=false;
+                               bool direct_connected = m_not_linked_slot_mask & slot_id;
                                long band=0,
                                        linked_prev_ptr=-1,
                                        linked_next_ptr=-1,
@@ -149,8 +155,6 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical))
                                        band |= 2;
 
-                               bool diseqc=false;
-
                                if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
                                {
                                        diseqc=true;
@@ -171,7 +175,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                        ret = 15000;
                                }
 
-                               if (m_not_linked_slot_mask & slot_id)  // frontend with direct connection?
+                               if (direct_connected)  // frontend with direct connection?
                                {
                                        long ocsw = -1,
                                                oucsw = -1,
@@ -239,8 +243,9 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                        }
                                }
 
-                               if (ret && rotor && curRotorPos != -1)
+                               if (ret && rotor && curRotorPos != -1 && direct_connected) {
                                        ret -= abs(curRotorPos-sat.orbital_position);
+                               }
 
                                if (ret)
                                        if (satpos_depends_ptr != -1)
@@ -248,6 +253,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                                eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr;
                                                if ( satpos_depends_to_fe->m_inuse )
                                                {
+                                                       if (!direct_connected)
+                                                               satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, curRotorPos);
                                                        if (!rotor || curRotorPos != sat.orbital_position)
                                                                ret=0;
                                                }
@@ -261,14 +268,21 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                        if (tuner_freq < 900000 || tuner_freq > 2200000)
                                                ret=0;
                                }
+
+                               if (ret > score)
+                               {
+                                       score = ret;
+                                       if (highest_score_lnb)
+                                               *highest_score_lnb = idx;
+                               }
                        }
                }
        }
-       if (ret && satcount)
-               ret -= (satcount-1);
-       if (ret && m_not_linked_slot_mask & slot_id)
-               ret += 5; // increase score for tuners with direct sat connection
-       return ret;
+       if (score && satcount)
+               score -= (satcount-1);
+       if (score && m_not_linked_slot_mask & slot_id)
+               score += 5; // increase score for tuners with direct sat connection
+       return score;
 }
 
 bool need_turn_fast(int turn_speed)
@@ -299,11 +313,10 @@ bool need_turn_fast(int turn_speed)
 
 RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int slot_id, unsigned int tunetimeout)
 {
-       for (int idx=0; idx <= m_lnbidx; ++idx )
+       int lnb_idx = -1;
+       if (canTune(sat, &frontend, slot_id, &lnb_idx))
        {
-               eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx];
-               if (!(lnb_param.slot_mask & slot_id)) // lnb for correct tuner?
-                       continue;
+               eDVBSatelliteLNBParameters &lnb_param = m_lnbs[lnb_idx];
                eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
                eDVBSatelliteRotorParameters &rotor_param = lnb_param.m_rotor_parameters;
 
@@ -314,7 +327,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        eDVBSatelliteSwitchParameters &sw_param = sit->second;
                        bool doSetFrontend = true;
                        bool doSetVoltageToneFrontend = true;
-                       bool allowDiseqc1_2 = true;
+                       bool sendDiSEqC = false;
                        long band=0,
                                voltage = iDVBFrontend::voltageOff,
                                tone = iDVBFrontend::toneOff,
@@ -328,6 +341,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                curRotorPos = -1,
                                satposDependPtr = -1;
                        iDVBFrontend *sec_fe=&frontend;
+                       eDVBSatelliteDiseqcParameters::t_diseqc_mode diseqc_mode = di_param.m_diseqc_mode;
 
                        frontend.getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satposDependPtr);
 
@@ -341,8 +355,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                        sec_fe = linked_fe->m_frontend;
                                        sec_fe->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr);
                                }
-                               if (satposDependPtr != -1)
-                                       allowDiseqc1_2 = false;
+                               if (satposDependPtr != -1)  // we dont need uncommitted switch and rotor cmds on second output of a rotor lnb
+                                       diseqc_mode = eDVBSatelliteDiseqcParameters::V1_0;
                        }
 
                        sec_fe->getData(eDVBFrontend::CSW, lastcsw);
@@ -383,7 +397,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
 
                        eSecCommandList sec_sequence;
 
-                       if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
+                       if (diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
                        {
                                if ( di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO )
                                        csw = 0xF0 | (csw << 2);
@@ -396,7 +410,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                bool changed_csw = send_csw && csw != lastcsw;
 
                                bool send_ucsw =
-                                       (di_param.m_uncommitted_cmd && di_param.m_diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
+                                       (di_param.m_uncommitted_cmd && diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
                                bool changed_ucsw = send_ucsw && ucsw != lastucsw;
 
                                bool send_burst =
@@ -459,9 +473,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                {
                                        int RotorCmd=-1;
                                        bool useGotoXX = false;
-                                       if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2
-                                               && !sat.no_rotor_command_on_tune
-                                               && allowDiseqc1_2 )
+                                       if ( diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2
+                                               && !sat.no_rotor_command_on_tune )
                                        {
                                                if (sw_param.m_rotorPosNum) // we have stored rotor pos?
                                                        RotorCmd=sw_param.m_rotorPosNum;
@@ -544,9 +557,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
 
                                                // check if voltage is disabled
                                                compare.voltage = iDVBFrontend::voltageOff;
-                                               compare.steps = +5;
+                                               compare.steps = +4;
                                                sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS) );
 
                                                // voltage is changed... use DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS
                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
@@ -557,6 +569,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS]) );
 
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS) );
                                                for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat)
                                                {
                                                        if ( send_mask & 4 )
@@ -633,6 +646,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_TONEBURST]) );
                                                        }
                                                }
+                                               sendDiSEqC = true;
                                        }
 
                                        eDebug("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd);
@@ -715,7 +729,6 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        compare.val = 0;
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
 ////////////////////////////
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_DISEQC_RETRYS, m_params[MOTOR_COMMAND_RETRIES]) );  // 2 retries
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
@@ -730,9 +743,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );  // check if rotor has started
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) );  // timeout .. we assume now the rotor is already at the correct position
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // goto loop start
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 9 : 8 ) );  // timeout .. we assume now the rotor is already at the correct position  
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 10 : 9 ) );  // timeout .. we assume now the rotor is already at the correct position 
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -8) );  // goto loop start
 ////////////////////
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
                                                        if (turn_fast)
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*20) );  // 2 minutes running timeout
@@ -746,7 +760,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // running loop start
 /////////////////////
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
                                                }
                                                else
                                                {  // use normal turning mode
@@ -760,8 +774,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) );  // wait 150msec after voltage change
 
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
 
                                                        compare.voltage = voltage;
@@ -786,10 +800,14 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) ); 
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) );  // goto loop start
                                                        sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );
                                                }
                                                sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
                                                sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
+                                               sendDiSEqC = true;
                                        }
                                }
                        }
@@ -799,6 +817,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                csw = band;
                        }
 
+                       if (sendDiSEqC)
+                               sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
+
                        sec_fe->setData(eDVBFrontend::NEW_CSW, csw);
                        sec_fe->setData(eDVBFrontend::NEW_UCSW, ucsw);
                        sec_fe->setData(eDVBFrontend::NEW_TONEBURST, di_param.m_toneburst_param);
@@ -824,13 +845,25 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
                        }
+
+                       if (sendDiSEqC)
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+
                        frontend.setSecSequence(sec_sequence);
 
                        return 0;
                }
        }
-
-       eDebug("found no useable satellite configuration for orbital position (%d)", sat.orbital_position );
+       eDebug("found no useable satellite configuration for %s freq %d%s %s on orbital position (%d)",
+               sat.system ? "DVB-S2" : "DVB-S",
+               sat.frequency,
+               sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal ? "H" :
+                       eDVBFrontendParametersSatellite::Polarisation::Vertical ? "V" :
+                       eDVBFrontendParametersSatellite::Polarisation::CircularLeft ? "CL" : "CR",
+               sat.modulation == eDVBFrontendParametersSatellite::Modulation::Auto ? "AUTO" :
+                       eDVBFrontendParametersSatellite::Modulation::QPSK ? "QPSK" :
+                       eDVBFrontendParametersSatellite::Modulation::M8PSK ? "8PSK" : "QAM16",
+               sat.orbital_position );
        return -1;
 }