713 lines
19 KiB
C
713 lines
19 KiB
C
/*--------------------------------------------------------------------------*/
|
||
/**@file qn8035.c
|
||
@brief qn8035收音底层驱动
|
||
@details
|
||
@author
|
||
@date 2011-11-24
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
#include "app_config.h"
|
||
#include "system/includes.h"
|
||
#include "fm/fm_manage.h"
|
||
#include "QN8035.h"
|
||
|
||
#if(TCFG_FM_QN8035_ENABLE && TCHFG_SOFT_I2C_ENABLE)
|
||
|
||
|
||
//#include "sdmmc_api.h"
|
||
|
||
//if antenna match circuit is used a inductor,macro USING_INDUCTOR will be set to 1
|
||
#define USING_INDUCTOR 0
|
||
|
||
#define INVERSE_IMR 1
|
||
|
||
//if using san noise floor as CCA algorithm,macro SCAN_NOISE_FLOOR_CCA will be set to 1
|
||
#define SCAN_NOISE_FLOOR_CCA 1
|
||
//if using pilot as CCA algorithm,macro PILOT_CCA will be set to 1
|
||
//#define PILOT_CCA 0
|
||
|
||
|
||
//长天线配置:
|
||
//u8 _xdata qnd_PreNoiseFloor = 40,qnd_NoiseFloor = 40;
|
||
bool qn8035_online;
|
||
//短天线配置:
|
||
|
||
|
||
|
||
static struct _fm_dev_info *fm_dev_info = NULL;
|
||
|
||
extern void delay_2ms(int cnt);
|
||
|
||
#define delay_n10ms(x) \
|
||
delay_2ms(x*5)
|
||
|
||
|
||
|
||
u16 aa;
|
||
u8 qnd_PrevMode;
|
||
u8 qnd_CH_STEP = 1;
|
||
u8 qnd_ChipID;
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief QN8035 读寄存器函数
|
||
@param addr:寄存器地址
|
||
@return 无
|
||
@note u8 QND_ReadReg(u8 addr)
|
||
//5_5_9_5
|
||
//4_5_8_5
|
||
//2_5_8_5
|
||
*/
|
||
|
||
#define qn8035_rssi 4 //越大台越少
|
||
#define qn8035_if2 0x05 //越大台越多
|
||
#define qn8035_snr_th1 0x08 //越大台越少 //
|
||
#define qn8035_snr_th2 0x05
|
||
#define qn8035_pilot_cca 0
|
||
#define qn8035_inductor 1
|
||
#define qn8075_snr 25
|
||
u8 qnd_PreNoiseFloor = 35; //越大台越少
|
||
u8 qnd_NoiseFloor = 35;
|
||
|
||
|
||
u8 QND_ReadReg(u8 addr)
|
||
{
|
||
u8 byte;
|
||
|
||
iic_start(fm_dev_info->iic_hdl); //I2C启动
|
||
iic_tx_byte(fm_dev_info->iic_hdl, 0x20); //写命令
|
||
iic_tx_byte(fm_dev_info->iic_hdl, addr); //写地址
|
||
|
||
iic_start(fm_dev_info->iic_hdl); //写转为读命令,需要再次启动I2C
|
||
iic_tx_byte(fm_dev_info->iic_hdl, 0x21); //读命令
|
||
byte = iic_rx_byte(fm_dev_info->iic_hdl, 1);
|
||
|
||
iic_stop(fm_dev_info->iic_hdl); //I2C停止
|
||
return byte;
|
||
}
|
||
|
||
#if 0 //IIC SD IO复用
|
||
u8 sd_iic_readQN(u8 addr)
|
||
{
|
||
u8 p_status;
|
||
u8 res;
|
||
|
||
/*Wait SD I/O release*/
|
||
if (device_active == DEVICE_SDMMCA) {
|
||
p_status = pause_decode(0);
|
||
}
|
||
sdmmca_force_idle();
|
||
sdmmcb_force_idle();
|
||
while (check_sd_controller()); //根据SD ID等待控制器繁忙
|
||
IO_MC0 &= ~BIT(3);
|
||
|
||
/*IIC Communicate*/
|
||
res = QND_ReadReg(addr);
|
||
|
||
/*Reset SD I/O*/
|
||
IO_MC0 |= BIT(3);
|
||
unlock_cmd_chk();
|
||
if ((p_status == MAD_PLAY) && (device_active == DEVICE_SDMMCA)) {
|
||
start_decode();
|
||
}
|
||
|
||
return res;
|
||
}
|
||
#endif
|
||
|
||
u8 qn8035_iic_write(u8 w_chip_id, u8 register_address, u8 *buf, u32 data_len)
|
||
{
|
||
u8 ret = 1;
|
||
|
||
if (fm_dev_info == NULL) {
|
||
puts("fm_dev_info not init !!!!!");
|
||
return 0;
|
||
}
|
||
|
||
iic_start(fm_dev_info->iic_hdl);
|
||
if (0 == iic_tx_byte(fm_dev_info->iic_hdl, w_chip_id)) {
|
||
ret = 0;
|
||
log_e("\n fm iic wr err 0\n");
|
||
goto __gcend;
|
||
}
|
||
|
||
delay(fm_dev_info->iic_delay);
|
||
|
||
if (0 == iic_tx_byte(fm_dev_info->iic_hdl, register_address)) {
|
||
ret = 0;
|
||
log_e("\n fm iic wr err 1\n");
|
||
goto __gcend;
|
||
}
|
||
u8 *pbuf = buf;
|
||
|
||
while (data_len--) {
|
||
delay(fm_dev_info->iic_delay);
|
||
|
||
if (0 == iic_tx_byte(fm_dev_info->iic_hdl, *pbuf++)) {
|
||
ret = 0;
|
||
log_e("\n fm iic wr err 2\n");
|
||
goto __gcend;
|
||
}
|
||
}
|
||
|
||
__gcend:
|
||
iic_stop(fm_dev_info->iic_hdl);
|
||
|
||
return ret;
|
||
}
|
||
|
||
u8 qn8035_iic_readn(u8 r_chip_id, u8 register_address, u8 *buf, u8 data_len)
|
||
{
|
||
u8 read_len = 0;
|
||
|
||
if (fm_dev_info == NULL) {
|
||
puts("fm_dev_info not init !!!!!");
|
||
return 0;
|
||
}
|
||
|
||
iic_start(fm_dev_info->iic_hdl);
|
||
if (0 == iic_tx_byte(fm_dev_info->iic_hdl, (r_chip_id & 0x01) ? (r_chip_id - 1) : (r_chip_id))) {
|
||
log_e("\n fm iic rd err 0\n");
|
||
read_len = 0;
|
||
goto __gdend;
|
||
}
|
||
|
||
|
||
delay(fm_dev_info->iic_delay);
|
||
if (0 == iic_tx_byte(fm_dev_info->iic_hdl, register_address)) {
|
||
log_e("\n fm iic rd err 1\n");
|
||
read_len = 0;
|
||
goto __gdend;
|
||
}
|
||
|
||
/* delay(fm_dev_info->iic_delay); */
|
||
/* iic_start(fm_dev_info->iic_hdl); */
|
||
/* if (0 == iic_tx_byte(fm_dev_info->iic_hdl, r_chip_id)) { */
|
||
/* log_e("\n fm iic rd err 2\n"); */
|
||
/* read_len = 0; */
|
||
/* goto __gdend; */
|
||
/* } */
|
||
|
||
delay(fm_dev_info->iic_delay);
|
||
|
||
for (; data_len > 1; data_len--) {
|
||
*buf++ = iic_rx_byte(fm_dev_info->iic_hdl, 1);
|
||
read_len ++;
|
||
}
|
||
|
||
*buf = iic_rx_byte(fm_dev_info->iic_hdl, 0);
|
||
|
||
__gdend:
|
||
|
||
iic_stop(fm_dev_info->iic_hdl);
|
||
delay(fm_dev_info->iic_delay);
|
||
|
||
return read_len;
|
||
}
|
||
|
||
#define app_IIC_write qn8035_iic_write
|
||
#define app_IIC_readn qn8035_iic_readn
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief QN8035 写寄存器函数
|
||
@param addr:寄存器地址 data:写入数据
|
||
@return 无
|
||
@note void QND_WriteReg(u8 addr,u8 data)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void QND_WriteReg(u8 addr, u8 data)
|
||
{
|
||
app_IIC_write(0x20, addr, &data, 1);
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
void QNF_SetCh(UINT16 start,UINT16 stop,UINT8 step)
|
||
**********************************************************************
|
||
Description: set channel frequency
|
||
Parameters:
|
||
freq: channel frequency to be set,frequency unit is 10KHZ
|
||
Return Value:
|
||
None
|
||
**********************************************************************/
|
||
void QNF_SetCh(u16 start, u16 stop, u8 step)
|
||
{
|
||
u8 temp;
|
||
|
||
start = FREQ2CHREG(start);
|
||
stop = FREQ2CHREG(stop);
|
||
//writing lower 8 bits of CCA channel start index
|
||
QND_WriteReg(CH_START, (u8)start);
|
||
//writing lower 8 bits of CCA channel stop index
|
||
QND_WriteReg(CH_STOP, (u8)stop);
|
||
//writing lower 8 bits of channel index
|
||
QND_WriteReg(CH, (u8)start);
|
||
//writing higher bits of CCA channel start,stop and step index
|
||
temp = (u8)((start >> 8) & CH_CH);
|
||
temp |= ((u8)(start >> 6) & CH_CH_START);
|
||
temp |= ((u8)(stop >> 4) & CH_CH_STOP);
|
||
temp |= (step << 6);
|
||
QND_WriteReg(CH_STEP, temp);
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
int QND_Delay()
|
||
**********************************************************************
|
||
Description: Delay for some ms, to be customized according to user
|
||
application platform
|
||
|
||
Parameters:
|
||
ms: ms counts
|
||
Return Value:
|
||
None
|
||
|
||
**********************************************************************/
|
||
void QND_Delay(u16 ms)
|
||
{
|
||
// Delay(25*ms); //rc
|
||
// delay16(1500*ms);
|
||
delay_n10ms(1);
|
||
}
|
||
|
||
void qn8035_mute1(bool On)
|
||
{
|
||
QND_WriteReg(0x4a, On ? 0x30 : 0x10);
|
||
//QND_WriteReg(0x4a, 0x30);
|
||
}
|
||
#define QNF_SetMute(x,y) qn8035_mute(x,y)
|
||
/**********************************************************************
|
||
void QNF_SetMute(u8 On)
|
||
**********************************************************************
|
||
Description: set register specified bit
|
||
|
||
Parameters:
|
||
On: 1: mute, 0: unmute
|
||
Return Value:
|
||
None
|
||
**********************************************************************/
|
||
u8 qn8035_mute(void *priv, u8 On)
|
||
{
|
||
QND_WriteReg(REG_DAC, On ? 0x1B : 0x10);
|
||
//QND_WriteReg(0x4a, On?0x30:0x10);
|
||
return 0;
|
||
}
|
||
|
||
#if SCAN_NOISE_FLOOR_CCA
|
||
/***********************************************************************
|
||
Description: scan a noise floor from 87.5M to 108M by step 200K
|
||
Parameters:
|
||
Return Value:
|
||
1: scan a noise floor successfully.
|
||
0: chip would not normally work.
|
||
**********************************************************************/
|
||
u8 QND_ScanNoiseFloor(u16 start, u16 stop)
|
||
{
|
||
u8 regValue;
|
||
u8 timeOut = 255; //time out is 2.55S
|
||
|
||
QND_WriteReg(CCA_SNR_TH_1, 0x00);
|
||
QND_WriteReg(CCA_SNR_TH_2, 0x05);
|
||
QND_WriteReg(0x40, 0xf0);
|
||
//config CCS frequency rang by step 200KHZ
|
||
QNF_SetCh(start, stop, 2);
|
||
/*
|
||
QND_WriteReg(CH_START,0x26);
|
||
QND_WriteReg(CH_STOP,0xc0);
|
||
QND_WriteReg(CH_STEP,0xb8);
|
||
*/
|
||
//enter CCA mode,channel index is decided by internal CCA
|
||
QND_WriteReg(SYSTEM1, 0x12);
|
||
while (1) {
|
||
regValue = QN_IIC_read(SYSTEM1);
|
||
//if it seeks a potential channel, the loop will be quited
|
||
if ((regValue & CHSC) == 0) {
|
||
break;
|
||
}
|
||
delay_n10ms(1); //delay 10ms
|
||
//if it was time out,chip would not normally work.
|
||
if ((timeOut--) == 0) {
|
||
QND_WriteReg(0x40, 0x70);
|
||
return 0;
|
||
}
|
||
}
|
||
QND_WriteReg(0x40, 0x70);
|
||
qnd_NoiseFloor = QN_IIC_read(0x3f);
|
||
if (((qnd_PreNoiseFloor - qnd_NoiseFloor) > 2) || ((qnd_NoiseFloor - qnd_PreNoiseFloor) > 2)) {
|
||
qnd_PreNoiseFloor = qnd_NoiseFloor;
|
||
}
|
||
//TRACE("NF:%d,timeOut:%d\n",qnd_NoiseFloor,255-timeOut);
|
||
return 1;
|
||
}
|
||
#endif
|
||
/**********************************************************************
|
||
void QNF_SetRegBit(u8 reg, u8 bitMask, u8 data_val)
|
||
**********************************************************************
|
||
Description: set register specified bit
|
||
|
||
Parameters:
|
||
reg: register that will be set
|
||
bitMask: mask specified bit of register
|
||
data_val: data will be set for specified bit
|
||
Return Value:
|
||
None
|
||
***********************************************************************/
|
||
void QND_RXSetTH(void)
|
||
{
|
||
u8 rssi_th;
|
||
|
||
rssi_th = qnd_PreNoiseFloor + qn8035_rssi - 28 ; //10 越小台多0-
|
||
///increase reference PLL charge pump current.
|
||
QND_WriteReg(REG_REF, 0x7a);
|
||
//NFILT program is enabled
|
||
QND_WriteReg(0x1b, 0x78);
|
||
//using Filter3
|
||
QND_WriteReg(CCA1, 0x75);
|
||
//setting CCA IF counter error range value(768).
|
||
QND_WriteReg(CCA_CNT2, qn8035_if2); //0x03 大台多 1-5
|
||
//#if PILOT_CCA
|
||
if (qn8035_pilot_cca) {
|
||
QND_WriteReg(PLT1, 0x00);
|
||
}
|
||
//#endif
|
||
//selection the time of CCA FSM wait SNR calculator to settle:20ms
|
||
//0x00: 20ms(default)
|
||
//0x40: 40ms
|
||
//0x80: 60ms
|
||
//0xC0: 100m
|
||
// QNF_SetRegBit(CCA_SNR_TH_1 , 0xC0, 0x00);
|
||
//selection the time of CCA FSM wait RF front end and AGC to settle:20ms
|
||
//0x00: 10ms
|
||
//0x40: 20ms(default)
|
||
//0x80: 40ms
|
||
//0xC0: 60ms
|
||
// QNF_SetRegBit(CCA_SNR_TH_2, 0xC0, 0x40);
|
||
// QNF_SetRegBit(CCA, 30); //setting CCA RSSI threshold is 30
|
||
QND_WriteReg(CCA_SNR_TH_2, qn8035_snr_th2); //0xc5
|
||
QND_WriteReg(CCA, (QN_IIC_read(CCA) & 0xc0) | rssi_th);
|
||
//#if PILOT_CCA
|
||
if (qn8035_pilot_cca) {
|
||
QND_WriteReg(CCA_SNR_TH_1, qn8035_snr_th1); //setting SNR threshold for CCA
|
||
} else {
|
||
QND_WriteReg(CCA_SNR_TH_1, qn8035_snr_th1); //小台多 8-12 //setting SNR threshold for CCA 9
|
||
}
|
||
//#endif
|
||
}
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief QN0835 初始化
|
||
@param 无
|
||
@return 无
|
||
@note u8 qn8035_init(void *priv)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u8 qn8035_init(void *priv)
|
||
{
|
||
if (fm_dev_info == NULL) {
|
||
fm_dev_info = (struct _fm_dev_info *)priv;
|
||
}
|
||
puts("qn8035_init\n");
|
||
QND_WriteReg(0x00, 0x81);
|
||
delay_n10ms(1);
|
||
|
||
/*********User sets chip working clock **********/
|
||
//Following is where change the input clock wave type,as sine-wave or square-wave.
|
||
//default set is 32.768KHZ square-wave input.
|
||
QND_WriteReg(0x01, QND_SINE_WAVE_CLOCK);
|
||
//QND_WriteReg(0x58,0x93);
|
||
//Following is where change the input clock frequency.
|
||
QND_WriteReg(XTAL_DIV0, QND_XTAL_DIV0);
|
||
QND_WriteReg(XTAL_DIV1, QND_XTAL_DIV1);
|
||
QND_WriteReg(XTAL_DIV2, QND_XTAL_DIV2);
|
||
/********User sets chip working clock end ********/
|
||
|
||
QND_WriteReg(0x54, 0x47);//mod PLL setting
|
||
//select SNR as filter3,SM step is 2db
|
||
QND_WriteReg(0x19, 0xc4);
|
||
QND_WriteReg(0x33, 0x9e);//set HCC and SM Hystersis 5db
|
||
QND_WriteReg(0x2d, 0xd6);//notch filter threshold adjusting
|
||
QND_WriteReg(0x43, 0x10);//notch filter threshold enable
|
||
QND_WriteReg(0x47, 0x39);
|
||
//QND_WriteReg(0x57, 0x21);//only for qn8035B test
|
||
//enter receiver mode directly
|
||
QND_WriteReg(0x00, 0x11);
|
||
//Enable the channel condition filter3 adaptation,Let ccfilter3 adjust freely
|
||
QND_WriteReg(0x1d, 0xa9);
|
||
QND_WriteReg(0x4f, 0x40);//dsiable auto tuning
|
||
QND_WriteReg(0x34, SMSTART_VAL); ///set SMSTART
|
||
QND_WriteReg(0x35, SNCSTART_VAL); ///set SNCSTART
|
||
QND_WriteReg(0x36, HCCSTART_VAL); ///set HCCSTART
|
||
QNF_SetMute((void *)fm_dev_info, 0);
|
||
|
||
//dac_channel_on(FM_IIC_CHANNEL, FADE_ON);
|
||
|
||
return 0;
|
||
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 关闭 QN0835的电源
|
||
@param 无
|
||
@return 无
|
||
@note u8 QN8035_powerdown(void *priv)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u8 qn8035_powerdown(void *priv)
|
||
{
|
||
if (fm_dev_info == NULL) {
|
||
fm_dev_info = (struct _fm_dev_info *)priv;
|
||
}
|
||
puts("qn8035_powerdown\n");
|
||
// QND_SetSysMode(0);
|
||
QNF_SetMute((void *)fm_dev_info, 1);
|
||
QND_WriteReg(SYSTEM1, 0x20);
|
||
|
||
//dac_channel_off(FM_IIC_CHANNEL, FADE_ON);
|
||
return 0;
|
||
}
|
||
/**********************************************************************
|
||
void QND_TuneToCH(UINT16 ch)
|
||
**********************************************************************
|
||
Description: Tune to the specific channel.
|
||
Parameters:
|
||
ch:Set the frequency (10kHz) to be tuned,
|
||
eg: 101.30MHz will be set to 10130.
|
||
Return Value:
|
||
None
|
||
**********************************************************************/
|
||
void QND_TuneToCH(u16 channel)
|
||
{
|
||
u8 reg;
|
||
u16 ch;
|
||
ch = channel * 10;
|
||
//increase reference PLL charge pump current.
|
||
QND_WriteReg(REG_REF, 0x7a);
|
||
|
||
/********** QNF_RXInit ****************/
|
||
QND_WriteReg(0x1b, 0x70); //Let NFILT adjust freely
|
||
QND_WriteReg(0x2c, 0x52);
|
||
QND_WriteReg(0x45, 0x50); //Set aud_thrd will affect ccfilter3's tap number
|
||
QND_WriteReg(0x40, 0x70); //set SNR as SM,SNC,HCC MPX
|
||
QND_WriteReg(0x41, 0xca);
|
||
/********** End of QNF_RXInit ****************/
|
||
#if INVERSE_IMR
|
||
reg = QN_IIC_read(CCA) & ~0x40;
|
||
if ((ch == 9340) || (ch == 9390) || (ch == 9530) || (ch == 9980) || (ch == 10480)) {
|
||
reg |= 0x40; // inverse IMR.
|
||
} else {
|
||
reg &= ~0x40;
|
||
}
|
||
QND_WriteReg(CCA, reg);
|
||
#endif
|
||
QNF_SetMute((void *)fm_dev_info, 1);
|
||
QNF_SetCh(ch, ch, 1);
|
||
//enable CCA mode with user write into frequency
|
||
QND_WriteReg(0x00, 0x13);
|
||
//#if USING_INDUCTOR
|
||
if (qn8035_inductor) {
|
||
//Auto tuning
|
||
QND_WriteReg(0x4f, 0x80);
|
||
reg = QN_IIC_read(0x4f);
|
||
reg >>= 1;
|
||
QND_WriteReg(0x4f, reg);
|
||
}
|
||
//#endif
|
||
///avoid the "POP" noise.
|
||
//QND_Delay(CH_SETUP_DELAY_TIME);
|
||
//QND_Delay(500);
|
||
|
||
delay_n10ms(10);
|
||
|
||
///decrease reference PLL charge pump current.
|
||
QND_WriteReg(REG_REF, 0x70);
|
||
QNF_SetMute((void *)fm_dev_info, 0);
|
||
}
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 设置一个频点QN0835
|
||
@param fre 频点 875~1080
|
||
@return 1:当前频点有台,0:当前频点无台
|
||
@note bool set_fre_QN8035(u16 freq)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
bool QND_RXValidCH(u16 freq)
|
||
{
|
||
/* printf("set_8035_frq %d ", freq); */
|
||
u8 regValue;
|
||
u8 timeOut;
|
||
u8 isValidChannelFlag;
|
||
// UINT8 snr,snc,temp1,temp2;
|
||
#if PILOT_CCA
|
||
u8 snr, readCnt, stereoCount = 0;
|
||
#endif
|
||
/* freq = freq * 10; */
|
||
#if SCAN_NOISE_FLOOR_CCA
|
||
switch (freq) {
|
||
case 8750:
|
||
QND_ScanNoiseFloor(8750, 8800);
|
||
QND_RXSetTH();
|
||
break;
|
||
case 8810:
|
||
QND_ScanNoiseFloor(8810, 9200);
|
||
QND_RXSetTH();
|
||
break;
|
||
case 9210:
|
||
QND_ScanNoiseFloor(9210, 9600);
|
||
QND_RXSetTH();
|
||
break;
|
||
case 9610:
|
||
QND_ScanNoiseFloor(9610, 10000);
|
||
QND_RXSetTH();
|
||
break;
|
||
case 10010:
|
||
QND_ScanNoiseFloor(10010, 10400);
|
||
QND_RXSetTH();
|
||
break;
|
||
case 10410:
|
||
QND_ScanNoiseFloor(10410, 10800);
|
||
QND_RXSetTH();
|
||
break;
|
||
default:
|
||
//QND_Delay(350);
|
||
break;
|
||
}
|
||
#endif
|
||
QNF_SetCh(freq, freq, 1);
|
||
//#if USING_INDUCTOR
|
||
if (qn8035_inductor) {
|
||
//Auto tuning
|
||
QND_WriteReg(0x00, 0x11);
|
||
QND_WriteReg(0x4f, 0x80);
|
||
regValue = QN_IIC_read(0x4f);
|
||
regValue = (regValue >> 1);
|
||
QND_WriteReg(0x4f, regValue);
|
||
}
|
||
|
||
//#endif
|
||
//entering into RX mode and CCA mode,channels index decide by CCA.
|
||
QND_WriteReg(0x00, 0x12);
|
||
timeOut = 20; // time out is 100ms
|
||
while (1) {
|
||
regValue = QN_IIC_read(SYSTEM1);
|
||
//if it seeks a potential channel, the loop will be quited
|
||
if ((regValue & CHSC) == 0) {
|
||
break;
|
||
}
|
||
delay_n10ms(1); //delay 5ms
|
||
//if it was time out,chip would not normally work.
|
||
if ((timeOut--) == 0) {
|
||
return 0;
|
||
}
|
||
}
|
||
//reading out the rxcca_fail flag of RXCCA status
|
||
isValidChannelFlag = (QN_IIC_read(STATUS1) & RXCCA_FAIL ? 0 : 1);
|
||
if (isValidChannelFlag) {
|
||
//#if PILOT_CCA
|
||
if (qn8035_pilot_cca) {
|
||
|
||
for (readCnt = 10; readCnt > 0; readCnt--) {
|
||
delay_n10ms(2);
|
||
stereoCount += ((QN_IIC_read(STATUS1) & ST_MO_RX) ? 0 : 1);
|
||
if (stereoCount >= 3) {
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
|
||
delay_n10ms(10);
|
||
snr = QN_IIC_read(SNR);
|
||
if (snr > qn8075_snr) {
|
||
return 1;
|
||
}
|
||
} else {
|
||
return 1;
|
||
}
|
||
//#endif
|
||
}
|
||
return 0;
|
||
}
|
||
/**/
|
||
u8 qn8035_set_fre(void *priv, u16 fre)
|
||
{
|
||
if (QND_RXValidCH(fre)) {
|
||
QND_TuneToCH(fre);
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
void QND_SetVol(u8 vol)
|
||
{
|
||
u8 sVol;
|
||
u8 regVal;
|
||
sVol = vol * 3 + 2;
|
||
regVal = QN_IIC_read(VOL_CTL);
|
||
regVal = (regVal & 0xC0) | (sVol / 6) | ((5 - (sVol % 6)) << 3);
|
||
//regVal = (regVal&0xC0)|0x02|0x06;
|
||
QND_WriteReg(VOL_CTL, regVal);
|
||
}
|
||
|
||
/*
|
||
void QND_SetVol(u8 vol)
|
||
{
|
||
u8 sVol;
|
||
u8 regVal;
|
||
sVol=vol*3+2;
|
||
regVal = QN_IIC_read(VOL_CTL);
|
||
regVal = regVal&0xC0;
|
||
regVal |= (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(5));
|
||
regVal &= ~BIT(4);
|
||
|
||
QND_WriteReg(VOL_CTL,regVal);
|
||
}
|
||
*/
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief FM模块检测,获取QN0835 模块ID
|
||
@param 无
|
||
@return 检测到QN0835模块返回1,否则返回0
|
||
@note u8 QN8035_Read_ID(void *priv)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u8 qn8035_read_id(void *priv)
|
||
{
|
||
u8 cChipID;
|
||
|
||
if (fm_dev_info == NULL) {
|
||
fm_dev_info = (struct _fm_dev_info *)priv;
|
||
}
|
||
|
||
cChipID = QN_IIC_read(CID2);
|
||
cChipID &= 0xfc;
|
||
if (0x84 == cChipID) {
|
||
qn8035_online = 1;
|
||
return 1;
|
||
} else {
|
||
qn8035_online = 0;
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void qn8035_setch(u8 db)
|
||
{
|
||
QND_RXSetTH();
|
||
}
|
||
|
||
REGISTER_FM(qn8035) = {
|
||
.logo = "qn8035",
|
||
.init = qn8035_init,
|
||
.close = qn8035_powerdown,
|
||
.set_fre = qn8035_set_fre,
|
||
.mute = qn8035_mute,
|
||
.read_id = qn8035_read_id,
|
||
};
|
||
|
||
#endif
|