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