--- Quote Start ---
originally posted by hippo@Oct 25 2006, 03:13 PM
in general, you should use level trigger interrupt, which should be more reliable for linux.
since the source of interrupts are inside the fpga, there is no need to use pio for edge trigger.
you should generate level trigger interrupt, and drive it directly to cpu.
then clear the interrupt request in your service routine.
<div align='right'><{post_snapback}> (index.php?act=findpost&pid=18903)
--- quote end ---
--- Quote End ---
Thank you for your reply.
We will start using level trigged interrupts, but this does not affect the DMA controller interrupts. I have created a module to test DMA transfer only, and I still get extra interrupts with status 0x00. See source code below. The invalid interrupt is trigged in addition to the correct interrupt.
How is this possible? Can this be a hardware related error?
#include <linux/interrupt.h># include <linux/i2o.h># include <asm/dma.h># include <asm/nios.h>
MODULE_LICENSE("GPL");
# define DEVICE_NAME "dmatest"# define FIFO_ADDRESS na_DSP_data_fifo_avalonS# define FIFO_COUNT 256
void *buffer;
dma_addr_t dma_handle;
struct device dev;
static void start_dma(void *dev_id)
{
/* Set DMA destination address */
nios2_set_dma_waddr(0, dma_handle);
/* Set DMA count */
set_dma_count(0, FIFO_COUNT);
// Start DMA transfer
enable_dma(0);
}
static DECLARE_WORK(start_dma_work, start_dma, (void*)&dev);
static int dmatest_handle_dma(void *dev_id, int stat)
{
if (stat & 0x01)
schedule_work(&start_dma_work);
else
printk(KERN_ERR "Invalid DMA status 0x%.2X\n",stat);
return IRQ_HANDLED;
}
static int __init dmatest_init(void)
{
// allocate memory for DMA transfer
buffer = dma_alloc_coherent(&dev, FIFO_COUNT, &dma_handle, GFP_KERNEL);
if (!request_dma(0, DEVICE_NAME)) {
nios2_set_dma_handler(0, dmatest_handle_dma, &dev);
nios2_set_dma_data_width(0, 0x04);
nios2_set_dma_rcon(0, 1);
nios2_set_dma_wcon(0, 0);
nios2_set_dma_raddr(0, FIFO_ADDRESS);
}
else {
printk(KERN_ERR DEVICE_NAME ": request_dma failed\n");
return -1;
}
printk(KERN_ERR "Start DMA test transfer (0x%.8X,0x%.8X)\n",(unsigned)buffer,dma_handle);
start_dma(&dev);
return 0;
}
static void __exit dmatest_exit(void)
{
disable_dma(0);
free_dma(0);
dma_free_coherent(&dev, FIFO_COUNT, buffer, dma_handle);
}
module_init(dmatest_init);
module_exit(dmatest_exit);
Hein