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 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 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 64 uint32_t DMA_getErrorStatus(void) 65 { 66 // 67 // Return the DMA error status. 68 // 69 return DMA_Control->ERRCLR; 70 } 71 72 void DMA_clearErrorStatus(void) 73 { 74 // 75 // Clear the DMA error interrupt. 76 // 77 DMA_Control->ERRCLR = 1; 78 } 79 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 759 void DMA_requestSoftwareTransfer(uint32_t channel) 760 { 761 DMA_Channel->SW_CHTRIG |= (1 << channel); 762 } 763 764 uint32_t DMA_getInterruptStatus(void) 765 { 766 return DMA_Channel->INT0_SRCFLG; 767 } 768 769 void DMA_clearInterruptFlag(uint32_t channel) 770 { 771 DMA_Channel->INT0_CLRFLG |= (1 << channel); 772 } 773 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 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 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 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