📄 fm_drv.c
字号:
/**
* modified by liwei@actions,2006,09,30
* add uint typedef
*/
/*********************************************************************
GL3963 TEA5767 FM Driver
File:FM_Driver.c
Written by Wangqian
Version:0.1
Update Data:2006-05-16
**********************************************************************/
#include "Actions_reg_213x.h"
//#include "console.h"
#include "extra_inc.h"
typedef unsigned int uint;
typedef unsigned long ulong;
#define IFhighlimit 0x3e
#define IFlowlimit 0x31
#define LEVdiffrence 0x02
/*function prototype from I2C_DRV.c*/
void I2C_Init(void);
void I2C_Exit(void);
char I2C_Start(unsigned long addr,char byt);
void I2C_Stop(void);
char I2C_WriteOneByte(char wbyte);
unsigned long I2C_ReadOneByte(char stat);
char trans_ov(void);
char recv_ov(void);
void DELAY_15us(void);
/*********************************Global Variable********************************/
unsigned long Write_Buffer[5] = {
0x00000080,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
unsigned long Read_Buffer[5] = {
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
/************ Write mode ***********/
char WSET_MUTE = 0; //Bit 7 of first byte of write buffer
char WSET_SM = 0; //Bit 6 of first byte of write buffer
unsigned long WSET_PLLHB = 0; //Bit 5 to 0 of first byte of write buffer
unsigned long WSET_PLLLB = 0; //Bit 7 to 0 of second byte of write buffer
char WSET_SUD = 0; //Bit 7 of third byte of write buffer(Search up/down)
char WSET_SSL = 0; //Bit 6 to 5 of third byte of write buffer(Search Stop Level)
char WSET_HLSI = 0; //Bit 4 of the third byte of write buffer(HIGH/LOW Side Injection)
char WSET_MS = 0; //Bit 3 of the third byte of write buffer(Mono/Stereo)
char WSET_MR = 0; //Bit 1 of the third byte of write buffer(Mute Right)
char WSET_ML = 0; //Bit 2 of the third byte of write buffer(Mute Left)
char WSET_SWP1 = 0; //Bit 0 of the third byte of write buffer(Software programmable port1)
char WSET_SWP2 = 0; //Bit 7 of the fourth byte of write buffer(Software programmable port2)
char WSET_STBY = 0; //Bit 6 of the fourth byte of write buffer(Standby)
char WSET_BL = 0; //Bit 5 of the fourth byte of write buffer(Band Limits)
char WSET_XTAL = 1; //Bit 4 of the fourth byte of write buffer
char WSET_SMUTE = 0; //Bit 3 of the fourth byte of write buffer(Soft Mute)
char WSET_HCC = 1; //Bit 2 of the fourth byte of write buffer(High Cut Control)
char WSET_SNC = 1; //Bit 1 of the fourth byte of write buffer(Stereo noise cancelling)
char WSET_SI = 0; //Bit 0 of the fourth byte of write buffer(Search indicator)
char WSET_PLLREF = 0; //Bit 7 of the fifth byte of write buffer
char WSET_DTC = 0; //Bit 6 of the fifth byte of write buffer.Bit 5 to 0 is not used,position don't care
/************Read mode************/
char RSET_RF = 0; //Bit 7 of the first byte of read buffer(Ready Flag)
char RSET_BLF = 0; //Bit 6 of the first byte of read buffer(Band Limit Flag)
char RSET_PLLHB = 0; //Bit 5 to 0 of first byte of write buffer
char RSET_PLLLB = 0; //Bit 7 to 0 of second byte of write buffer
char RSET_STEREO = 0; //Bit 7 of the third byte of read buffer(Stereo indication)
char RSET_IFCOUNTER = 0; //Bit 6 to 0 of the third byte of read buffer ,IF Counter result
char RSET_LEV = 0; //Bit 7 to 4 of the fourth byte of read buffer,Level ADC output
unsigned long FREQ_RF = 0;
/******************************Local Variable********************************/
char SOFT_LEV;
char SOFT_SUD;
char tempresult_LEV;
char Searchtemp_LEV;
char searchtemp_if;
char searchtemp_stereo;
char VOLUMELEV;
/********************************************************************************
Write Register:
Input Parameter:
*reg:Register point
var:Value
Output Parameter: No
********************************************************************************/
static void inline
Write_reg(volatile ulong * reg, ulong var)
{
*reg = var;
return;
}
/********************************************************************************
Read Register:
Input Parameter:
*reg:Register point
Output Parameter:
var:Return Value
********************************************************************************/
static ulong inline
Read_reg(volatile ulong * reg)
{
ulong var;
var = *reg;
return (var);
}
/********************************************************************************************
Function is I2C reading.
Input parameter:
readbuf(accept the data)
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
I2C_Read(unsigned long * readbuf)
{
unsigned long temp;
char flag;
int i;
for (i = 0; i < 4; i++) {
DELAY_15us();
temp = I2C_ReadOneByte(0x00); // ack
readbuf[i] = temp;
}
temp = I2C_ReadOneByte(0x01); // no ack
readbuf[4] = temp;
I2C_Stop();
flag = 1;
return (flag);
}
/********************************************************************************************
Function is I2C writing.
Input parameter:
wribuf(memory data)
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
I2C_Write(unsigned long * wribuf)
{
char flag;
static int i;
for (i = 0; i < 5; i++) {
flag = I2C_WriteOneByte(wribuf[i]);
if (flag == 0)
goto exit;
}
I2C_Stop();
exit:
return (flag);
}
/********************************************************************************************
Function is to read one frame.
Input parameter: no
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
READ_ONEFRAME(void)
{
char flag;
flag = I2C_Start(0xc1, 0);
if (flag == 0)
goto exit;
flag = I2C_Read(Read_Buffer);
exit:
return (flag);
}
/********************************************************************************************
Function is to write one frame.
Input parameter: no
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
WRITE_ONEFRAME(void)
{
char flag;
flag = I2C_Start(0xc0, 0);
if (flag == 0)
goto exit;
flag = I2C_Write(Write_Buffer);
exit:
return (flag);
}
/********************************************************************************************
Function is to drive standby of FM.
Input parameter:
stanb(direct on or off standby mode)
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
FM_STANDBY_Drv(char stanb)
{
char flag = 0;
static int c;
Write_Buffer[3] = Write_Buffer[3] & 0xbf; //no standby
WSET_STBY = stanb;
if (WSET_STBY != 0)
Write_Buffer[3] = Write_Buffer[3] | 0x40; //standby
c = 3;
do {
c = c - 1;
if (c == 0)
goto exit;
flag = WRITE_ONEFRAME();
} while (flag == 0);
exit:
return (flag);
}
/********************************************************************************************
Function is FM initialization and enable bus.
Input parameter:
1.bandinfo(japanese FM band or US/Europe FM band
2.softlev(adjust level)
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
FM_INIT_Drv(uint bandinfo, uint softlev)
{
//char flag_a,flag_g,flag_p,flag;
char flag;
WSET_MUTE = 0;
WSET_SM = 0;
WSET_PLLHB = 0;
WSET_PLLLB = 0;
WSET_SUD = 0;
WSET_SSL = 0;
WSET_HLSI = 0;
WSET_MS = 0;
WSET_MR = 0;
WSET_ML = 0;
WSET_SWP1 = 0;
WSET_SWP2 = 0;
WSET_STBY = 0;
WSET_BL = 0;
WSET_XTAL = 1;
WSET_SMUTE = 0;
WSET_HCC = 1;
WSET_SNC = 1;
WSET_SI = 0;
WSET_PLLREF = 0;
WSET_DTC = 0;
RSET_RF = 0;
RSET_BLF = 0;
RSET_PLLHB = 0;
RSET_PLLLB = 0;
RSET_STEREO = 0;
RSET_IFCOUNTER = 0;
RSET_LEV = 0;
FREQ_RF = 0;
WSET_MUTE = 0;
WSET_SM = 0; //no search
WSET_STBY = 0; //no standby
WSET_XTAL = 1; //XTAL f=32.768kHz
WSET_BL = bandinfo;
SOFT_LEV = softlev;
INIT_ADDA(1);
//flag_a=ENABLE_Ain(0x08);
//flag_g=SET_Again(0x02,0x05);
//flag_p=ENABLE_Pa(0x02,0x0f);
I2C_Init();
flag = FM_STANDBY_Drv(WSET_STBY);
//if((flag_a==1)&&(flag_g==1)&&(flag_p==1)) flag=1;
return (flag);
}
/********************************************************************************************
Function is FM exit and release bus.
Input parameter: no
Output parameter: no
********************************************************************************************/
void
FM_EXIT_Drv(void)
{
FM_STANDBY_Drv(1); //enter standby. added 2007-5-9 11:00 by wl.
I2C_Exit();
//DISABLE_Ain();
//DISABLE_Pa();
return;
}
/********************************************************************************************
Function is to assemble write buffer.
Input parameter: no
Output parameter: no
********************************************************************************************/
void
ASSEMBLE_WB(void)
{
char temp = 0;
temp = WSET_MUTE;
if (temp != 0)
WSET_PLLHB = WSET_PLLHB | 0x80;
if (WSET_SM != 0)
WSET_PLLHB = WSET_PLLHB | 0x40;
Write_Buffer[0] = WSET_PLLHB;
Write_Buffer[1] = WSET_PLLLB;
temp = (WSET_SUD & 0x01) << 7;
temp = temp | ((WSET_SSL & 0x03) << 6);
temp = temp | ((WSET_HLSI & 0x01) << 4);
temp = temp | ((WSET_MS & 0x01) << 3);
temp = temp | ((WSET_MR & 0x01) << 2);
temp = temp | ((WSET_ML & 0x01) << 1);
temp = temp | WSET_SWP1;
Write_Buffer[2] = temp;
temp = (WSET_SWP2 & 0x01) << 7;
temp = temp | ((WSET_STBY & 0x01) << 6);
temp = temp | ((WSET_BL & 0x01) << 5);
temp = temp | ((WSET_XTAL & 0x01) << 4);
temp = temp | ((WSET_SMUTE & 0x01) << 3);
temp = temp | ((WSET_HCC & 0x01) << 2);
temp = temp | ((WSET_SNC & 0x01) << 1);
temp = temp | WSET_SI;
Write_Buffer[3] = temp;
temp = (WSET_PLLREF & 0x01) << 7;
temp = temp | ((WSET_DTC & 0x01) << 6);
Write_Buffer[4] = temp;
return;
}
/********************************************************************************************
Function is to disassemble read buffer.
Input parameter: no
Output parameter: no
********************************************************************************************/
void
DISASSEMBLE_RB(void)
{
char temp;
temp = Read_Buffer[0];
RSET_RF = (temp >> 7);
RSET_BLF = (temp & 0x40) >> 6;
temp = Read_Buffer[2];
RSET_STEREO = (temp >> 7) & 0x1;
RSET_IFCOUNTER = (temp & 0x7f);
temp = Read_Buffer[3];
RSET_LEV = (temp & 0xf0) >> 4;
return;
}
/********************************************************************************************
Function is to calculate pll.
Input parameter:
freq(wanted frequency)
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
void
CALCULATE_Pll(unsigned long freq)
{
unsigned long PLL;
if (WSET_HLSI == 0) {
PLL = 125 * (freq - 225) / 1024;
} else {
PLL = 125 * (freq + 225) / 1024;
}
WSET_PLLLB = PLL & 0xff;
WSET_PLLHB = (PLL & 0xff00) >> 8;
return;
}
/********************************************************************************************
Function is to wait 50ms.
Input parameter: no
Output parameter: no
********************************************************************************************/
void
FMwait50ms(void)
{
#ifdef __DSP_RAM_FLAG__
{
volatile int i;
// 在32.768KHz频率下运行时,要延时50ms只需空等0.05 / ( 1 / 32768) 条指令即可
for(i = 0; i <= 1638; i++)
{
__asm__ __volatile__ ("nop");
}
}
#else
{
volatile int i, j, c;
int wait_times;
if(getCorePll() == 120 )
wait_times = 6000;
else
wait_times =1800;
for (i = 0; i <wait_times; i++) {//3000
for (j = 0; j < 120; j++) // 120
c = 0;
}
}
#endif
return;
}
/********************************************************************************************
Function is to read status.
Input parameter: no
Output parameter:
flag(1:success 0:failure)
********************************************************************************************/
char
READ_Status(void)
{
char flag = 0;
unsigned long temp;
static int c;
FMwait50ms();
//mdelay(100);
for (c = 4; c > 0; c--) {
flag = READ_ONEFRAME();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -