- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
On my Cyclone IV FPGA Development board, I have built a Qsys system with Nios II processor and two standard linear DMAs, and I am DMA'ing data from one on-chip memory buffer to another through a data processing block. After the first pass of the DMA runs, I update the contents in the source buffer and repeat the process. I need to repeat this over several MB of data, so will need to do this a few thousand times. Unfortunately, the process fails after the 3rd iteration of the DMA with this message: "Failed to post CH_DMA transmit request, reason = " (i.e. no error code printed out). Not sure why the DMA would fail on the 4th pass. Is this a situation anyone has encountered before? Here is the crux of the code I'm using: . . . // ************************************************************************** // ENABLE CH_DMA(s) // ************************************************************************** // Use CH_DMA to move data from CH_FIFO into CH_BUFFER: if ((CH_dma_txchan = alt_dma_txchan_open("/dev/ch_dma")) == NULL) { alt_printf ("Failed to open CH_DMA transmit channel\n"); exit (1); } // Create the receive channel if ((CH_dma_rxchan = alt_dma_rxchan_open("/dev/ch_dma")) == NULL) { alt_printf ("Failed to open CH_DMA receive channel\n"); exit (1); } // Lock the CH_DMA transmit (ie. read) channel to CH0_FIFO alt_dma_rxchan_ioctl(CH_dma_rxchan, ALT_DMA_RX_ONLY_ON, (void *)CH_DMA_READ_MASTER_CH_FIFO_BASE); // ************************************************************************** // ENABLE ABC_DMA: // ************************************************************************** // Use ABC_DMA to move data from ABC_DATA into ABC_FIFO: if ((ABC_dma_txchan = alt_dma_txchan_open("/dev/ABC_DMA")) == NULL) { alt_printf ("Failed to open ABC_DMA transmit channel\n"); exit (1); } // Create the receive channel if ((ABC_dma_rxchan = alt_dma_rxchan_open("/dev/ABC_DMA")) == NULL) { alt_printf ("Failed to open ABC_DMA receive channel\n"); exit (1); } // Lock ABC_DMA rx (destination) channel to ABC_FIFO alt_dma_txchan_ioctl(ABC_dma_txchan, ALT_DMA_TX_ONLY_ON, (void*) ABC_DMA_WRITE_MASTER_ABC_FIFO_BASE); // ************************************************************************** // Start superloop // ************************************************************************** while (1) { // ************************************************************************** // Flush Nios II Data Cache // ************************************************************************** alt_dcache_flush_all(); // ************************************************************************** // POST CH_DMA: // ************************************************************************** // Post CH_DMA transmit request: if ((rc = alt_dma_txchan_send (CH_dma_txchan,(void *)CH_DMA_READ_MASTER_CH_FIFO_BASE,bytes,NULL,NULL)) < 0) { alt_printf ("Failed to post CH_DMA transmit request, reason = %i\n", rc); exit (1); } // Post CH0_DMA receive request: if ((rc = alt_dma_rxchan_prepare (CH_dma_rxchan,(void *)CH_DMA_WRITE_MASTER_CH_BUFFER_BASE,bytes,CH_dma_done, NULL)) < 0) { alt_printf ("Failed to post read request, reason = %i\n", rc); exit (1); } // ************************************************************************** // POST ABC_DMA: // ************************************************************************** // Post ABC_DMA transmit request: if ((rc = alt_dma_txchan_send (ABC_dma_txchan,(void *)ABC_DMA_READ_MASTER_ABC_DATA_BASE,bytes,ABC_dma_done,NULL)) < 0) { alt_printf ("Failed to post ABC_DMA transmit request, reason = %i\n", rc); exit (1); } // ************************************************************************** // Vary LEDs // ************************************************************************** IOWR(LED_PIO_BASE,0,0xAA); // ************************************************************************** // Wait until buffer(s) is filled up then proceed // ************************************************************************** // while (!(ABC_dma_complete && CH_dma_complete)) { IOWR(LED_PIO_BASE,0,0xFF); } // ************************************************************************** // Turn appropriate LED on indicating which channel(s) transfer is complete // ************************************************************************** IOWR(LED_PIO_BASE,0,0xFE); // ************************************************************************** // Check data in buffer(s) // Format in Memory: {XYZ} LITTLE ENDIAN // A <-> X B <-> Y C <-> Z // ************************************************************************** # ifdef echo printf ("\nReading final contents of CH_BUFFER:\n"); read_data = (int*) CH_BUFFER_BASE; // Check XYZ data values for (j=0; j <= (words-1); j++) { printf(" 0x%-.8x", read_data[j]); X = (X_val << 16) & 0xFF0000; // MSB Y = (X_val+1 << 8) & 0xFF00; Z = (X_val+2 ) & 0xFF; // LSB Exp_Value = X | Y | Z; printf(" Expected value = 0x%.8x",Exp_Value); if (read_data[j] == Exp_Value) printf(" - Passed\n"); else printf(" - Failed\n"); X_val = X_val + 3; } // Init ABC_DATA with NON-default values write_data = (int*) ABC_DATA_BASE; for (j=0; j <= (words-1); j++) { A = (R_val << 16) & 0xFF0000; // MSB B = (R_val+1 << 8) & 0xFF00; C = (R_val+2 ) & 0xFF; // LSB ABC_Value = A | B | C; *write_data = ABC_Value; write_data++; A_val = A_val + 3; } # endif // ************************************************************************* // Pause then repeat with updated values // ************************************************************************* # ifdef echo printf("\nPausing...\n\n"); # endif usleep(1000000); printf("\nEnd of iteration\n"); // Reset flags ABC_dma_complete = 0; CH_dma_complete = 0; printf("\nPress Enter to proceed with program."); GetInputString(line,sizeof(line),stdin); } // end of superloop . . . Thank you for any help.Link Copied
0 Replies
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page