KT24-1110_65E-HA-651B/apps/common/device/fm/bk1080/Bk1080.c
2024-11-10 18:44:17 +08:00

468 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*--------------------------------------------------------------------------*/
/**@file bk1080.c
@brief BK1080收音底层驱动
@details
@author
@date 2011-3-30
@note
*/
/*----------------------------------------------------------------------------*/
#include "app_config.h"
#include "system/includes.h"
#include "fm/fm_manage.h"
#include "BK1080.h"
#if(TCFG_FM_BK1080_ENABLE && TCHFG_SOFT_I2C_ENABLE)
extern void delay_2ms(int cnt);
#define delay_n10ms(x) \
delay_2ms(x*5)
static struct _fm_dev_info *fm_dev_info;
/**
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 必看 @@@@@@@@@@@@@@@@@@@@@@@@@@@
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 必看 @@@@@@@@@@@@@@@@@@@@@@@@@@@
*
*BK1080H可以使用外部晶振
*
*BK1080E不能使用外部晶振因此主控需要提供一个时钟
*BK1080E需要的时钟范围是32.768kHz~38.4MHz
*可以通过以下bk1080e_set_clk函数让主控在PA0输出一个24MHz的时钟
*该函数使用时加到int fm_dev_init(void *_data)函数的第一行
*该时钟及输出的IO口可配置如需要可联系原厂提供帮助
*
*/
/* void bk1080e_set_clk(void){ */
/* JL_PORTA->DIR &= ~BIT(0); */
/* JL_CLOCK->CLK_CON0 &=~ BIT(12); */
/* JL_CLOCK->CLK_CON0 &=~ BIT(11); */
/* JL_CLOCK->CLK_CON0 |= BIT(10); */
/* } */
/*------------BK1080 Initialization Table-----------------*/
/*
const u16 HW_Reg[]=
{
0x0008,
0x1080,
#if XTAL_CLOCK //reg2
0x1201, //for internal crystal clock
#else
0x0201, //for extern clock
#endif
0x0000,
0x40C0,
0x0A1F, //reg5 RSSI[15:8] BAND[7:6] SPACE[5:4],Europe standar
0x002E,
0x02FF,
0x5B11,
0x0000,
0x411E,
0x0000,
0xCE00,
0x0000,
0x0000,
0x1000, //reg15
0x0010,
0x0000,
0x13FF,
0x9852,
0x0000,
0x0000,
0x0008,
0x0000,
0x51E1,
0x28DC,
0x2645,
0x00E4,
0x1CD8,
0x3A50,
0xEAF0,
0x3000, //reg31
0x0200,
0x0000,
};
*/
const u16 HW_Reg[] = {
0x0800,
0x8010,
#if XTAL_CLOCK //reg2
0x0112, //for internal crystal clock
#else
0x0142, //for extern clock, system mute
#endif
0x0000,
0xC040,
0x1F0A, //reg5 RSSI[15:8] BAND[7:6] SPACE[5:4],Europe standar
0x2E00,
0xFF02,
0x115B,
0x0000,
0x1E41,
0x0000,
0x00CE,
0x0000,
0x0000,
0x0010, //reg15
0x1000,
0x0000,
0xFF13,
0x5298,
0x0000,
0x0000,
0x0800,
0x0000,
0xE151,
0xDC38,
0x4526,
0xE400,
0xD81C,
0x503A,
0xF0EA,
0x0030, //reg31
0x0002,
0x0000,
};
u8 bk1080_iic_write(u8 w_chip_id, u8 register_address, u8 *buf, u32 data_len)
{
u8 ret = 1;
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 bk1080_iic_readn(u8 r_chip_id, u8 register_address, u8 *buf, u8 data_len)
{
u8 read_len = 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 bk1080_iic_write
#define app_IIC_readn bk1080_iic_readn
/*----------------------------------------------------------------------------*/
/**@brief BK1080读寄存器函数
@param num 需要的数目
@return 无
@note void BEKEN_I2c_Read(u8 reg,u8 *pBuf,u8 num)
*/
/*----------------------------------------------------------------------------*/
static void BEKEN_I2c_Read(u8 reg, u8 *pBuf, u8 num)
{
reg = reg << 1;
reg |= 0x01;
app_IIC_readn(CHIP_DEV_ID, reg, pBuf, num);
}
/*----------------------------------------------------------------------------*/
/**@brief BK1080读寄存器函数
@param num 需要的数目
@return 无
@note void BEKEN_I2c_Write(u8 reg,u8 *pBuf,u8 num)
*/
/*----------------------------------------------------------------------------*/
static void BEKEN_I2c_Write(u8 reg, u8 *pBuf, u8 num)
{
reg = reg << 1;
app_IIC_write(CHIP_DEV_ID, reg, pBuf, num);
}
/*----------------------------------------------------------------------------*/
/**@brief BK1080 初始化
@param 无
@return 无
@note void init_BK1080(void)
*/
/*----------------------------------------------------------------------------*/
void bk1080_init(void *priv)
{
if (priv != NULL) {
fm_dev_info = priv;
}
u8 temp[2];
//delay_n10ms(100); //delay 1s,please revise delay time according to your MCU
BEKEN_I2c_Write(0, (u8 *)HW_Reg, 68); //start from reg2,total 60 byte
delay_n10ms(25); //delay 250ms
temp[0] = HW_Reg[25];
temp[1] = HW_Reg[25] >> 8;
temp[1] &= 0x7f;
BEKEN_I2c_Write(25, temp, 2);
temp[1] |= 0x80;
BEKEN_I2c_Write(25, temp, 2);
/* dac_channel_on(FM_IIC_CHANNEL, FADE_ON); */
delay_n10ms(5); //delay 50ms
}
/*----------------------------------------------------------------------------*/
/**@brief 设置一个频点 BK1080
@param curFreq设置频点
@return 无
@note void bk1080_setfreq(u16 curFreq)
*/
/*----------------------------------------------------------------------------*/
void bk1080_setfreq(u16 curFreq)
{
u8 curChan;
u16 temp;
curChan = curFreq - (REAL_FREQ_MIN / 10);
temp = curChan << 8;
BEKEN_I2c_Write(0x03, (u8 *)&temp, 2); //write reg3,with 2 bytes
temp |= 0x80;
BEKEN_I2c_Write(0x03, (u8 *)&temp, 2);
}
/*----------------------------------------------------------------------------*/
/**@brief 设置一个频点BK1080
@param fre 频点 875~1080
@return 1当前频点有台0当前频点无台
@note bool bk1080_set_fre(u16 freq)
*/
/*----------------------------------------------------------------------------*/
bool bk1080_set_fre(void *priv, u16 freq)
{
static u16 last_tuned_freq;
static u16 g_last_freq_deviation_value;
u8 temp[4];
u16 cur_freq_deviation;
bk1080_setfreq(freq);
delay_n10ms(4); //延时时间>=30ms
///////////////////////////////////////////////////////////////////
//new added 2009-05-30
BEKEN_I2c_Read(0x07, temp, 2); //start from reg 0x7,with 2bytes
cur_freq_deviation = (temp[0] << 8) | temp[1];
cur_freq_deviation = cur_freq_deviation >> 4;
BEKEN_I2c_Read(0x0a, &temp[2], 2);
/////////////////////////////////////////////////////////////////////
if (temp[2] & 0x10) { //check AFCRL bit12
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
if (temp[3] < 8) { //RSSI<10 //搜台较少可减少该值,假台较多可增大该值 //8
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
if ((temp[1] & 0x0f) < 2) { //SNR<2 //搜台较少可减少该值,假台较多可增大该值
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
/////////////////////////////////////////////////////////////////////////
//add frequency devation check
if ((cur_freq_deviation >= 192) && (cur_freq_deviation <= (0xfff - 192))) { //0x64 //搜台较少可减少该值,假台较多可增大该值
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
///////////////////////////////////////////////////////////////////////////
//new added 2009-05-30
if ((freq > 875) && ((freq - last_tuned_freq) == 1)) { //start_freq)&&( (freq-last_tuned_freq)==1) )
if (g_last_freq_deviation_value & 0x800) {
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
if (g_last_freq_deviation_value < 150) { //搜台较少可减少该值,假台较多可增大该值
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
}
if ((freq >= 875) && ((last_tuned_freq - freq) == 1)) { //start_freq)&&( (last_tuned_freq - freq)==1) )
if ((g_last_freq_deviation_value & 0x800) == 0) {
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
if (g_last_freq_deviation_value > (0xfff - 150)) { //搜台较少可减少该值,假台较多可增大该值
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 0;
}
}
last_tuned_freq = freq; //save last tuned freqency
g_last_freq_deviation_value = cur_freq_deviation;
return 1;
}
/*----------------------------------------------------------------------------*/
/**@brief 关闭 BK1080的电源
@param 无
@return 无
@note void BK1080_PowerDown(void)
*/
/*----------------------------------------------------------------------------*/
void bk1080_powerdown(void *priv)
{
u16 temp = 0x4102;
//temp[0] = 0x02; //write 0x0241 into reg2
//temp[1] = 0x41;
BEKEN_I2c_Write(0x02, (u8 *)&temp, 2);
/* dac_channel_off(FM_IIC_CHANNEL, FADE_ON); */
delay_n10ms(5); //delay 50ms
}
/*----------------------------------------------------------------------------*/
/**@brief FM 模块静音控制
@param dir1-mute 0-unmute
@return 无
@note void BK1080_mute(dir)
*/
/*----------------------------------------------------------------------------*/
void bk1080_mute(void *priv, u8 flag)
{
u8 TmpData8[2];
BEKEN_I2c_Read(2, TmpData8, 2);
if (flag) {
TmpData8[0] |= 0x40; //mute
} else {
TmpData8[0] &= 0xbf;
}
BEKEN_I2c_Write(2, TmpData8, 2);
}
/*----------------------------------------------------------------------------*/
/**@brief FM模块检测获取BK1080 模块ID
@param 无
@return 检测到BK1080模块返回1否则返回0
@note bool BK1080_Read_ID(void)
*/
/*----------------------------------------------------------------------------*/
bool bk1080_read_id(void *priv)
{
u16 bk_id;
if (fm_dev_info == NULL) {
fm_dev_info = (struct _fm_dev_info *)priv;
}
BEKEN_I2c_Read(0x01, (u8 *)&bk_id, 2); //read reg3,with 2 bytes
printf("bk1080_read_id %x", bk_id);
if (0x8010 == bk_id) {
return TRUE;
}
return FALSE;
}
void bk1080_test(void)
{
printf("bk1080 test\n");
}
REGISTER_FM(bk1080) = {
.logo = "bk1080",
.init = bk1080_init,
.close = bk1080_powerdown,
.set_fre = bk1080_set_fre,
.mute = bk1080_mute,
.read_id = bk1080_read_id,
};
#endif