aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>2005-05-20 19:41:31 +0000
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>2005-05-20 19:41:31 +0000
commit4c1d83d373b4a0737da668945d1ddb3278b6c3b7 (patch)
treeb03235e5b74eacfe2092ba1b62493ecb2c7a903e /lib
parent1eb32db73e712e251ca1c52654649a3afc364dde (diff)
downloadenigma2-4c1d83d373b4a0737da668945d1ddb3278b6c3b7.tar.gz
enigma2-4c1d83d373b4a0737da668945d1ddb3278b6c3b7.zip
work on rotor support, add usals stuff (rotor stuff not completed yet),
only send diseqc when needed
Diffstat (limited to 'lib')
-rw-r--r--lib/dvb/Makefile.am4
-rw-r--r--lib/dvb/frontend.cpp4
-rw-r--r--lib/dvb/frontend.h5
-rw-r--r--lib/dvb/rotor_calc.cpp257
-rw-r--r--lib/dvb/rotor_calc.h4
-rw-r--r--lib/dvb/sec.cpp112
-rw-r--r--lib/dvb/sec.h7
-rw-r--r--lib/gdi/Makefile.am2
-rw-r--r--lib/gdi/gfbdc.cpp4
-rw-r--r--lib/gdi/sdl.cpp2
10 files changed, 387 insertions, 14 deletions
diff --git a/lib/dvb/Makefile.am b/lib/dvb/Makefile.am
index 41ce1748..2a1402bb 100644
--- a/lib/dvb/Makefile.am
+++ b/lib/dvb/Makefile.am
@@ -4,5 +4,5 @@ INCLUDES = \
noinst_LIBRARIES = libenigma_dvb.a
libenigma_dvb_a_SOURCES = dvb.cpp demux.cpp frontend.cpp esection.cpp db.cpp \
- sec.cpp scan.cpp crc32.cpp pmt.cpp decoder.cpp eit.cpp
- \ No newline at end of file
+ sec.cpp scan.cpp crc32.cpp pmt.cpp decoder.cpp eit.cpp rotor_calc.cpp
+
diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
index a2730962..1136d9dc 100644
--- a/lib/dvb/frontend.cpp
+++ b/lib/dvb/frontend.cpp
@@ -710,7 +710,7 @@ RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
RESULT eDVBFrontend::getData(int num, int &data)
{
- if ( num < 4 )
+ if ( num < 5 )
{
data = m_data[num];
return 0;
@@ -720,7 +720,7 @@ RESULT eDVBFrontend::getData(int num, int &data)
RESULT eDVBFrontend::setData(int num, int val)
{
- if ( num < 4 )
+ if ( num < 5 )
{
m_data[num] = val;
return 0;
diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h
index fce94e5e..e6beb680 100644
--- a/lib/dvb/frontend.h
+++ b/lib/dvb/frontend.h
@@ -53,11 +53,12 @@ class eDVBFrontend: public iDVBFrontend, public Object
eSecCommandList m_sec_sequence;
- int m_data[4]; /* when satellite frontend then
+ int m_data[5]; /* when satellite frontend then
data[0] = lastcsw -> state of the committed switch
data[1] = lastucsw -> state of the uncommitted switch
data[2] = lastToneburst -> current state of toneburst switch
- data[3] = prevRotorPos -> current Rotor Position */
+ data[3] = lastRotorCmd -> last sent rotor cmd
+ data[4] = curRotorPos -> current Rotor Position */
void feEvent(int);
void timeout();
diff --git a/lib/dvb/rotor_calc.cpp b/lib/dvb/rotor_calc.cpp
new file mode 100644
index 00000000..41322360
--- /dev/null
+++ b/lib/dvb/rotor_calc.cpp
@@ -0,0 +1,257 @@
+#include <cmath>
+
+/*----------------------------------------------------------------------------*/
+double factorial_div( double value, int x)
+{
+ if(!x)
+ return 1;
+ else
+ {
+ while( x > 1)
+ {
+ value = value / x--;
+ }
+ }
+ return value;
+}
+
+/*----------------------------------------------------------------------------*/
+double powerd( double x, int y)
+{
+ int i=0;
+ double ans=1.0;
+
+ if(!y)
+ return 1.000;
+ else
+ {
+ while( i < y)
+ {
+ i++;
+ ans = ans * x;
+ }
+ }
+ return ans;
+}
+
+/*----------------------------------------------------------------------------*/
+double SIN( double x)
+{
+ int i=0;
+ int j=1;
+ int sign=1;
+ double y1 = 0.0;
+ double diff = 1000.0;
+
+ if (x < 0.0)
+ {
+ x = -1 * x;
+ sign = -1;
+ }
+
+ while ( x > 360.0*M_PI/180)
+ {
+ x = x - 360*M_PI/180;
+ }
+
+ if( x > (270.0 * M_PI / 180) )
+ {
+ sign = sign * -1;
+ x = 360.0*M_PI/180 - x;
+ }
+ else if ( x > (180.0 * M_PI / 180) )
+ {
+ sign = sign * -1;
+ x = x - 180.0 *M_PI / 180;
+ }
+ else if ( x > (90.0 * M_PI / 180) )
+ {
+ x = 180.0 *M_PI / 180 - x;
+ }
+
+ while( powerd( diff, 2) > 1.0E-16 )
+ {
+ i++;
+ diff = j * factorial_div( powerd( x, (2*i -1)) ,(2*i -1));
+ y1 = y1 + diff;
+ j = -1 * j;
+ }
+ return ( sign * y1 );
+}
+
+/*----------------------------------------------------------------------------*/
+double COS(double x)
+{
+ return SIN(90 * M_PI / 180 - x);
+}
+
+/*----------------------------------------------------------------------------*/
+double ATAN( double x)
+{
+ int i=0; /* counter for terms in binomial series */
+ int j=1; /* sign of nth term in series */
+ int k=0;
+ int sign = 1; /* sign of the input x */
+ double y = 0.0; /* the output */
+ double deltay = 1.0; /* the value of the next term in the series */
+ double addangle = 0.0; /* used if arctan > 22.5 degrees */
+
+ if (x < 0.0)
+ {
+ x = -1 * x;
+ sign = -1;
+ }
+
+ while( x > 0.3249196962 )
+ {
+ k++;
+ x = (x - 0.3249196962) / (1 + x * 0.3249196962);
+ }
+
+ addangle = k * 18.0 *M_PI/180;
+
+ while( powerd( deltay, 2) > 1.0E-16 )
+ {
+ i++;
+ deltay = j * powerd( x, (2*i -1)) / (2*i -1);
+ y = y + deltay;
+ j = -1 * j;
+ }
+ return (sign * (y + addangle) );
+}
+
+double ASIN(double x)
+{
+ return 2 * ATAN( x / (1 + std::sqrt(1.0 - x*x)));
+}
+
+double Radians( double number )
+{
+ return number*M_PI/180;
+}
+
+double Deg( double number )
+{
+ return number*180/M_PI;
+}
+
+double Rev( double number )
+{
+ return number - std::floor( number / 360.0 ) * 360;
+}
+
+double calcElevation( double SatLon, double SiteLat, double SiteLon, int Height_over_ocean = 0 )
+{
+ double a0=0.58804392,
+ a1=-0.17941557,
+ a2=0.29906946E-1,
+ a3=-0.25187400E-2,
+ a4=0.82622101E-4,
+
+ f = 1.00 / 298.257, // Earth flattning factor
+
+ r_sat=42164.57, // Distance from earth centre to satellite
+
+ r_eq=6378.14, // Earth radius
+
+ sinRadSiteLat=SIN(Radians(SiteLat)),
+ cosRadSiteLat=COS(Radians(SiteLat)),
+
+ Rstation = r_eq / ( std::sqrt( 1.00 - f*(2.00-f)*sinRadSiteLat*sinRadSiteLat ) ),
+
+ Ra = (Rstation+Height_over_ocean)*cosRadSiteLat,
+ Rz= Rstation*(1.00-f)*(1.00-f)*sinRadSiteLat,
+
+ alfa_rx=r_sat*COS(Radians(SatLon-SiteLon)) - Ra,
+ alfa_ry=r_sat*SIN(Radians(SatLon-SiteLon)),
+ alfa_rz=-Rz,
+
+ alfa_r_north=-alfa_rx*sinRadSiteLat + alfa_rz*cosRadSiteLat,
+ alfa_r_zenith=alfa_rx*cosRadSiteLat + alfa_rz*sinRadSiteLat,
+
+ El_geometric=Deg(ATAN( alfa_r_zenith/std::sqrt(alfa_r_north*alfa_r_north+alfa_ry*alfa_ry))),
+
+ x = std::fabs(El_geometric+0.589),
+ refraction=std::fabs(a0+a1*x+a2*x*x+a3*x*x*x+a4*x*x*x*x),
+
+ El_observed = 0.00;
+
+ if (El_geometric > 10.2)
+ El_observed = El_geometric+0.01617*(COS(Radians(std::fabs(El_geometric)))/SIN(Radians(std::fabs(El_geometric))) );
+ else
+ El_observed = El_geometric+refraction;
+
+ if (alfa_r_zenith < -3000)
+ El_observed=-99;
+
+ return El_observed;
+}
+
+double calcAzimuth(double SatLon, double SiteLat, double SiteLon, int Height_over_ocean=0)
+{
+ double f = 1.00 / 298.257, // Earth flattning factor
+
+ r_sat=42164.57, // Distance from earth centre to satellite
+
+ r_eq=6378.14, // Earth radius
+
+ sinRadSiteLat=SIN(Radians(SiteLat)),
+ cosRadSiteLat=COS(Radians(SiteLat)),
+
+ Rstation = r_eq / ( std::sqrt( 1 - f*(2-f)*sinRadSiteLat*sinRadSiteLat ) ),
+ Ra = (Rstation+Height_over_ocean)*cosRadSiteLat,
+ Rz = Rstation*(1-f)*(1-f)*sinRadSiteLat,
+
+ alfa_rx = r_sat*COS(Radians(SatLon-SiteLon)) - Ra,
+ alfa_ry = r_sat*SIN(Radians(SatLon-SiteLon)),
+ alfa_rz = -Rz,
+
+ alfa_r_north = -alfa_rx*sinRadSiteLat + alfa_rz*cosRadSiteLat,
+
+ Azimuth = 0.00;
+
+ if (alfa_r_north < 0)
+ Azimuth = 180+Deg(ATAN(alfa_ry/alfa_r_north));
+ else
+ Azimuth = Rev(360+Deg(ATAN(alfa_ry/alfa_r_north)));
+
+ return Azimuth;
+}
+
+double calcDeclination( double SiteLat, double Azimuth, double Elevation)
+{
+ return Deg( ASIN(SIN(Radians(Elevation)) *
+ SIN(Radians(SiteLat)) +
+ COS(Radians(Elevation)) *
+ COS(Radians(SiteLat)) +
+ COS(Radians(Azimuth))
+ )
+ );
+}
+
+double calcSatHourangle( double SatLon, double SiteLat, double SiteLon )
+{
+ double Azimuth=calcAzimuth(SatLon, SiteLat, SiteLon ),
+ Elevation=calcElevation( SatLon, SiteLat, SiteLon ),
+
+ a = - COS(Radians(Elevation)) * SIN(Radians(Azimuth)),
+
+ b = SIN(Radians(Elevation)) * COS(Radians(SiteLat))
+ -
+ COS(Radians(Elevation)) * SIN(Radians(SiteLat)) * COS(Radians(Azimuth)),
+
+// Works for all azimuths (northern & southern hemisphere)
+ returnvalue = 180 + Deg(ATAN(a/b));
+
+ if ( Azimuth > 270 )
+ {
+ returnvalue = ( (returnvalue-180) + 360 );
+ if (returnvalue>360)
+ returnvalue = 360 - (returnvalue-360);
+ }
+
+ if ( Azimuth < 90 )
+ returnvalue = ( 180 - returnvalue );
+
+ return returnvalue;
+}
diff --git a/lib/dvb/rotor_calc.h b/lib/dvb/rotor_calc.h
new file mode 100644
index 00000000..dde45d22
--- /dev/null
+++ b/lib/dvb/rotor_calc.h
@@ -0,0 +1,4 @@
+#ifndef __LIB_ROTOR_CALC_H__
+#define __LIB_ROTOR_CALC_H__
+double calcSatHourangle( double SatLon, double SiteLat, double SiteLon );
+#endif // __LIB_ROTOR_CALC_H__ \ No newline at end of file
diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp
index 475739f7..98b00cf9 100644
--- a/lib/dvb/sec.cpp
+++ b/lib/dvb/sec.cpp
@@ -1,5 +1,7 @@
#include <config.h>
#include <lib/dvb/sec.h>
+#include <lib/dvb/rotor_calc.h>
+
#if HAVE_DVB_API_VERSION < 3
#define INVERSION Inversion
#define FREQUENCY Frequency
@@ -23,7 +25,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl()
eDVBSatelliteDiseqcParameters &diseqc_ref = astra1.m_diseqc_parameters;
eDVBSatelliteSwitchParameters &switch_ref = astra1.m_switch_parameters;
- lnb_ref.m_lof_hi = 10607000;
+ lnb_ref.m_lof_hi = 10600000;
lnb_ref.m_lof_lo = 9750000;
lnb_ref.m_lof_threshold = 11700000;
@@ -52,6 +54,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
{
eDVBSatelliteDiseqcParameters &di_param = sit->second.m_diseqc_parameters;
eDVBSatelliteSwitchParameters &sw_param = sit->second.m_switch_parameters;
+ eDVBSatelliteRotorParameters &rotor_param = sit->second.m_rotor_parameters;
int hi=0,
voltage = iDVBFrontend::voltageOff,
tone = iDVBFrontend::toneOff,
@@ -61,12 +64,14 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
lastcsw = -1,
lastucsw = -1,
lastToneburst = -1,
+ lastRotorCmd = -1,
curRotorPos = -1;
frontend.getData(0, lastcsw);
frontend.getData(1, lastucsw);
frontend.getData(2, lastToneburst);
- frontend.getData(3, curRotorPos);
+ frontend.getData(3, lastRotorCmd);
+ frontend.getData(4, curRotorPos);
if ( sat.frequency > lnb_param.m_lof_threshold )
hi = 1;
@@ -220,15 +225,112 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
}
else
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+
+ frontend.setData(0, csw);
+ frontend.setData(1, ucsw);
}
}
- if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 && curRotorPos != sat.orbital_position )
- {
- }
if ( (changed_burst || send_diseqc) && di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
{
sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) );
+ frontend.setData(2, di_param.m_toneburst_param);
+ }
+ if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 )
+ {
+ int RotorCmd=0;
+ bool useGotoXX = false;
+
+ std::map<int,int,eDVBSatelliteRotorParameters::Orbital_Position_Compare>::iterator it =
+ rotor_param.m_rotor_position_table.find( sat.orbital_position );
+
+ if (it != rotor_param.m_rotor_position_table.end()) // position for selected sat found ?
+ RotorCmd=it->second;
+ else // entry not in table found
+ {
+ eDebug("Entry for %d,%d° not in Rotor Table found... i try gotoXX°", sat.orbital_position / 10, sat.orbital_position % 10 );
+ useGotoXX = true;
+
+ int satDir = sat.orbital_position < 0 ?
+ eDVBSatelliteRotorParameters::WEST :
+ eDVBSatelliteRotorParameters::EAST;
+
+ double SatLon = abs(sat.orbital_position)/10.00,
+ SiteLat = rotor_param.m_gotoxx_parameters.m_latitude,
+ SiteLon = rotor_param.m_gotoxx_parameters.m_longitude;
+
+ if ( rotor_param.m_gotoxx_parameters.m_la_direction == eDVBSatelliteRotorParameters::SOUTH )
+ SiteLat = -SiteLat;
+
+ if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST )
+ SiteLon = 360 - SiteLon;
+
+ if (satDir == eDVBSatelliteRotorParameters::WEST )
+ SatLon = 360 - SatLon;
+
+ eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon );
+ double satHourAngle =
+ calcSatHourangle( SatLon, SiteLat, SiteLon );
+ eDebug("PolarmountHourAngle=%lf", satHourAngle );
+
+ static int gotoXTable[10] =
+ { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
+
+ if (SiteLat >= 0) // Northern Hemisphere
+ {
+ int tmp=(int)round( fabs( 180 - satHourAngle ) * 10.0 );
+ RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+
+ if (satHourAngle < 180) // the east
+ RotorCmd |= 0xE000;
+ else // west
+ RotorCmd |= 0xD000;
+ }
+ else // Southern Hemisphere
+ {
+ if (satHourAngle < 180) // the east
+ {
+ int tmp=(int)round( fabs( satHourAngle ) * 10.0 );
+ RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+ RotorCmd |= 0xD000;
+ }
+ else // west
+ {
+ int tmp=(int)round( fabs( 360 - satHourAngle ) * 10.0 );
+ RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+ RotorCmd |= 0xE000;
+ }
+ }
+ eDebug("RotorCmd = %04x", RotorCmd);
+ }
+ if ( RotorCmd != lastRotorCmd )
+ {
+ eDVBDiseqcCommand diseqc;
+ diseqc.data[0] = 0xE0;
+ diseqc.data[1] = 0x31; // positioner
+ if ( useGotoXX )
+ {
+ diseqc.len = 5;
+ diseqc.data[2] = 0x6E; // drive to angular position
+ diseqc.data[3] = ((RotorCmd & 0xFF00) / 0x100);
+ diseqc.data[4] = RotorCmd & 0xFF;
+ }
+ else
+ {
+ diseqc.len = 4;
+ 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::MEASURE_IDLE_INPUTPOWER) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+ frontend.setData(3, RotorCmd);
+ frontend.setData(4, sat.orbital_position);
+ }
+ else
+ eFatal("rotor turning without inputpowermeasure not implemented yet");
+ }
}
}
else
diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h
index 7b5e5b2b..645f8b15 100644
--- a/lib/dvb/sec.h
+++ b/lib/dvb/sec.h
@@ -9,7 +9,9 @@ class eSecCommand
{
public:
enum {
- NONE, SLEEP, SET_VOLTAGE, SET_TONE, SEND_DISEQC, SEND_TONEBURST, IF_LOCK_GOTO, IF_NOT_LOCK_GOTO, SET_FRONTEND
+ NONE, SLEEP, SET_VOLTAGE, SET_TONE,
+ SEND_DISEQC, SEND_TONEBURST, IF_LOCK_GOTO, IF_NOT_LOCK_GOTO,
+ MEASURE_IDLE_INPUTPOWER, SET_FRONTEND
};
int cmd;
union
@@ -20,6 +22,9 @@ public:
int msec;
eDVBDiseqcCommand diseqc;
};
+ eSecCommand( int cmd )
+ :cmd(cmd)
+ {}
eSecCommand( int cmd, int val )
:cmd(cmd), voltage(val)
{}
diff --git a/lib/gdi/Makefile.am b/lib/gdi/Makefile.am
index abb75b79..c3fc6556 100644
--- a/lib/gdi/Makefile.am
+++ b/lib/gdi/Makefile.am
@@ -5,4 +5,4 @@ noinst_LIBRARIES = libenigma_gdi.a
libenigma_gdi_a_SOURCES = \
region.cpp grc.cpp epng.cpp erect.cpp fb.cpp font.cpp font_arabic.cpp gfbdc.cpp \
- glcddc.cpp gpixmap.cpp lcd.cpp sdl.cpp gfont.cpp
+ glcddc.cpp gpixmap.cpp lcd.cpp gfont.cpp
diff --git a/lib/gdi/gfbdc.cpp b/lib/gdi/gfbdc.cpp
index 83ffed2b..164258d8 100644
--- a/lib/gdi/gfbdc.cpp
+++ b/lib/gdi/gfbdc.cpp
@@ -157,4 +157,6 @@ void gFBDC::reloadSettings()
setPalette();
}
-// eAutoInitPtr<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");
+#ifndef SDLDC
+eAutoInitPtr<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");
+#endif \ No newline at end of file
diff --git a/lib/gdi/sdl.cpp b/lib/gdi/sdl.cpp
index 591487f4..bf2b585b 100644
--- a/lib/gdi/sdl.cpp
+++ b/lib/gdi/sdl.cpp
@@ -82,4 +82,6 @@ void gSDLDC::exec(gOpcode *o)
}
}
+#ifdef SDLDC
eAutoInitPtr<gSDLDC> init_gSDLDC(eAutoInitNumbers::graphic-1, "gSDLDC");
+#endif