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