?? fmrda5800_1_5.c
字號:
//1.0 , 04/16/2007, lilin, RDA
//1.1 , 06/01/2007, lilin, RDA, insert 50ms delay in FmWaitSTC1 subprogram.
//1.2 , 06/22/2007, lilin, RDA, add stopseek and filter false station
//1.3 , 07/29/2007, lilin, RDA, move filter false station function into FmSeek, remove FmSearch, FmWaitSTC1_stopseek
//1.4 , 08/13/2007, lilin, RDA, use seek_singlestep function if want to display incremetal frequency station
//1.5 , 08/27/2007, lilin, RDA, adjust seek time to minimize, use delay 100ms to replace polling STC
#define FMRDA5800_GLOBALS
#include "FMRDA5800.h"
//Globals
XWORD FMshadowReg[45];
XWORD FMseekChannels[FMCHANNELSMAX];
CWORD cwFMDefault[]={
0x0000,
0x0000,
0xd881, //0x02
0x6300,
0x4400, //0x04
0x10ff, //0x13ff, lilin, 06/22, 0x10f8, //0x05
0x0000,
0x00cd,
0x0096,
0x0020,
0x4163,
0x0806,
0x5800,
0x5800,
0x5800,
0x5800,
0x4c17, //lilin, 08/13, seek_singlestep, 0x4817,
0x20a2,
0x0000,
0x000f,
0x06de,
0xecc0,
0x0200,
0x5383,
0x95a4,
0xe848,
0x0500, //0x0500, lilin, 06/22, 0x0500,
0x00a4, //0x00a4, lilin, 06/22, 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--);
// delay 70ms ; //lilin, 06/22, change the delay to 70ms
//
// return(1);
//
//#else
//
// BYTE readData8[2];
//
// do
// {
// //!!!!! lilin add, 06/01/2007
// //for(i=0x2000;i>0;i--) ; //lilin add, 06/01/2007, insert delay in continous polling STC, 50ms or 100ms is preferable
// delay 70ms ; //lilin, 06/22, change the delay to 70ms
// if(i2c_rd(I2C_FM,I2C_FM_RD_DATA,2,readData8)==0) return(0);
// //lilin, 08/13, change to software seek
// //lilin, 06/22, add to show readchan
// //READCHAN = readData8[1];
//
// //lilin, 08/13, change to software seek
// //if(STOPSEEK) //when user press button
// // FmStopSeek(seekDirection);
//
// }while((readData8[0]&0x40)==0);
//
// return(1);
//
//#endif
//}
//
//
//================================================================
//lilin, 08/13, change to software seek
//lilin, 06/22, set SEEKTH=0 to stop seek operation
/*
BYTE FmStopSeek(BYTE seekDirection)
{
BYTE writeData8[8];
//set seek and seekup bit as in FmSeek
if(seekDirection == 0)
writeData8[0] = ((FMshadowReg[2]>>8) | 0x01); // seek down
else
writeData8[0] = ((FMshadowReg[2]>>8) | 0x03); // seek up
writeData8[1] = (FMshadowReg[2]);
writeData8[2] = (READCHAN); //Tune to channel that seek operation just on
writeData8[3] = (FMshadowReg[3]);
writeData8[4] = (FMshadowReg[4] >> 8);
writeData8[5] = (FMshadowReg[4]);
writeData8[6] = (0x00); //set SEEKTH=0 to stop seek operation
writeData8[7] = (FMshadowReg[5]);
if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,8,writeData8)==0) return(0);
return(1);
}
*/
//================================================================
//BYTE FmWaitSTC0(void) large
//{
// WORD i;
// //for(i=0x2000;i>0;i--) ; //lilin note, 07/03/27, this timer should longer than 50ms
// delay 70ms ; //lilin, 06/22, change the delay to 70ms
//
// 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
delay 500ms; //lilin, 06/22, not specify how to get 500ms delay
#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);
delay 100ms;
//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);
delay 100ms;
//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);
}
//================================================================
//lilin, 08/13, use seek_singlestep function to easy display frequency station
BYTE FmSingleSeek(BYTE seekDirection) large
{
BYTE readData8[4];
BYTE writeData8[8];
//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);
delay 100ms;
//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);
return(1);
}
//================================================================
BYTE FmSeek(BYTE seekDirection) large
{
BYTE readData8[4];
BYTE writeData8[8];
BOOL fStopSeek=0;
bool falseStation=0;
do{
fStopSeek=0;
falseStation=0;
if(FmSingleSeek(seekDirection)==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];
READCHAN = readData8[1];
//check whether SF=1
if((readData8[0]&0x20)!=0) falseStation=1;
//check station RSSI again, if RSSI<SEEKTH, then falseStation, continue seek
if(readData8[2] < (FMshadowReg[5]>>8)) falseStation=1;
if(STOPSEEK) fStopSeek=1;
}while((falseStation==1)&&(fStopSeek==0));
}
//================================================================
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
delay 500ms; //lilin, 06/22, not specify how to get 500ms delay
#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);
delay 100ms;
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);
}
//================================================================
//lilin, 06/22, set tune_freq_diff when set volume, to avoid trigger tune
BYTE FmSetVolume(BYTE volume)
{
BYTE writeData8[8];
FMshadowReg[2] = 0xd091; // set tune_freq_diff, to avoid trigger tune
writeData8[0] = (FMshadowReg[2] >> 8);
writeData8[1] = (FMshadowReg[2]);
writeData8[2] = (FMshadowReg[3] >> 8);
writeData8[3] = (FMshadowReg[3]);
writeData8[4] = (FMshadowReg[4] >> 8);
writeData8[5] = (FMshadowReg[4]);
writeData8[6] = (FMshadowReg[5] >> 8);
writeData8[7] = (volume);
if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,8,writeData8)==0) return(0);
FMshadowReg[2] = 0xd081; // clear tune_freq_diff, for normal operation
writeData8[0] = (FMshadowReg[2] >> 8);
writeData8[1] = (FMshadowReg[2]);
if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
return (1);
}
//================================================================
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 + -