Nios® V Processor Software Developer Handbook

ID 743810
Date 10/12/2024
Public
Document Table of Contents

7.9.2. DMA Receive Channels

DMA receive channels operate similarly to DMA transmit channels. Software can obtain a handle for a DMA receive channel using the alt_dma_rxchan_open() function. You can then use the alt_dma_rxchan_prepare() function to post receive requests. The prototype for alt_dma_rxchan_prepare() is:
typedef void (alt_rxchan_done)(void* handle, void* data);
int alt_dma_rxchan_prepare (alt_dma_rxchan dma, 
void* data,
alt_u32 length,
alt_rxchan_done* done, 
void* handle);

A call to this function posts a receive request to channel dma, for up to length bytes of data to be placed at address data. This function returns before the DMA transaction completes. The return value indicates whether the request is successfully queued. A negative return value indicates that the request failed. When the transaction completes, the user-supplied function done() is called with argument handle to provide notification and a pointer to the receive data.

Certain errors can prevent the DMA transfer from completing. Typically this is caused by a catastrophic hardware failure; for example, if a component involved in the transfer fails to respond to a read or write request. If the DMA transfer does not complete (that is, less than length bytes are transferred), function done() is never called.

Two additional functions are provided for manipulating DMA receive channels: alt_dma_rxchan_depth() and alt_dma_rxchan_ioctl().

Note: If you are using the Avalon-MM DMA device to receive from hardware (not memory-to-memory transfer), call the alt_dma_rxchan_ioctl() function with the request argument set to ALT_DMA_RX_ONLY_ON.

alt_dma_rxchan_depth() returns the maximum number of receive requests that can be queued to the device. alt_dma_rxchan_ioctl() performs device-specific manipulation of the receive device.

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include "sys/alt_dma.h"
#include "alt_types.h"
/* flag used to indicate the transaction is complete */
volatile int dma_complete = 0;
/* function that is called when the transaction completes */
void dma_done (void* handle, void* data)
   {
   dma_complete = 1;
   }
   int main (void)
      {
      alt_u8 buffer[1024];
      alt_dma_rxchan rx;
      /* Obtain a handle for the device */
      if ((rx = alt_dma_rxchan_open ("/dev/dma_0")) == NULL)
         {
            printf ("Error: failed to open device\n");
            exit (1);
         }
      else
         {
         /* Post the receive request */
         if (alt_dma_rxchan_prepare (rx, buffer, 1024, dma_done, NULL) < 0)
            {
               printf ("Error: failed to post receive request\n");
               exit (1);
            }
         /* Wait for the transaction to complete */
         while (!dma_complete);
            printf ("Transaction complete\n");
            alt_dma_rxchan_close (rx);
      }
      return 0;
}