?? seeddm642aic23b.c
字號:
/********************************************************************/
/* Copyright 2004 by SEED Incorporated. */
/* All rights reserved. Property of SEED Incorporated. */
/* Restricted rights to use, duplicate or disclose this code are */
/* granted through contract. */
/* */
/********************************************************************/
#include <csl_i2c.h>
#include <csl_gpio.h>
#include <std.h>
#include <seeddm642_aic23.h>
/* Compatability definitions */
#define NULL 0
static I2C_Config aic23XmtCfg = {
0x0000007f, /* I2COAR - Not used if master */
0x00000000, /* I2CIER - Disable interrupts, use polling */
0x0000001b, /* I2CCLKL - Low period for 100KHz operation */
0x0000001b, /* I2CCLKH - High period for 100KHz operation */
0x00000002, /* I2CCNT - Data words per transmission */
0x0000001a, /* I2CSAR - Slave address */
0x00004ea0, /* I2CMDR - Mode */
0x00000019 /* I2CPSC - Prescale 300MHz to 12MHz */
};
/* Table of supported frequencies,CLKIN,SR3..SR0,BOSR */
Uint16 freqtable[] =
{
SEEDDM642_AIC23_FREQ_8KHZ, 0x0e, // 8000 Hz
SEEDDM642_AIC23_FREQ_16KHZ, 0x5a, // 16000 Hz
SEEDDM642_AIC23_FREQ_24KHZ, 0x22, // 24000 Hz
SEEDDM642_AIC23_FREQ_32KHZ, 0x1a, // 32000 Hz
SEEDDM642_AIC23_FREQ_48KHZ, 0x02, // 48000 Hz
SEEDDM642_AIC23_FREQ_96KHZ, 0x1e, // 96000 Hz
0, 0 // End of table
};
extern SEEDDM642_AIC23_Config codecstate;
/* Spin in a delay loop for delay iterations */
void SEEDDM642_wait(Uint32 delay)
{
volatile Uint32 i, n;
n = 0;
for (i = 0; i < delay; i++)
{
n = n + 1;
}
}
/* Spin in a delay loop for delay microseconds */
void SEEDDM642_waitusec(Uint32 delay)
{
SEEDDM642_wait(delay * 21);
}
/***************************************************************************************/
/* ======== SEEDDM642_AIC23_rset ======== */
/* Set codec register regnum to value regval */
/***************************************************************************************/
void SEEDDM642_AIC23_rset(I2C_Handle hI2c,
Uint16 I2Caddress,
Uint16 regnum,
Uint16 regval)
{
Uint16 data;
I2C_Config prevI2CCfg;
/* Mask off lower 9 bits */
regval &= 0x1ff;
/* Set transmit data */
data = (regnum << 9) | regval;
/* Wait until bus is free */
while (I2C_bb(hI2c));
/* Save old settings */
I2C_getConfig(hI2c, &prevI2CCfg);
/*設(shè)置要訪問的AIC23b的IIc的地址*/
aic23XmtCfg.i2csar = I2Caddress;
/* Restore settings for AIC23 */
I2C_config(hI2c, &aic23XmtCfg);
/* Submit the MSB for transmit */
I2C_RSETH(hI2c, I2CDXR, (data >> 8) & 0xff);
/* Generate start condition, starts transmission */
I2C_start(hI2c);
/* Wait until MSB transmit is done */
while(!I2C_xrdy(hI2c));
/* Submit the LSB for transmit */
I2C_writeByte(hI2c, data & 0xff);
/* Generate stop condition */
I2C_sendStop(hI2c);
/* Wait until bus is free */
while (I2C_bb(hI2c));
/* Save register value if regnum is in range */
if (regnum < SEEDDM642_AIC23_NUMREGS)
codecstate.regs[regnum] = regval;
/* Short delay for AIC23 to accept command */
SEEDDM642_waitusec(20);
/* Reconfigure I2C with old settings */
I2C_config(hI2c, &prevI2CCfg);
}
/**********************************************************************/
/* ======== EVMDM642_AIC23_config ======== */
/* Set the default codec register config values */
/**********************************************************************/
SEEDDM642_AIC23_Handle EVMDM642_AIC23_open( I2C_Handle hI2c,
Uint16 aic23num,
SEEDDM642_AIC23_Config *Config)
{
int i;
Uint8 I2Caddress;
/*配置IIC總線*/
GPIO_RSET(GPGC,0x0);/*將GPIO0不做為GPINT使用*/
GPIO_RSET(GPDIR,0x1);/*將GPIO0做為輸出*/
switch(aic23num)
{
case 0:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 1:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 2:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
case 3:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
default:
I2Caddress = 0x0;
break;
}
if(I2Caddress == 0x0)
{
return ((SEEDDM642_AIC23_Handle)aic23num);
}
/*延時等待開關(guān)動作完成*/
SEEDDM642_wait(2);
/* Use default parameters if none are given */
if (Config == NULL)
{
Config = &codecstate;
}
/* Reset the codec ,對AIC23進(jìn)行復(fù)位*/
SEEDDM642_AIC23_rset(hI2c,I2Caddress,15, 0);
/* Assign each register */
for (i = 0; i < SEEDDM642_AIC23_NUMREGS; i++)
{
/*Power寄存器最后設(shè)置*/
if (i != 6)
{
SEEDDM642_AIC23_rset(hI2c, I2Caddress ,i, Config -> regs[i]);
}
}
SEEDDM642_AIC23_rset(hI2c, I2Caddress ,6, Config -> regs[6]);
return ((SEEDDM642_AIC23_Handle)aic23num);
}
/*********************************************************************************/
/* ======== EVMDM642_AIC23_powerDown ======== */
/* Enable/disable powerdown modes for the DAC and ADC codec subsections */
/*********************************************************************************/
Bool SEEDDM642_AIC23_powerDown(SEEDDM642_AIC23_Handle hAic23,
I2C_Handle hI2c,
Uint16 sect)
{
Uint8 I2Caddress;
switch((int)hAic23)
{
case 0:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 1:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 2:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
case 3:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
default:
I2Caddress = 0x0;
break;
}
if(I2Caddress == 0x0)
{
return FALSE;
}
/*延時等待開關(guān)動作完成*/
SEEDDM642_wait(2);
/* Write to codec register */
SEEDDM642_AIC23_rset(hI2c, I2Caddress,SEEDDM642_AIC23_POWERDOWN,(sect & 0xff));
return TRUE;
}
/*
* ======== EVMDM642_AIC23_outGain ========
* Set the output gain on the codec
*/
Bool SEEDDM642_AIC23_outGain(SEEDDM642_AIC23_Handle hAic23,
I2C_Handle hI2c,
Uint16 outGain)
{
Uint8 I2Caddress;
switch((int)hAic23)
{
case 0:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 1:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 2:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
case 3:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
default:
I2Caddress = 0x0;
break;
}
if(I2Caddress == 0x0)
{
return FALSE;
}
/*延時等待開關(guān)動作完成*/
SEEDDM642_wait(2);
/* Write to codec registers (left and right) */
SEEDDM642_AIC23_rset(hI2c, I2Caddress,SEEDDM642_AIC23_LEFTHPVOL,(outGain & 0x7f));
SEEDDM642_AIC23_rset(hI2c, I2Caddress,SEEDDM642_AIC23_RIGHTHPVOL, (outGain & 0x7f));
return TRUE;
}
/*
* ======== EVMDM642_AIC23_mute ========
* Enable/disable codec mute mode
*/
Bool SEEDDM642_AIC23_mute(SEEDDM642_AIC23_Handle hAic23,
I2C_Handle hI2c,
Int16 mode)
{
int regval;
Uint8 I2Caddress;
switch((int)hAic23)
{
case 0:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 1:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 2:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
case 3:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
default:
I2Caddress = 0x0;
break;
}
if(I2Caddress == 0x0)
{
return FALSE;
}
/*延時等待開關(guān)動作完成*/
SEEDDM642_wait(2);
/* Enable mute if mode is true */
regval = (mode) ? 0x08 : 0x00;
/* Write to codec registers (left and right) */
SEEDDM642_AIC23_rset(hI2c,I2Caddress, SEEDDM642_AIC23_DIGPATH,regval);
return TRUE;
}
/*
* ======== EVMDM642_AIC23_setFreq ========
* Set the codec sample rate frequency
*/
Bool SEEDDM642_AIC23_setFreq(SEEDDM642_AIC23_Handle hAic23,
I2C_Handle hI2c,
Uint32 freq)
{
Uint16 regval, curr;
Uint8 I2Caddress;
switch((int)hAic23)
{
case 0:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 1:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x0);/*GPIO0輸出為低,選擇IIC0總線*/
break;
case 2:
I2Caddress = 0x1a;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
case 3:
I2Caddress = 0x1b;
GPIO_RSET(GPVAL,0x1);/*GPIO0輸出為低,選擇IIC1總線*/
break;
default:
I2Caddress = 0x0;
break;
}
if(I2Caddress == 0x0)
{
return FALSE;
}
/*延時等待開關(guān)動作完成*/
SEEDDM642_wait(2);
/* Calculate codec clock control setting, assume Nomal Mode (18.432MHz) */
/* regval will contain CLKIN,SR3..SR0,BOSR */
curr = 0;
while(1)
{
/* Do nothing if frequency doesn't match */
if (freqtable[curr] == 0)
return;
/* Check for match */
if (freqtable[curr] == freq)
{
regval = freqtable[curr + 1];
break;
}
/* Set up for next pair */
curr += 2;
}
/* Write to codec register */
SEEDDM642_AIC23_rset(hI2c, I2Caddress,SEEDDM642_AIC23_SAMPLERATE,(regval & 0x7f));
return TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -