原创 SP3767,TEA5767调谐驱动,基于ARM,ADS1.2(转)

2007-12-1 12:50 4264 7 7 分类: MCU/ 嵌入式

//SP3767和philips的TEA5767一样


/**
 * FL-120BC 收音模块 由TENSUN 深圳金图旭昂通讯科技有限公司
 * SP3767HN(the same as Philips' TEA5767HN) by SI-POWER 无锡,低功耗立体声收音电路
 * 2006 by Yan taosong<taosong.yan@gmail.com>
 */
#define  _SP3767_GLOBALS
#i nclude "fia.h"
#i nclude "sp3767.h"
#i nclude "i2c.h"
/*
苏    徐州市    徐州市    中央人民广播电台           
苏    徐州市    徐州市    江苏人民广播电台           
苏    徐州市    ??    徐州电台        94.2    
苏    徐州市    徐州市    徐州电台新闻综合频道    1269    93.0    
苏    徐州市    徐州市    徐州电台经济台    801    91.6    
苏    徐州市    徐州市    徐州电台交通台        103.3    
苏    徐州市    徐州市    徐州电台文艺之声    1143    89.6      —
苏    徐州市    贾旺区          —       
苏    徐州市    铜山县    铜山人民广播电台      —    94.2      —
苏    徐州市    沛县    沛县 徐州 221600       —         —
苏    徐州市    丰县    丰县 徐州 221700       —         —
苏    徐州市    邳州市    邳州市 徐州 221300       —         —
苏    徐州市    新沂市    新沂人民广播电台      —    99.9      —
苏    徐州市    睢宁县    睢宁县 徐州 221200       —         —
*/


/* main.c */
extern AT91PS_SYS AT91_SYS;


extern void mdelay(int ms);


int read_sp3767(char *info ,short len);
int write_sp3767(char *info ,short len);
void enable_search(void);
void disable_search(void);



char sp3767_tx[5];
char sp3767_rx[5] = { 0xff, 0xff, 0xff, 0xff, 0xff};


int write_sp3767(char *info ,short len)
{
 struct i2c_msg msgs[2];
 unsigned char rw_bit = 0;
 int ret; 
  
 msgs[0].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[0].flags = rw_bit;
 /* 无内部地址 */
 msgs[0].len = 0;
 msgs[0].buf = 0;
 
 msgs[1].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[1].flags = rw_bit;
 msgs[1].len = len;
 msgs[1].buf = info;


 ret =at91_i2c_transfer(msgs);
 
 return ret; 
}


int read_sp3767(char *info ,short len)
{
 struct i2c_msg msgs[2];
 unsigned char rw_bit = 1;//i2c read
 int ret; 
  
 msgs[0].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[0].flags = rw_bit;
 /* 无内部地址 */
 msgs[0].len = 0;
 msgs[0].buf = 0;
 
 msgs[1].addr = SP3767_I2C_SLAVE_ADDR;
 msgs[1].flags = rw_bit;
 msgs[1].len = len;
 msgs[1].buf = info;


 ret = at91_i2c_transfer(msgs);
 
 return ret; 
}


/*
 * frq(频率)以62.5Hz为单位,如98.0MHz ,frq = 98000000/62.5=1568000
 * div与频率的关系:
 *    f="87".5MHz  ,div = (87500 * 4 + 700 + 225 + 25) / 50;
 */
void set_sp3767_freq(unsigned int frq)
{
    unsigned div;


    //printk("radio freq = %d.%03d MHz\r\n", frq/16000,(frq/16)%1000);


    sp3767_tx[2] = SP3767_PORT1_HIGH;
    sp3767_tx[3] = SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL;
    //sp3767_tx[4] = 0;


//    printk("SP3767 set to stereo\r\n");
//    printk("SP3767 radio HIGH LO inject xtal @ 32,768 MHz\r\n");
 
    sp3767_tx[2] |= SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] |= SP3767_XTAL_32768;
    /* const 700=4000*175 kHz - to adjust freq to right value */
    /* 锁相环的参考频率为32.768kHz,所以要>>15,即除以32768
     * frq*(4000/16)*/
    div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
    sp3767_tx[0] |= (div >> 8) & 0x3f;
    sp3767_tx[1] = div & 0xff;
 write_sp3767(sp3767_tx, 5);
}


void set_sp3767_freq_real(unsigned int frq)
{
    unsigned div;
    static unsigned char count="0";
 frq = frq/62.5;
    printk("radio freq = %d.%03d MHz , count:%d\r\n", frq/16000,(frq/16)%1000,count++);


    sp3767_tx[2] |= SP3767_PORT1_HIGH;
    sp3767_tx[3] |= SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL;
    sp3767_tx[4] = 0;


//    printk("SP3767 set to stereo\r\n");
//    printk("SP3767 radio HIGH LO inject xtal @ 32,768 MHz\r\n");
 
    sp3767_tx[2] |= SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] |= SP3767_XTAL_32768;
    /* const 700=4000*175 kHz - to adjust freq to right value */
    /* 锁相环的参考频率为32.768kHz,所以要>>15,即除以32768
     * frq*(4000/16)*/
    div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
    sp3767_tx[0] |= (div >> 8) & 0x3f;
    sp3767_tx[1] = div & 0xff;
 write_sp3767(sp3767_tx, 5);
}


void sp3767_auto_search(unsigned int from_frq ,unsigned int to_frq)
{
 //float step = 62.5;
 unsigned int diff;
 unsigned int frq = from_frq;//1400000;//87.5MHz
 unsigned div;
 unsigned char station = 0;
 unsigned char completed = 0;
 char buf[5];
 
 //set_sp3767_freq_real(100000000);
 
 for (diff = 0 ;diff < 2000 ;diff ++){
  set_sp3767_freq_real(87500000+diff*10000);
  enable_search();
  read_sp3767(buf ,5);
  while(!(buf[0]&0x80)&&!completed){
   read_sp3767(buf ,5);
   mdelay(20);
   //if((buf[0]&0x80))printk("locked   \r\n");
   if((buf[1]&0x7f)>0x31&&(buf[1]&0x7f)<0x3E){
    completed = TRUE;
    
    printk("Locked  buf[1]:%x \r\n",(buf[1]&0x7f));
    
   }
  }
  completed = FALSE;
  //mdelay(100);
  //disable_search();
  mdelay(50);
 }
 
 
 
#if 0 
 enable_search();
 
 
 from_frq = (unsigned int)((float)from_frq/62.5);
 to_frq   = (unsigned int)((float)to_frq/62.5);
   


 for (diff = 0 ;diff <= (to_frq - from_frq)/100 && !completed;diff++){
  //set_sp3767_freq(from_frq + diff*100);
  read_sp3767(buf ,5);  
  /* RF : 1 ,a band is locked
   *      0 ,no band is locked */
   //div = ((unsigned)(buf[0]&0x3f)<<8)+(unsigned)buf[1];
   //frq = ((((unsigned int)div << 15) - 700000 - 225000 - 16384)*16)/4000;
   
   //printk("%d.%03dMHz ,frq=%d\r\n",frq/16000 ,(frq/16)%1000,frq);
   mdelay(20);//400
 //  div = ((unsigned)(buf[0]&0x3f)<<8)+((unsigned)buf[1])&0x00ff;
 //  frq = (unsigned int)((((float)( ((unsigned int)div * 32768) - 700000 - 225000 - 16384)*16)/4000)*62.5);
 //  printk("locked! ,diff:%d,station:%d,frq=%d,[0]:%x,[1]:%x,[2]:%x\r\n",diff,station,frq,buf[0],buf[1],buf[2]);
#if 1
  if (buf[0] & SP3767_READY_FLAG_MASK){
   station++;
   enable_search();
   div = ((unsigned)(buf[0]&0x3f)<<8)+(((unsigned)buf[1])&0x00ff);
   frq = (unsigned int)((((float)( ((unsigned int)div * 32768) - 700000 - 225000 - 16384)*16)/4000)*62.5);
   //printk("%d.%03dMHz band is locked , station = %d\r\n",frq/16000 ,(frq/16)%1000 ,station);
   //printk("locked!");
   //buf[2]:IF
   //set_sp3767_freq_real(frq);
   printk("locked! ,diff:%d,station:%d,frq=%d,[0]:%x,[1]:%x,[2]:%x\r\n",diff,station,frq,buf[0],buf[1],buf[2]);
   mdelay(200);
   //station ++;
  }
#endif  
  /* 先自动搜索5个台试试看 */
  //if (station >= 5)
   //completed = 1;  
 }
 disable_search();
#endif
 
}



void turn_on_sp3767(void)
{
 sp3767_tx[3] &= (~SP3767_STDBY);
 sp3767_tx[0] &= (~SP3767_MUTE);
 write_sp3767(sp3767_tx, 5);
 printk("Turn on radio.\r\n");
}


/* 待机模式,STBY(standby) */
void turn_off_sp3767(void)
{
 sp3767_tx[3] |= SP3767_STDBY;
 write_sp3767(sp3767_tx, 5);
}


void enable_search(void)
{
 /* Enable search mode */
 sp3767_tx[0] |= SP3767_SEARCH;
 write_sp3767(sp3767_tx, 5);
}


void disable_search(void)
{
 /* Disable search mode */
 sp3767_tx[0] &= (~SP3767_SEARCH);
 write_sp3767(sp3767_tx, 5);
}


int sp3767_detect(void)
{
 read_sp3767(sp3767_rx ,5);


  printk("rx[0] = %x ,rx[1] = %x ,rx[2] = %x ,rx[3] = %x ,rx[4] = %x \r\n",sp3767_rx[0],sp3767_rx[1],sp3767_rx[2],sp3767_rx[3],sp3767_rx[4]);
    /*  Status bytes:
     *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
     *          bit 0   : internally set to 0
     *  Byte 5: bit 7:0 : == 0 */
    if (((sp3767_rx[3] & 0x0f) != 0x00) || (sp3767_rx[4] != 0x00)) {
     printk("Chip ID is not zero. It is not a SP3767\r\n");
        return -1;
    }
 
 printk("SP3767 detected.\r\n");
 return 0;
 
}


void AT91F_SP3767_CfgPIO(void)
{
 /* I2C configuration */
 //AT91_SYS->PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
 //AT91_SYS->PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK; 
}


int sp3767_init(void)
{
 /* 对SP3767所需要的PIO进行初始化 */
 AT91F_SP3767_CfgPIO();
 /* Detect SP3767 */
 if(sp3767_detect()){
  printk("Can't find SP3767\r\n");
  return -1;
 }


 /* 静音,非搜索模式 */
 sp3767_tx[0] = SP3767_MUTE;
 sp3767_tx[1] = 0;
 /* 搜索停止标准:搜索模式下禁止 , 立体声 ,左右声道正常 */
 //sp3767_tx[2] = 0;
    //sp3767_tx[2] = SP3767_PORT1_HIGH;
    /* 自动搜索时,由高频往低频搜索(搜索方向) */
    sp3767_tx[2] = SP3767_PORT1_HIGH/*|SP3767_SEARCH_UP*/|SP3767_SRCH_HIGH_LVL|SP3767_HIGH_LO_INJECT;
    sp3767_tx[3] = SP3767_PORT2_HIGH | SP3767_HIGH_CUT_CTRL |
                    SP3767_ST_NOISE_CTL|SP3767_XTAL_32768|SP3767_STDBY;
 /* 初始化处于待机模式 ,XTAL为32.768KHz */
 //sp3767_tx[3] = SP3767_STDBY|SP3767_XTAL_32768;
 sp3767_tx[4] = 0;
 /* Write SP3767 initial status */
 //write_sp3767(sp3767_tx, 5);
 return 0;
}


 


连接:http://www.mcublog.com/blog/user1/11414/archives/2006/16753.html

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条