📄 i2c_tune_seek_0921.c
字号:
/******************************************************
START condition:
SCLK: -----------|______
SDIO:-----|_____________
1 | 2 | 3
STOP condition:
SCLK: ____|--------------
SDIO:____________|-------
1 | 2 | 3
DATA:
SCLK:_______________|---|________|----|_______
SDIO:___________|------------|____________|----
|<======= >|
RESET:
SENB:__|---------------------------------------------
SDIO:_________________________________________|------
RST: ___________|------------------------------------
SCLK:__|---------------------------------------------
| 1 | 2 | 3
********************************************************/
#define DURATION_INIT_1 600ns mininum
#define DURATION_INIT_2 600ns minimum
#define DURATION_INIT_3 600ns minimum
#define DURATION_START_1 600ns minimum
#define DURATION_START_2 600ns minimum
#define DURATION_START_3 800ns minimum
#define DURATION_STOP_1 800ns minimum
#define DURATION_STOP_2 600ns minimum
#define DURATION_STOP_3 1300ns minimum
#define DURATION_HIGH 900ns minimum
#define DURATION_LOW 1600ns minimum
#define POWER_SETTLING 50~100ms
//#define DELAY(DURATION) {unsigned short i; for(i = 1; i <= DURATION; i++){}}
#define READ 1
#define WRITE 0
void ResetSi4700_2w(void)
{
SDIO_DIR = OUT;
SENB = 1;
SDIO = 0;
RST = 0;
SCLK = 1;
DELAY(DURATION_INIT_1);
RST = 1;
DELAY(DURATION_INIT_2);
SDIO = 1;
DELAY(DURATION_INIT_3);
}
unsigned char OperationSi4700_2w(unsigned char operation, unsigned char *data, unsigned char numBytes)
{
unsigned char controlWord, j, error = 0;
int i;
/***************************************************
START: make sure here SDIO_DIR =OUT, SCLK = 1, SDIO = 1
****************************************************/
SCLK = 1;
SDIO = 1;
DELAY(DURATION_START_1);
SDIO = 0;
DELAY(DURATION_START_2);
SCLK = 0;
DELAY(DURATION_START_3);
/***************************************************
WRITE CONTROL DATA: make sure here: SLCK = 0; SDIO = 0
****************************************************/
if(operation == READ)
controlWord = 0x21;
else
controlWord = 0x20;
for(i = 7; i>=0; i--)
{
SDIO = (controlWord >> i) & 0x01;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/***************************
CHECK ACK for control word
***************************/
SDIO_DIR = IN;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(SDIO != 0)
{
error = 1;
goto STOP;
}
SCLK = 0;
DELAY(DURATION_LOW/2);
/***************************************
WRITE or READ data
****************************************/
for(j = 0; j < numBytes; j++, data++)
{
if(operation == WRITE)
SDIO_DIR = OUT;
else
SDIO_DIR = IN;
for(i = 7; i>=0; i--)
{
if(operation == WRITE)
SDIO = (*data >> i) & 0x01;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(operation == READ)
*data = (*data << 1) | SDIO;
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/******************************
CHECK ACK or SEND ACK=0
*******************************/
if(operation == WRITE)
SDIO_DIR = IN;
else
{
SDIO_DIR = OUT;
if(j == (numBytes -1))
SDIO = 1;
else
SDIO = 0;
}
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(operation == WRITE)
if(SDIO != 0)
{
error = 1;
goto STOP;
}
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/****************************
STOP: make sure here: SCLK = 0
*****************************/
STOP:
SDIO_DIR = OUT;
SDIO = 0;
DELAY(DURATION_STOP_1);
SCLK = 1;
DELAY(DURATION_STOP_2);
SDIO = 1;
DELAY(DURATION_STOP_3);
return(error);
}
UINT32 g_bandl=87500,g_bandh=108000;
UINT8 g_space=100,g_vol_level=0x08;
/**************************************
Si4700_Intialization():
after initialization please make sure(FW/B15):
0x00: 0x1242
0x01: 0x080F/0A0F
0x07: 0x3C04
0x08: 0x0008
0x09: 0x0001
***************************************/
void Si4700_Intialization(void)
{
unsigned char si4700_initialization[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x18,0x00,0x48};
unsigned char error_ind = 0;
g_vol_level=si4700_initialization[7]&0xf;
if(si4700_initialization[7]&0xc0==0x00){
g_bandl=87500;
g_bandh=108000;
}
else if(si4700_initialization[7]&0xc0==0x01){
g_bandl=76000;
g_bandh=108000;
}
else if(si4700_initialization[7]&0xc0==0x10){
g_bandl=76000;
g_bandh=90000;
}
if(si4700_initialization[7]&0x30==0x00){
g_space=200;
}
else if(si4700_initialization[7]&0x30==0x01){
g_space=100;
}
else if(si4700_initialization[7]&0x30==0x10){
g_space=50;
}
ResetSi4700_2w();
error_ind = OperationSi4700_2w(WRITE, &(si4700_initialization[0]), 10);
if(error_ind)
return;
DELAY(POWER_SETTLING);
}
/**************************************
Si4700_Channel_Selection()
***************************************/
void Si4700_Channel_Selection(UINT32 frq)
{
unsigned short loop_counter = 0;
unsigned char si4700_reg_data[4];
unsigned char error_ind = 0;
unsigned char si4700_channel_start_tune[] = {0x40,0x01,0x80,0xCA}; //107.7MHz
unsigned char si4700_channel_stop_tune[] = {0x40,0x01,0x00};
si4700_channel_start_tune[3]=(frq-g_bandl)/g_space;//channel
//set tune bit
error_ind = OperationSi4700_2w(WRITE, &(si4700_channel_start_tune[0]), 4);
if(error_ind)
return;
//wait STC=1
do
{
error_ind = OperationSi4700_2w(READ, &(si4700_reg_data[0]), 1);
if(error_ind)
return;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xff));
loop_counter = 0;
//clear tune bit
error_ind = OperationSi4700_2w(WRITE, &(si4700_channel_stop_tune[0]), 3);
if(error_ind)
return;
//wait STC=0
do
{
error_ind = OperationSi4700_2w(READ, &(si4700_reg_data[0]), 1);
if(error_ind)
return;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xff));
loop_counter = 0;
//read REG0A&0B
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
if(error_ind)
return;
}
/*****************************************************************************************************
Si4700_Channel_Seek()
return 0: good, current channel is valid
return 1: I2C error
return 2: used in SKMODE0, seek fail, no any valid channel, should end seek
return 2: used in SKMODE1, Band Limit, Stop seeking at the upper or lower band limit, should end seek
return 3: AFC rail, current channel is invalid, should seek next one
******************************************************************************************************/
UINT32 Si4700_Channel_Seek_UP(void)
{
unsigned short loop_counter = 0;
unsigned char si4700_reg_data[32];
unsigned char error_ind = 0, seek_error = 0;
unsigned char si4700_channel_seek_start[] = {0x41};
unsigned char si4700_channel_seek_stop[] = {0x40};
//set seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_start[0]), 1);
if(error_ind)
return 1;
//wait STC=1
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xfff)); //for loop_counter, when seek, the loop time must > 2s
loop_counter = 0;
//if you use SKMODE = 0, you can check Seek Fail here
//if you use SKMODE = 1, you can check Band Limit here
if((si4700_reg_data[0]&0x20) != 0)
seek_error = 2;
//you can check AFC Rail here
else if((si4700_reg_data[0]&0x10) != 0)
seek_error = 3;
//clear seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_stop[0]), 1);
if(error_ind)
return 1;
//wait STC=0
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xff));
loop_counter = 0;
//you can read REG0A&0B for channel number or RSSI here
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
if(error_ind)
return 1;
frq=(((UINT32)si4700_reg_data[2]<<8)|(UINT32)si4700_reg_data[3])&0x03ff;
return frq*g_space+g_bandl;
//return seek_error;
}
/*****************************************************************************************************
Si4700_Channel_Seek()
return 0: good, current channel is valid
return 1: I2C error
return 2: used in SKMODE0, seek fail, no any valid channel, should end seek
return 2: used in SKMODE1, Band Limit, Stop seeking at the upper or lower band limit, should end seek
return 3: AFC rail, current channel is invalid, should seek next one
******************************************************************************************************/
UINT32 Si4700_Channel_Seek_DOWN(void)
{
unsigned short loop_counter = 0;
unsigned char si4700_reg_data[32];
unsigned char error_ind = 0, seek_error = 0;
unsigned char si4700_channel_seek_start[] = {0x43};
unsigned char si4700_channel_seek_stop[] = {0x40};
//set seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_start[0]), 1);
if(error_ind)
return 1;
//wait STC=1
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xfff)); //for loop_counter, when seek, the loop time must > 2s
loop_counter = 0;
//if you use SKMODE = 0, you can check Seek Fail here
//if you use SKMODE = 1, you can check Band Limit here
if((si4700_reg_data[0]&0x20) != 0)
seek_error = 2;
//you can check AFC Rail here
else if((si4700_reg_data[0]&0x10) != 0)
seek_error = 3;
//clear seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_stop[0]), 1);
if(error_ind)
return 1;
//wait STC=0
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xff));
loop_counter = 0;
//you can read REG0A&0B for channel number or RSSI here
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
if(error_ind)
return 1;
frq=(((UINT32)si4700_reg_data[2]<<8)|(UINT32)si4700_reg_data[3])&0x03ff;
return frq*g_space+g_bandl;
//return seek_error;
}
void Si4700_mute_en(void){
unsigned char si4700_mute_data[1]={0x00};
OperationSi4700_2w(WRITE,si4700_mute_data, 1);
}
void Si4700_mute_dis(void){
unsigned char si4700_mute_data[1]={0x40};
OperationSi4700_2w(WRITE,si4700_mute_data, 1);
}
void Si4700_vol_up(void){
unsigned char si4700_vol_data[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x1f};
g_vol_level++;
if(g_vol_level<0||g_vol_level>15)
g_vol_level=15;
else{
si4700_vol_data[7]=g_vol_level|0x10;
OperationSi4700_2w(WRITE,si4700_mute_data, 8);
}
}
void Si4700_vol_down(void){
g_vol_level--;
if(g_vol_level<0||g_vol_level>15)
g_vol_level=0;
else{
si4700_vol_data[7]=g_vol_level|0x10;
OperationSi4700_2w(WRITE,si4700_mute_data, 8);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -