1 /* --COPYRIGHT--,BSD
2 * Copyright (c) 2017, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the 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 "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 #include <stdint.h>
33
34 #include <ti/devices/msp432p4xx/driverlib/debug.h>
35 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
36 #include <ti/devices/msp432p4xx/driverlib/dma.h>
37
DMA_enableModule(void)38 void DMA_enableModule(void)
39 {
40 //
41 // Set the master enable bit in the config register.
42 //
43 DMA_Control->CFG = DMA_CFG_MASTEN;
44 }
45
DMA_disableModule(void)46 void DMA_disableModule(void)
47 {
48 //
49 // Clear the master enable bit in the config register.
50 //
51 DMA_Control->CFG = 0;
52 }
53
DMA_getErrorStatus(void)54 uint32_t DMA_getErrorStatus(void)
55 {
56 //
57 // Return the DMA error status.
58 //
59 return DMA_Control->ERRCLR;
60 }
61
DMA_clearErrorStatus(void)62 void DMA_clearErrorStatus(void)
63 {
64 //
65 // Clear the DMA error interrupt.
66 //
67 DMA_Control->ERRCLR = 1;
68 }
69
DMA_enableChannel(uint32_t channelNum)70 void DMA_enableChannel(uint32_t channelNum)
71 {
72 //
73 // Check the arguments.
74 //
75 ASSERT((channelNum & 0xffff) < 8);
76
77 //
78 // Set the bit for this channel in the enable set register.
79 //
80 DMA_Control->ENASET = 1 << (channelNum & 0x0F);
81 }
82
DMA_disableChannel(uint32_t channelNum)83 void DMA_disableChannel(uint32_t channelNum)
84 {
85 //
86 // Check the arguments.
87 //
88 ASSERT((channelNum & 0xffff) < 8);
89
90 //
91 // Set the bit for this channel in the enable clear register.
92 //
93 DMA_Control->ENACLR = 1 << (channelNum & 0x0F);
94 }
95
DMA_isChannelEnabled(uint32_t channelNum)96 bool DMA_isChannelEnabled(uint32_t channelNum)
97 {
98 //
99 // Check the arguments.
100 //
101 ASSERT((channelNum & 0xffff) < 8);
102
103 //
104 // AND the specified channel bit with the enable register and return the
105 // result.
106 //
107 return ((DMA_Control->ENASET & (1 << (channelNum & 0x0F))) ? true : false);
108 }
109
DMA_setControlBase(void * controlTable)110 void DMA_setControlBase(void *controlTable)
111 {
112 //
113 // Check the arguments.
114 //
115 ASSERT(((uint32_t) controlTable & ~0x3FF) == (uint32_t) controlTable);
116 ASSERT((uint32_t) controlTable >= 0x20000000);
117
118 //
119 // Program the base address into the register.
120 //
121 DMA_Control->CTLBASE = (uint32_t) controlTable;
122 }
123
DMA_getControlBase(void)124 void* DMA_getControlBase(void)
125 {
126 //
127 // Read the current value of the control base register and return it to
128 // the caller.
129 //
130 return ((void *) DMA_Control->CTLBASE);
131 }
132
DMA_getControlAlternateBase(void)133 void* DMA_getControlAlternateBase(void)
134 {
135 //
136 // Read the current value of the control base register and return it to
137 // the caller.
138 //
139 return ((void *) DMA_Control->ALTBASE);
140 }
141
DMA_requestChannel(uint32_t channelNum)142 void DMA_requestChannel(uint32_t channelNum)
143 {
144 //
145 // Check the arguments.
146 //
147 ASSERT((channelNum & 0xffff) < 8);
148
149 //
150 // Set the bit for this channel in the software DMA request register.
151 //
152 DMA_Control->SWREQ = 1 << (channelNum & 0x0F);
153 }
154
DMA_enableChannelAttribute(uint32_t channelNum,uint32_t attr)155 void DMA_enableChannelAttribute(uint32_t channelNum, uint32_t attr)
156 {
157 //
158 // Check the arguments.
159 //
160 ASSERT((channelNum & 0xffff) < 8);
161 ASSERT(
162 (attr
163 & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT
164 | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK))
165 == 0);
166
167 //
168 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
169 // passed as the channelNum parameter, extract just the channel number
170 // from this parameter.
171 //
172 channelNum &= 0x0F;
173
174 //
175 // Set the useburst bit for this channel if set in config.
176 //
177 if (attr & UDMA_ATTR_USEBURST)
178 {
179 DMA_Control->USEBURSTSET = 1 << channelNum;
180 }
181
182 //
183 // Set the alternate control select bit for this channel,
184 // if set in config.
185 //
186 if (attr & UDMA_ATTR_ALTSELECT)
187 {
188 DMA_Control->ALTSET = 1 << channelNum;
189 }
190
191 //
192 // Set the high priority bit for this channel, if set in config.
193 //
194 if (attr & UDMA_ATTR_HIGH_PRIORITY)
195 {
196 DMA_Control->PRIOSET = 1 << channelNum;
197 }
198
199 //
200 // Set the request mask bit for this channel, if set in config.
201 //
202 if (attr & UDMA_ATTR_REQMASK)
203 {
204 DMA_Control->REQMASKSET = 1 << channelNum;
205 }
206 }
207
DMA_disableChannelAttribute(uint32_t channelNum,uint32_t attr)208 void DMA_disableChannelAttribute(uint32_t channelNum, uint32_t attr)
209 {
210 //
211 // Check the arguments.
212 //
213 ASSERT((channelNum & 0xffff) < 8);
214 ASSERT(
215 (attr
216 & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT
217 | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK))
218 == 0);
219
220 //
221 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
222 // passed as the channelNum parameter, extract just the channel number
223 // from this parameter.
224 //
225 channelNum &= 0x0F;
226
227 //
228 // Clear the useburst bit for this channel if set in config.
229 //
230 if (attr & UDMA_ATTR_USEBURST)
231 {
232 DMA_Control->USEBURSTCLR = 1 << channelNum;
233 }
234
235 //
236 // Clear the alternate control select bit for this channel, if set in
237 // config.
238 //
239 if (attr & UDMA_ATTR_ALTSELECT)
240 {
241 DMA_Control->ALTCLR = 1 << channelNum;
242 }
243
244 //
245 // Clear the high priority bit for this channel, if set in config.
246 //
247 if (attr & UDMA_ATTR_HIGH_PRIORITY)
248 {
249 DMA_Control->PRIOCLR = 1 << channelNum;
250 }
251
252 //
253 // Clear the request mask bit for this channel, if set in config.
254 //
255 if (attr & UDMA_ATTR_REQMASK)
256 {
257 DMA_Control->REQMASKCLR = 1 << channelNum;
258 }
259 }
260
DMA_getChannelAttribute(uint32_t channelNum)261 uint32_t DMA_getChannelAttribute(uint32_t channelNum)
262 {
263 uint32_t attr = 0;
264
265 //
266 // Check the arguments.
267 //
268 ASSERT((channelNum & 0xffff) < 8);
269
270 //
271 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
272 // passed as the channelNum parameter, extract just the channel number
273 // from this parameter.
274 //
275 channelNum &= 0x0F;
276
277 //
278 // Check to see if useburst bit is set for this channel.
279 //
280 if (DMA_Control->USEBURSTSET & (1 << channelNum))
281 {
282 attr |= UDMA_ATTR_USEBURST;
283 }
284
285 //
286 // Check to see if the alternate control bit is set for this channel.
287 //
288 if (DMA_Control->ALTSET & (1 << channelNum))
289 {
290 attr |= UDMA_ATTR_ALTSELECT;
291 }
292
293 //
294 // Check to see if the high priority bit is set for this channel.
295 //
296 if (DMA_Control->PRIOSET & (1 << channelNum))
297 {
298 attr |= UDMA_ATTR_HIGH_PRIORITY;
299 }
300
301 //
302 // Check to see if the request mask bit is set for this channel.
303 //
304 if (DMA_Control->REQMASKSET & (1 << channelNum))
305 {
306 attr |= UDMA_ATTR_REQMASK;
307 }
308
309 //
310 // Return the configuration flags.
311 //
312 return (attr);
313 }
314
DMA_setChannelControl(uint32_t channelStructIndex,uint32_t control)315 void DMA_setChannelControl(uint32_t channelStructIndex, uint32_t control)
316 {
317 DMA_ControlTable *pCtl;
318
319 //
320 // Check the arguments.
321 //
322 ASSERT((channelStructIndex & 0xffff) < 64);
323 ASSERT(DMA_Control->CTLBASE != 0);
324
325 //
326 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
327 // passed as the channelStructIndex parameter, extract just the channel
328 // index from this parameter.
329 //
330 channelStructIndex &= 0x3f;
331
332 //
333 // Get the base address of the control table.
334 //
335 pCtl = (DMA_ControlTable *) DMA_Control->CTLBASE;
336
337 //
338 // Get the current control word value and mask off the fields to be
339 // changed, then OR in the new settings.
340 //
341 pCtl[channelStructIndex].control = ((pCtl[channelStructIndex].control
342 & ~(UDMA_CHCTL_DSTINC_M | UDMA_CHCTL_DSTSIZE_M | UDMA_CHCTL_SRCINC_M
343 | UDMA_CHCTL_SRCSIZE_M | UDMA_CHCTL_ARBSIZE_M
344 | UDMA_CHCTL_NXTUSEBURST)) | control);
345 }
346
DMA_setChannelTransfer(uint32_t channelStructIndex,uint32_t mode,void * srcAddr,void * dstAddr,uint32_t transferSize)347 void DMA_setChannelTransfer(uint32_t channelStructIndex, uint32_t mode,
348 void *srcAddr, void *dstAddr, uint32_t transferSize)
349 {
350 DMA_ControlTable *controlTable;
351 uint32_t control;
352 uint32_t increment;
353 uint32_t bufferBytes;
354
355 //
356 // Check the arguments.
357 //
358 ASSERT((channelStructIndex & 0xffff) < 64);
359 ASSERT(DMA->CTLBASE != 0);
360 ASSERT(mode <= UDMA_MODE_PER_SCATTER_GATHER);
361 ASSERT((transferSize != 0) && (transferSize <= 1024));
362
363 //
364 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
365 // passed as the channelStructIndex parameter, extract just the channel
366 // index from this parameter.
367 //
368 channelStructIndex &= 0x3f;
369
370 //
371 // Get the base address of the control table.
372 //
373 controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE;
374
375 //
376 // Get the current control word value and mask off the mode and size
377 // fields.
378 //
379 control = (controlTable[channelStructIndex].control
380 & ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
381
382 //
383 // Adjust the mode if the alt control structure is selected.
384 //
385 if (channelStructIndex & UDMA_ALT_SELECT)
386 {
387 if ((mode == UDMA_MODE_MEM_SCATTER_GATHER)
388 || (mode == UDMA_MODE_PER_SCATTER_GATHER))
389 {
390 mode |= UDMA_MODE_ALT_SELECT;
391 }
392 }
393
394 //
395 // Set the transfer size and mode in the control word (but don't write the
396 // control word yet as it could kick off a transfer).
397 //
398 control |= mode | ((transferSize - 1) << 4);
399
400 //
401 // Get the address increment value for the source, from the control word.
402 //
403 increment = (control & UDMA_CHCTL_SRCINC_M);
404
405 //
406 // Compute the ending source address of the transfer. If the source
407 // increment is set to none, then the ending address is the same as the
408 // beginning.
409 //
410 if (increment != UDMA_SRC_INC_NONE)
411 {
412 increment = increment >> 26;
413 bufferBytes = transferSize << increment;
414 srcAddr = (void *) ((uint32_t) srcAddr + bufferBytes - 1);
415 }
416
417 //
418 // Load the source ending address into the control block.
419 //
420 controlTable[channelStructIndex].srcEndAddr = srcAddr;
421
422 //
423 // Get the address increment value for the destination, from the control
424 // word.
425 //
426 increment = control & UDMA_CHCTL_DSTINC_M;
427
428 //
429 // Compute the ending destination address of the transfer. If the
430 // destination increment is set to none, then the ending address is the
431 // same as the beginning.
432 //
433 if (increment != UDMA_DST_INC_NONE)
434 {
435 //
436 // There is a special case if this is setting up a scatter-gather
437 // transfer. The destination pointer must point to the end of
438 // the alternate structure for this channel instead of calculating
439 // the end of the buffer in the normal way.
440 //
441 if ((mode == UDMA_MODE_MEM_SCATTER_GATHER)
442 || (mode == UDMA_MODE_PER_SCATTER_GATHER))
443 {
444 dstAddr = (void *) &controlTable[channelStructIndex
445 | UDMA_ALT_SELECT].spare;
446 }
447 //
448 // Not a scatter-gather transfer, calculate end pointer normally.
449 //
450 else
451 {
452 increment = increment >> 30;
453 bufferBytes = transferSize << increment;
454 dstAddr = (void *) ((uint32_t) dstAddr + bufferBytes - 1);
455 }
456 }
457
458 //
459 // Load the destination ending address into the control block.
460 //
461 controlTable[channelStructIndex].dstEndAddr = dstAddr;
462
463 //
464 // Write the new control word value.
465 //
466 controlTable[channelStructIndex].control = control;
467 }
468
DMA_setChannelScatterGather(uint32_t channelNum,uint32_t taskCount,void * taskList,uint32_t isPeriphSG)469 void DMA_setChannelScatterGather(uint32_t channelNum, uint32_t taskCount,
470 void *taskList, uint32_t isPeriphSG)
471 {
472 DMA_ControlTable *controlTable;
473 DMA_ControlTable *pTaskTable;
474
475 //
476 // Check the parameters
477 //
478 ASSERT((channelNum & 0xffff) < 8);
479 ASSERT(DMA->CTLBASE != 0);
480 ASSERT(taskList != 0);
481 ASSERT(taskCount <= 1024);
482 ASSERT(taskCount != 0);
483
484 //
485 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
486 // passed as the channelNum parameter, extract just the channel number
487 // from this parameter.
488 //
489 channelNum &= 0x0F;
490
491 //
492 // Get the base address of the control table.
493 //
494 controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE;
495
496 //
497 // Get a handy pointer to the task list
498 //
499 pTaskTable = (DMA_ControlTable *) taskList;
500
501 //
502 // Compute the ending address for the source pointer. This address is the
503 // last element of the last task in the task table
504 //
505 controlTable[channelNum].srcEndAddr = &pTaskTable[taskCount - 1].spare;
506
507 //
508 // Compute the ending address for the destination pointer. This address
509 // is the end of the alternate structure for this channel.
510 //
511 controlTable[channelNum].dstEndAddr = &controlTable[channelNum
512 | UDMA_ALT_SELECT].spare;
513
514 //
515 // Compute the control word. Most configurable items are fixed for
516 // scatter-gather. Item and increment sizes are all 32-bit and arb
517 // size must be 4. The count is the number of items in the task list
518 // times 4 (4 words per task).
519 //
520 controlTable[channelNum].control = (UDMA_CHCTL_DSTINC_32
521 | UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_SRCINC_32
522 | UDMA_CHCTL_SRCSIZE_32 | UDMA_CHCTL_ARBSIZE_4
523 | (((taskCount * 4) - 1) << UDMA_CHCTL_XFERSIZE_S)
524 | (isPeriphSG ?
525 UDMA_CHCTL_XFERMODE_PER_SG :
526 UDMA_CHCTL_XFERMODE_MEM_SG));
527
528 //
529 // Scatter-gather operations can leave the alt bit set. So if doing
530 // back to back scatter-gather transfers, the second attempt may not
531 // work correctly because the alt bit is set. Therefore, clear the
532 // alt bit here to ensure that it is always cleared before a new SG
533 // transfer is started.
534 //
535 DMA_Control->ALTCLR = 1 << channelNum;
536 }
537
DMA_getChannelSize(uint32_t channelStructIndex)538 uint32_t DMA_getChannelSize(uint32_t channelStructIndex)
539 {
540 DMA_ControlTable *controlTable;
541 uint32_t control;
542
543 //
544 // Check the arguments.
545 //
546 ASSERT((channelStructIndex & 0xffff) < 16);
547 ASSERT(DMA->CTLBASE != 0);
548
549 //
550 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
551 // passed as the channelStructIndex parameter, extract just the channel
552 // index from this parameter.
553 //
554 channelStructIndex &= 0x3f;
555
556 //
557 // Get the base address of the control table.
558 //
559 controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE;
560
561 //
562 // Get the current control word value and mask off all but the size field
563 // and the mode field.
564 //
565 control = (controlTable[channelStructIndex].control
566 & (UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
567
568 //
569 // If the size field and mode field are 0 then the transfer is finished
570 // and there are no more items to transfer
571 //
572 if (control == 0)
573 {
574 return (0);
575 }
576
577 //
578 // Otherwise, if either the size field or more field is non-zero, then
579 // not all the items have been transferred.
580 //
581 else
582 {
583 //
584 // Shift the size field and add one, then return to user.
585 //
586 return ((control >> 4) + 1);
587 }
588 }
589
DMA_getChannelMode(uint32_t channelStructIndex)590 uint32_t DMA_getChannelMode(uint32_t channelStructIndex)
591 {
592 DMA_ControlTable *controlTable;
593 uint32_t control;
594
595 //
596 // Check the arguments.
597 //
598 ASSERT((channelStructIndex & 0xffff) < 64);
599 ASSERT(DMA->CTLBASE != 0);
600
601 //
602 // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was
603 // passed as the channelStructIndex parameter, extract just the channel
604 // index from this parameter.
605 //
606 channelStructIndex &= 0x3f;
607
608 //
609 // Get the base address of the control table.
610 //
611 controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE;
612
613 //
614 // Get the current control word value and mask off all but the mode field.
615 //
616 control =
617 (controlTable[channelStructIndex].control & UDMA_CHCTL_XFERMODE_M);
618
619 //
620 // Check if scatter/gather mode, and if so, mask off the alt bit.
621 //
622 if (((control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_MEM_SCATTER_GATHER)
623 || ((control & ~UDMA_MODE_ALT_SELECT)
624 == UDMA_MODE_PER_SCATTER_GATHER))
625 {
626 control &= ~UDMA_MODE_ALT_SELECT;
627 }
628
629 //
630 // Return the mode to the caller.
631 //
632 return (control);
633 }
634
DMA_assignChannel(uint32_t mapping)635 void DMA_assignChannel(uint32_t mapping)
636 {
637 switch (mapping)
638 {
639 case DMA_CH0_RESERVED0:
640 case DMA_CH0_EUSCIA0TX:
641 case DMA_CH0_EUSCIB0TX0:
642 case DMA_CH0_EUSCIB3TX1:
643 case DMA_CH0_EUSCIB2TX2:
644 case DMA_CH0_EUSCIB1TX3:
645 case DMA_CH0_TIMERA0CCR0:
646 case DMA_CH0_AESTRIGGER0:
647 DMA_Channel->CH_SRCCFG[0] = (mapping >> 24) & 0x1F;
648 break;
649 case DMA_CH1_RESERVED0:
650 case DMA_CH1_EUSCIA0RX:
651 case DMA_CH1_EUSCIB0RX0:
652 case DMA_CH1_EUSCIB3RX1:
653 case DMA_CH1_EUSCIB2RX2:
654 case DMA_CH1_EUSCIB1RX3:
655 case DMA_CH1_TIMERA0CCR2:
656 case DMA_CH1_AESTRIGGER1:
657 DMA_Channel->CH_SRCCFG[1] = (mapping >> 24) & 0x1F;
658 break;
659 case DMA_CH2_RESERVED0:
660 case DMA_CH2_EUSCIA1TX:
661 case DMA_CH2_EUSCIB1TX0:
662 case DMA_CH2_EUSCIB0TX1:
663 case DMA_CH2_EUSCIB3TX2:
664 case DMA_CH2_EUSCIB2TX3:
665 case DMA_CH2_TIMERA1CCR0:
666 case DMA_CH2_AESTRIGGER2:
667 DMA_Channel->CH_SRCCFG[2] = (mapping >> 24) & 0x1F;
668 break;
669 case DMA_CH3_RESERVED0:
670 case DMA_CH3_EUSCIA1RX:
671 case DMA_CH3_EUSCIB1RX0:
672 case DMA_CH3_EUSCIB0RX1:
673 case DMA_CH3_EUSCIB3RX2:
674 case DMA_CH3_EUSCIB2RX3:
675 case DMA_CH3_TIMERA1CCR2:
676 case DMA_CH3_RESERVED1:
677 DMA_Channel->CH_SRCCFG[3] = (mapping >> 24) & 0x1F;
678 break;
679 case DMA_CH4_RESERVED0:
680 case DMA_CH4_EUSCIA2TX:
681 case DMA_CH4_EUSCIB2TX0:
682 case DMA_CH4_EUSCIB1TX1:
683 case DMA_CH4_EUSCIB0TX2:
684 case DMA_CH4_EUSCIB3TX3:
685 case DMA_CH4_TIMERA2CCR0:
686 case DMA_CH4_RESERVED1:
687 DMA_Channel->CH_SRCCFG[4] = (mapping >> 24) & 0x1F;
688 break;
689 case DMA_CH5_RESERVED0:
690 case DMA_CH5_EUSCIA2RX:
691 case DMA_CH5_EUSCIB2RX0:
692 case DMA_CH5_EUSCIB1RX1:
693 case DMA_CH5_EUSCIB0RX2:
694 case DMA_CH5_EUSCIB3RX3:
695 case DMA_CH5_TIMERA2CCR2:
696 case DMA_CH5_RESERVED1:
697 DMA_Channel->CH_SRCCFG[5] = (mapping >> 24) & 0x1F;
698 break;
699 case DMA_CH6_RESERVED0:
700 case DMA_CH6_EUSCIA3TX:
701 case DMA_CH6_EUSCIB3TX0:
702 case DMA_CH6_EUSCIB2TX1:
703 case DMA_CH6_EUSCIB1TX2:
704 case DMA_CH6_EUSCIB0TX3:
705 case DMA_CH6_TIMERA3CCR0:
706 case DMA_CH6_EXTERNALPIN:
707 DMA_Channel->CH_SRCCFG[6] = (mapping >> 24) & 0x1F;
708 break;
709 case DMA_CH7_RESERVED0:
710 case DMA_CH7_EUSCIA3RX:
711 case DMA_CH7_EUSCIB3RX0:
712 case DMA_CH7_EUSCIB2RX1:
713 case DMA_CH7_EUSCIB1RX2:
714 case DMA_CH7_EUSCIB0RX3:
715 case DMA_CH7_TIMERA3CCR2:
716 case DMA_CH7_ADC14:
717 DMA_Channel->CH_SRCCFG[7] = (mapping >> 24) & 0x1F;
718 break;
719 default:
720 ASSERT(false);
721 }
722
723 }
724
DMA_assignInterrupt(uint32_t interruptNumber,uint32_t channel)725 void DMA_assignInterrupt(uint32_t interruptNumber, uint32_t channel)
726 {
727 ASSERT(
728 interruptNumber == DMA_INT1 || interruptNumber == DMA_INT2
729 || interruptNumber == DMA_INT3);
730
731 if (interruptNumber == DMA_INT1)
732 {
733 DMA_Channel->INT1_SRCCFG = (DMA_Channel->INT1_SRCCFG
734 & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel;
735 } else if (interruptNumber == DMA_INT2)
736 {
737 DMA_Channel->INT2_SRCCFG = (DMA_Channel->INT2_SRCCFG
738 & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel;
739 } else if (interruptNumber == DMA_INT3)
740 {
741 DMA_Channel->INT3_SRCCFG = (DMA_Channel->INT3_SRCCFG
742 & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel;
743 }
744
745 /* Enabling the assigned interrupt */
746 DMA_enableInterrupt(interruptNumber);
747 }
748
DMA_requestSoftwareTransfer(uint32_t channel)749 void DMA_requestSoftwareTransfer(uint32_t channel)
750 {
751 DMA_Channel->SW_CHTRIG |= (1 << channel);
752 }
753
DMA_getInterruptStatus(void)754 uint32_t DMA_getInterruptStatus(void)
755 {
756 return DMA_Channel->INT0_SRCFLG;
757 }
758
DMA_clearInterruptFlag(uint32_t channel)759 void DMA_clearInterruptFlag(uint32_t channel)
760 {
761 DMA_Channel->INT0_CLRFLG |= (1 << channel);
762 }
763
DMA_enableInterrupt(uint32_t interruptNumber)764 void DMA_enableInterrupt(uint32_t interruptNumber)
765 {
766 ASSERT(
767 (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1)
768 || (interruptNumber == DMA_INT2)
769 || (interruptNumber == DMA_INT3));
770
771 if (interruptNumber == DMA_INT1)
772 {
773 DMA_Channel->INT1_SRCCFG |= DMA_INT1_SRCCFG_EN;
774 } else if (interruptNumber == DMA_INT2)
775 {
776 DMA_Channel->INT2_SRCCFG |= DMA_INT2_SRCCFG_EN;
777 } else if (interruptNumber == DMA_INT3)
778 {
779 DMA_Channel->INT3_SRCCFG |= DMA_INT3_SRCCFG_EN;
780 }
781
782 }
783
DMA_disableInterrupt(uint32_t interruptNumber)784 void DMA_disableInterrupt(uint32_t interruptNumber)
785 {
786 ASSERT(
787 (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1)
788 || (interruptNumber == DMA_INT2)
789 || (interruptNumber == DMA_INT3));
790
791 if (interruptNumber == DMA_INT1)
792 {
793 DMA_Channel->INT1_SRCCFG &= ~DMA_INT1_SRCCFG_EN;
794 } else if (interruptNumber == DMA_INT2)
795 {
796 DMA_Channel->INT2_SRCCFG &= ~DMA_INT2_SRCCFG_EN;
797 } else if (interruptNumber == DMA_INT3)
798 {
799 DMA_Channel->INT3_SRCCFG &= ~DMA_INT3_SRCCFG_EN;
800 }
801 }
802
DMA_registerInterrupt(uint32_t interruptNumber,void (* intHandler)(void))803 void DMA_registerInterrupt(uint32_t interruptNumber, void (*intHandler)(void))
804 {
805 //
806 // Check the arguments.
807 //
808 ASSERT(intHandler);
809 ASSERT(
810 (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1)
811 || (interruptNumber == DMA_INT2)
812 || (interruptNumber == DMA_INT3)
813 || (interruptNumber == DMA_INTERR));
814
815 //
816 // Register the interrupt handler.
817 //
818 Interrupt_registerInterrupt(interruptNumber, intHandler);
819
820 //
821 // Enable the memory management fault.
822 //
823 Interrupt_enableInterrupt(interruptNumber);
824
825 }
826
DMA_unregisterInterrupt(uint32_t interruptNumber)827 void DMA_unregisterInterrupt(uint32_t interruptNumber)
828 {
829 ASSERT(
830 (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1)
831 || (interruptNumber == DMA_INT2)
832 || (interruptNumber == DMA_INT3)
833 || (interruptNumber == DMA_INTERR));
834
835 //
836 // Disable the interrupt.
837 //
838 Interrupt_disableInterrupt(interruptNumber);
839
840 //
841 // Unregister the interrupt handler.
842 //
843 Interrupt_unregisterInterrupt(interruptNumber);
844 }
845
846