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

Manu Abraham abraham.manu at gmail.com
Tue Oct 9 10:33:26 CEST 2007


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.
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.



+
+    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 ?




 	/* 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)



-					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