⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic.c

📁 DSP芯片TMS320C5416实验程序
💻 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 + -