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