首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

s3c2440的DMA应用(2)

s3c2440的DMA应用(2)

……
……
//一段纯音频数据数组
unsigned char music[] = {
0xF9, 0xFF, 0xF5, 0xFF, 0xF8, 0xFF, 0xF8, 0xFF, 0xF6, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xF9, 0xFF,
0xF6, 0xFF, 0xF6, 0xFF, 0xFA, 0xFF, 0xFD, 0xFF, 0xFA, 0xFF, 0xFA, 0xFF, 0xF7, 0xFF, 0xF6, 0xFF,
……
……
}


int result;
int remainder;
char flag;
char cmd;
char play_state;


void __irq uartISR(void)
{

char ch;


rSUBSRCPND |= 0x1;


rSRCPND |= 0x1<<28;


rINTPND |= 0x1<<28;


ch=rURXH0;




switch(ch)


{


case 0x55:

//
播放

cmd = 1;


break;


case 0x1:

//
静音

cmd = 0x11;


break;


case 0x2:

//
音量提高

cmd = 0x12;


break;


case 0x3:

//
音量降低

cmd = 0x13;


break;


case 0x66:

//
停止

cmd = 0x2;


break;


case 0x77:

//
暂停

cmd = 0x3;


break;


}


rUTXH0=ch;

}


//放音子程序
void playsound(unsigned char *buffer,int length)
{


//
用于计算音频数据的长度是否超过DMA所能传输的字节数范围

//
这里音频数据的通道位数为16位,因此需要length除以2

remainder = (length>>1) & 0xfffff;
//
余数

result = (length>>1) / 0x100000;
//




play_state = 1;
//
置播放标志



rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C);




//
配置1341,详细讲解请看上一篇文章

WriteL3(0x14 + 2,1);


WriteL3(0x60,0);




WriteL3(0x14 + 2,1);


WriteL3(0x10,0);




WriteL3(0x14 + 2,1);


WriteL3(0xc1,0);




//
配置IIS

rIISPSR
= 3<<5|3;


rIISCON
= (1<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);
//
发送IISDMA使能

rIISMOD
= (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);


rIISFCON = (1<<15)|(1<<13); //
发送FIFODMA



//
配置DMA

rDISRC2 = (U32)buffer;
//DMA
的源基址为音频数据数组的首地址

rDISRCC2 = (0<<1)|(0<<0);
//AHB
,源地址递增

rDIDST2 = (U32)IISFIFO;
//DMA
的目的基址为IISFIFO

rDIDSTC2 = (0<<2)| (1<<1)|(1<<0);

//
当传输计数值为0时中断,APB,目的地址不变

if (result == 0)
//
所传输的字节数没有超出DMA的最大传输范围

{


flag = 0;

//
清标志,表示没有超出范围,进入DMA中断后结束DMA操作

//
握手模式,PCLK同步,传输计数中断,单元传输,单步服务模式,IISSDO

//
硬件请求模式,非自动重载,半字,

rDCON2 = (1<<31) | (0<<30) | (1<<29) | (0<<28) | (0<<27) | (0<<24) | (1<<23) | (1<<22) | (1<<20) | (remainder);




}


else
//
所传输的字节数超出了DMA的最大传输范围

{


flag = 1;
//
置标志,表示超出范围

rDCON2 = (1<<31) | (0<<30) | (1<<29) | (0<<28) | (0<<27) | (0<<24) | (1<<23) | (1<<22) | (1<<20) | (0xfffff);


}


rDMASKTRIG2=(0<<2)|(1<<1)|0;
//
不停止DMADMA通道开启,非软件触发




//
启动IIS


rIISCON |= 0x1;

}




void __irq DMA_end(void)
{

rSRCPND |= 0x1<<19;


rINTPND |= 0x1<<19;




if (flag == 0)
//DMA
传输完毕

{


rIISCON = 0x0;
//
关闭IIS
rIISFCON = 0x0;
//
IISFIFO

rDMASKTRIG2=1<<2;
//
停止DMA


play_state = 0;
//
清播放标志
}
else
//DMA
没有传输完毕,继续传输
{

result --;
//
商递减

rDISRC2 += 0x200000;
//DMA
源基址递增。因为传输的数据是半字,所以这里递增0x200000

if (result == 0 )
//
只剩下余数部分需要传输


{


rDCON2=(rDCON2&(~0xfffff))|(remainder);
//
需要重新设置传输计数值


flag=0;
//
清标志

}



rDMASKTRIG2=(0<<2)|(1<<1)|0;
//
需要重新设置DMA通道的开启
}
}
继承事业,薪火相传
返回列表