Hardware Abstraction Layer (HAL)
DMA (Direct Memory Access)

General Description

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 can be triggered by software or hardware. Multiple channels can be active at the same time each with their own user-selectable priority and transfer characteristics.

Features

Flow

The operational flow of the driver is listed below. This shows the basic order in which each of the functions would generally be called. While Initialize must always be first and Release always last, with care, the other functions can be reordered based on the implementation needs.

  1. Initialize: cyhal_dma_init or cyhal_dma_init_adv or cyhal_dma_init_cfg
  2. Configure: cyhal_dma_configure
  3. Setup: cyhal_dma_register_callback, cyhal_dma_enable_event, cyhal_dma_connect_digital, or cyhal_dma_enable_output
  4. Enable: cyhal_dma_enable
  5. Trigger: cyhal_dma_start_transfer or via a hardware signal
  6. Status/ReEnable (optional): cyhal_dma_is_busy, cyhal_dma_enable
  7. Cleanup (optional): cyhal_dma_disable, cyhal_dma_enable_event, cyhal_dma_disconnect_digital, or cyhal_dma_disable_output
  8. Release (optional): cyhal_dma_free

Quick Start

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.

Code snippets

Note
Error handling code has been intentionally left out of snippets to highlight API usage.

Snippet 1: Simple DMA initialization and transfer

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

cy_rslt_t rslt;
{
.src_addr = 0x8000000, // Start from address
.src_increment = 1, // Increment source by 1 word
.dst_addr = 0x8001000, // Destination from address
.dst_increment = 1, // Increment destination by 1 word
.transfer_width = 32, // 32 bit transfer
.length = 0x10, // Transfer 64 bytes (16 transfers of 4 bytes)
.burst_size = 0, // Transfer everything in a single burst
.action = CYHAL_DMA_TRANSFER_FULL, // Notify when everything is done
};
// Allocate the DMA channel for use
// Configure the channel for the upcoming transfer
rslt = cyhal_dma_configure(&dma, &cfg);
// Begin the transfer
// If the DMA channel is no longer needed, it can be freed up for other uses
if (!cyhal_dma_is_busy(&dma))
{
}
uint32_t src_addr
Source address. Some devices can apply special requirements for user data arrays. Please refer to imp...
Definition: cyhal_dma.h:263
bool cyhal_dma_is_busy(cyhal_dma_t *obj)
Checks if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running)
void cyhal_dma_free(cyhal_dma_t *obj)
Free the DMA object.
#define cyhal_dma_init(obj, priority, direction)
Initialize the DMA peripheral.
Definition: cyhal_dma.h:328
cy_rslt_t cyhal_dma_configure(cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg)
Setup the DMA channel behavior.
cy_rslt_t cyhal_dma_start_transfer(cyhal_dma_t *obj)
Initiates DMA channel transfer for specified DMA object.
@ CYHAL_DMA_TRANSFER_FULL
All bursts are triggered and a single CYHAL_DMA_TRANSFER_COMPLETE will occur at the end.
Definition: cyhal_dma.h:249
@ CYHAL_DMA_DIRECTION_MEM2MEM
Memory to memory.
Definition: cyhal_dma.h:184
Configuration of a DMA channel.
Definition: cyhal_dma.h:262
#define CYHAL_DMA_PRIORITY_DEFAULT
Default DMA channel priority.
Definition: cyhal_dma_impl.h:66
DMA object.
Definition: cyhal_hw_types.h:216
uint32_t cy_rslt_t
Provides the result of an operation as a structured bitfield.
Definition: cy_result.h:426

Snippet 2: Configuring the DMA channel based on memory requirements

cyhal_dma_configure can be used after DMA initialization to handle a variety of memory layouts.

#define BUFFER_SIZE (32)
#define PERIPHERAL_FIFO_ADDR (0x4001000)
cy_rslt_t rslt;
uint32_t buffer[BUFFER_SIZE];
// Allocate the DMA channel for transfering from memory to a peripheral
{
.src_addr = (uint32_t)buffer, // Start from address
.src_increment = 1, // Increment source by 1 word
.dst_addr = PERIPHERAL_FIFO_ADDR, // Destination from address
.dst_increment = 0, // Don't increment the destination
.transfer_width = 32, // 32 bit transfer
.length = BUFFER_SIZE, // Transfer 64 bytes (16 transfers of 4 bytes)
.burst_size = 0, // Transfer everything in a single burst
.action = CYHAL_DMA_TRANSFER_FULL, // Notify when everything is done
};
rslt = cyhal_dma_configure(&dma, &cfg);
@ CYHAL_DMA_DIRECTION_MEM2PERIPH
Memory to peripheral.
Definition: cyhal_dma.h:185

