Code Confidencebuild 3.0.0.201402161939

Freescale eDMA

Name

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)