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