return val - floor(val / 360.0) * 360;
}
-/* **************************************************************************
- * Class methods
- * *************************************************************************/
-
-static int
-linuxdvb_rotor_grace
- ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm )
-{
- linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
- linuxdvb_satconf_t *ls = ld->ld_satconf->lse_parent;
- int newpos, delta, tunit;
-
- if (!ls->ls_last_orbital_pos || ls->ls_motor_rate == 0)
- return ls->ls_max_rotor_move;
-
- newpos = pos_to_integer(lr->lr_sat_lon);
- tunit = 10000; /* 1/1000 sec per one degree */
-
- delta = abs(deltaI32(ls->ls_last_orbital_pos, newpos));
-
- /* ignore very small movements like 0.8W and 1W */
- if (delta <= 2)
- return 0;
-
- /* add one extra second, because of the rounding issue */
- return ((ls->ls_motor_rate*delta+(tunit-1))/tunit) + 1;
-}
-
-static int
-linuxdvb_rotor_check_orbital_pos
- ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls )
-{
- linuxdvb_satconf_t *lsp = ls->lse_parent;
- int pos = lsp->ls_last_orbital_pos;
- char dir;
-
- if (!pos)
- return 0;
-
- if (abs(pos_to_integer(lr->lr_sat_lon) - pos) > 2)
- return 0;
-
- dir = 'E';
- if (pos < 0) {
- pos = -(pos);
- dir = 'W';
- }
- tvhdebug("diseqc", "rotor already positioned to %i.%i%c",
- pos / 10, pos % 10, dir);
- return 1;
-}
-
-/* GotoX */
-static int
-linuxdvb_rotor_gotox_tune
- ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
-{
- int i;
-
- for (i = 0; i <= ls->lse_parent->ls_diseqc_repeats; i++) {
- if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6B, 1, (int)lr->lr_position)) {
- tvherror("diseqc", "failed to set GOTOX pos %d", lr->lr_position);
- return -1;
- }
- usleep(25000);
- }
-
- tvhdebug("diseqc", "rotor GOTOX pos %d sent", lr->lr_position);
-
- return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm);
-}
-
static
-void usals_sat_azimuth_and_elevation
+void sat_azimuth_and_elevation
( double site_lat, double site_lon, double site_alt, double sat_lon,
double *azimuth, double *elevation )
{
* Satellite Longtitute
*/
static double
-usals_sat_angle( double site_lat, double site_lon,
- double site_alt, double sat_lon )
+sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls )
{
+ linuxdvb_satconf_t *lsp = ls->lse_parent;
+ double site_lat = lsp->ls_site_lat;
+ double site_lon = lsp->ls_site_lon;
+ double site_alt = lsp->ls_site_altitude;
+ double sat_lon = lr->lr_sat_lon;
+
+ if (lsp->ls_site_lat_south)
+ site_lat = -site_lat;
+ if (lsp->ls_site_lon_west)
+ site_lon = 360 - site_lon;
+ if (sat_lon < 0)
+ sat_lon = 360 - sat_lon;
+
double azimuth, elevation;
- usals_sat_azimuth_and_elevation(site_lat, site_lon, site_alt, sat_lon,
- &azimuth, &elevation);
+ sat_azimuth_and_elevation(site_lat, site_lon, site_alt, sat_lon,
+ &azimuth, &elevation);
tvhtrace("diseqc", "rotor angle azimuth %.4f elevation %.4f", azimuth, elevation);
if (azimuth < 90)
value = 180 - value;
- return value;
+ int ret;
+
+ if (site_lat >= 0) {
+ ret = round(fabs(180 - value) * 10.0);
+ if (value >= 180)
+ ret = -(ret);
+ } else if (value < 180) {
+ ret = -round(fabs(value) * 10.0);
+ } else {
+ ret = round(fabs(360 - value) * 10.0);
+ }
+
+ return ret;
+}
+
+/* **************************************************************************
+ * Class methods
+ * *************************************************************************/
+
+static int
+linuxdvb_rotor_grace
+ ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm )
+{
+ linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
+ linuxdvb_satconf_t *ls = ld->ld_satconf->lse_parent;
+ int newpos, delta, tunit;
+
+ if (!ls->ls_last_orbital_pos || ls->ls_motor_rate == 0)
+ return ls->ls_max_rotor_move;
+
+ newpos = pos_to_integer(lr->lr_sat_lon);
+
+ tunit = 10000; /* 1/1000 sec per one degree */
+
+ delta = abs(deltaI32(ls->ls_last_orbital_pos, newpos));
+
+ /* ignore very small movements like 0.8W and 1W */
+ if (delta <= 2)
+ return 0;
+
+ /* add one extra second, because of the rounding issue */
+ return ((ls->ls_motor_rate*delta+(tunit-1))/tunit) + 1;
+}
+
+static int
+linuxdvb_rotor_check_orbital_pos
+ ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls )
+{
+ linuxdvb_satconf_t *lsp = ls->lse_parent;
+ int pos = lsp->ls_last_orbital_pos;
+ char dir;
+
+ if (!pos)
+ return 0;
+
+ if (abs(pos_to_integer(lr->lr_sat_lon) - pos) > 2)
+ return 0;
+
+ dir = 'E';
+ if (pos < 0) {
+ pos = -(pos);
+ dir = 'W';
+ }
+ tvhdebug("diseqc", "rotor already positioned to %i.%i%c",
+ pos / 10, pos % 10, dir);
+ return 1;
+}
+
+/* GotoX */
+static int
+linuxdvb_rotor_gotox_tune
+ ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+{
+ int i;
+
+ for (i = 0; i <= ls->lse_parent->ls_diseqc_repeats; i++) {
+ if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6B, 1, (int)lr->lr_position)) {
+ tvherror("diseqc", "failed to set GOTOX pos %d", lr->lr_position);
+ return -1;
+ }
+ usleep(25000);
+ }
+
+ tvhdebug("diseqc", "rotor GOTOX pos %d sent", lr->lr_position);
+
+ return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm);
}
/* USALS */
{ 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
linuxdvb_satconf_t *lsp = ls->lse_parent;
+ int i, angle = sat_angle(lr, ls);
+ uint32_t cmd = 0xE000;
- double site_lat = lsp->ls_site_lat;
- double site_lon = lsp->ls_site_lon;
- double sat_lon = lr->lr_sat_lon;
- double motor_angle;
- uint32_t tmp, cmd;
- int i;
-
- if (lsp->ls_site_lat_south)
- site_lat = -site_lat;
- if (lsp->ls_site_lon_west)
- site_lon = 360 - site_lon;
- if (sat_lon < 0)
- sat_lon = 360 - sat_lon;
-
- motor_angle = usals_sat_angle(site_lat, site_lon,
- lsp->ls_site_altitude,
- sat_lon);
-
- if (site_lat >= 0) {
- tmp = round(fabs(180 - motor_angle) * 10.0);
- cmd = ((tmp / 10) * 0x10 + xtable[tmp % 10]) |
- (motor_angle < 180 ? 0xE000 : 0xD000);
- } else if (motor_angle < 180) {
- tmp = round(fabs(motor_angle) * 10.0);
- cmd = ((tmp / 10) * 0x10 + xtable[tmp % 10]) | 0xD000;
- } else {
- tmp = round(fabs(360 - motor_angle) * 10.0);
- cmd = ((tmp / 10) * 0x10 + xtable[tmp % 10]) | 0xE000;
+ if (angle < 0) {
+ angle = -(angle);
+ cmd = 0xD000;
}
+ cmd |= (angle / 10) * 0x10 + xtable[angle % 10];
tvhdebug("diseqc", "rotor USALS goto %0.1f%c (motor %0.1f %sclockwise)",
fabs(lr->lr_sat_lon), (lr->lr_sat_lon > 0.0) ? 'E' : 'W',
- ((double)tmp / 10.0), (cmd & 0xF000) == 0xD000 ? "counter-" : "");
+ ((double)angle / 10.0), (cmd & 0xF000) == 0xD000 ? "counter-" : "");
for (i = 0; i <= lsp->ls_diseqc_repeats; i++) {
if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6E, 2,
}
return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm);
-
-#undef TO_RAD
-#undef TO_DEG
}
static int