⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tea5760_drv.c

📁 是FM芯片 TEA5760的驱动代码 在ADS上面编译通过的.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Modify by xiezhongren.
 * Create 2006.12.1
 * Copyright by KONKA SOFTWARE GROUP. 2006.12.1
 *
 *
 */

#include "l1audio_def.h"
#if defined(TEA5760)
/* GPIO definition */
#if 0 
typedef unsigned short   uint16;
typedef short    int16;
typedef unsigned long   uint32;
typedef long    int32;
typedef unsigned char    uint8;
typedef char     int8;
#endif


#define TUNER_BYTE1            1
#define TUNER_BYTE2            2

#define TUNER_BIT0_MASK        0x01
#define TUNER_BIT1_MASK        0x02
#define TUNER_BIT2_MASK        0x04
#define TUNER_BIT3_MASK        0x08
#define TUNER_BIT4_MASK        0x10
#define TUNER_BIT5_MASK        0x20
#define TUNER_BIT6_MASK        0x40
#define TUNER_BIT7_MASK        0x80
//The following is for command bit mask
#define TUNER_MUTE_MASK        TUNER_BIT7_MASK
#define TUNER_MUTE_LOCATION    4

#define TUNER_SEARCH_MASK      TUNER_BIT6_MASK
#define TUNER_SEARCH_LOCATION  1

#define TUNER_HLSI_MASK        TUNER_BIT4_MASK
#define TUNER_HLSI_LOCATION    4

#define TUNER_MONO_STEREO_MASK TUNER_BIT3_MASK
#define TUNER_MONO_LOCATION    4

#define TUNER_STEREO_MASK      TUNER_BIT2_MASK
#define TUNER_STEREO_LOCATION  9


#define TUNER_STAND_BY_MASK     TUNER_BIT6_MASK
#define TUNER_STAND_BY_LOCATION 3

#define TUNER_SEARCH_UP_DOWN      TUNER_BIT7_MASK     
#define TUNER_SEARCH_UP_DOWN_LOCATION 1

#define TUNER_SSL0      TUNER_BIT5_MASK    
#define TUNER_SSL1      TUNER_BIT6_MASK      
#define TUNER_LEVEL_LOCATION 4


#define TUNER_BYTE3_DEFAULT    0x69
#define TUNER_BYTE4_DEFAULT    0x91
#define TUNER_BYTE3            3
#define TUNER_BYTE4            4

#define TUNER_BYTE5_DEFAULT    0x10
#define TUNER_BYTE6_DEFAULT    0x00
#define TUNER_BYTE5            5
#define TUNER_BYTE6            6

#define cFM_TUNER_FREQUENCY_START     8750
#define cFM_TUNER_FREQUENCY_END      10800
#define cFM_TUNER_FREQUENCY_STEP_SIZE_50KHz        5
#define cFM_TUNER_FREQUENCY_STEP_SIZE_100KHz       cFM_TUNER_FREQUENCY_STEP_SIZE_50KHz*2                     

#define SLAVE_ADDRESS                0x11
#define SUB_ADDRESS                  0
#define PHILIPS_I2C_WADDRESS          0x22 // by xiezhongren.
#define PHILIPS_I2C_RADDRESS          0x23 // by xiezhongren.

#define cIIC_READING_LENGTH             16 // 10
#define cIIC_WRITING_LENGTH             7


//extern int LM4811_ON(int fm_onoff);

static int16 Philips_FM_Read(uint8 *data, uint16 length, uint8 address);

static int16 Philips_FM_Send(uint8 *data, uint16 length, uint8 address);

void Philips_FM_Mute(uint8 mute);
static void FM_Debug_Print_Bin(uint8 *filename, uint8 *function, uint16 line_number, uint8 *debug_info,uint8 *data, uint16 length);
static void FM_Debug_Print_String(uint8 *filename, uint8 *function, uint16 line_number, uint8 *debug_info,uint8 *data);
static int16 Philips_FM_Send_checkRF(void);



#define HI_SIDE_INJECTION 1
#define LO_SIDE_INJECTION 0

