From 93f3f6fbddf8b10df2bae54d1b6d72d6295fdbf9 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 22 Mar 2015 16:40:58 +0100 Subject: [PATCH] linuxdvb: improve diseqc switch handling, cleanups --- src/input/mpegts/linuxdvb/linuxdvb_en50494.c | 9 +-- src/input/mpegts/linuxdvb/linuxdvb_lnb.c | 28 +------ src/input/mpegts/linuxdvb/linuxdvb_private.h | 5 +- src/input/mpegts/linuxdvb/linuxdvb_rotor.c | 3 +- src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 40 +++++----- src/input/mpegts/linuxdvb/linuxdvb_switch.c | 78 ++++++++++++-------- 6 files changed, 84 insertions(+), 79 deletions(-) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c index eb143770..08702bb3 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c @@ -158,16 +158,11 @@ const idclass_t linuxdvb_en50494_class = static int linuxdvb_en50494_tune ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, int vol ) + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, + int vol, int pol, int band, int freq ) { int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp); linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld; - linuxdvb_lnb_t *lnb = sc->lse_lnb; - - /* band & polarization */ - uint8_t pol = lnb->lnb_pol(lnb, lm); - uint8_t band = lnb->lnb_band(lnb, lm); - uint32_t freq = lnb->lnb_freq(lnb, lm); /* transponder value - t*/ uint16_t t = round((( (freq / 1000) + 2 + le->le_frequency) / 4) - 350); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c index 664f112d..f8d5878b 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c @@ -111,16 +111,10 @@ linuxdvb_lnb_inverted_pol static int linuxdvb_lnb_standard_tune ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol ) + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, + int vol, int pol, int band, int freq ) { - /* en50494 does not use the voltage tune. this is happend in the switch */ - if (ls->lse_en50494) - return 0; - - /* note: differentiate between linuxdvb_lnb_standard_pol / linuxdvb_lnb_inverted_pol */ - int pol = ((linuxdvb_lnb_t*)ld)->lnb_pol((linuxdvb_lnb_t*)ld, lm); - - return linuxdvb_diseqc_set_volt(ls->lse_parent, pol); + return linuxdvb_diseqc_set_volt(ls->lse_parent, vol); } /* @@ -160,20 +154,6 @@ linuxdvb_lnb_bandstack_pol return 0; } -static int -linuxdvb_lnb_bandstack_tune - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol ) -{ - int pol = linuxdvb_lnb_bandstack_pol((linuxdvb_lnb_t*)ld, lm); - - /* en50494 does not use the voltage tune. this is happend in the switch */ - if (ls->lse_en50494) - return 0; - - return linuxdvb_diseqc_set_volt(ls->lse_parent, pol); -} - /* ************************************************************************** * Static list * *************************************************************************/ @@ -312,7 +292,7 @@ struct linuxdvb_lnb_conf linuxdvb_lnb_all[] = { { { { .ld_type = "DBS Bandstack", - .ld_tune = linuxdvb_lnb_bandstack_tune, + .ld_tune = linuxdvb_lnb_standard_tune, }, .lnb_freq = linuxdvb_lnb_bandstack_freq, .lnb_band = linuxdvb_lnb_bandstack_band, diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 8115dc16..d829a336 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -168,6 +168,8 @@ struct linuxdvb_satconf */ linuxdvb_satconf_ele_list_t ls_elements; linuxdvb_satconf_ele_t *ls_last_switch; + int ls_last_switch_pol; + int ls_last_switch_band; int ls_last_vol; int ls_last_toneburst; int ls_last_tone_off; @@ -214,7 +216,8 @@ struct linuxdvb_diseqc linuxdvb_satconf_ele_t *ld_satconf; int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm); int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int pol); + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, + int vol, int pol, int band, int freq); int (*ld_post) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls); }; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 4b59f60c..2fcb2ce5 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -401,7 +401,8 @@ linuxdvb_rotor_usals_tune static int linuxdvb_rotor_tune ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol ) + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, + int vol, int pol, int band, int freq ) { linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 93b7647b..b704a2b4 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -720,7 +720,7 @@ static void linuxdvb_satconf_ele_tune_cb ( void *o ); static int linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) { - int r, i, b, pol; + int r, i, vol, pol, band, freq; uint32_t f; linuxdvb_satconf_t *ls = lse->lse_parent; @@ -737,10 +737,18 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) (linuxdvb_diseqc_t*)lse->lse_lnb }; - if (!lse->lse_en50494) { - pol = (lse->lse_lnb) ? lse->lse_lnb->lnb_pol(lse->lse_lnb, lm) & 0x1 : 0; + if (lse->lse_lnb) { + pol = lse->lse_lnb->lnb_pol (lse->lse_lnb, lm) & 0x1; + band = lse->lse_lnb->lnb_band(lse->lse_lnb, lm) & 0x1; + freq = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm); } else { - pol = 0; /* 13V */ + tvherror("linuxdvb", "LNB is not defined!!!"); + return -1; + } + if (!lse->lse_en50494) { + vol = pol; + } else { + vol = 0; /* 13V */ } /* @@ -753,7 +761,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) if (!lse->lse_en50494 || lse->lse_switch || lse->lse_rotor) { if (ls->ls_diseqc_full) { ls->ls_last_tone_off = 0; /* force */ - if (linuxdvb_satconf_start(ls, 0, pol)) + if (linuxdvb_satconf_start(ls, 0, vol)) return -1; } } @@ -761,7 +769,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Diseqc */ for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) { if (!lds[i]) continue; - r = lds[i]->ld_tune(lds[i], lm, ls, lse, pol); + r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq); /* Error */ if (r < 0) return r; @@ -781,23 +789,21 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* LNB settings */ /* EN50494 devices have another mechanism to select polarization */ - if (!lse->lse_en50494) { - /* Set the voltage */ - if (linuxdvb_diseqc_set_volt(ls, pol)) - return -1; - } + + /* Set the voltage */ + if (linuxdvb_diseqc_set_volt(ls, vol)) + return -1; /* Set the tone (en50494 don't use tone) */ if (!lse->lse_en50494) { - b = lse->lse_lnb->lnb_band(lse->lse_lnb, lm); - if (ls->ls_diseqc_full || ls->ls_last_tone_off != b + 1) { + if (ls->ls_last_tone_off != band + 1) { ls->ls_last_tone_off = 0; - tvhtrace("diseqc", "set diseqc tone %s", b ? "on" : "off"); - if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, b ? SEC_TONE_ON : SEC_TONE_OFF)) { + tvhtrace("diseqc", "set diseqc tone %s", band ? "on" : "off"); + if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, band ? SEC_TONE_ON : SEC_TONE_OFF)) { tvherror("diseqc", "failed to set diseqc tone (e=%s)", strerror(errno)); return -1; } - ls->ls_last_tone_off = b + 1; + ls->ls_last_tone_off = band + 1; usleep(20000); // Allow LNB to settle before tuning } } @@ -806,7 +812,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* use en50494 tuning frequency, if needed (not channel frequency) */ f = lse->lse_en50494 ? ((linuxdvb_en50494_t*)lse->lse_en50494)->le_tune_freq - : lse->lse_lnb->lnb_freq(lse->lse_lnb, lm); + : freq; return linuxdvb_frontend_tune1(lfe, mmi, f); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index 53cffda6..28753d05 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -43,6 +43,8 @@ typedef struct linuxdvb_switch int ls_toneburst; int ls_committed; int ls_uncommitted; + int ls_uncommitted_first; + int ls_sleep_time; /* in ms */ } linuxdvb_switch_t; @@ -134,6 +136,18 @@ const idclass_t linuxdvb_switch_class = .off = offsetof(linuxdvb_switch_t, ls_toneburst), .list = linuxdvb_switch_class_toneburst_list }, + { + .type = PT_BOOL, + .id = "preferun", + .name = "Uncommited First", + .off = offsetof(linuxdvb_switch_t, ls_uncommitted_first), + }, + { + .type = PT_INT, + .id = "sleeptime", + .name = "Cmd Delay Time (ms) (10-500)", + .off = offsetof(linuxdvb_switch_t, ls_sleep_time) + }, {} } }; @@ -145,60 +159,66 @@ const idclass_t linuxdvb_switch_class = static int linuxdvb_switch_tune ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp, - linuxdvb_satconf_ele_t *sc, int vol ) + linuxdvb_satconf_ele_t *sc, int vol, int pol, int band, int freq ) { - int i, com, r1 = 0, r2 = 0; - int pol, band; + int i, com, r1 = 0, r2 = 0, slp; int fd = linuxdvb_satconf_fe_fd(lsp); linuxdvb_switch_t *ls = (linuxdvb_switch_t*)ld; - if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc) { + if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc || + (ls->ls_committed >= 0 && + (pol + 1 != lsp->ls_last_switch_pol || + band + 1 != lsp->ls_last_switch_band))) { lsp->ls_last_switch = NULL; - if (linuxdvb_satconf_start(lsp, 1, vol)) + if (linuxdvb_satconf_start(lsp, 1, pol)) return -1; - pol = (sc->lse_lnb) ? sc->lse_lnb->lnb_pol (sc->lse_lnb, lm) & 0x1 : 0; - band = (sc->lse_lnb) ? sc->lse_lnb->lnb_band(sc->lse_lnb, lm) & 0x1 : 0; - com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band; - - /* Single committed (before repeats) */ - if (ls->ls_committed >= 0) { - if (lsp->ls_diseqc_repeats > 0) { - r2 = 1; - if (linuxdvb_diseqc_send(fd, 0xE0, 0x10, 0x38, 1, com)) - return -1; - usleep(25000); // 25ms - } - } + com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band; + slp = ls->ls_sleep_time > 10 ? + MAX(500, MIN(25, ls->ls_sleep_time)) * 1000 : + 25000; /* Repeats */ for (i = 0; i <= lsp->ls_diseqc_repeats; i++) { - /* Uncommitted */ - if (ls->ls_uncommitted >= 0) { - if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x39, 1, - 0xF0 | ls->ls_uncommitted)) - return -1; - usleep(25000); - } + if (ls->ls_uncommitted_first) + /* Uncommitted */ + if (ls->ls_uncommitted >= 0) { + if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, + 0xF0 | ls->ls_uncommitted)) + return -1; + usleep(slp); + } /* Committed */ if (ls->ls_committed >= 0) { - if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x38, 1, com)) + if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x38, 1, com)) return -1; - usleep(25000); + usleep(slp); + } + + if (!ls->ls_uncommitted_first) { + /* Uncommitted */ + if (ls->ls_uncommitted >= 0) { + if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, + 0xF0 | ls->ls_uncommitted)) + return -1; + usleep(slp); + } } /* repeat flag */ r1 = r2 = 1; } - lsp->ls_last_switch = sc; + lsp->ls_last_switch = sc; + lsp->ls_last_switch_pol = pol + 1; + lsp->ls_last_switch_band = band + 1; /* port was changed, new LNB has not received toneburst yet */ - lsp->ls_last_toneburst = 0; + lsp->ls_last_toneburst = 0; } /* Tone burst */