[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Re(2): External DMA interrupts



Hi again Arne,

Do you get the data out on the external DMA channel as expected ?

The two first interrupts occur before the internal DMA has
started to really process the descriptor. I guess the external DMA
channel causes this. 

One reason could be if you enable the external DMA interrupt (in the 
interrupt mask) before you start the external DMA channel. Possibly there
is also a small latency after giving the start command to the external DMA 
channel until it is actually started.

I think there should be the following steps:

1. start the external DMA channel
2. poll the "run" bit until it really starts (this will take care of 
   the possible command latency)
3. Enable the external DMA channel interrupt in the interrupt mask.

I hope this helps

Best regards


Per Zander 

On Thu, 6 Mar 2003, Arne Bockholdt wrote:

> Hi Per,
> 
> thanks for the quick answer.
> 
> >
> >The ext_dma0 interrupt is generated when the external DMA channel is 
> >stopped. It can be stopped for three reasons:
> >1. SW stopped it.
> >2. End of packet was set from the internal DMA channel.
> >3. The transfer counter in the external DMA channel expired.
> 
> I get three interrupts with the d_wait flag, here is the data : 
> 
> 
> Altera ACEX 1k External DMA interrupt received
> Altera ACEX 1k Bytes send = 32, Bytes left = 0
> Altera ACEX 1k Bytes in FIFO = 32
> Altera ACEX 1k Descriptor status = 0x0
> Altera ACEX 1k CH4 DESCR = 0x40127440
> Altera ACEX 1k CH4 FIRST = 0x40127440
> Altera ACEX 1k CH4 NEXT = 0x0
> Altera ACEX 1k CH4 Status = 0x1
> Altera ACEX 1k DMA0 Status = 0x0
> 
> 
> Altera ACEX 1k External DMA interrupt received
> Altera ACEX 1k Bytes send = 32, Bytes left = 0
> Altera ACEX 1k Bytes in FIFO = 32
> Altera ACEX 1k Descriptor status = 0x0
> Altera ACEX 1k CH4 DESCR = 0x40127440
> Altera ACEX 1k CH4 FIRST = 0x40127440
> Altera ACEX 1k CH4 NEXT = 0x0
> Altera ACEX 1k CH4 Status = 0x1
> Altera ACEX 1k DMA0 Status = 0x0
> 
> 
> Altera ACEX 1k DMA transfer finished, disable interrupt...
> Altera ACEX 1k External DMA interrupt received
> Altera ACEX 1k Bytes send = 32, Bytes left = 32
> Altera ACEX 1k Bytes in FIFO = 0
> Altera ACEX 1k Descriptor status = 0x0
> Altera ACEX 1k CH4 DESCR = 0x40127440
> Altera ACEX 1k CH4 FIRST = 0x0
> Altera ACEX 1k CH4 NEXT = 0x0
> Altera ACEX 1k CH4 Status = 0x0
> Altera ACEX 1k DMA0 Status = 0x0
> 
> This is the descriptor : 
> 
> 	g_dma_descr.sw_len = ucCount;
> 	g_dma_descr.ctrl	= d_eol | d_eop | d_wait;
> 	g_dma_descr.next	= 0;
> 	g_dma_descr.hw_len = 0;
> 	g_dma_descr.status 	= 0;
> 	g_dma_descr.buf 	= virt_to_phys( &g_ucaDmaBuf );
> 
> This is the DMA_0_CMD : 
> 
> 		IO_STATE (R_EXT_DMA_0_CMD, cnt, disable) |
> 		IO_STATE (R_EXT_DMA_0_CMD, rqpol, ahigh) |
> 		IO_STATE (R_EXT_DMA_0_CMD, apol, ahigh) |
> 		IO_STATE (R_EXT_DMA_0_CMD, rq_ack, burst) |
> 		IO_STATE (R_EXT_DMA_0_CMD, wid, word) |
> 		IO_STATE (R_EXT_DMA_0_CMD, dir, output) |
> 		IO_STATE (R_EXT_DMA_0_CMD, run, start) |
> 		ucCount >> 1;
> 
> The output code : 
> 
> 	printk(KERN_INFO "%s External DMA interrupt received\n", FPGA_NAME);
> 	printk(KERN_INFO "%s Bytes send = %i, Bytes left = %i\n", FPGA_NAME,
> (*R_DMA_CH4_HWSW) & 0xffff, (*R_DMA_CH4_HWSW) >> 16 );
> 	printk(KERN_INFO "%s Bytes in FIFO = %i\n", FPGA_NAME,
> (*R_DMA_CH4_STATUS));
> 	printk(KERN_INFO "%s Descriptor status = 0x%x\n", FPGA_NAME,
> ((etrax_dma_descr*)phys_to_virt(*R_DMA_CH4_DESCR))->status );
> 	printk(KERN_INFO "%s CH4 DESCR = 0x%x\n", FPGA_NAME, *R_DMA_CH4_DESCR );
> 	printk(KERN_INFO "%s CH4 FIRST = 0x%x\n", FPGA_NAME, *R_DMA_CH4_FIRST );
> 	printk(KERN_INFO "%s CH4 NEXT = 0x%x\n", FPGA_NAME, *R_DMA_CH4_NEXT );
> 	printk(KERN_INFO "%s CH4 Status = 0x%x\n", FPGA_NAME, (*R_DMA_CH4_CMD) );
> 	printk(KERN_INFO "%s DMA0 Status = 0x%x\n", FPGA_NAME,
> (*R_EXT_DMA_0_STAT) );
> 
> The ext_dma0 channel seems to be stopped all the time, this seems odd to
> me. The descriptor status byte isn't updated after the transfer. When I
> remove the d_wait flag I only get the last interrupt but with 32 bytes in
> FIFO left. I think the first interrupts is for the eop in the descriptor ?
> The last one is end of transfer, the odd thing is the second interrupt and
> the fact that the external dma channel is stopped all the time.
> >
> >
> >
> >> * There seems to be no way to see why I received a ext_DMA interrupt.
> >The
> >> internal DMA has a register to get the reason for the interrupt. Where
> >is
> >> the data for the external DMA ?
> >
> >There is onlu one reason: The channel is stopped. Se above for 
> >reasons for stopping. DREQ inactive does not stop the channel,
> >it just "pauses" it.
> 
> Does this means that when the IO drops DREQ the run bit in
> R_EXT_DMA_0_STAT is still 1 ? 
> 
> Thanks,
> 
>  Arne Bockholdt
> >
> 
>