1 /******************************************************************************
2  *  Filename:       udma.h
3  *
4  *  Description:    Defines and prototypes for the uDMA controller.
5  *
6  *  Copyright (c) 2022 Texas Instruments Incorporated
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions are met:
10  *
11  *  1) Redistributions of source code must retain the above copyright notice,
12  *     this list of conditions and the following disclaimer.
13  *
14  *  2) Redistributions in binary form must reproduce the above copyright notice,
15  *     this list of conditions and the following disclaimer in the documentation
16  *     and/or other materials provided with the distribution.
17  *
18  *  3) Neither the name of the copyright holder nor the names of its
19  *     contributors may be used to endorse or promote products derived from this
20  *     software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  *  POSSIBILITY OF SUCH DAMAGE.
33  *
34  ******************************************************************************/
35 
36 #ifndef __UDMA_H__
37 #define __UDMA_H__
38 
39 //*****************************************************************************
40 //
41 //! \addtogroup peripheral_group
42 //! @{
43 //! \addtogroup udma_api
44 //! @{
45 //
46 //*****************************************************************************
47 
48 //*****************************************************************************
49 //
50 // If building with a C++ compiler, make all of the definitions in this header
51 // have a C binding.
52 //
53 //*****************************************************************************
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 #include <stdbool.h>
59 #include <stdint.h>
60 #include "../inc/hw_types.h"
61 #include "../inc/hw_ints.h"
62 #include "../inc/hw_memmap.h"
63 #include "../inc/hw_dma.h"
64 #include "debug.h"
65 #include "interrupt.h"
66 
67 //*****************************************************************************
68 //
69 //! \brief A structure that defines an entry in the channel control table.
70 //!
71 //! These fields are used by the uDMA controller and normally it is not necessary for
72 //! software to directly read or write fields in the table.
73 //
74 //*****************************************************************************
75 typedef struct
76 {
77     volatile void *pSrcEndAddr; //!< The ending source address of the data transfer.
78     volatile void *pDstEndAddr; //!< The ending destination address of the data transfer.
79     volatile uint32_t control;  //!< The channel control mode.
80     volatile uint32_t spare;    //!< An unused location.
81 } uDMAControlTableEntry;
82 
83 //*****************************************************************************
84 //
85 //! \brief A helper macro for building scatter-gather task table entries.
86 //!
87 //! This macro is intended to be used to help populate a table of uDMA tasks
88 //! for a scatter-gather transfer. This macro will calculate the values for
89 //! the fields of a task structure entry based on the input parameters.
90 //!
91 //! There are specific requirements for the values of each parameter.  No
92 //! checking is done so it is up to the caller to ensure that correct values
93 //! are used for the parameters.
94 //!
95 //! This macro is intended to be used to initialize individual entries of
96 //! a structure of uDMAControlTableEntry type, like this:
97 //!
98 /*!
99 \verbatim
100   uDMAControlTableEntry MyTaskList[] =
101   {
102       uDMATaskStructEntry(Task1Count, UDMA_SIZE_8,
103                           UDMA_SRC_INC_8, MySourceBuf,
104                           UDMA_DST_INC_8, MyDestBuf,
105                           UDMA_ARB_8, UDMA_MODE_MEM_SCATTER_GATHER),
106       uDMATaskStructEntry(Task2Count, ... ),
107   }
108 \endverbatim
109 */
110 //! \param transferCount is the count of items to transfer for this task.
111 //! It must be in the range 1-1024.
112 //! \param itemSize is the bit size of the items to transfer for this task.
113 //! It must be one of:
114 //! - \ref UDMA_SIZE_8
115 //! - \ref UDMA_SIZE_16
116 //! - \ref UDMA_SIZE_32
117 //! \param srcIncrement is the bit size increment for source data.
118 //! It must be one of:
119 //! - \ref UDMA_SRC_INC_8
120 //! - \ref UDMA_SRC_INC_16
121 //! - \ref UDMA_SRC_INC_32
122 //! - \ref UDMA_SRC_INC_NONE
123 //! \param pSrcAddr is the starting address of the data to transfer.
124 //! \param dstIncrement is the bit size increment for destination data.
125 //! It must be one of:
126 //! - \ref UDMA_DST_INC_8
127 //! - \ref UDMA_DST_INC_16
128 //! - \ref UDMA_DST_INC_32
129 //! - \ref UDMA_DST_INC_NONE
130 //! \param pDstAddr is the starting address of the destination data.
131 //! \param arbSize is the arbitration size to use for the transfer task.
132 //! This is used to select the arbitration size in powers of 2, from 1 to 1024.
133 //! It must be one of:
134 //! - \ref UDMA_ARB_1
135 //! - \ref UDMA_ARB_2
136 //! - \ref UDMA_ARB_4
137 //! - ...
138 //! - \ref UDMA_ARB_1024
139 //! \param mode is the transfer mode for this task.
140 //! Note that normally all tasks will be one of the scatter-gather modes while the
141 //! last task is a task list will be AUTO or BASIC.
142 //! It must be one of:
143 //! - \ref UDMA_MODE_BASIC
144 //! - \ref UDMA_MODE_AUTO
145 //! - \ref UDMA_MODE_MEM_SCATTER_GATHER
146 //! - \ref UDMA_MODE_PER_SCATTER_GATHER
147 //!
148 //! \return None (this is not a function)
149 //
150 //*****************************************************************************
151 #define uDMATaskStructEntry(transferCount, itemSize, srcIncrement, pSrcAddr, dstIncrement, pDstAddr, arbSize, mode) \
152     {                                                                                                               \
153         (((srcIncrement) == UDMA_SRC_INC_NONE)                                                                      \
154              ? (pSrcAddr)                                                                                           \
155              : ((void *)(&((uint8_t *)(pSrcAddr))[((transferCount) << ((srcIncrement) >> 26)) - 1]))),              \
156             (((dstIncrement) == UDMA_DST_INC_NONE)                                                                  \
157                  ? (pDstAddr)                                                                                       \
158                  : ((void *)(&((uint8_t *)(pDstAddr))[((transferCount) << ((dstIncrement) >> 30)) - 1]))),          \
159             (srcIncrement) | (dstIncrement) | (itemSize) | (arbSize) | (((transferCount)-1) << 4) |                 \
160                 ((((mode) == UDMA_MODE_MEM_SCATTER_GATHER) || ((mode) == UDMA_MODE_PER_SCATTER_GATHER))             \
161                      ? (mode) | UDMA_MODE_ALT_SELECT                                                                \
162                      : (mode)),                                                                                     \
163             0                                                                                                       \
164     }
165 
166 //*****************************************************************************
167 //
168 // The hardware configured number of uDMA channels.
169 //
170 //*****************************************************************************
171 #define UDMA_NUM_CHANNELS 8
172 
173 //*****************************************************************************
174 //
175 // The level of priority for the uDMA channels
176 //
177 //*****************************************************************************
178 #define UDMA_PRIORITY_LOW  0x00000000
179 #define UDMA_PRIORITY_HIGH 0x00000001
180 
181 //*****************************************************************************
182 //
183 // Flags that can be passed to uDMAEnableChannelAttribute(),
184 // uDMADisableChannelAttribute(), and returned from uDMAGetChannelAttribute().
185 //
186 //*****************************************************************************
187 #define UDMA_ATTR_USEBURST      0x00000001
188 #define UDMA_ATTR_ALTSELECT     0x00000002
189 #define UDMA_ATTR_HIGH_PRIORITY 0x00000004
190 #define UDMA_ATTR_REQMASK       0x00000008
191 #define UDMA_ATTR_ALL           0x0000000F
192 
193 //*****************************************************************************
194 //
195 // DMA control modes that can be passed to uDMASetChannelTransfer() and returned
196 // from uDMAGetChannelMode().
197 //
198 //*****************************************************************************
199 #define UDMA_MODE_STOP               0x00000000
200 #define UDMA_MODE_BASIC              0x00000001
201 #define UDMA_MODE_AUTO               0x00000002
202 #define UDMA_MODE_PINGPONG           0x00000003
203 #define UDMA_MODE_MEM_SCATTER_GATHER 0x00000004
204 #define UDMA_MODE_PER_SCATTER_GATHER 0x00000006
205 #define UDMA_MODE_M                  0x00000007 // uDMA Transfer Mode
206 #define UDMA_MODE_ALT_SELECT         0x00000001
207 
208 //*****************************************************************************
209 //
210 // Channel configuration values that can be passed to uDMASetChannelControl().
211 //
212 //*****************************************************************************
213 #define UDMA_DST_INC_8     0x00000000
214 #define UDMA_DST_INC_16    0x40000000
215 #define UDMA_DST_INC_32    0x80000000
216 #define UDMA_DST_INC_NONE  0xC0000000
217 #define UDMA_DST_INC_M     0xC0000000 // Destination Address Increment
218 #define UDMA_DST_INC_S     30
219 #define UDMA_SRC_INC_8     0x00000000
220 #define UDMA_SRC_INC_16    0x04000000
221 #define UDMA_SRC_INC_32    0x08000000
222 #define UDMA_SRC_INC_NONE  0x0c000000
223 #define UDMA_SRC_INC_M     0x0C000000 // Source Address Increment
224 #define UDMA_SRC_INC_S     26
225 #define UDMA_SIZE_8        0x00000000
226 #define UDMA_SIZE_16       0x11000000
227 #define UDMA_SIZE_32       0x22000000
228 #define UDMA_SIZE_M        0x33000000 // Data Size
229 #define UDMA_SIZE_S        24
230 #define UDMA_ARB_1         0x00000000
231 #define UDMA_ARB_2         0x00004000
232 #define UDMA_ARB_4         0x00008000
233 #define UDMA_ARB_8         0x0000c000
234 #define UDMA_ARB_16        0x00010000
235 #define UDMA_ARB_32        0x00014000
236 #define UDMA_ARB_64        0x00018000
237 #define UDMA_ARB_128       0x0001c000
238 #define UDMA_ARB_256       0x00020000
239 #define UDMA_ARB_512       0x00024000
240 #define UDMA_ARB_1024      0x00028000
241 #define UDMA_ARB_M         0x0003C000 // Arbitration Size
242 #define UDMA_ARB_S         14
243 #define UDMA_NEXT_USEBURST 0x00000008
244 #define UDMA_XFER_SIZE_MAX 1024
245 #define UDMA_XFER_SIZE_M   0x00003FF0 // Transfer size
246 #define UDMA_XFER_SIZE_S   4
247 
248 //*****************************************************************************
249 //
250 // Channel numbers to be passed to API functions that require a channel number
251 // ID. On CC23x0 each uDMA channel is multiplexed between two different
252 // peripherals. The 1-to-1 mapping between UDMA channel and peripheral must be
253 // decided by the user and set in the event fabric registers EVTSVT.DMACH[x]SEL.
254 // The two valid peripherals for each channel are listed next to each channel's
255 // mask definition.
256 //
257 //*****************************************************************************
258 #define UDMA_CHANNEL_0_M 0x01 //!< UDMA channel 0 (SSI0_TX or UART0_RX)
259 #define UDMA_CHANNEL_1_M 0x02 //!< UDMA channel 1 (SSI0_RX or UART0_TX)
260 #define UDMA_CHANNEL_2_M 0x04 //!< UDMA channel 2 (LRFD or UART0_TX)
261 #define UDMA_CHANNEL_3_M 0x08 //!< UDMA channel 3 (ADC0 or UART0_RX)
262 #define UDMA_CHANNEL_4_M 0x10 //!< UDMA channel 4 (AES_A or LRFD)
263 #define UDMA_CHANNEL_5_M 0x20 //!< UDMA channel 5 (AES_B or ADC0)
264 #define UDMA_CHANNEL_6_M 0x40 //!< UDMA channel 6 (Software Event Channel 0)
265 #define UDMA_CHANNEL_7_M 0x80 //!< UDMA channel 7 (Software Event Channel 1)
266 
267 //*****************************************************************************
268 //
269 // Flags to be OR'd with the channel ID to indicate if the primary or alternate
270 // control structure should be used.
271 //
272 //*****************************************************************************
273 #define UDMA_PRI_SELECT 0x00000000
274 #define UDMA_ALT_SELECT 0x00000008
275 
276 //*****************************************************************************
277 //
278 // API Functions and prototypes
279 //
280 //*****************************************************************************
281 
282 //*****************************************************************************
283 //
284 //! \brief Enables the uDMA controller for use.
285 //!
286 //! This function enables the uDMA controller. The uDMA controller must be
287 //! enabled before it can be configured and used.
288 //!
289 //! \return None
290 //
291 //*****************************************************************************
uDMAEnable(void)292 __STATIC_INLINE void uDMAEnable(void)
293 {
294     // Set the master enable bit in the config register.
295     HWREG(DMA_BASE + DMA_O_CFG) = DMA_CFG_MASTERENABLE;
296 }
297 
298 //*****************************************************************************
299 //
300 //! \brief Disables the uDMA controller for use.
301 //!
302 //! This function disables the uDMA controller.  Once disabled, the uDMA
303 //! controller will not operate until re-enabled with \ref uDMAEnable().
304 //!
305 //! \return None.
306 //
307 //*****************************************************************************
uDMADisable(void)308 __STATIC_INLINE void uDMADisable(void)
309 {
310     // Clear the master enable bit in the config register.
311     HWREG(DMA_BASE + DMA_O_CFG) = 0;
312 }
313 
314 //*****************************************************************************
315 //
316 //! \brief Gets the uDMA error status.
317 //!
318 //! This function returns the uDMA error status. It should be called from
319 //! within the uDMA error interrupt handler to determine if a uDMA error
320 //! occurred.
321 //!
322 //! \return Returns non-zero if a uDMA error is pending.
323 //
324 //*****************************************************************************
uDMAGetErrorStatus(void)325 __STATIC_INLINE uint32_t uDMAGetErrorStatus(void)
326 {
327     // Return the uDMA error status.
328     return (HWREG(DMA_BASE + DMA_O_ERROR));
329 }
330 
331 //*****************************************************************************
332 //
333 //! \brief Clears the uDMA error interrupt.
334 //!
335 //! This function clears a pending uDMA error interrupt. It should be called
336 //! from within the uDMA error interrupt handler to clear the interrupt.
337 //!
338 //! \return None
339 //
340 //*****************************************************************************
uDMAClearErrorStatus(void)341 __STATIC_INLINE void uDMAClearErrorStatus(void)
342 {
343     // Clear the uDMA error interrupt.
344     HWREG(DMA_BASE + DMA_O_ERROR) = DMA_ERROR_STATUS;
345 }
346 
347 //*****************************************************************************
348 //
349 //! \brief Enables a uDMA channel for operation.
350 //!
351 //! This function enables the specified uDMA channels for use. This function must
352 //! be used to enable a channel before it can be used to perform a uDMA
353 //! transfer.
354 //!
355 //! When a uDMA transfer is completed, the channel will be automatically
356 //! disabled by the uDMA controller. Therefore, this function should be called
357 //! prior to starting up any new transfer.
358 //!
359 //! \param channelBitMask is the bitmask of the channels to enable.
360 //!
361 //! \return None
362 //
363 //*****************************************************************************
uDMAEnableChannel(uint32_t channelBitMask)364 __STATIC_INLINE void uDMAEnableChannel(uint32_t channelBitMask)
365 {
366     HWREG(DMA_BASE + DMA_O_SETCHANNELEN) = channelBitMask;
367 }
368 
369 //*****************************************************************************
370 //
371 //! \brief Disables a uDMA channel for operation.
372 //!
373 //! This function disables the specified uDMA channels. Once disabled, a channel
374 //! will not respond to uDMA transfer requests until re-enabled via
375 //! \ref uDMAEnableChannel().
376 //!
377 //! \param channelBitMask is the bitmask of the channels to disable.
378 //!
379 //! \return None.
380 //
381 //*****************************************************************************
uDMADisableChannel(uint32_t channelBitMask)382 __STATIC_INLINE void uDMADisableChannel(uint32_t channelBitMask)
383 {
384     HWREG(DMA_BASE + DMA_O_CLEARCHANNELEN) = channelBitMask;
385 }
386 
387 //*****************************************************************************
388 //
389 //! \brief Checks if a uDMA channel is enabled for operation.
390 //!
391 //! This function checks to see if a specific uDMA channel is enabled.  This
392 //! can be used to check the status of a transfer, since the channel will
393 //! be automatically disabled at the end of a transfer. Note that if multiple
394 //! channels are specified in the bitmask, the return value will be true if at
395 //! least one channel is enabled.
396 //!
397 //! \param channelBitMask is the bitmask of the channel to check.
398 //!
399 //! \return Returns status of uDMA channel.
400 //! - \c true  : Channel is enabled.
401 //! - \c false : Channel is disabled.
402 //
403 //*****************************************************************************
uDMAIsChannelEnabled(uint32_t channelBitMask)404 __STATIC_INLINE bool uDMAIsChannelEnabled(uint32_t channelBitMask)
405 {
406     return ((HWREG(DMA_BASE + DMA_O_SETCHANNELEN) & (channelBitMask)) ? true : false);
407 }
408 
409 //*****************************************************************************
410 //
411 //! \brief Sets the base address for the channel control table.
412 //!
413 //! This function sets the base address of the channel control table. This
414 //! table resides in system memory and holds control information for each uDMA
415 //! channel.  The table must be aligned on a 1024 byte boundary. The base
416 //! address must be set before any of the channel functions can be used.
417 //! Setting the base address of the primary control table will automatically
418 //! set the address for the alternate control table as the next memory
419 //! location after the primary control table.
420 //!
421 //! The size of the channel control table depends on the number of uDMA
422 //! channels, and which transfer modes are used.  Refer to the introductory
423 //! text and the microcontroller datasheet for more information about the
424 //! channel control table.
425 //!
426 //! \note This register cannot be read when the controller is in the reset
427 //! state.
428 //!
429 //! \param pControlTable is a pointer to the 1024 byte aligned base address
430 //! of the uDMA channel control table. The address must be an absolute address
431 //! in system memory space.
432 //!
433 //! \return None
434 //
435 //*****************************************************************************
uDMASetControlBase(void * pControlTable)436 __STATIC_INLINE void uDMASetControlBase(void *pControlTable)
437 {
438     // Check the arguments.
439     ASSERT(((uint32_t)pControlTable & ~0x3FF) == (uint32_t)pControlTable);
440     ASSERT((uint32_t)pControlTable >= SRAM_BASE);
441 
442     // Program the base address into the register.
443     HWREG(DMA_BASE + DMA_O_CTRL) = (uint32_t)pControlTable;
444 }
445 
446 //*****************************************************************************
447 //
448 //! \brief Gets the base address for the channel control table.
449 //!
450 //! This function gets the base address of the channel control table.  This
451 //! table resides in system memory and holds control information for each uDMA
452 //! channel.
453 //!
454 //! \return Returns a pointer to the base address of the channel control table.
455 //
456 //*****************************************************************************
uDMAGetControlBase(void)457 __STATIC_INLINE void *uDMAGetControlBase(void)
458 {
459     // Read the current value of the control base register, and return it to
460     // the caller.
461     return ((void *)HWREG(DMA_BASE + DMA_O_CTRL));
462 }
463 
464 //*****************************************************************************
465 //
466 //! \brief Gets the base address for the channel control table alternate structures.
467 //!
468 //! This function gets the base address of the second half of the channel
469 //! control table that holds the alternate control structures for each channel.
470 //!
471 //! \return Returns a pointer to the base address of the second half of the
472 //! channel control table.
473 //
474 //*****************************************************************************
uDMAGetControlAlternateBase(void)475 __STATIC_INLINE void *uDMAGetControlAlternateBase(void)
476 {
477     // Read the current value of the control base register, and return it to
478     // the caller.
479     return ((void *)HWREG(DMA_BASE + DMA_O_ALTCTRL));
480 }
481 
482 //*****************************************************************************
483 //
484 //! \brief Requests a uDMA channel to start a transfer.
485 //!
486 //! This function allows software to request a uDMA channel to begin a
487 //! transfer. This could be used for performing a memory to memory transfer,
488 //! or if for some reason a transfer needs to be initiated by software instead
489 //! of the peripheral associated with that channel.
490 //!
491 //! \note If the channel is a software channel and interrupts are used, then
492 //! the completion will be signaled on the uDMA dedicated interrupt. If a
493 //! peripheral channel is used, then the completion will be signaled on the
494 //! peripheral's interrupt.
495 //!
496 //! \param channelBitMask is the bitmask of the channel on which to request a
497 //!        uDMA transfer.
498 //!
499 //! \return None.
500 //
501 //*****************************************************************************
uDMARequestChannel(uint32_t channelBitMask)502 __STATIC_INLINE void uDMARequestChannel(uint32_t channelBitMask)
503 {
504     // Set the bit for this channel in the software uDMA request register.
505     HWREG(DMA_BASE + DMA_O_SOFTREQ) = channelBitMask;
506 }
507 
508 //*****************************************************************************
509 //
510 //! \brief Enables attributes of a uDMA channel.
511 //!
512 //! This function is used to enable attributes of a uDMA channel.
513 //!
514 //! \param channelBitMask is bitmask of the channel to configure.
515 //! \param attr is a combination of attributes for the channel.
516 //! The parameter is the bitwise OR of any of the following:
517 //! - \ref UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst mode.
518 //! - \ref UDMA_ATTR_ALTSELECT is used to select the alternate control structure
519 //! for this channel (it is very unlikely that this flag should be used).
520 //! - \ref UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
521 //! - \ref UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
522 //! peripheral for this channel.
523 //!
524 //! \return None
525 //
526 //*****************************************************************************
527 extern void uDMAEnableChannelAttribute(uint32_t channelBitMask, uint32_t attr);
528 
529 //*****************************************************************************
530 //
531 //! \brief Disables attributes of an uDMA channel.
532 //!
533 //! This function is used to disable attributes of a uDMA channel.
534 //!
535 //! \param channelBitMask is bitmask of the channel to configure.
536 //! \param attr is a combination of attributes for the channel.
537 //! The parameter is the bitwise OR of any of the following:
538 //! - \ref UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst mode.
539 //! - \ref UDMA_ATTR_ALTSELECT is used to select the alternate control structure
540 //! for this channel (it is very unlikely that this flag should be used).
541 //! - \ref UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
542 //! - \ref UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
543 //! peripheral for this channel.
544 //!
545 //! \return None
546 //
547 //*****************************************************************************
548 extern void uDMADisableChannelAttribute(uint32_t channelBitMask, uint32_t attr);
549 
550 //*****************************************************************************
551 //
552 //! \brief Gets the enabled attributes of a uDMA channel.
553 //!
554 //! This function returns a combination of flags representing the attributes of
555 //! the uDMA channel.
556 //!
557 //! \param channelBitMask is the bitmask of the channel to configure.
558 //!
559 //! \return Returns the bitwise OR of the attributes of the uDMA channel, which
560 //! can be any of the following:
561 //! - \ref UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst mode.
562 //! - \ref UDMA_ATTR_ALTSELECT is used to select the alternate control structure
563 //! for this channel (it is very unlikely that this flag should be used).
564 //! - \ref UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
565 //! - \ref UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
566 //! peripheral for this channel.
567 //
568 //*****************************************************************************
569 extern uint32_t uDMAGetChannelAttribute(uint32_t channelBitMask);
570 
571 //*****************************************************************************
572 //
573 //! \brief Sets the control parameters for a uDMA channel control structure.
574 //!
575 //! This function is used to set control parameters for a uDMA transfer.  These
576 //! are typically parameters that are not changed often.
577 //!
578 //! \note The address increment cannot be smaller than the data size.
579 //!
580 //! \param pChannelControlStruct is a pointer to the primary or alternate
581 //! control table of the uDMA channel to be set.
582 //! \param control is the bitwise OR of five values:
583 //! - Data size
584 //!   - \ref UDMA_SIZE_8  : 8 bits.
585 //!   - \ref UDMA_SIZE_16 : 16 bits.
586 //!   - \ref UDMA_SIZE_32 : 32 bits.
587 //! - Source address increment
588 //!   - \ref UDMA_SRC_INC_8    : 8 bits.
589 //!   - \ref UDMA_SRC_INC_16   : 16 bits.
590 //!   - \ref UDMA_SRC_INC_32   : 32 bits.
591 //!   - \ref UDMA_SRC_INC_NONE : Non-incrementing.
592 //! - Destination address increment
593 //!   - \ref UDMA_DST_INC_8    : 8 bits.
594 //!   - \ref UDMA_DST_INC_16   : 16 bits.
595 //!   - \ref UDMA_DST_INC_32   : 32 bits.
596 //!   - \ref UDMA_DST_INC_NONE : Non-incrementing.
597 //! - Arbitration size. Determines how many items are transferred before
598 //! the uDMA controller re-arbitrates for the bus. In power of 2.
599 //!   - \ref UDMA_ARB_1
600 //!   - \ref UDMA_ARB_2
601 //!   - \ref UDMA_ARB_4
602 //!   - \ref UDMA_ARB_8
603 //!   - ...
604 //!   - \ref UDMA_ARB_1024
605 //! - Force the channel to only respond to burst requests at the tail end of a scatter-gather transfer.
606 //!   - \ref UDMA_NEXT_USEBURST
607 //!
608 //! \return None
609 //
610 //*****************************************************************************
611 extern void uDMASetChannelControl(volatile uDMAControlTableEntry *pChannelControlStruct, uint32_t control);
612 
613 //*****************************************************************************
614 //
615 //! \brief Sets the transfer parameters for a uDMA channel control structure.
616 //!
617 //! This function is used to set the parameters for a uDMA transfer.  These are
618 //! typically parameters that are changed often. The function
619 //! \ref uDMASetChannelControl() MUST be called at least once for this channel prior
620 //! to calling this function.
621 //!
622 //! The \c pSrcAddr and \c pDstAddr parameters are pointers to the first
623 //! location of the data to be transferred. These addresses should be aligned
624 //! according to the item size. The compiler will take care of this if the
625 //! pointers are pointing to storage of the appropriate data type.
626 //!
627 //! The two scatter/gather modes, MEMORY and PERIPHERAL, are actually different
628 //! depending on whether the primary or alternate control structure is
629 //! selected. This function will recognize from the address of the
630 //! \c pChannelControlStruct if it's a primary or alternate control structure and
631 //! will set the scatter/gather mode as appropriate for it.
632 //!
633 //! The channel must also be enabled using \ref uDMAEnableChannel() after calling
634 //! this function. The transfer will not begin until the channel has been set
635 //! up and enabled. Note that the channel is automatically disabled after the
636 //! transfer is completed, meaning that \ref uDMAEnableChannel() must be called
637 //! again after setting up the next transfer.
638 //!
639 //! \note Great care must be taken to not modify a channel control structure
640 //! that is in use or else the results will be unpredictable, including the
641 //! possibility of undesired data transfers to or from memory or peripherals.
642 //! For BASIC and AUTO modes, it is safe to make changes when the channel is
643 //! disabled, or the \ref uDMAGetChannelMode() returns \ref UDMA_MODE_STOP. For
644 //! PINGPONG or one of the SCATTER_GATHER modes, it is safe to modify the
645 //! primary or alternate control structure only when the other is being used.
646 //! The \ref uDMAGetChannelMode() function will return \ref UDMA_MODE_STOP when a
647 //! channel control structure is inactive and safe to modify.
648 //!
649 //! \param pChannelControlStruct is a pointer to the primary or alternate
650 //! control table of the uDMA channel to be set.
651 //! \param mode is the type of uDMA transfer.
652 //! The parameter should be one of the following values:
653 //! - \ref UDMA_MODE_STOP     : Stops the uDMA transfer. The controller sets the mode
654 //! to this value at the end of a transfer.
655 //! - \ref UDMA_MODE_BASIC    : Perform a basic transfer based on request.
656 //! - \ref UDMA_MODE_AUTO to perform a transfer that will always complete once
657 //! started even if request is removed.
658 //! - \ref UDMA_MODE_PINGPONG : Set up a transfer that switches between the
659 //! primary and alternate control structures for the channel. This allows
660 //! use of ping-pong buffering for uDMA transfers.
661 //! - \ref UDMA_MODE_MEM_SCATTER_GATHER : Set up a memory scatter-gather transfer.
662 //! - \ref UDMA_MODE_PER_SCATTER_GATHER : Set up a peripheral scatter-gather transfer.
663 //! \param pSrcAddr is the source address for the transfer.
664 //! \param pDstAddr is the destination address for the transfer.
665 //! \param transferSize is the number of data items to transfer (\b NOT bytes).
666 //!
667 //! \return None
668 //
669 //*****************************************************************************
670 extern void uDMASetChannelTransfer(volatile uDMAControlTableEntry *pChannelControlStruct,
671                                    uint32_t mode,
672                                    void *pSrcAddr,
673                                    void *pDstAddr,
674                                    uint32_t transferSize);
675 
676 //*****************************************************************************
677 //
678 //! \brief Gets the current transfer size for a uDMA channel control structure.
679 //!
680 //! This function is used to get the uDMA transfer size for a channel. The
681 //! transfer size is the number of items to transfer, where the size of an item
682 //! might be 8, 16, or 32 bits. If a partial transfer has already occurred,
683 //! then the number of remaining items will be returned. If the transfer is
684 //! complete, then 0 will be returned.
685 //!
686 //! \param pChannelControlStruct is a pointer to the primary or alternate
687 //! control table of the uDMA channel in use.
688 //!
689 //! \return Returns the number of items remaining to transfer.
690 //
691 //*****************************************************************************
692 extern uint32_t uDMAGetChannelSize(volatile uDMAControlTableEntry const *pChannelControlStruct);
693 
694 //*****************************************************************************
695 //
696 //! \brief Gets the transfer mode for a uDMA channel control structure.
697 //!
698 //! This function is used to get the transfer mode for the uDMA channel. It
699 //! can be used to query the status of a transfer on a channel. When the
700 //! transfer is complete the mode will be \ref UDMA_MODE_STOP.
701 //!
702 //! \param pChannelControlStruct is a pointer to the primary or alternate
703 //! control table of the uDMA channel in use.
704 //!
705 //! \return Returns the transfer mode of the specified channel and control
706 //! structure, which will be one of the following values:
707 //! - \ref UDMA_MODE_STOP
708 //! - \ref UDMA_MODE_BASIC
709 //! - \ref UDMA_MODE_AUTO
710 //! - \ref UDMA_MODE_PINGPONG
711 //! - \ref UDMA_MODE_MEM_SCATTER_GATHER
712 //! - \ref UDMA_MODE_PER_SCATTER_GATHER
713 //
714 //*****************************************************************************
715 extern uint32_t uDMAGetChannelMode(volatile uDMAControlTableEntry const *pChannelControlStruct);
716 
717 //*****************************************************************************
718 //
719 //! \brief Registers an interrupt handler for the uDMA controller in the dynamic interrupt table.
720 //!
721 //! \note Only use this function if you want to use the dynamic vector table (in SRAM)!
722 //!
723 //! This function registers a function as the interrupt handler for a specific
724 //! interrupt and enables the corresponding interrupt in the interrupt controller.
725 //!
726 //! \note The interrupt handler for uDMA is for transfer completion when the
727 //! software channel is used. The interrupts for each peripheral channel are
728 //! handled through the individual peripheral interrupt handlers.
729 //!
730 //! \param intChannel specifies which uDMA interrupt is to be registered.
731 //! - \c INT_DMA_DONE_COMB : Register an interrupt handler to process interrupts
732 //!   from the uDMA software channel.
733 //! \param pfnHandler is a pointer to the function to be called when the
734 //! interrupt is activated.
735 //!
736 //! \return None
737 //!
738 //! \sa \ref IntRegister() for important information about registering interrupt
739 //! handlers.
740 //
741 //*****************************************************************************
uDMARegisterInt(uint32_t intChannel,void (* pfnHandler)(void))742 __STATIC_INLINE void uDMARegisterInt(uint32_t intChannel, void (*pfnHandler)(void))
743 {
744     // Check the arguments.
745     ASSERT(pfnHandler);
746     ASSERT(intChannel == INT_DMA_DONE_COMB);
747 
748     // Register the interrupt handler.
749     IntRegister(intChannel, pfnHandler);
750 
751     // Enable the memory management fault.
752     IntEnable(intChannel);
753 }
754 
755 //*****************************************************************************
756 //
757 //! \brief Unregisters an interrupt handler for the uDMA controller in the dynamic interrupt table.
758 //!
759 //! This function will disable and clear the handler to be called for the
760 //! specified uDMA interrupt.
761 //!
762 //! \param intChannel specifies which uDMA interrupt to unregister.
763 //! - \c INT_DMA_DONE_COMB : Register an interrupt handler to process interrupts
764 //!   from the uDMA software channel.
765 //!
766 //! \return None
767 //!
768 //! \sa \ref IntRegister() for important information about registering interrupt
769 //! handlers.
770 //
771 //*****************************************************************************
uDMAUnregisterInt(uint32_t intChannel)772 __STATIC_INLINE void uDMAUnregisterInt(uint32_t intChannel)
773 {
774     // Check the arguments.
775     ASSERT(intChannel == INT_DMA_DONE_COMB);
776 
777     // Disable the interrupt.
778     IntDisable(intChannel);
779 
780     // Unregister the interrupt handler.
781     IntUnregister(intChannel);
782 }
783 
784 //*****************************************************************************
785 //
786 //! \brief Clears uDMA interrupt done status.
787 //!
788 //! Clears bits in the uDMA interrupt status register according to which bits
789 //! are set in \c channelBitMask. There is one bit for each channel. If a a bit
790 //! is set in \c channelBitMask, then that corresponding channel's interrupt
791 //! status will be cleared (if it was set).
792 //!
793 //! \param channelBitMask is a mask with one bit for each uDMA channel.
794 //!
795 //! \return None
796 //
797 //*****************************************************************************
uDMAClearInt(uint32_t channelBitMask)798 __STATIC_INLINE void uDMAClearInt(uint32_t channelBitMask)
799 {
800     // Clear the requested bits in the uDMA interrupt status register.
801     HWREG(DMA_BASE + DMA_O_REQDONE) = channelBitMask;
802 }
803 
804 //*****************************************************************************
805 //
806 //! \brief Get the uDMA interrupt status.
807 //!
808 //! This function returns the interrupt status for the specified UDMA. This
809 //! function does not differentiate between software or hardware activated
810 //! interrupts.
811 //!
812 //! \return None
813 //
814 //*****************************************************************************
uDMAIntStatus(void)815 __STATIC_INLINE uint32_t uDMAIntStatus(void)
816 {
817     // Return the uDMA interrupt status register.
818     return (HWREG(DMA_BASE + DMA_O_REQDONE));
819 }
820 
821 //*****************************************************************************
822 //
823 //! \brief Enable interrupt on software event driven uDMA transfers.
824 //!
825 //! \note The main purpose of this function is to prevent propagation of uDMA
826 //! status signals to a peripheral, if a peripheral and a software event is
827 //! sharing the uDMA channel. If it is desired to initiate a transfer by
828 //! writing to a register inside the uDMA (this means a software driven
829 //! channel), then the uDMA status signals propagation need to be blocked to
830 //! the hardware peripherals.
831 //!
832 //! \param intChannel identifies which uDMA interrupt to enable software
833 //!        interrupts for.
834 //!
835 //! \return None
836 //
837 //*****************************************************************************
uDMAEnableSwEventInt(uint32_t intChannel)838 __STATIC_INLINE void uDMAEnableSwEventInt(uint32_t intChannel)
839 {
840     // Check the arguments.
841     ASSERT(intChannel < UDMA_NUM_CHANNELS);
842 
843     // Enable the channel.
844     HWREG(DMA_BASE + DMA_O_DONEMASK) |= intChannel;
845 }
846 
847 //*****************************************************************************
848 //
849 //! \brief Disable interrupt on software event driven uDMA transfers.
850 //!
851 //! This register disables the blocking of the uDMA status signals propagation
852 //! to the hardware peripheral connected to the uDMA on the \c intChannel.
853 //!
854 //! \param intChannel identifies which uDMA interrupt to disable software
855 //!        interrupts for.
856 //!
857 //! \return None
858 //!
859 //! \sa \ref uDMAEnableSwEventInt()
860 //
861 //*****************************************************************************
uDMADisableSwEventInt(uint32_t intChannel)862 __STATIC_INLINE void uDMADisableSwEventInt(uint32_t intChannel)
863 {
864     // Check the arguments.
865     ASSERT(intChannel < UDMA_NUM_CHANNELS);
866 
867     // Disable the SW channel.
868     HWREG(DMA_BASE + DMA_O_DONEMASK) &= ~intChannel;
869 }
870 
871 //*****************************************************************************
872 //
873 //! \brief Return the status of the uDMA module.
874 //!
875 //! \note This status register cannot be read when the controller is in the reset state.
876 //!
877 //! \return Current status of the uDMA module.
878 //
879 //*****************************************************************************
uDMAGetStatus(void)880 __STATIC_INLINE uint32_t uDMAGetStatus(void)
881 {
882     // Read and return the status register.
883     return HWREG(DMA_BASE + DMA_O_STATUS);
884 }
885 
886 //*****************************************************************************
887 //
888 //! \brief Set the priority of a uDMA channel.
889 //!
890 //! \note Writing 0 to a bit has no effect on the priority. To reset a channel
891 //! priority to the default value use \ref uDMAClearChannelPriority().
892 //!
893 //! \param channelBitMask is bitmask of the uDMA channel to set the priority for.
894 //!
895 //! \return None
896 //
897 //*****************************************************************************
uDMASetChannelPriority(uint32_t channelBitMask)898 __STATIC_INLINE void uDMASetChannelPriority(uint32_t channelBitMask)
899 {
900     // Set the channel priority to high.
901     HWREG(DMA_BASE + DMA_O_SETCHNLPRIORITY) = channelBitMask;
902 }
903 
904 //*****************************************************************************
905 //
906 //! \brief Get the priority of a uDMA channel.
907 //!
908 //! \param channelBitMask The bitmask of the uDMA channel to get the priority for.
909 //!
910 //! \return Returns one of:
911 //! - \ref UDMA_PRIORITY_HIGH
912 //! - \ref UDMA_PRIORITY_LOW
913 //
914 //*****************************************************************************
uDMAGetChannelPriority(uint32_t channelBitMask)915 __STATIC_INLINE bool uDMAGetChannelPriority(uint32_t channelBitMask)
916 {
917     // Return the channel priority.
918     return (HWREG(DMA_BASE + DMA_O_SETCHNLPRIORITY) & (channelBitMask) ? UDMA_PRIORITY_HIGH : UDMA_PRIORITY_LOW);
919 }
920 
921 //*****************************************************************************
922 //
923 //! \brief Clear the priority of a uDMA channel.
924 //!
925 //! \note Writing 0 to a bit has no effect on the priority. To set a channel
926 //! priority to high use \ref uDMASetChannelPriority().
927 //!
928 //! \param channelBitMask The bitmask of the uDMA channel to clear the priority for.
929 //!
930 //! \return None
931 //
932 //*****************************************************************************
uDMAClearChannelPriority(uint32_t channelBitMask)933 __STATIC_INLINE void uDMAClearChannelPriority(uint32_t channelBitMask)
934 {
935     // Clear the channel priority.
936     HWREG(DMA_BASE + DMA_O_CLEARCHNLPRIORITY) = channelBitMask;
937 }
938 
939 //*****************************************************************************
940 //
941 // Mark the end of the C bindings section for C++ compilers.
942 //
943 //*****************************************************************************
944 #ifdef __cplusplus
945 }
946 #endif
947 
948 //*****************************************************************************
949 //
950 //! Close the Doxygen group.
951 //! @}
952 //! @}
953 //
954 //*****************************************************************************
955 
956 #endif //  __UDMA_H__
957