1 /**
2  * @file
3  * @brief   Direct Memory Access (DMA) driver function prototypes and data types.
4  */
5 
6 /******************************************************************************
7  *
8  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9  * Analog Devices, Inc.),
10  * Copyright (C) 2023-2024 Analog Devices, Inc.
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  ******************************************************************************/
25 
26 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_DMA_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_DMA_H_
28 
29 /* **** Includes **** */
30 #include "dma_regs.h"
31 #include <stdbool.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /**
38  * @defgroup dma Direct Memory Access (DMA)
39  * @ingroup periphlibs
40  * @{
41  */
42 
43 /* **** Definitions **** */
44 
45 /**
46  * Enumeration for the DMA Channel's priority level.
47  */
48 typedef enum {
49     MXC_DMA_PRIO_HIGH = MXC_S_DMA_CFG_PRI_HIGH, /**< High Priority */
50     MXC_DMA_PRIO_MEDHIGH = MXC_S_DMA_CFG_PRI_MEDHIGH, /**< Medium High Priority */
51     MXC_DMA_PRIO_MEDLOW = MXC_S_DMA_CFG_PRI_MEDLOW, /**< Medium Low Priority */
52     MXC_DMA_PRIO_LOW = MXC_S_DMA_CFG_PRI_LOW, /**< Low Priority */
53 } mxc_dma_priority_t;
54 
55 /** @brief DMA request select */
56 typedef enum {
57     MXC_DMA_REQUEST_MEMTOMEM =
58         MXC_S_DMA_CFG_REQSEL_MEMTOMEM, /**< Memory to Memory DMA Request Selection */
59     MXC_DMA_REQUEST_SPI0RX = MXC_S_DMA_CFG_REQSEL_SPI0RX, /**< SPI0 Receive DMA Request Selection */
60     MXC_DMA_REQUEST_SPI1RX = MXC_S_DMA_CFG_REQSEL_SPI1RX, /**< SPI1 Receive DMA Request Selection */
61     MXC_DMA_REQUEST_SPI2RX = MXC_S_DMA_CFG_REQSEL_SPI2RX, /**< SPI2 Receive DMA Request Selection */
62     MXC_DMA_REQUEST_UART0RX =
63         MXC_S_DMA_CFG_REQSEL_UART0RX, /**< UART0 Receive DMA Request Selection */
64     MXC_DMA_REQUEST_UART1RX =
65         MXC_S_DMA_CFG_REQSEL_UART1RX, /**< UART1 Receive DMA Request Selection */
66     MXC_DMA_REQUEST_I2C0RX = MXC_S_DMA_CFG_REQSEL_I2C0RX, /**< I2C0 Receive DMA Request Selection */
67     MXC_DMA_REQUEST_I2C1RX = MXC_S_DMA_CFG_REQSEL_I2C1RX, /**< I2C1 Receive DMA Request Selection */
68     MXC_DMA_REQUEST_ADC = MXC_S_DMA_CFG_REQSEL_ADC, /**< ADC DMA Request Selection */
69     MXC_DMA_REQUEST_UART2RX =
70         MXC_S_DMA_CFG_REQSEL_UART2RX, /**< UART2 Receive DMA Request Selection */
71     MXC_DMA_REQUEST_SPI3RX = MXC_S_DMA_CFG_REQSEL_SPI3RX, /**< SPI3 Receive DMA Request Selection */
72     MXC_DMA_REQUEST_SPIMSSRX =
73         MXC_S_DMA_CFG_REQSEL_SPIMSSRX, /**< I2S Receive DMA Request Selection */
74     MXC_DMA_REQUEST_USBRXEP1 =
75         MXC_S_DMA_CFG_REQSEL_USBRXEP1, /**< USB Receive Endpoint 1 DMA Request Selection */
76     MXC_DMA_REQUEST_USBRXEP2 =
77         MXC_S_DMA_CFG_REQSEL_USBRXEP2, /**< USB Receive Endpoint 2 DMA Request Selection */
78     MXC_DMA_REQUEST_USBRXEP3 =
79         MXC_S_DMA_CFG_REQSEL_USBRXEP3, /**< USB Receive Endpoint 3 DMA Request Selection */
80     MXC_DMA_REQUEST_USBRXEP4 =
81         MXC_S_DMA_CFG_REQSEL_USBRXEP4, /**< USB Receive Endpoint 4 DMA Request Selection */
82     MXC_DMA_REQUEST_USBRXEP5 =
83         MXC_S_DMA_CFG_REQSEL_USBRXEP5, /**< USB Receive Endpoint 5 DMA Request Selection */
84     MXC_DMA_REQUEST_USBRXEP6 =
85         MXC_S_DMA_CFG_REQSEL_USBRXEP6, /**< USB Receive Endpoint 6 DMA Request Selection */
86     MXC_DMA_REQUEST_USBRXEP7 =
87         MXC_S_DMA_CFG_REQSEL_USBRXEP7, /**< USB Receive Endpoint 7 DMA Request Selection */
88     MXC_DMA_REQUEST_USBRXEP8 =
89         MXC_S_DMA_CFG_REQSEL_USBRXEP8, /**< USB Receive Endpoint 8 DMA Request Selection */
90     MXC_DMA_REQUEST_USBRXEP9 =
91         MXC_S_DMA_CFG_REQSEL_USBRXEP9, /**< USB Receive Endpoint 9 DMA Request Selection */
92     MXC_DMA_REQUEST_USBRXEP10 =
93         MXC_S_DMA_CFG_REQSEL_USBRXEP10, /**< USB Receive Endpoint 10 DMA Request Selection */
94     MXC_DMA_REQUEST_USBRXEP11 =
95         MXC_S_DMA_CFG_REQSEL_USBRXEP11, /**< USB Receive Endpoint 11 DMA Request Selection */
96     MXC_DMA_REQUEST_SPI0TX =
97         MXC_S_DMA_CFG_REQSEL_SPI0TX, /**< SPI0 Transmit DMA Request Selection */
98     MXC_DMA_REQUEST_SPI1TX =
99         MXC_S_DMA_CFG_REQSEL_SPI1TX, /**< SPI1 Transmit DMA Request Selection */
100     MXC_DMA_REQUEST_SPI2TX =
101         MXC_S_DMA_CFG_REQSEL_SPI2TX, /**< SPI2 Transmit DMA Request Selection */
102     MXC_DMA_REQUEST_UART0TX =
103         MXC_S_DMA_CFG_REQSEL_UART0TX, /**< UART0 Transmit DMA Request Selection */
104     MXC_DMA_REQUEST_UART1TX =
105         MXC_S_DMA_CFG_REQSEL_UART1TX, /**< UART1 Transmit DMA Request Selection */
106     MXC_DMA_REQUEST_I2C0TX =
107         MXC_S_DMA_CFG_REQSEL_I2C0TX, /**< I2C0 Transmit DMA Request Selection */
108     MXC_DMA_REQUEST_I2C1TX =
109         MXC_S_DMA_CFG_REQSEL_I2C1TX, /**< I2C1 Transmit DMA Request Selection */
110     MXC_DMA_REQUEST_UART2TX =
111         MXC_S_DMA_CFG_REQSEL_UART2TX, /**< UART 2 Transmit DMA Request Selection */
112     MXC_DMA_REQUEST_SPI3TX =
113         MXC_S_DMA_CFG_REQSEL_SPI3TX, /**< SPI3 Transmit DMA Request Selection */
114     MXC_DMA_REQUEST_SPIMSSTX =
115         MXC_S_DMA_CFG_REQSEL_SPIMSSTX, /**< I2S Transmit DMA Request Selection */
116     MXC_DMA_REQUEST_USBTXEP1 =
117         MXC_S_DMA_CFG_REQSEL_USBTXEP1, /**< USB TX Endpoint 1 DMA Request Selection */
118     MXC_DMA_REQUEST_USBTXEP2 =
119         MXC_S_DMA_CFG_REQSEL_USBTXEP2, /**< USB TX Endpoint 2 DMA Request Selection */
120     MXC_DMA_REQUEST_USBTXEP3 =
121         MXC_S_DMA_CFG_REQSEL_USBTXEP3, /**< USB TX Endpoint 3 DMA Request Selection */
122     MXC_DMA_REQUEST_USBTXEP4 =
123         MXC_S_DMA_CFG_REQSEL_USBTXEP4, /**< USB TX Endpoint 4 DMA Request Selection */
124     MXC_DMA_REQUEST_USBTXEP5 =
125         MXC_S_DMA_CFG_REQSEL_USBTXEP5, /**< USB TX Endpoint 5 DMA Request Selection */
126     MXC_DMA_REQUEST_USBTXEP6 =
127         MXC_S_DMA_CFG_REQSEL_USBTXEP6, /**< USB TX Endpoint 6 DMA Request Selection */
128     MXC_DMA_REQUEST_USBTXEP7 =
129         MXC_S_DMA_CFG_REQSEL_USBTXEP7, /**< USB TX Endpoint 7 DMA Request Selection */
130     MXC_DMA_REQUEST_USBTXEP8 =
131         MXC_S_DMA_CFG_REQSEL_USBTXEP8, /**< USB TX Endpoint 8 DMA Request Selection */
132     MXC_DMA_REQUEST_USBTXEP9 =
133         MXC_S_DMA_CFG_REQSEL_USBTXEP9, /**< USB TX Endpoint 9 DMA Request Selection */
134     MXC_DMA_REQUEST_USBTXEP10 =
135         MXC_S_DMA_CFG_REQSEL_USBTXEP10, /**< USB TX Endpoint 10 DMA Request Selection */
136     MXC_DMA_REQUEST_USBTXEP11 =
137         MXC_S_DMA_CFG_REQSEL_USBTXEP11, /**< USB TX Endpoint 11 DMA Request Selection */
138 } mxc_dma_reqsel_t;
139 
140 /** @brief Enumeration for the DMA prescaler */
141 typedef enum {
142     MXC_DMA_PRESCALE_DISABLE = MXC_S_DMA_CFG_PSSEL_DIS, /**< Prescaler disabled */
143     MXC_DMA_PRESCALE_DIV256 = MXC_S_DMA_CFG_PSSEL_DIV256, /**< Divide by 256 */
144     MXC_DMA_PRESCALE_DIV64K = MXC_S_DMA_CFG_PSSEL_DIV64K, /**< Divide by 65,536 */
145     MXC_DMA_PRESCALE_DIV16M = MXC_S_DMA_CFG_PSSEL_DIV16M, /**< Divide by 16,777,216 */
146 } mxc_dma_prescale_t;
147 
148 /** @brief Enumeration for the DMA timeout value */
149 typedef enum {
150     MXC_DMA_TIMEOUT_4_CLK = MXC_S_DMA_CFG_TOSEL_TO4, /**< DMA timeout of 4 clocks */
151     MXC_DMA_TIMEOUT_8_CLK = MXC_S_DMA_CFG_TOSEL_TO8, /**< DMA timeout of 8 clocks */
152     MXC_DMA_TIMEOUT_16_CLK = MXC_S_DMA_CFG_TOSEL_TO16, /**< DMA timeout of 16 clocks */
153     MXC_DMA_TIMEOUT_32_CLK = MXC_S_DMA_CFG_TOSEL_TO32, /**< DMA timeout of 32 clocks */
154     MXC_DMA_TIMEOUT_64_CLK = MXC_S_DMA_CFG_TOSEL_TO64, /**< DMA timeout of 64 clocks */
155     MXC_DMA_TIMEOUT_128_CLK = MXC_S_DMA_CFG_TOSEL_TO128, /**< DMA timeout of 128 clocks */
156     MXC_DMA_TIMEOUT_256_CLK = MXC_S_DMA_CFG_TOSEL_TO256, /**< DMA timeout of 256 clocks */
157     MXC_DMA_TIMEOUT_512_CLK = MXC_S_DMA_CFG_TOSEL_TO512, /**< DMA timeout of 512 clocks */
158 } mxc_dma_timeout_t;
159 
160 /** @brief DMA transfer data width */
161 typedef enum {
162     /* Using the '_V_' define instead of the '_S_' since these same values will be used to
163        specify the DSTWD also.  The API functions will shift the value the correct amount
164        prior to writing the cfg register. */
165     MXC_DMA_WIDTH_BYTE = MXC_V_DMA_CFG_SRCWD_BYTE, /**< DMA transfer in bytes */
166     MXC_DMA_WIDTH_HALFWORD = MXC_V_DMA_CFG_SRCWD_HALFWORD, /**< DMA transfer in 16-bit half-words */
167     MXC_DMA_WIDTH_WORD = MXC_V_DMA_CFG_SRCWD_WORD, /**< DMA transfer in 32-bit words */
168 } mxc_dma_width_t;
169 
170 /**
171  * @brief   The basic configuration information to set up a DMA channel
172  *          and prepare it for transfers.
173  *
174  */
175 typedef struct {
176     int ch; ///< The channel to load the configuration data into
177     mxc_dma_reqsel_t reqsel; ///< The request select line to be used (mem2mem, peripheral)
178     mxc_dma_width_t srcwd; ///< The source width (could be dependent on FIFO width)
179     mxc_dma_width_t dstwd; ///< The destination width (could be dependent on FIFO width)
180     int srcinc_en; ///< Whether to increment the source address during the transfer
181     int dstinc_en; ///< Whether to increment the source address during the transfer
182 } mxc_dma_config_t;
183 
184 /**
185  * @brief   The information needed to complete a DMA transfer
186  *
187  */
188 typedef struct {
189     int ch; ///< The channel to use for the transfer
190     void *source; ///< Pointer to the source address, if applicable
191     void *dest; ///< Pointer to the destination address, if applicable
192     int len; ///< Number of bytes to transfer
193 } mxc_dma_srcdst_t;
194 
195 /**
196  * @brief   The advanced configuration options, these are optional but could
197  *          be needed in cases where multiple DMA channels are running concurrently
198  *          or DMA is being used with low bandwidth peripherals.
199  *
200  */
201 typedef struct {
202     int ch; ///< The channel to use for the transfer
203     mxc_dma_priority_t prio; ///< The DMA priority for the channel
204     unsigned int reqwait_en; ///< Delay the timeout timer start until after first transfer
205     mxc_dma_timeout_t tosel; ///< Number of prescaled clocks seen by the channel before a timeout
206     mxc_dma_prescale_t pssel; ///< Prescaler for the timeout timer
207     unsigned int burst_size; ///< Number of bytes moved in a single burst
208 } mxc_dma_adv_config_t;
209 
210 /**
211  * @brief   The callback called on completion of a DMA_MemCpy() transfer
212  *
213  * @param   dest    Pointer to the destination of the copy
214  */
215 typedef void (*mxc_dma_complete_cb_t)(void *dest);
216 
217 /**
218  * @brief   The callback called on completion of a transfer,
219  * @note    This callback is used with MXC_DMA_DoTransfer()
220  *          to allow the user to chain an unlimited number of
221  *          DMA Transfers.
222  *
223  * @param   trans    Struct of the completed transfer
224  *
225  * @return  Returns the next transfer to be completed, or NULL
226  *          if no more transfers will be done
227  */
228 typedef mxc_dma_srcdst_t (*mxc_dma_trans_chain_t)(mxc_dma_srcdst_t dest);
229 
230 /* **** Function Prototypes **** */
231 
232 /**
233  * @brief      Initialize DMA resources
234  * @details    This initialization is required before using the DMA driver functions.
235  * @note       On default this function enables DMA peripheral clock.
236  *             if you wish to manage clock and gpio related things in upper level instead of here.
237  *             Define MSDK_NO_GPIO_CLK_INIT flag in project.mk file.
238  *             By this flag this function will remove clock and gpio related codes from file.
239  * @return     #E_NO_ERROR if successful
240  */
241 int MXC_DMA_Init(void);
242 
243 /**
244  * @brief      De-Initialize DMA resources.
245  */
246 void MXC_DMA_DeInit(void);
247 
248 /**
249  * @brief      Request DMA channel
250  * @details    Returns a handle to the first free DMA channel, which can be used via API calls
251  *             or direct access to channel registers using the DMA_GetCHRegs(int ch) function.
252  * @return     Non-negative channel handle (inclusive of zero).
253  * @return     #E_NONE_AVAIL    All channels in use.
254  * @return     #E_BAD_STATE     DMA is not initialized, call DMA_Init() first.
255  * @return     #E_BUSY          DMA is currently busy (locked), try again later.
256  */
257 int MXC_DMA_AcquireChannel(void);
258 
259 /**
260  * @brief      Release DMA channel
261  * @details    Stops any DMA operation on the channel and returns it to the pool of free channels.
262  *
263  * @param          ch   channel handle to release
264  *
265  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
266  */
267 int MXC_DMA_ReleaseChannel(int ch);
268 
269 /**
270  * @brief      Configure the DMA channel
271  * @details    Configures the channel, which was previously requested by DMA_Getchannel()
272  *
273  * @param      config       Struct containing basic channel configuration information
274  * @param      srcdst       Struct containing DMA transfer source and destination information
275  *
276  * @return     #E_BAD_PARAM if an unused or invalid channel handle
277  * @return     #E_NO_ERROR otherwise
278  */
279 int MXC_DMA_ConfigChannel(mxc_dma_config_t config, mxc_dma_srcdst_t srcdst);
280 
281 /**
282  * @brief      Configure the DMA channel with more advanced parameters
283  *
284  * @param      advConfig    Struct containing advanced DMA parameters
285  *
286  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
287  */
288 int MXC_DMA_AdvConfigChannel(mxc_dma_adv_config_t advConfig);
289 
290 /**
291  * @brief      Set channel source, destination, and count for the transfer
292  * @param      srcdst Struct containing the channel, source, destination, and count for the channel
293  * @note       Unless the channel request select is #mxc_dma_srcdst_t = MXC_DMA_REQUEST_MEMTOMEM,
294  *             either src_addr or dst_addr will be ignored by the DMA engine.
295  *             In these cases, the address is a don't-care. See the User's
296  *             Guide for more information.
297  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
298  */
299 int MXC_DMA_SetSrcDst(mxc_dma_srcdst_t srcdst);
300 
301 /**
302  * @brief      Get channel source, destination, and count for transfer
303  *
304  * @param      srcdst Pointer to struct with the correct channel number
305  *
306  * @return     See \ref MXC_Error_Codes for a list of return values
307  */
308 
309 int MXC_DMA_GetSrcDst(mxc_dma_srcdst_t *srcdst);
310 
311 /**
312  * @brief      Set channel reload source, destination, and count for the transfer
313  * @param      srcdstReload Struct containing the channel, source, destination, and count for the channel
314  * @note       Unless the channel request select is #mxc_dma_srcdst_t = MXC_DMA_REQUEST_MEMTOMEM,
315  *             either src_addr or dst_addr will be ignored by the DMA engine.
316  *             In these cases, the address is a don't-care. See the User's
317  *             Guide for more information.
318  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
319  */
320 int MXC_DMA_SetSrcReload(mxc_dma_srcdst_t srcdstReload);
321 
322 /**
323  * @brief      Get channel reload source, destination, and count for transfer
324  *
325  * @param      srcdstReload Pointer to struct with the correct channel number
326  *
327  * @return     See \ref MXC_Error_Codes for a list of return values
328  */
329 int MXC_DMA_GetSrcReload(mxc_dma_srcdst_t *srcdstReload);
330 
331 /**
332  * @brief      Set channel interrupt callback
333  * @param      ch        channel handle
334  * @param      callback  Pointer to a function to call when the channel
335  *                       interrupt flag is set and interrupts are enabled or
336  *                       when DMA is shutdown by the driver.
337  * @details    Configures the channel interrupt callback. The @p callback
338  *             function is called for two conditions:
339  *               -# When the channel's interrupt flag is set and DMA interrupts
340  *                  are enabled.
341  *               -# If the driver calls the DMA_Shutdown() function. The
342  *                  callback function prototype is:
343  * @code
344  *             void callback_fn(int ch, int reason);
345  * @endcode
346  *             @p ch indicates the channel that generated the callback, @p
347  *             reason is either #E_NO_ERROR for a DMA interrupt or #E_SHUTDOWN
348  *             if the DMA is being shutdown.
349  *
350  * @return     #E_BAD_PARAM if an unused or invalid channel handle
351  * @return     #E_NO_ERROR otherwise
352  */
353 int MXC_DMA_SetCallback(int ch, void (*callback)(int, int));
354 
355 /**
356  * @brief      Set channel interrupt
357  * @note       Each channel has two interrupts (complete, and count to zero).
358  *             To enable complete, pass true for chdis. To enable count to zero,
359  *             pass true for ctz.
360  * @param      ch Channel Handle
361  * @param      chdis Enable channel complete interrupt
362  * @param      ctz Enable channel count to zero interrupt.
363  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
364  */
365 int MXC_DMA_SetChannelInterruptEn(int ch, bool chdis, bool ctz);
366 
367 /**
368  * @brief      Enable channel interrupt
369  * @note       Each channel has two interrupts (complete, and count to zero)
370                which must also be enabled with MXC_DMA_SetChannelInterruptEn()
371  * @param      ch   channel handle
372  * @param      flags The flags to enable
373  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
374  */
375 int MXC_DMA_ChannelEnableInt(int ch, int flags);
376 
377 /**
378  * @brief      Disable channel interrupt
379  * @param      ch   channel handle
380  * @param      flags The flags to disable
381  * @return     #E_BAD_PARAM if an unused or invalid channel handle, #E_NO_ERROR otherwise
382  */
383 int MXC_DMA_ChannelDisableInt(int ch, int flags);
384 
385 /**
386  * @brief Read channel interrupt flags
387  * @param      ch channel handle
388  * @return    #E_BAD_PARAM if an unused or invalid channel handle
389  * @return    The flags set on the specified channel, otherwise
390  */
391 int MXC_DMA_ChannelGetFlags(int ch);
392 
393 /**
394  * @brief      Clear channel interrupt flags
395  * @param      ch    channel handle
396  * @param      flags flags to clear
397  * @return     #E_BAD_PARAM if an unused or invalid channel handle
398  * @return     #E_NO_ERROR otherwise
399  */
400 int MXC_DMA_ChannelClearFlags(int ch, int flags);
401 
402 /**
403  * @brief      Enable channel interrupt
404  * @param      ch   channel handle
405  * @return     #E_BAD_PARAM if an unused or invalid channel handle
406  * @return     #E_NO_ERROR otherwise
407  */
408 int MXC_DMA_EnableInt(int ch);
409 
410 /**
411  * @brief      Disable channel interrupt
412  * @param      ch   channel handle
413  * @return     #E_BAD_PARAM if an unused or invalid channel handle
414  * @return     #E_NO_ERROR otherwise
415  */
416 int MXC_DMA_DisableInt(int ch);
417 
418 /**
419  * @brief      Start transfer
420  * @param      ch   channel handle
421  * @details    Start the DMA channel transfer, assumes that DMA_SetSrcDstCnt() has been called beforehand.
422  * @return     #E_BAD_PARAM if an unused or invalid channel handle
423  * @return     #E_NO_ERROR otherwise
424  */
425 int MXC_DMA_Start(int ch);
426 
427 /**
428  * @brief      Stop DMA transfer, irrespective of status (complete or in-progress)
429  * @param      ch   channel handle
430  * @return     #E_BAD_PARAM if an unused or invalid channel handle
431  * @return     #E_NO_ERROR otherwise
432  */
433 int MXC_DMA_Stop(int ch);
434 
435 /**
436  * @brief      Get a pointer to the DMA channel registers
437  * @param      ch   channel handle
438  * @details    If direct access to DMA channel registers is required, this
439  *             function can be used on a channel handle returned by DMA_AcquireChannel().
440  * @return     NULL if an unused or invalid channel handle, or a valid pointer otherwise
441  */
442 mxc_dma_ch_regs_t *MXC_DMA_GetCHRegs(int ch);
443 
444 /**
445  * @brief      Interrupt handler function
446  * @param      ch   channel handle
447  * @details    Call this function as the ISR for each DMA channel under driver control.
448  *             Interrupt flags for channel ch will be automatically cleared before return.
449  * @return     NULL if an unused or invalid channel handle, or a valid pointer otherwise
450  */
451 void MXC_DMA_Handler(void);
452 
453 /**
454  * @brief      Performs a memcpy, using DMA, optionally asynchronous
455  * @note       The user must have the DMA interrupt enabled and call
456  *             MXC_DMA_Handler() from the ISR.
457  *
458  * @param      dest     pointer to destination memory
459  * @param      src      pointer to source memory
460  * @param      len      number of bytes to copy
461  * @param      callback function to call when transfer is complete
462  *
463  * @return     see \ref MXC_Error_Codes
464  */
465 int MXC_DMA_MemCpy(void *dest, void *src, int len, mxc_dma_complete_cb_t callback);
466 
467 /**
468  * @brief      Performs a memcpy, using DMA, optionally asynchronous
469  * @note       The user must have the DMA interrupt enabled and call
470  *             MXC_DMA_Handler() from the ISR.
471  *
472  * @param      config   The channel config struct
473  * @param      firstSrcDst  The source, destination, and count for the first transfer
474  * @param      callback function is called when transfer is complete
475  *
476  * @return     see \ref MXC_Error_Codes
477  */
478 int MXC_DMA_DoTransfer(mxc_dma_config_t config, mxc_dma_srcdst_t firstSrcDst,
479                        mxc_dma_trans_chain_t callback);
480 /**
481  * For other functional uses of DMA (UART, SPI, etc) see the appropriate peripheral driver
482  */
483 
484 /**@} end of group dma */
485 #ifdef __cplusplus
486 }
487 #endif
488 
489 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_DMA_H_
490