1 //*****************************************************************************
2 //
3 // udma.c - Driver for the micro-DMA controller.
4 //
5 // Copyright (c) 2007-2017 Texas Instruments Incorporated.  All rights reserved.
6 // Software License Agreement
7 //
8 //   Redistribution and use in source and binary forms, with or without
9 //   modification, are permitted provided that the following conditions
10 //   are met:
11 //
12 //   Redistributions of source code must retain the above copyright
13 //   notice, this list of conditions and the following disclaimer.
14 //
15 //   Redistributions in binary form must reproduce the above copyright
16 //   notice, this list of conditions and the following disclaimer in the
17 //   documentation and/or other materials provided with the
18 //   distribution.
19 //
20 //   Neither the name of Texas Instruments Incorporated nor the names of
21 //   its contributors may be used to endorse or promote products derived
22 //   from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 //*****************************************************************************
37 
38 //*****************************************************************************
39 //
40 //! \addtogroup udma_api
41 //! @{
42 //
43 //*****************************************************************************
44 
45 #include "types.h"
46 #include <stdbool.h>
47 #include <stdint.h>
48 #include "inc/hw_sysctl.h"
49 #include "inc/hw_udma.h"
50 #include "debug.h"
51 #include "interrupt.h"
52 #include "udma.h"
53 
54 //*****************************************************************************
55 //
56 //! Initializes the uDMA for use.
57 //!
58 //! This function assigns a default peripheral mapping for uDMA channels 20-25.
59 //! This function must be called in order to prevent multiple channels from
60 //! being assigned to the same peripheral by moving these channels to an encoding
61 //! where they are in reserved status.
62 //!
63 //! \return None.
64 //
65 //*****************************************************************************
66 void
uDMAInit(void)67 uDMAInit(void)
68 {
69     uDMAChannelAssign(UDMA_CH20_RESERVED7);
70     uDMAChannelAssign(UDMA_CH21_RESERVED7);
71     uDMAChannelAssign(UDMA_CH22_RESERVED7);
72     uDMAChannelAssign(UDMA_CH23_RESERVED7);
73     uDMAChannelAssign(UDMA_CH24_RESERVED7);
74     uDMAChannelAssign(UDMA_CH25_RESERVED7);
75 }
76 //*****************************************************************************
77 //
78 //! Enables the uDMA controller for use.
79 //!
80 //! This function enables the uDMA controller.  The uDMA controller must be
81 //! enabled before it can be configured and used.
82 //!
83 //! \return None.
84 //
85 //*****************************************************************************
86 void
uDMAEnable(void)87 uDMAEnable(void)
88 {
89     //
90     // Set the master enable bit in the config register.
91     //
92     HWREG(UDMA_CFG) = UDMA_CFG_MASTEN;
93 }
94 
95 //*****************************************************************************
96 //
97 //! Disables the uDMA controller for use.
98 //!
99 //! This function disables the uDMA controller.  Once disabled, the uDMA
100 //! controller cannot operate until re-enabled with uDMAEnable().
101 //!
102 //! \return None.
103 //
104 //*****************************************************************************
105 void
uDMADisable(void)106 uDMADisable(void)
107 {
108     //
109     // Clear the master enable bit in the config register.
110     //
111     HWREG(UDMA_CFG) = 0;
112 }
113 
114 //*****************************************************************************
115 //
116 //! Gets the uDMA error status.
117 //!
118 //! This function returns the uDMA error status.  It should be called from
119 //! within the uDMA error interrupt handler to determine if a uDMA error
120 //! occurred.
121 //!
122 //! \return Returns non-zero if a uDMA error is pending.
123 //
124 //*****************************************************************************
125 uint32_t
uDMAErrorStatusGet(void)126 uDMAErrorStatusGet(void)
127 {
128     //
129     // Return the uDMA error status.
130     //
131     return (HWREG(UDMA_ERRCLR));
132 }
133 
134 //*****************************************************************************
135 //
136 //! Clears the uDMA error interrupt.
137 //!
138 //! This function clears a pending uDMA error interrupt.  This function should
139 //! be called from within the uDMA error interrupt handler to clear the
140 //! interrupt.
141 //!
142 //! \return None.
143 //
144 //*****************************************************************************
145 void
uDMAErrorStatusClear(void)146 uDMAErrorStatusClear(void)
147 {
148     //
149     // Clear the uDMA error interrupt.
150     //
151     HWREG(UDMA_ERRCLR) = 1;
152 }
153 
154 //*****************************************************************************
155 //
156 //! Enables a uDMA channel for operation.
157 //!
158 //! \param ui32ChannelNum is the channel number to enable.
159 //!
160 //! This function enables a specific uDMA channel for use.  This function must
161 //! be used to enable a channel before it can be used to perform a uDMA
162 //! transfer.
163 //!
164 //! When a uDMA transfer is completed, the channel is automatically disabled by
165 //! the uDMA controller.  Therefore, this function should be called prior to
166 //! starting up any new transfer.
167 //!
168 //! \return None.
169 //
170 //*****************************************************************************
171 void
uDMAChannelEnable(uint32_t ui32ChannelNum)172 uDMAChannelEnable(uint32_t ui32ChannelNum)
173 {
174     //
175     // Check the arguments.
176     //
177     ASSERT((ui32ChannelNum & 0xffff) < 32);
178 
179     //
180     // Set the bit for this channel in the enable set register.
181     //
182     HWREG(UDMA_ENASET) = 1 << (ui32ChannelNum & 0x1f);
183 }
184 
185 //*****************************************************************************
186 //
187 //! Disables a uDMA channel for operation.
188 //!
189 //! \param ui32ChannelNum is the channel number to disable.
190 //!
191 //! This function disables a specific uDMA channel.  Once disabled, a channel
192 //! cannot respond to uDMA transfer requests until re-enabled via
193 //! uDMAChannelEnable().
194 //!
195 //! \return None.
196 //
197 //*****************************************************************************
198 void
uDMAChannelDisable(uint32_t ui32ChannelNum)199 uDMAChannelDisable(uint32_t ui32ChannelNum)
200 {
201     //
202     // Check the arguments.
203     //
204     ASSERT((ui32ChannelNum & 0xffff) < 32);
205 
206     //
207     // Set the bit for this channel in the enable clear register.
208     //
209     HWREG(UDMA_ENACLR) = 1 << (ui32ChannelNum & 0x1f);
210 }
211 
212 //*****************************************************************************
213 //
214 //! Checks if a uDMA channel is enabled for operation.
215 //!
216 //! \param ui32ChannelNum is the channel number to check.
217 //!
218 //! This function checks to see if a specific uDMA channel is enabled.  This
219 //! function can be used to check the status of a transfer, as the channel is
220 //! automatically disabled at the end of a transfer.
221 //!
222 //! \return Returns \b true if the channel is enabled, \b false if disabled.
223 //
224 //*****************************************************************************
225 bool
uDMAChannelIsEnabled(uint32_t ui32ChannelNum)226 uDMAChannelIsEnabled(uint32_t ui32ChannelNum)
227 {
228     //
229     // Check the arguments.
230     //
231     ASSERT((ui32ChannelNum & 0xffff) < 32);
232 
233     //
234     // AND the specified channel bit with the enable register and return the
235     // result.
236     //
237     return ((HWREG(UDMA_ENASET) & (1 << (ui32ChannelNum & 0x1f))) ? true :
238             false);
239 }
240 
241 //*****************************************************************************
242 //
243 //! Sets the base address for the channel control table.
244 //!
245 //! \param psControlTable is a pointer to the 1024-byte-aligned base address
246 //! of the uDMA channel control table.
247 //!
248 //! This function configures the base address of the channel control table.
249 //! This table resides in system memory and holds control information for each
250 //! uDMA channel.  The table must be aligned on a 1024-byte boundary.  The base
251 //! address must be configured before any of the channel functions can be used.
252 //!
253 //! The size of the channel control table depends on the number of uDMA
254 //! channels and the transfer modes that are used. Refer to the technical
255 //! reference manual and the data sheet for more information about the channel
256 //! control table.
257 //!
258 //! \return None.
259 //
260 //*****************************************************************************
261 void
uDMAControlBaseSet(void * psControlTable)262 uDMAControlBaseSet(void *psControlTable)
263 {
264     //
265     // Check the arguments.
266     //
267     ASSERT(((uint32_t)psControlTable & ~0x3FF) ==
268            (uint32_t)psControlTable);
269     ASSERT((uint32_t)psControlTable >= 0x20000000);
270 
271     //
272     // Program the base address into the register.
273     //
274     HWREG(UDMA_CTLBASE) = (uint32_t)psControlTable;
275 }
276 
277 //*****************************************************************************
278 //
279 //! Gets the base address for the channel control table.
280 //!
281 //! This function gets the base address of the channel control table.  This
282 //! table resides in system memory and holds control information for each uDMA
283 //! channel.
284 //!
285 //! \return Returns a pointer to the base address of the channel control table.
286 //
287 //*****************************************************************************
288 void *
uDMAControlBaseGet(void)289 uDMAControlBaseGet(void)
290 {
291     //
292     // Read the current value of the control base register and return it to
293     // the caller.
294     //
295     return ((void *)HWREG(UDMA_CTLBASE));
296 }
297 
298 //*****************************************************************************
299 //
300 //! Gets the base address for the channel control table alternate structures.
301 //!
302 //! This function gets the base address of the second half of the channel
303 //! control table that holds the alternate control structures for each channel.
304 //!
305 //! \return Returns a pointer to the base address of the second half of the
306 //! channel control table.
307 //
308 //*****************************************************************************
309 void *
uDMAControlAlternateBaseGet(void)310 uDMAControlAlternateBaseGet(void)
311 {
312     //
313     // Read the current value of the control base register and return it to
314     // the caller.
315     //
316     return ((void *)HWREG(UDMA_ALTBASE));
317 }
318 
319 //*****************************************************************************
320 //
321 //! Requests a uDMA channel to start a transfer.
322 //!
323 //! \param ui32ChannelNum is the channel number on which to request a uDMA
324 //! transfer.
325 //!
326 //! This function allows software to request a uDMA channel to begin a
327 //! transfer.  This function could be used for performing a memory-to-memory
328 //! transfer, or if for some reason a transfer needs to be initiated by
329 //! software instead of the peripheral associated with that channel.
330 //!
331 //! \note If the channel is \b UDMA_CHANNEL_SW and interrupts are used, then
332 //! the completion is signaled on the uDMA dedicated interrupt.  If a
333 //! peripheral channel is used, then the completion is signaled on the
334 //! peripheral's interrupt.
335 //!
336 //! \return None.
337 //
338 //*****************************************************************************
339 void
uDMAChannelRequest(uint32_t ui32ChannelNum)340 uDMAChannelRequest(uint32_t ui32ChannelNum)
341 {
342     //
343     // Check the arguments.
344     //
345     ASSERT((ui32ChannelNum & 0xffff) < 32);
346 
347     //
348     // Set the bit for this channel in the software uDMA request register.
349     //
350     HWREG(UDMA_SWREQ) = 1 << (ui32ChannelNum & 0x1f);
351 }
352 
353 //*****************************************************************************
354 //
355 //! Enables attributes of a uDMA channel.
356 //!
357 //! \param ui32ChannelNum is the channel to configure.
358 //! \param ui32Attr is a combination of attributes for the channel.
359 //!
360 //! This function is used to enable attributes of a uDMA channel.
361 //!
362 //! The \e ui32Attr parameter is the logical OR of any of the following:
363 //!
364 //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
365 //!   mode.
366 //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
367 //!   for this channel (it is very unlikely that this flag should be used).
368 //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
369 //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
370 //!   peripheral for this channel.
371 //!
372 //! \return None.
373 //
374 //*****************************************************************************
375 void
uDMAChannelAttributeEnable(uint32_t ui32ChannelNum,uint32_t ui32Attr)376 uDMAChannelAttributeEnable(uint32_t ui32ChannelNum, uint32_t ui32Attr)
377 {
378     //
379     // Check the arguments.
380     //
381     ASSERT((ui32ChannelNum & 0xffff) < 32);
382     ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
383                          UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
384 
385     //
386     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
387     // passed as the ui32ChannelNum parameter, extract just the channel number
388     // from this parameter.
389     //
390     ui32ChannelNum &= 0x1f;
391 
392     //
393     // Set the useburst bit for this channel if set in ui32Config.
394     //
395     if (ui32Attr & UDMA_ATTR_USEBURST)
396     {
397         HWREG(UDMA_USEBURSTSET) = 1 << ui32ChannelNum;
398     }
399 
400     //
401     // Set the alternate control select bit for this channel,
402     // if set in ui32Config.
403     //
404     if (ui32Attr & UDMA_ATTR_ALTSELECT)
405     {
406         HWREG(UDMA_ALTSET) = 1 << ui32ChannelNum;
407     }
408 
409     //
410     // Set the high priority bit for this channel, if set in ui32Config.
411     //
412     if (ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
413     {
414         HWREG(UDMA_PRIOSET) = 1 << ui32ChannelNum;
415     }
416 
417     //
418     // Set the request mask bit for this channel, if set in ui32Config.
419     //
420     if (ui32Attr & UDMA_ATTR_REQMASK)
421     {
422         HWREG(UDMA_REQMASKSET) = 1 << ui32ChannelNum;
423     }
424 }
425 
426 //*****************************************************************************
427 //
428 //! Disables attributes of a uDMA channel.
429 //!
430 //! \param ui32ChannelNum is the channel to configure.
431 //! \param ui32Attr is a combination of attributes for the channel.
432 //!
433 //! This function is used to disable attributes of a uDMA channel.
434 //!
435 //! The \e ui32Attr parameter is the logical OR of any of the following:
436 //!
437 //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
438 //!   mode.
439 //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
440 //!   for this channel.
441 //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
442 //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
443 //!   peripheral for this channel.
444 //!
445 //! \return None.
446 //
447 //*****************************************************************************
448 void
uDMAChannelAttributeDisable(uint32_t ui32ChannelNum,uint32_t ui32Attr)449 uDMAChannelAttributeDisable(uint32_t ui32ChannelNum, uint32_t ui32Attr)
450 {
451     //
452     // Check the arguments.
453     //
454     ASSERT((ui32ChannelNum & 0xffff) < 32);
455     ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
456                          UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
457 
458     //
459     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
460     // passed as the ui32ChannelNum parameter, extract just the channel number
461     // from this parameter.
462     //
463     ui32ChannelNum &= 0x1f;
464 
465     //
466     // Clear the useburst bit for this channel if set in ui32Config.
467     //
468     if (ui32Attr & UDMA_ATTR_USEBURST)
469     {
470         HWREG(UDMA_USEBURSTCLR) = 1 << ui32ChannelNum;
471     }
472 
473     //
474     // Clear the alternate control select bit for this channel, if set in
475     // ui32Config.
476     //
477     if (ui32Attr & UDMA_ATTR_ALTSELECT)
478     {
479         HWREG(UDMA_ALTCLR) = 1 << ui32ChannelNum;
480     }
481 
482     //
483     // Clear the high priority bit for this channel, if set in ui32Config.
484     //
485     if (ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
486     {
487         HWREG(UDMA_PRIOCLR) = 1 << ui32ChannelNum;
488     }
489 
490     //
491     // Clear the request mask bit for this channel, if set in ui32Config.
492     //
493     if (ui32Attr & UDMA_ATTR_REQMASK)
494     {
495         HWREG(UDMA_REQMASKCLR) = 1 << ui32ChannelNum;
496     }
497 }
498 
499 //*****************************************************************************
500 //
501 //! Gets the enabled attributes of a uDMA channel.
502 //!
503 //! \param ui32ChannelNum is the channel to configure.
504 //!
505 //! This function returns a combination of flags representing the attributes of
506 //! the uDMA channel.
507 //!
508 //! \return Returns the logical OR of the attributes of the uDMA channel, which
509 //! can be any of the following:
510 //! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst
511 //!   mode.
512 //! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure
513 //!   for this channel.
514 //! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority.
515 //! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the
516 //!   peripheral for this channel.
517 //
518 //*****************************************************************************
519 uint32_t
uDMAChannelAttributeGet(uint32_t ui32ChannelNum)520 uDMAChannelAttributeGet(uint32_t ui32ChannelNum)
521 {
522     uint32_t ui32Attr = 0;
523 
524     //
525     // Check the arguments.
526     //
527     ASSERT((ui32ChannelNum & 0xffff) < 32);
528 
529     //
530     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
531     // passed as the ui32ChannelNum parameter, extract just the channel number
532     // from this parameter.
533     //
534     ui32ChannelNum &= 0x1f;
535 
536     //
537     // Check to see if useburst bit is set for this channel.
538     //
539     if (HWREG(UDMA_USEBURSTSET) & (1 << ui32ChannelNum))
540     {
541         ui32Attr |= UDMA_ATTR_USEBURST;
542     }
543 
544     //
545     // Check to see if the alternate control bit is set for this channel.
546     //
547     if (HWREG(UDMA_ALTSET) & (1 << ui32ChannelNum))
548     {
549         ui32Attr |= UDMA_ATTR_ALTSELECT;
550     }
551 
552     //
553     // Check to see if the high priority bit is set for this channel.
554     //
555     if (HWREG(UDMA_PRIOSET) & (1 << ui32ChannelNum))
556     {
557         ui32Attr |= UDMA_ATTR_HIGH_PRIORITY;
558     }
559 
560     //
561     // Check to see if the request mask bit is set for this channel.
562     //
563     if (HWREG(UDMA_REQMASKSET) & (1 << ui32ChannelNum))
564     {
565         ui32Attr |= UDMA_ATTR_REQMASK;
566     }
567 
568     //
569     // Return the configuration flags.
570     //
571     return (ui32Attr);
572 }
573 
574 //*****************************************************************************
575 //
576 //! Sets the control parameters for a uDMA channel control structure.
577 //!
578 //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
579 //! with \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
580 //! \param ui32Control is logical OR of several control values to set the
581 //! control parameters for the channel.
582 //!
583 //! This function is used to set control parameters for a uDMA transfer.  These
584 //! parameters are typically not changed often.
585 //!
586 //! The \e ui32ChannelStructIndex parameter should be the logical OR of the
587 //! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to
588 //! choose whether the primary or alternate data structure is used.
589 //!
590 //! The \e ui32Control parameter is the logical OR of five values: the data
591 //! size, the source address increment, the destination address increment, the
592 //! arbitration size, and the use burst flag.  The choices available for each
593 //! of these values is described below.
594 //!
595 //! Choose the data size from one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or
596 //! \b UDMA_SIZE_32 to select a data size of 8, 16, or 32 bits.
597 //!
598 //! Choose the source address increment from one of \b UDMA_SRC_INC_8,
599 //! \b UDMA_SRC_INC_16, \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE to select
600 //! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or
601 //! to select non-incrementing.
602 //!
603 //! Choose the destination address increment from one of \b UDMA_DST_INC_8,
604 //! \b UDMA_DST_INC_16, \b UDMA_DST_INC_32, or \b UDMA_DST_INC_NONE to select
605 //! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or
606 //! to select non-incrementing.
607 //!
608 //! The arbitration size determines how many items are transferred before
609 //! the uDMA controller re-arbitrates for the bus.  Choose the arbitration size
610 //! from one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, \b UDMA_ARB_8,
611 //! through \b UDMA_ARB_1024 to select the arbitration size from 1 to 1024
612 //! items, in powers of 2.
613 //!
614 //! The value \b UDMA_NEXT_USEBURST is used to force the channel to only
615 //! respond to burst requests at the tail end of a scatter-gather transfer.
616 //!
617 //! \note The address increment cannot be smaller than the data size.
618 //!
619 //! \return None.
620 //
621 //*****************************************************************************
622 void
uDMAChannelControlSet(uint32_t ui32ChannelStructIndex,uint32_t ui32Control)623 uDMAChannelControlSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Control)
624 {
625     tDMAControlTable *psCtl;
626 
627     //
628     // Check the arguments.
629     //
630     ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
631     ASSERT(HWREG(UDMA_CTLBASE) != 0);
632 
633     //
634     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
635     // passed as the ui32ChannelStructIndex parameter, extract just the channel
636     // index from this parameter.
637     //
638     ui32ChannelStructIndex &= 0x3f;
639 
640     //
641     // Get the base address of the control table.
642     //
643     psCtl = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
644 
645     //
646     // Get the current control word value and mask off the fields to be
647     // changed, then OR in the new settings.
648     //
649     psCtl[ui32ChannelStructIndex].ui32Control =
650         ((psCtl[ui32ChannelStructIndex].ui32Control &
651           ~(UDMA_CHCTL_DSTINC_M |
652             UDMA_CHCTL_DSTSIZE_M |
653             UDMA_CHCTL_SRCINC_M |
654             UDMA_CHCTL_SRCSIZE_M |
655             UDMA_CHCTL_ARBSIZE_M |
656             UDMA_CHCTL_NXTUSEBURST)) |
657          ui32Control);
658 }
659 
660 //*****************************************************************************
661 //
662 //! Sets the transfer parameters for a uDMA channel control structure.
663 //!
664 //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
665 //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
666 //! \param ui32Mode is the type of uDMA transfer.
667 //! \param pvSrcAddr is the source address for the transfer.
668 //! \param pvDstAddr is the destination address for the transfer.
669 //! \param ui32TransferSize is the number of data items to transfer.
670 //!
671 //! This function is used to configure the parameters for a uDMA transfer.
672 //! These parameters are not typically changed often.  The function
673 //! uDMAChannelControlSet() MUST be called at least once for this channel prior
674 //! to calling this function.
675 //!
676 //! The \e ui32ChannelStructIndex parameter should be the logical OR of the
677 //! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to
678 //! choose whether the primary or alternate data structure is used.
679 //!
680 //! The \e ui32Mode parameter should be one of the following values:
681 //!
682 //! - \b UDMA_MODE_STOP stops the uDMA transfer.  The controller sets the mode
683 //!   to this value at the end of a transfer.
684 //! - \b UDMA_MODE_BASIC to perform a basic transfer based on request.
685 //! - \b UDMA_MODE_AUTO to perform a transfer that always completes once
686 //!   started even if the request is removed.
687 //! - \b UDMA_MODE_PINGPONG to set up a transfer that switches between the
688 //!   primary and alternate control structures for the channel.  This mode
689 //!   allows use of ping-pong buffering for uDMA transfers.
690 //! - \b UDMA_MODE_MEM_SCATTER_GATHER to set up a memory scatter-gather
691 //!   transfer.
692 //! - \b UDMA_MODE_PER_SCATTER_GATHER to set up a peripheral scatter-gather
693 //!   transfer.
694 //!
695 //! The \e pvSrcAddr and \e pvDstAddr parameters are pointers to the first
696 //! location of the data to be transferred.  These addresses should be aligned
697 //! according to the item size.  The compiler takes care of this alignment if
698 //! the pointers are pointing to storage of the appropriate data type.
699 //!
700 //! The \e ui32TransferSize parameter is the number of data items, not the
701 //! number of bytes.
702 //!
703 //! The two scatter-gather modes, memory and peripheral, are actually different
704 //! depending on whether the primary or alternate control structure is
705 //! selected.  This function looks for the \b UDMA_PRI_SELECT and
706 //! \b UDMA_ALT_SELECT flag along with the channel number and sets the
707 //! scatter-gather mode as appropriate for the primary or alternate control
708 //! structure.
709 //!
710 //! The channel must also be enabled using uDMAChannelEnable() after calling
711 //! this function.  The transfer does not begin until the channel has been
712 //! configured and enabled.  Note that the channel is automatically disabled
713 //! after the transfer is completed, meaning that uDMAChannelEnable() must be
714 //! called again after setting up the next transfer.
715 //!
716 //! \note Great care must be taken to not modify a channel control structure
717 //! that is in use or else the results are unpredictable, including the
718 //! possibility of undesired data transfers to or from memory or peripherals.
719 //! For BASIC and AUTO modes, it is safe to make changes when the channel is
720 //! disabled, or the uDMAChannelModeGet() returns \b UDMA_MODE_STOP.  For
721 //! PINGPONG or one of the SCATTER_GATHER modes, it is safe to modify the
722 //! primary or alternate control structure only when the other is being used.
723 //! The uDMAChannelModeGet() function returns \b UDMA_MODE_STOP when a
724 //! channel control structure is inactive and safe to modify.
725 //!
726 //! \return None.
727 //
728 //*****************************************************************************
729 void
uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex,uint32_t ui32Mode,void * pvSrcAddr,void * pvDstAddr,uint32_t ui32TransferSize)730 uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Mode,
731                        void *pvSrcAddr, void *pvDstAddr,
732                        uint32_t ui32TransferSize)
733 {
734     tDMAControlTable *psControlTable;
735     uint32_t ui32Control;
736     uint32_t ui32Inc;
737     uint32_t ui32BufferBytes;
738 
739     //
740     // Check the arguments.
741     //
742     ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
743     ASSERT(HWREG(UDMA_CTLBASE) != 0);
744     ASSERT(ui32Mode <= UDMA_MODE_PER_SCATTER_GATHER);
745     ASSERT((uint32_t)pvSrcAddr >= 0x20000000);
746     ASSERT((uint32_t)pvDstAddr >= 0x20000000);
747     ASSERT((ui32TransferSize != 0) && (ui32TransferSize <= 1024));
748 
749     //
750     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
751     // passed as the ui32ChannelStructIndex parameter, extract just the channel
752     // index from this parameter.
753     //
754     ui32ChannelStructIndex &= 0x3f;
755 
756     //
757     // Get the base address of the control table.
758     //
759     psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
760 
761     //
762     // Get the current control word value and mask off the mode and size
763     // fields.
764     //
765     ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
766                    ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
767 
768     //
769     // Adjust the mode if the alt control structure is selected.
770     //
771     if (ui32ChannelStructIndex & UDMA_ALT_SELECT)
772     {
773         if ((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
774                 (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
775         {
776             ui32Mode |= UDMA_MODE_ALT_SELECT;
777         }
778     }
779 
780     //
781     // Set the transfer size and mode in the control word (but don't write the
782     // control word yet as it could kick off a transfer).
783     //
784     ui32Control |= ui32Mode | ((ui32TransferSize - 1) << 4);
785 
786     //
787     // Get the address increment value for the source, from the control word.
788     //
789     ui32Inc = (ui32Control & UDMA_CHCTL_SRCINC_M);
790 
791     //
792     // Compute the ending source address of the transfer.  If the source
793     // increment is set to none, then the ending address is the same as the
794     // beginning.
795     //
796     if (ui32Inc != UDMA_SRC_INC_NONE)
797     {
798         ui32Inc = ui32Inc >> 26;
799         ui32BufferBytes = ui32TransferSize << ui32Inc;
800         pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1);
801     }
802 
803     //
804     // Load the source ending address into the control block.
805     //
806     psControlTable[ui32ChannelStructIndex].pvSrcEndAddr = pvSrcAddr;
807 
808     //
809     // Get the address increment value for the destination, from the control
810     // word.
811     //
812     ui32Inc = ui32Control & UDMA_CHCTL_DSTINC_M;
813 
814     //
815     // Compute the ending destination address of the transfer.  If the
816     // destination increment is set to none, then the ending address is the
817     // same as the beginning.
818     //
819     if (ui32Inc != UDMA_DST_INC_NONE)
820     {
821         //
822         // There is a special case if this is setting up a scatter-gather
823         // transfer.  The destination pointer must point to the end of
824         // the alternate structure for this channel instead of calculating
825         // the end of the buffer in the normal way.
826         //
827         if ((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
828                 (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
829         {
830             pvDstAddr =
831                 (void *)&psControlTable[ui32ChannelStructIndex |
832                                         UDMA_ALT_SELECT].ui32Spare;
833         }
834         //
835         // Not a scatter-gather transfer, calculate end pointer normally.
836         //
837         else
838         {
839             ui32Inc = ui32Inc >> 30;
840             ui32BufferBytes = ui32TransferSize << ui32Inc;
841             pvDstAddr = (void *)((uint32_t)pvDstAddr + ui32BufferBytes - 1);
842         }
843     }
844 
845     //
846     // Load the destination ending address into the control block.
847     //
848     psControlTable[ui32ChannelStructIndex].pvDstEndAddr = pvDstAddr;
849 
850     //
851     // Write the new control word value.
852     //
853     psControlTable[ui32ChannelStructIndex].ui32Control = ui32Control;
854 }
855 
856 //*****************************************************************************
857 //
858 //! Configures a uDMA channel for scatter-gather mode.
859 //!
860 //! \param ui32ChannelNum is the uDMA channel number.
861 //! \param ui32TaskCount is the number of scatter-gather tasks to execute.
862 //! \param pvTaskList is a pointer to the beginning of the scatter-gather
863 //! task list.
864 //! \param ui32IsPeriphSG is a flag to indicate it is a peripheral
865 //! scatter-gather transfer (else it is memory scatter-gather transfer)
866 //!
867 //! This function is used to configure a channel for scatter-gather mode.
868 //! The caller must have already set up a task list and must pass a pointer to
869 //! the start of the task list as the \e pvTaskList parameter.  The
870 //! \e ui32TaskCount parameter is the count of tasks in the task list, not the
871 //! size of the task list.  The flag \e bIsPeriphSG should be used to indicate
872 //! if scatter-gather should be configured for peripheral or memory
873 //! operation.
874 //!
875 //! \sa uDMATaskStructEntry
876 //!
877 //! \return None.
878 //
879 //*****************************************************************************
880 void
uDMAChannelScatterGatherSet(uint32_t ui32ChannelNum,uint32_t ui32TaskCount,void * pvTaskList,uint32_t ui32IsPeriphSG)881 uDMAChannelScatterGatherSet(uint32_t ui32ChannelNum, uint32_t ui32TaskCount,
882                             void *pvTaskList, uint32_t ui32IsPeriphSG)
883 {
884     tDMAControlTable *psControlTable;
885     tDMAControlTable *psTaskTable;
886 
887     //
888     // Check the parameters
889     //
890     ASSERT((ui32ChannelNum & 0xffff) < 32);
891     ASSERT(HWREG(UDMA_CTLBASE) != 0);
892     ASSERT(pvTaskList != 0);
893     ASSERT(ui32TaskCount <= 1024);
894     ASSERT(ui32TaskCount != 0);
895 
896     //
897     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
898     // passed as the ui32ChannelNum parameter, extract just the channel number
899     // from this parameter.
900     //
901     ui32ChannelNum &= 0x1f;
902 
903     //
904     // Get the base address of the control table.
905     //
906     psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
907 
908     //
909     // Get a handy pointer to the task list
910     //
911     psTaskTable = (tDMAControlTable *)pvTaskList;
912 
913     //
914     // Compute the ending address for the source pointer.  This address is the
915     // last element of the last task in the task table
916     //
917     psControlTable[ui32ChannelNum].pvSrcEndAddr =
918         &psTaskTable[ui32TaskCount - 1].ui32Spare;
919 
920     //
921     // Compute the ending address for the destination pointer.  This address
922     // is the end of the alternate structure for this channel.
923     //
924     psControlTable[ui32ChannelNum].pvDstEndAddr =
925         &psControlTable[ui32ChannelNum | UDMA_ALT_SELECT].ui32Spare;
926 
927     //
928     // Compute the control word.  Most configurable items are fixed for
929     // scatter-gather.  Item and increment sizes are all 32-bit and arb
930     // size must be 4.  The count is the number of items in the task list
931     // times 4 (4 words per task).
932     //
933     psControlTable[ui32ChannelNum].ui32Control =
934         (UDMA_CHCTL_DSTINC_32 | UDMA_CHCTL_DSTSIZE_32 |
935          UDMA_CHCTL_SRCINC_32 | UDMA_CHCTL_SRCSIZE_32 |
936          UDMA_CHCTL_ARBSIZE_4 |
937          (((ui32TaskCount * 4) - 1) << UDMA_CHCTL_XFERSIZE_S) |
938          (ui32IsPeriphSG ? UDMA_CHCTL_XFERMODE_PER_SG :
939           UDMA_CHCTL_XFERMODE_MEM_SG));
940 
941     //
942     // Scatter-gather operations can leave the alt bit set.  So if doing
943     // back to back scatter-gather transfers, the second attempt may not
944     // work correctly because the alt bit is set.  Therefore, clear the
945     // alt bit here to ensure that it is always cleared before a new SG
946     // transfer is started.
947     //
948     HWREG(UDMA_ALTCLR) = 1 << ui32ChannelNum;
949 }
950 
951 //*****************************************************************************
952 //
953 //! Gets the current transfer size for a uDMA channel control structure.
954 //!
955 //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
956 //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
957 //!
958 //! This function is used to get the uDMA transfer size for a channel.  The
959 //! transfer size is the number of items to transfer, where the size of an item
960 //! might be 8, 16, or 32 bits.  If a partial transfer has already occurred,
961 //! then the number of remaining items is returned.  If the transfer is
962 //! complete, then 0 is returned.
963 //!
964 //! \return Returns the number of items remaining to transfer.
965 //
966 //*****************************************************************************
967 uint32_t
uDMAChannelSizeGet(uint32_t ui32ChannelStructIndex)968 uDMAChannelSizeGet(uint32_t ui32ChannelStructIndex)
969 {
970     tDMAControlTable *psControlTable;
971     uint32_t ui32Control;
972 
973     //
974     // Check the arguments.
975     //
976     ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
977     ASSERT(HWREG(UDMA_CTLBASE) != 0);
978 
979     //
980     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
981     // passed as the ui32ChannelStructIndex parameter, extract just the channel
982     // index from this parameter.
983     //
984     ui32ChannelStructIndex &= 0x3f;
985 
986     //
987     // Get the base address of the control table.
988     //
989     psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
990 
991     //
992     // Get the current control word value and mask off all but the size field
993     // and the mode field.
994     //
995     ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
996                    (UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
997 
998     //
999     // If the size field and mode field are 0 then the transfer is finished
1000     // and there are no more items to transfer
1001     //
1002     if (ui32Control == 0)
1003     {
1004         return (0);
1005     }
1006 
1007     //
1008     // Otherwise, if either the size field or more field is non-zero, then
1009     // not all the items have been transferred.
1010     //
1011     else
1012     {
1013         //
1014         // Shift the size field and add one, then return to user.
1015         //
1016         return ((ui32Control >> 4) + 1);
1017     }
1018 }
1019 
1020 //*****************************************************************************
1021 //
1022 //! Gets the transfer mode for a uDMA channel control structure.
1023 //!
1024 //! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number
1025 //! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
1026 //!
1027 //! This function is used to get the transfer mode for the uDMA channel and
1028 //! to query the status of a transfer on a channel.  When the transfer is
1029 //! complete the mode is \b UDMA_MODE_STOP.
1030 //!
1031 //! \return Returns the transfer mode of the specified channel and control
1032 //! structure, which is one of the following values: \b UDMA_MODE_STOP,
1033 //! \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, \b UDMA_MODE_PINGPONG,
1034 //! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER.
1035 //
1036 //*****************************************************************************
1037 uint32_t
uDMAChannelModeGet(uint32_t ui32ChannelStructIndex)1038 uDMAChannelModeGet(uint32_t ui32ChannelStructIndex)
1039 {
1040     tDMAControlTable *psControlTable;
1041     uint32_t ui32Control;
1042 
1043     //
1044     // Check the arguments.
1045     //
1046     ASSERT((ui32ChannelStructIndex & 0xffff) < 64);
1047     ASSERT(HWREG(UDMA_CTLBASE) != 0);
1048 
1049     //
1050     // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
1051     // passed as the ui32ChannelStructIndex parameter, extract just the channel
1052     // index from this parameter.
1053     //
1054     ui32ChannelStructIndex &= 0x3f;
1055 
1056     //
1057     // Get the base address of the control table.
1058     //
1059     psControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);
1060 
1061     //
1062     // Get the current control word value and mask off all but the mode field.
1063     //
1064     ui32Control = (psControlTable[ui32ChannelStructIndex].ui32Control &
1065                    UDMA_CHCTL_XFERMODE_M);
1066 
1067     //
1068     // Check if scatter/gather mode, and if so, mask off the alt bit.
1069     //
1070     if (((ui32Control & ~UDMA_MODE_ALT_SELECT) ==
1071             UDMA_MODE_MEM_SCATTER_GATHER) ||
1072             ((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_PER_SCATTER_GATHER))
1073     {
1074         ui32Control &= ~UDMA_MODE_ALT_SELECT;
1075     }
1076 
1077     //
1078     // Return the mode to the caller.
1079     //
1080     return (ui32Control);
1081 }
1082 
1083 //*****************************************************************************
1084 //
1085 //! Registers an interrupt handler for the uDMA controller.
1086 //!
1087 //! \param ui32IntChannel identifies which uDMA interrupt is to be registered.
1088 //! \param pfnHandler is a pointer to the function to be called when the
1089 //! interrupt is activated.
1090 //!
1091 //! This function registers and enables the handler to be called when the uDMA
1092 //! controller generates an interrupt.  The \e ui32IntChannel parameter should
1093 //! be one of the following:
1094 //!
1095 //! - \b INT_UDMA to register an interrupt handler to process interrupts
1096 //!   from the uDMA software channel (UDMA_CHANNEL_SW)
1097 //! - \b INT_UDMAERR to register an interrupt handler to process uDMA error
1098 //!   interrupts
1099 //!
1100 //! \sa IntRegister() for important information about registering interrupt
1101 //! handlers.
1102 //!
1103 //! \note The interrupt handler for the uDMA is for transfer completion when
1104 //! the channel UDMA_CHANNEL_SW is used and for error interrupts.  The
1105 //! interrupts for each peripheral channel are handled through the individual
1106 //! peripheral interrupt handlers.
1107 //!
1108 //! \return None.
1109 //
1110 //*****************************************************************************
1111 void
uDMAIntRegister(uint32_t ui32IntChannel,void (* pfnHandler)(void))1112 uDMAIntRegister(uint32_t ui32IntChannel, void (*pfnHandler)(void))
1113 {
1114     //
1115     // Check the arguments.
1116     //
1117     ASSERT(pfnHandler);
1118 
1119     //
1120     // Register the interrupt handler.
1121     //
1122     IntRegister(ui32IntChannel, pfnHandler);
1123 
1124     //
1125     // Enable the memory management fault.
1126     //
1127     IntEnable(ui32IntChannel);
1128 }
1129 
1130 //*****************************************************************************
1131 //
1132 //! Unregisters an interrupt handler for the uDMA controller.
1133 //!
1134 //! \param ui32IntChannel identifies which uDMA interrupt to unregister.
1135 //!
1136 //! This function disables and unregisters the handler to be called for the
1137 //! specified uDMA interrupt.  The \e ui32IntChannel parameter should be one of
1138 //! \b INT_UDMA or \b INT_UDMAERR as documented for the function
1139 //! uDMAIntRegister().
1140 //!
1141 //! \sa IntRegister() for important information about registering interrupt
1142 //! handlers.
1143 //!
1144 //! \return None.
1145 //
1146 //*****************************************************************************
1147 void
uDMAIntUnregister(uint32_t ui32IntChannel)1148 uDMAIntUnregister(uint32_t ui32IntChannel)
1149 {
1150     //
1151     // Disable the interrupt.
1152     //
1153     IntDisable(ui32IntChannel);
1154 
1155     //
1156     // Unregister the interrupt handler.
1157     //
1158     IntUnregister(ui32IntChannel);
1159 }
1160 
1161 //*****************************************************************************
1162 //
1163 //! Assigns a peripheral mapping for a uDMA channel.
1164 //!
1165 //! \param ui32Mapping is a macro specifying the peripheral assignment for
1166 //! a channel.
1167 //!
1168 //! This function assigns a peripheral mapping to a uDMA channel.  It is
1169 //! used to select which peripheral is used for a uDMA channel.  The parameter
1170 //! \e ui32Mapping should be one of the macros named \b UDMA_CHn_tttt from the
1171 //! header file \e udma.h.  For example, to assign uDMA channel 0 to the
1172 //! UART2 RX channel, the parameter should be the macro \b UDMA_CH0_UART2RX.
1173 //!
1174 //! Please consult the data sheet for a table showing all the possible
1175 //! peripheral assignments for the uDMA channels.
1176 //!
1177 //! \return None.
1178 //
1179 //*****************************************************************************
1180 void
uDMAChannelAssign(uint32_t ui32Mapping)1181 uDMAChannelAssign(uint32_t ui32Mapping)
1182 {
1183     uint32_t ui32MapReg;
1184     uint_fast8_t ui8MapShift;
1185     uint_fast8_t ui8ChannelNum;
1186 
1187     //
1188     // Check the parameters
1189     //
1190     ASSERT((ui32Mapping & 0xffffff00) < 0x00090000);
1191 
1192     //
1193     // Extract the channel number and map encoding value from the parameter.
1194     //
1195     ui8ChannelNum = ui32Mapping & 0xff;
1196     ui32Mapping = ui32Mapping >> 16;
1197 
1198     //
1199     // Find the uDMA channel mapping register and shift value to use for this
1200     // channel
1201     //
1202     ui32MapReg = UDMA_CHMAP0 + (uint32_t)((ui8ChannelNum / 8) * 4);
1203     ui8MapShift = (ui8ChannelNum % 8) * 4;
1204 
1205     //
1206     // Set the channel map encoding for this channel
1207     //
1208     HWREG(ui32MapReg) = (HWREG(ui32MapReg) & ~(0xf << ui8MapShift)) |
1209                         ui32Mapping << ui8MapShift;
1210 }
1211 
1212 //*****************************************************************************
1213 //
1214 // Close the Doxygen group.
1215 //! @}
1216 //
1217 //*****************************************************************************
1218