Snippet 3: Interrupts and retriggering DMA transfers

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().

void dma_event_callback(void* callback_arg, cyhal_dma_event_t event)
{
CY_UNUSED_PARAMETER(event);
cyhal_dma_t* dma = (cyhal_dma_t*)callback_arg;
// Do work specific to each burst complete
// If all bursts are complete, start another
if (!cyhal_dma_is_busy(dma))
{
}
}
cy_rslt_t snippet_cyhal_dma_events()
{
cy_rslt_t rslt;
{
.src_addr = 0x8000000, // Start from address
.src_increment = 1, // Increment source by 1 word
.dst_addr = 0x8001000, // Destination from address
.dst_increment = 1, // Increment destination by 1 word
.transfer_width = 32, // 32 bit transfer
.length = 0x10, // Transfer 64 bytes (16 transfers of 4 bytes)
.burst_size = 4, // Transfer 4 words a a time
.action = CYHAL_DMA_TRANSFER_BURST, // Notify when each burst is done
};
// Allocate the DMA channel for use
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
// Configure the channel for the upcoming transfer
if (CY_RSLT_SUCCESS == rslt)
{
rslt = cyhal_dma_configure(&dma, &cfg);
}
// Register an event callback handler and enable events
if (CY_RSLT_SUCCESS == rslt)
{
cyhal_dma_register_callback(&dma, &dma_event_callback, &dma);
// Begin the transfer
}
return rslt;
}
void cyhal_dma_register_callback(cyhal_dma_t *obj, cyhal_dma_event_callback_t callback, void *callback_arg)
Register a DMA callback handler.
void cyhal_dma_enable_event(cyhal_dma_t *obj, cyhal_dma_event_t event, uint8_t intr_priority, bool enable)
Configure DMA event enablement.
cyhal_dma_event_t
Flags enum of DMA events.
Definition: cyhal_dma.h:193
@ CYHAL_DMA_TRANSFER_BURST
A single burst is triggered and a CYHAL_DMA_TRANSFER_COMPLETE will occur after each burst.
Definition: cyhal_dma.h:246
@ CYHAL_DMA_TRANSFER_COMPLETE
Indicates that an individual transfer (burst or full) has completed based on the specified cyhal_dma_...
Definition: cyhal_dma.h:195
#define CYHAL_DMA_PRIORITY_LOW
Low DMA channel priority.
Definition: cyhal_dma_impl.h:72
#define CYHAL_ISR_PRIORITY_DEFAULT
Priority that is applied by default to all drivers when initialized.
Definition: cyhal_hw_types.h:114
#define CY_RSLT_SUCCESS
cy_rslt_t return value indicating success
Definition: cy_result.h:453

Snippet 4: Using hardware signals with DMA

DMA operations can be initiated by a hardware signal, or initiate a hardware signal on completion.
This snippet shows how either can be done with a timer object.

Note
Not all devices have the same internal connections. As a result, it may not be possible to setup connections exactly as shown in the snippet on your device.

In the first case, the DMA output signal (cyhal_dma_enable_output) is used so that when the DMA operation complets it in turn causes the timer to run.
NOTE: The cyhal_dma_init_adv can also be used insted of cyhal_dma_enable_output to enable the output. The advantage of using init_adv is it makes sure the DMA instance that is allocated is able to connected to the specified signal.

rslt = cyhal_dma_configure(&dma, &dma_config);
// starting the DMA transfers data and then starts the timer
//CY_ASSERT(cyhal_timer_read(&timer) == 0); // timer not started
while (cyhal_dma_is_busy(&dma))
{
}
// DMA completed, and timer has started
//CY_ASSERT(src == dst);
//CY_ASSERT(cyhal_timer_read(&timer) > 0);
cy_rslt_t cyhal_dma_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source)
Enables the specified output signal from a DMA channel that is triggered when a transfer is completed...
@ CYHAL_DMA_DIRECTION_PERIPH2PERIPH
Peripheral to peripheral.
Definition: cyhal_dma.h:187
@ CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS
Trigger an output when all elements are transferred.
Definition: cyhal_dma.h:221
cy_rslt_t cyhal_system_delay_ms(uint32_t milliseconds)
Requests that the current operation delays for at least the specified length of time.
cy_rslt_t cyhal_timer_connect_digital(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal)
Connects a source signal and configures and enables a timer event to be triggered from that signal.
@ CYHAL_TIMER_INPUT_START
Start signal.
Definition: cyhal_timer.h:146

