1 #include <lib/dvb/frontend.h>
14 #include <lib/base/ebase.h>
15 #include <lib/dvb/edvb.h>
16 #include <lib/dvb/esection.h>
17 #include <lib/dvb/decoder.h>
18 #include <lib/system/econfig.h>
19 #include <lib/system/info.h>
20 #include <lib/driver/rc.h>
22 // need this to check if currently a dvb service running..
23 // for lostlock/retune handling..
24 // when no dvb service is running or needed we call savePower..
25 #include <lib/dvb/service.h>
26 // for check if in background a recording is running
27 #include <lib/dvb/edvb.h>
28 #include <lib/system/math.h>
30 eFrontend
* eFrontend::frontend
;
32 eFrontend::eFrontend(int type
, const char *demod
, const char *sec
)
34 curRotorPos(10000), transponder(0), rotorTimer1(eApp
),
36 #if HAVE_DVB_API_VERSION >= 3
39 checkRotorLockTimer(eApp
), checkLockTimer(eApp
),
40 updateTransponderTimer(eApp
), sn(0), noRotorCmd(0)
42 CONNECT(rotorTimer1
.timeout
, eFrontend::RotorStartLoop
);
43 CONNECT(rotorTimer2
.timeout
, eFrontend::RotorRunningLoop
);
44 CONNECT(checkRotorLockTimer
.timeout
, eFrontend::checkRotorLock
);
45 CONNECT(checkLockTimer
.timeout
, eFrontend::checkLock
);
46 CONNECT(updateTransponderTimer
.timeout
, eFrontend::updateTransponder
);
48 #if HAVE_DVB_API_VERSION >= 3
49 CONNECT(timeout
.timeout
, eFrontend::tuneFailed
);
52 fd
=::open(demod
, O_RDWR
|O_NONBLOCK
);
55 type
=eSystemInfo::feUnknown
;
57 #if HAVE_DVB_API_VERSION < 3
64 #if HAVE_DVB_API_VERSION < 3
67 dvb_frontend_event ev
;
69 while ( !::ioctl(fd
, FE_GET_EVENT
, &ev
) )
70 eDebug("[FE] clear FE_EVENT queue");
72 sn
=new eSocketNotifier(eApp
, fd
, eSocketNotifier::Read
);
73 CONNECT(sn
->activated
, eFrontend::readFeEvent
);
74 #if HAVE_DVB_API_VERSION < 3
75 if (type
==eSystemInfo::feSatellite
)
77 secfd
=::open(sec
, O_RDWR
);
86 if (type
== eSystemInfo::feTerrestrial
)
88 int antenna_5v_disabled
=0;
89 eConfig::getInstance()->getKey("/elitedvb/DVB/config/disable_5V", antenna_5v_disabled
);
90 setTerrestrialAntennaVoltage(antenna_5v_disabled
);
94 curContTone
= curVoltage
= -1;
99 void eFrontend::checkLock()
103 if (++lostlockcount
> 2)
106 checkLockTimer
.start(750,true);
111 checkLockTimer
.start(750,true);
115 void eFrontend::checkRotorLock()
119 if (type
==eSystemInfo::feSatellite
)
121 eSatellite
* sat
= eTransponderList::getInstance()->findSatellite(transponder
->satellite
.orbital_position
);
124 eLNB
*lnb
= sat
->getLNB();
125 if (lnb
&& lnb
->getDiSEqC().DiSEqCMode
== eDiSEqC::V1_2
&& curRotorPos
>=11000 )
128 eDebug("[FE] checkRotorLock SNR is %d... old was %d", snr
, curRotorPos
-=11000 );
129 if ( Locked() && abs(curRotorPos
- snr
) < 5000 )
131 eDebug("[FE] rotor has stopped..");
133 /*emit*/ tunedIn(transponder
, 0);
134 // eDebug("!!!!!!!!!!!!!!!! TUNED IN OK 1 !!!!!!!!!!!!!!!!");
135 if ( !eDVB::getInstance()->getScanAPI() )
137 eDebug("[FE] start update transponder data timer");
138 updateTransponderTimer
.start(2000,true);
139 checkLockTimer
.start(750,true);
140 // eDebug("ROTOR STOPPED 2");
147 eDebug("[FE] rotor already running");
149 if ( eDVB::getInstance()->getScanAPI() )
151 // eDebug("!!!!!!!!!!!!!!!! TUNED IN EAGAIN 1 !!!!!!!!!!!!!!!!");
152 /*emit*/ tunedIn(transponder
, -EAGAIN
);
163 int eFrontend::setFrontend()
165 if (type
== eSystemInfo::feUnknown
)
167 if (ioctl(fd
, FE_SET_FRONTEND
, &front
)<0)
169 eDebug("FE_SET_FRONTEND failed (%m)");
172 eDebug("FE_SET_FRONTEND OK");
173 #if HAVE_DVB_API_VERSION >= 3
174 // API V3 drivers have no working TIMEDOUT event..
175 timeout
.start(3000,true);
180 void eFrontend::tuneOK()
182 #if HAVE_DVB_API_VERSION >= 3
183 // stop userspace lock timeout
186 if (!transponder
|| type
== eSystemInfo::feUnknown
)
188 if (type
==eSystemInfo::feSatellite
)
190 eSatellite
* sat
= eTransponderList::getInstance()->findSatellite(transponder
->satellite
.orbital_position
);
193 eLNB
*lnb
= sat
->getLNB();
194 if (lnb
&& lnb
->getDiSEqC().DiSEqCMode
== eDiSEqC::V1_2
)
196 if (curRotorPos
==5000) // rotor running in input power mode
198 eDebug("[FE] ignore .. rotor is running");
201 if (curRotorPos
==11000)
204 checkRotorLockTimer
.start(2000,true); // check SNR in 2 sek
205 eDebug("[FE] start check locktimer cur snr is %d", curRotorPos
);
211 if ( !eDVB::getInstance()->getScanAPI() )
213 eDebug("[FE] start update transponder data timer");
214 updateTransponderTimer
.start(2000,true);
215 checkLockTimer
.start(750,true);
217 // eDebug("!!!!!!!!!!!!!!!! TUNED IN OK 2 !!!!!!!!!!!!!!!!");
218 /*emit*/ tunedIn(transponder
, 0);
222 void eFrontend::tuneFailed()
224 if (!transponder
|| type
== eSystemInfo::feUnknown
)
226 if (type
==eSystemInfo::feSatellite
)
228 eSatellite
* sat
= eTransponderList::getInstance()->findSatellite(transponder
->satellite
.orbital_position
);
231 eLNB
*lnb
= sat
->getLNB();
232 if ( lnb
&& lnb
->getDiSEqC().DiSEqCMode
== eDiSEqC::V1_2
)
234 if (curRotorPos
==5000) // rotor running in input power mode
236 eDebug("[FE] ignore .. rotor is running");
239 if ( curRotorPos
==11000 )
241 eDebug("[FE] RotorPos uninitialized (%d)", tries
);
242 // check every transponder two times..
243 if (eDVB::getInstance()->getScanAPI() && ++tries
> 1)
246 eDebug("[FE] don't set this TP to error");
247 // eDebug("!!!!!!!!!!!!!!!! TUNED IN EAGAIN 2 !!!!!!!!!!!!!!!!");
248 /*emit*/ tunedIn(transponder
, -EAGAIN
); // nextTransponder
257 // eDebug("!!!!!!!!!!!!!!!! TUNED IN ETIMEDOUT 1 !!!!!!!!!!!!!!!!");
258 if ( !eDVB::getInstance()->getScanAPI() )
260 if (++lostlockcount
> 5)
269 /*emit*/ tunedIn(transponder
, -ETIMEDOUT
);
273 void eFrontend::readFeEvent(int what
)
275 #if HAVE_DVB_API_VERSION < 3
277 memset(&ev
, 0, sizeof(FrontendEvent
));
279 dvb_frontend_event ev
;
280 memset(&ev
, 0, sizeof(dvb_frontend_event
));
282 if ( ::ioctl(fd
, FE_GET_EVENT
, &ev
) < 0 )
284 eDebug("FE_GET_EVENT failed(%m)");
289 eDebug("[FE] no transponder .. ignore FE Events");
292 #if HAVE_DVB_API_VERSION < 3
295 case FE_COMPLETION_EV
:
297 if ( ev
.status
& FE_HAS_LOCK
)
300 eDebug("[FE] evt. locked");
304 #if HAVE_DVB_API_VERSION < 3
307 eDebug("[FE] evt. failure");
312 else if ( ev
.status
& FE_TIMEDOUT
)
315 #if HAVE_DVB_API_VERSION < 3
317 eDebug("[FE] unhandled event (type %d)", ev
.type
);
320 else if ( ev
.status
)
321 eDebug("[FE] unhandled event (status %d)", ev
.status
);
325 void eFrontend::InitDiSEqC()
327 lastcsw
= lastSmatvFreq
= lastRotorCmd
= lastucsw
= lastToneBurst
= -1;
330 std::list
<eLNB
> &lnbs
= eTransponderList::getInstance()->getLNBs();
331 for (std::list
<eLNB
>::iterator
it(lnbs
.begin()); it
!= lnbs
.end(); ++it
)
332 if ( it
->getDiSEqC().DiSEqCMode
!= eDiSEqC::NONE
&&
333 ( it
->getDiSEqC().DiSEqCParam
!= eDiSEqC::SENDNO
||
334 it
->getDiSEqC().uncommitted_cmd
) )
337 sendDiSEqCCmd( 0, 0 );
338 // peripheral power supply on
339 sendDiSEqCCmd( 0, 3 );
345 eFrontend::~eFrontend()
350 #if HAVE_DVB_API_VERSION < 3
357 int eFrontend::Status()
359 if (!transponder
|| type
== eSystemInfo::feUnknown
)
361 #if HAVE_DVB_API_VERSION < 3
362 FrontendStatus status
=0;
366 if ( ioctl(fd
, FE_READ_STATUS
, &status
) < 0 && errno
!= ERANGE
)
367 eDebug("FE_READ_STATUS failed (%m)");
371 uint32_t eFrontend::BER()
373 if (!transponder
|| type
== eSystemInfo::feUnknown
)
376 if (ioctl(fd
, FE_READ_BER
, &ber
) < 0 && errno
!= ERANGE
)
377 eDebug("FE_READ_BER failed (%m)");
381 int eFrontend::SignalStrength()
383 if (!transponder
|| type
== eSystemInfo::feUnknown
)
386 if (ioctl(fd
, FE_READ_SIGNAL_STRENGTH
, &strength
) < 0 && errno
!= ERANGE
)
387 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
389 if ((strength
<0) || (strength
>65535))
391 eWarning("buggy SignalStrength driver (or old version) (%08x)", strength
);
400 if (!transponder
|| type
== eSystemInfo::feUnknown
)
403 if (ioctl(fd
, FE_READ_SNR
, &snr
) < 0 && errno
!= ERANGE
)
404 eDebug("FE_READ_SNR failed (%m)");
406 if ((snr
<0) || (snr
>65535))
408 eWarning("buggy SNR driver (or old version) (%08x)", snr
);
415 uint32_t eFrontend::UncorrectedBlocks()
417 if (!transponder
|| type
== eSystemInfo::feUnknown
)
420 if (ioctl(fd
, FE_READ_UNCORRECTED_BLOCKS
, &ublocks
) < 0 && errno
!= ERANGE
)
421 eDebug("FE_READ_UNCORRECTED_BLOCKS failed (%m)");
425 static CodeRate
etsiToDvbApiFEC(int fec
)
450 static Modulation
etsiToDvbApiModulation(int mod
)
469 // conversions etsi -> API for DVB-T
470 static Modulation
etsiToDvbApiConstellation(int mod
)
483 return (Modulation
)QAM_AUTO
;
486 static CodeRate
etsiToDvbApiCodeRate(int rate
)
503 return (CodeRate
)FEC_AUTO
;
506 static BandWidth
etsiToDvbApiBandwidth(int bwidth
)
511 return BANDWIDTH_8_MHZ
;
513 return BANDWIDTH_7_MHZ
;
515 return BANDWIDTH_6_MHZ
;
519 return (BandWidth
)BANDWIDTH_AUTO
;
522 static GuardInterval
etsiToDvbApiGuardInterval( int interval
)
527 return GUARD_INTERVAL_1_32
;
529 return GUARD_INTERVAL_1_16
;
531 return GUARD_INTERVAL_1_8
;
533 return GUARD_INTERVAL_1_4
;
537 return (GuardInterval
)GUARD_INTERVAL_AUTO
;
540 static TransmitMode
etsiToDvbApiTransmitMode( int mode
)
545 return TRANSMISSION_MODE_2K
;
547 return TRANSMISSION_MODE_8K
;
551 return (TransmitMode
)TRANSMISSION_MODE_AUTO
;
554 static Hierarchy
etsiToDvbApiHierarchyInformation( int hierarchy
)
559 return HIERARCHY_NONE
;
569 return (Hierarchy
)HIERARCHY_AUTO
;
572 static int dvbApiToEtsiCodeRate(CodeRate cr
)
591 static int dvbApiToEtsiConstellation(Modulation mod
)
607 static int dvbApiToEtsiBandWidth(BandWidth bw
)
611 case BANDWIDTH_8_MHZ
:
613 case BANDWIDTH_7_MHZ
:
615 case BANDWIDTH_6_MHZ
:
623 static int dvbApiToEtsiGuardInterval( GuardInterval interval
)
627 case GUARD_INTERVAL_1_32
:
629 case GUARD_INTERVAL_1_16
:
631 case GUARD_INTERVAL_1_8
:
633 case GUARD_INTERVAL_1_4
:
641 static int dvbApiToEtsiTransmitMode( TransmitMode mode
)
645 case TRANSMISSION_MODE_2K
:
647 case TRANSMISSION_MODE_8K
:
655 static int dvbApiToEtsiHierarchyInformation( Hierarchy hierarchy
)
674 int gotoXTable
[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
676 int eFrontend::readInputPower()
679 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() )
681 switch ( eSystemInfo::getInstance()->getHwType() )
683 case eSystemInfo::DM7000
:
684 case eSystemInfo::DM7020
:
686 // open front prozessor
687 int fp
=::open("/dev/dbox/fp0", O_RDWR
);
690 eDebug("couldn't open fp");
693 #define FP_IOCTL_GET_ID 0
694 static bool old_fp
= (::ioctl(fp
, FP_IOCTL_GET_ID
) < 0);
695 if ( ioctl( fp
, old_fp
? 9 : 0x100, &power
) < 0 )
697 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
704 eDebug("Inputpower read for platform %d not yet implemented", eSystemInfo::getInstance()->getHwType());
710 #if HAVE_DVB_API_VERSION < 3
711 int eFrontend::sendDiSEqCCmd( int addr
, int Cmd
, eString params
, int frame
)
713 if (type
!= eSystemInfo::feSatellite
)
720 for ( unsigned int i
=0; i
< params
.length() && i
< 6; i
+=2 )
721 cmd
.u
.diseqc
.params
[cnt
++] = strtol( params
.mid(i
, 2).c_str(), 0, 16 );
723 cmd
.type
= SEC_CMDTYPE_DISEQC_RAW
;
724 cmd
.u
.diseqc
.cmdtype
= frame
;
725 cmd
.u
.diseqc
.addr
= addr
;
726 cmd
.u
.diseqc
.cmd
= Cmd
;
727 cmd
.u
.diseqc
.numParams
= cnt
;
732 for (int i
=0; i
< cnt
; i
++)
733 parms
+=eString().sprintf("0x%02x ",cmd
.u
.diseqc
.params
[i
]);
736 if ( transponder
&& lastLNB
)
738 // eDebug("hold current voltage and continuous tone");
739 // set Continuous Tone ( 22 Khz... low - high band )
740 if ( transponder
->satellite
.frequency
> lastLNB
->getLOFThreshold() )
741 seq
.continuousTone
= SEC_TONE_ON
;
743 seq
.continuousTone
= SEC_TONE_OFF
;
745 if ( transponder
->satellite
.polarisation
== polVert
)
746 seq
.voltage
= SEC_VOLTAGE_13
;
748 seq
.voltage
= SEC_VOLTAGE_18
;
752 eDebug("set continuous tone OFF and voltage to 13V");
753 seq
.continuousTone
= SEC_TONE_OFF
;
754 seq
.voltage
= SEC_VOLTAGE_13
;
757 // eDebug("cmdtype = %02x, addr = %02x, cmd = %02x, numParams = %02x, params=%s", frame, addr, Cmd, cnt, parms.c_str() );
758 seq
.miniCommand
= SEC_MINI_NONE
;
762 if ( ioctl(secfd
, SEC_SEND_SEQUENCE
, &seq
) < 0 )
764 eDebug("SEC_SEND_SEQUENCE failed ( %m )");
768 eDebug("cmd send");*/
770 lastcsw
= lastucsw
= -1;
775 int eFrontend::sendDiSEqCCmd( int addr
, int Cmd
, eString params
, int frame
)
777 if (type
!= eSystemInfo::feSatellite
)
779 struct dvb_diseqc_master_cmd cmd
;
786 for (uint8_t i
= 0; i
< params
.length() && i
< 6; i
+= 2)
787 cmd
.msg
[cmd
.msg_len
++] = strtol( params
.mid(i
, 2).c_str(), 0, 16 );
789 if ( curVoltage
== -1 && (::ioctl(fd
, FE_SET_VOLTAGE
, SEC_VOLTAGE_18
) < 0) )
790 eDebug("FE_SET_VOLTAGE (18) failed (%m)");
792 if (ioctl(fd
, FE_SET_TONE
, SEC_TONE_OFF
) < 0)
794 eDebug("FE_SET_TONE failed (%m)");
797 curContTone
= eSecCmdSequence::TONE_OFF
;
799 if (ioctl(fd
, FE_DISEQC_SEND_MASTER_CMD
, &cmd
) < 0)
801 eDebug("FE_DISEQC_SEND_MASTER_CMD failed (%m)");
805 lastcsw
= lastucsw
= -1;
811 #if HAVE_DVB_API_VERSION < 3
812 int eFrontend::SendSequence( const eSecCmdSequence
&s
)
814 if (type
!= eSystemInfo::feSatellite
)
817 memset( &seq
, 0, sizeof(seq
) );
818 seq
.commands
= s
.commands
;
819 seq
.numCommands
= s
.numCommands
;
820 seq
.continuousTone
= s
.continuousTone
;
821 seq
.miniCommand
= s
.toneBurst
;
824 case eSecCmdSequence::VOLTAGE_13
:
825 seq
.voltage
=s
.increasedVoltage
?SEC_VOLTAGE_13_5
:SEC_VOLTAGE_13
;
827 case eSecCmdSequence::VOLTAGE_18
:
828 seq
.voltage
=s
.increasedVoltage
?SEC_VOLTAGE_18_5
:SEC_VOLTAGE_18
;
830 case eSecCmdSequence::VOLTAGE_OFF
:
832 seq
.voltage
=SEC_VOLTAGE_OFF
;
835 return ::ioctl(secfd
, SEC_SEND_SEQUENCE
, &seq
);
838 int eFrontend::SendSequence( const eSecCmdSequence
&seq
)
840 if (type
!= eSystemInfo::feSatellite
)
843 int i
=0, ret
=0, wait
=0;
844 dvb_diseqc_master_cmd
*scommands
;
847 // eDebug("curContTone = %d, newTone = %d", curContTone, seq.continuousTone );
848 if ( curContTone
!= eSecCmdSequence::TONE_OFF
&&
849 ( seq
.continuousTone
== eSecCmdSequence::TONE_OFF
850 // diseqc command or minidiseqc command to sent ?
851 || seq
.numCommands
|| seq
.toneBurst
!= eSecCmdSequence::NONE
) )
853 // eDebug("disable cont Tone");
854 ret
= ioctl(fd
, FE_SET_TONE
, SEC_TONE_OFF
);
857 eDebug("FE_SET_TONE failed (%m)");
860 curContTone
= eSecCmdSequence::TONE_OFF
;
864 if (seq
.increasedVoltage
)
866 // eDebug("enable high voltage");
867 ret
= ioctl(fd
, FE_ENABLE_HIGH_LNB_VOLTAGE
, 1);
870 eDebug("FE_ENABLE_HIGH_LNB_VOLTAGE failed (%m)");
874 // eDebug("curVoltage = %d, new Voltage = %d", curContTone, seq.voltage);
875 if ( seq
.voltage
!= curVoltage
)
877 ret
= ioctl(fd
, FE_SET_VOLTAGE
, seq
.voltage
);
880 eDebug("FE_SET_VOLTAGE failed (%m)");
883 curVoltage
= seq
.voltage
;
884 // eDebug("set voltage to %s", seq.voltage==eSecCmdSequence::VOLTAGE_13?"13 V":seq.voltage==eSecCmdSequence::VOLTAGE_18?"18 V":"unknown ... bug!!");
890 // eDebug("delay 30 ms");
895 while (true && seq
.numCommands
)
897 scommands
= &seq
.commands
[i
];
899 ret
= ioctl(fd
, FE_DISEQC_SEND_MASTER_CMD
, scommands
);
902 eDebug("FE_DISEQC_SEND_MASTER_CMD failed (%m)");
905 // eDebug("DiSEqC Cmd sent %02x %02x %02x %02x", scommands->msg[0], scommands->msg[1], scommands->msg[2], scommands->msg[3] );
907 if ( scommands->msg[0] & 1 )
909 if ( scommands->msg[2] == 0x39 )
911 eDebug("(%d)uncommited repeat command sent", i);
915 eDebug("(%d)commited repeat command sent", i);
920 if ( scommands->msg[2] == 0x39 )
922 eDebug("(%d)uncommited command sent", i);
926 eDebug("(%d)commited command sent", i);
931 if ( i
< seq
.numCommands
) // another command is to send...
933 if (wait
&& seq
.commands
[i
].msg
[0] & 1)
936 // eDebug("delay %dms",wait);
938 if ( seq
.commands
[i
].msg
[2] == scommands
->msg
[2]
939 && seq
.commands
[i
].msg
[3] == scommands
->msg
[3] )
940 // send repeat without uncommitted switch in gap... wait 120 ms
943 // eDebug("delay 120ms");
945 else if ( seq
.commands
[i
].msg
[0] & 1 // repeat
946 || (i
+1 < seq
.numCommands
&&
947 seq
.commands
[i
-1].msg
[2] == seq
.commands
[i
+1].msg
[2] ))
951 // we calc prev message length
952 int mlength
= (scommands
->msg_len
* 8 + scommands
->msg_len
) * 15;
953 // eDebug("messageLength = %dms", mlength / 10 );
954 wait
= ( ( (1200 - mlength
) / 20) );
955 // half time we wait before next cmd
957 // eDebug("delay %dms",wait);
961 } // MSG[1] ??? or MSG
962 else if ( seq
.commands
[i
].msg
[1] == 0x58 ) // handle SMATV Cmd
964 // eDebug("delay 10ms"); // Standard > 6ms
967 else // we calc the delay between two cmds with difference types.. switch..rotor
969 usleep( 120*1000 ); // wait after msg
970 // eDebug("delay 120ms");
978 if (seq
.numCommands
) // When DiSEqC Commands was sent.. then wait..
980 // eDebug("delay 30ms after send last diseqc command"); // Standard > 15ms
985 if (seq
.toneBurst
!= eSecCmdSequence::NONE
)
987 ret
= ioctl(fd
, FE_DISEQC_SEND_BURST
, seq
.toneBurst
);
990 eDebug("FE_DISEQC_SEND_BURST failed (%m)");
993 // eDebug("toneBurst sent\n");
995 usleep(30*1000); // after send toneburst we wait...
996 // eDebug("delay 30ms");
999 // eDebug("curTone = %d, newTone = %d", curContTone, seq.continuousTone );
1000 if ( seq
.continuousTone
== eSecCmdSequence::TONE_ON
&& curContTone
!= SEC_TONE_ON
)
1002 // eDebug("enable continuous Tone");
1003 ret
= ioctl(fd
, FE_SET_TONE
, SEC_TONE_ON
);
1006 eDebug("FE_SET_TONE failed (%m)");
1011 curContTone
= eSecCmdSequence::TONE_ON
;
1013 // eDebug("delay 10ms");
1016 /////////////////////////////////////////
1021 int eFrontend::RotorUseTimeout(eSecCmdSequence
& seq
, eLNB
*lnb
)
1023 #if HAVE_DVB_API_VERSION < 3
1024 secCommand
*commands
= seq
.commands
;
1026 dvb_diseqc_master_cmd
*commands
= seq
.commands
;
1028 // we send first the normal DiSEqC Switch Cmds
1029 // and then the Rotor CMD
1032 int secTone
= seq
.continuousTone
;
1033 // send DiSEqC Sequence ( normal diseqc switches )
1034 seq
.continuousTone
= eSecCmdSequence::TONE_OFF
;
1035 if ( SendSequence(seq
) < 0 )
1037 eDebug("SendSequence failed (%m)");
1040 else if ( lnb
->getDiSEqC().SeqRepeat
) // Sequence Repeat selected ?
1042 usleep( 100000 ); // between seq repeats we wait 75ms
1043 SendSequence(seq
); // then repeat the command
1045 if ( lastLNB
!= lnb
)
1046 usleep( 1000000 ); // wait 1sek
1048 usleep( 100000 ); // wait 100ms
1050 // send DiSEqC Sequence (Rotor)
1051 seq
.commands
=&commands
[seq
.numCommands
]; // last command is rotor cmd... see above...
1052 seq
.numCommands
=1; // only rotor cmd
1053 seq
.toneBurst
= eSecCmdSequence::NONE
;
1054 seq
.continuousTone
=secTone
;
1056 if ( SendSequence(seq
) < 0 )
1058 eDebug("SendSequence failed (%m)");
1062 eDebug("Rotor Cmd is sent");
1068 int eFrontend::RotorUseInputPower(eSecCmdSequence
& seq
, eLNB
*lnb
)
1070 #if HAVE_DVB_API_VERSION < 3
1071 secCommand
*commands
= seq
.commands
;
1073 dvb_diseqc_master_cmd
*commands
= seq
.commands
;
1076 runningPowerInput
=0;
1077 int secTone
= seq
.continuousTone
;
1079 // we send first the normal DiSEqC Switch Cmds
1080 // and then the Rotor CMD
1083 // eDebug("sent normal diseqc switch cmd");
1084 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x, numParams=%d, numcmds=%d", seq.commands[0].u.diseqc.cmdtype, seq.commands[0].u.diseqc.addr, seq.commands[0].u.diseqc.cmd, seq.commands[0].u.diseqc.params[0], seq.numCommands, seq.commands[0].u.diseqc.numParams );
1085 // send DiSEqC Sequence ( normal diseqc switches )
1087 seq
.continuousTone
=SEC_TONE_OFF
;
1088 if ( SendSequence(seq
) < 0 )
1090 eDebug("SendSequence failed (%m)");
1093 else if ( lnb
->getDiSEqC().SeqRepeat
) // Sequence Repeat selected ?
1095 usleep( 100000 ); // between seq repeats we wait 100ms
1096 SendSequence(seq
); // then repeat the cmd
1099 if ( lastLNB
!= lnb
)
1101 usleep( 1000*1000 ); // wait 1sek
1102 // eDebug("sleep 1sek");
1106 usleep( 100*1000 ); // wait 100ms
1107 // eDebug("sleep 100ms");
1110 // get power input of Rotor on idle not work on dbox yet .. only dreambox
1111 idlePowerInput
= readInputPower();
1112 if ( idlePowerInput
< 0 )
1113 return idlePowerInput
;
1114 // eDebug("idle power input = %dmA", idlePowerInput );
1116 // send DiSEqC Sequence (Rotor)
1117 seq
.commands
=&commands
[seq
.numCommands
]; // last command is rotor cmd... see above...
1118 seq
.numCommands
=1; // only rotor cmd
1119 seq
.toneBurst
= eSecCmdSequence::NONE
;
1121 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", seq.commands[0].u.diseqc.cmdtype, seq.commands[0].u.diseqc.addr, seq.commands[0].u.diseqc.cmd, seq.commands[0].u.diseqc.params[0], seq.commands[0].u.diseqc.params[1]);
1122 seq
.continuousTone
=secTone
;
1123 if ( SendSequence(seq
) < 0 )
1125 eDebug("SendSequence failed (%m)");
1128 // set rotor start timeout // 2 sek..
1129 gettimeofday(&rotorTimeout
,0);
1135 void eFrontend::RotorStartLoop()
1139 gettimeofday(&now
,0);
1140 if ( rotorTimeout
< now
)
1142 eDebug("rotor has timeoutet :( ");
1143 /* emit */ s_RotorTimeout();
1148 runningPowerInput
= readInputPower();
1149 if ( runningPowerInput
< 0 )
1151 // eDebug("running %d mA", runningPowerInput);
1152 // eDebug("delta %d mA", DeltaA);
1154 if ( abs(runningPowerInput
-idlePowerInput
) >= (DeltaA
&0xFF) ) // rotor running ?
1156 if ( (DeltaA
& 0x200) == 0x200 )
1158 eDebug("Rotor is Running");
1160 if ( !eDVB::getInstance()->getScanAPI() )
1162 // eDebug("ROTOR RUNNING EMIT");
1163 /* emit */ s_RotorRunning( newPos
);
1166 // set rotor running timeout // 360 sek
1167 gettimeofday(&rotorTimeout
,0);
1168 rotorTimeout
+=360000;
1177 rotorTimer1
.start(50,true); // restart timer
1181 void eFrontend::RotorRunningLoop()
1184 gettimeofday(&now
,0);
1185 if ( rotorTimeout
< now
)
1187 eDebug("Rotor timeouted :-(");
1188 /* emit */ s_RotorTimeout();
1192 runningPowerInput
= readInputPower();
1193 if ( runningPowerInput
< 0 )
1195 // eDebug("running %d mA", runningPowerInput);
1197 if ( abs( idlePowerInput
-runningPowerInput
) <= (DeltaA
&0xFF) ) // rotor stoped ?
1199 if ( (DeltaA
& 0x200) == 0x200 )
1201 eDebug("Rotor Stopped");
1202 /* emit */ s_RotorStopped();
1211 rotorTimer2
.start(50,true); // restart timer
1215 void eFrontend::RotorFinish(bool tune
)
1217 if (type
!= eSystemInfo::feSatellite
)
1219 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() == 1 )
1221 if ( voltage
!= eSecCmdSequence::VOLTAGE_18
)
1222 #if HAVE_DVB_API_VERSION < 3
1223 if (ioctl(secfd
, SEC_SET_VOLTAGE
, increased
? SEC_VOLTAGE_13_5
: SEC_VOLTAGE_13
) < 0 )
1224 eDebug("SEC_SET_VOLTAGE failed (%m)");
1226 if ( ioctl(fd
, FE_SET_VOLTAGE
, voltage
) < 0 )
1227 eDebug("FE_SET_VOLTAGE failed (%m)");
1228 curVoltage
= voltage
;
1231 else // can only measure with lower lnb voltage ( 13V )
1233 if ( voltage
!= eSecCmdSequence::VOLTAGE_13
)
1234 #if HAVE_DVB_API_VERSION < 3
1235 if (ioctl(secfd
, SEC_SET_VOLTAGE
, increased
? SEC_VOLTAGE_18_5
: SEC_VOLTAGE_18
) < 0 )
1236 eDebug("SEC_SET_VOLTAGE failed (%m)");
1238 if ( ioctl(fd
, FE_SET_VOLTAGE
, voltage
) < 0 )
1239 eDebug("FE_SET_VOLTAGE failed (%m)");
1240 curVoltage
= voltage
;
1244 if ( tune
&& transponder
)
1245 transponder
->tune();
1248 double calcElevation( double SatLon
, double SiteLat
, double SiteLon
, int Height_over_ocean
= 0 )
1250 double a0
=0.58804392,
1256 f
= 1.00 / 298.257, // Earth flattning factor
1258 r_sat
=42164.57, // Distance from earth centre to satellite
1260 r_eq
=6378.14, // Earth radius
1262 sinRadSiteLat
=SIN(Radians(SiteLat
)),
1263 cosRadSiteLat
=COS(Radians(SiteLat
)),
1265 Rstation
= r_eq
/ ( std::sqrt( 1.00 - f
*(2.00-f
)*sinRadSiteLat
*sinRadSiteLat
) ),
1267 Ra
= (Rstation
+Height_over_ocean
)*cosRadSiteLat
,
1268 Rz
= Rstation
*(1.00-f
)*(1.00-f
)*sinRadSiteLat
,
1270 alfa_rx
=r_sat
*COS(Radians(SatLon
-SiteLon
)) - Ra
,
1271 alfa_ry
=r_sat
*SIN(Radians(SatLon
-SiteLon
)),
1274 alfa_r_north
=-alfa_rx
*sinRadSiteLat
+ alfa_rz
*cosRadSiteLat
,
1275 alfa_r_zenith
=alfa_rx
*cosRadSiteLat
+ alfa_rz
*sinRadSiteLat
,
1277 El_geometric
=Deg(ATAN( alfa_r_zenith
/std::sqrt(alfa_r_north
*alfa_r_north
+alfa_ry
*alfa_ry
))),
1279 x
= std::fabs(El_geometric
+0.589),
1280 refraction
=std::fabs(a0
+a1
*x
+a2
*x
*x
+a3
*x
*x
*x
+a4
*x
*x
*x
*x
),
1283 if (El_geometric
> 10.2)
1284 El_observed
= El_geometric
+0.01617*(COS(Radians(std::fabs(El_geometric
)))/SIN(Radians(std::fabs(El_geometric
))) );
1287 El_observed
= El_geometric
+refraction
;
1290 if (alfa_r_zenith
< -3000)
1296 double calcAzimuth(double SatLon
, double SiteLat
, double SiteLon
, int Height_over_ocean
=0)
1298 double f
= 1.00 / 298.257, // Earth flattning factor
1300 r_sat
=42164.57, // Distance from earth centre to satellite
1302 r_eq
=6378.14, // Earth radius
1304 sinRadSiteLat
=SIN(Radians(SiteLat
)),
1305 cosRadSiteLat
=COS(Radians(SiteLat
)),
1307 Rstation
= r_eq
/ ( std::sqrt( 1 - f
*(2-f
)*sinRadSiteLat
*sinRadSiteLat
) ),
1308 Ra
= (Rstation
+Height_over_ocean
)*cosRadSiteLat
,
1309 Rz
= Rstation
*(1-f
)*(1-f
)*sinRadSiteLat
,
1311 alfa_rx
= r_sat
*COS(Radians(SatLon
-SiteLon
)) - Ra
,
1312 alfa_ry
= r_sat
*SIN(Radians(SatLon
-SiteLon
)),
1315 alfa_r_north
= -alfa_rx
*sinRadSiteLat
+ alfa_rz
*cosRadSiteLat
,
1319 if (alfa_r_north
< 0)
1320 Azimuth
= 180+Deg(ATAN(alfa_ry
/alfa_r_north
));
1322 Azimuth
= Rev(360+Deg(ATAN(alfa_ry
/alfa_r_north
)));
1327 double calcDeclination( double SiteLat
, double Azimuth
, double Elevation
)
1329 return Deg( ASIN(SIN(Radians(Elevation
)) *
1330 SIN(Radians(SiteLat
)) +
1331 COS(Radians(Elevation
)) *
1332 COS(Radians(SiteLat
)) +
1333 COS(Radians(Azimuth
))
1338 double calcSatHourangle( double Azimuth
, double Elevation
, double Declination
, double Lat
)
1340 double a
= - COS(Radians(Elevation
)) *
1341 SIN(Radians(Azimuth
)),
1343 b
= SIN(Radians(Elevation
)) *
1345 COS(Radians(Elevation
)) *
1347 COS(Radians(Azimuth
)),
1349 // Works for all azimuths (northern & sourhern hemisphere)
1350 returnvalue
= 180 + Deg(ATAN(a
/b
));
1354 if ( Azimuth
> 270 )
1356 returnvalue
= ( (returnvalue
-180) + 360 );
1357 if (returnvalue
>360)
1358 returnvalue
= 360 - (returnvalue
-360);
1362 returnvalue
= ( 180 - returnvalue
);
1367 void eFrontend::updateTransponder()
1369 if (type
== eSystemInfo::feUnknown
)
1373 if (!eSystemInfo::getInstance()->canUpdateTransponder())
1378 #if HAVE_DVB_API_VERSION < 3
1379 FrontendParameters front
;
1381 struct dvb_frontend_parameters front
;
1383 if (ioctl(fd
, FE_GET_FRONTEND
, &front
)<0) {
1384 eDebug("FE_GET_FRONTEND (%m)");
1388 if ((type
==eSystemInfo::feSatellite
) && (transponder
->satellite
.valid
))
1390 unsigned int freq
, inv
, sr
;
1391 #if HAVE_DVB_API_VERSION < 3
1392 freq
= front
.Frequency
;
1393 inv
= front
.Inversion
;
1394 sr
= front
.u
.qpsk
.SymbolRate
;
1396 freq
= front
.frequency
;
1397 inv
= front
.inversion
;
1398 sr
= front
.u
.qpsk
.symbol_rate
;
1400 eDebug("[FE] update transponder data");
1401 eSatellite
* sat
= eTransponderList::getInstance()->findSatellite(transponder
->satellite
.orbital_position
);
1404 eLNB
*lnb
= sat
->getLNB();
1407 int lof
= transponder
->satellite
.frequency
> lnb
->getLOFThreshold() ?
1408 lnb
->getLOFHi() : lnb
->getLOFLo();
1409 int tuned_freq
= transponder
->satellite
.frequency
- lof
;
1410 if ( tuned_freq
< 0 ) // c-band
1411 transponder
->satellite
.frequency
= abs(freq
-lof
);
1413 transponder
->satellite
.frequency
= freq
+lof
;
1416 /* transponder->satellite.fec = front.u.qpsk.FEC_inner; */
1417 transponder
->satellite
.inversion
= inv
;
1418 transponder
->satellite
.symbol_rate
= sr
;
1420 else if ((type
==eSystemInfo::feCable
) && (transponder
->cable
.valid
)) {
1421 #if HAVE_DVB_API_VERSION < 3
1427 else if ((type
==eSystemInfo::feTerrestrial
) && (transponder
->terrestrial
.valid
)) {
1428 #if HAVE_DVB_API_VERSION < 3
1429 transponder
->terrestrial
.centre_frequency
= front
.Frequency
;
1430 transponder
->terrestrial
.bandwidth
= dvbApiToEtsiBandWidth(front
.u
.ofdm
.bandWidth
);
1431 transponder
->terrestrial
.code_rate_hp
= dvbApiToEtsiCodeRate(front
.u
.ofdm
.HP_CodeRate
);
1432 transponder
->terrestrial
.code_rate_lp
= dvbApiToEtsiCodeRate(front
.u
.ofdm
.LP_CodeRate
);
1433 transponder
->terrestrial
.constellation
= dvbApiToEtsiConstellation(front
.u
.ofdm
.Constellation
);
1434 transponder
->terrestrial
.transmission_mode
= dvbApiToEtsiTransmitMode(front
.u
.ofdm
.TransmissionMode
);
1435 transponder
->terrestrial
.guard_interval
= dvbApiToEtsiGuardInterval(front
.u
.ofdm
.guardInterval
);
1436 transponder
->terrestrial
.hierarchy_information
= dvbApiToEtsiHierarchyInformation(front
.u
.ofdm
.HierarchyInformation
);
1443 void eFrontend::tune_all(eTransponder
*trans
) // called from within tune_qpsk, tune_qam, tune_ofdm
1446 eSection::abortAll();
1448 updateTransponderTimer
.stop();
1449 transponder
= trans
;
1452 int eFrontend::tune_qpsk(eTransponder
*trans
,
1453 uint32_t Frequency
, // absolute frequency in kHz
1454 int polarisation
, // polarisation (polHor, polVert, ...)
1455 uint32_t SymbolRate
, // symbolrate in symbols/s (e.g. 27500000)
1456 uint8_t FEC_inner
, // FEC_inner (-1 for none, 0 for auto, but please don't use that)
1457 int Inversion
, // spectral inversion, INVERSION_OFF / _ON / _AUTO (but please...)
1458 eSatellite
&sat
) // Satellite Data.. LNB, DiSEqC, switch..
1460 if (type
!= eSystemInfo::feSatellite
)
1464 // eDebug("op = %d", trans->satellite.orbital_position );
1465 checkRotorLockTimer
.stop();
1466 checkLockTimer
.stop();
1468 if ( curRotorPos
> 11000 )
1469 curRotorPos
= 11000;
1471 // eDebug("ROTOR STOPPED 1");
1472 /* emit */ s_RotorStopped();
1474 if ( rotorTimer1
.isActive() || rotorTimer2
.isActive() )
1476 eDebug("Switch ... but running rotor... send stop..");
1480 sendDiSEqCCmd( 0x31, 0x60 );
1481 sendDiSEqCCmd( 0x31, 0x60 );
1488 #if HAVE_DVB_API_VERSION < 3
1489 ioctl(fd
, FE_SET_POWER_STATE
, FE_POWER_ON
);
1492 curContTone
= curVoltage
= -1;
1500 eSwitchParameter
&swParams
= sat
.getSwitchParams();
1501 eLNB
*lnb
= sat
.getLNB();
1502 // Variables to detect if DiSEqC must sent .. or not
1503 int csw
= lnb
->getDiSEqC().DiSEqCParam
,
1504 ucsw
= (lnb
->getDiSEqC().uncommitted_cmd
?
1505 lnb
->getDiSEqC().uncommitted_cmd
: lastucsw
),
1506 ToneBurst
= (lnb
->getDiSEqC().MiniDiSEqCParam
?
1507 lnb
->getDiSEqC().MiniDiSEqCParam
: lastToneBurst
),
1508 RotorCmd
= lastRotorCmd
,
1512 if ( !transponder
->satellite
.useable( lnb
) )
1514 // eDebug("!!!!!!!!!!!!!!!! TUNED IN ETIMEDOUT 2 !!!!!!!!!!!!!!!!");
1515 /*emit*/ tunedIn(transponder
, -ETIMEDOUT
);
1519 eSecCmdSequence seq
;
1520 #if HAVE_DVB_API_VERSION < 3
1521 #define SEC_12V_OUT_OFF 0x10
1522 #define SEC_12V_OUT_ON 0x11
1523 if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020
&&
1524 ioctl(secfd
, SEC_SET_VOLTAGE
, lnb
->get12VOut() ? SEC_12V_OUT_ON
: SEC_12V_OUT_OFF
) < 0 )
1525 eDebug("SEC_SET_VOLTAGE (12V Out) failed (%m)");
1526 secCommand
*commands
=0; // pointer to all sec commands
1528 dvb_diseqc_master_cmd
*commands
=0;
1531 // num command counter
1534 if (csw
<= eDiSEqC::SENDNO
) // use AA/AB/BA/BB/SENDNO
1536 // eDebug("csw=%d, csw<<2=%d", csw, csw << 2);
1537 if ( csw
!= eDiSEqC::SENDNO
)
1538 csw
= 0xF0 | ( csw
<< 2 );
1539 if ( polarisation
==polHor
)
1541 csw
|= 2; // Horizontal
1542 eDebug("Horizontal");
1547 if ( Frequency
> lnb
->getLOFThreshold() )
1549 csw
|= 1; // 22 Khz enabled
1555 //else we sent directly the cmd 0xF0..0xFF
1557 if ( csw
!= eDiSEqC::SENDNO
)
1558 eDebug("DiSEqC Switch cmd = %04x", csw
);
1560 eDebug("send no committed diseqc cmd !");
1563 if ( lnb
->getDiSEqC().DiSEqCMode
== eDiSEqC::V1_2
&& !noRotorCmd
)
1565 bool useGotoXX
=false;
1568 std::map
<int,int,Orbital_Position_Compare
>::iterator it
=
1569 lnb
->getDiSEqC().RotorTable
.find( sat
.getOrbitalPosition() );
1571 if (it
!= lnb
->getDiSEqC().RotorTable
.end()) // position for selected sat found ?
1572 RotorCmd
=it
->second
;
1573 else // entry not in table found
1575 eDebug("Entry for %d,%d° not in Rotor Table found... i try gotoXX°", sat
.getOrbitalPosition() / 10, sat
.getOrbitalPosition() % 10 );
1578 int pos
= sat
.getOrbitalPosition();
1579 int satDir
= pos
< 0 ? eDiSEqC::WEST
: eDiSEqC::EAST
;
1581 double SatLon
= abs(pos
)/10.00,
1582 SiteLat
= lnb
->getDiSEqC().gotoXXLatitude
,
1583 SiteLon
= lnb
->getDiSEqC().gotoXXLongitude
;
1585 if ( lnb
->getDiSEqC().gotoXXLaDirection
== eDiSEqC::SOUTH
)
1588 if ( lnb
->getDiSEqC().gotoXXLoDirection
== eDiSEqC::WEST
)
1589 SiteLon
= 360 - SiteLon
;
1591 if (satDir
== eDiSEqC::WEST
)
1592 SatLon
= 360 - SatLon
;
1594 eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat
, SiteLon
, SatLon
);
1595 double azimuth
=calcAzimuth(SatLon
, SiteLat
, SiteLon
);
1596 double elevation
=calcElevation( SatLon
, SiteLat
, SiteLon
);
1597 double declination
=calcDeclination( SiteLat
, azimuth
, elevation
);
1598 double satHourAngle
=calcSatHourangle( azimuth
, elevation
, declination
, SiteLat
);
1599 eDebug("azimuth=%lf, elevation=%lf, declination=%lf, PolarmountHourAngle=%lf", azimuth
, elevation
, declination
, satHourAngle
);
1602 // xphile: USALS fix for southern hemisphere
1607 // Northern Hemisphere
1609 int tmp
=(int)round( fabs( 180 - satHourAngle
) * 10.0 );
1610 RotorCmd
= (tmp
/10)*0x10 + gotoXTable
[ tmp
% 10 ];
1612 if (satHourAngle
< 180) // the east
1620 // Southern Hemisphere
1622 if (satHourAngle
< 180) // the east
1624 int tmp
=(int)round( fabs( satHourAngle
) * 10.0 );
1625 RotorCmd
= (tmp
/10)*0x10 + gotoXTable
[ tmp
% 10 ];
1630 int tmp
=(int)round( fabs( 360 - satHourAngle
) * 10.0 );
1631 RotorCmd
= (tmp
/10)*0x10 + gotoXTable
[ tmp
% 10 ];
1636 eDebug("RotorCmd = %04x", RotorCmd
);
1639 if ( RotorCmd
!= lastRotorCmd
|| (RotorCmd
&& curRotorPos
== 10000) ) // rotorCmd must sent?
1641 cmdCount
=1; // this is the RotorCmd
1642 if ( ucsw
!= lastucsw
)
1644 if ( csw
!= lastcsw
&& csw
& 0xF0) // NOT SENDNO
1646 cmdCount
+= (cmdCount
-1)*lnb
->getDiSEqC().DiSEqCRepeats
;
1648 #if HAVE_DVB_API_VERSION < 3
1649 // allocate memory for all DiSEqC commands
1650 commands
= new secCommand
[cmdCount
];
1651 commands
[cmdCount
-1].type
= SEC_CMDTYPE_DISEQC_RAW
;
1652 commands
[cmdCount
-1].u
.diseqc
.addr
=0x31; // normal positioner
1653 commands
[cmdCount
-1].u
.diseqc
.cmdtype
=0xE0; // no replay... first transmission
1655 commands
= new dvb_diseqc_master_cmd
[cmdCount
];
1656 commands
[cmdCount
-1].msg
[0]=0xE0;
1657 commands
[cmdCount
-1].msg
[1]=0x31;
1661 eDebug("Rotor DiSEqC Param = %04x (useGotoXX)", RotorCmd
);
1662 #if HAVE_DVB_API_VERSION < 3
1663 commands
[cmdCount
-1].u
.diseqc
.cmd
=0x6E; // gotoXX Drive Motor to Angular Position
1664 commands
[cmdCount
-1].u
.diseqc
.numParams
=2;
1665 commands
[cmdCount
-1].u
.diseqc
.params
[0]=((RotorCmd
& 0xFF00) / 0x100);
1666 commands
[cmdCount
-1].u
.diseqc
.params
[1]=RotorCmd
& 0xFF;
1668 commands
[cmdCount
-1].msg
[2]=0x6E;
1669 commands
[cmdCount
-1].msg
[3]=((RotorCmd
& 0xFF00) / 0x100);
1670 commands
[cmdCount
-1].msg
[4]=RotorCmd
& 0xFF;
1671 commands
[cmdCount
-1].msg_len
=5;
1676 eDebug("Rotor DiSEqC Param = %02x (use stored position)", RotorCmd
);
1677 #if HAVE_DVB_API_VERSION < 3
1678 commands
[cmdCount
-1].u
.diseqc
.cmd
=0x6B; // goto stored sat position
1679 commands
[cmdCount
-1].u
.diseqc
.numParams
=1;
1680 commands
[cmdCount
-1].u
.diseqc
.params
[0]=RotorCmd
;
1682 commands
[cmdCount
-1].msg
[2]=0x6B;
1683 commands
[cmdCount
-1].msg
[3]=RotorCmd
;
1684 commands
[cmdCount
-1].msg_len
=4;
1691 if ( curRotorPos
> 10000 && !sendRotorCmd
)
1693 eDebug("reset Rotor cmd");
1694 curRotorPos
= 10000;
1698 else if ( lnb
->getDiSEqC().DiSEqCMode
== eDiSEqC::SMATV
)
1700 SmatvFreq
=Frequency
;
1701 if ( lastSmatvFreq
!= SmatvFreq
)
1703 if ( lnb
->getDiSEqC().uncommitted_cmd
&& lastucsw
!= ucsw
)
1707 cmdCount
+= (cmdCount
-1)*lnb
->getDiSEqC().DiSEqCRepeats
;
1709 // allocate memory for all DiSEqC commands
1710 commands
= new secCommand
[cmdCount
];
1712 commands
[cmdCount
-1].type
= SEC_CMDTYPE_DISEQC_RAW
;
1713 commands
[cmdCount
-1].u
.diseqc
.addr
= 0x71; // intelligent slave interface for multi-master bus
1714 commands
[cmdCount
-1].u
.diseqc
.cmd
= 0x58; // write channel frequency
1715 commands
[cmdCount
-1].u
.diseqc
.cmdtype
= 0xE0;
1716 commands
[cmdCount
-1].u
.diseqc
.numParams
= 3;
1717 commands
[cmdCount
-1].u
.diseqc
.params
[0] = (((Frequency
/ 10000000) << 4) & 0xF0) | ((Frequency
/ 1000000) & 0x0F);
1718 commands
[cmdCount
-1].u
.diseqc
.params
[1] = (((Frequency
/ 100000) << 4) & 0xF0) | ((Frequency
/ 10000) & 0x0F);
1719 commands
[cmdCount
-1].u
.diseqc
.params
[2] = (((Frequency
/ 1000) << 4) & 0xF0) | ((Frequency
/ 100) & 0x0F);
1723 if ( lnb
->getDiSEqC().DiSEqCMode
>= eDiSEqC::V1_0
)
1725 // eDebug("ucsw=%d lastucsw=%d csw=%d lastcsw=%d", ucsw, lastucsw, csw, lastcsw);
1726 if ( ucsw
!= lastucsw
|| csw
!= lastcsw
|| (ToneBurst
&& ToneBurst
!= lastToneBurst
) )
1728 // eDebug("cmdCount=%d", cmdCount);
1730 if ( cmdCount
) // Smatv or Rotor is avail...
1731 loops
= cmdCount
- 1; // do not overwrite rotor cmd
1732 else // no rotor or smatv
1734 // DiSEqC Repeats and uncommitted switches only when DiSEqC >= V1_1
1735 if ( lnb
->getDiSEqC().DiSEqCMode
>= eDiSEqC::V1_1
&& ucsw
!= lastucsw
)
1737 if ( csw
!= lastcsw
&& csw
& 0xF0 )
1739 cmdCount
+= cmdCount
*lnb
->getDiSEqC().DiSEqCRepeats
;
1743 #if HAVE_DVB_API_VERSION < 3
1744 commands
= new secCommand
[cmdCount
];
1746 commands
= new dvb_diseqc_master_cmd
[cmdCount
];
1750 for ( int i
= 0; i
< loops
;) // fill commands...
1752 enum { UNCOMMITTED
, COMMITTED
} cmdbefore
= COMMITTED
;
1753 #if HAVE_DVB_API_VERSION < 3
1754 commands
[i
].type
= SEC_CMDTYPE_DISEQC_RAW
;
1755 commands
[i
].u
.diseqc
.cmdtype
= i
? 0xE1 : 0xE0; // repeated or not repeated transm.
1756 commands
[i
].u
.diseqc
.numParams
=1;
1757 commands
[i
].u
.diseqc
.addr
=0x10;
1759 commands
[i
].msg
[0]= i
? 0xE1 : 0xE0;
1760 commands
[i
].msg
[1]=0x10;
1761 commands
[i
].msg_len
=4;
1763 if ( ( lnb
->getDiSEqC().SwapCmds
1764 && lnb
->getDiSEqC().DiSEqCMode
> eDiSEqC::V1_0
1765 && ucsw
!= lastucsw
)
1768 cmdbefore
= UNCOMMITTED
;
1769 #if HAVE_DVB_API_VERSION < 3
1770 commands
[i
].u
.diseqc
.params
[0] = ucsw
;
1771 commands
[i
].u
.diseqc
.cmd
=0x39;
1773 commands
[i
].msg
[2]=0x39;
1774 commands
[i
].msg
[3]=ucsw
;
1779 #if HAVE_DVB_API_VERSION < 3
1780 commands
[i
].u
.diseqc
.params
[0] = csw
;
1781 commands
[i
].u
.diseqc
.cmd
=0x38;
1783 commands
[i
].msg
[2]=0x38;
1784 commands
[i
].msg
[3]=csw
;
1787 // eDebug("normalCmd");
1788 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x", commands[i].u.diseqc.cmdtype, commands[i].u.diseqc.addr, commands[i].u.diseqc.cmd, commands[i].u.diseqc.params[0]);
1791 && ( ( (cmdbefore
== COMMITTED
) && ucsw
)
1792 || ( (cmdbefore
== UNCOMMITTED
) && csw
& 0xF0 ) ) )
1794 memcpy( &commands
[i
], &commands
[i
-1], sizeof(commands
[i
]) );
1795 if ( cmdbefore
== COMMITTED
)
1797 #if HAVE_DVB_API_VERSION < 3
1798 commands
[i
].u
.diseqc
.cmd
=0x39;
1799 commands
[i
].u
.diseqc
.params
[0]=ucsw
;
1801 commands
[i
].msg
[2]=0x39;
1802 commands
[i
].msg
[3]=ucsw
;
1807 #if HAVE_DVB_API_VERSION < 3
1808 commands
[i
].u
.diseqc
.cmd
=0x38;
1809 commands
[i
].u
.diseqc
.params
[0]=csw
;
1811 commands
[i
].msg
[2]=0x38;
1812 commands
[i
].msg
[3]=csw
;
1815 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x", commands[i].u.diseqc.cmdtype, commands[i].u.diseqc.addr, commands[i].u.diseqc.cmd, commands[i].u.diseqc.params[0]);
1823 eDebug("send no DiSEqC");
1827 seq
.numCommands
=cmdCount
;
1828 eDebug("%d DiSEqC cmds to send", cmdCount
);
1830 seq
.toneBurst
= eSecCmdSequence::NONE
;
1831 if ( ucsw
!= lastucsw
|| csw
!= lastcsw
|| (ToneBurst
&& ToneBurst
!= lastToneBurst
) )
1833 if ( lnb
->getDiSEqC().MiniDiSEqCParam
== eDiSEqC::A
)
1835 eDebug("Toneburst A");
1836 seq
.toneBurst
=eSecCmdSequence::TONEBURST_A
;
1838 else if ( lnb
->getDiSEqC().MiniDiSEqCParam
== eDiSEqC::B
)
1840 eDebug("Toneburst B");
1841 seq
.toneBurst
=eSecCmdSequence::TONEBURST_B
;
1844 eDebug("no Toneburst (MiniDiSEqC)");
1847 // no DiSEqC related Stuff
1850 int local
= Frequency
- ( Frequency
> lnb
->getLOFThreshold() ? lnb
->getLOFHi() : lnb
->getLOFLo() );
1851 #if HAVE_DVB_API_VERSION < 3
1852 front
.Frequency
= abs(local
);
1854 front
.frequency
= abs(local
);
1857 // set Continuous Tone ( 22 Khz... low - high band )
1858 if ( (swParams
.HiLoSignal
== eSwitchParameter::ON
) || ( (swParams
.HiLoSignal
== eSwitchParameter::HILO
) && (Frequency
> lnb
->getLOFThreshold()) ) )
1859 seq
.continuousTone
= eSecCmdSequence::TONE_ON
;
1860 else if ( (swParams
.HiLoSignal
== eSwitchParameter::OFF
) || ( (swParams
.HiLoSignal
== eSwitchParameter::HILO
) && (Frequency
<= lnb
->getLOFThreshold()) ) )
1861 seq
.continuousTone
= eSecCmdSequence::TONE_OFF
;
1863 seq
.increasedVoltage
= lnb
->getIncreasedVoltage();
1865 // Voltage( 0/14/18V vertical/horizontal )
1866 if ( swParams
.VoltageMode
== eSwitchParameter::_14V
|| ( polarisation
== polVert
&& swParams
.VoltageMode
== eSwitchParameter::HV
) )
1867 voltage
= eSecCmdSequence::VOLTAGE_13
;
1868 else if ( swParams
.VoltageMode
== eSwitchParameter::_18V
|| ( polarisation
==polHor
&& swParams
.VoltageMode
== eSwitchParameter::HV
) )
1869 voltage
= eSecCmdSequence::VOLTAGE_18
;
1871 voltage
= eSecCmdSequence::VOLTAGE_OFF
;
1873 // set cmd ptr in sequence..
1874 seq
.commands
=commands
;
1876 // handle DiSEqC Rotor
1880 eDebug("handle DISEqC Rotor.. cmdCount = %d", cmdCount
);
1881 eDebug("0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",
1882 commands
[cmdCount
-1].u
.diseqc
.cmdtype
,
1883 commands
[cmdCount
-1].u
.diseqc
.addr
,
1884 commands
[cmdCount
-1].u
.diseqc
.cmd
,
1885 commands
[cmdCount
-1].u
.diseqc
.params
[0],
1886 commands
[cmdCount
-1].u
.diseqc
.params
[1]);
1889 // drive rotor with 18V when we can measure inputpower
1890 // or we know which orbital pos currently is selected
1891 if ( lnb
->getDiSEqC().useRotorInPower
&1 )
1893 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() == 1 ) // can measure with voltage > 13V ?
1894 seq
.voltage
= eSecCmdSequence::VOLTAGE_18
;
1896 seq
.voltage
= eSecCmdSequence::VOLTAGE_13
;
1899 seq
.voltage
= voltage
;
1901 lastRotorCmd
=RotorCmd
;
1903 increased
= seq
.increasedVoltage
;
1904 newPos
= sat
.getOrbitalPosition();
1906 if ( lnb
->getDiSEqC().useRotorInPower
&1 )
1909 DeltaA
=(lnb
->getDiSEqC().useRotorInPower
& 0x0000FF00) >> 8;
1910 RotorUseInputPower(seq
, lnb
);
1915 if ( !eDVB::getInstance()->getScanAPI() )
1917 eDebug("ROTOR RUNNING EMIT");
1918 /* emit */ s_RotorRunning( newPos
);
1920 RotorUseTimeout(seq
, lnb
);
1921 curRotorPos
=11000; // Rotor cmd sent
1924 else if ( lastucsw
!= ucsw
|| ( ToneBurst
&& lastToneBurst
!= ToneBurst
) )
1927 seq
.voltage
=voltage
;
1928 if ( SendSequence(seq
) < 0 )
1930 eDebug("SendSequence failed (%m)");
1933 else if ( lnb
->getDiSEqC().DiSEqCMode
>= eDiSEqC::V1_1
&& lnb
->getDiSEqC().SeqRepeat
) // Sequence Repeat ?
1935 usleep( 100000 ); // between seq repeats we wait 80ms
1936 SendSequence(seq
); // just do it *g*
1939 else if ( lastcsw
!= csw
)
1941 // faster zap workaround... send only diseqc when satpos changed
1942 if ( lnb
->getDiSEqC().FastDiSEqC
&& csw
&& (csw
/ 4) == (lastcsw
/ 4) )
1944 eDebug("Satellite has not changed.. don't send DiSEqC cmd (Fast DiSEqC)");
1947 goto send
; // jump above...
1950 eDebug("no Band or Polarisation changed .. don't send Sequence");
1954 lastToneBurst
= ToneBurst
;
1955 lastLNB
= lnb
; /* important.. for the correct timeout
1956 between normal diseqc cmd and rotor cmd */
1958 // delete allocated memory
1961 // fill in Frontend data
1962 #if HAVE_DVB_API_VERSION < 3
1963 front
.Inversion
=(Inversion
== 2 ? INVERSION_AUTO
:
1964 (Inversion
?INVERSION_ON
:INVERSION_OFF
) );
1965 front
.u
.qpsk
.FEC_inner
=etsiToDvbApiFEC(FEC_inner
);
1966 front
.u
.qpsk
.SymbolRate
=SymbolRate
;
1968 front
.inversion
=(Inversion
== 2 ? INVERSION_AUTO
:
1969 (Inversion
?INVERSION_ON
:INVERSION_OFF
) );
1970 front
.u
.qpsk
.fec_inner
=etsiToDvbApiFEC(FEC_inner
);
1971 front
.u
.qpsk
.symbol_rate
=SymbolRate
;
1975 return setFrontend();
1980 int eFrontend::tune_qam(eTransponder
*trans
,
1981 uint32_t Frequency
, // absolute frequency in kHz
1982 uint32_t SymbolRate
, // symbolrate in symbols/s (e.g. 6900000)
1983 uint8_t FEC_inner
, // FEC_inner (-1 for none, 0 for auto, but please don't use that). normally -1.
1984 int Inversion
, // spectral inversion, INVERSION_OFF / _ON / _AUTO (but please...)
1985 int QAM
) // Modulation, QAM_xx
1987 eDebug("Cable Frontend detected");
1992 #if HAVE_DVB_API_VERSION < 3
1993 ioctl(fd
, FE_SET_POWER_STATE
, FE_POWER_ON
);
1999 #if HAVE_DVB_API_VERSION < 3
2000 front
.Inversion
=(Inversion
== 2 ? INVERSION_AUTO
:
2001 (Inversion
?INVERSION_ON
:INVERSION_OFF
) );
2002 front
.Frequency
=Frequency
;
2003 front
.u
.qam
.QAM
=etsiToDvbApiModulation(QAM
);
2004 front
.u
.qam
.FEC_inner
=etsiToDvbApiFEC(FEC_inner
);
2005 front
.u
.qam
.SymbolRate
=SymbolRate
;
2007 front
.inversion
=(Inversion
== 2 ? INVERSION_AUTO
:
2008 (Inversion
?INVERSION_ON
:INVERSION_OFF
) );
2009 front
.frequency
= Frequency
*1000; // dbox2 v3 drivers need frequency as Hz
2010 front
.u
.qam
.modulation
=etsiToDvbApiModulation(QAM
);
2011 front
.u
.qam
.fec_inner
=etsiToDvbApiFEC(FEC_inner
);
2012 front
.u
.qam
.symbol_rate
=SymbolRate
;
2014 return setFrontend();
2017 int eFrontend::tune_ofdm(eTransponder
*trans
,
2018 int centre_frequency
,
2021 int hierarchy_information
,
2025 int transmission_mode
,
2028 eDebug("DVB-T Frontend detected");
2033 #if HAVE_DVB_API_VERSION < 3
2034 ioctl(fd
, FE_SET_POWER_STATE
, FE_POWER_ON
);
2040 #if HAVE_DVB_API_VERSION < 3
2041 front
.Inversion
=(inversion
== 2 ? INVERSION_AUTO
:
2042 (inversion
?INVERSION_ON
:INVERSION_OFF
) );
2043 front
.Frequency
= centre_frequency
;
2044 front
.u
.ofdm
.bandWidth
=etsiToDvbApiBandwidth(bandwidth
);
2045 front
.u
.ofdm
.HP_CodeRate
=etsiToDvbApiCodeRate(code_rate_hp
);
2046 front
.u
.ofdm
.LP_CodeRate
=etsiToDvbApiCodeRate(code_rate_lp
);
2047 front
.u
.ofdm
.Constellation
=etsiToDvbApiConstellation(constellation
);
2048 front
.u
.ofdm
.TransmissionMode
=etsiToDvbApiTransmitMode(transmission_mode
);
2049 front
.u
.ofdm
.guardInterval
=etsiToDvbApiGuardInterval(guard_interval
);
2050 front
.u
.ofdm
.HierarchyInformation
=etsiToDvbApiHierarchyInformation(hierarchy_information
);
2052 front
.inversion
=(inversion
== 2 ? INVERSION_AUTO
:
2053 (inversion
?INVERSION_ON
:INVERSION_OFF
) );
2054 front
.frequency
= centre_frequency
;
2055 front
.u
.ofdm
.bandwidth
=etsiToDvbApiBandwidth(bandwidth
);
2056 front
.u
.ofdm
.code_rate_HP
=etsiToDvbApiCodeRate(code_rate_hp
);
2057 front
.u
.ofdm
.code_rate_LP
=etsiToDvbApiCodeRate(code_rate_lp
);
2058 front
.u
.ofdm
.constellation
=etsiToDvbApiConstellation(constellation
);
2059 front
.u
.ofdm
.transmission_mode
=etsiToDvbApiTransmitMode(transmission_mode
);
2060 front
.u
.ofdm
.guard_interval
=etsiToDvbApiGuardInterval(guard_interval
);
2061 front
.u
.ofdm
.hierarchy_information
=etsiToDvbApiHierarchyInformation(hierarchy_information
);
2063 return setFrontend();
2066 int eFrontend::savePower()
2068 if (type
== eSystemInfo::feUnknown
)
2071 checkLockTimer
.stop();
2072 checkRotorLockTimer
.stop();
2073 updateTransponderTimer
.stop();
2076 #if HAVE_DVB_API_VERSION < 3
2079 eSecCmdSequence seq
;
2082 seq
.voltage
= eSecCmdSequence::VOLTAGE_OFF
;
2083 seq
.continuousTone
= eSecCmdSequence::TONE_OFF
;
2084 seq
.toneBurst
= eSecCmdSequence::NONE
;
2085 if (SendSequence(seq
) < 0 )
2087 eDebug("SendSequence failed (%m)");
2091 if ( ioctl(fd
, FE_SET_POWER_STATE
, FE_POWER_OFF
) < 0 )
2092 eDebug("FE_SET_POWER_STATE failed (%m)");
2094 if (ioctl(fd
, FE_SET_VOLTAGE
, SEC_VOLTAGE_OFF
) < 0)
2095 eDebug("FE_SET_VOLTAGE (off) failed (%m)");
2096 if (ioctl(fd
, FE_SET_TONE
, SEC_TONE_OFF
) < 0)
2097 eDebug("FE_SET_TONE (off) failed (%m)");
2104 void eFrontend::setTerrestrialAntennaVoltage(bool state
)
2106 if (type
!= eSystemInfo::feTerrestrial
)
2108 #if HAVE_DVB_API_VERSION < 3
2109 int secfd
=::open(SEC_DEV
, O_RDWR
);
2112 eDebug("open secfd failed(%m)");
2115 if ( ::ioctl(secfd
, SEC_SET_VOLTAGE
, state
? SEC_VOLTAGE_OFF
: SEC_VOLTAGE_13
) < 0 )
2116 eDebug("SEC_SET_VOLTAGE (-T) failed (%m)");