<div class='quotetop'>QUOTE </div>
--- Quote Start ---
Have you looked at the example on page 4-21 of the Nios II Software Developer's Handbook, there is an example of exactly what you're trying to do and it works. If this does not answer your question then please post back.
Lastly the bug that Kerri refers to is an edge case, and will not apply in the use case you have described.
To explain the problem, it is important to understand the HAL DMA model. This expects a DMA device to be performing DMA transfers in one of three modes:
- memory to memory
- devices to memory
- memory to device
Which mode is used is expected to be determined at system creation time.
In the case of the altera_avalon_dma driver, this is actually done through a run time ioctl call. The bug occurs if you have run the DMA in one of these modes, and then make the ioctl call to change to one of the other modes.
This is in any case not an efficent way to make use of the DMA controller, since the pending transfer queues will need to be drained between the ioctl calls. It is better to provide additional DMA channels instead.[/b]
--- Quote End ---
I use mode "devices to memory".
I try use code on page 4-21. This code also does not work.
1. This code with small error: /* Wait for the transaction to complete */ while (!dma_done); - dma_done: void result function
2. I add to example IOCT request for RX_STREAM_ON with argumet = SPI_BASE address, before call alt_dma_rxchan_prepare.
"Which mode is used is expected to be determined at system creation time"
System created in "devices to memory":
1. DMA read_master connected ONLY to SPI control port
2. DMA write_master connected ONLY to SDRAM.
This configuration work correctly through direct access to DMA registers, but don't work through HAL.
This my worked code:
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_SPI_REC_BASE, 0);
IOWR_ALTERA_AVALON_DMA_STATUS(DMA_SPI_REC_BASE, 0);
IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_SPI_REC_BASE, SPIS_DATA_BASE);
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_SPI_REC_BASE, (alt_u32)buffer);
IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_SPI_REC_BASE, DMA_BUFF_SIZE*2);
ch = ALTERA_AVALON_DMA_CONTROL_HW_MSK
| ALTERA_AVALON_DMA_CONTROL_GO_MSK
| ALTERA_AVALON_DMA_CONTROL_LEEN_MSK
| ALTERA_AVALON_DMA_CONTROL_RCON_MSK;
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_SPI_REC_BASE, ch);
printf("Wait data...\n");
while(1){
ch = IORD_ALTERA_AVALON_DMA_STATUS(DMA_SPI_REC_BASE);
if( ch & (~ALTERA_AVALON_DMA_STATUS_BUSY_MSK) )
{
printf("DMA %d\n", ch);
break;
}
}
There can be you can result a correct code for HAL operations?