[linux-dvb] [patch] Improvement dvb-s2 lock with KNC1 DVB-S2 Plus, Satelco DVB-S2, TT S2 3200, Technisat DVB-S2

jlacvdr jlacvdr at gmail.com
Tue Oct 9 11:29:07 CEST 2007


2007/10/9, Manu Abraham <abraham.manu at gmail.com>:
> jlacvdr wrote:
> > I rewrote a part of stb0899_dvbs2_algo( ) to remove duplicate source
> > code and to get a source code more readable.
> > I added also re-initialization of some registers.
> > The result is a lower probability to don't obtain the lock.
> >
> > I tested on TT-s2 3200 and on Knc1 dvb-s2 plus.
> > It must work on other cards, the patch touch only stb0899 part.
> >
> > I don't remember the time duration to lock, but if you want I can measure it.
> >
> > The aim of this patch, it's obtain the lock all the time.
> >
> > Regards,
> >
>
> I doubt whether there is a problem in acquiring LOCK on the KNC1, Satelco and the TT cards.

without the patch, I can't lock all the time, and it's seems that
other persons have the same problem.



> Julian, Marco can you guys please confirm ?
>
>
>
> Let me walk through your patch  ....
> (I feel something wrong in the patch)
>
>
> --- linux/drivers/media/dvb/frontends/stb0899_algo.c.org        2007-10-08 21:25:09.000000000 +0200
> +++ linux/drivers/media/dvb/frontends/stb0899_algo.c    2007-10-08 21:25:06.000000000 +0200
> @@ -1351,7 +1351,17 @@
>
>         s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
>         int i = 0;
> +    int cpt = 0;
>         u32 reg, csm1;
> +    s32 retry = 0;
> +
> +
> +    reg = STB0899_READ_S2REG( STB0899_S2DEMOD, DMD_CNTRL2 );
> +    STB0899_SETFIELD_VAL( SPECTRUM_INVERT, reg, 1 );
> +    stb0899_write_s2reg( state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg );
>
>
>
> Why do you forcefully invert the I/Q inputs ? Different hardware have different configurations.

yes, there are different hardware configurations, so with this patch
the algo find automatically the good configuration.
This is an initialiation, I begin with a I/Q configuration, if failure
the configuration is inverted.


>
>
> +
> +    do
> +    {
>
>         if (internal->srate <= 2000000) {
>                 searchTime      = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs           */
> @@ -1381,9 +1391,16 @@
>         STB0899_SETFIELD_VAL(FRESRS, reg, 1);
>         stb0899_write_reg(state, STB0899_TSTRES, reg);
>
> +        reg = STB0899_READ_S2REG( STB0899_S2DEMOD, CRL_NOM_FREQ );
> +        STB0899_SETFIELD_VAL( CRL_NOM_FREQ, reg, 0xd0 );
> +        stb0899_write_s2reg( state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, 0xd0 );
> +
>
>
>
> You read Nominal Frequency into "reg", set 208 Hz into "reg", ignore reg ..
> After which you forcefully enter 208 Hz into the Complex mixer straight away.
> Even if you required to reprogram the mixer to 208 Hz, i don't see then why
> do you need the Complex mixer current setting as a part of the Carrier Recovery ?
>
> But, i don't see this "magic frequency" in any of the specs from STM.
>
> Although one question i have, irrespective to your patch, does setting the
> Complex Mixer to "0" Hz (30 bit unsigned) help in your case, as applicable to you ?
>
>

Before starting acquisition, I restore the initial conditions.
The 208 is the initial value of nominal frequency in CRL_NOM_FREQ
register. (can be found is the datasheet)


>
>
>         /* Move tuner to frequency      */
>         if (state->config->tuner_set_frequency)
>                 state->config->tuner_set_frequency(&state->frontend, internal->freq);
> +
> +        msleep( 100 );
> +
>         if (state->config->tuner_get_frequency)
>                 state->config->tuner_get_frequency(&state->frontend, &internal->freq);
>
> @@ -1400,23 +1417,13 @@
>         /* Initialisation       */
>         stb0899_dvbs2_init_calc(state);
>
> -       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
> -       switch (internal->inversion) {
> -       case IQ_SWAP_OFF:
> -               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
> -               break;
> -       case IQ_SWAP_ON:
> -               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
> -               break;
> -       case IQ_SWAP_AUTO:      /* use last successful search first     */
> -               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
> -               break;
> -       }
> -       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
> +        stb0899_write_s2reg( state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL, 0x0005 );
> +
>         stb0899_dvbs2_reacquire(state);
>
>         /* Wait for demod lock (UWP and CSM)    */
>         internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
> +        cpt++;
>
>         if (internal->status == DVBS2_DEMOD_LOCK) {
>                 dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
> @@ -1432,51 +1439,28 @@
>                         /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
>                         reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
>                         STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
> -                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
> +                stb0899_write_s2reg( state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ,
> +                                     STB0899_OFF0_CRL_NOM_FREQ, offsetfreq );
>                         stb0899_dvbs2_reacquire(state);
>                         internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
>                         i++;
>                 }
>         }
>
> -       if (internal->status != DVBS2_FEC_LOCK) {
> -               if (internal->inversion == IQ_SWAP_AUTO) {
> +        if( internal->status != DVBS2_FEC_LOCK )
> +        {
> +            /* IQ Inversion */
>                         reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
>                         iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
>                         /* IQ Spectrum Inversion        */
>                         STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
>                         stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
> -                       /* start acquistion process     */
> -                       stb0899_dvbs2_reacquire(state);
>
> -                       /* Wait for demod lock (UWP and CSM)    */
> -                       internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
> -                       if (internal->status == DVBS2_DEMOD_LOCK) {
> -                               i = 0;
> -                               /* Demod Locked, check FEC      */
> -                               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
> -                               /*try thrice for false locks, (UWP and CSM Locked but no FEC)   */
> -                               while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
> -                                       /*      Read the frequency offset*/
> -                                       offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
> +        }
> +        else
> +        {
>
> -                                       /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
> -                                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
> -                                       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
> -                                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
>
> -                                       stb0899_dvbs2_reacquire(state);
>
>
>
>
> According to STM, after each failure, the frontend as a whole must de-lock and reacquire.
> You simply removed off reacquisition. (I am scratching my head)

don't forget we are in a  do{ }while


>
>
>
> -                                       internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
> -                                       i++;
> -                               }
> -                       }
> -/*
> -                       if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
> -                               pParams->IQLocked = !iqSpectrum;
> -*/
> -               }
> -       }
> -       if (internal->status == DVBS2_FEC_LOCK) {
>                 dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
>                 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
>                 modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
> @@ -1550,6 +1534,8 @@
>                 STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
>                 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
>         }
> +    }
> +    while( ( ++retry < 5 ) && ( internal->status != DVBS2_FEC_LOCK ) );
>
>         /* Release Stream Merger Reset          */
>         reg = stb0899_read_reg(state, STB0899_TSTRES);
>
>
>
> I don't know what your patch does, but it looks a bit "shady" with that
> magic number and doing something else than what it is supposed to do.
> Can you please clarify the points that what i have mentioned ?
>
> Thanks,
> Manu
>



More information about the linux-dvb mailing list