📄 cncodec.c
字号:
read the value of indirect register
*************************************/
UINT16 ReadInDrProSLIC(UINT8 codec_cs,UINT8 addr)
{
addr=possibleAddressCorrect(codec_cs,addr);
if(addr == 0xff)
{
return 0; // Don't attempt to write an invalid si3215 address
}
while (ReadDrProSLIC(codec_cs,I_STATUS))
{
;
}
WriteDrProSLIC(codec_cs,IAA,addr);
while (ReadDrProSLIC(codec_cs,I_STATUS))
{
;
}
return ( (UINT16)ReadDrProSLIC(codec_cs,IDA_LO) | (UINT16)(ReadDrProSLIC (codec_cs,IDA_HI))<<8);
}
int Si3215orSi3216(UINT8 codec_cs)
{
static int slicPreviouslyIdentified = 0;
static int isSi3215 = 0;
if(!slicPreviouslyIdentified)
{
isSi3215 = ((ReadDrProSLIC(codec_cs,1) & 0x80) == 0x80);
slicPreviouslyIdentified = 1;
}
return (isSi3215);
}
/******************************************
UINT8 possibleAddressCorrect(UINT8 address)
******************************************/
UINT8 possibleAddressCorrect(UINT8 codec_cs,UINT8 address)
{
if (!Si3215orSi3216(codec_cs))
return (address);
if ((address > 12) && (address < 41))
return (address - 13);
if ((address == 41) || (address == 43))
return (address + 23);
if ((address > 98) && (address < 105))
return (address - 30);
return 0xFF;
}
/*******************************************************
int verifyIndirectReg(UINT8 addr, UINT16 should_be_value)
*******************************************************/
int verifyIndirectReg(UINT8 codec_cs,UINT8 addr, UINT16 should_be_value)
{
int error_flag ;
UINT16 value;
UINT8 new_address;
new_address=possibleAddressCorrect(codec_cs,addr);
if(new_address == 0xff)
{
return 0; // invalid si3215 address
}
value = ReadInDrProSLIC(codec_cs,addr);
error_flag = (should_be_value != value);
#if CODEC_DEBUG
if ( error_flag )
{
printk("\n iREG %d = %X should be %X ",addr,value,should_be_value );
}
#endif
return error_flag;
}
/********************************************
int verifyIndirectRegisters(UINT8 familycodec)
********************************************/
int verifyIndirectRegisters(UINT8 codec_cs,UINT8 familycodec)
{
int error=0;
if (familycodec==0)
{
error |= verifyIndirectReg(codec_cs, 0 , INIT_IR0 ); // 0x55C2 DTMF_ROW_0_PEAK
error |= verifyIndirectReg(codec_cs, 1 , INIT_IR1 ); // 0x51E6 DTMF_ROW_1_PEAK
error |= verifyIndirectReg(codec_cs, 2 , INIT_IR2 ); // 0x4B85 DTMF_ROW2_PEAK
error |= verifyIndirectReg(codec_cs, 3 , INIT_IR3 ); // 0x4937 DTMF_ROW3_PEAK
error |= verifyIndirectReg(codec_cs, 4 , INIT_IR4 ); // 0x3333 DTMF_COL1_PEAK
error |= verifyIndirectReg(codec_cs, 5 , INIT_IR5 ); // 0x0202 DTMF_FWD_TWIST
error |= verifyIndirectReg(codec_cs, 6 , INIT_IR6 ); // 0x0202 DTMF_RVS_TWIST
error |= verifyIndirectReg(codec_cs, 7 , INIT_IR7 ); // 0x0198 DTMF_ROW_RATIO
error |= verifyIndirectReg(codec_cs, 8 , INIT_IR8 ); // 0x0198 DTMF_COL_RATIO
error |= verifyIndirectReg(codec_cs, 9 , INIT_IR9 ); // 0x0611 DTMF_ROW_2ND_ARM
error |= verifyIndirectReg(codec_cs, 10 , INIT_IR10 ); // 0x0202 DTMF_COL_2ND_ARM
error |= verifyIndirectReg(codec_cs, 11 , INIT_IR11 ); // 0x00E5 DTMF_PWR_MIN_
error |= verifyIndirectReg(codec_cs, 12 , INIT_IR12 ); // 0x0A1C DTMF_OT_LIM_TRES
}
error |= verifyIndirectReg(codec_cs, 13 , INIT_IR13 ); // 0x7b30 OSC1_COEF
error |= verifyIndirectReg(codec_cs, 14 , INIT_IR14 ); // 0x0063 OSC1X
error |= verifyIndirectReg(codec_cs, 15 , INIT_IR15); // 0x0000 OSC1Y
error |= verifyIndirectReg(codec_cs, 16 , INIT_IR16); // 0x7870 OSC2_COEF
error |= verifyIndirectReg(codec_cs, 17 , INIT_IR17); // 0x007d OSC2X
error |= verifyIndirectReg(codec_cs, 18 , INIT_IR18); // 0x0000 OSC2Y
error |= verifyIndirectReg(codec_cs, 19 , INIT_IR19); // 0x0000 RING_V_OFF
error |= verifyIndirectReg(codec_cs, 20 , INIT_IR20); // 0x7EF0 RING_OSC
error |= verifyIndirectReg(codec_cs, 21 , INIT_IR21); // 0x0160 RING_X
error |= verifyIndirectReg(codec_cs, 22 , INIT_IR22); // 0x0000 RING_Y
error |= verifyIndirectReg(codec_cs, 23 , INIT_IR23); // 0x2000 PULSE_ENVEL
error |= verifyIndirectReg(codec_cs, 24 , INIT_IR24); // 0x2000 PULSE_X
error |= verifyIndirectReg(codec_cs, 25 , INIT_IR25); // 0x0000 PULSE_Y
error |= verifyIndirectReg(codec_cs, 26 , INIT_IR26); // 0x4000 RECV_DIGITAL_GAIN
error |= verifyIndirectReg(codec_cs, 27 , INIT_IR27); // 0x4000 XMIT_DIGITAL_GAIN
error |= verifyIndirectReg(codec_cs, 28 , INIT_IR28); // 0x1000 LOOP_CLOSE_TRES
error |= verifyIndirectReg(codec_cs, 29 , INIT_IR29); // 0x3600 RING_TRIP_TRES
error |= verifyIndirectReg(codec_cs, 30 , INIT_IR30); // 0x1000 COMMON_MIN_TRES
error |= verifyIndirectReg(codec_cs, 31 , INIT_IR31); // 0x0200 COMMON_MAX_TRES
error |= verifyIndirectReg(codec_cs, 32 , INIT_IR32); // 0x7c0 PWR_ALARM_Q1Q2
error |= verifyIndirectReg(codec_cs, 33 , INIT_IR33); // 0x2600 PWR_ALARM_Q3Q4
error |= verifyIndirectReg(codec_cs, 34 , INIT_IR34); // 0x1B80 PWR_ALARM_Q5Q6
error |= verifyIndirectReg(codec_cs, 35 , INIT_IR35); // 0x8000 LOOP_CLSRE_FlTER
error |= verifyIndirectReg(codec_cs, 36 , INIT_IR36); // 0x0320 RING_TRIP_FILTER
error |= verifyIndirectReg(codec_cs, 37 , INIT_IR37); // 0x08c TERM_LP_POLE_Q1Q2
error |= verifyIndirectReg(codec_cs, 38 , INIT_IR38); // 0x0100 TERM_LP_POLE_Q3Q4
error |= verifyIndirectReg(codec_cs, 39 , INIT_IR39); // 0x0010 TERM_LP_POLE_Q5Q6
error |= verifyIndirectReg(codec_cs, 40 , INIT_IR40); // 0x0C00 CM_BIAS_RINGING
error |= verifyIndirectReg(codec_cs, 41 , INIT_IR41); // 0x0C00 DCDC_MIN_V
error |= verifyIndirectReg(codec_cs, 43 , INIT_IR43); // 0x1000 LOOP_CLOSE_TRES Low
error |= verifyIndirectReg(codec_cs, 99 , INIT_IR99); // 0x00DA FSK 0 FREQ PARAM
error |= verifyIndirectReg(codec_cs, 100 , INIT_IR100); // 0x6B60 FSK 0 AMPL PARAM
error |= verifyIndirectReg(codec_cs, 101 , INIT_IR101); // 0x0074 FSK 1 FREQ PARAM
error |= verifyIndirectReg(codec_cs, 102 , INIT_IR102); // 0x79C0 FSK 1 AMPl PARAM
error |= verifyIndirectReg(codec_cs, 103 , INIT_IR103); // 0x1120 FSK 0to1 SCALER
error |= verifyIndirectReg(codec_cs, 104 , INIT_IR104); // 0x3BE0 FSK 1to0 SCALER
return error;
}
/*************************************
int calibrate(UINT8 codec_cs)
calibrate the ProSLIC
*************************************/
int calibrate(UINT8 codec_cs)
{
int x,y,i=0,progress=0; // progress contains individual bits for the Tip and Ring Calibrations
int DRvalue;
int timeOut,nCalComplete;
/* Do Flush durring powerUp and calibrate */
WriteDrProSLIC(codec_cs,21,DISABLE_ALL_DR21);//(0) Disable all interupts in DR21
WriteDrProSLIC(codec_cs,22,DISABLE_ALL_DR22);//(0) Disable all interupts in DR21
WriteDrProSLIC(codec_cs,23,DISABLE_ALL_DR23);//(0) Disabel all interupts in DR21
WriteDrProSLIC(codec_cs,64,OPEN_DR64);//(0)
for ( i=0; i<10; i++)
cpld_rw_sync(1);
WriteDrProSLIC(codec_cs,97,0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.
WriteDrProSLIC(codec_cs,96,0x47); //(0x47) Calibrate common mode and differential DAC mode DAC + ILIM
do
{
DRvalue = ReadDrProSLIC(codec_cs,96);
nCalComplete = DRvalue==CAL_COMPLETE_DR96;// (0) When Calibration completes DR 96 will be zero
timeOut= i++>MAX_CAL_PERIOD;
cpld_rw_sync(1);
}while (nCalComplete&&!timeOut);
if (timeOut)
{
CODEC_ASSERT(0);
return 0;
}
//Initialized DR 98 and 99 to get consistant results.
// 98 and 99 are the results registers and the search should have same intial conditions.
/*******************************The following is the manual gain mismatch calibration****************************/
/*******************************This is also available as a function *******************************************/
cpld_rw_sync(1);//add by chen long
cpld_rw_sync(1);
for ( i=0x1f; i>0; i--)
{
WriteDrProSLIC(codec_cs,98,i);
cpld_rw_sync(1);//add by chen long
cpld_rw_sync(1);
if((ReadDrProSLIC(codec_cs,88)) == 0)
{
progress|=1;
x=i;
break;
}
}
for ( i=0x1f; i>0; i--)
{
WriteDrProSLIC(codec_cs,99,i);
cpld_rw_sync(1);//add by chen long
cpld_rw_sync(1);
if((ReadDrProSLIC(codec_cs,89)) == 0)
{
progress|=2;
y=i;
break;
}
}
WriteDrProSLIC(codec_cs,64,1);
cpld_rw_sync(1);//add by chen long
if ((ReadDrProSLIC(codec_cs,68) & 0x3)& 4)
{
CODEC_ASSERT(0);
return 0;
}
WriteDrProSLIC(codec_cs,64,OPEN_DR64);
WriteDrProSLIC(codec_cs,23,ENB2_DR23); // enable interrupt for the balance Cal
WriteDrProSLIC(codec_cs,97,BIT_CALCM_DR97); // this is a singular calibration bit for longitudinal calibration
WriteDrProSLIC(codec_cs,96,0x40);
while(ReadDrProSLIC(codec_cs,96) != 0 )
{
;
}
WriteInDrProSLIC(codec_cs,75,0);
WriteInDrProSLIC(codec_cs,76,0);
WriteInDrProSLIC(codec_cs,77,0);
WriteInDrProSLIC(codec_cs,78,0);
WriteInDrProSLIC(codec_cs,79,0);
WriteInDrProSLIC(codec_cs,80,0);
WriteInDrProSLIC(codec_cs,81,0);
WriteInDrProSLIC(codec_cs,82,0);
WriteInDrProSLIC(codec_cs,84,0);
WriteInDrProSLIC(codec_cs,208,0);
WriteInDrProSLIC(codec_cs,209,0);
WriteInDrProSLIC(codec_cs,210,0);
WriteInDrProSLIC(codec_cs,211,0);
WriteDrProSLIC(codec_cs,98,0x10);
WriteDrProSLIC(codec_cs,99,0x10);
WriteDrProSLIC(codec_cs,21,INIT_DR21);
WriteDrProSLIC(codec_cs,22,INIT_DR22);
WriteDrProSLIC(codec_cs,23,INIT_DR23);
return(0);
}// End of calibration
/*************************************
UINT8 powerUp(UINT8 codec_cs)
Turn on the ProSLIC's DC-DC
converter and verify voltage
*************************************/
UINT8 powerUp(UINT8 codec_cs)
{
unsigned short vBat,t;
int i=0, initialTime;
if (ReadDrProSLIC (codec_cs,1) & 0x80)
{
t=(0x60&ReadDrProSLIC (codec_cs,6))>>5;
}
else
{
t=(0x30 & ReadDrProSLIC(codec_cs,0)) >> 4;
}
if (t == 3) // M version correction
{
WriteDrProSLIC(codec_cs,92,INIT_SI3210M_DR92);// M version
WriteDrProSLIC(codec_cs,93,INIT_SI3210M_DR93);// M version
}
else
{
WriteDrProSLIC(codec_cs,93, 0x19);
ReadDrProSLIC(codec_cs,93); //xiazj
WriteDrProSLIC(codec_cs,92, 0xff);/* set the period of the DC-DC converter to 1/64 kHz START OUT SLOW*/
ReadDrProSLIC(codec_cs,92); //xiazj
}
// initialTime= clock();
WriteDrProSLIC(codec_cs,14, 0); /* Engage the DC-DC converter */
ReadDrProSLIC(codec_cs,14); //xiaj
while ((vBat=ReadDrProSLIC(codec_cs,82)) < 0xa0)/*0xc0(72V)->0xa0(60V)*/
{
cpld_rw_sync(1);
cpld_rw_sync(1);
++i;
if (i > 200)
{
CODEC_ASSERT(0);
return 0;
}
}
//powerTime= clock() - initialTime;
//if (i>500)
// printk("\nPower Up took %i milliseconds.\n",powerTime);
if (ReadDrProSLIC (codec_cs,1) & 0x80)
{
t=(0x60&ReadDrProSLIC (codec_cs,6))>>5;
}
else
{
t=(0x30 & ReadDrProSLIC(codec_cs,0)) >> 4;
}
if (t== 3) // M version correction chipType()
{
WriteDrProSLIC(codec_cs,92,(UINT8)(0X80 +INIT_SI3210M_DR92));// M version
}
else
{
WriteDrProSLIC(codec_cs,93, 0x99); /* DC-DC Calibration */
}
while(0x80&ReadDrProSLIC(codec_cs,93))
{
; // Wait for DC-DC Calibration to complete
}
//follow an35 step 13 TO 15
WriteDrProSLIC(codec_cs,64,0);
WriteDrProSLIC(codec_cs,97,0x1e);
WriteDrProSLIC(codec_cs,64,0x47);
while(0x80&ReadDrProSLIC(codec_cs,96))
{
; // Wait for DC-DC Calibration to complete
}
return vBat;
}
/******************************************
unsigned short Read_cpld(void)
read data from codec spi via cpld
*******************************************/
unsigned short Read_cpld(void)
{
unsigned short i,data=0,data1;
unsigned short j=0,delay=1000;
CPLD_WRITE_DATA(CS_PROSLIC,0); /*set cs*/
for(j=0; j<delay;j++);
for(i=8;i>0;i--)
{
CPLD_WRITE_DATA(CLK_PROSLIC,0); /*set clk*/
for(j=0; j<delay;j++);
CPLD_READ_DATA(READ_PROSLIC,data1);
data1 = data1&0x01;
data |= data1<<(i-1);
for(j=0; j<delay;j++);
CPLD_WRITE_DATA(CLK_PROSLIC,1); /*set clk*/
for(j=0; j<delay;j++);
}
CPLD_WRITE_DATA(CS_PROSLIC,1); /*set cs*/
for(j=0; j<delay;j++);
return data;
}
/******************************************
void Write_cpld(unsigned short data)
write data to codec spi via cpld
*******************************************/
void Write_cpld(unsigned short data)
{
unsigned short i,data1;
unsigned short j=0,delay=1000;
CPLD_WRITE_DATA(CS_PROSLIC,0); /*set cs*/
for(j=0; j<delay;j++);
for(i=8;i>0;i--)
{
data1 = data >>(i-1);
data1 = data1 & 1;
CPLD_WRITE_DATA(WRITE_PROSLIC,data1); /*write bit*/
for(j=0; j<delay;j++);
CPLD_WRITE_DATA(CLK_PROSLIC,0); /*set clk*/
for(j=0; j<delay;j++);
CPLD_WRITE_DATA(CLK_PROSLIC,1); /*set clk*/
for(j=0; j<delay;j++);
}
CPLD_WRITE_DATA(CS_PROSLIC,1); /*set cs*/
for(j=0; j<delay;j++);
}
void ADSP_tone(UINT8 codec_cs,int tone_type)
{
UINT8 Timeon_low,Timeon_high,Timeoff_low,Timeoff_high,Control;
UINT16 Freq,Gain,Phase;
switch(tone_type)
{
case 0:
Timeon_low=0x40;
Timeon_high=0x1f;
Timeoff_low=0x0;
Timeoff_high=0x0;
Freq=0x7e00;
Gain=0x32;
Phase=0x0;
Control=0x3e;
break;
case 1:
Timeon_low=0x40;
Timeon_high=0x1f;
Timeoff_low=0x0;
Timeoff_high=0x7d;
Freq=0x7e00;
Gain=0x32;
Phase=0x0;
Control=0x3e;
break;
case 2:
Timeon_low=0x0;
Timeon_high=0xaf;
Timeoff_low=0x0;
Timeoff_high=0xaf;
Freq=0x7e00;
Gain=0x32;
Phase=0x0;
Control=0x3e;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -