📄 aic.c
字号:
#include "regs54xx.h"
#include "dma54xx.h"
#define DMA
#undef DMA
#ifdef DMA
#pragma DATA_SECTION(DmaTx, ".dma_buf")
#pragma DATA_SECTION(DmaRx, ".dma_buf")
static int flag = 0;
int DmaRx[128];
int DmaTx[128];
#endif
#define SPSA_ADDR0 *(volatile unsigned int *)0x0038
#define SPSD_ADDR0 *(volatile unsigned int *)0x0039
#define SPSA_ADDR1 *(volatile unsigned int *)0x0048
#define SPSD_ADDR1 *(volatile unsigned int *)0x0049
#define SPSA_ADDR2 *(volatile unsigned int *)0x0034
#define SPSD_ADDR2 *(volatile unsigned int *)0x0035
#define SPCR10_VAL 0x0000
#define SPCR20_VAL 0x0200
#define RCR10_VAL 0x00a0
#define RCR20_VAL 0x0004
#define XCR10_VAL 0x00a0
#define XCR20_VAL 0x0004
#define PCR0_VAL 0x000f
/*TLV320AIC23 */
#define L_LINE_VOLUME 0x0000
#define R_LINE_VOLUME 0x0001
#define L_HEADPHONE_VOLUME 0x0002
#define R_HEADPHONE_VOLUME 0x0003
#define A_AUDIO_PATH 0x0004
#define D_AUDIO_PATH 0x0005
#define POWER_CON 0x0006
#define D_AUDIO_INTERFACE 0x0007
#define SAMPLE_RATE 0x0008
#define D_INTERFACE_ACT 0x0009
#define RESET 0x000f
void write_subreg1(unsigned int addr,unsigned int val);
void write_subreg2(unsigned int addr,unsigned int val);
void write_subreg0(unsigned int addr,unsigned int val);
unsigned int read_subreg0(unsigned int addr);
void delay(int k);
void delay(int k)
{
while(k--);
}
unsigned int read_subreg0(unsigned int addr)
{
SPSA_ADDR0 = addr;
return SPSD_ADDR0 ;
}
unsigned int read_subreg1(unsigned int addr)
{
SPSA_ADDR1 = addr;
return SPSD_ADDR1;
}
unsigned int read_subreg2(unsigned int addr)
{
SPSA_ADDR2 = addr;
return SPSD_ADDR2;
}
void write_subreg0(unsigned int addr,unsigned int val)
{
SPSA_ADDR0 = addr;
SPSD_ADDR0 = val;
}
void write_subreg1(unsigned int addr,unsigned int val)
{
SPSA_ADDR1 = addr;
SPSD_ADDR1 = val;
}
void write_subreg2(unsigned int addr,unsigned int val)
{
SPSA_ADDR2 = addr;
SPSD_ADDR2 = val;
}
void McBsp0_init()
{
write_subreg0(SPCR1_SUBADDR, 0);
write_subreg0(SPCR2_SUBADDR, 0);
write_subreg0(SPCR1_SUBADDR, SPCR10_VAL);
write_subreg0(SPCR2_SUBADDR, SPCR20_VAL);
write_subreg0(PCR_SUBADDR, PCR0_VAL);
write_subreg0(RCR1_SUBADDR, RCR10_VAL);
write_subreg0(RCR2_SUBADDR, RCR20_VAL);
write_subreg0(XCR1_SUBADDR, XCR10_VAL);
write_subreg0(XCR2_SUBADDR, XCR20_VAL);
write_subreg0(PCR_SUBADDR, PCR0_VAL);
delay(10);
DXR10 = 0;
DXR20 = 0;
/*now enable McBSP transmit and receive*/
write_subreg0(SPCR1_SUBADDR,SPCR10_VAL|1);
write_subreg0(SPCR2_SUBADDR,SPCR20_VAL|1);
delay(10);
IMR |= 0x0010; //开接收0中断
}
/****************************************************************************
* 使用MCBSP口模拟SPI总线操作-片选信号产生
****************************************************************************/
void CS(unsigned char x)
{
SPSA_ADDR2 = PCR_SUBADDR;
if(x) SPSD_ADDR2 = SPSD_ADDR2 | 0x0008;
else SPSD_ADDR2 = SPSD_ADDR2 & 0xfff7;
}
/****************************************************************************
* 使用MCBSP口模拟SPI总线操作-串行输出一位数据
****************************************************************************/
void SDIN(unsigned char x)
{
SPSA_ADDR2 = PCR_SUBADDR;
if(x) SPSD_ADDR2 = SPSD_ADDR2 | 0x0020;
else SPSD_ADDR2 = SPSD_ADDR2 & 0xffdf;
}
/****************************************************************************
* 使用MCBSP口模拟SPI总线操作-串行时钟产生
****************************************************************************/
void SCLK(unsigned char x)
{
SPSA_ADDR2 = PCR_SUBADDR;
if(x) SPSD_ADDR2 = SPSD_ADDR2 | 0x0002;
else SPSD_ADDR2 = SPSD_ADDR2 & 0xfffd;
}
/****************************************************************************
* 使用SPI总线向AIC23写控制字
****************************************************************************/
write_AIC23(unsigned char addr,unsigned int dat)
{
unsigned char i;
dat|=addr<<9;
CS(0); /* 选中设备 */
for(i=0;i<16;i++)
{
SCLK(0); /* 将CLK置低 */
if((dat<<i)&0x8000)
SDIN(1); /* 输出数据1*/
else
SDIN(0); /* 输出数据0*/
SCLK(1); /* 将CLK置高,产生一个完整的脉冲 */
}
SCLK(0); /* 将CLK置低 */
CS(1); /* 去除设备选中信号 */
}
void AIC_init()
{
/* Reset McBsp1 */
write_subreg2(SPCR1_SUBADDR, 0);
write_subreg2(SPCR2_SUBADDR, 0);
write_subreg2(PCR_SUBADDR, 0x3a00);
/* 复位AIC23B */
write_AIC23(RESET,0);
/*
Power Down Control (Address: 0000110)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function X OFF CLK OSC OUT DAC ADC MIC LINE
Default 0 0 0 0 0 0 1 1 1
OFF Device power 0 = On 1 = Off
CLK Clock 0 = On 1 = Off
OSC Oscillator 0 = On 1 = Off
OUT Outputs 0 = On 1 = Off
DAC DAC 0 = On 1 = Off
ADC ADC 0 = On 1 = Off
MIC Microphone input 0 = On 1 = Off
LINE Line input 0 = On 1 = Off */
/* 打开/使能除线路输入外的所有部件 */
write_AIC23(POWER_CON,0x001);
/* 使用线路输入时打开线路输入信号 */
//write_AIC23(POWER_CON,0x000);
/*
Left line input channel volume control (Address: 0000000)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function LRS LIM X X LIV4 LIV3 LIV2 LIV1 LIV0
Default 0 1 0 0 1 0 1 1 1
LRS Left/right line simultaneous volume/mute update
Simultaneous update 0 = Disabled 1 = Enabled
LIM Left line input mute 0 = Normal 1 = Muted
LIV[4:0] Left line input volume control (10111 = 0 dB default)
11111 = +12 dB down to 00000 = -34.5 dB in 1.5-dB step */
/* 关闭线路输入信号,并同步更新线路输入(右)设置 */
write_AIC23(L_LINE_VOLUME,0x0180);
/* 使用线路输入时,设置线路输入增益 */
//write_AIC23(L_LINE_VOLUME,0x0110);
/*
Left Channel Headphone Volume Control (Address: 0000010)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function LRS LZC LHV6 LHV5 LHV4 LHV3 LHV2 LHV1 LHV0
Default 0 1 1 1 1 1 0 0 1
LRS Left/right headphone channel simultaneous volume/mute update
Simultaneous update 0 = Disabled 1 = Enabled
LZC Left-channel zero-cross detect
Zero-cross detect 0 = Off 1 = On
LHV[6:0] Left Headphone volume control (1111001 = 0 dB default)
1111111 = +6 dB, 79 steps between +6 dB and -73 dB (mute),
0110000 = -73 dB (mute),any thing below 0110000 does nothing .
you are still muted*/
/* 设置话筒输出为最大音量+6 DB, 同步更新右声道*/
write_AIC23(L_HEADPHONE_VOLUME,0x017f);
/*
Analog Audio Path Control (Address: 0000100)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function STA2 STA1 STA0 STE DAC BYP INSEL MICM MICB
Default 0 0 0 0 0 1 0 1 0
STA[2:0] and STE
STE STA2 STA1 STA0 ADDED SIDETONE
1 1 X X 0 dB
1 0 0 0 -6 dB
1 0 0 1 -9 dB
1 0 1 0 -12 dB
1 0 1 1 -18 dB
0 X X X Disabled
DAC DAC select 0 = DAC off 1 = DAC selected
BYP Bypass 0 = Disabled 1 = Enabled
INSEL Input select for ADC 0 = Line 1 = Microphone
MICM Microphone mute 0 = Normal 1 = Muted
MICB Microphone boost 0=dB 1 = 20dB
*/
/* 选择话筒输入,使能DAC,关闭侧音 */
write_AIC23(A_AUDIO_PATH,0x0015);
/* 使用线路输入时,关闭麦克风信号 */
//write_AIC23(A_AUDIO_PATH,0x0010);
/*
Digital Audio Path Control (Address: 0000101)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function X X X X X DACM DEEMP1 DEEMP0 ADCHP
Default 0 0 0 0 0 1 0 0 0
DACM DAC soft mute 0 = Disabled 1 = Enabled
DEEMP[1:0] De-emphasis control
00 = Disabled 01 = 32 kHz
10 = 44.1 kHz 11 = 48 kHz
ADCHP ADC high-pass filter 1 = Disabled 0 = Enabled
X Reserved*/
write_AIC23(D_AUDIO_PATH,0x0006);
/*
Digital Audio Interface Format (Address: 0000111)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function X X MS LRSWAP LRP IWL1 IWL0 FOR1 FOR0
Default 0 0 0 0 0 0 0 0 ve 1 = Master
LRSWAP DAC left/right swap 0 = Disabled 1 = Enabled
LRP DAC left/right phase 0 = Right channel on, LRCIN high
1 = Right channel on, LRCIN low
DSP mode
1 = MSB is available on 2nd BCLK rising edge after LRCIN rising edge
0 = MSB is available on 1st BCLK rising edge after LRCIN rising edge
IWL[1:0] Input bit length 00 = 16 bit 01 = 20 bit
10 = 24 bit 11 = 32 bit
FOR[1:0] Data format 11 = DSP format, frame sync followed by two data words
10 = I2S format, MSB first, left - 1 aligned
01 = MSB first, left aligned
00 = MSB first, right aligned
X Reserved */
/* 0x43 导致一个声道有噪音, 将其设置为0x53后正常(5416*20M/50M) */
write_AIC23(D_AUDIO_INTERFACE,0x0053);
/*
Sample Rate Control (Address: 0001000)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function X CLKOUT CLKIN SR3 SR2 SR1 SR0 BOSR USB/Normal
Default 0 0 0 1 0 0 0 0 0
CLKIN Clock input divider 0 = MCLK 1 = MCLK/2
CLKOUT Clock output divider 0 = MCLK 1 = MCLK/2
SR[3:0] Sampling rate control
BOSR Base oversampling rate
USB mode: 0 = 250 fs 1 = 272 fs
Normal mode: 0 = 256 fs 1 = 384 fs
USB/Normal Clock mode select: 0 = Normal 1 = USB */
write_AIC23(SAMPLE_RATE,0x01d); //96k 0x01e, USB MODE(12MHZ)
//write_AIC23(SAMPLE_RATE,0x001); //48k 0x001, USB MODE(12MHZ)
/*
Digital Interface Activation (Address: 0001001)
BIT D8 D7 D6 D5 D4 D3 D2 D1 D0
Function X RES RES X X X X X ACT
Default 0 0 0 0 0 0 0 0 0
ACT Activate interface 0 = Inactive 1 = Active
X Reserved*/
write_AIC23(D_INTERFACE_ACT, 0x0001);
}
#ifdef DMA
interrupt void dma_rx_int()
{
int size;
int *src, *dst;
flag++;
if(flag&1)
{
src = DmaRx;
dst = DmaTx+0x40;
}
else
{
src = DmaRx+0x40;
dst = DmaTx;
}
for( size = 0; size < 64; size++)
{
*dst++= *src++;
}
return;
}
interrupt void dma_tx_int()
{
return;
}
void Dma0Init()
{
dma_reset(0);
dma_reset(1);
/* receive */
DMA_SUBREG_WRITE(0, DMSRC_SUBADDR, DRR20_ADDR); /* DMSRC0 = DRR10_ADDR */
REG_WRITE(DMSAI_ADDR, (int)DmaRx); /* 目的地址 */
REG_WRITE(DMSAI_ADDR, 0x800-1); /* 单元计数寄存器 */
REG_WRITE(DMSAI_ADDR, 0x1800); /* 同步事件和帧计数寄存器 */
REG_WRITE(DMSAI_ADDR, 0x7045); /* 传输模式寄存器 */
/* send */
DMA_SUBREG_WRITE(1, DMSRC_SUBADDR, (int)DmaRx); /* DMSRC0 = DRR10_ADDR */
REG_WRITE(DMSAI_ADDR, DXR20_ADDR); /* 目的地址 */
REG_WRITE(DMSAI_ADDR, 0x800-1); /* 单元计数寄存器 */
REG_WRITE(DMSAI_ADDR, 0x2800); /* 同步事件和帧计数寄存器 */
REG_WRITE(DMSAI_ADDR, 0x7141); /* 传输模式寄存器 */
REG_WRITE(DMPRE_ADDR, 0x0183); /* DMA0 -> int6, DMA1 -> int7 */
}
#endif
interrupt void codec_ch0_in() //接收0中断
{
unsigned int temp1;
unsigned int temp2;
unsigned int state;
state=read_subreg0(SPCR1_SUBADDR);
if((state & 2 )!=0)
{
temp2=DRR20;
temp1=DRR10;
state=read_subreg0(SPCR2_SUBADDR);
if((state & 2 ))
{
DXR20=temp2;
DXR10=temp1;
}
}
else
{
return;
}
}
void OpenAudio()
{
AIC_init();
delay(20000);
McBsp0_init();
delay(20000);
#ifdef DMA
Dma0Init();
IMR &= ~0x0010;
IMR |= 0x00c0;
#else
IMR |= 0x0010;
IMR &= ~0x00c0;
#endif
}
void CloseAudio()
{
#ifdef DMA
dma_reset(0);
dma_reset(1);
IMR &= ~0x00C0;
#else
IMR &= ~0x0010;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -