xref: /btstack/port/msp432p401lp-cc256x/ti/devices/msp432p4xx/driverlib/dma.c (revision 5fd0122a3e19d95e11e1f3eb8a08a2b2acb2557e)
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