The second snippet shows how a timer overflow can be used to trigger a DMA operation. It uses cyhal_dma_init_adv to setup the connection, but cyhal_dma_connect_digital could be used instead; with the same note as above about ensuring a connection between instances.

cyhal_dma_src_t dma_src =
{
.source = source,
};
rslt = cyhal_dma_init_adv(&dma, &dma_src, NULL, NULL, 1, CYHAL_DMA_DIRECTION_PERIPH2MEM);
rslt = cyhal_dma_configure(&dma, &dma_config);
//CY_ASSERT(src != dst); // values do not match before DMA
cyhal_timer_start(&timer); // start the timer that will trigger DMA
cyhal_system_delay_ms(100); // give plenty of time for timer and DMA to finish
//CY_ASSERT(src == dst); // values now match after DMA finishes
cyhal_source_t source
Source of signal to DMA; obtained from another driver's cyhal_<PERIPH>_enable_output.
Definition: cyhal_dma.h:279
cy_rslt_t cyhal_dma_init_adv(cyhal_dma_t *obj, cyhal_dma_src_t *src, cyhal_dma_dest_t *dest, cyhal_source_t *dest_source, uint8_t priority, cyhal_dma_direction_t direction)
Initialize the DMA peripheral.
@ CYHAL_DMA_DIRECTION_PERIPH2MEM
Peripheral to memory.
Definition: cyhal_dma.h:186
@ CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS
Transfer all elements when an input signal is received.
Definition: cyhal_dma.h:213
DMA input connection information to setup while initializing the driver.
Definition: cyhal_dma.h:278
cy_rslt_t cyhal_timer_enable_output(cyhal_timer_t *obj, cyhal_timer_output_t signal, cyhal_source_t *source)
Enables the specified output signal from a tcpwm that will be triggered when the corresponding event ...
cy_rslt_t cyhal_timer_start(cyhal_timer_t *obj)
Starts the timer/counter with the pre-set configuration from cyhal_timer_configure.
@ CYHAL_TIMER_OUTPUT_OVERFLOW
Overflow signal.
Definition: cyhal_timer.h:156

Snippet 5: DMA transfers with D-cache

If CPU D-cache is enabled, DMA transfers must be handled using cache management API when dealing with cacheable memory in order to maintain CPU data cache coherency. Regarding the CPU data cache coherence with DMA, the general rules are,

The following snippet initializes a DMA channel and uses it to transfer a single block from one cacheable memory to another cacheable memory. Cleaning D-cache of DMA descriptor is done by calling cyhal_dma_configure. Cleaning D-cache of source's buffer and Invalidating D-cache of destination's buffer should be done explicitly.

Refer to DCACHE_Management for more information.

