}
eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBRegisteredFrontend> &avail_frontends, eSmartPtrList<eDVBRegisteredFrontend> &avail_simulate_frontends)
- :m_lnbidx((sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters))-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(false)
+ :m_lnbidx((sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters))-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(0)
{
if (!instance)
instance = this;
bool simulate = ((eDVBFrontend*)fe)->is_simulate();
bool direct_connected = m_not_linked_slot_mask & slot_id;
int score=0, satcount=0;
+ long linked_prev_ptr=-1, linked_next_ptr=-1, linked_csw=-1, linked_ucsw=-1, linked_toneburst=-1,
+ fe_satpos_depends_ptr=-1, fe_rotor_pos=-1;
+ bool linked_in_use = false;
+
+ eSecDebugNoSimulate("direct_connected %d", !!direct_connected);
+
+ fe->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
+ fe->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
+ fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, fe_satpos_depends_ptr);
+
+ // first we search the linkage base frontend and check if any tuner in prev direction is used
+ while (linked_prev_ptr != -1)
+ {
+ eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr;
+ if (linked_fe->m_inuse)
+ linked_in_use = true;
+ fe = linked_fe->m_frontend;
+ linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr);
+ }
+
+ fe->getData(eDVBFrontend::ROTOR_POS, fe_rotor_pos);
+
+ // now check also the linked tuners is in use
+ while (!linked_in_use && linked_next_ptr != -1)
+ {
+ eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr;
+ if (linked_fe->m_inuse)
+ linked_in_use = true;
+ linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr);
+ }
+
+ // when a linked in use tuner is found we get the tuner data...
+ if (linked_in_use)
+ {
+ fe->getData(eDVBFrontend::CSW, linked_csw);
+ fe->getData(eDVBFrontend::UCSW, linked_ucsw);
+ fe->getData(eDVBFrontend::TONEBURST, linked_toneburst);
+ }
if (highest_score_lnb)
*highest_score_lnb = -1;
{
bool diseqc=false;
long band=0,
- linked_prev_ptr=-1,
- linked_next_ptr=-1,
- satpos_depends_ptr=-1,
+ satpos_depends_ptr=fe_satpos_depends_ptr,
csw = di_param.m_committed_cmd,
ucsw = di_param.m_uncommitted_cmd,
toneburst = di_param.m_toneburst_param,
- curRotorPos;
+ rotor_pos = fe_rotor_pos;
eSecDebugNoSimulate("sat %d found", sat.orbital_position);
- fe->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
- fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr);
if ( sat.frequency > lnb_param.m_lof_threshold )
band |= 1;
if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 ) // ROTOR
rotor = true;
- ret=10000;
+ ret = 10000;
}
else
{
eSecDebugNoSimulate("ret1 %d", ret);
- if (direct_connected) // frontend with direct connection?
+ if (linked_in_use)
{
- long ocsw = -1,
- oucsw = -1,
- oToneburst = -1;
- eSecDebugNoSimulate("direct");
- fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos);
- fe->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
- fe->getData(eDVBFrontend::CSW, ocsw);
- fe->getData(eDVBFrontend::UCSW, oucsw);
- fe->getData(eDVBFrontend::TONEBURST, oToneburst);
- while (ret && linked_prev_ptr != -1) // check for linked tuners..
+ // compare tuner data
+ if ( (csw != linked_csw) ||
+ ( diseqc && (ucsw != linked_ucsw || toneburst != linked_toneburst) ) ||
+ ( rotor && rotor_pos != sat.orbital_position ) )
{
- eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr;
- if (linked_fe->m_inuse)
- {
- if ( (csw != ocsw) ||
- ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) ||
- ( rotor && curRotorPos != sat.orbital_position ) )
- {
- ret=0;
- }
- }
- linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr);
+ ret = 0;
}
+ else
+ ret += 15;
eSecDebugNoSimulate("ret2 %d", ret);
- while (ret && linked_next_ptr != -1) // check for linked tuners..
+ if (ret) // special case when this tuner is linked to a satpos dependent tuner
{
- eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr;
- if (linked_fe->m_inuse)
+ fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr);
+ if (satpos_depends_ptr != -1)
{
- if ( (csw != ocsw) ||
- ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) ||
- ( rotor && curRotorPos != sat.orbital_position ) )
+ eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr;
+ satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, rotor_pos);
+ if (!rotor || rotor_pos == -1 /* we dont know the rotor position yet */
+ || rotor_pos != sat.orbital_position ) // not the same orbital position?
{
- ret=0;
+ ret = 0;
}
}
- linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr);
}
eSecDebugNoSimulate("ret3 %d", ret);
}
- else // linked frontend..
+ else if (satpos_depends_ptr != -1)
{
- long ocsw = -1,
- oucsw = -1,
- oToneburst = -1;
- while (linked_prev_ptr != -1)
+ eSecDebugNoSimulate("satpos depends");
+ eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr;
+ if (direct_connected) // current fe is direct connected.. (can turn the rotor)
{
- eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr;
- linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr);
- if (linked_prev_ptr == -1)
+ if (satpos_depends_to_fe->m_inuse) // if the dependent frontend is in use?
{
- iDVBFrontend *sec_fe = linked_fe->m_frontend;
- sec_fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos);
- if (linked_fe->m_inuse)
- {
- sec_fe->getData(eDVBFrontend::CSW, ocsw);
- sec_fe->getData(eDVBFrontend::UCSW, oucsw);
- sec_fe->getData(eDVBFrontend::TONEBURST, oToneburst);
- eSecDebug("(%ld != %ld) || \n(%d && (%ld != %ld || %ld != %ld) ) ||\n( %d && %ld != %d ) )",
- csw, ocsw, diseqc, ucsw, oucsw, toneburst, oToneburst, rotor, curRotorPos, sat.orbital_position);
- if ( (csw != ocsw) ||
- ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) ||
- ( rotor && curRotorPos != sat.orbital_position ) )
- {
- ret=0;
- }
- }
+ if (!rotor || rotor_pos != sat.orbital_position) // new orbital position not equal to current orbital pos?
+ ret = 0;
+ else
+ ret += 10;
}
}
- eSecDebugNoSimulate("ret4 %d", ret);
- }
-
- if (ret)
- if (satpos_depends_ptr != -1)
+ else // current fe is dependent of another tuner ... (so this fe can't turn the rotor!)
{
- eSecDebugNoSimulate("satpos depends");
- eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr;
- if ( satpos_depends_to_fe->m_inuse )
+ // get current orb pos of the tuner with rotor connection
+ satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, rotor_pos);
+ if (!rotor || rotor_pos == -1 /* we dont know the rotor position yet */
+ || rotor_pos != sat.orbital_position ) // not the same orbital position?
{
- if (!direct_connected)
- satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, curRotorPos);
- if (!rotor || curRotorPos != sat.orbital_position)
- ret=0;
+ ret = 0;
}
- eSecDebugNoSimulate("ret5 %d", ret);
}
+ eSecDebugNoSimulate("ret4 %d", ret);
+ }
- if (ret && rotor && curRotorPos != -1)
- ret -= abs(curRotorPos-sat.orbital_position);
+ if (ret && rotor && rotor_pos != -1)
+ ret -= abs(rotor_pos-sat.orbital_position);
- eSecDebugNoSimulate("ret6 %d", ret);
+ eSecDebugNoSimulate("ret5 %d", ret);
if (ret)
{
lnb_param.m_lof_hi : lnb_param.m_lof_lo;
int tuner_freq = abs(sat.frequency - lof);
if (tuner_freq < 900000 || tuner_freq > 2200000)
- ret=0;
+ ret = 0;
}
if (ret && lnb_param.m_prio != -1)
eDVBSatelliteSwitchParameters &sw_param = sit->second;
bool doSetFrontend = true;
bool doSetVoltageToneFrontend = true;
- bool forceStaticMode = true;
bool forceChanged = false;
bool needDiSEqCReset = false;
long band=0,
compare.tone = iDVBFrontend::toneOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
if (diseqc13V)
vlt = iDVBFrontend::voltage13;
compare.tone = iDVBFrontend::toneOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
compare.voltage = iDVBFrontend::voltageOff;
compare.steps = +4;
}
if(lnb_param.SatCR_idx == -1)
{
+ int mrt = m_params[MOTOR_RUNNING_TIMEOUT]; // in seconds!
if ( rotor_param.m_inputpower_parameters.m_use )
{ // use measure rotor input power to detect rotor state
bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
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
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*20) ); // mrt is in seconds... our SLEEP time is 50ms.. so * 20
// rotor running loop
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec
sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
}
else
{ // use normal turning mode
+ if (curRotorPos != -1)
+ {
+ mrt = abs(curRotorPos - sat.orbital_position);
+ if (mrt > 1800)
+ mrt = 3600 - mrt;
+ if (mrt % 10)
+ mrt += 10; // round a little bit
+ mrt *= 2000; // (we assume a very slow rotor with just 0.5 degree per second here)
+ mrt /= 10000;
+ mrt += 3; // a little bit overhead
+ }
doSetVoltageToneFrontend=false;
doSetFrontend=false;
eSecCommand::rotor cmd;
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) );
-
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); // sleep one second before change voltage or tone
+
compare.voltage = voltage;
compare.steps = +3;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) ); // wait 2 second before set high voltage
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-
+
compare.tone = tone;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) );
cmd.direction=1; // check for running rotor
cmd.deltaA=0;
- cmd.steps=+3;
+ cmd.steps = +3;
cmd.okcount=0;
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*4) ); // 2 minutes running timeout
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*4) ); // mrt is in seconds... our SLEEP time is 250ms.. so * 4
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); // 250msec delay
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +5 ) );
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_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_sequence.push_back( eSecCommand(eSecCommand::GOTO, +4) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -5) );
}
+ eDebug("set rotor timeout to %d seconds", mrt);
+ sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
+ sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
}
- sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
- sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
}
}
}
compare.tone = tone;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
}
sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_SWITCHPARMS) );
compare.voltage = iDVBFrontend::voltageOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS] ) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- 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::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS]) ); // wait 20 ms after voltage change
eDVBDiseqcCommand diseqc;
memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
if (doSetFrontend)
{
sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
- }
-
- if (forceStaticMode)
- {
- sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
}
+
+ sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 500) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+
frontend.setSecSequence(sec_sequence);
return 0;
for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it)
{
long tmp;
- if (!strcmp(it->m_frontend->getDescription(), "BCM4501 (internal)") && !it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp) && tmp != -1)
+ char c;
+ if (sscanf(it->m_frontend->getDescription(), "BCM450%c (internal)", &c) == 1 && !it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp) && tmp != -1)
{
FILE *f=fopen("/proc/stb/tsmux/lnb_b_input", "w");
if (!f || fwrite("B", 1, 1, f) != 1)
if (tu1 != tu2)
{
eDVBRegisteredFrontend *p1=NULL, *p2=NULL;
-
- for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it)
+ eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_frontends.begin());
+ for (; it != m_avail_frontends.end(); ++it)
{
if (it->m_frontend->getSlotID() == tu1)
p1 = *it;
}
if (p1 && p2)
{
+ char c;
p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)p2);
p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)p1);
- if (!strcmp(p1->m_frontend->getDescription(), p2->m_frontend->getDescription()) && !strcmp(p1->m_frontend->getDescription(), "BCM4501 (internal)"))
+ if (!strcmp(p1->m_frontend->getDescription(), p2->m_frontend->getDescription()) && sscanf(p1->m_frontend->getDescription(), "BCM450%c (internal)", &c) == 1)
{
FILE *f=fopen("/proc/stb/tsmux/lnb_b_input", "w");
if (!f || fwrite("A", 1, 1, f) != 1)
}
p1=p2=NULL;
- for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it)
+ it=m_avail_simulate_frontends.begin();
+ for (; it != m_avail_simulate_frontends.end(); ++it)
{
if (it->m_frontend->getSlotID() == tu1)
p1 = *it;
return m_rotorMoving;
}
-void eDVBSatelliteEquipmentControl::setRotorMoving(bool b)
+void eDVBSatelliteEquipmentControl::setRotorMoving(int slot_no, bool b)
{
- m_rotorMoving=b;
+ if (b)
+ m_rotorMoving |= (1 << slot_no);
+ else
+ m_rotorMoving &= ~(1 << slot_no);
}