- set default diseqc to AA, in the hope to match more defaults (sorry)
[enigma2.git] / lib / dvb / sec.cpp
1 #include <config.h>
2 #include <lib/dvb/sec.h>
3 #if HAVE_DVB_API_VERSION < 3
4 #define INVERSION Inversion
5 #define FREQUENCY Frequency
6 #define FEC_INNER FEC_inner
7 #define SYMBOLRATE SymbolRate
8 #else
9 #define INVERSION inversion
10 #define FREQUENCY frequency
11 #define FEC_INNER fec_inner
12 #define SYMBOLRATE symbol_rate
13 #endif
14 #include <lib/base/eerror.h>
15
16 DEFINE_REF(eDVBSatelliteEquipmentControl);
17
18 eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl()
19 {
20         m_lnblist.push_back(eDVBSatelliteLNBParameters());
21         eDVBSatelliteLNBParameters &lnb_ref = m_lnblist.front();
22         eDVBSatelliteParameters &astra1 = lnb_ref.m_satellites[192];
23         eDVBSatelliteDiseqcParameters &diseqc_ref = astra1.m_diseqc_parameters;
24         eDVBSatelliteSwitchParameters &switch_ref = astra1.m_switch_parameters;
25
26         lnb_ref.m_lof_hi = 10607000;
27         lnb_ref.m_lof_lo = 9750000;
28         lnb_ref.m_lof_threshold = 11700000;
29
30         diseqc_ref.m_diseqc_mode = eDVBSatelliteDiseqcParameters::V1_0;
31         diseqc_ref.m_committed_cmd = eDVBSatelliteDiseqcParameters::AA;
32         diseqc_ref.m_repeats = 0;
33         diseqc_ref.m_seq_repeat = false;
34         diseqc_ref.m_swap_cmds = false;
35         diseqc_ref.m_toneburst_param = eDVBSatelliteDiseqcParameters::NO;
36         diseqc_ref.m_uncommitted_cmd = 0;
37         diseqc_ref.m_use_fast = 1;
38
39         switch_ref.m_22khz_signal = eDVBSatelliteSwitchParameters::HILO;
40         switch_ref.m_voltage_mode = eDVBSatelliteSwitchParameters::HV;
41 }
42
43 RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, eDVBFrontendParametersSatellite &sat)
44 {
45         std::list<eDVBSatelliteLNBParameters>::iterator it = m_lnblist.begin();
46         for (;it != m_lnblist.end(); ++it )
47         {
48                 eDVBSatelliteLNBParameters &lnb_param = *it;
49                 std::map<int, eDVBSatelliteParameters>::iterator sit =
50                         lnb_param.m_satellites.find(sat.orbital_position);
51                 if ( sit != lnb_param.m_satellites.end())
52                 {
53                         eDVBSatelliteDiseqcParameters &di_param = sit->second.m_diseqc_parameters;
54                         eDVBSatelliteSwitchParameters &sw_param = sit->second.m_switch_parameters;
55                         int hi=0,
56                                 voltage = iDVBFrontend::voltageOff,
57                                 tone = iDVBFrontend::toneOff,
58                                 csw = di_param.m_committed_cmd,
59                                 ucsw = di_param.m_uncommitted_cmd,
60                                 toneburst = di_param.m_toneburst_param,
61                                 lastcsw = -1,
62                                 lastucsw = -1,
63                                 lastToneburst = -1,
64                                 curRotorPos = -1;
65
66                         frontend.getData(0, lastcsw);
67                         frontend.getData(1, lastucsw);
68                         frontend.getData(2, lastToneburst);
69                         frontend.getData(3, curRotorPos);
70
71                         if ( sat.frequency > lnb_param.m_lof_threshold )
72                                 hi = 1;
73
74                         if (hi)
75                                 parm.FREQUENCY = sat.frequency - lnb_param.m_lof_hi;
76                         else
77                                 parm.FREQUENCY = sat.frequency - lnb_param.m_lof_lo;
78
79                         parm.INVERSION = (!sat.inversion) ? INVERSION_ON : INVERSION_OFF;
80
81                         switch (sat.fec)
82                         {
83                                 default:
84                                 case eDVBFrontendParametersSatellite::FEC::fNone:
85                                         eDebug("no fec set.. assume auto");
86                                 case eDVBFrontendParametersSatellite::FEC::fAuto:
87                                         parm.u.qpsk.FEC_INNER = FEC_AUTO;
88                                         break;
89                                 case eDVBFrontendParametersSatellite::FEC::f1_2:
90                                         parm.u.qpsk.FEC_INNER = FEC_1_2;
91                                         break;
92                                 case eDVBFrontendParametersSatellite::FEC::f2_3:
93                                         parm.u.qpsk.FEC_INNER = FEC_2_3;
94                                         break;
95                                 case eDVBFrontendParametersSatellite::FEC::f3_4:
96                                         parm.u.qpsk.FEC_INNER = FEC_3_4;
97                                         break;
98                                 case eDVBFrontendParametersSatellite::FEC::f5_6:
99                                         parm.u.qpsk.FEC_INNER = FEC_5_6;
100                                         break;
101                                 case eDVBFrontendParametersSatellite::FEC::f7_8: 
102                                         parm.u.qpsk.FEC_INNER = FEC_7_8;
103                                         break;
104                         }
105
106                         parm.u.qpsk.SYMBOLRATE = sat.symbol_rate;
107
108                         if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_14V
109                                 || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Vertical
110                                         && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV )  )
111                                 voltage = iDVBFrontend::voltage13;
112                         else if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_18V
113                                 || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal
114                                         && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV )  )
115                                 voltage = iDVBFrontend::voltage18;
116
117                         if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::ON)
118                                 || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && hi ) )
119                                 tone = iDVBFrontend::toneOn;
120                         else if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::OFF)
121                                 || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && !hi ) )
122                                 tone = iDVBFrontend::toneOff;
123
124                         eSecCommandList sec_sequence;
125
126                         if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
127                         {
128                                 if ( di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO )
129                                 {
130                                         csw = 0xF0 | (csw << 2);
131                                         if (hi)
132                                                 csw |= 1;
133                                         if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal)
134                                                 csw |= 2;
135                                 }
136
137                                 bool send_csw =
138                                         (di_param.m_committed_cmd != eDVBSatelliteDiseqcParameters::SENDNO);
139                                 bool changed_csw = send_csw && csw != lastcsw;
140
141                                 bool send_ucsw =
142                                         (di_param.m_uncommitted_cmd && di_param.m_diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
143                                 bool changed_ucsw = send_ucsw && ucsw != lastucsw;
144
145                                 bool send_burst =
146                                         (di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO);
147                                 bool changed_burst = send_burst && toneburst != lastToneburst;
148
149                                 bool send_diseqc = changed_ucsw;
150                                 if (!send_diseqc)
151                                         send_diseqc = changed_burst && (send_ucsw || send_csw);
152                                 if (!send_diseqc)
153                                 {
154                                         send_diseqc = changed_csw;
155                                         if ( send_diseqc && di_param.m_use_fast && (csw & 0xF0) && (lastcsw & 0xF0) && ((csw / 4) == (lastcsw / 4)) )
156                                                 send_diseqc = false;
157                                 }
158
159                                 if ( send_diseqc || changed_burst )
160                                 {
161                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
162                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
163                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );  // standard says 15 msek here
164                                 }
165
166                                 if ( send_diseqc )
167                                 {
168                                         int loops=0;
169
170                                         if ( send_csw )
171                                                 ++loops;
172                                         if ( send_ucsw )
173                                                 ++loops;
174
175                                         for ( int i=0; i < di_param.m_repeats; ++i )
176                                                 loops *= 2;
177
178                                         for ( int i = 0; i < loops;)  // fill commands...
179                                         {
180                                                 eDVBDiseqcCommand diseqc;
181                                                 diseqc.len = 4;
182                                                 diseqc.data[0] = i ? 0xE1 : 0xE0;
183                                                 diseqc.data[1] = 0x10;
184
185                                                 if ( !send_csw || (di_param.m_swap_cmds && send_ucsw) )
186                                                 {
187                                                         diseqc.data[2] = 0x39;
188                                                         diseqc.data[3] = ucsw;
189                                                 }
190                                                 else
191                                                 {
192                                                         diseqc.data[2] = 0x38;
193                                                         diseqc.data[3] = csw;
194                                                 }
195                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
196
197                                                 i++;
198                                                 if ( i < loops )
199                                                 {
200                                                         int cmd=0;
201                                                         if (diseqc.data[2] == 0x38 && send_ucsw)
202                                                                 cmd=0x39;
203                                                         else if (diseqc.data[2] == 0x39 && send_csw)
204                                                                 cmd=0x38;
205                                                         if (cmd)
206                                                         {
207                                                                 static int delay = (120 - 54) / 2;  // standard says 100msek between two repeated commands
208                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay) );
209                                                                 diseqc.data[2]=cmd;
210                                                                 diseqc.data[3]=(cmd==0x38) ? csw : ucsw;
211                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
212                                                                 ++i;
213                                                                 if ( i < loops )
214                                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay ) );
215                                                                 else
216                                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
217                                                         }
218                                                         else  // delay 120msek when no command is in repeat gap
219                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 120) );
220                                                 }
221                                                 else
222                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
223                                         }
224                                 }
225                                 if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 && curRotorPos != sat.orbital_position )
226                                 {
227                                 }
228                                 if ( (changed_burst || send_diseqc) && di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
229                                 {
230                                         sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
231                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
232                                 }
233                         }
234                         else
235                         {
236                                 sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
237                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 10) );
238                         }
239
240                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
241                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) );
242
243                         frontend.setSecSequence(sec_sequence);
244
245                         return 0;
246                 }
247         }
248
249         eDebug("not found satellite configuration for orbital position (%d)", sat.orbital_position );
250
251         return -1;
252 }
253