1 /***************************************************************************//**
2 * \file cyhal_dma.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon DMA.
6 * This interface abstracts out the chip specific details. If any chip specific
7 * functionality is necessary, or performance is critical the low level functions
8 * can be used directly.
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
13 * an affiliate of Cypress Semiconductor Corporation
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *******************************************************************************/
29 
30 /**
31  * \addtogroup group_hal_dma DMA (Direct Memory Access)
32  * \ingroup group_hal
33  * \{
34  * High level interface for interacting with the direct memory access (DMA). The DMA driver allows
35  * for initializing and configuring a DMA channel in order to trigger data transfers to and from
36  * memory and peripherals. The transfers occur independently of the CPU and can be triggered by
37  * software or hardware. Multiple channels can be active at the same time each with their own
38  * user-selectable priority and transfer characteristics.
39  *
40  * \section section_dma_features Features
41  * * CPU independent memory access
42  * * Access to memory and peripherals
43  * * Multiple independent channels
44  * * Configurable transer sizes and bursts
45  * * Configurable priorities
46  * * Event completion notification
47  *
48  * \section Usage Flow
49  * The operational flow of the driver is listed below. This shows the basic order in which each of
50  * the functions would generally be called. While Initialize must always be first and Release always
51  * last, with care, the other functions can be reordered based on the implementation needs.
52  * -# Initialize: \ref cyhal_dma_init or \ref cyhal_dma_init_adv or \ref cyhal_dma_init_cfg
53  * -# Configure: \ref cyhal_dma_configure
54  * -# Setup: \ref cyhal_dma_register_callback, \ref cyhal_dma_enable_event, \ref cyhal_dma_connect_digital, or \ref cyhal_dma_enable_output
55  * -# Enable: \ref cyhal_dma_enable
56  * -# Trigger: \ref cyhal_dma_start_transfer or via a hardware signal
57  * -# Status/ReEnable (optional): \ref cyhal_dma_is_busy, \ref cyhal_dma_enable
58  * -# Cleanup (optional): \ref cyhal_dma_disable, \ref cyhal_dma_enable_event, \ref cyhal_dma_disconnect_digital, or \ref cyhal_dma_disable_output
59  * -# Release (optional): \ref cyhal_dma_free
60  *
61  * \section section_dma_quickstart Quick Start
62  *
63  * See \ref subsection_dma_snippet_1 for a code snippet that sets up a DMA
64  * transfer to move memory from one location to another.
65  *
66  * \section section_dma_snippets Code snippets
67  * \note Error handling code has been intentionally left out of snippets to highlight API usage.
68  *
69  * \subsection subsection_dma_snippet_1 Snippet 1: Simple DMA initialization and transfer
70  * The following snippet initializes a DMA channel and uses it to transfer a a single block of memory.
71  * The DMA channel is reserved by calling \ref cyhal_dma_init. It then needs to be configured with
72  * \ref cyhal_dma_configure and then the transfer is started with \ref cyhal_dma_start_transfer.<br>
73  * If the DMA channel is not needed anymore, it can be released by calling \ref cyhal_dma_free
74  *
75  * \snippet hal_dma.c snippet_cyhal_dma_simple_init
76  *
77  *
78  * \subsection subsection_dma_snippet_2 Snippet 2: Configuring the DMA channel based on memory requirements
79  * \ref cyhal_dma_configure can be used after DMA initialization to handle a variety of memory layouts.
80  *
81  * \snippet hal_dma.c snippet_cyhal_dma_configure
82  *
83  *
84  * \subsection subsection_dma_snippet_3 Snippet 3: Interrupts and retriggering DMA transfers
85  * DMA events like transfer complete or error events can be used to trigger a callback function. <br>
86  * This snippet uses \ref cyhal_dma_configure to break the full transfer into multiple bursts. This
87  * allows higher priority items access to the memory bus if necessary while the DMA operation is still
88  * in progress. It then uses \ref cyhal_dma_enable_event() to enable the transfer complete event to
89  * trigger the callback function registered by \ref cyhal_dma_register_callback().
90  *
91  * \snippet hal_dma.c snippet_cyhal_dma_events
92  *
93  *
94  * \subsection subsection_dma_snippet_4 Snippet 4: Using hardware signals with DMA
95  * DMA operations can be initiated by a hardware signal, or initiate a hardware signal on completion.
96  * <br>This snippet shows how either can be done with a timer object.
97  * \note Not all devices have the same internal connections. As a result, it may not be possible to
98  * setup connections exactly as shown in the snippet on your device.
99  *
100  * In the first case, the DMA output signal (\ref cyhal_dma_enable_output) is used so that when the
101  * DMA operation complets it in turn causes the timer to run.
102  * <br>NOTE: The \ref cyhal_dma_init_adv can also be used insted of \ref cyhal_dma_enable_output to
103  * enable the output. The advantage of using init_adv is it makes sure the DMA instance that is
104  * allocated is able to connected to the specified signal.
105  *
106  * \snippet hal_dma.c snippet_cyhal_dma_triggers_output
107  *
108  * The second snippet shows how a timer overflow can be used to trigger a DMA operation. It uses
109  * \ref cyhal_dma_init_adv to setup the connection, but \ref cyhal_dma_connect_digital could be used
110  * instead; with the same note as above about ensuring a connection between instances.
111  *
112  * \snippet hal_dma.c snippet_cyhal_dma_triggers_input
113  */
114 
115 #pragma once
116 
117 #include <stdbool.h>
118 #include <stdint.h>
119 #include "cy_result.h"
120 #include "cyhal_hw_types.h"
121 
122 #if defined(__cplusplus)
123 extern "C" {
124 #endif
125 
126 /** \addtogroup group_hal_results_dma DMA HAL Results
127  *  DMA specific return codes
128  *  \ingroup group_hal_results
129  *  \{ *//**
130  */
131 
132 /** Invalid transfer width parameter error */
133 #define CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_WIDTH       \
134     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 0))
135 /** Invalid parameter error */
136 #define CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER            \
137     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 1))
138 /** Invalid priority parameter error */
139 #define CYHAL_DMA_RSLT_ERR_INVALID_PRIORITY             \
140     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 2))
141 /** Invalid src or dst addr alignment error */
142 #define CYHAL_DMA_RSLT_ERR_INVALID_ALIGNMENT            \
143     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 3))
144 /** Invalid burst_size paramenter error */
145 #define CYHAL_DMA_RSLT_ERR_INVALID_BURST_SIZE           \
146     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 4))
147 /** Channel busy error */
148 #define CYHAL_DMA_RSLT_ERR_CHANNEL_BUSY                 \
149     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 5))
150 /** Transfer has already been started warning */
151 #define CYHAL_DMA_RSLT_WARN_TRANSFER_ALREADY_STARTED    \
152     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_WARNING, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 6))
153 /** Unsupported hardware error */
154 #define CYHAL_DMA_RSLT_FATAL_UNSUPPORTED_HARDWARE       \
155     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_FATAL, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 7))
156 /** Requested transfer size is not supported */
157 #define CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_SIZE        \
158     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_FATAL, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 8))
159 
160 /**
161  * \}
162  */
163 
164 /** Direction for DMA transfers. */
165 typedef enum
166 {
167     CYHAL_DMA_DIRECTION_MEM2MEM,       //!< Memory to memory
168     CYHAL_DMA_DIRECTION_MEM2PERIPH,    //!< Memory to peripheral
169     CYHAL_DMA_DIRECTION_PERIPH2MEM,    //!< Peripheral to memory
170     CYHAL_DMA_DIRECTION_PERIPH2PERIPH, //!< Peripheral to peripheral
171 } cyhal_dma_direction_t;
172 
173 /** Flags enum of DMA events. Multiple events can be enabled via \ref cyhal_dma_enable_event and
174  * the callback from \ref cyhal_dma_register_callback will be run to notify. */
175 typedef enum
176 {
177     CYHAL_DMA_NO_INTR             = 0,      //!< No interrupt
178     CYHAL_DMA_TRANSFER_COMPLETE   = 1 << 0, /**< Indicates that an individual transfer (burst or
179                                                  full) has completed based on the specified \ref
180                                                  cyhal_dma_transfer_action_t */
181     CYHAL_DMA_DESCRIPTOR_COMPLETE = 1 << 1, //!< Indicates that the full transfer has completed
182     CYHAL_DMA_SRC_BUS_ERROR       = 1 << 2, //!< Indicates that there is a source bus error
183     CYHAL_DMA_DST_BUS_ERROR       = 1 << 3, //!< Indicates that there is a destination bus error
184     CYHAL_DMA_SRC_MISAL           = 1 << 4, //!< Indicates that the source address is not aligned
185     CYHAL_DMA_DST_MISAL           = 1 << 5, //!< Indicates that the destination address is not aligned
186     CYHAL_DMA_CURR_PTR_NULL       = 1 << 6, //!< Indicates that the current descriptor pointer is null
187     CYHAL_DMA_ACTIVE_CH_DISABLED  = 1 << 7, //!< Indicates that the active channel is disabled
188     CYHAL_DMA_DESCR_BUS_ERROR     = 1 << 8, //!< Indicates that there has been a descriptor bus error
189 } cyhal_dma_event_t;
190 
191 /** Specifies the transfer type to trigger when an input signal is received. */
192 typedef enum
193 {
194     CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT, //!< Transfer a single element when an input signal is received
195     CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST,   //!< Transfer a single burst when an input signal is received
196     CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS,   //!< Transfer all elements when an input signal is received
197 } cyhal_dma_input_t;
198 
199 /** Specifies the transfer completion event that triggers a signal output. */
200 typedef enum
201 {
202     CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT, //!< Trigger an output when a single element is transferred
203     CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST,   //!< Trigger an output when a single burst is transferred
204     CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS,   //!< Trigger an output when all elements are transferred
205 } cyhal_dma_output_t;
206 
207 /** This defines the behavior of the the channel when transfers are initiated. It can specify both
208  * how the transfer is broken up and what happens at the end of the transfer.
209  * If burst_size from \ref cyhal_dma_cfg_t is used, this specifies the granularity of operations
210  * that occur. Using \ref CYHAL_DMA_TRANSFER_BURST or \ref CYHAL_DMA_TRANSFER_BURST_DISABLE means
211  * a single trigger will transfer a single burst (of burst_size) and raise the \ref
212  * CYHAL_DMA_TRANSFER_COMPLETE interrupt. Using \ref CYHAL_DMA_TRANSFER_FULL means a single trigger
213  * will transfer all bursts (total size length) and raise the \ref CYHAL_DMA_TRANSFER_COMPLETE
214  * interrupt. If burst_size is not used, this has no impact and a single trigger will perform a
215  * complete transfer and raise a single interrupt at the end.
216  * When the transfer is complete, the channel can be left enabled, or automatically disabled. When
217  * left enabled (\ref CYHAL_DMA_TRANSFER_BURST or \ref CYHAL_DMA_TRANSFER_FULL) subsequent triggers
218  * will re-start the transfers. If the channel is diabled on completion (\ref
219  * CYHAL_DMA_TRANSFER_BURST_DISABLE or \ref CYHAL_DMA_TRANSFER_FULL_DISABLE), \ref
220  * cyhal_dma_configure must be called to reconfigure the channel for future transfers.
221  *
222  * \note When using \ref cyhal_dma_connect_digital for a hardware input trigger, the
223  * \ref cyhal_dma_input_t argument defines how much of the transfer is initiated at a time. This
224  * enum will still define when interrupts are raised. */
225 typedef enum
226 {
227     /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after
228      * each burst. The channel will be left enabled and can continue to be triggered. */
229     CYHAL_DMA_TRANSFER_BURST,
230     /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at
231      * the end. The channel will be left enabled and can continue to be triggered. */
232     CYHAL_DMA_TRANSFER_FULL,
233     /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after
234      * each burst. When all bursts are complete, the channel will be disabled. */
235     CYHAL_DMA_TRANSFER_BURST_DISABLE,
236     /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at
237      * the end. When complete, the channel will be disabled. */
238     CYHAL_DMA_TRANSFER_FULL_DISABLE,
239 } cyhal_dma_transfer_action_t;
240 
241 /** \brief Configuration of a DMA channel. When configuring address,
242  * increments, and transfer width keep in mind your hardware may have more
243  * stringent address and data alignment requirements. */
244 typedef struct
245 {
246     uint32_t src_addr;                  //!< Source address
247     int16_t  src_increment;             //!< Source address auto increment amount in multiples of transfer_width
248     uint32_t dst_addr;                  //!< Destination address
249     int16_t  dst_increment;             //!< Destination address auto increment amount in multiples of transfer_width
250     uint8_t  transfer_width;            //!< Transfer width in bits. Valid values are: 8, 16, or 32
251     uint32_t length;                    //!< Number of elements to be transferred in total
252     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.
253     cyhal_dma_transfer_action_t action; //!< Sets the behavior of the channel when triggered (using start_transfer). Ignored if burst_size is not configured.
254 } cyhal_dma_cfg_t;
255 
256 /** Event handler for DMA interrupts */
257 typedef void (*cyhal_dma_event_callback_t)(void *callback_arg, cyhal_dma_event_t event);
258 
259 /** DMA input connection information to setup while initializing the driver. */
260 typedef struct
261 {
262     cyhal_source_t      source; //!< Source of signal to DMA; obtained from another driver's cyhal_<PERIPH>_enable_output
263     cyhal_dma_input_t   input;  //!< DMA input signal to be driven
264 } cyhal_dma_src_t;
265 
266 /** DMA output connection information to setup while initializing the driver. */
267 typedef struct
268 {
269     cyhal_dma_output_t  output; //!< Output signal of DMA
270     cyhal_dest_t        dest;   //!< Destination of DMA signal
271 } cyhal_dma_dest_t;
272 
273 /** Initialize the DMA peripheral.
274  *
275  * If a source signal is provided for \p src, this will connect the provided signal to the DMA
276  * just as would be done by calling \ref cyhal_dma_connect_digital. Similarly, if a destination
277  * target is provided for \p dest this will enable the specified output just as would be done
278  * by calling \ref cyhal_dma_enable_output.
279  * @param[out] obj  Pointer to a DMA object. The caller must allocate the memory
280  *  for this object but the init function will initialize its contents.
281  * @param[in]  src          An optional source signal to connect to the DMA
282  * @param[in]  dest         An optional destination singal to drive from the DMA
283  * @param[out] dest_source  An optional pointer to user-allocated source signal object which
284  * will be initialized by enable_output. If \p dest is non-null, this must also be non-null.
285  * \p dest_source should be passed to (dis)connect_digital functions to (dis)connect the
286  * associated endpoints.
287  * @param[in]  priority     The priority of this DMA operation relative to others. The number of
288  * priority levels which are supported is hardware dependent. All implementations define a
289  * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will
290  * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW.
291  * The behavior of any other value is implementation defined. See the implementation-specific DMA
292  * documentation for more details.
293  * @param[in]  direction    The direction memory is copied
294  * @return The status of the init request
295  */
296 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);
297 
298 /** Initialize the DMA peripheral.
299  *
300  * @param[out] obj          Pointer to a DMA object. The caller must allocate the memory for this
301  * object but the init function will initialize its contents.
302  * @param[in]  priority     The priority of this DMA operation relative to others. The number of
303  * priority levels which are supported is hardware dependent. All implementations define a
304  * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will
305  * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW.
306  * The behavior of any other value is implementation defined. See the implementation-specific DMA
307  * documentation for more details.
308  * @param[in]  direction    The direction memory is copied
309  * @return The status of the init request
310  */
311 #define cyhal_dma_init(obj, priority, direction)    (cyhal_dma_init_adv(obj, NULL, NULL, NULL, priority, direction))
312 
313 /** Initialize the DMA peripheral using data provided by the configurator.
314  *
315  * \note Depending on what the configurator allows filling it, it is likely that at least the source
316  * and destination addresses of the transfer(s) still need to be setup.
317  *
318  * @param[out] obj  Pointer to a DMA object. The caller must allocate the memory for this
319  * object but the init function will initialize its contents.
320  * @param[in]  cfg  Configuration structure generated by a configurator.
321  * @return The status of the init request
322  */
323 cy_rslt_t cyhal_dma_init_cfg(cyhal_dma_t *obj, const cyhal_dma_configurator_t *cfg);
324 
325 /** Free the DMA object. Freeing a DMA object while a transfer is in progress
326  * (\ref cyhal_dma_is_busy) is invalid.
327  *
328  * @param[in,out] obj The DMA object
329  */
330 void cyhal_dma_free(cyhal_dma_t *obj);
331 
332 /** Setup the DMA channel behavior. This will also enable the channel to allow it to be triggered.
333  * The transfer can be software triggered by calling \ref cyhal_dma_start_transfer or by hardware.
334  * A hardware input signal is setup by \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv.
335  * \note If hardware triggers are used, any necessary event callback setup (\ref
336  * cyhal_dma_register_callback and \ref cyhal_dma_enable_event) should be done before calling
337  * this function to ensure the handlers are in place before the transfer can happen.
338  * \note The automatic enablement of the channel as part of this function is expected to change
339  * in a future update. This would only happen on a new major release (eg: 1.0 -> 2.0).
340  * \note If the DMA was setup using \ref cyhal_dma_init_cfg, this function should not be used.
341  *
342  * @param[in] obj    The DMA object
343  * @param[in] cfg    Configuration parameters for the transfer
344  * @return The status of the configure request
345  */
346 cy_rslt_t cyhal_dma_configure(cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg);
347 
348 /** Enable the DMA transfer so that it can start transferring data when triggered. A trigger is
349  * caused either by calling \ref cyhal_dma_start_transfer or by hardware as a result of a connection
350  * made in either \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv. The DMA can be disabled
351  * by calling \ref cyhal_dma_disable or by setting the \ref cyhal_dma_cfg_t action to \ref
352  * CYHAL_DMA_TRANSFER_BURST_DISABLE, or \ref CYHAL_DMA_TRANSFER_FULL_DISABLE.
353  *
354  * @param[in] obj    The DMA object
355  * @return The status of the enable request
356  */
357 cy_rslt_t cyhal_dma_enable(cyhal_dma_t *obj);
358 
359 /** Disable the DMA transfer so that it does not continue to trigger. It can be reenabled by calling
360  * \ref cyhal_dma_enable or \ref cyhal_dma_configure.
361  *
362  * @param[in] obj    The DMA object
363  * @return The status of the enable request
364  */
365 cy_rslt_t cyhal_dma_disable(cyhal_dma_t *obj);
366 
367 /** Initiates DMA channel transfer for specified DMA object. This should only be done after the
368  * channel has been configured (\ref cyhal_dma_configure) and any necessary event callbacks setup
369  * (\ref cyhal_dma_register_callback \ref cyhal_dma_enable_event)
370  *
371  * @param[in] obj    The DMA object
372  * @return The status of the start_transfer request
373  */
374 cy_rslt_t cyhal_dma_start_transfer(cyhal_dma_t *obj);
375 
376 /** Checks if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running)
377  *
378  * @param[in] obj    The DMA object
379  * @return True if DMA channel is busy
380  */
381 bool cyhal_dma_is_busy(cyhal_dma_t *obj);
382 
383 /** Register a DMA callback handler.
384  *
385  * This function will be called when one of the events enabled by \ref cyhal_dma_enable_event occurs.
386  *
387  * @param[in] obj          The DMA object
388  * @param[in] callback     The callback handler which will be invoked when an event triggers
389  * @param[in] callback_arg Generic argument that will be provided to the callback when called
390  */
391 void cyhal_dma_register_callback(cyhal_dma_t *obj, cyhal_dma_event_callback_t callback, void *callback_arg);
392 
393 /** Configure DMA event enablement.
394  *
395  * When an enabled event occurs, the function specified by \ref cyhal_dma_register_callback will be called.
396  *
397  * @param[in] obj            The DMA object
398  * @param[in] event          The DMA event type
399  * @param[in] intr_priority  The priority for NVIC interrupt events. The priority from the most
400  * recent call will take precedence, i.e all events will have the same priority.
401  * @param[in] enable         True to turn on interrupts, False to turn off
402  */
403 void cyhal_dma_enable_event(cyhal_dma_t *obj, cyhal_dma_event_t event, uint8_t intr_priority, bool enable);
404 
405 /** Connects a source signal and enables the specified input to the DMA channel. This connection
406  * can also be setup automatically on initialization via \ref cyhal_dma_init_adv. If the signal
407  * needs to be disconnected later, \ref cyhal_dma_disconnect_digital can be used.
408  *
409  * @param[in] obj         The DMA object
410  * @param[in] source      Source signal obtained from another driver's cyhal_<PERIPH>_enable_output
411  * @param[in] input       Which input to enable
412  * @return The status of the connection
413  */
414 cy_rslt_t cyhal_dma_connect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input);
415 
416 /** Enables the specified output signal from a DMA channel that is triggered when a transfer is
417  * completed. This can also be setup automatically on initialization via \ref cyhal_dma_init_adv.
418  * If the output is not needed in the future, \ref cyhal_dma_disable_output can be used.
419  *
420  * @param[in]  obj         The DMA object
421  * @param[in]  output      Which event triggers the output
422  * @param[out] source      Pointer to user-allocated source signal object which
423  * will be initialized by enable_output. \p source should be passed to
424  * (dis)connect_digital functions to (dis)connect the associated endpoints.
425  * @return The status of the output enable
426  */
427 cy_rslt_t cyhal_dma_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source);
428 
429 /** Disconnects a source signal and disables the specified input to the DMA channel. This removes
430  * the connection that was established by either \ref cyhal_dma_init_adv or \ref
431  * cyhal_dma_connect_digital.
432  *
433  * @param[in] obj         The DMA object
434  * @param[in] source      Source signal from cyhal_<PERIPH>_enable_output to disable
435  * @param[in] input       Which input to disable
436  * @return The status of the disconnect
437  */
438 cy_rslt_t cyhal_dma_disconnect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input);
439 
440 /** Disables the specified output signal from a DMA channel. This turns off the signal that was
441  * enabled by either \ref cyhal_dma_init_adv or \ref cyhal_dma_enable_output. It is recommended
442  * that the signal is disconnected (cyhal_<PERIPH>_disconnect_digital) from anything it might be
443  * driving before being disabled.
444  *
445  * @param[in]  obj         The DMA object
446  * @param[in]  output      Which output to disable
447  * @return The status of the disablement
448  * */
449 cy_rslt_t cyhal_dma_disable_output(cyhal_dma_t *obj, cyhal_dma_output_t output);
450 
451 #if defined(__cplusplus)
452 }
453 #endif
454 
455 #ifdef CYHAL_DMA_IMPL_HEADER
456 #include CYHAL_DMA_IMPL_HEADER
457 #endif /* CYHAL_DMA_IMPL_HEADER */
458 
459 /** \} group_hal_dma */
460