Freescale eDMA
CYGPKG_HAL_FREESCALE_EDMA
eCos Support for Freescale eDMA Direct Memory Access controller
Description
eDMA is enhanced Direct Memory Access controller found on various Freescale
microcontroller families. It is combined with different architectures such as Power Architecture,
Coldfire/M68K, ARM, Cortex-M, etc.
The eDMA HAL library provides generic support for module configuration and initialization as well as for executing of DMA transfers.
Most common usage of eDMA is as an enhancement of other device. eDMA acts as a cross-bar master and executes fast data
transfers on behalf of slave devices.
DMA can also perform memory to memory transfers on direct request by the application.
In following text the devices and applications
that use DMA shall be referenced as [DMA] users.
Configuration
The eDMA package CYGPKG_HAL_FREESCALE_EDMA is activated by implementing CYGINT_HAL_DMA interface.
The CDL provides configuration of DMA multiplexer, channel priorities and interrupt priorities.
For the systems with more than 16 channels also there is a provision for configuration of group priorities.
Please refer to CDL and eDMA reference manual for details of module operation.
eDMA API
hal_freescale_edma_init_chanset
void hal_freescale_edma_init_chanset(cyghwr_hal_freescale_dma_set_t *inidat_p);
Initialise inidat_p channel set. A channel set consists of
one or more DMA channels.
The initialisation parameters are provided by following structure:
// DMA Channel set
typedef struct cyghwr_hal_freescale_dma_set_s {
cyghwr_hal_freescale_edma_t* edma_p; // eDMA controller [register set]
const cyghwr_hal_freescale_dma_chan_set_t *chan_p; // Channel configuration data
cyg_uint8 chan_n; // Number of channels
} cyghwr_hal_freescale_dma_set_t;
where:
chan_p points to an array of
chan_n channels.
Channel configuration is provided by following structure.
// DMA Channel data
typedef struct cyghwr_hal_freescale_dma_chan_set_s {
cyg_uint8 dma_src; // Data source
cyg_uint8 dma_chan_i; // Channel index
cyg_uint8 dma_prio; // DMA channel priority
cyg_uint8 isr_prio; // Interrupt priority
cyg_uint8 isr_num; // Interrupt vector
cyg_uint8 isr_ena; // Interruot enable
} cyghwr_hal_freescale_dma_chan_set_t;
The DMA channel priority dma_chan_i must be unique for every channel.
In order to satisfy this requirement the channel that previously had the given priority shall
be assigned with the previous prioruty of the target channel.
As a special (and most common case) FREESCALE_EDMA_DCHPRI_ASIS shall keep the
priority unchanged.
hal_freescale_edma_transfer_init
void hal_freescale_edma_transfer_init(cyghwr_hal_freescale_dma_set_t *inidat_p,
cyg_uint8 chan_i,
const cyghwr_hal_freescale_edma_tcd_t *tcd_cfg_p
);
Initialise transfer. trannsfer on chan_i channel of
edma_p shall be initialised. with transfer control descriptor
tcd_cfg_p.
hal_freescale_edma_transfer_diag
void hal_freescale_edma_transfer_diag(cyghwr_hal_freescale_edma_t
*edma_p, cyg_uint8 chan_i, cyg_bool recurse);
Show contents of a transfer control descriptor set.
eDMA operations
Following inline functions and macros initiate or stop respective DMA operations.
void hal_freescale_edma_erq_enable(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_erq_disable(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_erq_cleardone(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_irq_enable(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_irq_disable(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_irq_clear(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_transfer_clear(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
void hal_freescale_edma_transfer_start(cyghwr_hal_freescale_edma_t *edma_p,
cyg_uint8 chan_i);
#define HAL_DMA_TRANSFER_STOP(__edma,__chan) \
hal_freescale_edma_erq_disable(__edma, __chan)
#define HAL_DMA_TRANSFER_START(__edma,__chan) \
hal_freescale_edma_erq_enable(__edma, __chan)
#define HAL_DMA_TRANSFER_CLEAR(__edma,__chan) \
hal_freescale_edma_cleardone(__edma, __chan)