//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 { }
frequency = (bottomOfBand + channelSpacing * channel); return (frequency);
WORD channelSpacing;这个WORD 是什么类型 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;
//================================================================ WORD FmFreqToChan(WORD frequency) large { }
channel = (frequency - bottomOfBand) / channelSpacing; return (channel); 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;
//================================================================ //BYTE FmWaitSTC1(void) large //{
//#if(WAITGPIO2) // // // // // // // // // // // // // //
BYTE readData8[2]; do WORD i;
WAIT_FOR_GPIO2();
//for(i=0x2000;i>0;i--); delay 70ms ; //lilin, 06/22, change the delay to 70ms return(1);
//#else
// {
// //!!!!! 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]);
//Tune to channel that seek operation just
writeData8[2] = (READCHAN); on
writeData8[3] = (FMshadowReg[3]);
writeData8[4] = (FMshadowReg[4] >> 8);因为FMshadowReg是WORD形吗 writeData8[5] = (FMshadowReg[4]); writeData8[6] = (0x00); writeData8[7] = (FMshadowReg[5]);
//set SEEKTH=0 to stop seek operation
} */
if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,8,writeData8)==0) return(0);
return(1);
//================================================================ //BYTE FmWaitSTC0(void) large //{
// WORD i; // // // // //}
//================================================================ BYTE FmInit(void) large {
//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);
WORD i,j;
XBYTE writeData8[86],xbTemp;
I2C_FM_SEN_1();
I2C_FM_RST_0(); I2C_FM_RST_0是伪指令吗? _nop_(); _nop_();
_nop_();
I2C_FM_RST_1(); _nop_(); _nop_(); _nop_();
for(xbTemp = 0; xbTemp < 45; xbTemp++) FMshadowReg[xbTemp] = cwFMDefault[xbTemp];
//0x02 0xd881
//0x81;
//lilin, for wait 0.5s after enable RCLK writeData8[0] = 0xd8;
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
//lilin, 06/22, not specify how to get 500ms delay
delay 500ms;
#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; writeData8[1] = 0x81;
writeData8[2] = channel; writeData8[3] = 0x00;
//0x02 0xd081 //0x03
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; //writeData8[1] = 0x81;
//if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0);
//wait STC=0
//0x02 0xd081 //0x81;
}
//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 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; writeData8[1] = 0x81; if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0); //0x02 0xd081 #if(DCXO) //wait 500ms for RCLK stable, //for(i=0x500;i>0;i--) // for(j=0x500;j>0;j--) ; //wait 500ms for RCLK stable //lilin, 06/22, not specify how to get 500ms delay delay 500ms; #endif writeData8[0] = 0xd0; writeData8[1] = 0x81; //tune to orginal channel writeData8[2] = channel; writeData8[3] = 0x00; //0x02 0xd081 //0x03 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; //writeData8[1] = 0x81; //wait STC=0 //if(FmWaitSTC0()==0) return(0); //0x02 0xd081 //0x81; //if (i2c_wr(I2C_FM,I2C_FM_WR_DATA,2,writeData8)==0) return(0); } return(1); //================================================================ BYTE FmSetMute(void) { } FMshadowReg[2] = 0x9881; // MUTE ENABLE = 1 BYTE writeData8[2]; 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 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) 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); { 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); 因篇幅问题不能全部显示,请点此查看更多更全内容