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-2022 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 * \subsection subsection_dma_snippet_5 Snippet 5: DMA transfers with D-cache 116 * If CPU D-cache is enabled, DMA transfers must be handled using cache management API when dealing with cacheable memory 117 * in order to maintain CPU data cache coherency. 118 * Regarding the CPU data cache coherence with DMA, the general rules are, <br> 119 * - Source and destination buffers must be cacheline aligned (__SCB_DCACHE_LINE_SIZE) <br> 120 * - D-cache of DMA descriptor and D-cache of source's buffers must be cleaned before a DMA transfer <br> 121 * - D-cache of destination buffer must be invalidated after a DMA transfer <br> 122 * 123 * The following snippet initializes a DMA channel and uses it to transfer a single block from one cacheable memory 124 * to another cacheable memory. Cleaning D-cache of DMA descriptor is done by calling \ref cyhal_dma_configure. 125 * Cleaning D-cache of source's buffer and Invalidating D-cache of destination's buffer should be done explicitly. 126 * 127 * Refer to \ref DCACHE_Management for more information. 128 * 129 * \snippet hal_dma.c snippet_cyhal_dma_with_dcache 130 */ 131 132 #pragma once 133 134 #include <stdbool.h> 135 #include <stdint.h> 136 #include "cy_result.h" 137 #include "cyhal_hw_types.h" 138 139 #if defined(__cplusplus) 140 extern "C" { 141 #endif 142 143 /** \addtogroup group_hal_results_dma DMA HAL Results 144 * DMA specific return codes 145 * \ingroup group_hal_results 146 * \{ *//** 147 */ 148 149 /** Invalid transfer width parameter error */ 150 #define CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_WIDTH \ 151 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 0)) 152 /** Invalid parameter error */ 153 #define CYHAL_DMA_RSLT_ERR_INVALID_PARAMETER \ 154 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 1)) 155 /** Invalid priority parameter error */ 156 #define CYHAL_DMA_RSLT_ERR_INVALID_PRIORITY \ 157 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 2)) 158 /** Invalid src or dst addr alignment error */ 159 #define CYHAL_DMA_RSLT_ERR_INVALID_ALIGNMENT \ 160 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 3)) 161 /** Invalid burst_size paramenter error */ 162 #define CYHAL_DMA_RSLT_ERR_INVALID_BURST_SIZE \ 163 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 4)) 164 /** Channel busy error */ 165 #define CYHAL_DMA_RSLT_ERR_CHANNEL_BUSY \ 166 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 5)) 167 /** Transfer has already been started warning */ 168 #define CYHAL_DMA_RSLT_WARN_TRANSFER_ALREADY_STARTED \ 169 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_WARNING, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 6)) 170 /** Unsupported hardware error */ 171 #define CYHAL_DMA_RSLT_FATAL_UNSUPPORTED_HARDWARE \ 172 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_FATAL, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 7)) 173 /** Requested transfer size is not supported */ 174 #define CYHAL_DMA_RSLT_ERR_INVALID_TRANSFER_SIZE \ 175 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_FATAL, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_DMA, 8)) 176 177 /** 178 * \} 179 */ 180 181 /** Direction for DMA transfers. */ 182 typedef enum 183 { 184 CYHAL_DMA_DIRECTION_MEM2MEM, //!< Memory to memory 185 CYHAL_DMA_DIRECTION_MEM2PERIPH, //!< Memory to peripheral 186 CYHAL_DMA_DIRECTION_PERIPH2MEM, //!< Peripheral to memory 187 CYHAL_DMA_DIRECTION_PERIPH2PERIPH, //!< Peripheral to peripheral 188 } cyhal_dma_direction_t; 189 190 /** Flags enum of DMA events. Multiple events can be enabled via \ref cyhal_dma_enable_event and 191 * the callback from \ref cyhal_dma_register_callback will be run to notify. */ 192 typedef enum 193 { 194 CYHAL_DMA_NO_INTR = 0, //!< No interrupt 195 CYHAL_DMA_TRANSFER_COMPLETE = 1 << 0, /**< Indicates that an individual transfer (burst or 196 full) has completed based on the specified \ref 197 cyhal_dma_transfer_action_t */ 198 CYHAL_DMA_DESCRIPTOR_COMPLETE = 1 << 1, //!< Indicates that the full transfer has completed 199 CYHAL_DMA_SRC_BUS_ERROR = 1 << 2, //!< Indicates that there is a source bus error 200 CYHAL_DMA_DST_BUS_ERROR = 1 << 3, //!< Indicates that there is a destination bus error 201 CYHAL_DMA_SRC_MISAL = 1 << 4, //!< Indicates that the source address is not aligned 202 CYHAL_DMA_DST_MISAL = 1 << 5, //!< Indicates that the destination address is not aligned 203 CYHAL_DMA_CURR_PTR_NULL = 1 << 6, //!< Indicates that the current descriptor pointer is null 204 CYHAL_DMA_ACTIVE_CH_DISABLED = 1 << 7, //!< Indicates that the active channel is disabled 205 CYHAL_DMA_DESCR_BUS_ERROR = 1 << 8, //!< Indicates that there has been a descriptor bus error 206 } cyhal_dma_event_t; 207 208 /** Specifies the transfer type to trigger when an input signal is received. */ 209 typedef enum 210 { 211 CYHAL_DMA_INPUT_TRIGGER_SINGLE_ELEMENT, //!< Transfer a single element when an input signal is received 212 CYHAL_DMA_INPUT_TRIGGER_SINGLE_BURST, //!< Transfer a single burst when an input signal is received 213 CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS, //!< Transfer all elements when an input signal is received 214 } cyhal_dma_input_t; 215 216 /** Specifies the transfer completion event that triggers a signal output. */ 217 typedef enum 218 { 219 CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_ELEMENT, //!< Trigger an output when a single element is transferred 220 CYHAL_DMA_OUTPUT_TRIGGER_SINGLE_BURST, //!< Trigger an output when a single burst is transferred 221 CYHAL_DMA_OUTPUT_TRIGGER_ALL_ELEMENTS, //!< Trigger an output when all elements are transferred 222 } cyhal_dma_output_t; 223 224 /** This defines the behavior of the the channel when transfers are initiated. It can specify both 225 * how the transfer is broken up and what happens at the end of the transfer. 226 * If burst_size from \ref cyhal_dma_cfg_t is used, this specifies the granularity of operations 227 * that occur. Using \ref CYHAL_DMA_TRANSFER_BURST or \ref CYHAL_DMA_TRANSFER_BURST_DISABLE means 228 * a single trigger will transfer a single burst (of burst_size) and raise the \ref 229 * CYHAL_DMA_TRANSFER_COMPLETE interrupt. Using \ref CYHAL_DMA_TRANSFER_FULL means a single trigger 230 * will transfer all bursts (total size length) and raise the \ref CYHAL_DMA_TRANSFER_COMPLETE 231 * interrupt. If burst_size is not used, this has no impact and a single trigger will perform a 232 * complete transfer and raise a single interrupt at the end. 233 * When the transfer is complete, the channel can be left enabled, or automatically disabled. When 234 * left enabled (\ref CYHAL_DMA_TRANSFER_BURST or \ref CYHAL_DMA_TRANSFER_FULL) subsequent triggers 235 * will re-start the transfers. If the channel is diabled on completion (\ref 236 * CYHAL_DMA_TRANSFER_BURST_DISABLE or \ref CYHAL_DMA_TRANSFER_FULL_DISABLE), \ref 237 * cyhal_dma_configure must be called to reconfigure the channel for future transfers. 238 * 239 * \note When using \ref cyhal_dma_connect_digital for a hardware input trigger, the 240 * \ref cyhal_dma_input_t argument defines how much of the transfer is initiated at a time. This 241 * enum will still define when interrupts are raised. */ 242 typedef enum 243 { 244 /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after 245 * each burst. The channel will be left enabled and can continue to be triggered. */ 246 CYHAL_DMA_TRANSFER_BURST, 247 /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at 248 * the end. The channel will be left enabled and can continue to be triggered. */ 249 CYHAL_DMA_TRANSFER_FULL, 250 /** A single burst is triggered and a \ref CYHAL_DMA_TRANSFER_COMPLETE will occur after 251 * each burst. When all bursts are complete, the channel will be disabled. */ 252 CYHAL_DMA_TRANSFER_BURST_DISABLE, 253 /** All bursts are triggered and a single \ref CYHAL_DMA_TRANSFER_COMPLETE will occur at 254 * the end. When complete, the channel will be disabled. */ 255 CYHAL_DMA_TRANSFER_FULL_DISABLE, 256 } cyhal_dma_transfer_action_t; 257 258 /** \brief Configuration of a DMA channel. When configuring address, 259 * increments, and transfer width keep in mind your hardware may have more 260 * stringent address and data alignment requirements. */ 261 typedef struct 262 { 263 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. 264 int16_t src_increment; //!< Source address auto increment amount in multiples of transfer_width 265 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. 266 int16_t dst_increment; //!< Destination address auto increment amount in multiples of transfer_width 267 uint8_t transfer_width; //!< Transfer width in bits. Valid values are: 8, 16, or 32 268 uint32_t length; //!< Number of elements to be transferred in total 269 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. 270 cyhal_dma_transfer_action_t action; //!< Sets the behavior of the channel when triggered (using start_transfer). Ignored if burst_size is not configured. 271 } cyhal_dma_cfg_t; 272 273 /** Event handler for DMA interrupts */ 274 typedef void (*cyhal_dma_event_callback_t)(void *callback_arg, cyhal_dma_event_t event); 275 276 /** DMA input connection information to setup while initializing the driver. */ 277 typedef struct 278 { 279 cyhal_source_t source; //!< Source of signal to DMA; obtained from another driver's cyhal_<PERIPH>_enable_output 280 cyhal_dma_input_t input; //!< DMA input signal to be driven 281 } cyhal_dma_src_t; 282 283 /** DMA output connection information to setup while initializing the driver. */ 284 typedef struct 285 { 286 cyhal_dma_output_t output; //!< Output signal of DMA 287 cyhal_dest_t dest; //!< Destination of DMA signal 288 } cyhal_dma_dest_t; 289 290 /** Initialize the DMA peripheral. 291 * 292 * If a source signal is provided for \p src, this will connect the provided signal to the DMA 293 * just as would be done by calling \ref cyhal_dma_connect_digital. Similarly, if a destination 294 * target is provided for \p dest this will enable the specified output just as would be done 295 * by calling \ref cyhal_dma_enable_output. 296 * @param[out] obj Pointer to a DMA object. The caller must allocate the memory 297 * for this object but the init function will initialize its contents. 298 * @param[in] src An optional source signal to connect to the DMA 299 * @param[in] dest An optional destination signal to drive from the DMA 300 * @param[out] dest_source An optional pointer to user-allocated source signal object which 301 * will be initialized by enable_output. If \p dest is non-null, this must also be non-null. 302 * \p dest_source should be passed to (dis)connect_digital functions to (dis)connect the 303 * associated endpoints. 304 * @param[in] priority The priority of this DMA operation relative to others. The number of 305 * priority levels which are supported is hardware dependent. All implementations define a 306 * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will 307 * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW. 308 * The behavior of any other value is implementation defined. See the implementation-specific DMA 309 * documentation for more details. 310 * @param[in] direction The direction memory is copied 311 * @return The status of the init request 312 */ 313 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); 314 315 /** Initialize the DMA peripheral. 316 * 317 * @param[out] obj Pointer to a DMA object. The caller must allocate the memory for this 318 * object but the init function will initialize its contents. 319 * @param[in] priority The priority of this DMA operation relative to others. The number of 320 * priority levels which are supported is hardware dependent. All implementations define a 321 * #CYHAL_DMA_PRIORITY_DEFAULT constant which is always valid. If supported, implementations will 322 * also define #CYHAL_DMA_PRIORITY_HIGH, #CYHAL_DMA_PRIORITY_MEDIUM, and #CYHAL_DMA_PRIORITY_LOW. 323 * The behavior of any other value is implementation defined. See the implementation-specific DMA 324 * documentation for more details. 325 * @param[in] direction The direction memory is copied 326 * @return The status of the init request 327 */ 328 #define cyhal_dma_init(obj, priority, direction) (cyhal_dma_init_adv(obj, NULL, NULL, NULL, priority, direction)) 329 330 /** Initialize the DMA peripheral using data provided by the configurator. 331 * 332 * \note Depending on what the configurator allows filling it, it is likely that at least the source 333 * and destination addresses of the transfer(s) still need to be setup. 334 * 335 * @param[out] obj Pointer to a DMA object. The caller must allocate the memory for this 336 * object but the init function will initialize its contents. 337 * @param[in] cfg Configuration structure generated by a configurator. 338 * @return The status of the init request 339 */ 340 cy_rslt_t cyhal_dma_init_cfg(cyhal_dma_t *obj, const cyhal_dma_configurator_t *cfg); 341 342 /** Free the DMA object. Freeing a DMA object while a transfer is in progress 343 * (\ref cyhal_dma_is_busy) is invalid. 344 * 345 * @param[in,out] obj The DMA object 346 */ 347 void cyhal_dma_free(cyhal_dma_t *obj); 348 349 /** Setup the DMA channel behavior. This will also enable the channel to allow it to be triggered. 350 * The transfer can be software triggered by calling \ref cyhal_dma_start_transfer or by hardware. 351 * A hardware input signal is setup by \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv. 352 * \note If hardware triggers are used, any necessary event callback setup (\ref 353 * cyhal_dma_register_callback and \ref cyhal_dma_enable_event) should be done before calling 354 * this function to ensure the handlers are in place before the transfer can happen. 355 * \note The automatic enablement of the channel as part of this function is expected to change 356 * in a future update. This would only happen on a new major release (eg: 1.0 -> 2.0). 357 * \note If the DMA was setup using \ref cyhal_dma_init_cfg, this function should not be used. 358 * \note If D-cache is enabled, this function cleans D-cache of DMA descriptor. 359 * 360 * @param[in] obj The DMA object 361 * @param[in] cfg Configuration parameters for the transfer 362 * @return The status of the configure request 363 */ 364 cy_rslt_t cyhal_dma_configure(cyhal_dma_t *obj, const cyhal_dma_cfg_t *cfg); 365 366 /** Enable the DMA transfer so that it can start transferring data when triggered. A trigger is 367 * caused either by calling \ref cyhal_dma_start_transfer or by hardware as a result of a connection 368 * made in either \ref cyhal_dma_connect_digital or \ref cyhal_dma_init_adv. The DMA can be disabled 369 * by calling \ref cyhal_dma_disable or by setting the \ref cyhal_dma_cfg_t action to \ref 370 * CYHAL_DMA_TRANSFER_BURST_DISABLE, or \ref CYHAL_DMA_TRANSFER_FULL_DISABLE. 371 * 372 * @param[in] obj The DMA object 373 * @return The status of the enable request 374 */ 375 cy_rslt_t cyhal_dma_enable(cyhal_dma_t *obj); 376 377 /** Disable the DMA transfer so that it does not continue to trigger. It can be reenabled by calling 378 * \ref cyhal_dma_enable or \ref cyhal_dma_configure. 379 * 380 * @param[in] obj The DMA object 381 * @return The status of the enable request 382 */ 383 cy_rslt_t cyhal_dma_disable(cyhal_dma_t *obj); 384 385 /** Initiates DMA channel transfer for specified DMA object. This should only be done after the 386 * channel has been configured (\ref cyhal_dma_configure) and any necessary event callbacks setup 387 * (\ref cyhal_dma_register_callback \ref cyhal_dma_enable_event) 388 * 389 * @param[in] obj The DMA object 390 * @return The status of the start_transfer request 391 */ 392 cy_rslt_t cyhal_dma_start_transfer(cyhal_dma_t *obj); 393 394 /** Checks if the transfer has been triggered, but not yet complete (eg: is pending, blocked or running) 395 * 396 * @param[in] obj The DMA object 397 * @return True if DMA channel is busy 398 */ 399 bool cyhal_dma_is_busy(cyhal_dma_t *obj); 400 401 /** Register a DMA callback handler. 402 * 403 * This function will be called when one of the events enabled by \ref cyhal_dma_enable_event occurs. 404 * 405 * @param[in] obj The DMA object 406 * @param[in] callback The callback handler which will be invoked when an event triggers 407 * @param[in] callback_arg Generic argument that will be provided to the callback when called 408 */ 409 void cyhal_dma_register_callback(cyhal_dma_t *obj, cyhal_dma_event_callback_t callback, void *callback_arg); 410 411 /** Configure DMA event enablement. 412 * 413 * When an enabled event occurs, the function specified by \ref cyhal_dma_register_callback will be called. 414 * 415 * @param[in] obj The DMA object 416 * @param[in] event The DMA event type 417 * @param[in] intr_priority The priority for NVIC interrupt events. The priority from the most 418 * recent call will take precedence, i.e all events will have the same priority. 419 * @param[in] enable True to turn on interrupts, False to turn off 420 */ 421 void cyhal_dma_enable_event(cyhal_dma_t *obj, cyhal_dma_event_t event, uint8_t intr_priority, bool enable); 422 423 /** Connects a source signal and enables the specified input to the DMA channel. This connection 424 * can also be setup automatically on initialization via \ref cyhal_dma_init_adv. If the signal 425 * needs to be disconnected later, \ref cyhal_dma_disconnect_digital can be used. 426 * 427 * @param[in] obj The DMA object 428 * @param[in] source Source signal obtained from another driver's cyhal_<PERIPH>_enable_output 429 * @param[in] input Which input to enable 430 * @return The status of the connection 431 */ 432 cy_rslt_t cyhal_dma_connect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input); 433 434 /** Enables the specified output signal from a DMA channel that is triggered when a transfer is 435 * completed. This can also be setup automatically on initialization via \ref cyhal_dma_init_adv. 436 * If the output is not needed in the future, \ref cyhal_dma_disable_output can be used. 437 * 438 * @param[in] obj The DMA object 439 * @param[in] output Which event triggers the output 440 * @param[out] source Pointer to user-allocated source signal object which 441 * will be initialized by enable_output. \p source should be passed to 442 * (dis)connect_digital functions to (dis)connect the associated endpoints. 443 * @return The status of the output enable 444 */ 445 cy_rslt_t cyhal_dma_enable_output(cyhal_dma_t *obj, cyhal_dma_output_t output, cyhal_source_t *source); 446 447 /** Disconnects a source signal and disables the specified input to the DMA channel. This removes 448 * the connection that was established by either \ref cyhal_dma_init_adv or \ref 449 * cyhal_dma_connect_digital. 450 * 451 * @param[in] obj The DMA object 452 * @param[in] source Source signal from cyhal_<PERIPH>_enable_output to disable 453 * @param[in] input Which input to disable 454 * @return The status of the disconnect 455 */ 456 cy_rslt_t cyhal_dma_disconnect_digital(cyhal_dma_t *obj, cyhal_source_t source, cyhal_dma_input_t input); 457 458 /** Disables the specified output signal from a DMA channel. This turns off the signal that was 459 * enabled by either \ref cyhal_dma_init_adv or \ref cyhal_dma_enable_output. It is recommended 460 * that the signal is disconnected (cyhal_<PERIPH>_disconnect_digital) from anything it might be 461 * driving before being disabled. 462 * 463 * @param[in] obj The DMA object 464 * @param[in] output Which output to disable 465 * @return The status of the disablement 466 * */ 467 cy_rslt_t cyhal_dma_disable_output(cyhal_dma_t *obj, cyhal_dma_output_t output); 468 469 #if defined(__cplusplus) 470 } 471 #endif 472 473 #ifdef CYHAL_DMA_IMPL_HEADER 474 #include CYHAL_DMA_IMPL_HEADER 475 #endif /* CYHAL_DMA_IMPL_HEADER */ 476 477 /** \} group_hal_dma */ 478