Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Re: Channel switching
Klaus Schmidinger wrote:
>
> I therefore commented out the checks whether the settings have actually changed,
> so that the tuning commands would always be sent to the DVB card. The result was
> that still sometimes channels don't sync at the first attempt, but (as far as I
> have seen in my tests) they always sync when VDR retries tuning to the same channel.
...
> --- dvb.c.001 Fri Sep 7 08:21:43 2001
> +++ dvb.c Sat Sep 8 11:28:02 2001
> @@ -2771,16 +2772,20 @@
> {
> switch (dvb->dvbtype) {
> case DVB_S:
> +/*
> if (dvb->front.srate!=dvb->new_srate ||
> dvb->front.fec!=dvb->new_fec) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since your ctest.c uses FEC_AUTO, and fe_lock() reads the real FEC
from the frontend into dvb->front.fec, this test will always
evaluate to TRUE, and the demodulator parameters will be always be set.
*Except* when the previous channel failed to sync. Then, dvb->front.fec
will keep the FEC_AUTO value, which explains why your retries had no effect.
The datasheet for the VES1893 and stv0299 say that they continuously
try to sync, so it shouldn't make much of a difference...
> +*/
> dvb->front.srate=dvb->new_srate;
> dvb->front.fec=dvb->new_fec;
> demod_command(dvb, DVB_SET_FRONTEND, &dvb->front);
> //if (dvb->demod_type==DVB_DEMOD_STV0299)
> demod_command(dvb, DVB_RESET, 0);
> +/*
> }
> if (dvb->front.freq==dvb->new_freq && fe_lock(dvb))
> return mon_complete(dvb);
> +*/
>
> dvb->front.freq=dvb->new_freq;
> tuner_command(dvb, TUNER_SET_TVFREQ, &dvb->front.freq);
My understanding of the DVB hardware suggests to set the tuner
before setting the demodulator, but again, the VES1893 and stv0299
should be able to sync anyway.
I added some debug prints to the driver's tuning code to find out what
it actually does. It showed that there were a lot of
zig-zag scans. I tentatively tried to improve the tuning code by
- doing the tuner_command first
- always doing a DVB_RESET after a tuner_command or a demod_command
With this modificatons, fe_lock() almost always returns TRUE on
the first try with ctest and with my own test progams, and I don't
get any failed syncs anymore.
I append a patch against the current CVS which includes my debug
prints.
Note: I only tested DVB-S, not DVB-C.
Index: dvb.c
===================================================================
RCS file: /cvs/linuxtv/DVB/driver/dvb.c,v
retrieving revision 1.91
diff -u -r1.91 dvb.c
--- dvb.c 2001/09/06 19:28:29 1.91
+++ dvb.c 2001/09/10 17:42:28
@@ -2678,6 +2678,13 @@
{
struct qpskEvent ev;
+ printk(KERN_DEBUG "mon_complete: freq=%d, sr=%d, "
+ "realfreq=%d, step=%-2d, fdiff=%d, fec=%d\n",
+ dvb->front.freq, dvb->front.srate,
+ dvb->front.curfreq,
+ dvb->mon_fstate,
+ (dvb->front.curfreq - dvb->front.freq),
+ dvb->front.fec);
ev.type=FE_COMPLETION_EV;
ev.u.completionEvent.iFrequency=dvb->front.freq/1000;
ev.u.completionEvent.SymbolRate=dvb->front.srate;
@@ -2719,6 +2726,8 @@
dvb->mon_tuning=0;
ev.type=FE_FAILURE_EV;
add_qpsk_event(&dvb->qpsk, &ev);
+ printk(KERN_DEBUG "mon_fail: freq=%d, sr=%d\n",
+ dvb->front.freq, dvb->front.srate);
break;
}
case DVB_C:
@@ -2739,9 +2748,10 @@
mon_zigzag(struct dvb_struct *dvb)
{
int i=dvb->mon_fstate;
- u32 sfreq=dvb->front.curfreq=dvb->front.freq;
+ u32 sfreq=dvb->front.freq;
u32 soff=dvb->front.srate/16;
+ printk("mon_zigzag: i=%d freq=%d\n", i, sfreq);
if (fe_lock(dvb))
return mon_complete(dvb);
if (i==20)
@@ -2769,31 +2779,43 @@
static int
mon_tune(struct dvb_struct *dvb)
{
+ int kickit = 0, locked = 0;
+
+ printk("mon_tune\n");
switch (dvb->dvbtype) {
case DVB_S:
- if (dvb->front.srate!=dvb->new_srate ||
- dvb->front.fec!=dvb->new_fec) {
- dvb->front.srate=dvb->new_srate;
- dvb->front.fec=dvb->new_fec;
- demod_command(dvb, DVB_SET_FRONTEND, &dvb->front);
- //if (dvb->demod_type==DVB_DEMOD_STV0299)
- demod_command(dvb, DVB_RESET, 0);
- }
- if (dvb->front.freq==dvb->new_freq && fe_lock(dvb))
- return mon_complete(dvb);
-
- dvb->front.freq=dvb->new_freq;
- tuner_command(dvb, TUNER_SET_TVFREQ, &dvb->front.freq);
- if (dvb->demod_type==DVB_DEMOD_STV0299)
- demod_command(dvb, DVB_RESET, 0);
+ locked = fe_lock(dvb);
+ if (! locked || dvb->front.freq != dvb->new_freq) {
+ printk("mon_tune: TUNER_SET_TVFREQ\n");
+ dvb->front.freq = dvb->new_freq;
+ tuner_command(dvb, TUNER_SET_TVFREQ, &dvb->front.freq);
+ kickit = 1;
+ }
+ /* if locked == 1, dvb->front.fec is guaranteed to be != FEC_AUTO,
+ * so using FEC_AUTO will always reset the demod
+ */
+ if (!locked
+ || dvb->front.srate != dvb->new_srate
+ || dvb->front.fec != dvb->new_fec) {
+ dvb->front.srate = dvb->new_srate;
+ dvb->front.fec = dvb->new_fec;
+ printk("mon_tune: DVB_SET_FRONTEND\n");
+ demod_command(dvb, DVB_SET_FRONTEND, &dvb->front);
+ kickit = 1;
+ }
+ if (kickit)
+ demod_command(dvb, DVB_RESET, 0);
dprintk("freq=%d\n", dvb->new_freq);
mdelay(10);
- if (fe_lock(dvb))
+ dvb->mon_fstate = 1;
+ dvb->front.curfreq = dvb->front.freq;
+ if (fe_lock(dvb)) {
+ printk("mon_tune: locked on 1st try\n");
return mon_complete(dvb);
+ }
+ printk("need zigzag, freq=%d\n", dvb->new_freq);
dvb->mon_tuning=2;
- dvb->mon_fstate=1;
dvb->mon_delay=HZ/10;
- dvb->front.curfreq=dvb->front.freq;
return 0;
case DVB_C:
case DVB_T:
===================================================================
I also patched ctest to
- log each channel switch via syslog, so i can match it with
the driver log
- set FEC explicitly, not via FEC_AUTO
===================================================================
--- ctest.c Mon Sep 10 15:58:49 2001
+++ ctest-km.c Mon Sep 10 17:32:40 2001
@@ -11,7 +11,6 @@
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <unistd.h>
-#include <syslog.h>
#define LOG_ERROR fprintf(stderr, "\nERROR (%s,%d): %m\n", __FILE__, __LINE__);
#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
@@ -20,7 +19,6 @@
char *name;
int freq;
char pol;
- int fec;
int diseqc;
int srate;
int vpid;
@@ -31,14 +29,14 @@
tChannel SatChannels[] = {
#define XXX
#ifdef XXX
- { "RTL", 12188, 'h', 3, 0, 27500, 163, 104, 105 },
- { "Sat.1", 12480, 'v', 3, 0, 27500, 1791, 1792, 34 },
- { "Pro-7", 12480, 'v', 3, 0, 27500, 255, 256, 32 },
- { "ORF1", 12692, 'h', 4, 0, 22000, 160, 161, 165 },
- { "DW TV", 12363, 'v', 3, 0, 27500, 305, 306, 0 },
- { "BLOOMBERG TV", 11817, 'v', 3, 0, 27500, 163, 92, 0 },
- { "Premiere World Promo", 11798, 'h', 3, 0, 27500, 255, 256, 0 },
- { "13th Street", 11797, 'h', 3, 0, 27500, 2303, 2304, 0 },
+ { "RTL", 12188, 'h', 0, 27500, 163, 104, 105 },
+ { "Sat.1", 12480, 'v', 0, 27500, 1791, 1792, 34 },
+ { "Pro-7", 12480, 'v', 0, 27500, 255, 256, 32 },
+ { "ORF1", 12692, 'h', 0, 22000, 160, 161, 165 },
+ { "DW TV", 12363, 'v', 0, 27500, 305, 306, 0 },
+ { "BLOOMBERG TV", 11817, 'v', 0, 27500, 163, 92, 0 },
+ { "Premiere World Promo", 11798, 'h', 0, 27500, 255, 256, 0 },
+ { "13th Street", 11797, 'h', 0, 27500, 2303, 2304, 0 },
/*
{ "ORF1", 12692, 'h', 0, 22000, 160, 161, 165 },
{ "DW TV", 12363, 'v', 0, 27500, 305, 306, 0 },
@@ -388,7 +386,7 @@
fprintf(stderr, "P");//XXX
}
-bool SetChannel(int FrequencyMHz, char Polarization, int Fec, int Diseqc, int Srate, int Vpid, int Apid, int Tpid)
+bool SetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid)
{
bool ChannelSynced = false;
@@ -430,7 +428,7 @@
qpskParameters qpsk;
qpsk.iFrequency = freq * 1000UL;
qpsk.SymbolRate = Srate * 1000UL;
- qpsk.FEC_inner = Fec;
+ qpsk.FEC_inner = FEC_AUTO;
int volt = (Polarization == 'v' || Polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
@@ -539,15 +537,13 @@
int main(void)
{
- openlog("ctest", 0, LOG_KERN);
OpenFiles();
for (;;) {
tChannel *ch = (fd_qpskfe >= 0) ? SatChannels : CableChannels;
while (ch->name) {
fprintf(stderr, "tuning to %s\t", ch->name);
- syslog(LOG_KERN | LOG_DEBUG, "tuning to %s", ch->name);
for (int i = 0; i < 3; i++) {
- if (SetChannel(ch->freq, ch->pol, ch->fec, ch->diseqc, ch->srate, ch->vpid, ch->apid, ch->tpid))
+ if (SetChannel(ch->freq, ch->pol, ch->diseqc, ch->srate, ch->vpid, ch->apid, ch->tpid))
break;
sleep(1);
}
===================================================================
Regards,
Johannes
--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index