High level interface for interacting with the direct memory access (DMA).
The DMA driver allows for initializing and configuring a DMA channel in order to trigger data transfers to and from memory and peripherals. The transfers occur independently of the CPU and are triggered in software. Multiple channels are available with user-selectable priority and transfer characteristics.
See Snippet 1: Simple DMA initialization and transfer for a code snippet that sets up a DMA transfer to move memory from one location to another.
The following snippet initializes a DMA channel and uses it to transfer a a single block of memory. The DMA channel is reserved by calling cyhal_dma_init. It then needs to be configured with cyhal_dma_configure and then the transfer is started with cyhal_dma_start_transfer.
If the DMA channel is not needed anymore, it can be released by calling cyhal_dma_free
cyhal_dma_configure can be used after DMA initialization to handle a variety of memory layouts.
DMA events like transfer complete or error events can be used to trigger a callback function.
This snippet uses cyhal_dma_configure to break the full transfer into multiple bursts. This allows higher priority items access to the memory bus if necessary while the DMA operation is still in progress. It then uses cyhal_dma_enable_event() to enable the transfer complete event to trigger the callback function registered by cyhal_dma_register_callback().
API Reference | |
DMA HAL Results | |
DMA specific return codes. | |
Data Structures | |
struct | cyhal_dma_cfg_t |
Configuration of a DMA channel. More... | |
Typedefs | |
typedef void(* | cyhal_dma_event_callback_t) (void *callback_arg, cyhal_dma_event_t event) |
Event handler for DMA interrupts. | |
Enumerations | |
enum | cyhal_dma_direction_t { CYHAL_DMA_DIRECTION_MEM2MEM, CYHAL_DMA_DIRECTION_MEM2PERIPH, CYHAL_DMA_DIRECTION_PERIPH2MEM, CYHAL_DMA_DIRECTION_PERIPH2PERIPH } |
Direction for DMA transfers. More... | |
enum | cyhal_dma_event_t { CYHAL_DMA_NO_INTR = 0, CYHAL_DMA_TRANSFER_COMPLETE = 1 << 0, CYHAL_DMA_SRC_BUS_ERROR = 1 << 1, CYHAL_DMA_DST_BUS_ERROR = 1 << 2, CYHAL_DMA_SRC_MISAL = 1 << 3, CYHAL_DMA_DST_MISAL = 1 << 4, CYHAL_DMA_CURR_PTR_NULL = 1 << 5, CYHAL_DMA_ACTIVE_CH_DISABLED = 1 << 6, CYHAL_DMA_DESCR_BUS_ERROR = 1 << 7 } |
Flags enum of DMA events. More... | |
enum | cyhal_dma_transfer_action_t { CYHAL_DMA_TRANSFER_BURST, CYHAL_DMA_TRANSFER_FULL } |
If burst_size is used, selects whether a single trigger of the channel transfers a single burst of burst_size or a full transfer of size length (that is, every burst is triggered). More... | |
Functions | |
cy_rslt_t | cyhal_dma_init (cyhal_dma_t *obj, uint8_t priority, cyhal_dma_direction_t direction) |
Initialize the DMA peripheral. More... | |
void | cyhal_dma_free (cyhal_dma_t *obj) |
Free the DMA object. More... | |
cy_rslt_t | cyhal_dma_configure (cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg) |
Setup a DMA descriptor for specified resource. More... | |
cy_rslt_t | cyhal_dma_start_transfer (cyhal_dma_t *obj) |
Initiates DMA channel transfer for specified DMA object. More... | |
bool | cyhal_dma_is_busy (cyhal_dma_t *obj) |
Checks whether a transfer is pending or running on the DMA channel. More... | |
void | cyhal_dma_register_callback (cyhal_dma_t *obj, cyhal_dma_event_callback_t callback, void *callback_arg) |
Register a DMA callback handler. More... | |
void | cyhal_dma_enable_event (cyhal_dma_t *obj, cyhal_dma_event_t event, uint8_t intr_priority, bool enable) |
Configure DMA event enablement. More... | |
struct cyhal_dma_cfg_t |
Data Fields | ||
---|---|---|
uint32_t | src_addr | Source address. |
int16_t | src_increment | Source address auto increment amount in multiples of transfer_width. |
uint32_t | dst_addr | Destination address. |
int16_t | dst_increment | Destination address auto increment amount in multiples of transfer_width. |
uint8_t | transfer_width | Transfer width in bits. Valid values are: 8, 16, or 32. |
uint32_t | length | Number of elements to be transferred in total. |
uint32_t | burst_size | Number of elements to be transferred per trigger. If set to 0 every element is transferred, otherwise burst_size must evenly divide length. |
cyhal_dma_transfer_action_t | action | Sets the behavior of the channel when triggered (using start_transfer). Ignored if burst_size is not configured. |
enum cyhal_dma_event_t |
Flags enum of DMA events.
Multiple events can be enabled.
If burst_size is used, selects whether a single trigger of the channel transfers a single burst of burst_size or a full transfer of size length (that is, every burst is triggered).
This will also select when a trigger complete event will occur; after each burst or after the full transfer
cy_rslt_t cyhal_dma_init | ( | cyhal_dma_t * | obj, |
uint8_t | priority, | ||
cyhal_dma_direction_t | direction | ||
) |
Initialize the DMA peripheral.
[out] | obj | Pointer to a DMA object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | priority | The priority of this DMA operation relative to others. The number of priority levels which are supported is hardware dependent. All implementations define a CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will also define CYHAL_DMA_PRIORITY_HIGH, CYHAL_DMA_PRIORITY_MEDIUM, and CYHAL_DMA_PRIORITY_LOW. The behavior of any other value is implementation defined. See the implementation-specific DMA documentation for more details. |
[in] | direction | The direction memory is copied |
void cyhal_dma_free | ( | cyhal_dma_t * | obj | ) |
Free the DMA object.
Freeing a DMA object while a transfer is in progress (see cyhal_dma_is_busy) is invalid.
[in,out] | obj | The DMA object |
cy_rslt_t cyhal_dma_configure | ( | cyhal_dma_t * | obj, |
const cyhal_dma_cfg_t * | cfg | ||
) |
Setup a DMA descriptor for specified resource.
[in] | obj | The DMA object |
[in] | cfg | Configuration parameters for the transfer |
cy_rslt_t cyhal_dma_start_transfer | ( | cyhal_dma_t * | obj | ) |
Initiates DMA channel transfer for specified DMA object.
[in] | obj | The DMA object |
bool cyhal_dma_is_busy | ( | cyhal_dma_t * | obj | ) |
Checks whether a transfer is pending or running on the DMA channel.
[in] | obj | The DMA object |
void cyhal_dma_register_callback | ( | cyhal_dma_t * | obj, |
cyhal_dma_event_callback_t | callback, | ||
void * | callback_arg | ||
) |
Register a DMA callback handler.
This function will be called when one of the events enabled by cyhal_dma_enable_event occurs.
[in] | obj | The DMA object |
[in] | callback | The callback handler which will be invoked when an event triggers |
[in] | callback_arg | Generic argument that will be provided to the callback when called |
void cyhal_dma_enable_event | ( | cyhal_dma_t * | obj, |
cyhal_dma_event_t | event, | ||
uint8_t | intr_priority, | ||
bool | enable | ||
) |
Configure DMA event enablement.
When an enabled event occurs, the function specified by cyhal_dma_register_callback will be called.
[in] | obj | The DMA object |
[in] | event | The DMA event type |
[in] | intr_priority | The priority for NVIC interrupt events. The priority from the most recent call will take precedence, i.e all events will have the same priority. |
[in] | enable | True to turn on interrupts, False to turn off |