From: Jaroslav Kysela Date: Mon, 15 Dec 2014 14:21:41 +0000 (+0100) Subject: linuxdvb rotor: reshuffle code again X-Git-Tag: v4.1~592 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cfc78aba5fa203c42f5a363847db24eecdf8b23c;p=thirdparty%2Ftvheadend.git linuxdvb rotor: reshuffle code again --- diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 17e9fcac0..25a00a2fc 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -131,80 +131,8 @@ double to_rev( double val ) 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 ) { @@ -256,13 +184,25 @@ void usals_sat_azimuth_and_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); @@ -286,7 +226,92 @@ usals_sat_angle( double site_lat, double site_lon, 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 */ @@ -298,40 +323,18 @@ linuxdvb_rotor_usals_tune { 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, @@ -343,9 +346,6 @@ linuxdvb_rotor_usals_tune } return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm); - -#undef TO_RAD -#undef TO_DEG } static int