/**
************************************************************
************************************************************
************************************************************
* 文件名: si47xx.c
*
* 作者: 庞作超
*
* 日期: 2018-9-21
*
* 版本: V1.0
*
* 说明: si4734 FM模块驱动
*
* 修改记录:
************************************************************
************************************************************
************************************************************
**/
/*包含的头文件*/
#include "si47xx.h"
#include "fm_rtc_i2c.h"
#include "usart.h"
//类型定义
#include "typedef.h"
#include "system_task.h"
#undef LOG_TAG
#define LOG_TAG "si47xx"
#include <elog.h>
/*TUNE_STATUS相关变量*/
fm_tune_status_st fm_tune_status;
/*RSQ_STATUS相关变量*/
fm_rsq_status_st fm_rsq_status;
/*AGC_STATUS相关变量*/
u8 rf_agc_status;
u8 lna_gain_index;
/*频率信息*/
fm_freq_st fm_freq;
/*状态及命令和回复buf*/
u8 power_up=0;
u8 WaitSTCInterrupt = 0;
u8 SeekTuneInProc = 0;
u8 cmd[8];
u8 rsp[13];
u8 status;
u8 autoseek_flag=0;
/*
************************************************************
* 函数名称: si47xx_RESETGPIO_Config
*
* 函数功能: 复位引脚配置
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明: PB0--RESET
************************************************************
*/
void si47xx_RESETGPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体
RCC_APB2PeriphClockCmd( si47xx_RESET_CLK, ENABLE); //开启LED相关的GPIO外设时钟
GPIO_InitStructure.GPIO_Pin = si47xx_RESET_PIN; //选择要控制的GPIO引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHz
GPIO_Init(si47xx_RESET_PORT, &GPIO_InitStructure); //调用库函数,初始化GPIO
}
/*
************************************************************
* 函数名称: si47xx_SendCmd
*
* 函数功能: 向模块发送命令
*
* 入口参数: _pCmdBuf:命令 _ucCmdLen:命令字节数
*
* 返回参数: 0:写入失败 1:写入成功
*
* 说明:
************************************************************
*/
uint8_t si47xx_SendCmd(u8 *_pCmdBuf, u8 _ucCmdLen)
{
u8 ack;
u8 i;
Si47xx_IIC_Start();
ack = Si47xx_IIC_SendByte(si47xx_SLAVE_ADDRESS);
if (ack != 0)
{
goto err;
}
for (i = 0; i < _ucCmdLen; i++)
{
ack = Si47xx_IIC_SendByte(_pCmdBuf[i]);
if (ack != 0)
{
goto err;
}
}
Si47xx_IIC_Stop();
return 1;
err:
Si47xx_IIC_Stop();
return 0;
}
/*
************************************************************
* 函数名称: Delay
*
* 函数功能: 延迟
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
static void Delay(void)
{
int i=0,j=0;
for(i=0;i<1000;i++)
{
for(j=0;j<1000;j++)
{;}
}
}
/*
************************************************************
* 函数名称: si47xx_WriteReg
*
* 函数功能: 向模块寄存器写命令
*
* 入口参数: _pCmdBuf:命令 _ucCmdLen:命令字节数
*
* 返回参数: 0:写入失败 1:写入成功
*
* 说明:
************************************************************
*/
uint8_t si47xx_WriteReg(u8 *_pCmdBuf, u8 _ucCmdLen)
{
uint8_t ack;
uint8_t i;
Si47xx_IIC_Start();
ack = Si47xx_IIC_SendByte(si47xx_SLAVE_ADDRESS);
if (ack != 0)
{
goto err;
}
for (i = 0; i < _ucCmdLen; i++)
{
ack = Si47xx_IIC_SendByte(_pCmdBuf[i]);
if (ack != 0)
{
goto err;
}
}
Si47xx_IIC_Stop();
return 1;
err:
Si47xx_IIC_Stop();
return 0;
}
/*
************************************************************
* 函数名称: si47xx_ReadData
*
* 函数功能: 读取值
*
* 入口参数: num:字节数 Read:存储buf
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void si47xx_ReadData(u8 num, u8 *Read)
{
unsigned char i;
Si47xx_IIC_Start();
Si47xx_IIC_SendByte(si47xx_SLAVE_ADDRESS+1);
for(i=0;i<(num-1);i++)
{
Read[i] = Si47xx_IIC_RecvByte(ACK);
}
*Read=Si47xx_IIC_RecvByte(NACK);
Si47xx_IIC_Stop();
}
/*
************************************************************
* 函数名称: si47xx_readStatus
*
* 函数功能: 读取状态信息
*
* 入口参数: 无
*
* 返回参数: status:状态值
*
* 说明:
************************************************************
*/
u8 si47xx_readStatus()
{
u8 status;
si47xx_ReadData(1,&status);
return status;
}
/*
************************************************************
* 函数名称: si47xx_waitForCTS
*
* 函数功能: 等待CTS置一
*
* 入口参数: 无
*
* 返回参数: 0:waitForCTS失败 1:waitForCTS成功
*
* 说明:
************************************************************
*/
uint8_t si47xx_waitForCTS()
{
u16 i=1000;
while (--i && !(si47xx_readStatus() & CTS)) // 直到CTS置位.
{
Delay();
}
if(i==0)
{
return 0;
}
return 1;
/*可以选择对返回0的情况的处理*/
}
/*
************************************************************
* 函数名称: si47xx_command
*
* 函数功能: 发送命令获取返回值
*
* 入口参数: cmd_size:命令字节数 cmd:命令 reply_size:返回字节数 reply:返回的值
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
uint8_t si47xx_command(u8 cmd_size, u8 *cmd, u8 reply_size, u8 *reply)
{
u16 timeout=1000;
si47xx_WriteReg(cmd, cmd_size); //写命令到寄存器
while(--timeout&&!si47xx_waitForCTS()) // 等待CTS置一
{
Delay();
}
if(timeout==0)
{
return 0;
}
if(reply_size) // 读出返回值.
{
si47xx_ReadData(reply_size, reply);
}
return 1;
}
/*
************************************************************
* 函数名称: fmTuneFreq
*
* 函数功能: 发送FM_TUNE_FREQ命令设置频率并获取返回值
*
* 入口参数: frequency:频率
*
* 返回参数: 0:发送命令成功 1:发送命令失败
*
* 说明:FM_TUNE_FREQ=0x20
************************************************************
*/
static uint8_t fmTuneFreq(float frequency)
{
u16 freq=0;
u16 timeout=1000;
freq = (u16)(frequency*100.0);
cmd[0] = FM_TUNE_FREQ;
cmd[1] = 0;
cmd[2] = (u8)(freq >> 8);
cmd[3] = (u8)(freq & 0x00FF);
cmd[4] = (u8)0; //设置ANTCAP为Auto
while(--timeout&&!si47xx_command(5, cmd, 1, rsp)) // 等待CTS置一
{
Delay();
}
if(timeout==0)
{
LOG_E("FM_TUNE_FREQ失败\r\n");
return 0;
}
return 1;
}
/*
************************************************************
* 函数名称: getIntStatus
*
* 函数功能: 发送GET_INT_STATUS命令获取INT_STATUS
*
* 入口参数: 无
*
* 返回参数: rsp:返回的INT_STATUS状态
*
* 说明:GET_INT_STATUS=0x14
************************************************************
*/
u8 getIntStatus(void)
{
u16 timeout=1000;
u8 cmd[1] = {0};
u8 rsp[1] = {0};
cmd[0] = GET_INT_STATUS;
while(--timeout&&!si47xx_command(1, cmd, 1, rsp))
{
Delay();
}
if(timeout==0)
{
LOG_E("GET_INT_STATUS失败\r\n");
return 0;
}
return rsp[0];
}
/*
************************************************************
* 函数名称: fmAgcStatus
*
* 函数功能: 发FM_AGC_STATUS返回AGC的状态.
*
* 入口参数: 无
*
* 返回参数: 0:失败 1:成功
*
* 说明:FM_AGC_STATUS=0x27
* Outputs:
* rf_agc_status: RF AGC 是否使能
* 0 = RF AGC使能
* 1 = RF AGC失能
* lna_gain_index: LNA GAIN 的值
* 0 = 最小衰减 (最大增益)
* 1 – 25 衰减值
* 26 = 最大衰减 (最小增益)
************************************************************
*/
uint8_t fmAgcStatus()
{
u8 ucCmdBuf[2];
u16 uiTimeOut;
u8 i;
ucCmdBuf[0] = FM_AGC_STATUS;
si47xx_SendCmd(ucCmdBuf, 1);
uiTimeOut = si47xx_WaitStatus80(100, 0);
if (uiTimeOut == 0)
{
LOG_E("FM_AGC_STA