一:DMA传输基本原理
二:举例
1)从SDRAM中读取数据,然后写入到我的模块,SDRAM地址是递增的,我的模块地址是不变的
void wr_cp_blk(int wr_num, char *array_tx) //wr_num要写数据块大小除以(ALT_DMA_SET_MODE_32/8),*array_tx要写数据
{ //譬如你要写16个字节,则wr_num=16/(ALT_DMA_SET_MODE_32/8)=4,在DMA设置的时候会*4
//注意下面设置的数必须为 (ALT_DMA_SET_MODE_32/8)整数倍,否则不会写数据
alt_dma_txchan tx_chan;
int tx_set;
int j=wr_num;
void *sdram_tx_addr=(void*)array_tx;
//此处地址为lzo_cp_0_base + offset*4,offset 为想写的偏移地址,譬如我要写的偏移地址为7的地方,则为+28
void *lzo_cp_rx_addr=(void*)(LZO_CP_0_BASE+28);
/*********************************************************
* sdram to lzo_cp,transfer
*********************************************************/
tx_chan=alt_dma_txchan_open("/dev/dma_0"); //打开DMA设备
if(tx_chan == NULL)
{
printf("can not open /dev/dma_0_tx \n ");
exit(1);
}
//设置要传输目的地地址lzo_cp_rx_addr,ALT_DMA_TX_ONLY_ON表示lzo_cp_rx_addr不自增
tx_set=alt_dma_txchan_ioctl(tx_chan,ALT_DMA_RX_ONLY_OFF,NULL);//先关闭ALT_DMA_RX_ONLY_OFF
tx_set=alt_dma_txchan_ioctl(tx_chan,ALT_DMA_TX_ONLY_ON,lzo_cp_rx_addr);
if(tx_set < 0)
{
printf("failed to set tx_ioctl \n ");
exit(1);
}
//设置每次传输32字节
tx_set=alt_dma_txchan_ioctl(tx_chan,ALT_DMA_SET_MODE_32,NULL);
if(tx_set < 0)
{
printf("failed to set tx_chan 32bits \n ");
exit(1);
}
//发送数据
tx_set=alt_dma_txchan_send(tx_chan,sdram_tx_addr,4*j,fun_tx_done,NULL);
if(tx_set < 0)
{
printf("failed to send data \n ");
exit(1);
}
//等待发送结束
/* while(!tx_done)
printf("send blk ok!! \n");*/
alt_dma_txchan_close(tx_chan);
}
2)从我的模块读数据到SDRAM,我的模块地址不变,SDRAM地址递增
void rd_cp_blk(int rd_num,char *array_rx)//rd_num要读数据块大小,*array_rx缓存数组
{ //对 (ALT_DMA_SET_MODE_32/8)取模,譬如你要读15个数,rd_num为4,在下面设置的时候会乘以4
//注意下面设置的数必须为 (ALT_DMA_SET_MODE_32/8)整数倍,否则不会读取数据
alt_dma_rxchan rx_chan;
int rx_set;
int j=rd_num;
void *sdram_rx_addr=(void*)array_rx;
void *lzo_cp_tx_addr=(void*)(LZO_CP_0_BASE+52);
/*********************************************************
* lzo to sdram,transfer
*********************************************************/
rx_chan=alt_dma_rxchan_open("/dev/dma_0"); //打开DMA设备
if(rx_chan == NULL)
{
printf("can not open /dev/dma_0_rx \n ");
exit(1);
}
//设置要发送的源地址lzo_cp_tx_addr,ALT_DMA_TX_ONLY_ON表示lzo_cp_tx_addr不自增
rx_set=alt_dma_rxchan_ioctl(rx_chan,ALT_DMA_TX_ONLY_OFF,NULL); //先关闭ALT_DMA_TX_ONLY_OFF
rx_set=alt_dma_rxchan_ioctl(rx_chan,ALT_DMA_RX_ONLY_ON,lzo_cp_tx_addr);
if(rx_set < 0)
{
printf("failed to set rx_ioctl \n ");
exit(1);
}
//设置每次传输32字节
rx_set=alt_dma_rxchan_ioctl(rx_chan,ALT_DMA_SET_MODE_32,NULL);
if(rx_set < 0)
{
printf("failed to set rx_chan 32bits \n ");
exit(1);
}
//接收数据
rx_set=alt_dma_rxchan_prepare(rx_chan,sdram_rx_addr,4*j,fun_rx_done,NULL);
if(rx_set < 0)
{
printf("failed to recieve data \n ");
exit(1);
}
//等待接收结束
/* while(!rx_done)
printf("recieve blk ok!! \n");*/
alt_dma_rxchan_close(rx_chan);
}
文章评论(0条评论)
登录后参与讨论