?? cs1100_drv.c
字號:
#include "l1audio_def.h"
#if (defined(CS1100))
#define READ 1
#define WRITE 0
#define CS1100_WR_CTRL 0x20
#define CS1100_RD_CTRL 0x21
uint8 CS1100ControlData[26];
/* Serial communication interfaces */
void SerialCommInit(void);
void SerialCommRelease(void);
void SerialCommCryClkOn(void);
void SerialCommCryClkOff(void);
void SerialCommRxByte(uint8 *data, uint8 ack);
uint8 SerialCommTxByte(uint8 data);
void SerialCommStop(void);
void SerialCommStart(void);
void CS1100_Delay_ms(kal_uint32 times)
{
kal_uint32 delay1;
kal_uint16 delay2;
for(delay1=0;delay1<times;delay1++)
for(delay2=0;delay2<4700;delay2++){ } // about 1ms
}
unsigned int CS1100_I2C_ReadCS1100Reg(uint8 *data,uint8 size) //state=0->success
{ //state=1->fail
unsigned int i,state = 0;
SerialCommInit();
SerialCommStart();
if(SerialCommTxByte(CS1100_RD_CTRL))
{
state = 1;
goto I2C_STOP;
}
for(i=0;i<size-1;i++)
{
SerialCommRxByte(&data[i],0 );
}
SerialCommRxByte(&data[i],1);
I2C_STOP:
SerialCommStop();
SerialCommRelease();
return state;
}
unsigned int CS1100_I2C_WriteCS1100Reg(uint8 *data,uint8 size) //state=0->success
{ //state=1->fail
unsigned int i,state = 0;;
SerialCommInit();
SerialCommStart();
if(SerialCommTxByte(CS1100_WR_CTRL))
{
state = 1;
goto I2C_STOP;
}
for(i=0;i<size;i++)
{
if(SerialCommTxByte(data[i]))
{
state = 1;
break;
}
}
I2C_STOP:
SerialCommStop();
SerialCommRelease();
return state;
}
bool CS1100_FMInit(void)
{
unsigned char error_ind = 0;
// initial default value of CS1100 READ/WRITE registers 03h~0Eh
CS1100ControlData[0] = 0xe4;
CS1100ControlData[1] = 0xd8;
CS1100ControlData[2] = 0x7e; // internal PA OFF, 0x3e->internal PA ON
CS1100ControlData[3] = 0x26;
CS1100ControlData[4] = 0x1f;
CS1100ControlData[5] = 0x80;
CS1100ControlData[6] = 0x28; //CS1100ControlData[6] = 0x38; // for 32.768k crystal
CS1100ControlData[7] = 0x53;
CS1100ControlData[8] = 0xb3;
CS1100ControlData[9] = 0xb3;
CS1100ControlData[10] = 0xaa;
CS1100ControlData[11] = 0xf0;
CS1100ControlData[12] = 0x8b;
CS1100ControlData[13] = 0xaa;
CS1100ControlData[14] = 0xc0;
CS1100ControlData[15] = 0x00; //CS1100ControlData[15] = 0x04;//for 32.768k crystal
CS1100ControlData[16] = 0x25;
CS1100ControlData[17] = 0x35;
CS1100ControlData[18] = 0xff;
CS1100ControlData[19] = 0xfd;
CS1100ControlData[20] = 0x92;
CS1100ControlData[21] = 0x0f;
CS1100ControlData[22] = 0x44;
CS1100ControlData[23] = 0x00;
CS1100ControlData[24] = 0x84;
CS1100ControlData[25] = 0x50;
#if 0
CS1100ControlData[2] &= 0xfc;
CS1100ControlData[2] |= (924 & 0x0300)>>8;
CS1100ControlData[3] = 924 & 0xff;
CS1100ControlData[0] |= 0x02; // TUNE=1
CS1100ControlData[0] &= 0xdf; // mute off
#endif
error_ind = CS1100_I2C_WriteCS1100Reg(CS1100ControlData,26);
if (error_ind )
return 0;
else
return 1;
}
void CS1100_FMTune(unsigned int TunerFrequency)
{
unsigned int ch = 0;
#if 0
kal_uint8 Temp[10];
unsigned int rssi, snr, fd;
#endif
// frequency transfer to channel number, channel=(frequencyMHz-60)/0.05, e.g. 87.5Mhz->550
ch = (TunerFrequency - 6000)/5;
// set channel number
CS1100ControlData[2] &= 0xfc;
CS1100ControlData[2] |= (ch & 0x0300)>>8;
CS1100ControlData[3] = ch & 0xff;
//
// tune function
CS1100ControlData[0] &= 0xfe; // seek=0
CS1100ControlData[0] &= 0xdf; // mute off
CS1100ControlData[0] &= 0xfd; // tune=0
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,4);
CS1100ControlData[0] |= 0x02; // tune=1
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
CS1100_Delay_ms(100); // wait for 100ms
#if 0
CS1100_I2C_ReadCS1100Reg(Temp,10);
rssi=Temp[1];
snr=Temp[2]/4;
fd=Temp[5];
kal_prompt_trace(MOD_MM, "temp is %x,%x \n", Temp[0],Temp[1]);
kal_prompt_trace(MOD_MM, "tune ch,rssi,snr,fd=%d,%d,%d,%d \n",ch,rssi,snr,fd);
#endif
}
uint8 CS1100_FMSeek_Software(bool seekUp, int16 Frequency)
{
static int prefd=-50, preHLSI=0;
// local variable
unsigned int ch = 0;
unsigned int snr,fd,rssi,fd_abs,loop;
int fd_comp;
bool stcflag;
bool hlsi;
bool st;
bool fdstate=0;
kal_uint8 Temp[10];
ch = (Frequency - 6000)/5;
// set channel number
CS1100ControlData[2] &= 0xfc;
CS1100ControlData[2] |= (ch & 0x0300)>>8;
CS1100ControlData[3] = ch & 0xff;
// tune function
CS1100ControlData[0] &= 0xfe; // seek=0
CS1100ControlData[0] &= 0xfd; // tune=0
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,4);
CS1100ControlData[0] |= 0x02; // tune=1
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
CS1100_Delay_ms(50); // wait for 50ms
// read STC indicator and judgement of seek threshold
stcflag=0;
loop=0;
do
{
CS1100_I2C_ReadCS1100Reg(Temp,10);
stcflag=Temp[0]&0x04; // STC bit
loop++;
CS1100_Delay_ms(1); // delay 1ms
}while((!stcflag)&&(loop!=0x1f));
#if 0
//CS1100_I2C_ReadCS1100Reg(Temp,10);
kal_prompt_trace(MOD_MM, "Temp=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",Temp[0],Temp[1],Temp[2],Temp[3],Temp[4],Temp[5],Temp[6],Temp[7],Temp[8],Temp[9]);
#endif
if(!stcflag) //STC=0
{
//kal_prompt_trace(MOD_MM, "STC error\n");
return 0; // it's error
}
// read hlsi, rssi, snr, fd, st
st = Temp[0]& 0x01;
hlsi = Temp[0]&0x08;
rssi=Temp[1];
snr=Temp[2]/4;
fd=Temp[5];
if(fd>127)
{
fd_comp=fd-256;
fd_abs=256-fd;
}
else
{
fd_abs=fd;
fd_comp=fd;
}
if(seekUp)
{
if(preHLSI)
{
if(-prefd<=-20) // prefd inverse
{
fdstate=1;
}
else
{
fdstate=0;
}
}
else
{
if(prefd<=-20)
{
fdstate=1;
}
else
{
fdstate=0;
}
}
}
else
{
if(preHLSI)
{
if(-prefd>=20) // prefd inverse
{
fdstate=1;
}
else
{
fdstate=0;
}
}
else
{
if(prefd>=20)
{
fdstate=1;
}
else
{
fdstate=0;
}
}
}
#if 0
kal_prompt_trace(MOD_MM, "seek is %d,%d,%d,%d,%d,%d,%d \n", Frequency,ch,rssi,snr,fd_abs,fd_comp,prefd);
#endif
// save to global variables
prefd = fd_comp;
preHLSI = hlsi;
//seek threshod judgement
if(rssi>=170 && snr<=42 && fd_abs<=10 && fdstate)
{
if((Frequency==10400||Frequency==9600||Frequency==9100)&&st==0)
{
return 0;
}
#if 0
kal_prompt_trace(MOD_MM, "find radio is %d,%d,%d,%d \n", Frequency,rssi,snr,fd_abs);
#endif
return 1;
}
else
{
return 0;
}
}
void FMDrv_PowerOnReset(void)
{
SerialCommCryClkOn(); //32k clock on
SerialCommInit(); // I2C initial
CS1100_Delay_ms(10);
CS1100ControlData[0] &= 0x7f; //power up
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,26);
CS1100_Delay_ms(100); // delay 100ms, for 32k crystal, waiting for 1s to oscillate
}
void FMDrv_PowerOffProc(void)
{
CS1100ControlData[0] |= 0x20; // mute on
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
CS1100ControlData[0] |= 0x80; // power down
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
SerialCommCryClkOff(); // 32k clock off
}
void FMDrv_ChipInit()
{
SerialCommCryClkOn(); // 32k clock on
SerialCommInit(); // I2C initial
CS1100_FMInit();
//FMDrv_PowerOffProc();
}
void FMDrv_Mute(uint8 mute)
{
if (mute == 0)
{
CS1100ControlData[0] &= 0xdf;// mute off, audio output
}
else
{
CS1100ControlData[0] |= 0x20; // mute on
}
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
}
void FMDrv_SetFreq( int16 curf )
{
CS1100_FMTune(curf*10);
}
uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up) //自動搜索時,作為判定條件,再從中選擇信號最強的9個臺
{
uint8 ret =0;
CS1100ControlData[0] |= 0x20; // mute on
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
ret =CS1100_FMSeek_Software(is_step_up,freq*10);
return ret;
}
uint8 FMDrv_GetSigLvl( int16 curf ) //當滿足rssi 的條件時,將信號記錄,再選最強的9個頻點
{
unsigned int rssi,level;
kal_uint8 Temp[6];
CS1100_I2C_ReadCS1100Reg(Temp,6);
rssi=Temp[1];
level = rssi/20;
return level;
}
bool FMDrv_IsChipValid(void)
{
static bool Fm_chip_exist = false;
static bool Fm_chip_checked = false;
if(Fm_chip_checked)
{
return Fm_chip_exist;
}
Fm_chip_checked = true;
SerialCommCryClkOn();
SerialCommInit();
CS1100_Delay_ms(10);;//add by yang guangfu
Fm_chip_exist = CS1100_FMInit();
//FMDrv_PowerOffProc();
return Fm_chip_exist;
}
void FMDrv_SetVolumeLevel(uint8 level) /*一般不調用,即不用芯片來調節音量。*/
{
/*
unsigned int temp;
if(uint8 > 0x0f)
{
uint8 = 0x0f;
}
temp = uint8<<2;
temp &= 0x3c; //0x3c=00111100
CS1100ControlData[2] |= temp;
CS1100_I2C_WriteCS1100Reg(CS1100ControlData,3);
*/
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -