S32 SDK

Detailed Description

This module covers the functionality of the Enhanced Direct Memory Access (eDMA) peripheral driver.

The eDMA driver implements direct memory access support in the S32144K processor; the main usage of this module is to offload the bus read/write accesses from the core to the eDMA engine.

Features

Functionality

Initialization

In order to use the eDMA driver, the module must be first initialized, using EDMA_DRV_Init() function. Once initialized, it cannot be initialized again until it is de-initialized, using EDMA_DRV_Deinit(). The initialization function does the following operations:

Upon module initialization, the application must initialize the channel(s) to be used, using EDMA_DRV_ChannelInit() function. This operation means enabling a eDMA channel number (or dynamically allocating one), selecting a source trigger (DMA request multiplexed via DMAMUX) and setting the channel priority. Additionally, a user callback can be installed for each channel, which will be called when the corresponding interrupt is triggered.

Transfer Configuration

After initialization, the transfer control descriptor for the selected channel must be configured before use. Depending on the application use-case, on of the three transfer configuration methods should be called.

Single-block transfer

For the simplest use-case where a contiguous chunk of data must be transferred, the most suitable function is EDMA_DRV_ConfigSingleBlockTransfer(). This takes the source/destination addresses as parameters, as well as transfer type/size and data buffer size, and configures the channel TCD to read/write the data in a single request. The looping and scatter/gather features are not used in this scenario. The driver computes the appropriate offsets for source/destination addresses and set the other TCD fields.

Loop transfer

The eDMA IP on S32K144 supports complex addressing modes. One of the methods to configure complex transfers in multiple requests is using the minor/major loop support. The EDMA_DRV_ConfigLoopTransfer() function sets up the transfer control descriptor for subsequent requests to trigger multiple transfers. The addresses are adjusted after each minor/major loop, according to user setup. This method takes a transfer configuration structure as parameter, with settings for all the fields that control addressing mode (source/destination offsets, minor loop offset, channel linking, minor/major loop count, address last adjustments). It is the responsibility of the application to correctly initialize the configuration structure passed to this function, according to the addressed use-case.

Scatter/gather

The eDMA driver also supports scatter/gather feature, which allows various transfer scenarios. When scatter/gather is enabled, a new TCD structure is automatically loaded in the current channel's TCD registers when a transfer is complete, allowing the application to define multiple different subsequent transfers. The EDMA_DRV_ConfigScatterGatherTransfer() function sets up a list of TCD structures based on the parameters received and configures the eDMA channel for the first transfer; upon completion, the second TCD from the list will be loaded and the channel will be ready to start the new transfer when a new request is received.
The application must allocate memory for the TCD list passed to this function (with an extra 32-bytes buffer, as the TCD structures need to be 32 bytes aligned); nevertheless, the driver will take care of initializing the array of descriptors, based on the other parameters passed. The function also received two lists of scatter/gather configuration structures (for source and destination, respectively), which define the address, length and type for each transfer. Besides these, the other parameters received are the transfer size, the number of bytes to be transferred on each request and the number of TCD structures to be used. This method will initialize all the descriptors according to user input and link them together; the linkage is done by writing the address of the next descriptor in the appropriate field of each one, similar to a linked-list data structure. The first descriptor is also copied to the TCD registers of the selected channel; if no errors are returned, after calling this function the channel is configured for the transfer defined by the first descriptor.

Channel Control

The eDMA driver provides functions that allow the user to start, stop, allocate and release an eDMA channel.
The EDMA_DRV_StartChannel() enables the DMA requests for a channel; this function should be called when the channel is already initialized, as the first request received after the function call will trigger the transfer based on the current values of the channel's TCD registers.
The EDMA_DRV_StopChannel() function disables requests for the selected channel; this function should be called whenever the application needs to ignore DMA requests for a channel. It is automatically called when the channel is released.
The EDMA_DRV_RequestChannel() function selects a channel to be used by application and updates the driver state structure accordingly. Two types of channel allocation are available:

The EDMA_DRV_ReleaseChannel() function frees the hw and sw resources allocated for that channel; it clears the channel state structure, updates the driver state and disables requests for that channel.

Important Notes

Data Structures

struct  edma_user_config_t
 The user configuration structure for the eDMA driver. More...
 
struct  edma_chn_state_t
 Data structure for the eDMA channel state. Implements : edma_chn_state_t_Class. More...
 
struct  edma_channel_config_t
 The user configuration structure for the an eDMA driver channel. More...
 
struct  edma_scatter_gather_list_t
 Data structure for configuring a discrete memory transfer. Implements : edma_scatter_gather_list_t_Class. More...
 
struct  edma_state_t
 Runtime state structure for the eDMA driver. More...
 
struct  edma_loop_transfer_config_t
 eDMA loop transfer configuration. More...
 
struct  edma_transfer_config_t
 eDMA transfer size configuration. More...
 
struct  edma_software_tcd_t
 eDMA TCD Implements : edma_software_tcd_t_Class More...
 

Macros

#define STCD_SIZE(number)    (((number) * 32U) - 1U)
 Macro for the memory size needed for the software TCD. More...
 
#define STCD_ADDR(address)    (((uint32_t)address + 31UL) & ~0x1FUL)
 
#define EDMA_ERR_LSB_MASK   1U
 Macro for accessing the least significant bit of the ERR register. More...
 

Typedefs

typedef void(* edma_callback_t) (void *parameter, edma_chn_status_t status)
 Definition for the eDMA channel callback function. More...
 

Enumerations

enum  edma_chn_status_t { EDMA_CHN_NORMAL = 0U, EDMA_CHN_IDLE, EDMA_CHN_ERROR }
 Channel status for eDMA channel. More...
 
enum  edma_transfer_type_t { EDMA_TRANSFER_PERIPH2MEM, EDMA_TRANSFER_MEM2PERIPH, EDMA_TRANSFER_MEM2MEM }
 A type for the DMA transfer. Implements : edma_transfer_type_t_Class. More...
 

Variables

DMA_Type *const g_edmaBase [DMA_INSTANCE_COUNT]
 Array for the eDMA module register base address. More...
 
DMAMUX_Type *const g_dmamuxBase [DMAMUX_INSTANCE_COUNT]
 Array for DMAMUX module register base address. More...
 
const IRQn_Type g_edmaIrqId [FEATURE_CHANNEL_INTERRUPT_LINES]
 Array for eDMA channel interrupt vector number. More...
 
const clock_names_t g_edmaClockNames [DMA_INSTANCE_COUNT]
 Array for eDMA clock sources. More...
 
const clock_names_t g_dmamuxClockNames [DMAMUX_INSTANCE_COUNT]
 
const IRQn_Type g_edmaErrIrqId [FEATURE_ERROR_INTERRUPT_LINES]
 Array for eDMA module's error interrupt vector number. More...
 

eDMA peripheral driver module level functions

status_t EDMA_DRV_Init (edma_state_t *edmaState, const edma_user_config_t *userConfig, edma_chn_state_t *const chnStateArray[], const edma_channel_config_t *const chnConfigArray[], uint8_t chnCount)
 Initializes the eDMA module. More...
 
status_t EDMA_DRV_Deinit (void)
 De-initializes the eDMA module. More...
 

eDMA peripheral driver channel management functions

status_t EDMA_DRV_ChannelInit (edma_chn_state_t *edmaChannelState, const edma_channel_config_t *edmaChannelConfig)
 Initializes an eDMA channel. More...
 
status_t EDMA_DRV_ReleaseChannel (uint8_t channel)
 Releases an eDMA channel. More...
 

eDMA peripheral driver transfer setup functions

void EDMA_DRV_PushConfigToReg (uint8_t channel, const edma_transfer_config_t *tcd)
 Copies the channel configuration to the TCD registers. More...
 
void EDMA_DRV_PushConfigToSTCD (const edma_transfer_config_t *config, edma_software_tcd_t *stcd)
 Copies the channel configuration to the software TCD structure. More...
 
status_t EDMA_DRV_ConfigSingleBlockTransfer (uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t dataBufferSize)
 Configures a simple single block data transfer with DMA. More...
 
status_t EDMA_DRV_ConfigLoopTransfer (uint8_t channel, const edma_transfer_config_t *transferConfig)
 Configures the DMA transfer in loop mode. More...
 
status_t EDMA_DRV_ConfigScatterGatherTransfer (uint8_t channel, edma_software_tcd_t *stcd, edma_transfer_size_t transferSize, uint32_t bytesOnEachRequest, const edma_scatter_gather_list_t *srcList, const edma_scatter_gather_list_t *destList, uint8_t tcdCount)
 Configures the DMA transfer in a scatter-gather mode. More...
 

eDMA Peripheral driver channel operation functions

status_t EDMA_DRV_StartChannel (uint8_t channel)
 Starts an eDMA channel. More...
 
status_t EDMA_DRV_StopChannel (uint8_t channel)
 Stops the eDMA channel. More...
 

eDMA Peripheral callback and interrupt functions

status_t EDMA_DRV_InstallCallback (uint8_t channel, edma_callback_t callback, void *parameter)
 Registers the callback function and the parameter for eDMA channel. More...
 

eDMA Peripheral driver miscellaneous functions

edma_chn_status_t EDMA_DRV_GetChannelStatus (uint8_t channel)
 Gets the eDMA channel status. More...
 

Macro Definition Documentation

#define EDMA_ERR_LSB_MASK   1U

Macro for accessing the least significant bit of the ERR register.

The erroneous channels are retrieved from ERR register by subsequently right shifting all the ERR bits + "AND"-ing the result with this mask.

Definition at line 98 of file edma_driver.h.

#define STCD_ADDR (   address)    (((uint32_t)address + 31UL) & ~0x1FUL)

Definition at line 90 of file edma_driver.h.

#define STCD_SIZE (   number)    (((number) * 32U) - 1U)

Macro for the memory size needed for the software TCD.

Software TCD is aligned to 32 bytes. We don't need a software TCD structure for the first descriptor, since the configuration is pushed directly to registers. To make sure the software TCD can meet the eDMA module requirement regarding alignment, allocate memory for the remaining descriptors with extra 31 bytes.

Definition at line 89 of file edma_driver.h.

Typedef Documentation

typedef void(* edma_callback_t) (void *parameter, edma_chn_status_t status)

Definition for the eDMA channel callback function.

Prototype for the callback function registered in the eDMA driver. Implements : edma_callback_t_Class

Definition at line 137 of file edma_driver.h.

Enumeration Type Documentation

Channel status for eDMA channel.

A structure describing the eDMA channel status. The user can get the status by callback parameter or by calling EDMA_DRV_getStatus() function. Implements : edma_chn_status_t_Class

Enumerator
EDMA_CHN_NORMAL 

eDMA channel is occupied.

EDMA_CHN_IDLE 

eDMA channel is idle.

EDMA_CHN_ERROR 

An error occurs in the eDMA channel.

Definition at line 125 of file edma_driver.h.

A type for the DMA transfer. Implements : edma_transfer_type_t_Class.

Enumerator
EDMA_TRANSFER_PERIPH2MEM 

Transfer from peripheral to memory

EDMA_TRANSFER_MEM2PERIPH 

Transfer from memory to peripheral

EDMA_TRANSFER_MEM2MEM 

Transfer from memory to memory

Definition at line 170 of file edma_driver.h.

Function Documentation

status_t EDMA_DRV_ChannelInit ( edma_chn_state_t edmaChannelState,
const edma_channel_config_t edmaChannelConfig 
)

Initializes an eDMA channel.

This function initializes the run-time state structure for a eDMA channel, based on user configuration. It will request the channel, set up the channel priority and install the callback.

Parameters
edmaChannelStatePointer to the eDMA channel state structure. The user passes the memory for this run-time state structure and the eDMA peripheral driver populates the members. This run-time state structure keeps track of the eDMA channel status. The memory must be kept valid before calling the EDMA_DRV_ReleaseChannel.
edmaChannelConfigUser configuration structure for eDMA channel. The user populates the members of this structure and passes the pointer of this structure into the function.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 246 of file edma_driver.c.

status_t EDMA_DRV_ConfigLoopTransfer ( uint8_t  channel,
const edma_transfer_config_t transferConfig 
)

Configures the DMA transfer in loop mode.

This function configures the DMA transfer in a loop chain. The user passes a block of memory into this function that configures the loop transfer properties (minor/major loop count, address offsets, channel linking). The DMA driver copies the configuration to TCD registers, only when the loop properties are set up correctly and minor loop mapping is enabled for the eDMA module.

Parameters
chnPointer to the channel state structure.
transferConfigPointer to the transfer configuration strucutre; this structure defines fields for setting up the basic transfer and also a pointer to a memory strucure that defines the loop chain properties (minor/major).
Returns
STATUS_ERROR or STATUS_SUCCESS

Definition at line 577 of file edma_driver.c.

status_t EDMA_DRV_ConfigScatterGatherTransfer ( uint8_t  channel,
edma_software_tcd_t stcd,
edma_transfer_size_t  transferSize,
uint32_t  bytesOnEachRequest,
const edma_scatter_gather_list_t srcList,
const edma_scatter_gather_list_t destList,
uint8_t  tcdCount 
)

Configures the DMA transfer in a scatter-gather mode.

This function configures the descriptors into a single-ended chain. The user passes blocks of memory into this function. The interrupt is triggered only when the last memory block is completed. The memory block information is passed with the edma_scatter_gather_list_t data structure, which can tell the memory address and length. The DMA driver configures the descriptor for each memory block, transfers the descriptor from the first one to the last one, and stops.

Parameters
chnPointer to the channel state structure.
stcdArray of empty software TCD structures. The user must prepare this memory block. We don't need a software TCD structure for the first descriptor, since the configuration is pushed directly to registers.The "stcd" buffer must align with 32 bytes; if not, an error occurs in the eDMA driver. Thus, the required memory size for "stcd" is equal to tcdCount * size_of(edma_software_tcd_t) - 1; the driver will take care of the memory alignment if the provided memory buffer is big enough. For proper allocation of the "stcd" buffer it is recommended to use STCD_SIZE macro.
transferSizeThe number of bytes to be transferred on every DMA write/read.
bytesOnEachRequestBytes to be transferred in each DMA request.
srcListData structure storing the address, length and type of transfer (M->M, M->P, P->M) for the bytes to be transferred for source memory blocks. If the source memory is peripheral, the length is not used.
destListData structure storing the address, length and type of transfer (M->M, M->P, P->M) for the bytes to be transferred for destination memory blocks. In the memory-to-memory transfer mode, the user must ensure that the length of the destination scatter gather list is equal to the source scatter gather list. If the destination memory is a peripheral register, the length is not used.
tcdCountThe number of TCD memory blocks contained in the scatter gather list.
Returns
STATUS_ERROR or STATUS_SUCCESS

Definition at line 614 of file edma_driver.c.

status_t EDMA_DRV_ConfigSingleBlockTransfer ( uint8_t  channel,
edma_transfer_type_t  type,
uint32_t  srcAddr,
uint32_t  destAddr,
edma_transfer_size_t  transferSize,
uint32_t  dataBufferSize 
)

Configures a simple single block data transfer with DMA.

This function configures the descriptor for a single block transfer. The function considers contiguous memory blocks, thus it configures the TCD source/destination offset fields to cover the data buffer without gaps, according to "transferSize" parameter (the offset is equal to the number of bytes transferred in a source read/destination write).

NOTE: For memory-to-peripheral or peripheral-to-memory transfers, make sure the transfer size is equal to the data buffer size of the peripheral used, otherwise only truncated chunks of data may be transferred (e.g. for a communication IP with an 8-bit data register the transfer size should be 1B, whereas for a 32-bit data register, the transfer size should be 4B). The rationale of this constraint is that, on the peripheral side, the address offset is set to zero, allowing to read/write data from/to the peripheral in a single source read/destination write operation.

Parameters
chnPointer to the channel state structure.
typeTransfer type (M->M, P->M, M->P).
srcAddrA source register address or a source memory address.
destAddrA destination register address or a destination memory address.
transferSizeThe number of bytes to be transferred on every DMA write/read. Source/Dest share the same write/read size.
dataBufferSizeThe total number of bytes to be transferred.
Returns
STATUS_ERROR or STATUS_SUCCESS

Definition at line 487 of file edma_driver.c.

status_t EDMA_DRV_Deinit ( void  )

De-initializes the eDMA module.

This function resets the eDMA module to reset state and disables the interrupt to the core.

Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 199 of file edma_driver.c.

edma_chn_status_t EDMA_DRV_GetChannelStatus ( uint8_t  channel)

Gets the eDMA channel status.

Parameters
chnChannel number.
Returns
Channel status.

Definition at line 953 of file edma_driver.c.

status_t EDMA_DRV_Init ( edma_state_t edmaState,
const edma_user_config_t userConfig,
edma_chn_state_t *const  chnStateArray[],
const edma_channel_config_t *const  chnConfigArray[],
uint8_t  chnCount 
)

Initializes the eDMA module.

This function initializes the run-time state structure to provide the eDMA channel allocation release, protect, and track the state for channels. This function also resets the eDMA modules, initializes the module to user-defined settings and default settings.

Parameters
edmaStateThe pointer to the eDMA peripheral driver state structure. The user passes the memory for this run-time state structure and the eDMA peripheral driver populates the members. This run-time state structure keeps track of the eDMA channels status. The memory must be kept valid before calling the EDMA_DRV_DeInit.
userConfigUser configuration structure for eDMA peripheral drivers. The user populates the members of this structure and passes the pointer of this structure into the function.
chnStateArrayArray of pointers to run-time state structures for eDMA channels; will populate the state structures inside the eDMA driver state structure.
chnConfigArrayArray of pointers to channel initialization structures.
chnCountThe number of eDMA channels to be initialized.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 91 of file edma_driver.c.

status_t EDMA_DRV_InstallCallback ( uint8_t  channel,
edma_callback_t  callback,
void *  parameter 
)

Registers the callback function and the parameter for eDMA channel.

This function registers the callback function and the parameter into the eDMA channel state structure. The callback function is called when the channel is complete or a channel error occurs. The eDMA driver passes the channel status to this callback function to indicate whether it is caused by the channel complete event or the channel error event.

To un-register the callback function, set the callback function to "NULL" and call this function.

Parameters
chnThe pointer to the channel state structure.
callbackThe pointer to the callback function.
parameterThe pointer to the callback function's parameter.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 285 of file edma_driver.c.

void EDMA_DRV_PushConfigToReg ( uint8_t  channel,
const edma_transfer_config_t tcd 
)

Copies the channel configuration to the TCD registers.

Parameters
chnPointer to the channel state structure.
configPointer to the channel configuration structure.

Definition at line 853 of file edma_driver.c.

void EDMA_DRV_PushConfigToSTCD ( const edma_transfer_config_t config,
edma_software_tcd_t stcd 
)

Copies the channel configuration to the software TCD structure.

This function copies the properties from the channel configuration to the software TCD structure; the address of the software TCD can be used to enable scatter/gather operation (pointer to the next TCD).

Parameters
chnPointer to the channel state structure.
configPointer to the channel configuration structure.
stcdPointer to the software TCD structure.

Definition at line 815 of file edma_driver.c.

status_t EDMA_DRV_ReleaseChannel ( uint8_t  channel)

Releases an eDMA channel.

This function stops the eDMA channel and disables the interrupt of this channel. The channel state structure can be released after this function is called.

Parameters
chnThe pointer to the channel state structure.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 359 of file edma_driver.c.

status_t EDMA_DRV_StartChannel ( uint8_t  channel)

Starts an eDMA channel.

This function enables the eDMA channel DMA request.

Parameters
chnPointer to the channel state structure.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 765 of file edma_driver.c.

status_t EDMA_DRV_StopChannel ( uint8_t  channel)

Stops the eDMA channel.

This function disables the eDMA channel DMA request.

Parameters
chnPointer to the channel state structure.
Returns
STATUS_ERROR or STATUS_SUCCESS.

Definition at line 790 of file edma_driver.c.

Variable Documentation

DMAMUX_Type* const g_dmamuxBase[DMAMUX_INSTANCE_COUNT]

Array for DMAMUX module register base address.

Definition at line 50 of file edma_common.c.

const clock_names_t g_dmamuxClockNames[DMAMUX_INSTANCE_COUNT]

Definition at line 62 of file edma_common.c.

DMA_Type* const g_edmaBase[DMA_INSTANCE_COUNT]

Array for the eDMA module register base address.

Definition at line 47 of file edma_common.c.

const clock_names_t g_edmaClockNames[DMA_INSTANCE_COUNT]

Array for eDMA clock sources.

Array for eDMA & DMAMUX clock sources.

Definition at line 61 of file edma_common.c.

Array for eDMA module's error interrupt vector number.

Definition at line 57 of file edma_common.c.

Array for eDMA channel interrupt vector number.

Definition at line 53 of file edma_common.c.