最近做个项目痛fpga采集数据,通过数据总线传输给mini6410,采用中断方式正常工作,为了降低CPU使用率现在想改成DMA方式。但是一直不成功大家帮我分析一下问题。
部分驱动代码。
static void s3c64xx_fpga_dma_done(struct s3c2410_dma_chan *chan , void *id,
int size , enum s3c2410_dma_buffresult ret)
{
if(ret == S3C2410_RES_ERR)
PRINTK("strnsffer err!!!\n");
else if(ret ==S3C2410_RES_OK )
{
PRINTK("strnsffer OK!!!\n");
}
}
int fpga_6410_sram_init(void)
{
int result ;
struct fpga_sram *devp = NULL;
devp = kmalloc(sizeof(struct fpga_sram),GFP_KERNEL);
if(!devp)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(devp , 0 , (sizeof(struct fpga_sram)));
devp->src_addr = sram_phyaddr;//ncs4
devp->dma_ch = 27;
s3c_gpio_cfgpin(S3C64XX_GPB(0) , 0x00000003);
s3c_gpio_cfgpin(S3C64XX_GPB(1) , 0x00000030);
devp->dst_buf = (void *)dma_alloc_coherent(NULL , sram_size,&(devp->dst_addr), GFP_ATOMIC);
memset(devp->dst_buf , 0x00 , sram_size);
if(s3c2410_dma_request(devp->dma_ch ,&s3c6410_fpga_dma_client , NULL )<0)
{
PRINTK("cannot get DMA\n");
return 0;
}
result = s3c2410_dma_set_buffdone_fn(devp->dma_ch,s3c64xx_fpga_dma_done );
if(result != 0)
{
PRINTK("DMA set buffdone err \n");
}
result = s3c2410_dma_devconfig(devp->dma_ch, S3C2410_DMASRC_MEM, (unsigned long)devp->src_addr);
if(result != 0)
{
PRINTK("DMA devconfig err \n");
}
result = s3c2410_dma_config(devp->dma_ch, 1 );
if(result != 0)
{
PRINTK("DMA Config err \n");
}
if((result = s3c2410_dma_enqueue(devp->dma_ch, devp->dst_buf,devp->dst_addr, sram_size)))
{
PRINTK("DMA enqueue failed \n");
}
s3c2410_dma_ctrl(devp->dma_ch, S3C2410_DMAOP_START);
misc_register(&misc);
return 0;
正常调用完s3c2410_dma_ctrl函数之后GPB0如果有是高电平的话马上开始DMA传输。传输完就进入回调函数。事实上一点反应都没有。打印信息也都感觉没问题。很郁闷。下面是打印信息
[root@FriendlyARM /sdcard]# insmod 6410_fpga.ko
dma27: s3c2410_request_dma: client=fpga_dma, dev= (null)
DMA8: 00000000->00000000 L 00000000 C 00000000,00000000 S 00000000
s3c2410_dma_request: channel initialised, c075f6c8
s3c2410_dma_devconfig: channel 27, source 0, dev 30000000, chan c075f6c8
s3c2410_dma_devconfig: peripheral 11
s3c2410_dma_devconfig: config 0000d016
s3c2410_dma_enqueue: buff cccffd80, dp 5d529000 lli (ff182000, 5ce09000) 256
enquing onto empty channel
s3c64xx_lli_to_regs: LLI ff182000 => regs
LLI[ff182000] 30000000->5d529000, NL 00000000 C 99000000,00000100
LLI[ff182000] 30000000->5d529000, NL 00000000 C 99000000,00000100
DMA8: 30000000->5d529000 L 00000000 C 99000000,00000000 S 0000d016
DMA8: buffs next cccffd80, curr cccffd80, end cccffd80
DMA8: 30000000->5d529000 L 00000000 C 99000000,00000000 S 0000d016
s3c64xx_dma_start: clearing interrupts
s3c64xx_dma_start: starting channel
s3c64xx_dma_start: writing config 0000d017