X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/655614dbacf97de7347619a9a746daa28f9ef887..96857065b23a18ed81c3165b9c503d7563e30351:/lib/dvb/frontend.cpp diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 0319c4c9..ea9e7385 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -455,7 +455,7 @@ int eDVBFrontend::PriorityOrder=0; eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate) :m_simulate(simulate), m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe) - ,m_fd(-1), m_need_rotor_workaround(false), m_can_handle_dvbs2(false) + ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false) ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0) #if HAVE_DVB_API_VERSION < 3 ,m_secfd(-1) @@ -483,6 +483,13 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate) closeFrontend(); } +void eDVBFrontend::reopenFrontend() +{ + sleep(1); + m_type = -1; + openFrontend(); +} + int eDVBFrontend::openFrontend() { if (m_state != stateClosed) @@ -575,7 +582,7 @@ int eDVBFrontend::openFrontend() return 0; } -int eDVBFrontend::closeFrontend(bool force) +int eDVBFrontend::closeFrontend(bool force, bool no_delayed) { if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff) { @@ -598,13 +605,36 @@ int eDVBFrontend::closeFrontend(bool force) eDebugNoSimulate("close frontend %d", m_dvbid); if (m_data[SATCR] != -1) { - turnOffSatCR(m_data[SATCR]); + if (!no_delayed) + { + m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]); + m_tuneTimer->start(0, true); + if(!m_tuneTimer->isActive()) + { + int timeout=0; + eDebug("[turnOffSatCR] no mainloop"); + while(true) + { + timeout = tuneLoopInt(); + if (timeout == -1) + break; + usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr + } + } + else + eDebug("[turnOffSatCR] running mainloop"); + return 0; + } + else + m_data[ROTOR_CMD] = -1; } + setTone(iDVBFrontend::toneOff); setVoltage(iDVBFrontend::voltageOff); m_tuneTimer->stop(); + if (m_sec && !m_simulate) - m_sec->setRotorMoving(false); + m_sec->setRotorMoving(m_slotid, false); if (!::close(m_fd)) m_fd=-1; else @@ -692,7 +722,8 @@ void eDVBFrontend::feEvent(int w) { eDebug("stateLostLock"); state = stateLostLock; - sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc + if (!m_rotor_mode) + sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc } } if (m_state != state) @@ -782,7 +813,7 @@ int eDVBFrontend::readFrontendData(int type) float fval1 = SDS_SNRE / 268435456.0, fval2, fval3, fval4; - if (parm_u_qpsk_fec_inner <= FEC_S2_QPSK_9_10) // DVB-S2 QPSK + if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK) { fval2 = 6.76; fval3 = 4.35; @@ -804,7 +835,7 @@ int eDVBFrontend::readFrontendData(int type) ret = (int)(snr_in_db * 100); } else if (strstr(m_description, "Alps BSBE1 C01A") || - !strcmp(m_description, "Alps -S(STV0288)")) + strstr(m_description, "Alps -S(STV0288)")) { if (snr == 0) ret = 0; @@ -875,6 +906,19 @@ int eDVBFrontend::readFrontendData(int type) } else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505")) ret = (snr * 100) >> 8; + else if (!strcmp(m_description, "CXD1981")) + { + int mse = (~snr) & 0xFF; + switch (parm_u_qam_modulation) { + case QAM_16: + case QAM_64: + case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break; + case QAM_32: + case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break; + + default: break; + } + } if (type == signalQuality) { @@ -1045,6 +1089,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS & case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break; default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n"); } + PutToDict(dict, "fec_inner", tmp); switch (p[0].u.data) { @@ -1093,7 +1138,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS & PutToDict(dict, "orbital_position", orb_pos); PutToDict(dict, "polarization", polarization); - switch(parm_u_qpsk_fec_inner) + switch((int)parm_u_qpsk_fec_inner) { case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break; case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break; @@ -1427,9 +1472,11 @@ int eDVBFrontend::readInputpower() return 0; int power=m_slotid; // this is needed for read inputpower from the correct tuner ! char proc_name[64]; - sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid); - FILE *f=fopen(proc_name, "r"); - if (f) + char proc_name2[64]; + sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid); + sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid); + FILE *f; + if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r"))) { if (fscanf(f, "%d", &power) != 1) eDebug("read %s failed!! (%m)", proc_name); @@ -1478,9 +1525,14 @@ bool eDVBFrontend::setSecSequencePos(int steps) return true; } -void eDVBFrontend::tuneLoop() // called by m_tuneTimer +void eDVBFrontend::tuneLoop() +{ + tuneLoopInt(); +} + +int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer { - int delay=0; + int delay=-1; eDVBFrontend *sec_fe = this; eDVBRegisteredFrontend *regFE = 0; long tmp = m_data[LINKED_PREV_PTR]; @@ -1510,6 +1562,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer { long *sec_fe_data = sec_fe->m_data; // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd); + delay = 0; switch (m_sec_sequence.current()->cmd) { case eSecCommand::SLEEP: @@ -1694,12 +1747,12 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer break; case eSecCommand::SET_ROTOR_MOVING: if (!m_simulate) - m_sec->setRotorMoving(true); + m_sec->setRotorMoving(m_slotid, true); ++m_sec_sequence.current(); break; case eSecCommand::SET_ROTOR_STOPPED: if (!m_simulate) - m_sec->setRotorMoving(false); + m_sec->setRotorMoving(m_slotid, false); ++m_sec_sequence.current(); break; case eSecCommand::IF_INPUTPOWER_DELTA_GOTO: @@ -1836,6 +1889,13 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; } + case eSecCommand::DELAYED_CLOSE_FRONTEND: + { + eDebugNoSimulate("[SEC] delayed close frontend"); + closeFrontend(false, true); + ++m_sec_sequence.current(); + break; + } default: eDebugNoSimulate("[SEC] unhandled sec command %d", ++m_sec_sequence.current()->cmd); @@ -1848,6 +1908,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer regFE->dec_use(); if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end()) tuneLoop(); + return delay; } void eDVBFrontend::setFrontend(bool recvEvents) @@ -2050,8 +2111,8 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, return -EINVAL; } #if HAVE_DVB_API_VERSION < 5 - parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff - parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot + parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff + parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK) { parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9); @@ -2343,8 +2404,22 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) res = -EINVAL; goto tune_error; } + if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune) + { + eDVBFrontend *sec_fe = this; + long tmp = m_data[LINKED_PREV_PTR]; + while (tmp != -1) + { + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp; + sec_fe = linked_fe->m_frontend; + sec_fe->getData(LINKED_NEXT_PTR, tmp); + } + eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid); + sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = sec_fe->m_data[ROTOR_CMD] = sec_fe->m_data[ROTOR_POS] = -1; // reset diseqc + } + m_rotor_mode = feparm.no_rotor_command_on_tune; if (!m_simulate) - m_sec->setRotorMoving(false); + m_sec->setRotorMoving(m_slotid, false); res=prepare_sat(feparm, timeout); if (res) goto tune_error; @@ -2569,9 +2644,12 @@ RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec) return 0; } -RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list) +RESULT eDVBFrontend::setSecSequence(eSecCommandList &list) { - m_sec_sequence = list; + if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end()) + m_sec_sequence.push_back(list); + else + m_sec_sequence = list; return 0; } @@ -2622,17 +2700,23 @@ int eDVBFrontend::isCompatibleWith(ePtr &feparm) bool eDVBFrontend::setSlotInfo(ePyObject obj) { - ePyObject Id, Descr, Enabled, IsDVBS2; - if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4) + ePyObject Id, Descr, Enabled, IsDVBS2, frontendId; + if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5) goto arg_error; Id = PyTuple_GET_ITEM(obj, 0); Descr = PyTuple_GET_ITEM(obj, 1); Enabled = PyTuple_GET_ITEM(obj, 2); IsDVBS2 = PyTuple_GET_ITEM(obj, 3); - if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2)) + frontendId = PyTuple_GET_ITEM(obj, 4); + m_slotid = PyInt_AsLong(Id); + if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId)) goto arg_error; strcpy(m_description, PyString_AS_STRING(Descr)); - m_slotid = PyInt_AsLong(Id); + if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) { +// eDebugNoSimulate("skip slotinfo for slotid %d, descr %s", +// m_slotid, m_description); + return false; + } m_enabled = Enabled == Py_True; // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator... m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") || @@ -2648,42 +2732,3 @@ arg_error: "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean"); return false; } - -RESULT eDVBFrontend::turnOffSatCR(int satcr) -{ - eSecCommandList sec_sequence; - // check if voltage is disabled - eSecCommand::pair compare; - compare.steps = +9; //nothing to do - 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::SET_VOLTAGE, iDVBFrontend::voltage18_5) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); - - eDVBDiseqcCommand diseqc; - memset(diseqc.data, 0, MAX_DISEQC_LENGTH); - diseqc.len = 5; - diseqc.data[0] = 0xE0; - diseqc.data[1] = 0x10; - diseqc.data[2] = 0x5A; - diseqc.data[3] = satcr << 5; - diseqc.data[4] = 0x00; - - sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50+20+14*diseqc.len) ); - sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) ); - setSecSequence(sec_sequence); - return 0; -} - -RESULT eDVBFrontend::ScanSatCR() -{ - setFrontend(); - usleep(20000); - setTone(iDVBFrontend::toneOff); - return 0; -}