#define BUFFER_SIZE (32) /* multiple of cache line size */
CY_ALIGN(__SCB_DCACHE_LINE_SIZE) uint32_t tx_buffer[BUFFER_SIZE];
CY_ALIGN(__SCB_DCACHE_LINE_SIZE) uint32_t rx_buffer[BUFFER_SIZE]; /* Memory address should be
cacheline-aligned */
void snippet_cyhal_dma_with_dcache()
{
cy_rslt_t rslt;
// Allocate the DMA channel for transfering from memory to memory
{
.src_addr = (uint32_t)tx_buffer, // Start from address
.src_increment = 1, // Increment source by 1 word
.dst_addr = (uint32_t)rx_buffer, // Destination from address
.dst_increment = 1, // Don't increment the destination
.transfer_width = 32, // 32 bit transfer
.length = BUFFER_SIZE, // Transfer 64 bytes (16 transfers of 4 bytes)
.burst_size = 0, // Transfer everything in a single burst
.action = CYHAL_DMA_TRANSFER_FULL, // Notify when everything is done
};
/* cyhal_dma_configure will do clean dcache of DMA descriptor. */
rslt = cyhal_dma_configure(&dma, &cfg);
/* Before enabling DMA channel, clean dcahe of tx_buffer. */
SCB_CleanDCache_by_Addr((void*)tx_buffer, BUFFER_SIZE * sizeof(uint32_t));
SCB_CleanDCache_by_Addr((void*)rx_buffer, BUFFER_SIZE * sizeof(uint32_t)); /* This maybe
optional. */
rslt = cyhal_dma_enable(&dma);
/* Before reading rx_buffer, invalidate dcache of rx_buffer. */
SCB_InvalidateDCache_by_Addr((void*)rx_buffer, BUFFER_SIZE * sizeof(uint32_t));
cy_rslt_t cyhal_dma_enable(cyhal_dma_t *obj)
Enable the DMA transfer so that it can start transferring data when triggered.

API Reference

 DMA HAL Results
 DMA specific return codes.
 

Data Structures

struct  cyhal_dma_cfg_t
 Configuration of a DMA channel. More...
 
struct  cyhal_dma_src_t
 DMA input connection information to setup while initializing the driver. More...
 
struct  cyhal_dma_dest_t
 DMA output connection information to setup while initializing the driver. More...
 

Macros

#define cyhal_dma_init(obj, priority, direction)   (cyhal_dma_init_adv(obj, NULL, NULL, NULL, priority, direction))
 Initialize the DMA peripheral. 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_DESCRIPTOR_COMPLETE = 1 << 1 ,
  CYHAL_DMA_SRC_BUS_ERROR = 1 << 2 ,
  CYHAL_DMA_DST_BUS_ERROR = 1 << 3 ,
  CYHAL_DMA_SRC_MISAL = 1 << 4 ,
  CYHAL_DMA_DST_MISAL = 1 << 5 ,
  CYHAL_DMA_CURR_PTR_NULL = 1 << 6 ,
  CYHAL_DMA_ACTIVE_CH_DISABLED = 1 << 7 ,
  CYHAL_DMA_DESCR_BUS_ERROR = 1 << 8
}
 Flags enum of DMA events. More...
 
enum  cyhal_dma_input_t {
  CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT ,
  CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST ,
  CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS
}
 Specifies the transfer type to trigger when an input signal is received. More...
 
enum  cyhal_dma_output_t {
  CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT ,
  CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST ,
  CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS
}
 Specifies the transfer completion event that triggers a signal output. More...
 
enum  cyhal_dma_transfer_action_t {
  CYHAL_DMA_TRANSFER_BURST ,
  CYHAL_DMA_TRANSFER_FULL ,
  CYHAL_DMA_TRANSFER_BURST_DISABLE ,
  CYHAL_DMA_TRANSFER_FULL_DISABLE
}
 This defines the behavior of the the channel when transfers are initiated. More...
 

Functions

cy_rslt_t cyhal_dma_init_adv (cyhal_dma_t *obj, cyhal_dma_src_t *src, cyhal_dma_dest_t *dest, cyhal_source_t *dest_source, uint8_t priority, cyhal_dma_direction_t direction)
 Initialize the DMA peripheral. More...
 
cy_rslt_t cyhal_dma_init_cfg (cyhal_dma_t *obj, const cyhal_dma_configurator_t *cfg)
 Initialize the DMA peripheral using data provided by the configurator. 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 the DMA channel behavior. More...
 
cy_rslt_t cyhal_dma_enable (cyhal_dma_t *obj)
 Enable the DMA transfer so that it can start transferring data when triggered. More...
 
cy_rslt_t cyhal_dma_disable (cyhal_dma_t *obj)
 Disable the DMA transfer so that it does not continue to trigger. 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 if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running) 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...
 
