This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMA trigger is not happened

Other Parts Discussed in Thread: MSP430F6438

Hi,

 I am using MSP430F6438, the following code i used to trigger DMA and transfer data but if i test in the debugger the DMASZ register never decrements, can any one guide me what mistsake i done in code. 

#include <msp430.h>

static char String1[] = { "Hello World\r\n" };

int main(void) {

  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog

P2SEL = BIT4+BIT5;                        // P4.4,5 = UART1 TXD/RXD
  // configure USCI_A1 UART
  UCA0CTL1 = UCSSEL__SMCLK;                      // SMCLK
  UCA0BR0 = 0x03;                           // 32768Hz 9600 32k/9600=3.41
  UCA0BR1 = 0x0;
  UCA0MCTL = UCBRS_3+UCBRF_0;               // Modulation UCBRSx = 3
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  // configure DMA0
  DMACTL0 = DMA0TSEL_17;                     
  __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) String1);
                                            // Source block address
  __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
                                            // Destination single address

 DMA0SZ = sizeof String1-1;                // Block size
  DMA0CTL &= ~(DMALEVEL);
  DMA0CTL = DMADT_0 + DMASRCINCR_3 + DMASBDB + DMAEN;// Rpt, inc src, enable

while(1);
}

#pragma vector=DMA_VECTOR __interrupt void DMA_ISR (void)

{

    DMA0CTL &= ~DMAIFG;    

  DMA0CTL &= ~DMAEN;

}

Thanks in advance

  • Each DMA transfer requires a trigger, and you're simply missing to trigger the first one. You can either start by transferring the first byte manually (UCA0TXBUF) and set the DMA start address to the second position, or (dirty) clear and set UCTXIFG in UCA0IFG to generate a fake interrupt.

    After the first byte, the TX interrupts will trigger each subsequent transfer until everything is transmitted.

    Some general issues: you didn't enable DMAIE for your DMA channel even though you have an ISR, and if you use SMCLK instead of ACLK for your application, you'll have to adapt the baudrate dividers.

  • Thanks Michael,

    I tried the two procedures which you explained but i am not getting trigger. Can you guide me where i made mistake.

    #include <msp430.h>

    static char String1[] = { "Hello World" };

    int main(void)

    {  

    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog

      P2SEL = BIT4+BIT5;                        // P4.4,5 = UART1 TXD/RXD
      UCA0CTL1 |= UCSWRST;                     // **Initialize USCI state machine**
      // configure USCI_A1 UART
      UCA0CTL1 = UCSSEL__SMCLK;                      // SMCLK
      UCA0BR0 = 0x03;                           // 32768Hz 9600 32k/9600=3.41
      UCA0BR1 = 0x0;
      UCA0MCTL = UCBRS_3+UCBRF_0;               // Modulation UCBRSx = 3
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

      DMA0CTL &= ~DMAEN;
      DMA0CTL = DMADT_4;
      DMA0CTL = DMASRCINCR_3;
      DMA0CTL = DMASBDB;

     DMA0SZ = sizeof String1;                // Block size
      __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) (String1+1));
                                                // Source block address
      __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
                                                // Destination single address

      DMA0CTL &= ~(DMAIFG);
       // configure DMA0
      DMACTL0 = DMA0TSEL_17;                    
      DMA0CTL |= DMAEN;

    /*To make fake interrupt*/

    /*  UCA0IFG &= ~(UCTXIFG);
      UCA0IFG |= UCTXIFG;*/

    /*To transfer first byte manually*/

    UCA0TXBUF = 0x48;

    }

    please guide me wheteher i made correctly to trigger DMA.

     

    Thanks in advance

  • Please don't change your configuration at random. Your DMA0CTL accesses overwrite every previous configuration.

        DMA0SZ = sizeof String1-2;
        DMA0CTL = DMADT_0 + DMASRCINCR_3 + DMASBDB + DMAIE;
        DMA0CTL |= DMAEN;

        __bis_SR_register(GIE);

        UCA0TXBUF = *String1;

        while(1);

    You also deleted the while(1); statement. If you still want to use interrupts, please return to your previous code sample, otherwise remove my GIE statement and DMAIE. I just tried it, and it works just fine with both variants.

  • Thanks Michael,

    But still this way is not works i have done the code as follows

    #include <msp430.h>

    static char String1[] = { "HelloWorld" };

    int main(void) {   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog

     P2SEL = BIT4+BIT5;                        // P4.4,5 = UART1 TXD/RXD
      UCA0CTL1 |= UCSWRST;                     // **Initialize USCI state machine**
      // configure USCI_A1 UART
      UCA0CTL1 |= UCSSEL_3;                      // SMCLK
      UCA0BR0 |= 0x03;                           // 32768Hz 9600 32k/9600=3.41
      UCA0BR1 |= 0x0;
      UCA0MCTL |= UCBRS_3+UCBRF_0;               // Modulation UCBRSx = 3
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

    DMA0CTL &= ~DMAEN;
      DMA0CTL |= DMADT_0;
      DMA0CTL |= DMASRCINCR_3;
      DMA0CTL |= DMASBDB;
     
      DMA0SZ = sizeof String1-2;                // Block size
      __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) String1);
                                                // Source block address
      __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
                                                // Destination single address

    DMA0CTL &= ~(DMAIFG);

    DMACTL0 |= DMA0TSEL_17; 

    DMA0CTL |= DMAEN;

    UCA0TXBUF = *String1;

    while(1);

    }

    but the fake interrupt method is works fine Thanks a lot...

  • IF UCTXIFG toggling works then writing to UCA0TXBUF should do the job, too. The code you posted works fine after changing the DMA0SA to (String1+1).

  • Hi Michael,

    Thanks for your reply

    can you please explain me how to trigger the DMA when receive through UART. I have done the code as follows

      
                    DMA1CTL &= ~DMAEN; 
                     
                    DMACTL0 = DMA1TSEL_16;    //DMA1TSEL_16 
      
                    DMA1CTL |= DMADT_0; 
                    
                    DMA1CTL |= DMADSTINCR_3;   
                       
                    DMA1CTL |= DMASBDB;    
                   
                    DMA1SZ = buf_ptr->szBuf;    
                  
                    DMA1SA = (uint16_t)&uartRegister0->rxbuf;
                         
                    DMA1DA =(uint16_t)buf_ptr->txrxbuf_ptr; //buffer to read values
                            
                    DMA1CTL = DMAIE;  
                      
                    DMA1CTL &= ~DMAIFG;
                           
                    DMA1CTL |= DMAEN;

    while checking in debugger UCOE bit is set, based on that i think the trigger for DMA1 is not occured.

    I tested in loopback mode concept, whichever sends through DMA0  its received through DMA1, the rxbuff is updated with the values sent, but the destination address also not increments.

    can you guide me how to enable trigger for receive

    Thanks in advance

**Attention** This is a public forum