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

Re(2): External DMA interrupts



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
>