📄 codec.c
字号:
#include "vxWorks.h" /* types */
#include "codec.h"
#include "Ads860.h"
#include "drv/multi/ppc860Siu.h"
#ifndef CODEC_DEBUG
#define CODEC_DEBUG
#endif
/* in the bit patterns, 'u' means 'untouched', 'x' means 'any'*/
/*The funtion read single register value
Channel_sel: 0 means CODEC 1 channel 1, 1 means CODEC 1 channel2.
2 means CODEC 2 channel 1, 3 means CODEC 2 channel2.
*/
unsigned char readreg(unsigned char Channel_sel,unsigned char reg_beg,unsigned char len)
{
unsigned char tmp[100];
int i=0;
UINT length;
unsigned char channel_adr;
channel_adr = 0x80+(3-Channel_sel)*2;/*cal codec channel address*/
if(reg_beg>6)return ERROR;
if( len < 1) return ERROR;
tmp[0] = reg_beg;
length = I2CRead(channel_adr,tmp,len);
for(i=0;i<len;i++)
{
/* printf ("reg 0x%x val: 0x%x\n",i ,tmp[i]);*/
}
return tmp[0];
}
/*The funtion write single register
Channel_sel: 0 means CODEC 1 channel 1, 1 means CODEC 1 channel2.
2 means CODEC 2 channel 1, 3 means CODEC 2 channel2.
reg: 1~6
*/
void Codec_Write_Reg(unsigned char Channel_sel,unsigned char reg,unsigned char val)
{
unsigned char tp[2] ={R3B,0x66};/*R3b =0x66*/
UINT channel_adr;
channel_adr = 0x80+(3-Channel_sel)*2;/*cal codec channel address*/
tp[0] = reg;
tp[1] = val;
I2CWrite(channel_adr,tp,2);
}
/*
The funtion hardware reset codec
*/
void HardwareResetCodec(void)
{
int immrVal = INTERNAL_MEM_MAP_ADDR;
int i=0;
*PDPAR(immrVal) &= ~0x00C0;
*PDDIR(immrVal) |= 0x00C0;
*PDDAT(immrVal) &= ~0x00C0; /*pd8,pd9 <---0 for codec reset */
for(i=0;i<2000;i++);
*PDDAT(immrVal) |= 0x00C0; /*pd8,pd9<---1*/
}
/*The funtion soft reset codec
codec_sel: 0 means CODEC 1 channel 1, 1 means CODEC 1 channel2.
2 means CODEC 2 channel 1, 3 means CODEC 2 channel2.
reg: 1~6
*/
void SoftResetCodec(unsigned char codec_sel)
{
if(codec_sel == 0)/*maste channel 1*/
{
readreg(0,1,1);
readreg(1,1,1);
Codec_Write_Reg(0,3,0x08);
Codec_Write_Reg(1,3,0x08);
}
else if(codec_sel == 1)/*slave channel 1*/
{
readreg(2,1,1);
readreg(3,1,1);
Codec_Write_Reg(2,3,0x08);
Codec_Write_Reg(3,3,0x08);
}
}
/*************************************************************
* this codec's write cycle is fixed and only do according to attached follows
* please see the file INTERFACE WITH VOICE-BAND CODECS USING I2C
* Group :{CR1,CR2,CR3A},
{CR3B},
{CR3C},
{CR3D,CR4A(Nand P)},
{CR4B(M),CR5A},
{CR5B},
{CR5C},
{CR5D,CR6A},
{CR6B}
**********************************************************/
/*************************************************************
*The routine Initial audio codec chip
*Input:void
*Output:void
***************************************************************/
void HW_Audio_Initial(void)
{
int i = 3;
int iy =0;
/*HardwareResetCodec();*/
/*for(iy =0;iy<1000;iy++);*/
Codec_Initial();
while(0x69 != readreg(0,1,1)) {
for(iy =0;iy<1000;iy++);
HardwareResetCodec();
for(iy =0;iy<1000;iy++);
Codec_Initial();
i --;
if (i == 0)
break;
}
if(i == 0)
printf("HW:codec Initial fail \n");
}
void Codec_Initial(void)
{
unsigned char tp1[] ={R1,0x69,0x20,0x01};/*r1 = 0x69 set micbase = 2.35v */
unsigned char tp2[] ={R3B,0x60};/*nothing is mute*/
unsigned char tp3[] ={R3C,0x85};
unsigned char tp4[] ={R3D,0xC0,0x08 };/*r4a=0x08,r4b=0x90 master clk =16.348Mhz m=16,n=8,p=1*/
unsigned char tp5[] ={R4,0x90,0x0e};/*R5a<--0x0e means ADC input PGA gain is 21db*/
unsigned char tp6[] ={R5B,0x40};/*R5B <---0x40 means DAC input PGA gain is 0db*/
unsigned char tp7[] ={R5C,0xbf};/*Both Analog sidetone gain and digital sidetone gain is mute*/
unsigned char tp8[] ={R5D,0xf0,0x00};/*R6A<--0x00 means nothing is connected to ADC channel*/
unsigned char tp9[] ={R6B,0x80};/*nothing is connected to DAC channel*/
#if 0
unsigned char tp8[] ={R5D,0xf0,0x04};/*R6A<--0x04 means MICI connected to ADC channel*/
unsigned char tp9[] ={R6B,0x88};/*Speaker is connected to DAC channel*/
#endif
int i=0,j=0;
unsigned char adr=codec2B;
SoftResetCodec(0);
SoftResetCodec(1);
for(j=0;j<8;j+=2)
{
I2CWrite(adr+j,tp1,4);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp2,2);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp3,2);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp4,3);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp5,3);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp6,2);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp7,2);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp8,3);
for(i=0;i<500;i++);
I2CWrite(adr+j,tp9,2);
for(i=0;i<500;i++);
}
}
/*************************************************************
*The routine set mute device
*Input:Codec_Sel, dev_id
*Output:void
*
*
ref:Codec_Sel: 0 means CODEC 1, 1 means CODEC 2.
dev_id range 0~3.
0:Handset output driver.
1:Headset output driver.
2:Line driver output driver 600Ω(not use currently).
3:Speaker driver output.
***************************************************************/
/*Channel_sel 0:codec0 channel1
1:codec0 channel2
2:codec1 channel1
3:codec1 channel2
*/
void HW_Set_Mute(unsigned char Channel_sel,unsigned char dev_id)
{
unsigned char tp =0;
int i;
if(Channel_sel>3)return;
if(dev_id>3)return;
for(i=0;i<4;i++)
{
tp = readreg(Channel_sel,R3B,1);
if(((tp &0x80) ==0x00 )&& ((tp &0x40 )==0x40 ))
break;
}
switch(dev_id)
{
case 0:
tp= tp|0x08;
break;
case 1:
tp = tp|0x04;
break;
case 2:
tp = tp|0x02;
break;
case 3:
tp = tp|0x01;
break;
default:
}
#ifdef CODEC_DEBUG
printf("fun:hw_set_mute set reg R3B val=0x%x\n",tp);
#endif
Codec_Write_Reg(Channel_sel,R3B,tp);
}
/*************************************************************
*The routine open a device
*Input:Codec_Sel, dev_id
*Output:void
*
*
ref:Codec_Sel: 0 means CODEC 1, 1 means CODEC 2.
dev_id range 0~3.
0:Handset output driver.
1:Headset output driver.
2:Line driver output driver 600Ω(not use currently).
3:Speaker driver output.
***************************************************************/
void HW_NOT_Mute(unsigned char Channel_sel,unsigned char dev_id)
{
unsigned char tp = 0;
int i;
if(Channel_sel>3)return;
if(dev_id>3)return;
for(i=0;i<4;i++)
{
tp = readreg(Channel_sel,R3B,1);
if(((tp &0x80) ==0x00 )&& ((tp &0x40) ==0x40 ))
break;
}
switch(dev_id)
{
case 0:
tp = tp&0xF7;
break;
case 1:
tp = tp&0xFB;
break;
case 2:
tp = tp&0xFD;
break;
case 3:
tp = tp&0xFE;
break;
default:
}
#ifdef CODEC_DEBUG
printf("fun:HW_Eable_Play set reg R3B val=0x%x\n",tp);
#endif
Codec_Write_Reg(Channel_sel,R3B,tp);
}
/*************************************************************
*The routine get ADC gain
*Input:Codec_Sel. 0 means CODEC 1, 1 means CODEC 2.
*Output:Gain level (db) 0~54db; spe( 0xff:MUTE)
*
***************************************************************/
unsigned short HW_Get_ADC_Gain(unsigned char Channel_sel)
{
unsigned char tp = 0;
int i;
if(Channel_sel>3)return 0;
for(i=0;i<4;i++)
{
tp = readreg(Channel_sel,R5A,1);
if(((tp & 0x80) == 0x00 ) && ((tp & 0x40) == 0x00 ))
break;
}
#ifdef CODEC_DEBUG
printf("fun:HW_Get_ADC_Gain get reg R5A ori val=0x%x\n",tp);
#endif
if(tp == 0x1F) tp =0xff;
else if ( tp == 0x1e ) tp = 54;
else if (tp == 0x1d) tp = 48;
else tp = tp*1.5;
#ifdef CODEC_DEBUG
printf("fun:HW_Get_ADC_Gain gain=0x%d\n",tp);
#endif
return tp;
}
/*************************************************************
*The routine get DAC gain
*Input:Codec_Sel. 0 means CODEC 1, 1 means CODEC 2.
*Output:Gain level
*Output:Gain level (db) 0~54db; spe( 0xff:MUTE)
*
***************************************************************/
unsigned short HW_Get_DAC_Gain(unsigned char Channel_sel)
{
unsigned char tp = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -