Forum Discussion
Altera_Forum
Honored Contributor
12 years agoSlacker and Forum members thanks form your help.
Made some progress but what worked before converting to the HAL design ... now seems to hang and transfers some data but not much. The HAL design will help I believe in supporting both ARRIA V ( for Gen1 + Gen2 ) and STRATIX V ( for Gen1, Gen2 and Gen3 ). Code: mixture of example code and other code from forums. what is not clear is the default mode of the DMA controller ... or if everything needs to be set up via ioctl calls. prior to the HAL, I explicitly set up the DMA controller and polled for the end status. the sample code fetched data from system memory and sends the data back to system memory via PCIe link. If I uncomment the while ( !rx_done ); it hangs with rx_done = 0. This was the same result when moving and internal FPGA memory buffer to another internal memory buffer ... looks like only 4 bytes were moved. I have seen this behavior in other posts where the recommendation was to disable the NIOS II data cache .. The NIOS II is minimum with no caches so I don't believe that is a factor. Any recommendations on where to go. I may be able to display the DMA controller state for the hang. I susspect some set up issue where the DMA controller is stuck and can't make progress after the first 4 bytes ? the support says all different data sizes are supported bu maybe an alignment issue. 1) How to debug ? Do I need to go to simulation or is something plain wrong. 2) The interrupts are connected but it isn't clear how they are used with DMA and the HAL. 3) I need to add a "generic" working register set that the host side of the PCIe link can send commands to NIOS and the start address of a linked list of descriptors that reside in system memory for NIOS to process. I figure I need to generate an Avalon MM megafunction to add these registers that are simply r/w registers to pass data ot NIOS II ... would there be any example or existing megafunction ? # include <stdio.h> # include <stdlib.h> # include "system.h" # include "sys/alt_sys_init.h" # include "sys/alt_irq.h" # include "priv/alt_file.h" # include "sys/alt_dma.h" # include "alt_types.h" static volatile int rx_done = 0; /* * Callback function that obtains notification that the data has * been received. */ static void done (void* handle, void* data) { rx_done++; } int main (void) __attribute__ ((weak, alias ("alt_main"))); int alt_main(void) { int rc; int i; int rxchan_depth; int txchan_depth; int val; alt_dma_txchan txchan; alt_dma_rxchan rxchan; void* tx_data = (void*) 0x08000000; /* system memory*/ void* rx_buffer = (void*) 0x0800200; /* system memory */ char * fill_string = "Hello From Avenger System Memory "; char * fill_ptr = (char *) 0x08000000; int fill_string_len; /* alt_irq_init (ALT_IRQ_BASE); alt_io_redirect (ALT_STDOUT, ALT_STDIN, ALT_STDERR); printf("Hello from Nios II Free-Standing! Monday \n"); printf("tx_data = %p \n", tx_data ); printf("rx_buffer = %p \n", 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); } else { printf ("/dev/dma_0 opened tx device ok , tx = %x....\n", txchan); } /* Obtain a handle for the device */ if ((rxchan = alt_dma_rxchan_open ("/dev/dma_0")) == NULL) { printf ("Error: failed to open device ....\n"); exit (1); } else { printf ("/dev/dma_0 opened rx device ok , rx = %x....\n", rxchan); } // check attributes rxchan_depth = alt_dma_rxchan_depth( rxchan ); printf ( "rxchan_depth = %i \n" , rxchan_depth ); txchan_depth = alt_dma_rxchan_depth( rxchan ); printf ( "txchan_depth = %i \n" , txchan_depth ); val = alt_dma_rxchan_ioctl( rxchan, ALT_DMA_GET_MODE, 0 ); printf ( "rxchan mode = %x \n" , val ); val = alt_dma_txchan_ioctl( txchan, ALT_DMA_GET_MODE, 0 ); printf ( "txchan mode = %x \n" , val ); // initialize system buffer fill_string_len = strlen( fill_string ); printf ( "fill string len = %i \n", fill_string_len ); for ( i = 0; i++; i < fill_string_len+1 ) { fill_ptr = fill_string; } /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan,tx_data,32,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,32,done,NULL)) <0 ) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } else { printf ("Passed post read request\n"); } /* wait for transfer to complete */ //while (!rx_done) { printf ("Waiting on rx_done, rx_done = %i\n", rx_done); } printf ("Transfer successful!\n"); printf ( "%s \n", tx_data ); printf ( "%s \n", rx_buffer ); printf ("Transaction complete\n"); alt_dma_rxchan_close (rxchan); alt_dma_txchan_close (txchan); exit(0); // Return code for "success!" if anyone is checking (they aren't). } Ourput: I pre-conditioned the src ( tx ) buffer with ZZZefgh and only ZZZZ was transferred to the dest ( rx ) buffer. Hello from Nios II Free-Standing! Monday tx_data = 0x8000000 rx_buffer = 0x800200 /dev/dma_0 opened tx device ok , tx = 820e6a8.... /dev/dma_0 opened rx device ok , rx = 820e6c4.... rxchan_depth = 3 txchan_depth = 3 rxchan mode = ffffffe7 txchan mode = ffffffe7 fill string len = 35 Passed post read request Waiting on rx_done, rx_done = 0 Transfer successful! ZZZZhgfe ÀÀÀÀZZZZ Transaction complete Eclipse: I am a new user to it and am able to create new projects, importing an associated .socinfo file. When it comes time to running, something changed now there is a problem with an id at 70 and a timestamp which I believe checks it the FPGA design and the NIOS II code is in synch ? Anyhow I have trouble geting that check to pass and it use to then something changed in Eclipse. Is the "free standing" the correct software model for a simple design ?