The HAL provides support for access to the EDMA3 DMA
controllers. This support is not intended to expose the full
functionality of these devices and is strictly limited to
supporting peripheral DMA, in particular SPI and MMC/SD.
The user is referred to the TI EDMA3 documentation for a full
description of the EDMA3 devices, and to the sources of the MMC
and SPI drivers for examples of the use of this API. This
documentation only gives a brief description of the functions
available.
Each device transfer direction is described by a controller number
(0 or 1) and an event numbers (0 to 31). These values are usually
defined by the peripheral being accessed. The macro
CYGHWR_HAL_L1XX_EDMA_CHANNEL( controller,
event) combines these into a descriptor that may be
used to initialize the channel. A channel is controlled by a
hal_edma_channel object that must be allocated by
the client. To initialize a channel,
hal_edma_channel_init() is called, passing
the channel object, the descriptor and an optional callback
function and user-defined value. After use the channel can be
deleted with hal_edma_channel_delete().
Before starting a transfer, the channel must be initialized with
the source, destination and size of the transfer to be
done. hal_edma_channel_source() and
hal_edma_channel_dest() describe the source
and destination buffers. A memory buffer is described by its
address plus the increments, or indexes, to step the read or write
pointer through it. The sizes of these indexes depend on the size
of the transfers that the peripheral is programmed to make, and
its synchronisation mode. One of the source or destination will be
the peripheral itself; the address should be the address of the
peripheral's input or output data register, and the indexes should
be zero to prevent the pointer incrementing.
hal_edma_channel_size() supplies the total
transfer size in bytes.
hal_edma_channel_burstsize() describes the A
and B burst sizes for AB synchronized transfers and must be called
before hal_edma_channel_size(). If
hal_edma_channel_burstsize() is not called
then A synchronization is assumed. The values set by
hal_edma_channel_burstsize() remain set in
the channel, and another call to this function is needed to reset
them.
A transfer is started by calling
hal_edma_channel_start(). The
opt argument contains bits that will be
merged with the PaRAM options field. When a transfer is complete,
then hal_edma_channel_stop() should be
called. This function may also be called to abort a transfer.
If a callback was passed to
hal_edma_channel_init() then when the
transfer finishes or encounters and error, the callback will be
called from DSR context. The callback will be passed a pointer to
the channel object, an event code and the user-defined value that
was passed to hal_edma_channel_init(). There
are two possible event codes:
CYGHWR_HAL_L1XX_EDMA_COMPLETE indicates that
the transfer finished successfully, and
CYGHWR_HAL_L1XX_EDMA_ERROR indicates that an
error condition was encountered.
In kernel configurations the DMA system will use interrupts to
detect transfer completion or errors. In non-kernel configurations
it will use polling. For the polling to happen, client code must
call hal_edma_poll() on a regular basis. On
DMA completion the callback function will be called, as before.