cy_rslt_t cyhal_dma_connect_digital (cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
 Connects a source signal and enables the specified input to the DMA channel. More...
 
cy_rslt_t cyhal_dma_enable_output (cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source)
 Enables the specified output signal from a DMA channel that is triggered when a transfer is completed. More...
 
cy_rslt_t cyhal_dma_disconnect_digital (cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input)
 Disconnects a source signal and disables the specified input to the DMA channel. More...
 
cy_rslt_t cyhal_dma_disable_output (cyhal_dma_t *obj, cyhal_dma_output_t output)
 Disables the specified output signal from a DMA channel. More...
 

Data Structure Documentation

◆ cyhal_dma_cfg_t

struct cyhal_dma_cfg_t
Data Fields
uint32_t src_addr Source address. Some devices can apply special requirements for user data arrays. Please refer to implementation-specific documentation to see whether any limitations exist for used device.
int16_t src_increment Source address auto increment amount in multiples of transfer_width.
uint32_t dst_addr Destination address. Some devices can apply special requirements for user data arrays. Please refer to implementation-specific documentation to see whether any limitations exist for used device.
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.

◆ cyhal_dma_src_t

struct cyhal_dma_src_t
Data Fields
cyhal_source_t source Source of signal to DMA; obtained from another driver's cyhal_<PERIPH>_enable_output.
cyhal_dma_input_t input DMA input signal to be driven.

◆ cyhal_dma_dest_t

struct cyhal_dma_dest_t
Data Fields
cyhal_dma_output_t output Output signal of DMA.
cyhal_dest_t dest Destination of DMA signal.

Macro Definition Documentation

◆ cyhal_dma_init

#define cyhal_dma_init (   obj,
  priority,
  direction 
)    (cyhal_dma_init_adv(obj, NULL, NULL, NULL, priority, direction))

Initialize the DMA peripheral.

Parameters
[out]objPointer to a DMA object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]priorityThe 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]directionThe direction memory is copied
Returns
The status of the init request

Enumeration Type Documentation

◆ cyhal_dma_direction_t

Direction for DMA transfers.

Enumerator
CYHAL_DMA_DIRECTION_MEM2MEM 

Memory to memory.

CYHAL_DMA_DIRECTION_MEM2PERIPH 

Memory to peripheral.

CYHAL_DMA_DIRECTION_PERIPH2MEM 

Peripheral to memory.

CYHAL_DMA_DIRECTION_PERIPH2PERIPH 

Peripheral to peripheral.

◆ cyhal_dma_event_t

Flags enum of DMA events.

Multiple events can be enabled via cyhal_dma_enable_event and the callback from cyhal_dma_register_callback will be run to notify.

Enumerator
CYHAL_DMA_NO_INTR 

No interrupt.

CYHAL_DMA_TRANSFER_COMPLETE 

Indicates that an individual transfer (burst or full) has completed based on the specified cyhal_dma_transfer_action_t.

CYHAL_DMA_DESCRIPTOR_COMPLETE 

Indicates that the full transfer has completed.

CYHAL_DMA_SRC_BUS_ERROR 

Indicates that there is a source bus error.

CYHAL_DMA_DST_BUS_ERROR 

Indicates that there is a destination bus error.

CYHAL_DMA_SRC_MISAL 

Indicates that the source address is not aligned.

CYHAL_DMA_DST_MISAL 

Indicates that the destination address is not aligned.

CYHAL_DMA_CURR_PTR_NULL 

Indicates that the current descriptor pointer is null.

CYHAL_DMA_ACTIVE_CH_DISABLED 

Indicates that the active channel is disabled.

CYHAL_DMA_DESCR_BUS_ERROR 

Indicates that there has been a descriptor bus error.

◆ cyhal_dma_input_t

Specifies the transfer type to trigger when an input signal is received.

Enumerator
CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT 

Transfer a single element when an input signal is received.

CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST 

Transfer a single burst when an input signal is received.

CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS 

Transfer all elements when an input signal is received.

◆ cyhal_dma_output_t

Specifies the transfer completion event that triggers a signal output.

Enumerator
CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT 

Trigger an output when a single element is transferred.

CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST 

Trigger an output when a single burst is transferred.

CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS 

Trigger an output when all elements are transferred.

◆ cyhal_dma_transfer_action_t

This defines the behavior of the the channel when transfers are initiated.

It can specify both how the transfer is broken up and what happens at the end of the transfer. If burst_size from cyhal_dma_cfg_t is used, this specifies the granularity of operations that occur. Using CYHAL_DMA_TRANSFER_BURST or CYHAL_DMA_TRANSFER_BURST_DISABLE means a single trigger will transfer a single burst (of burst_size) and raise the CYHAL_DMA_TRANSFER_COMPLETE interrupt. Using CYHAL_DMA_TRANSFER_FULL means a single trigger will transfer all bursts (total size length) and raise the CYHAL_DMA_TRANSFER_COMPLETE interrupt. If burst_size is not used, this has no impact and a single trigger will perform a complete transfer and raise a single interrupt at the end. When the transfer is complete, the channel can be left enabled, or automatically disabled. When left enabled (CYHAL_DMA_TRANSFER_BURST or CYHAL_DMA_TRANSFER_FULL) subsequent triggers will re-start the transfers. If the channel is diabled on completion (CYHAL_DMA_TRANSFER_BURST_DISABLE or CYHAL_DMA_TRANSFER_FULL_DISABLE), cyhal_dma_configure must be called to reconfigure the channel for future transfers.

Note
When using cyhal_dma_connect_digital for a hardware input trigger, the cyhal_dma_input_t argument defines how much of the transfer is initiated at a time. This enum will still define when interrupts are raised.
Enumerator
CYHAL_DMA_TRANSFER_BURST 

A single burst is triggered and a CYHAL_DMA_TRANSFER_COMPLETE will occur after each burst.

The channel will be left enabled and can continue to be triggered.

CYHAL_DMA_TRANSFER_FULL 

All bursts are triggered and a single CYHAL_DMA_TRANSFER_COMPLETE will occur at the end.

The channel will be left enabled and can continue to be triggered.

CYHAL_DMA_TRANSFER_BURST_DISABLE 

A single burst is triggered and a CYHAL_DMA_TRANSFER_COMPLETE will occur after each burst.

When all bursts are complete, the channel will be disabled.

CYHAL_DMA_TRANSFER_FULL_DISABLE 

All bursts are triggered and a single CYHAL_DMA_TRANSFER_COMPLETE will occur at the end.

When complete, the channel will be disabled.

Function Documentation

◆ cyhal_dma_init_adv()

cy_rslt_t cyhal_dma_init_adv ( cyhal_dma_t obj,
cyhal_dma_src_t src,
cyhal_dma_dest_t dest,
cyhal_source_t dest_source,
uint8_t  priority,
cyhal_dma_direction_t  direction 
)

Initialize the DMA peripheral.

If a source signal is provided for src, this will connect the provided signal to the DMA just as would be done by calling cyhal_dma_connect_digital. Similarly, if a destination target is provided for dest this will enable the specified output just as would be done by calling cyhal_dma_enable_output.

Parameters
[out]objPointer to a DMA object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]srcAn optional source signal to connect to the DMA
[in]destAn optional destination signal to drive from the DMA
[out]dest_sourceAn optional pointer to user-allocated source signal object which will be initialized by enable_output. If dest is non-null, this must also be non-null. dest_source should be passed to (dis)connect_digital functions to (dis)connect the associated endpoints.
[in]priorityThe 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]directionThe direction memory is copied
Returns
The status of the init request

◆ cyhal_dma_init_cfg()

cy_rslt_t cyhal_dma_init_cfg ( cyhal_dma_t obj,
const cyhal_dma_configurator_t cfg 
)

Initialize the DMA peripheral using data provided by the configurator.

Note
Depending on what the configurator allows filling it, it is likely that at least the source and destination addresses of the transfer(s) still need to be setup.
Parameters
[out]objPointer to a DMA object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]cfgConfiguration structure generated by a configurator.
Returns
The status of the init request

◆ cyhal_dma_free()

void cyhal_dma_free ( cyhal_dma_t obj)

Free the DMA object.

Freeing a DMA object while a transfer is in progress (cyhal_dma_is_busy) is invalid.

Parameters
[in,out]objThe DMA object

◆ cyhal_dma_configure()

cy_rslt_t cyhal_dma_configure ( cyhal_dma_t obj,
const cyhal_dma_cfg_t cfg 
)

Setup the DMA channel behavior.

This will also enable the channel to allow it to be triggered. The transfer can be software triggered by calling cyhal_dma_start_transfer or by hardware. A hardware input signal is setup by cyhal_dma_connect_digital or cyhal_dma_init_adv.

Note
If hardware triggers are used, any necessary event callback setup (cyhal_dma_register_callback and cyhal_dma_enable_event) should be done before calling this function to ensure the handlers are in place before the transfer can happen.
The automatic enablement of the channel as part of this function is expected to change in a future update. This would only happen on a new major release (eg: 1.0 -> 2.0).
If the DMA was setup using cyhal_dma_init_cfg, this function should not be used.
If D-cache is enabled, this function cleans D-cache of DMA descriptor.
Parameters
[in]objThe DMA object
[in]cfgConfiguration parameters for the transfer
Returns
The status of the configure request

◆ cyhal_dma_enable()

cy_rslt_t cyhal_dma_enable ( cyhal_dma_t obj)

Enable the DMA transfer so that it can start transferring data when triggered.

A trigger is caused either by calling cyhal_dma_start_transfer or by hardware as a result of a connection made in either cyhal_dma_connect_digital or cyhal_dma_init_adv. The DMA can be disabled by calling cyhal_dma_disable or by setting the cyhal_dma_cfg_t action to CYHAL_DMA_TRANSFER_BURST_DISABLE, or CYHAL_DMA_TRANSFER_FULL_DISABLE.

Parameters
[in]objThe DMA object
Returns
The status of the enable request

◆ cyhal_dma_disable()

cy_rslt_t cyhal_dma_disable ( cyhal_dma_t obj)

Disable the DMA transfer so that it does not continue to trigger.

It can be reenabled by calling cyhal_dma_enable or cyhal_dma_configure.

Parameters
[in]objThe DMA object
Returns
The status of the enable request

◆ cyhal_dma_start_transfer()

cy_rslt_t cyhal_dma_start_transfer ( cyhal_dma_t obj)

Initiates DMA channel transfer for specified DMA object.

This should only be done after the channel has been configured (cyhal_dma_configure) and any necessary event callbacks setup (cyhal_dma_register_callback cyhal_dma_enable_event)

Parameters
[in]objThe DMA object
Returns
The status of the start_transfer request

◆ cyhal_dma_is_busy()

bool cyhal_dma_is_busy ( cyhal_dma_t obj)

Checks if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running)

Parameters
[in]objThe DMA object
Returns
True if DMA channel is busy

◆ cyhal_dma_register_callback()

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.

Parameters
[in]objThe DMA object
[in]callbackThe callback handler which will be invoked when an event triggers
[in]callback_argGeneric argument that will be provided to the callback when called

◆ cyhal_dma_enable_event()

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.

Parameters
[in]objThe DMA object
[in]eventThe DMA event type
[in]intr_priorityThe 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]enableTrue to turn on interrupts, False to turn off

◆ cyhal_dma_connect_digital()

cy_rslt_t cyhal_dma_connect_digital ( cyhal_dma_t obj,
cyhal_source_t  source,
cyhal_dma_input_t  input 
)

Connects a source signal and enables the specified input to the DMA channel.

This connection can also be setup automatically on initialization via cyhal_dma_init_adv. If the signal needs to be disconnected later, cyhal_dma_disconnect_digital can be used.

Parameters
[in]objThe DMA object
[in]sourceSource signal obtained from another driver's cyhal_<PERIPH>_enable_output
[in]inputWhich input to enable
Returns
The status of the connection

◆ cyhal_dma_enable_output()

cy_rslt_t cyhal_dma_enable_output ( cyhal_dma_t obj,
cyhal_dma_output_t  output,
cyhal_source_t source 
)

Enables the specified output signal from a DMA channel that is triggered when a transfer is completed.

This can also be setup automatically on initialization via cyhal_dma_init_adv. If the output is not needed in the future, cyhal_dma_disable_output can be used.

Parameters
[in]objThe DMA object
[in]outputWhich event triggers the output
[out]sourcePointer to user-allocated source signal object which will be initialized by enable_output. source should be passed to (dis)connect_digital functions to (dis)connect the associated endpoints.
Returns
The status of the output enable

◆ cyhal_dma_disconnect_digital()

cy_rslt_t cyhal_dma_disconnect_digital ( cyhal_dma_t obj,
cyhal_source_t  source,
cyhal_dma_input_t  input 
)

Disconnects a source signal and disables the specified input to the DMA channel.

This removes the connection that was established by either cyhal_dma_init_adv or cyhal_dma_connect_digital.

Parameters
[in]objThe DMA object
[in]sourceSource signal from cyhal_<PERIPH>_enable_output to disable
[in]inputWhich input to disable
Returns
The status of the disconnect

◆ cyhal_dma_disable_output()

cy_rslt_t cyhal_dma_disable_output ( cyhal_dma_t obj,
cyhal_dma_output_t  output 
)

Disables the specified output signal from a DMA channel.

This turns off the signal that was enabled by either cyhal_dma_init_adv or cyhal_dma_enable_output. It is recommended that the signal is disconnected (cyhal_<PERIPH>_disconnect_digital) from anything it might be driving before being disabled.

Parameters
[in]objThe DMA object
[in]outputWhich output to disable
Returns
The status of the disablement