DMAC — eCos Support for the Atmel DMA Controller



ch = atmel_dmac_chan_alloc( cyg_uint32 descriptor , atmel_dmac_callback *cb , CYG_ADDRWORD priv );

void atmel_dmac_chan_config( atmel_dmac_channel *ch , cyg_uint32 extended );

void atmel_dmac_chan_free( atmel_dmac_channel *ch );

void atmel_dmac_start( atmel_dmac_channel *ch , CYG_ADDRWORD src , CYG_ADDRWORD dst , cyg_uint32 size );

void atmel_dmac_stop( atmel_dmac_channel *ch );

void atmel_dmac_dma_poll( atmel_dmac_channel *ch );


This package provides access to the Atmel DMAC (DMA Controller) devices. This support is not intended to expose the full functionality of these devices. It is mainly limited to supporting peripheral DMA (e.g. USART, SPI, etc.). It is currently limited to single DMA transfers.

There is currently no cross-platform/variant standardised eCos DMA I/O interface package, since DMA features and functionality vary greatly between architectures, and event within variants of an architecture. This stand-alone device package allows common DMA support to be shared between devices that implement Atmel DMA Controllers.

The user is directed towards the relevant Atmel documentation for a full description of the DMAC devices, and to the variant device drivers for examples of the use of this API. This documentation only gives a brief description of the functions available.

A DMAC instance is defined by a controller number (0 or 1), and each controller has support for a number of (variant defined) channels. The API uses a simple 32-bit encoding to describe how a specific DMA channel should be used, with this package providing helper macros to combine the necessary information into a unique descriptor. These descriptors may be stored with a device driver as required.

The following are examples of how definitions can be made:

// USART0 TX on controller 0, 8-bit mem-to-peripheral transfers using AHB_IF2

// USART0 RX on controller 0, 8-bit peripheral-to-mem transfers using AHB_IF2

Before DMA transfers can be performed, a DMA channel must be claimed. This is done by calling atmel_dmac_chan_alloc(). The descriptor argument describes the majority of the DMA transfer configuration that will be used. As shown in the examples above the passed descriptor not only encodes the source and destination interfaces, but also the transfer sizes. Also, depending on the descriptor construction macros used, it is possible to control the direction and modification of addresses during transfers. The cb argument is used to register a client function that will be called when a requested transfer completes. The priv argument is a client specified value that will be passed to the callback function, and can be used to reference client driver specific data.

If DMA chunk transfers of more than one item per transaction are required then an “extension” 32-bit configuration descriptor can be specifed using the atmel_dmac_chan_config() function. The extended descriptor allows for non-default FIFO configurations and transfer chunk sizes to be specified. The <cyg/hal/sama5d3.h> header file contains examples of defining extended descriptors. For example, see the ATMEL_AES_DMA_TX_EXT manifest.

Most drivers will allocate a DMA channel object and keep it active throughout the system lifetime. However, if it is necessary to share a channel, or otherwise disable the use of a stream, the driver may call atmel_dmac_chan_free() to return a channel to an unused state. It will be necessary to call atmel_dmac_chan_alloc() before specific DMA descriptor operations can be performed again.

The register callback function has the following prototype:

typedef void atmel_dmac_callback( atmel_dmac_channel  *ch,
                                  cyg_uint32          cbid,
                                  cyg_uint32          count,
                                  CYG_ADDRWORD        data );

The ch is the channel structure describing the transfer. The cbid argument is a completion identifier:

Table 106.1. Completion Codes

CYGHWR_ATMEL_DMA_COMPLETE A valid transfer completion. The count argument should match the size passed to the atmel_dmac_start() call.
CYGHWR_ATMEL_DMA_AHBERR This code indicates that the DMA Controller has detected an AHB read or write access error. This may indicate invalid memory addresses have been passed, or invalid AHB_IF mappings have been used.
CYGHWR_ATMEL_DMA_DICERR For configurations where Descriptor Integrity Check support is available, and enabled, then if an error is detected in a referenced memory-based transfer structure this result will be raised.

The count argument is the number of data items successfully transferred. The data argument is the client private data registered for the callback.

A transfer is configured and started by calling atmel_dmac_start(). The ch argument describes the DMA channel, with the descriptor used when allocating the channel defining how the other arguments are used. The src argument defines the peripheral or memory address from which the transfer will be made. The dst argument supplies the peripheral or memory address to which the transfer will write. The size argument defines the number of data items to be transferred. Once this function call completes the channel is operational and will transfer data once the relevant peripheral starts triggering transfers.

When the transfer completes the registered callback is called from DSR mode.

  1. Since the callback function is executed as a DSR, only a subset of eCos operations are valid.
  2. It is expected that the client driver will perform any necessary CACHE operations within either its supplied callback handler functions, or before calling atmel_dmac_start() as required.