Name

XDMAC — eCos Support for the Atmel XDMAC Controller

Synopsis

#include CYGBLD_DEV_DMA_H
    

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 );

Description

This package provides access to the Atmel XDMAC (Extended 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 XDMAC 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.

The API of this controller is designed to be compatible with that for the Atmel DMAC controller and is a drop-in replacement for it. Thus the API refers to the DMAC in its naming, not the XDMAC.

A XDMAC 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 default memory interfaces
#define AT91_SERIAL0_DMA_TX      CYGHWR_ATMEL_DMA_M2P(0,USART0_TX,8)

// USART0 RX on controller 0, 8-bit peripheral-to-mem transfers using default memory interfaces
#define AT91_SERIAL0_DMA_RX      CYGHWR_ATMEL_DMA_P2M(0,USART0_RX,8)

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.

The atmel_dmac_chan_config() function is present for compatibility with the DMAC driver. It is not currently needed, but device drivers that may use both drivers may call this with not effect.

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 109.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.

[Note]Notes:
  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.