From: Andreas Monzner Date: Wed, 26 Oct 2005 08:14:11 +0000 (+0000) Subject: start rotor with 13V and static power limiting mode (LNBP21).. after 500msec switch... X-Git-Tag: 2.6.0~5436 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/0ecfa70938499a3386c282577e28625d04d4626b start rotor with 13V and static power limiting mode (LNBP21).. after 500msec switch rotor to faster speed.. (18V) .. TODO: change limiting mode should be done in driver.. not in userspace.. at the moment this is only working for the first tuner... (hardcoded i2c bus) --- diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 69519837..a4ad170d 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -204,7 +204,7 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const DEFINE_REF(eDVBFrontend); -eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1) +eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1), m_curVoltage(-1) { #if HAVE_DVB_API_VERSION < 3 char sec_filename[128]; @@ -435,8 +435,9 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; case eSecCommand::SET_VOLTAGE: - eDebug("[SEC] setVoltage %d", m_sec_sequence.current()->voltage); - setVoltage(m_sec_sequence.current()++->voltage); + int voltage = m_sec_sequence.current()++->voltage; + eDebug("[SEC] setVoltage %d", voltage); + setVoltage(voltage); break; case eSecCommand::SET_TONE: eDebug("[SEC] setTone %d", m_sec_sequence.current()->tone); @@ -444,10 +445,10 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer break; case eSecCommand::SEND_DISEQC: sendDiseqc(m_sec_sequence.current()->diseqc); - eDebugNoNewLine("sendDiseqc: "); + eDebugNoNewLine("[SEC] sendDiseqc: "); for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i) eDebugNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]); - eDebug("[SEC] "); + eDebug(""); ++m_sec_sequence.current(); break; case eSecCommand::SEND_TONEBURST: @@ -460,10 +461,17 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; case eSecCommand::MEASURE_IDLE_INPUTPOWER: - m_idleInputpower = readInputpower(); - eDebug("[SEC] idleInputpower is %d", m_idleInputpower); - ++m_sec_sequence.current(); + { + int idx = m_sec_sequence.current()++->val; + if ( idx == 0 || idx == 1 ) + { + m_idleInputpower[idx] = readInputpower(); + eDebug("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]); + } + else + eDebug("[SEC] idleInputpower measure index(%d) out of bound !!!", idx); break; + } case eSecCommand::MEASURE_RUNNING_INPUTPOWER: m_runningInputpower = readInputpower(); eDebug("[SEC] runningInputpower is %d", m_runningInputpower); @@ -481,26 +489,57 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer break; case eSecCommand::IF_TIMEOUT_GOTO: if (!m_timeoutCount) + { + eDebug("[SEC] rotor timout"); setSecSequencePos(m_sec_sequence.current()->steps); + } else ++m_sec_sequence.current(); break; + case eSecCommand::SET_POWER_LIMITING_MODE: + { + int fd=::open("/dev/i2c/0", O_RDWR); + unsigned char data[2]; + ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1); + if(::read(fd, data, 1) != 1) + eDebug("[SEC] error read lnbp (%m)"); + if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic ) + { + data[0] |= 0x90; // enable static current limiting + eDebug("[SEC] set static current limiting"); + } + else + { + data[0] &= ~0x90; // enable dynamic current limiting + eDebug("[SEC] set dynamic current limiting"); + } + if(::write(fd, data, 1) != 1) + eDebug("[SEC] error write lnbp (%m)"); + ::close(fd); + ++m_sec_sequence.current(); + break; + } + case eSecCommand::IF_IDLE_INPUTPOWER_AVAIL_GOTO: + if (m_idleInputpower[0] && m_idleInputpower[1] && setSecSequencePos(m_sec_sequence.current()->steps)) + break; + ++m_sec_sequence.current(); + break; case eSecCommand::IF_INPUTPOWER_DELTA_GOTO: { + int idleInputpower = m_idleInputpower[m_curVoltage == iDVBFrontend::voltage13 ? 0 : 1]; eSecCommand::rotor &cmd = m_sec_sequence.current()->measure; const char *txt = cmd.direction ? "running" : "stopped"; - eDebug("[SEC] waiting for rotor %s", txt); - eDebug("[SEC] %s %d, idle %d, delta %d", + eDebug("[SEC] waiting for rotor %s %d, idle %d, delta %d", txt, m_runningInputpower, - m_idleInputpower, + idleInputpower, cmd.deltaA); - if ( (cmd.direction && abs(m_runningInputpower - m_idleInputpower) >= cmd.deltaA) - || (!cmd.direction && abs(m_runningInputpower - m_idleInputpower) <= cmd.deltaA) ) + if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA) + || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) ) { ++cmd.okcount; eDebug("[SEC] rotor %s step %d ok", txt, cmd.okcount); - if ( cmd.okcount > 1 ) + if ( cmd.okcount > 6 ) { eDebug("[SEC] rotor is %s", txt); if (setSecSequencePos(cmd.steps)) @@ -516,6 +555,14 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; } + case eSecCommand::IF_VOLTAGE_GOTO: + { + eSecCommand::pair &compare = m_sec_sequence.current()->compare; + if ( compare.voltage == m_curVoltage && setSecSequencePos(compare.steps) ) + break; + ++m_sec_sequence.current(); + break; + } default: ++m_sec_sequence.current(); eDebug("[SEC] unhandled sec command"); @@ -725,6 +772,7 @@ RESULT eDVBFrontend::setVoltage(int voltage) fe_sec_voltage_t vlt; #endif + m_curVoltage=voltage; switch (voltage) { case voltageOff: diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index a0ca08ec..c091227b 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -62,9 +62,10 @@ class eDVBFrontend: public iDVBFrontend, public Object data[5] = curRotorCmd data[6] = curRotorPos */ - int m_idleInputpower; + int m_idleInputpower[2]; // 13V .. 18V int m_runningInputpower; int m_timeoutCount; // needed for timeout + int m_curVoltage; void feEvent(int); void timeout(); diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index 876d7d29..71f7c900 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -149,7 +149,6 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA tone = iDVBFrontend::toneOff; eSecCommandList sec_sequence; - bool setVoltage=true; if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0) { @@ -187,9 +186,12 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if ( send_diseqc || changed_burst ) { sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) ); + eSecCommand::pair compare; + compare.voltage = voltage; + compare.steps = +3; + sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ? sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) ); // standard says 15 msek here - setVoltage=false; + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); } if ( send_diseqc ) @@ -329,6 +331,25 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA } if ( RotorCmd != lastRotorCmd ) { + if ( changed_burst || send_diseqc ) + { + // override first voltage change + *(++(++sec_sequence.begin()))=eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13); + // wait 1 second after first switch diseqc command + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); + } + else // no other diseqc commands before + { + sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) ); // wait 50msec after voltage change + eSecCommand::pair compare; + compare.voltage = voltage; + compare.steps = +3; + sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ? + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec after voltage change + } + eDVBDiseqcCommand diseqc; diseqc.data[0] = 0xE0; diseqc.data[1] = 0x31; // positioner @@ -345,30 +366,47 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA diseqc.data[2] = 0x6B; // goto stored sat position diseqc.data[3] = RotorCmd; } + if ( rotor_param.m_inputpower_parameters.m_use ) { // use measure rotor input power to detect rotor state - sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18) ); // always turn with high voltage - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50sec after voltage change - sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER) ); + eSecCommand::rotor cmd; +// measure idle power values + sec_sequence.push_back( eSecCommand(eSecCommand::IF_IDLE_INPUTPOWER_AVAIL_GOTO, +8) ); // already measured? + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec after voltage change + sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 100) ); // wait 100msec before measure + sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) ); // back to lower voltage + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec +//////////////////////////// + sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec after voltage change sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 8) ); // 2 seconds rotor start timout - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) ); // 2 seconds rotor start timout +// rotor start loop + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // 50msec delay sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) ); - eSecCommand::rotor cmd; cmd.direction=1; // check for running rotor cmd.deltaA=rotor_param.m_inputpower_parameters.m_threshold; cmd.steps=+3; cmd.okcount=0; - sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) ); - sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +8 ) ); - sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 240) ); // 1 minute running timeout - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); + 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, +11 ) ); // timeout ? + sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // goto loop start +//////////////////// + sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 2400) ); // 2 minutes running timeout + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) ); +// rotor running loop + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) ); cmd.direction=0; // check for stopped rotor + cmd.steps=+3; sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) ); - sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) ); - sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); + sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) ); // timeout ? + sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // running loop start +///////////////////// sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) ); frontend.setData(3, RotorCmd); frontend.setData(4, sat.orbital_position); @@ -379,11 +417,12 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA } } - if ( setVoltage ) - { - sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 10) ); - } + eSecCommand::pair compare; + compare.voltage = voltage; + compare.steps = +3; + sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ? + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 10) ); sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) ); sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) ); diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h index 574fd9d6..0b06afc6 100644 --- a/lib/dvb/sec.h +++ b/lib/dvb/sec.h @@ -8,12 +8,15 @@ class eSecCommand { public: + enum { modeStatic, modeDynamic }; enum { NONE, SLEEP, SET_VOLTAGE, SET_TONE, GOTO, SEND_DISEQC, SEND_TONEBURST, SET_FRONTEND, MEASURE_IDLE_INPUTPOWER, MEASURE_RUNNING_INPUTPOWER, IF_TIMEOUT_GOTO, IF_INPUTPOWER_DELTA_GOTO, - UPDATE_CURRENT_ROTORPARAMS, SET_TIMEOUT + UPDATE_CURRENT_ROTORPARAMS, SET_TIMEOUT, + IF_IDLE_INPUTPOWER_AVAIL_GOTO, SET_POWER_LIMITING_MODE, + IF_VOLTAGE_GOTO }; int cmd; struct rotor @@ -23,6 +26,11 @@ public: int steps; // goto steps int direction; }; + struct pair + { + int voltage; + int steps; + }; union { int val; @@ -32,8 +40,10 @@ public: int tone; int toneburst; int msec; + int mode; rotor measure; eDVBDiseqcCommand diseqc; + pair compare; }; eSecCommand( int cmd ) :cmd(cmd) @@ -47,6 +57,9 @@ public: eSecCommand( int cmd, rotor measure ) :cmd(cmd), measure(measure) {} + eSecCommand( int cmd, pair compare ) + :cmd(cmd), compare(compare) + {} eSecCommand() :cmd(NONE) {}