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