此程序只能是ac97发出BBBBB的声音。。。欢迎牛人提供宝贵意见
#include "myprintf.h"
#include "nand.h"
#define GPC0CON (*(volatile unsigned long *)0xE0200060)
#define VIC2VECTADDR19 (*(volatile unsigned long *)0xF220014C)
#define VIC2INTENCLEAR (*(volatile unsigned long *)0xE2200014)
#define AC_GLBCTRL (*(volatile unsigned long *)0xE2200000)
#define AC_CODEC_CMD (*(volatile unsigned long *)0xE2200008)
#define AC_GLBSTAT (*(volatile unsigned long *)0xE2200004)
#define VIC2INTENABLE (*(volatile unsigned long *)0xF2200010)
#define AC_PCMDATA (*(volatile unsigned long *)0xE2200018)
#define VIC2ADDR ( *(volatile unsigned long *)0xF2200F00)
#define VIC2INTSELECT (*(volatile unsigned long *)0xf2200010)
#define MUSIC_BUFF 0x32000000
static volatile unsigned long *p_music_data = (volatile unsigned long *)0x32000000;
/* 编解码芯片就绪 */
void mdelay(int i)
{
int j;
for(j=50000;j>0;j--)
for(;i>0;i--);
}
void codec_read_irq(void)
{
}
/* 输出缓冲区已经没有数据了 */
void pcm_out_underrun_irq(void)
{
static int cnt = 0;
int i;
/* 清中断 */
AC_GLBCTRL |= (1<<29);
for (i = 0; i < 16; i++)
{
AC_PCMDATA=p_music_data[cnt++];
}
if (cnt > 150000)
{
cnt = 0;
}
}
/* 输出缓冲区的数据量已经降到阈值了 */
void pcm_out_threshold_irq(void)
{
}
void ac97_controller_init(void)
{
/* 配置GPIO引脚用于ac97 */
GPC0CON &= ~(0xfffff);
GPC0CON |= (4<<0)|(4<<4)|(4<<8)|(4<<12)|(4<<16);
/* code reset */
AC_GLBCTRL |= (1<<0);
mdelay(1);
AC_GLBCTRL &= ~(1<<0);
/* warm reset */
AC_GLBCTRL |= (3<<1);
mdelay(1);
AC_GLBCTRL &= ~(1<<1);
mdelay(1);
ac97_int_init();
/* 设置AC97控制器 */
AC_GLBCTRL &= ~((3<<12) | (3<<10) | (3<<8));
AC_GLBCTRL |= ((1<<12) | (1<<10) | (1<<8));
mdelay(1);
AC_GLBCTRL |= (1<<3); /* Transfer data enable using AC-link */
/* read ac97 status */
AC_CODEC_CMD |= (1<<23);
if ( (AC_GLBSTAT & 3 ) == 3 )
my_printf("ac97 has been active ...\n");
else
my_printf("ac97 init failed ...\n");
}
void ac97_irq(void)
{
my_printf("ac97 irq:\n\r");
pcm_out_underrun_irq();
/* 清中断 */
VIC2ADDR=0;
}
void ac97_int_init(void)
{
VIC2VECTADDR19 = ac97_irq;
}
void ac97_int_enable(void)
{
//AC_GLBCTRL |= ((1<<22) | (1<<21) | (1<<18));
/* enable fifo empty interupt,
* at first, the fifo is empyt,
* so generate the interrupt, and then intr driver
*/
AC_GLBCTRL |= (1<<21);
VIC2INTENABLE |= (1<<19); /* 使能INT_AC97 */
VIC2INTSELECT&=~(1<<19);
}
void ac97_int_disable(void)
{
AC_GLBCTRL &= ~((1<<22) | (1<<21) | (1<<18));
VIC2ADDR=0;
VIC2INTENCLEAR |= (1<<19);
}
void ac97_write_cmd(unsigned char addr, unsigned short data)
{
AC_CODEC_CMD = (addr << 16) | data;
mdelay(1);
}
void wm9714_init(void)
{
// set volume, sample rate, mux, enable power output
my_printf("wm9714 init:\n\r");
// left right DAC VOL control
ac97_write_cmd(0x0c, 0);
ac97_write_cmd(0x5c, 0);
// enable variable rate audio control
ac97_write_cmd(0x2a, 1);
// set sample rate to 22050Hz
//ac97_write_cmd(0x2c, 0x5622);
ac97_write_cmd(0x2c, 0xBB80); /* 48K */
// output mux select and speaker source
ac97_write_cmd(0x1c,(1 << 12) | (1 << 9) | (1 << 7) | (1 << 5));
// set headphone volume
ac97_write_cmd(0x04, (0xf << 8) | (0xf));
// set speaker volume
ac97_write_cmd(0x02, (0x9 << 8) | (0x9));
ac97_write_cmd(0x6,0);
// enable power
ac97_write_cmd(0x26, 0);
ac97_write_cmd(0x3c, 0);
ac97_write_cmd(0x3e, 3 << 9);
// enable jake insert
ac97_write_cmd(0x24, (1 << 4));
}
void ac97_init()
{
ac97_controller_init();
wm9714_init();
}
void ac97_clear(void)
{
int i;
my_printf("ac97 clear data:");
for (i = 0; i < 150000; i++)
{
p_music_data[i] = 0;
}
}
void ac97_test(void)
{
unsigned char *buf = (unsigned char *)0x32000000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
unsigned char c;
ac97_init();
ac97_clear();
ac97_int_enable();
my_printf("press q to stop and exit\n\r");
}