NIOS II (full sample working with DMA in HAL)?

Sep 24, 2004 1 Replies

I couldn't find a full sample how work with DMA (HAL). I want to write by DMA from SDRAM to some device with constant address.



I've wrote next source code:



//********************************************************************* volatile int dma_complete = 0; int* page1 =(int*)((int) SDRAM_BASE + 0x5E0000);



void DMA_VGA_Done(void*) { dma_complete=1; }



void isr_dma(void* context, alt_u32 id) { alt_dma_txchan* tx = (alt_dma_txchan*) context; if (dma_complete) { dma_complete = 0; alt_dma_txchan_ioctl(tx, ALT_DMA_SET_MODE_32, NULL); alt_dma_txchan_ioctl(tx, ALT_DMA_TX_STREAM_ON, (int*) VGA_BASE); alt_dma_txchan_send(*tx, page1, 1024*768, DMA_VGA_Done, NULL); } }


int main(void) { alt_dma_txchan tx; tx = alt_dma_txchan_open ("/dev/dma"); ..... alt_irq_register(DMA_IRQ, tx, isr_dma);



alt_dma_txchan_reg(tx); alt_dma_txchan_ioctl(tx, ALT_DMA_SET_MODE_32, NULL); alt_dma_txchan_ioctl(tx, ALT_DMA_TX_STREAM_ON, (void*) VGA_BASE); alt_dma_txchan_send(tx, page1, 1024*768, DMA_VGA_Done, NULL); while( 1 ) { ..... } alt_dma_txchan_close(tx); fclose(lcd); return(0); }



//*********************************************************************


It doesn't work. Please, correct me if you know as.


Nios II version 1.0 SP1, just released, contains a new software example design called "memtest". This example design checks using #ifdef to see if the system contains a DMA. If it does, it performs a test of memory using HAL DMA code in addition to the normal tests it runs. Pasted below is a copy of the DMA test function which includes calls to the DMA HAL routines.

-Nathan Knight Altera Applications

/******************************************************************

  • Function: MemDMATest
*
  • Purpose: Tests every bit in the memory device within the
  • specified address range using DMA. The DMA controller provides
  • a more rigourous test of the memory since it performs back-to-
  • back memory accesses at full system speed.
* ******************************************************************/ #ifdef DMA_NAME static int MemDMATest(unsigned int memory_base, unsigned int nBytes) { int rc; int ret_code = 0; int pattern, offset; alt_dma_txchan txchan; alt_dma_rxchan rxchan; void* data_written; void* data_read; /* Get a couple buffers for the test */ /* Using the "uncached" version of malloc to avoid cache coherency issues */ data_written = (void*)alt_uncached_malloc(0x1000); data_read = (void*)alt_uncached_malloc(0x1000); /* Fill write buffer with known values */ for (pattern = 1, offset = 0; offset < sizeof(data_written); pattern++, offset+=4) { IOWR_32DIRECT((int)data_written, offset, pattern); }

/* Create the transmit channel */ if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) { printf ("Failed to open transmit channel\n"); exit (1); } /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) { printf ("Failed to open receive channel\n"); exit (1); } for(offset = memory_base; offset < (memory_base + nBytes); offset +=

0x1000) { /* Use DMA to transfer from write buffer to memory under test */ /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan, data_written, 0x1000, NULL, NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", rc); exit (1); }

/* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan, (void*)offset, 0x1000, dma_done, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } /* Wait for transfer to complete */ while (!rx_done); rx_done = 0; /* Clear the read buffer before we fill it */ memset(data_read, 0, 0x1000); /* Use DMA to read data back into read buffer from memory under test */ /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan, (void*)offset, 0x1000, NULL, NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", rc); exit (1); }

/* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan, data_read, 0x1000, dma_done, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); }

/* Wait for transfer to complete */ while (!rx_done); rx_done = 0; if (memcmp(data_written, data_read, 0x1000)) { ret_code = offset; break; } } alt_uncached_free(data_written); alt_uncached_free(data_read); return ret_code; } #endif /* DMA_NAME */

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required