Johannes Stezenbach wrote: > Wolfgang Fritz wrote: > >>I've changed the FE_GET_EVENT handling in VDR to use poll() and in this >>case I see short 0x1f-events (FE_HAS_LOCK bit set) of abt 100ms on >>channels I can't tune to (I had a bogus entry in my channels.conf). >> >>The original VDR lock detection handles this as a valid lock, which is a >>bit sloppy in my opinion, but I would like to know if an application has >>to expect such "spikes" and do some filtering on frontend events? > > > Hm, it seems with frontend hardware one has to expect the unexpected... > Unless there is some really strange bug the 0x1f status is > signalled by the frontend, so there isn't much we can do about it. >
Up to now I thought this is a matter of VDR, but further tests showed that this spurious event is really generated. I patched dvb_frontend.c to get some more debug output and get the following in my syslog if VDR tries to tune from a locked channel to an invalid channel: Aug 1 12:22:17 vdr vdr[1606]: SetChannelDevice: channel 0, LiveView=0 Aug 1 12:22:17 vdr kernel: dvb_frontend_ioctl: FE_SET_FRONTEND Aug 1 12:22:17 vdr kernel: dvb_frontend_add_event: status 00 Aug 1 12:22:17 vdr kernel: dvb_frontend_thread (state=0002): adding event 1f Aug 1 12:22:17 vdr kernel: dvb_frontend_add_event: status 1f Aug 1 12:22:17 vdr vdr[1632]: Event on frontend 1 (channel ""): 00 dt = 21221 ms Aug 1 12:22:17 vdr vdr[1632]: Event on frontend 1 (channel ""): 1f dt = 0 ms Aug 1 12:22:17 vdr vdr[1632]: Frontend 1 (channel "") first lock Aug 1 12:22:17 vdr kernel: dvb_frontend_get_event: status 00 Aug 1 12:22:17 vdr kernel: dvb_frontend_get_event: status 1f Aug 1 12:22:18 vdr vdr[1632]: Event on frontend 1 (channel ""): 01 dt = 100 ms Aug 1 12:22:18 vdr kernel: dvb_frontend_thread (state=0004): adding event 01 Aug 1 12:22:18 vdr kernel: dvb_frontend_add_event: status 01 Aug 1 12:22:18 vdr kernel: dvb_frontend_get_event: status 01 Aug 1 12:22:20 vdr vdr[1632]: Event on frontend 1 (channel ""): 03 dt = 2700 ms What I find strange is that dvb_frontend_thread adds an FE event while it is in FSM state FESTATE_RETUNE. If I understand the code correctly, nothing has happened to the hardware up to now and the thus the FE state reflects the last state of the previous tuning. This does not make sense to me. I attach a patch that resets the FE state to 0 and does not add an event if the FSM is in state FESTATE_RETUNE. It removes the "spike" and otherwise seems to work as before. dvb_frontend_debug.diff: Patch with additional debug printks dvb_frontend.diff : Patch without debug printks Please comment. Wolfgang > >>Other question: There _seems_ to be some evidence that it is dangerous >>if you set (change?) filters when the frontend is not locked. Could that >>be possible? > > > Generally it should not be a problem, except for the av7110 based > cards which might crash if the video/audio decoder is fed with junk. > (It seems that skystar2 users also have problems, but I don't know > anything about skystar2 hardware, so I cannot comment. Does anyone > have a FlexCopII/III data sheet?) > > > Johannes > >
--- dvb_frontend.orig.c 2004-08-01 12:32:44.000000000 +0200 +++ dvb_frontend.debug.c 2004-08-01 13:15:01.000000000 +0200 @@ -77,6 +77,7 @@ static int do_frequency_bending = 0; #define dprintk if (dvb_frontend_debug) printk +#define xdprintk printk #define MAX_EVENT 8 @@ -255,7 +256,7 @@ struct dvb_frontend_event *e; int wp; - dprintk ("%s\n", __FUNCTION__); + xdprintk ("%s: status %02x\n", __FUNCTION__, status); if (down_interruptible (&events->sem)) return; @@ -322,7 +323,7 @@ memcpy (event, &events->events[events->eventr], sizeof(struct dvb_frontend_event)); - + xdprintk ("%s: status %02x\n", __FUNCTION__, event->status); events->eventr = (events->eventr + 1) % MAX_EVENT; up (&events->sem); @@ -520,10 +521,15 @@ } // get the frontend status - dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s); - if (s != fe->status) - dvb_frontend_add_event (fe, s); - + if (fe->state & FESTATE_RETUNE) { + s = 0; + } else { + dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s); + if (s != fe->status) { + xdprintk ("%s (state=%04x): adding event %02x\n", __FUNCTION__, fe->state, s); + dvb_frontend_add_event (fe, s); + } + } // if we're not tuned, and we have a lock, move to the TUNED state if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); @@ -741,6 +747,7 @@ break; case FE_SET_FRONTEND: + xdprintk ("%s: FE_SET_FRONTEND\n", __FUNCTION__); fe->state = FESTATE_RETUNE; memcpy (&fe->parameters, parg,
--- dvb_frontend.orig.c 2004-08-01 12:32:44.000000000 +0200 +++ dvb_frontend.c 2004-08-01 13:13:27.000000000 +0200 @@ -520,10 +520,14 @@ } // get the frontend status - dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s); - if (s != fe->status) - dvb_frontend_add_event (fe, s); - + if (fe->state & FESTATE_RETUNE) { + s = 0; + } else { + dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s); + if (s != fe->status) { + dvb_frontend_add_event (fe, s); + } + } // if we're not tuned, and we have a lock, move to the TUNED state if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);