Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12689 Discussions

Little help with DMA reading from a source

Altera_Forum
Honored Contributor II
1,008 Views

Hello i have a fifo that get's filled after 10 seconds and i want to read half of the fifo from my DMA. How can i do that? 

I am recieving a half_full signal from my fifo, which generates an IRQ. 

 

I am getting this IRQ without any problem but i want to know how to tell the DMA to read 32 positions of my fifo (half). 

 

My DMA CODE that works from SDRAM to ONCHIP ram is the follow 

 

#include <stdio.h># include <unistd.h> // usleep()# include "system.h"# include "sys/alt_irq.h"# include "altera_avalon_pio_regs.h"# include <stdlib.h># include <stddef.h># include <string.h># include <io.h># include <alt_types.h># include "sys/alt_dma.h"# include "sys/alt_cache.h"# include "sys/alt_alarm.h"# include "sys/alt_irq.h"# include "alt_types.h"# include "altera_avalon_pio_regs.h" static volatile int txrx_done = 0; int i; static void handle_button_interrupts(void* context, alt_u32 id); volatile alt_u8 led=0; /* A variable to hold the value of the button pio edge capture register. */ volatile int edge_capture; volatile int irq_count; //callback function when DMA transfer done static void txrxDone(void * handle, void * data) { txrx_done = 1; } void initMEM(int base_addr,int len) { for ( i=0;i<len;i++) { IOWR_8DIRECT(base_addr,i,i); } } int initdma(void) { printf("testing fifo & onchip : dma operation\n"); alt_16 buffer; //memset((void *)SSRAM_0_BASE,0x7a,0x10);//this write base on byte //initMEM(FIFO_0_BASE,0x10); memset((void *)(DESTINO_BASE),0x33,0x10); printf("content of fifo:before DMA operation\n"); for ( i=0;i<0x10;i++) { printf("%d: %x\n",i,IORD_8DIRECT(FIFOWRAPPER_0_BASE,i)); } printf("content of onchip:before DMA operation\n"); for ( i=0;i<0x10;i++) { printf("%d: %x\n",i,IORD_8DIRECT(DESTINO_BASE,i)); } int rc; //request alt_dma_txchan txchan; alt_dma_rxchan rxchan; void* tx_data = (void*)FIFOWRAPPER_0_BASE; /* pointer to data to send */ void* rx_buffer = (void*)(DESTINO_BASE); /* pointer to rx buffer */ /* Create the transmit channel */ if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL) { printf ("Failed to open transmit channel\n"); exit (1); } /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL) { printf ("Failed to open receive channel\n"); exit (1); } /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan, tx_data, 0x10, 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, rx_buffer, 0x10, txrxDone, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); //exit (1); } /* wait for transfer to complete */ while (!txrx_done); printf ("Transfer successful!\n"); printf("content of fifo:after DMA operation\n"); for ( i=0;i<0x10;i++) { printf("%d: %x\n",i,IORD_8DIRECT(FIFOWRAPPER_0_BASE,i)); } printf("content of onchip:after DMA operation\n"); for ( i=0;i<0x10;i++) { printf("%d: %x\n",i,IORD_8DIRECT(DESTINO_BASE,i)); } return 0; }
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
316 Views

Simply change to 32 the DMA length (which is now 0x10 in your example) 

Then, you probably want the tx channel to get data from a constant address, since usually FIFOs work this way; 

so, you need to set the RCON bit in the DMA control register (this applies to the standard Altera DMA core; in other cores there will be a similar control bit).
0 Kudos
Altera_Forum
Honored Contributor II
316 Views

Hello Cris72, i see that the rcon bit is the bit number 8, what would be the C code to set it? I can't find in the literature.. 

Thanks 

 

 

nvm you've answered me this before 

#include "altera_avalon_dma_regs.h" int reg; reg = IORD_ALTERA_AVALON_DMA_CONTROL (dma_base_address); IOWR_ALTERA_AVALON_DMA_CONTROL (dma_base_address, reg | ALTERA_AVALON_DMA_CONTROL_RCON_MSK);
0 Kudos
Reply