📄 fmrda5800_1_0.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 + -