From d5023cdac1fb8340fad05e0823d40d38abfe355c Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 27 Jul 2014 17:45:34 +0200 Subject: [PATCH] linuxdvb: rotor - remember the last orbital position to skip movement... --- src/input/mpegts/linuxdvb/linuxdvb_private.h | 6 ++++ src/input/mpegts/linuxdvb/linuxdvb_rotor.c | 29 ++++++++++++++++++++ src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 5 ++++ src/input/mpegts/mpegts_dvb.h | 3 ++ src/input/mpegts/mpegts_network_dvb.c | 21 ++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index a5e89da6..4089ca14 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -137,6 +137,12 @@ struct linuxdvb_satconf * LNB settings */ int ls_lnb_poweroff; + + /* + * Position + */ + int ls_orbital_pos; + char ls_orbital_dir; /* * Satconf elements diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 4ded7004..0b6a6410 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -129,12 +129,38 @@ const idclass_t linuxdvb_rotor_usals_class = * Class methods * *************************************************************************/ +static int +linuxdvb_rotor_check_orbital_pos + ( dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls ) +{ + int pos; + char dir; + + + if (dvb_network_get_orbital_pos(lm->mm_network, &pos, &dir) < 0) + return 0; + + if (dir != ls->lse_parent->ls_orbital_dir) + return 0; + + if (abs(pos - ls->lse_parent->ls_orbital_pos) > 2) + return 0; + + 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; + + if (linuxdvb_rotor_check_orbital_pos(lm, ls)) + return 0; + 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); @@ -199,6 +225,9 @@ linuxdvb_rotor_usals_tune int angle_1 = (((motor_angle > 0.0) ? 0xd0 : 0xe0) | (sixteenths >> 8)); int angle_2 = (sixteenths & 0xff); + if (linuxdvb_rotor_check_orbital_pos(lm, ls)) + return 0; + tvhtrace("diseqc", "rotor USALS goto %0.1f%c (motor %0.2f %sclockwise)", fabs(pos), (pos > 0.0) ? 'E' : 'W', motor_angle, (motor_angle > 0.0) ? "counter-" : ""); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index d4351e0f..b8fa0e38 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -649,6 +649,11 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) } } + /* Remember the last network position for rotor */ + dvb_network_get_orbital_pos(lm->mm_network, + &lse->lse_parent->ls_orbital_pos, + &lse->lse_parent->ls_orbital_dir); + /* Set the tone */ b = lse->lse_lnb->lnb_band(lse->lse_lnb, lm); tvhtrace("disqec", "set diseqc tone %s", b ? "on" : "off"); diff --git a/src/input/mpegts/mpegts_dvb.h b/src/input/mpegts/mpegts_dvb.h index 5c3ed2bd..b426040d 100644 --- a/src/input/mpegts/mpegts_dvb.h +++ b/src/input/mpegts/mpegts_dvb.h @@ -46,6 +46,9 @@ dvb_network_t *dvb_network_find_by_uuid(const char *uuid); dvb_network_t *dvb_network_create0 ( const char *uuid, const idclass_t *idc, htsmsg_t *conf ); +int dvb_network_get_orbital_pos + ( mpegts_network_t *mn, int *pos, char *dir ); + /* * */ diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index 7680c1fd..0eefbe0d 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -632,6 +632,27 @@ dvb_network_find_by_uuid(const char *uuid) return (dvb_network_t*)in; } +int dvb_network_get_orbital_pos + ( mpegts_network_t *mn, int *pos, char *dir ) +{ + dvb_network_t *ln = (dvb_network_t *)mn; + mpegts_mux_t *mm; + dvb_mux_t *lm = NULL; + + LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) { + lm = (dvb_mux_t *)mm; + if (lm->lm_tuning.u.dmc_fe_qpsk.orbital_dir) + break; + } + if (lm) { + *pos = lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos; + *dir = lm->lm_tuning.u.dmc_fe_qpsk.orbital_dir; + return 0; + } else { + return -1; + } +} + /****************************************************************************** * Editor Configuration *