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

📄 fm.c

📁 TEA5767收音源码
💻 C
字号:
/****************************************************************************/
/* MODULE:                                                                  								*/
/*	FM.c 
	
*/	 
/****************************************************************************/
/*
 *   TCC Version 0.0
 *   Copyright (c) telechips, Inc.
 *   ALL RIGHTS RESERVED
*/
/****************************************************************************/

#include "main.h"
#include "fm/FM.h"
#include "kernel/telechips.h"
#include "i2c/i2c.h"

FMRADIO			RadioData;

#ifdef RADIO_INCLUDE
#ifdef RADIO_MCU
unsigned char radio_state = RADIO_SET_STERO|RADIO_SET_SENS_150;
unsigned int radio_freq ;		
unsigned char command_buff[2];
unsigned char receive_data[2];
unsigned int	fm_khz;	
unsigned char radio_pwron_counter=0;

void delay720(unsigned int count)
{
		for(;count>0;count--) ;
	// 1:0.84, 5:1.36, 10:1.96, 20:3.20, 30:4.48, 60:8.04, 80:10.6, 90:11.6, 100:13 
}

void fmw_stand_by_rtn(unsigned char onoff)		//radio power onoff
{
//	if(onoff)
//		fm_pwr_on;
//	else
//		fm_pwr_off;
	if(onoff) 
		{
		radio_state &= ~RADIO_SET_PWR;
		radio_pwron_counter=1;
		}
	else	  radio_state |= RADIO_SET_PWR;
	mcu_send_state();
	
}

void fmw_stereo_rtn(unsigned char onoff)
{ 

	//radio_state &= 0xcf;
	//if(onoff) 
	//	radio_state |= RADIO_SET_STERO;
	//else	  radio_state |= RADIO_SET_MONO;
	if(onoff) 
		radio_state |= RADIO_SET_STERO;
	else	  radio_state &= ~RADIO_SET_STERO;
	mcu_send_state();
}

unsigned char mcu_rd_rtn(unsigned char subadr,unsigned char *ptr, unsigned char bytes)
{
	return (unsigned char)(i2c_read((unsigned int)I2C_FM, (unsigned char)mcu_slaveaddr, subadr, ptr, bytes));
}

unsigned char mcu_wr_rtn(unsigned char subadr,unsigned char *ptr, unsigned char bytes)
{
	return (unsigned char)(i2c_write((unsigned int)I2C_FM, (unsigned char)mcu_slaveaddr, subadr, ptr, bytes));
}

void mcu_set_state(unsigned char *com)
{
	mcu_wr_rtn(COM_RADIO_STATE,com,1);
}

void mcu_set_freq(unsigned char *com)
{
	mcu_wr_rtn(COM_RADIO_FREQ,com,2);
}

void mcu_read_state(unsigned char *com)
{
	mcu_rd_rtn(COM_RADIO_STATE,com,1);
}

void mcu_read_freq(unsigned char *com)
{
	mcu_rd_rtn(COM_RADIO_FREQ,com,2);
}

void mcu_send_state(void)
{
	command_buff[0] = radio_state;
	mcu_set_state(command_buff);
}
void mcu_manuscan_up(void)
{
	radio_state &= 0xf0;
	radio_state |= RADIO_MANUSCAN_UP;
	mcu_send_state();
}

void mcu_manuscan_down(void)
{
	radio_state &= 0xf0;
	radio_state |= RADIO_MANUSCAN_DOWN;
	mcu_send_state();
}

void mcu_autoscan_up(void)
{
	radio_state &= 0xf0;
	radio_state |= RADIO_AUTOSCAN_UP;
	mcu_send_state();
}

void mcu_autoscan_down(void)
{
	radio_state &= 0xf0;
	radio_state |= RADIO_AUTOSCAN_DOWN;
	mcu_send_state();
}


void mcu_set_bandfreq(unsigned char band)
{
	
	if(band == RADIO_FM)
		radio_freq = fm_khz/10;
	else
		radio_freq = fm_khz | ((unsigned int)(band)<<14);
	
	command_buff[0] = (unsigned char)((radio_freq>>8) & 0xff);
	command_buff[1] = (unsigned char)(radio_freq & 0xff);
	mcu_set_freq(command_buff);
}

unsigned char	mcu_read_radio_state(void)
{
	unsigned char temp;
	
	mcu_read_state(receive_data);
	temp = receive_data[0];
	receive_data[0] = 0;
	return temp;
}

unsigned int mcu_read_radio_freq(void)
{
	unsigned int temp;
	mcu_read_freq(receive_data);
	temp = receive_data[0];
	temp = (temp<<8) & 0xff00;
	temp |= receive_data[1];
	receive_data[0] = 0;
	receive_data[1] = 0;
	return temp;
}

void fm_init(void)
{
	//mute fm
	fmw_stand_by_rtn(off);
	/*
	fm_pwr_on;//power on radio
	delay720(100);			
	fm_khz = 87500;	
	mcu_set_bandfreq(RADIO_FM);
	*/
	//unmute fm
}

void fmw_all_mute_rtn(unsigned char onoff)
{
}

void Radio_manual_scan(unsigned char dir)
{	
	unsigned char status;
	unsigned int freq;

	if(dir)
		mcu_manuscan_up();
	else
		mcu_manuscan_down();

}

void Radio_auto_scan(unsigned char dir)
{	
	unsigned char status;
	unsigned int freq;

	if(dir)
		mcu_autoscan_up();
	else
		mcu_autoscan_down();
}

#else

unsigned char fm_rd_byte[5] = {0,0,0,0,0};	// Read buf
unsigned char fm_wr_byte[5] = {0,0,0,0,0};	// write but
unsigned int	fm_khz;	

void delay720(unsigned int count)
{
		for(;count>0;count--) ;
	// 1:0.84, 5:1.36, 10:1.96, 20:3.20, 30:4.48, 60:8.04, 80:10.6, 90:11.6, 100:13 
}
/* ---------------------------------- Command Function ------------------------------------ */

void fmw_hilo_side_rtn(unsigned char hilo)
{
	if(hilo) fm_wr_byte[2] |= 0x10;
	else	 fm_wr_byte[2] &= 0xef;
}

void fmw_all_mute_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[0] |= 0x80;
	else	  fm_wr_byte[0] &= 0x7f;
}

void fmw_search_mode_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[0] |= 0x40;
	else	  fm_wr_byte[0] &= 0xbf;
}

void fmw_search_dir_rtn(unsigned char dir)
{
	if(dir) fm_wr_byte[2] |= 0x80;
	else	fm_wr_byte[2] &= 0x7f;
}

void fmw_search_level_rtn(unsigned char level)
{
	switch(level)
	{
		case	all_level : fm_wr_byte[2] &= 0x9f;
					  		break;
		case	lo_level : 	fm_wr_byte[2] &= 0xbf;
					  		fm_wr_byte[2] |= 0x20;
					  		break;
		case	mid_level : fm_wr_byte[2] |= 0x40;
					  		fm_wr_byte[2] &= 0xdf;
					  		break;
		case	hi_level  : fm_wr_byte[2] |= 0x60;
					  		break;
	}
}

void fmw_stereo_rtn(unsigned char onoff)
{ 
	if(onoff) fm_wr_byte[2] &= 0xf7;
	else	  fm_wr_byte[2] |= 0x08;
}

void fmw_mute_left_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[2] |= 0x04;
	else	  fm_wr_byte[2] &= 0xfb;
}

void fmw_mute_right_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[2] |= 0x02;
	else	  fm_wr_byte[2] &= 0xfd;
}

void fmw_stand_by_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[3] |= 0x40;
	else	  fm_wr_byte[3] &= 0xbf;
}

void fmw_band_sel_rtn(unsigned char sel)
{
	if(sel) fm_wr_byte[3] |= 0x20;
	else    fm_wr_byte[3] &= 0xdf;
}

void fmw_xtal_sel_rtn(unsigned char sel)
{
	if(sel) fm_wr_byte[3] |= 0x10;
	else    fm_wr_byte[3] &= 0xef;
}

void fmw_soft_mute_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[3] |= 0x08;
	else	  fm_wr_byte[3] &= 0xf7;
}

void fmw_hcc_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[3] |= 0x04;
	else	  fm_wr_byte[3] &= 0xfb;
}

void fmw_snc_rtn(unsigned char onoff)
{
	if(onoff) fm_wr_byte[3] |= 0x02;
	else	  fm_wr_byte[3] &= 0xfd;
}

void fmw_search_indi_rtn(unsigned char sel)
{
	if(sel) fm_wr_byte[3] |= 0x01;
	else	fm_wr_byte[3] &= 0xfe;
}

void fmw_pll_ref_rtn(unsigned char sel)
{
	if(sel) fm_wr_byte[4] |= 0x80;
	else    fm_wr_byte[4] &= 0x7f;
}

void fmw_deemph_rtn(unsigned char sel)
{
	if(sel) fm_wr_byte[4] |= 0x40;
	else    fm_wr_byte[4] &= 0xbf;
}

unsigned char fmr_ready_flag_rtn(void)
{
	return (unsigned char)((fm_rd_byte[0] >> 7) & 0x01);
}

unsigned char fmr_band_limit_rtn(void)
{
	return (unsigned char)((fm_rd_byte[0] >> 6) & 0x01);
}

unsigned short fmr_pll_rtn(void)
{
	unsigned short temp = 0;
	
	temp = (unsigned short)((fm_rd_byte[0] & 0x3f) << 8);
	temp |= (unsigned short)fm_rd_byte[1];
	
	return temp;
}

unsigned char fmr_stereo_indi_rtn(void)
{
	return (unsigned char)((fm_rd_byte[2] >> 7) & 0x01);
}

unsigned char fmr_if_count_rtn(void)
{
	return (unsigned char)(fm_rd_byte[2] & 0x7f);
}

unsigned char fmr_level_adc_rtn(void)
{
	return (unsigned char)((fm_rd_byte[3] >> 4) & 0x0f);
}

/* ------------------------------ End Command function ------------------------------------- */
unsigned char fm_rd_rtn(unsigned char *ptr)
{
	return (unsigned char)(i2c_read((unsigned int)I2C_FM, (unsigned char)fm_slaveaddr, (char)I2C_SUBADDR_NOUSE, ptr, (unsigned char)5));
}

unsigned char fm_wr_rtn(unsigned char *ptr)
{
	return (unsigned char)(i2c_write((unsigned int)I2C_FM, (unsigned char)fm_slaveaddr, (char)I2C_SUBADDR_NOUSE, ptr, (unsigned char)5));
}

void fmw_pll_rtn(unsigned char hilo, unsigned int fm_freq)
{
	unsigned char temp;
	unsigned short fm_pll_val = 0;
	
	if(hilo) fm_pll_val = (unsigned short)((4000*(fm_freq+225))/32768);	// calc PLL decoder
	else	 fm_pll_val = (unsigned short)((4000*(fm_freq-225))/32768);
	
	temp = (unsigned char)((fm_pll_val >> 8) & 0x3f);
	fm_wr_byte[0] &= 0xc0;
	fm_wr_byte[0] |= temp;
	
	temp = (unsigned char)fm_pll_val;
	fm_wr_byte[1] = temp;
	
	fmw_hilo_side_rtn(hilo);
}

unsigned char fm_hilo_optimal(unsigned int fm_freq)
{
	unsigned char status;
	unsigned char temp;
	unsigned char levelhigh, levellow;
	
	fmw_pll_rtn(hi_side, fm_freq+450);	// Set PLL value High
	status = fm_wr_rtn(fm_wr_byte);		// Send Command


        delay720(20000);		
					
	status = fm_rd_rtn(fm_rd_byte);		// Read status
	
	levelhigh = fmr_level_adc_rtn();	// Get ADC value
		
	fmw_pll_rtn(hi_side, fm_freq-450);	// Set PLL value Low
	status = fm_wr_rtn(fm_wr_byte);
	
	delay720(20000);		

					
	status = fm_rd_rtn(fm_rd_byte);
	
	levellow = fmr_level_adc_rtn();
		
	if(levelhigh < levellow) temp = hi_side;
	else	temp = lo_side;
	
	return temp;
}

void fm_init(void)
{
	unsigned char i;
#if 0 /* lhm */
	i2c_wr
	i2c_clk_hi
	i2c_data_hi
#endif /* lhm */	
//	fm_pwr_on // 20050111
	
	delay720(100);			
	
	fm_khz = 89100;	//107700;
	
	
	fmw_all_mute_rtn(on);					// MUTE OFF
	fmw_search_mode_rtn(off);				// OFF SearchMode
	fmw_search_dir_rtn(up);					// Search direction is up
	fmw_search_level_rtn(mid_level);		// search ADC level is middle
//	fmw_search_level_rtn(lo_level);		// search ADC level is middle
	fmw_stereo_rtn(on);						//	Steleo ON
	fmw_mute_left_rtn(off);					//	Left force mono off
	fmw_mute_right_rtn(off);				// Right	force mono 0ff
	fmw_stand_by_rtn(on);					// Stanby off
//	fmw_band_sel_rtn(japan);				// Japan FM zone
	fmw_band_sel_rtn(us_eu);				// Japan FM zone
	fmw_xtal_sel_rtn(xtal_32768);			//	set the x-tal to 32.768 KHz
	fmw_soft_mute_rtn(on);
	fmw_hcc_rtn(on);						// HCC ON
	fmw_snc_rtn(on);						// SNC ON
	fmw_search_indi_rtn(on);				// Pin 14 is output for the ready flag
	fmw_pll_ref_rtn(ref_65_dis);			// 6.5Mhz	ref. not enable
	fmw_deemph_rtn(deemph50);				// deemphasis is 50us
	
	i = fm_hilo_optimal(fm_khz);			// HILO algorithm	-> find optimize PLL
	fmw_pll_rtn(i, fm_khz);
	fmw_all_mute_rtn(off);	
	i = fm_wr_rtn(fm_wr_byte);
}
/*---------------------------------------- Change Hz and Auto Scan ---------------------------------------- */
void fm_manual_scan(unsigned char dir)
{	
	unsigned char status;
	
	
	if(dir)
	{
		if(fm_khz >= 108000) fm_khz = 87500;
		else				 fm_khz += scan_step;
	}
	else
	{	
		if(fm_khz <= 87500) fm_khz = 108000;
		else				fm_khz -= scan_step;
	}
								
	status = fm_hilo_optimal(fm_khz);
							
	fmw_pll_rtn(status, fm_khz);
		
	//fmw_all_mute_rtn(off); // TEST

	status = fm_wr_rtn(fm_wr_byte);

	//LCD_DisplayChannelForFM(fm_khz);
	
}

unsigned char fm_auto_scan(unsigned char dir)
{
	unsigned char status, curlev, curifc;
	
	if(dir)
	{
		if(fm_khz >= 108000) fm_khz = 87500;
		else				 fm_khz += scan_step;
	}
	else
	{	
		if(fm_khz <= 87500) fm_khz = 108000;
		else				fm_khz -= scan_step;
	}
	
	//fmw_all_mute_rtn(on);	// TEST
	status = fm_wr_rtn(fm_wr_byte); // Edit By Jim
	status = fm_hilo_optimal(fm_khz);
	fmw_pll_rtn(status, fm_khz);
	status = fm_wr_rtn(fm_wr_byte);
								
//	delay720(20000);
	delay720(30000);

					
	status = fm_rd_rtn(fm_rd_byte);
	curlev = fmr_level_adc_rtn();
	curifc = fmr_if_count_rtn();

//	LCD_DisplayChannelForFM(fm_khz);
	
/*
	if(fm_khz == 88000) 
		fm_khz = 88000;
	else if(fm_khz == 89100) 
		fm_khz = 89100;
	else if(fm_khz == 89700) 
		fm_khz = 89700;
	else if(fm_khz == 91900) 
		fm_khz = 91900;
	else if(fm_khz == 93100) 
		fm_khz = 93100;
	else if(fm_khz == 93900) 
		fm_khz = 93900;
	else if(fm_khz == 95100) 
		fm_khz = 95100;
	else if(fm_khz == 95700) 
		fm_khz = 95700;
	else if(fm_khz == 95900) 
		fm_khz = 95900;
	else if(fm_khz == 97300) 
		fm_khz = 97300;
	else if(fm_khz == 98100) 
		fm_khz = 98100;
	else if(fm_khz == 99100) 
		fm_khz = 99100;
	else if(fm_khz == 99600) 
		fm_khz = 99600;
	else if(fm_khz == 100000) 
		fm_khz = 100000;
	else if(fm_khz == 101100) 
		fm_khz = 101100;
	else if(fm_khz == 101900) 
		fm_khz = 101900;
	else if(fm_khz == 102700) 
		fm_khz = 102700;
	else if(fm_khz == 103500) 
		fm_khz = 103500;
	else if(fm_khz == 105300) 
		fm_khz = 105300;
	else if(fm_khz == 106100) 
		fm_khz = 106100;
	else if(fm_khz == 106900) 
		fm_khz = 106900;
	else if(fm_khz == 107700) 
		fm_khz = 107700;
*/	
//	if((curlev > 3) && (0x30 < curifc) && (curifc < 0x3c)  ) return	1; // scan_level
	if((curlev > 3) && (0x30 < curifc) && (curifc < 0x3c)  ) return	1; // scan_level
	else
		return	0;
}

unsigned int fm_auto_scan_detect(unsigned char dir)
{
	unsigned char status, i; 
	unsigned char index = 1; // Edit By Jim
	
	unsigned int dumy_fm_khz = fm_khz;
	
	
	for(i=0;i<10;i++)
	{
		if(fm_auto_scan(dir)) index++;
		else break;
	}
		 
	if(index%2)
	{
		if(dir) fm_khz = dumy_fm_khz + (unsigned int)((index/2)*100);
		else    fm_khz = dumy_fm_khz - (unsigned int)((index/2)*100);
	}
	else
	{
		if(dir) fm_khz = dumy_fm_khz + (unsigned int)(((index/2)-1)*100);
		else    fm_khz = dumy_fm_khz - (unsigned int)((index/2)*100);
	}
	
	status = fm_hilo_optimal(fm_khz);
	fmw_pll_rtn(status, fm_khz);
	//fmw_all_mute_rtn(off); 	TEST
	
	status = fm_wr_rtn(fm_wr_byte);
									
//	LCD_ClearOneLine(2);
//	lcd_var(0, 2, fm_khz);
//	LCD_DisplayChannelForFM(fm_khz);
	return fm_khz;
}
#endif
#endif

⌨️ 快捷键说明

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