public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [linux-dvb] Twinhan 1041 (SP 400) lock and scan problems - the solution
@ 2008-10-01 14:21 Alex Betis
  2008-10-01 19:41 ` [linux-dvb] Re : Twinhan 1041 (SP 400) lock and scan problems - the solution [not quite :(] Emmanuel ALLAUD
  0 siblings, 1 reply; 11+ messages in thread
From: Alex Betis @ 2008-10-01 14:21 UTC (permalink / raw)
  To: linux-dvb, stefan_ell


[-- Attachment #1.1: Type: text/plain, Size: 842 bytes --]

Patch files are attached.
Several people reported better lock on DVB-S channels.

Just to clarify it, the changes mostly affect DVB-S channels scanning, it
doesn't help with DVB-S2 locking problem since the code is totally different
for S and S2 signal search.

I've increased a timer for S2 signal search and decreased the search step,
this helps to lock on "good" S2 channels that were locked anyway with
several attempts, but this time it locks from first attempt. The "bad"
channels finds the signal, but the FEC is unable to lock.
Since searching of S2 channels is done in the card and not in the driver,
its pretty hard to know what is going on there.

Can't say what happens with the lock on "good" channels since I don't have
any S2 FTA in my sight.

If anyone has any progress with S2 lock, let me know, I'd like to join the
forces.

[-- Attachment #1.2: Type: text/html, Size: 961 bytes --]

[-- Attachment #2: stb0899_drv.c.diff --]
[-- Type: application/octet-stream, Size: 747 bytes --]

--- /media/storage/Download/dvb/mantis-303b1d29d735/linux/drivers/media/dvb/frontends/stb0899_drv.c	2008-09-21 18:41:00.000000000 +0300
+++ stb0899_drv.c	2008-10-01 16:38:43.000000000 +0300
@@ -31,7 +31,7 @@
 #include "stb0899_priv.h"
 #include "stb0899_reg.h"
 
-static unsigned int verbose = 0;//1;
+static unsigned int verbose = 0; // change back to 0
 module_param(verbose, int, 0644);
 
 /* C/N in dB/10, NIRM/NIRL */
@@ -1630,7 +1630,8 @@
 			 *	    10% of the symbol rate
 			 */
 			internal->srch_range	= SearchRange + 1500000 + (i_params->srate / 5);
-			internal->derot_percent	= 30;
+			// Alex: changed from 30
+			internal->derot_percent	= 20;
 
 			/* What to do for tuners having no bandwidth setup ?	*/
 			/* enable tuner I/O */

[-- Attachment #3: stb0899_algo.c.diff --]
[-- Type: application/octet-stream, Size: 14653 bytes --]

--- /media/storage/Download/dvb/mantis-303b1d29d735/linux/drivers/media/dvb/frontends/stb0899_algo.c	2008-09-21 18:41:00.000000000 +0300
+++ stb0899_algo.c	2008-10-01 16:51:33.000000000 +0300
@@ -207,18 +207,37 @@
 
 	short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
 	int index = 0;
+	int internal_index = -1;
+	int numOfInternalLoops = 3;
 	u8 cfr[2];
 
 	internal->status = NOTIMING;
 
 	/* timing loop computation & symbol rate optimisation	*/
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
-	derot_step = (params->srate / 2L) / internal->mclk;
+	// Alex: use precalculated step
+	derot_step = internal->derot_step * 4;
+	//derot_step = (params->srate / 32L) / internal->mclk;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "limit = %d, step = %d, mclk = %d", 
+		derot_limit, derot_step, internal->mclk);
 
 	while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
+		// Alex: Loop on the same freq few interations		
+		internal_index++;
+		internal_index %= numOfInternalLoops;
+		
+		if(internal_index == 0) {
 		index++;
+
 		derot_freq += index * internal->direction * derot_step;	/* next derot zig zag position	*/
 
+			internal->direction = -internal->direction;	/* Change zigzag direction		*/
+		}
+
+		dprintk(state->verbose, FE_DEBUG, 1, "index = %d, derot_freq = %d, limit = %d, direction = %d, step = %d", 
+		index, derot_freq, derot_limit, internal->direction, derot_step);
+	
 		if (ABS(derot_freq) > derot_limit)
 			next_loop--;
 
@@ -227,7 +246,7 @@
 			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
 			stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency		*/
 		}
-		internal->direction = -internal->direction;	/* Change zigzag direction		*/
+
 	}
 
 	if (internal->status == TIMINGOK) {
@@ -275,14 +294,23 @@
 {
 	struct stb0899_internal *internal = &state->internal;
 
-	short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
+	short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3;
 	int index = 0;
+	int internal_index = -1;
+	int numOfInternalLoops = 3;
+	int base_freq;
 	u8 cfr[2];
 	u8 reg;
 
 	internal->status = NOCARRIER;
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
 	derot_freq = internal->derot_freq;
+	derot_step = internal->derot_step * 2;
+	last_derot_freq = internal->derot_freq;
+	base_freq = internal->derot_freq;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "freq = %d, limit = %d, step = %d, mclk = %d", 
+		derot_freq, derot_limit, derot_step, internal->mclk);
 
 	reg = stb0899_read_reg(state, STB0899_CFD);
 	STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
@@ -291,11 +319,24 @@
 	do {
 		dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
 		if (stb0899_check_carrier(state) == NOCARRIER) {
+			// Alex: Loop on the same freq few interations		
+			internal_index++;
+			internal_index %= numOfInternalLoops;
+		
+			if(internal_index == 0) {
 			index++;
+
 			last_derot_freq = derot_freq;
-			derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position	*/
+				derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position	*/
 
-			if(ABS(derot_freq) > derot_limit)
+				internal->direction = -internal->direction; /* Change zigzag direction	*/
+			}
+
+			dprintk(state->verbose, FE_DEBUG, 1, "index = %d, derot_freq = %d, limit = %d, step = %d", 
+		index, derot_freq, derot_limit, derot_step);
+
+			// Alex: should limit based on initial base freq
+			if(derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
 				next_loop--;
 
 			if (next_loop) {
@@ -308,8 +349,6 @@
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 			}
 		}
-
-		internal->direction = -internal->direction; /* Change zigzag direction	*/
 	} while ((internal->status != CARRIEROK) && next_loop);
 
 	if (internal->status == CARRIEROK) {
@@ -335,16 +374,22 @@
 	int lock = 0, index = 0, dataTime = 500, loop;
 	u8 reg;
 
+	// Alex: added sleep 5 mSec
+	msleep(5);
+
 	internal->status = NODATA;
 
 	/* RESET FEC	*/
 	reg = stb0899_read_reg(state, STB0899_TSTRES);
 	STB0899_SETFIELD_VAL(FRESACS, reg, 1);
 	stb0899_write_reg(state, STB0899_TSTRES, reg);
-	msleep(1);
+	// Alex: changed from 1 to 5 mSec
+	msleep(5);
 	reg = stb0899_read_reg(state, STB0899_TSTRES);
 	STB0899_SETFIELD_VAL(FRESACS, reg, 0);
 	stb0899_write_reg(state, STB0899_TSTRES, reg);
+	// Alex: added 5 mSec
+	msleep(5);
 
 	if (params->srate <= 2000000)
 		dataTime = 2000;
@@ -357,6 +402,9 @@
 
 	stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop	*/
 	while (1) {
+		// Alex: added 1 mSec
+		msleep(1);
+
 		/* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP	*/
 		reg = stb0899_read_reg(state, STB0899_VSTATUS);
 		lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
@@ -384,20 +432,43 @@
 	short int derot_freq, derot_step, derot_limit, next_loop = 3;
 	u8 cfr[2];
 	u8 reg;
-	int index = 1;
+	int index = 0;
+	int internal_index = -1;
+	int numOfInternalLoops = 3;
+	int base_freq;
 
 	struct stb0899_internal *internal = &state->internal;
 	struct stb0899_params *params = &state->params;
 
-	derot_step = (params->srate / 4L) / internal->mclk;
+	// Alex: use precalculated step
+	derot_step = internal->derot_step;
+	//derot_step = (params->srate / 128L) / internal->mclk;
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
 	derot_freq = internal->derot_freq;
+	base_freq = internal->derot_freq;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "limit = %d, step = %d, mclk = %d", 
+		derot_limit, derot_step, internal->mclk);
 
 	do {
 		if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
+			// Alex: Loop on the same freq few interations		
+			internal_index++;
+			internal_index %= numOfInternalLoops;
+		
+			if(internal_index == 0) {
+				index++;
 
 			derot_freq += index * internal->direction * derot_step;	/* next zig zag derotator position	*/
-			if (ABS(derot_freq) > derot_limit)
+
+				internal->direction = -internal->direction; /* change zig zag direction		*/
+			}
+
+			dprintk(state->verbose, FE_DEBUG, 1, "index = %d, derot_freq = %d, limit = %d, direction = %d, step = %d", 
+			index, derot_freq, derot_limit, internal->direction, derot_step);
+
+			// Alex: should limit based on initial base freq
+			if(derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
 				next_loop--;
 
 			if (next_loop) {
@@ -411,10 +482,8 @@
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 
 				stb0899_check_carrier(state);
-				index++;
 			}
 		}
-		internal->direction = -internal->direction; /* change zig zag direction		*/
 	} while ((internal->status != DATAOK) && next_loop);
 
 	if (internal->status == DATAOK) {
@@ -551,6 +620,10 @@
 
 	/* Initial calculations	*/
 	internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol	*/
+
+	dprintk(state->verbose, FE_DEBUG, 1, "Derot step=%d",
+		internal->derot_step);
+
 	internal->t_derot = stb0899_calc_derot_time(params->srate);
 	internal->t_data = 500;
 
@@ -844,6 +917,8 @@
 	dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
 	dec_rate = Log2Int(dec_ratio);
 
+	dprintk(state->verbose, FE_DEBUG, 1, "dec_ratio %d, dec_rate %d", dec_ratio, dec_rate);
+
 	win_sel = 0;
 	if (dec_rate >= 5)
 		win_sel = dec_rate - 4;
@@ -857,6 +932,8 @@
 	else
 		band_lim = 0;	/* band limit signal going into btr block*/
 
+	dprintk(state->verbose, FE_DEBUG, 1, "decim %d, f_sym %d, master_clk %d, srate %d, band_lim %d", decim, f_sym, internal->master_clk, internal->srate, band_lim);
+
 	decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
 
@@ -867,6 +944,8 @@
 	else
 		anti_alias = 2;
 
+	dprintk(state->verbose, FE_DEBUG, 1, "anti_alias %d", anti_alias);
+
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
 	btr_nom_freq = stb0899_dvbs2_calc_srate(state);
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
@@ -879,6 +958,9 @@
 	/* scale UWP+CSM frequency to sample rate*/
 	freq_adj =  internal->srate / (internal->master_clk / 4096);
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
+
+	dprintk(state->verbose, FE_DEBUG, 1, "btr_nom_freq %d, correction %d, freq_adj %d", btr_nom_freq, correction, freq_adj);
+
 }
 
 /*
@@ -985,7 +1067,12 @@
 	else
 		step_size = (1 << 17) / 4;
 
-	range = internal->srch_range / 1000000;
+	// Alex: make smaller steps
+	step_size = 250;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "step size %d", step_size);
+
+	range = 4;//Alex: return to: internal->srch_range / 1000000;
 	steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
 	steps = (steps + 6) / 10;
 	steps = (steps == 0) ? 1 : steps;
@@ -996,6 +1083,8 @@
 	else
 		stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
 
+	dprintk(state->verbose, FE_DEBUG, 1, "range %d, steps %d", range, steps);
+
 	/*Set Carrier Search params (zigzag, num steps and freq step size*/
 	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
 	STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
@@ -1084,6 +1173,8 @@
 	int time = -10, lock = 0, uwp, csm;
 	u32 reg;
 
+	dprintk(state->verbose, FE_DEBUG, 1, "timeout = %d mSec", timeout);
+
 	do {
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
 		dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
@@ -1136,6 +1227,8 @@
 {
 	int time = 0, Locked;
 
+	dprintk(state->verbose, FE_DEBUG, 1, "timeout = %d", timeout);
+
 	do {
 		Locked = stb0899_dvbs2_get_data_lock(state, 1);
 		time++;
@@ -1342,6 +1434,12 @@
 		FecLockTime	= 20;	/* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs		*/
 	}
 
+	// Alex: timeouts seems to be too small
+	searchTime *= 10;
+	FecLockTime *= 10;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "srate = %d, searchTime = %d, FecLockTime = %d", internal->srate, searchTime, FecLockTime);
+
 	/* Maintain Stream Merger in reset during acquisition	*/
 	reg = stb0899_read_reg(state, STB0899_TSTRES);
 	STB0899_SETFIELD_VAL(FRESRS, reg, 1);
@@ -1401,12 +1499,18 @@
 			/*	Read the frequency offset*/
 			offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
+			dprintk(state->verbose, FE_DEBUG, 1, "1: i = %d, offsetfreq = %d", i, offsetfreq);
+
 			/* 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);
+
+			msleep(10);
+
 			internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+
 			i++;
 		}
 	}
@@ -1412,12 +1516,19 @@
 	}
 
 	if (internal->status != DVBS2_FEC_LOCK) {
+		dprintk(state->verbose, FE_DEBUG, 1, "still no lock, inversion = %d", internal->inversion);
+
 		if (internal->inversion == IQ_SWAP_AUTO) {
+			dprintk(state->verbose, FE_DEBUG, 1, "inversion = IQ_SWAP_AUTO");
+
 			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);
+
+			msleep(10);
+
 			/* start acquistion process	*/
 			stb0899_dvbs2_reacquire(state);
 
@@ -1432,13 +1544,19 @@
 					/*	Read the frequency offset*/
 					offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
+					dprintk(state->verbose, FE_DEBUG, 1, "2: i = %d, offsetfreq = %d", i, offsetfreq);
+
 					/* 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);
 
+					msleep(10);
+
 					stb0899_dvbs2_reacquire(state);
+
 					internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+
 					i++;
 				}
 			}
@@ -1464,13 +1582,21 @@
 
 			i = 0;
 			while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+
+				dprintk(state->verbose, FE_DEBUG, 1, "3: i = %d", i);
+
 				csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
 				STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
 				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+				msleep(10);
+
 				csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
 				STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
 				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
 
+				msleep(10);
+
 				internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
 				i++;
 			}
@@ -1480,6 +1606,8 @@
 		      (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
 		      (pilots == 1)) {
 
+  			dprintk(state->verbose, FE_DEBUG, 1, "Equalizer disable update");
+
 			/* Equalizer Disable update	 */
 			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
 			STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
@@ -1491,18 +1619,26 @@
 		STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
 		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
 
+		msleep(10);
+
 		/* Store signal parameters	*/
 		offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
+		dprintk(state->verbose, FE_DEBUG, 1, "offsetfreq from reg = %d", offsetfreq);
+
 		offsetfreq = offsetfreq / ((1 << 30) / 1000);
 		offsetfreq *= (internal->master_clk / 1000000);
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
 		if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
 			offsetfreq *= -1;
 
+		dprintk(state->verbose, FE_DEBUG, 1, "offsetfreq after calc = %d", offsetfreq);
+
 		internal->freq = internal->freq - offsetfreq;
 		internal->srate = stb0899_dvbs2_get_srate(state);
 
+		dprintk(state->verbose, FE_DEBUG, 1, "freq = %d, srate = %d", internal->freq, internal->srate);
+
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
 		internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
 		internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;

[-- Attachment #4: Type: text/plain, Size: 150 bytes --]

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-10-15  6:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-01 14:21 [linux-dvb] Twinhan 1041 (SP 400) lock and scan problems - the solution Alex Betis
2008-10-01 19:41 ` [linux-dvb] Re : Twinhan 1041 (SP 400) lock and scan problems - the solution [not quite :(] Emmanuel ALLAUD
2008-10-02  5:38   ` Alex Betis
2008-10-05 13:13     ` [linux-dvb] Re : " Emmanuel ALLAUD
2008-10-05 13:54       ` Alex Betis
2008-10-06  1:00         ` [linux-dvb] Re : " Emmanuel ALLAUD
2008-10-06 10:33           ` Alex Betis
     [not found]             ` <1224014045l.11287l.1l@manu-laptop>
2008-10-14 23:09               ` [linux-dvb] Re : " Manu Abraham
2008-10-14 23:37                 ` [linux-dvb] Re : " Emmanuel ALLAUD
2008-10-15  6:22                   ` Alex Betis
2008-10-14 23:35             ` [linux-dvb] " Emmanuel ALLAUD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox