⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vp310_driver.c

📁 嵌入式软件VP310tuner驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	*scan_time_ms = clock() - scan_start_time;
	*V_channel_cnt = channel_cnt[0];
	*H_channel_cnt = channel_cnt[1];
	return VP310_NO_ERROR;
}

/*-----------------------------------------------------------------------------------------------*/
/*  Obtaining channel parameters																 */
/*-----------------------------------------------------------------------------------------------*/
VP310_STATUS
VP310_get_channel_status(	ULONG					KHz_tuner_freq, 
							VP310_CHANNEL_PARAMS	*channel_params, 
							int						*KHz_freq_offset)
{
	VP310_CHANNEL_PARAMS	channel_params_init = {	1000000, CODE_3_4, 27500, IQ_NORMAL,
													POL_VERTICAL, TONE_OFF};
	VP310_STATUS			status;
	BYTE					buffer[8];
	VP310_BOOLEAN			fec_locked;

	/* Note that this function does NOT include the offset frequency in the KHz_tuner_freq
	of channel_params. */
	*channel_params = channel_params_init;
	channel_params->KHz_tuner_freq = KHz_tuner_freq;
	/* Read VP310 registers for code rate and frequency offset */
	if ((status = VP310_Read_Registers(VP310_FEC_STATUS, buffer, 3, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	*KHz_freq_offset = ( (buffer[1] & 0x7F) << 8) + buffer[2] - ((buffer[1] & 128)<< 8);
	/* Third term is for two's complement correction */
	*KHz_freq_offset = ((*KHz_freq_offset) * 1000) >> 9;
	channel_params->code_rate = int2coderate((buffer[0] >> 4) & 7, VP310_TRUE);

	if ((buffer[0] & 12) == 12)
		fec_locked = VP310_TRUE;
	else
		fec_locked = VP310_FALSE;

	/* Read VP310 registers for Baud rate */
	if ((status = VP310_Read_Registers(VP310_MONITOR_H, buffer, 2, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	channel_params->KBd_rate = (((buffer[0] << 8) + buffer[1]) * 1000) >> 10;
	/* Read VP310 registers for spectral inversion */
	if ((status = VP310_Read_Registers(VP310_VIT_MODE, buffer, 1, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	channel_params->iq_mode = int2iqmode((buffer[0] >> 6) & 1);

	/* Read VP310 registers for polarisation and 22 kHz */
	if ((status = VP310_Read_Registers(VP310_DISEQC_MODE, buffer, 1, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	channel_params->lnb_polar	= int2lnbpolar((buffer[0] >> 6) & 1);
	channel_params->khz_22		= int2lnbtone((buffer[0]) & 1);
	if (fec_locked)
		return VP310_LOCK;
	else
		return VP310_NO_FEC_LOCK;

}

/*-----------------------------------------------------------------------------------------------*/
/*  Centering channel																			 */
/*-----------------------------------------------------------------------------------------------*/
VP310_STATUS
VP310_centre_channel(	VP310_CHANNEL_PARAMS	*channel_params,
						UINT					lock_time_lim_ms,
						int						*KHz_freq_offset,
						ULONG					*KHz_tuner_freq,
						ULONG					*acq_time_ms)
/* This program will modify the data structure channel_params, to reflect new tuner frequency */

{
	VP310_BOOLEAN	fec_lock;
	clock_t			start_time, current_time;
	VP310_STATUS	status;
	BYTE			buffer[8];

	*acq_time_ms		= 0;
	*KHz_freq_offset	= 0;
	/* Read VP310 registers for lock status and frequency offset */
	if ((status = VP310_Read_Registers(VP310_FEC_STATUS, buffer, 3, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	if ((buffer[0] & 12) != 12)
		return VP310_NO_FEC_LOCK;  /* There is little point in trying to centre a channel
								   without lock */

	*KHz_freq_offset	=	((buffer[1] & 0x7F) << 8) + buffer[2] - ((buffer[1] & 128) << 8);
	*KHz_freq_offset	= ((*KHz_freq_offset) * 1000) >> 9;
	*KHz_tuner_freq		= channel_params->KHz_tuner_freq + (*KHz_freq_offset);
	channel_params->KHz_tuner_freq = *KHz_tuner_freq;
	
	/* Program tuner synthesiser */
	if ((status = VP310_program_tuner(*KHz_tuner_freq, lock_time_lim_ms)) != VP310_NO_ERROR)
		return status;
	/* Apply GO pulse */
	buffer[0] = 1;
	if ((status = VP310_Write_Registers(VP310_GO, buffer, 1, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	start_time = clock();
	current_time  = start_time;
	*acq_time_ms  = 0L;
	fec_lock = VP310_FALSE;
	while ((*acq_time_ms) < ((ULONG) lock_time_lim_ms) )
	{
		if ((status = VP310_Read_Registers(VP310_FEC_STATUS, buffer, 3, VP310_FALSE)) != VP310_NO_ERROR)
			return status;
		if ((buffer[0] & 12) == 12)
		{
			fec_lock = VP310_TRUE;
			break;
		}
		go_to_sleep(DELTA_LOCK_DET_MS);
		current_time = clock();
		*acq_time_ms = current_time - start_time;
	}
	/* Read frequency offset for test purposes */
	if ((status = VP310_Read_Registers(VP310_LNB_FREQ_H, buffer, 2, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	if (fec_lock)
	{
		*KHz_freq_offset =	((buffer[0] & 0x7F) << 8) + buffer[1] - ((buffer[0] & 128) << 8);
		*KHz_freq_offset = ((*KHz_freq_offset) * 1000) >> 9;
		return VP310_LOCK;
	}
	else
	{
		return VP310_NO_FEC_LOCK;
		*KHz_freq_offset = 10000;
	}
}

/*----------------------------------------------------------------------------------------------*/
/*  Obtaining QPSK Bit Error Rate (BER)															*/
/*----------------------------------------------------------------------------------------------*/
VP310_STATUS
VP310_get_ber (	UINT			ber_time_in_seconds,
				VP310_BOOLEAN	qpsk_ber_only,
	  			float			*qpsk_ber,
				ULONG			*qpsk_bit_errors,
				float			*vit_ber,
				ULONG			*vit_bit_errors,
				float			*rs_ber,
				ULONG			*rs_blk_errors
				)
{
	clock_t			start_time;
	ULONG			elapsed_time;
	VP310_STATUS	status;
	BYTE			buffer[10];
	BYTE			code_rate, sym_rate_mbd_h, sym_rate_mbd_l;
	VP310_BOOLEAN	first_int_recd;
	ULONG			vit_dec_bits;

	*qpsk_ber =			0.0;
	*qpsk_bit_errors =	0;
	*vit_ber =			0.0;
	*vit_bit_errors	=	0;
	*rs_ber =			0.0;
	*rs_blk_errors =	0;

	/* Clearing FEC_INT register and testing lock and getting code rate */
	if ((status = VP310_Read_Registers(VP310_FEC_INT, buffer, 4, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	if ((buffer[3] & 12) != 12)
		return VP310_NO_FEC_LOCK;
	code_rate = (buffer[3] >> 4) & 7;
	/* Read symbol rate */
	if ((status = VP310_Read_Registers(VP310_MONITOR_H, buffer, 2, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	sym_rate_mbd_h = buffer[0];
	sym_rate_mbd_l = buffer[1];

	/* Clear RS BER and RS Block error registers by reading them */
	if ((status = VP310_Read_Registers(VP310_RS_BERCNT_H, buffer, 5, VP310_FALSE)) != VP310_NO_ERROR)
		return status;

	start_time = clock();
	elapsed_time = 0;
	while (elapsed_time < (ber_time_in_seconds*1000))
	{
		if (qpsk_ber_only)
		{
			if ((status = VP310_Read_Registers(VP310_FEC_INT, buffer, 1, VP310_FALSE)) != VP310_NO_ERROR)
				return status;
			if ((buffer[0] & 4) != 0)
				if (!first_int_recd)
					first_int_recd = VP310_TRUE;
				else
				{
					/* Read Viterbi bit error count registers and form qpsk_ber */
					if ((status = VP310_Read_Registers(VP310_VIT_ERRCNT_H, buffer, 3, VP310_FALSE)) != VP310_NO_ERROR)
						return status;
					*qpsk_bit_errors = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2];
					*qpsk_ber = ((float)(*qpsk_bit_errors))/((float)(1 << 26));
					return VP310_NO_ERROR;
				}
		}
		go_to_sleep(10);
		elapsed_time = clock() - start_time;
	}
	if (qpsk_ber_only)
		return VP310_BER_TIME_TOO_SMALL;
	/* Read all BER registers */
	if ((status = VP310_Read_Registers(VP310_VIT_ERRCNT_H, buffer, 8, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
	*qpsk_bit_errors = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2];
	*qpsk_ber = ((float)(*qpsk_bit_errors))/((float)(1 << 26));
	/* Get the number of RS detected bit errors */
	*vit_bit_errors = (buffer[3] << 16) + (buffer[4] << 8) + buffer[5];
	/* Get symbol rate in Baud */
	vit_dec_bits = (((sym_rate_mbd_h << 8) + (sym_rate_mbd_l)) * 1000000) >> 10;
	/* Include coding rate information, assuming QPSK */
	switch (code_rate)
	{
		case 0 : vit_dec_bits = vit_dec_bits; break;
		case 1 : (vit_dec_bits = vit_dec_bits * 4)/3; break;
		case 2 : (vit_dec_bits = vit_dec_bits * 6)/4; break;
		case 3 : (vit_dec_bits = vit_dec_bits * 10)/6; break;
		case 5 : (vit_dec_bits = vit_dec_bits * 16)/7; break;
		default: vit_dec_bits = vit_dec_bits;
	}
	*vit_ber = ((float) (*vit_bit_errors)) / ( ((float) vit_dec_bits) * ((float) ber_time_in_seconds) );
	*rs_blk_errors = (buffer[6] << 8) + buffer[7];
	*rs_ber = (((float) (*rs_blk_errors)) * 1632) / ( ((float) vit_dec_bits) * ((float) ber_time_in_seconds) );
	return VP310_NO_ERROR;
}

/*-----------------------------------------------------------------------------------------------*/
/*  obtain AGC value                                                                             */
/*-----------------------------------------------------------------------------------------------*/
VP310_STATUS VP310_get_agc_value (float *fe_agc)
{
	VP310_STATUS	status;
	BYTE			buffer[8];
	if ((status = VP310_Read_Registers(VP310_AGC_H, buffer, 2, VP310_FALSE)) != VP310_NO_ERROR)
		return status;
    *fe_agc = ( (float) ((buffer[0]<<6) + ((buffer[1] >> 2) & 0x3F)))/((float) (1 << 14));
	return VP310_NO_ERROR;
}

/*-----------------------------------------------------------------------------------------------*/
/*  Read VP310 registers                                                                         */
/*-----------------------------------------------------------------------------------------------*/
VP310_STATUS
VP310_Read_Registers(BYTE address, BYTE *buffer, BYTE no_of_bytes, VP310_BOOLEAN i2c_tuner_access_on)
{
	VP310_STATUS	status;
	BYTE			i, usDevice_Id;

	if (i2c_tuner_access_on)
		usDevice_Id = tuner_device_id;
	else
		usDevice_Id = VP310_DEVICE_ID;

	if ((address != 0) && (!i2c_tuner_access_on))
	{
		i = address;
		if ((status = I2C_DRIVER_Write_Without_Stop(usDevice_Id, &i, 1)) != VP310_NO_ERROR)
			return status;
	}
	
	if ((status = I2C_DRIVER_Read(usDevice_Id, buffer, no_of_bytes)) != VP310_NO_ERROR)
		return status;

    return VP310_NO_ERROR;
}

/*-----------------------------------------------------------------------------------------------*/
/*  Write VP310 Registers												                         */
/*-----------------------------------------------------------------------------------------------*/
VP310_STATUS 
VP310_Write_Registers(BYTE address, BYTE *buffer, BYTE no_of_bytes, VP310_BOOLEAN i2c_tuner_access_on)
{
	VP310_STATUS	status;
	BYTE			i;

	if (i2c_tuner_access_on)
	{
		/* We do not write an address to the tuner */
		if ((status = I2C_DRIVER_Write(tuner_device_id, buffer, no_of_bytes)) != VP310_NO_ERROR)
			return status;
	}
	else
	{
		for (i = no_of_bytes; i > 0; i--)
			buffer[i] = buffer[i-1];
		buffer[0] = address;
		status = I2C_DRIVER_Write(VP310_DEVICE_ID, buffer, no_of_bytes+1);
		if (status != VP310_NO_ERROR)
			return status;
	}

    return VP310_NO_ERROR;
}

/*-----------------------------------------------------------------------------------------------*/
/*  Sleeping for a short time																	 */
/*-----------------------------------------------------------------------------------------------*/

void go_to_sleep (int sleep_time_ms)
{
	clock_t  start_time, current_time;
	start_time = clock();
	current_time = clock();
	while ((current_time - start_time) < sleep_time_ms)
		current_time = clock();
	return;
}

/*-----------------------------------------------------------------------------------------------*/
/*  Integer to enum conversion functions (needed for visual C),                         		 */
/*-----------------------------------------------------------------------------------------------*/
VP310_BOOLEAN int2boolean(int A)
{
	if (A==0)
		return VP310_FALSE;
	else
		return VP310_TRUE;
}


VP310_CODE_RATE int2coderate(int A, VP310_BOOLEAN from_vp310)
{
	/*	This function is different from other conversion functions.
		Others convert to an enum type as defined in the enum declaration.
		However, if from_vp310 = VP310_TRUE, then
		this converts the 3-bit code rate in FEC_STATUS registers into enum.
		Hence 5 converted to CODE_7_8, although enum value for this is 4.
		Because 4 has been assigned by VP310 to DSS code rate 6/7.
		If from_vp310 = VP310_TRUE, this does the conversion from
		external to enum type.  4 : CODE_7_8, 5 : CODE_AUTO */

	switch (A)
	{
		case 0 : return CODE_1_2;
		case 1 : return CODE_2_3;
		case 2 : return CODE_3_4;
		case 3 : return CODE_5_6;
		case 4 : if (from_vp310) return CODE_AUTO; /* because this is DSS 6/7 */
				 else return CODE_7_8;
		case 5 : if (from_vp310) return CODE_7_8; /* because this is DSS 6/7 */
				 else return CODE_AUTO;
		default : return CODE_AUTO;
	}
}


VP310_IQ_MODE int2iqmode(int A)
{
	if (A == 0)
		return IQ_NORMAL;
	else if (A == 1)
		return IQ_INVERSE;
	else
		return IQ_AUTO;

}

VP310_LNB_POLAR int2lnbpolar(int A)
{
	if (A == 0)
		return POL_VERTICAL;
	else
		return POL_HORIZONTAL;

}

VP310_LNB_TONE int2lnbtone(int A)
{
	if (A == 0)
		return TONE_OFF;
	else
		return TONE_ON;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -