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

📄 fmrda5800_1_0.c

📁 这是FM模块RDA5800 的C语言控制程序.
💻 C
字号:
//1.0 , 04/16/2007, lilin, RDA

#define     	FMRDA5800_GLOBALS

#include "FMRDA5800.h"


//Globals
XWORD FMshadowReg[45];
XWORD FMseekChannels[FMCHANNELSMAX];

CWORD	cwFMDefault[]={
0x0000,
0x0000,	
0xd881,	//0x02
0x6300,
0x4400,	//0x04
0x10f8, //0x05
0x0000,
0x00cd,
0x0096,
0x0020,
0x4163,
0x0806,
0x5800,
0x5800,
0x5800,
0x5800,
0x4817,
0x20a2,
0x0000,
0x000f,
0x06de,
0xecc0,
0x0200,
0x5383,
0x95a4,
0xe848,
0x0500,
0x00a4,
0x889b,
0x0d84,
0x4f04,
0x8832,
0x7f71,
0x0660,
0x4010,
0x6002,
0x1808,
0x6458,
0x787f,
0x0100,
0xc040,
0xc020,
0x0024,
0x0400,
0x0020,
};

//================================================================
WORD FmChanToFreq(BYTE channel) large
{
	WORD channelSpacing;
	WORD bottomOfBand;
	WORD frequency;

	if ((FMshadowReg[3] & 0x0002) == 0x0000) 
		bottomOfBand = 875;
	else 	
		bottomOfBand = 760;
	if ((FMshadowReg[3] & 0x0001) == 0x0000) 
		channelSpacing = 1;
	else if ((FMshadowReg[5] & 0x0001) == 0x0001) 
		channelSpacing = 2;
	else 
		channelSpacing = 1;

	frequency = (bottomOfBand + channelSpacing * channel);
	return (frequency);
}


//================================================================
WORD FmFreqToChan(WORD frequency) large 
{
	WORD channelSpacing;
	WORD bottomOfBand;
	WORD channel;

	if ((FMshadowReg[3] & 0x0002) == 0x0000) 
		bottomOfBand = 875;
	else 	
		bottomOfBand = 760;
	if ((FMshadowReg[3] & 0x0001) == 0x0000) 
		channelSpacing = 1;
	else if ((FMshadowReg[5] & 0x0001) == 0x0001) 
		channelSpacing = 2;
	else 
		channelSpacing = 1;

	channel = (frequency - bottomOfBand) / channelSpacing;
	return (channel);
}


//================================================================
BYTE FmWaitSTC1(void) large
{
#if(WAITGPIO2)

	WORD i;
	
	WAIT_FOR_GPIO2();

	for(i=0x2000;i>0;i--); 
	return(1);
	
#else

	BYTE readData8[2];

	do
	{			
		if(i2c_rd(I2C_FM,I2C_FM_RD_DATA,2,readData8)==0) return(0);	
	}

	while((readData8[0]&0x40)==0) 
	return(1);
			
#endif
}


//================================================================
BYTE FmWaitSTC0(void) large
{
	WORD i;
	for(i=0x2000;i>0;i--) ;	//lilin note, 07/03/27, this timer should longer than 50ms
	return(1);
}


//================================================================
BYTE FmInit(void) large
{

	WORD i,j;
	XBYTE writeData8[86],xbTemp;		

	I2C_FM_SEN_1();
	I2C_FM_RST_0();	
	_nop_();
	_nop_();
	_nop_();
	I2C_FM_RST_1();	
	_nop_();
	_nop_();
	_nop_();

	
	for(xbTemp = 0; xbTemp < 45; xbTemp++)
		FMshadowReg[xbTemp] = cwFMDefault[xbTemp];
		
	//lilin, for wait 0.5s after enable RCLK
	writeData8[0] = 0xd8;		//0x02   0xd881
	writeData8[1] = 0x81;		//0x81;		
	
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);

#if(DCXO)	
	//wait 500ms for RCLK stable,
	for(i=0x500;i>0;i--)	
		for(j=0x500;j>0;j--) ; 	//wait 500ms for RCLK stable
#endif		
	
	for(xbTemp = 0; xbTemp < 43; xbTemp++)
	{
		writeData8[xbTemp*2] = (FMshadowReg[xbTemp+2] >> 8);
		writeData8[xbTemp*2+1] = (FMshadowReg[xbTemp+2]);
	}
		
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,86,writeData8)) 
	{
	}
	else
	return (0);
		
	//lilin, Tune caused by write REG 03H just now
	//wait STC==1
	if(FmWaitSTC1()==0) return(0);
	
	//clear STC and lab_mode at the same time, from now only could access register 00H~0FH
	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		//0x81;		
	
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	//guarantee STC=0	
	if(FmWaitSTC0()==0) return(0);

}


//================================================================
BYTE FmTune(WORD channel) large
{
	BYTE readData8[32];
	BYTE writeData8[4];

 	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		
	
	writeData8[2] = channel; 	//0x03	 
	writeData8[3] = 0x00; 
	
	if(i2c_wr(I2C_FM,I2C_FM_WR_DATA,4,writeData8)==0) return(0);				
	
	//wait STC=1
	if(FmWaitSTC1()==0) return(0);
		
	//read REG0A&0B	
	#if(FMTEST)	
	if (i2c_rd(I2C_FM,I2C_FM_RD_DATA,32,readData8)==0) return(0);
	#else	
	if (i2c_rd(I2C_FM,I2C_FM_RD_DATA,4,readData8)==0) return(0);
	#endif	
	FMshadowReg[10] = readData8[0]*0x100 + readData8[1];
	FMshadowReg[11] = readData8[2]*0x100 + readData8[3];  
	#if(FMTEST)	
	FMshadowReg[12] = readData8[4]*0x100 + readData8[5];
	FMshadowReg[13] = readData8[6]*0x100 + readData8[7]; 
	FMshadowReg[14] = readData8[8]*0x100 + readData8[9];
	FMshadowReg[15] = readData8[10]*0x100 + readData8[11]; 
	FMshadowReg[0] = readData8[12]*0x100 + readData8[13];
	FMshadowReg[1] = readData8[14]*0x100 + readData8[15]; 
	FMshadowReg[2] = readData8[16]*0x100 + readData8[17];
	FMshadowReg[3] = readData8[18]*0x100 + readData8[19]; 
	FMshadowReg[4] = readData8[20]*0x100 + readData8[21];
	FMshadowReg[5] = readData8[22]*0x100 + readData8[23]; 
	FMshadowReg[6] = readData8[24]*0x100 + readData8[25];
	FMshadowReg[7] = readData8[26]*0x100 + readData8[27]; 
	FMshadowReg[8] = readData8[28]*0x100 + readData8[29];
	FMshadowReg[9] = readData8[30]*0x100 + readData8[31];
	#endif
	
	//clear STC
	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		//0x81;
	
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	
	//wait STC=0	
	if(FmWaitSTC0()==0) return(0);
	
	return(1);
	
}		

	
//================================================================	
BYTE FmSeek(BYTE seekDirection) large
{
	BYTE readData8[4];
	BYTE writeData8[2];
	BOOL fTemp=0;
	
	//set seek bit		
	if(seekDirection == 0) 
		writeData8[0] = ((FMshadowReg[2]>>8) | 0x01);	// seek down
	else 
		writeData8[0] = ((FMshadowReg[2]>>8) | 0x03); 	// seek up
		
	writeData8[1] = FMshadowReg[2];
	
	if(i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	
	//wait STC=1
	if(FmWaitSTC1()==0) return(0);

	//read REG0A&0B	
	if(i2c_rd(I2C_FM,I2C_FM_RD_DATA,4,readData8)==0) return(0);	
	FMshadowReg[10] = readData8[0]*0x100 + readData8[1];
	FMshadowReg[11] = readData8[2]*0x100 + readData8[3];
	//check whether SF=1
	if((readData8[0]&0x20)!=0) fTemp=1;
	
	//clear STC
	writeData8[0] = (FMshadowReg[2] >> 8);
	writeData8[1] = (FMshadowReg[2]);
	
	if(i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	
	//wait STC=0	
	if(FmWaitSTC0()==0) return(0);
	
	if(fTemp) return(0);	 	
	else 	  return(1);
	
}


//================================================================
BYTE FmEnterSleep(void) large 
{
	BYTE writeData8[2];
	
	FMshadowReg[2] = 0xd080; //ENABLE = 0
	
	writeData8[0] = (FMshadowReg[2] >> 8);
	writeData8[1] = (FMshadowReg[2]);
	
	if(i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	
}


//================================================================
BYTE FmExitSleep(void) large
{
	
	BYTE readData8[4];
	BYTE writeData8[4];
	
	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		
	
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);

#if(DCXO)	
	//wait 500ms for RCLK stable,
	for(i=0x500;i>0;i--)	
		for(j=0x500;j>0;j--) ; 	//wait 500ms for RCLK stable
#endif		

 	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		
	
	//tune to orginal channel
	writeData8[2] = channel; 	//0x03	 
	writeData8[3] = 0x00; 
	
	if(i2c_wr(I2C_FM,I2C_FM_WR_DATA,4,writeData8)==0) return(0);				
	
	//wait STC=1
	if(FmWaitSTC1()==0) return(0);
		
	if (i2c_rd(I2C_FM,I2C_FM_RD_DATA,4,readData8)==0) return(0);
	FMshadowReg[10] = readData8[0]*0x100 + readData8[1];
	FMshadowReg[11] = readData8[2]*0x100 + readData8[3];  
	
	//clear STC
	writeData8[0] = 0xd0;		//0x02   0xd081
	writeData8[1] = 0x81;		//0x81;
	
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
	
	//wait STC=0	
	if(FmWaitSTC0()==0) return(0);
	
	return(1);		

}


//================================================================
BYTE FmSetMute(void)
{
	BYTE writeData8[2];

	FMshadowReg[2] = 0x9881; 		// MUTE ENABLE = 1
		
	writeData8[0] = (FMshadowReg[2] >> 8);
	writeData8[1] = (FMshadowReg[2]);
		
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8))
	{	
		return (1);
	}
	else	
		return (0);
	
}


//================================================================
BYTE FmSetNoMute(void)
{
	BYTE writeData8[2];
	
	FMshadowReg[2] = 0xd081; 		// MUTE ENABLE = 0
		
	writeData8[0] = (FMshadowReg[2] >> 8);
	writeData8[1] = (FMshadowReg[2]);
		
	if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8))
	{	
		return (1);
	}
	else	
		return (0);
		
}


//================================================================
BYTE FmAutoSeek (BYTE *numChannels) large
{
	BYTE doneSeeking = 0;
	BYTE chanIndex;
	chanIndex = 0;
	
	// tune to the bottom of the band
	if (FmTune(0)==0) return(0);
	
	// seek through the band
	while (!doneSeeking) 
	{
		if (FmSeek(1)==0)
		{
			*numChannels = chanIndex;	
			return (0);
		}
		
		// done seeking if
		// at least one channel has been found previously (chanIndex != 0) and
		// current channel is lower frequency than previous channel
		// (indicating the seek has wrapped the band)
		if ((chanIndex != 0) && ((FMshadowReg[10]&0x00ff) <= (FMseekChannels[chanIndex-1]))) 
			doneSeeking = 1;
		// otherwise store the channel and keep seeking
		else
		{
			if((FMshadowReg[10]&0x2000)==0)
			{
			FMseekChannels[chanIndex] = (FMshadowReg[10]&0x00ff); 	// store chan
			chanIndex++; 					// increment channel index
			if (chanIndex == FMCHANNELSMAX) doneSeeking = 1;// max channels stored
			}
		}
	}
	
	*numChannels = chanIndex;
	if(chanIndex) 	return(1);
	else		return(0);
	
}

⌨️ 快捷键说明

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