Hello,
I am trying to use DMA to transfer data over UART. My aim is to transfer 128 bytes using DMA over UART.
For UART i am using UCA3 and DMA channel 3
In order to achieve this, i wrote following code :
#include <msp430.h>
#include <stdint.h>
const uint16_t tx_char = 128;
volatile unsigned char TXData[128] =
"0123456789d!Hello World!Hello World!Hello World!Hello World!HellHello World!Hello World!Hello World!Hello World!Hello World!Hell";
volatile unsigned char RXData[128];
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog
// configure gpio to toggle on interrupt
P4OUT &= ~BIT7; // Clear P4.7 output latch for a defined power-on state
P4DIR |= BIT7; // Set P4.7 to output direction
P3DIR |= BIT4;
P3SEL1 |= BIT4; // Output SMCLK
P1DIR |= BIT0;
P1SEL1 |= BIT0; // Output SMCLK
uint16_t c_tx = 0;
// Configure GPIO
P6SEL1 &= ~(BIT0 | BIT1);
P6SEL0 |= (BIT0 | BIT1); // USCI_A3 UART operation
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Configure USCI_A3 for UART mode
UCA3CTLW0 = UCSWRST; // Put eUSCI in reset
UCA3CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK
UCA3BRW = 8; // 1000000/115200 = 8.68
UCA3MCTLW = 0xD600; // 1000000/115200 - INT(1000000/115200)=0.68
// UCBRSx value = 0xD6 (See UG)
UCA3CTLW0 &= ~UCSWRST; // release from reset
// disable interrupt functionality to use DMA to perform transfers
UCA3IE &= (~UCTXIE); // Enable USCI_A3 TX interrupt
// configure DMA
DMA3CTL &= ~DMAEN; // DMA trigger should only be set when DMAEN = 0
DMACTL0 = DMA3TSEL__UCA3TXIFG; // UC0TXIFG trigger
// no interrupt pending
//DMACTL0 &= ~DMAIFG;
__data16_write_addr((unsigned short) &DMA3SA, (unsigned long) &TXData);
// Source single address
//__data16_write_addr((unsigned short) &DMA3DA, (unsigned long) &RXData);
__data16_write_addr((unsigned short) &DMA3DA, (unsigned long) &UCA3TXBUF);
// Destination array address
DMA3SZ = 128; // 128 bytes
// enable burst block transfer
// source increment
// enable DMA IE
// byte transfer
DMA3CTL = DMADT_1 + DMAEN + DMASRCINCR + DMASRCBYTE
+ DMADSTBYTE + DMADSTINCR;
__bis_SR_register(GIE); // Enter LPM0, interrupts enabled
__no_operation();
}
//------------------------------------------------------------------------------
// DMA Interrupt Service Routine
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(DMA_VECTOR))) DMA_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(DMAIV,16))
{
case 0: break;
case 2: // DMA0IFG = DMA Channel 0
P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE
break;
case 4: break; // DMA1IFG = DMA Channel 1
case 6: break; // DMA2IFG = DMA Channel 2
case 8: // DMA3IFG = DMA Channel 3
DMA3CTL |= DMAREQ;
P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE
break;
case 10: break; // DMA4IFG = DMA Channel 4
case 12: break; // DMA5IFG = DMA Channel 5
case 14: break; // DMA6IFG = DMA Channel 6
case 16: break; // DMA7IFG = DMA Channel 7
default: break;
}
}
Here, I am not able to generate any DMA interrupts. Can someone help me with this?