#define FM_HLSI            0x10
#define FM_MUTE            0x80
#define FM_POWERON         0x40
#define FM_SUD             0x80
#define FM_SM              0x40

#define SEND_ADDRESS_WITHOUT_ACK       -1001
#define SEND_CMD_ACK_ERROR             -1002
#define SEND_READ_ADDRESS_WITHOUT_ACK  -1003
#define OPTIMIZER_HI_SIDE_READ_ERROR   -1004
#define OPTIMIZER_HI_SIDE_TIMEOUT_ERROR -1005
#define OPTIMIZER_LO_SIDE_READ_ERROR   -1006
#define OPTIMIZER_LO_SIDE_TIMEOUT_ERROR -1007
#define CHECK_PHILIPSFM_RF_TIMEOUT    -1008
#define CHECK_PHILIPSFM_REATCH_LIMIT  -1009
#define CHECK_PHILIPSFM_RF_READ_ERR   -1010

typedef struct {
	uint8 wb[7];
	uint8 rb[16];
	uint8 hi_level,lo_level;
}PHILIPS_FM;

PHILIPS_FM philips_fm;



static void FetchCommandData(void)
{
	//{0x00,0x00,0x00,0x49,0x10,0x00,0x00};
	philips_fm.wb[0] = 0x00;
	philips_fm.wb[1] = 0x00;
	philips_fm.wb[2] = 0x00;
	philips_fm.wb[3] = 0x49; 
	philips_fm.wb[4] = 0x10;  
	philips_fm.wb[5] = 0x00; 
	philips_fm.wb[6] = 0x00; 
    philips_fm.wb[TUNER_MONO_LOCATION]&=(~TUNER_MONO_STEREO_MASK);
    philips_fm.wb[TUNER_HLSI_LOCATION]|=TUNER_HLSI_MASK;
	FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Build Data",philips_fm.wb,7);  
}


static int32 GetPllFromFrequency(int16 curf,uint8 InJect_Type)
{
 
    int32 PLL;
    if(InJect_Type == HI_SIDE_INJECTION)
    {        
        PLL=((int32)curf*10000+225000)/8192;
    }
    else
    {
        PLL=((int32)curf*10000-225000)/8192;
    }
    return PLL;
	
}


void FMDrv_PowerOnReset(void)
{
	uint16 i;
	//uint8  philips_read_buffer[26];
	  
	SerialCommInit();
	FetchCommandData();

    	// Send Data....
	FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Init Send Data",philips_fm.wb,7);

	Philips_FM_Send(philips_fm.wb,7,PHILIPS_I2C_WADDRESS);

    	for( i = 0; i < 1000; i++);

    	Philips_FM_Read(philips_fm.rb,16,PHILIPS_I2C_RADDRESS);

	FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Init Send Data",philips_fm.rb,16);
	return;
	 
}


static int16 Philips_FM_Send(uint8 *data, uint16 length, uint8 address)
{
  uint16 i;
  uint8  ack;

  //kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);

  SerialCommStart();
  ack = SerialCommTxByte(address);
  if (ack != 0 )
  {
  
    kal_prompt_trace(MOD_MMI,"%s:%d: Write Address ACK not Low!!",__FILE__,__LINE__);
  	return SEND_ADDRESS_WITHOUT_ACK;
  }
       GPIO_WriteIO(1,7);//wzs
  for(i=0;i<length;i++)
  {
      ack = SerialCommTxByte(data[i]);
	  if (ack != 0 )
	  {
	    kal_prompt_trace(MOD_MMI,"%s:%d: I = [%d] Write Data ACK not Low!!",__FILE__,__LINE__,i);
	  	return SEND_CMD_ACK_ERROR;
	  }
	  else
	  {
	    kal_prompt_trace(MOD_MMI,"%s:%d: I = [%d] Write Data: [ %x ]",__FILE__,__LINE__,i,data[i]);
	  }
  }
 	SerialCommStop();
 //kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);
 
 return length; 
}

static int16 Philips_FM_Read(uint8 *data, uint16 length, uint8 address)
{
   uint16 i;
   uint8 ack;
   uint8 read_fm_data;

  //kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);

  SerialCommStart();


  ack = SerialCommTxByte(address);
  if (ack != 0 )
  {
    kal_prompt_trace(MOD_MMI,"%s:%d: Write Address ACK not Low!!",__FILE__,__LINE__);
  	return SEND_READ_ADDRESS_WITHOUT_ACK;
  }

  for(i=0;i<length-1;i++)
  {
	  SerialCommRxByte(&read_fm_data, 0);
	  data[i] = (uint8)read_fm_data;
  }
  SerialCommRxByte(&read_fm_data, 1);
  data[i] = (uint8)read_fm_data;

  SerialCommStop();
  //kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);
 
  return length; 
}


void FMDrv_PowerOffProc(void)
{
   int16 retcode;
   
   //GPIO_ModeSetup(3,0);
   //GPIO_InitIO(1,3);  
   //      GPIO_WriteIO(1,3);  // Modify, Enable LM4811
   // tunoff PHILIPS CHIPID1
   // 1. power offsetof
   FetchCommandData();
   philips_fm.wb[3] &= ~(FM_POWERON);
   retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);

   //Disable CHIP
  //GPIO_ModeSetup(6,0);
   //GPIO_InitIO(1,6);
   //GPIO_WriteIO(0,6);//wzs   //JAMES
   //Disable Loaudspeaker
  // LM4811_ON(1);
 
}

uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up)
{
    int16  retcode;
	uint8  fm_hlsi;
	uint32 command_pll;
	uint8  frrflag,if_value;
	uint16 i;
	uint8  search_directory;
	uint16 used_freq;


	used_freq = (freq*10);
	
	
    kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);


    if ( used_freq > 10800 || used_freq < 8750)
    {
	    kal_prompt_trace(MOD_MMI,"%s:%s:%d: fatal error: feq = %d \n",__FILE__,__func__,__LINE__,used_freq);    
		return 0;
    }

    if ( is_step_up )
    {
        search_directory = 1; //up
        fm_hlsi = 0;
    }
	else
	{
        search_directory = 0; //down
        fm_hlsi = 1;
	}

    if ( fm_hlsi)
    {
       command_pll = GetPllFromFrequency(used_freq, HI_SIDE_INJECTION);
    }
	else
    {
       command_pll = GetPllFromFrequency(used_freq, LO_SIDE_INJECTION);
    }

	FetchCommandData();

    philips_fm.wb[4] = (philips_fm.wb[4] | (FM_MUTE));
    //set HLSI
    if ( fm_hlsi)
    {
      philips_fm.wb[1] &= ~(FM_SUD);
      philips_fm.wb[4] |= FM_HLSI;
    }
    else
    {
      philips_fm.wb[1] |= FM_SUD;
      philips_fm.wb[4] &= (~FM_HLSI);  
    }

	// Threshold
	philips_fm.wb[4] |= 0x20; // 00100000
	// SETTING searching mode
	philips_fm.wb[1] |= FM_SM;
    // set feq.
    philips_fm.wb[1] |= (uint8)((command_pll>>8)&0x0000003f);
    philips_fm.wb[2] = (uint8)(command_pll&0x000000ff);

	//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Vaild stop send",philips_fm.wb,7);

    // send to philips chip register
    retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);

    if ( retcode < 0 )
    {
	    kal_prompt_trace(MOD_MMI,"%s:%s:%d: set register error,code = %d\n",__FILE__,__func__,__LINE__,retcode);    
		return 0; // FLASE
    }

    //wait for RF == 1 
    retcode = Philips_FM_Send_checkRF();
	if ( retcode < 0 )
	{
	     kal_prompt_trace(MOD_MMI,"%s,%s,%d: Check RF Error,retcode:%d", __FILE__,__func__,__LINE__,retcode);
         return 0;
	}
	//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Read vaild stop",philips_fm.rb,16);
    kal_prompt_trace(MOD_MMI,"%s:%s:%d: Feq = %d IF Count = %x, Level = %x ",__FILE__,__func__,__LINE__,used_freq,(philips_fm.rb[8]>>1),(philips_fm.rb[9]>>4));    
	
	// IF check
	if_value = (philips_fm.rb[8]>>1);

	if ( if_value <= 0x31 || if_value >= 0x3e )
	{
	    // not in condition check.
	    kal_prompt_trace(MOD_MMI,"%s,%s,%d: %x not in IF condition check. ",__FILE__,__func__,__LINE__,if_value);
		return 0;
	}

	philips_fm.hi_level = (philips_fm.rb[9]>>4);

/*
	if ( philips_fm.hi_level < 5 ) // FIXME!!
	{
		return 0;
	}
*/

	fm_hlsi = ( fm_hlsi )? 0:1;

    if ( fm_hlsi)
    {
       command_pll = GetPllFromFrequency(used_freq, HI_SIDE_INJECTION);
    }
	else
    {
       command_pll = GetPllFromFrequency(used_freq, LO_SIDE_INJECTION);
    }


	FetchCommandData();

    philips_fm.wb[4] = (philips_fm.wb[4] | (FM_MUTE));
    //set HLSI
    if ( fm_hlsi)
    {
      philips_fm.wb[1] &= ~(FM_SUD);
      philips_fm.wb[4] |= FM_HLSI;
    }
    else
    {
      philips_fm.wb[1] |= FM_SUD;
      philips_fm.wb[4] &= (~FM_HLSI);  
    }
	// SETTING searching mode
	philips_fm.wb[1] &= ~(FM_SM);
    // set feq.
    philips_fm.wb[1] |= (uint8)((command_pll>>8)&0x0000003f);
    philips_fm.wb[2] = (uint8)(command_pll&0x000000ff);

 //	FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Vaild stop send2",philips_fm.wb,7);
   // send to philips chip register
    retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);

    if ( retcode < 0 )
    {
	    kal_prompt_trace(MOD_MMI,"%s:%s:%d: set register error,code = %d\n",__FILE__,__func__,__LINE__,retcode);    
		return 0; // FLASE
    }

    //wait for RF == 1 
    retcode = Philips_FM_Send_checkRF();
	if ( retcode < 0 )
	{
	     kal_prompt_trace(MOD_MMI,"%s,%s,%d: Check RF Error,retcode:%d", __FILE__,__func__,__LINE__,retcode);
         return 0;
	}
    kal_prompt_trace(MOD_MMI,"%s:%s:%d: FEQ = %d IF Count2 = %x, Level = %x ",__FILE__,__func__,__LINE__,used_freq,(philips_fm.rb[8]>>1),(philips_fm.rb[9]>>4));    

	//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Read vaild stop2",philips_fm.rb,16);
	// IF check
	if_value = (philips_fm.rb[8]>>1);

	if ( if_value <= 0x31 || if_value >= 0x3e )
	{
	    // not in condition check.
	    kal_prompt_trace(MOD_MMI,"%s,%s,%d: %x not in IF condition check.",__FILE__,__func__,__LINE__,if_value);
		return 0;
	}

	philips_fm.lo_level = (philips_fm.rb[9]>>4);

/*
	if ( philips_fm.lo_level < 5 ) // FIXME!!
	{
		return 0;
	}
*/

    if ( philips_fm.lo_level > philips_fm.hi_level )
    {
    	if_value = philips_fm.lo_level - philips_fm.hi_level;
    }
	else
	{
    	if_value = philips_fm.hi_level - philips_fm.lo_level;
	}
		
    if ( if_value > 2 )
    {
    	return 0;
    }

    kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);

    return 1;
}

//频率选择优化
static int16 FM_Philips_optimizer(int16 curf)
{
  uint32 command1_pll,command2_pll;
  uint16 i;
  int16  retcode;
  int16  frrflag;
  uint8  fm_hlsi;
  // set command 1
  // PLL = F+450KHZ
  // HLSI = 1
  // MUTE = 1
  kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);  
  // 1. set Default command Data
  FetchCommandData();
  // 2. set HI INJECT PLL
  command1_pll = GetPllFromFrequency((curf+45), HI_SIDE_INJECTION);
  philips_fm.wb[4] = philips_fm.wb[4] | FM_HLSI| FM_MUTE; // HLSI = 1, MUTE = 1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -