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 Problem for msp430f2618

Other Parts Discussed in Thread: MSP430F2618

HI

 I am ran a Example code , but the RxString is 0x00 , why?

the Example code is changed the MSP430F550x_dma_03.c


//                MSP430F2618
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32768Hz
//          --|RST          XOUT|-
//            |                 |
//            |             P1.0|-> LED
//            |                 |
//            |             P3.3|-> Data Out (UCA0SIMO)
//            |                 |
//            |             P3.4|<- Data In (UCA0SOMI)
//            |                 |
//            |             P2.7|-> Serial Clock Out (UCA0CLK)

#include "msp430x26x.h"
char TxString;
char RxString;

void main(void)
{
  // Set Watchdog interval to ~30ms
  WDTCTL = WDT_ADLY_1000;                   // WDT 1000ms, ACLK, interval timer
  IE1 |= WDTIE;                          // Enable WDT interrupt
  P1OUT &= ~0x01;                           // Clear P1.0 LED
  P1DIR |= BIT0;
  P3SEL |= BIT0+BIT4+BIT5+BIT6+BIT7;                       // P3.3,4 = USCI_A0 SPI Option
 

  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL0 = UCMST+UCSYNC+UCCKPL+UCMSB;     // 3-pin, 8-bit SPI master
                                            // Clock polarity high, MSB
  UCA0CTL1 = UCSSEL_2;                      // SMCLK
  UCA0BR0 = 0x02;                           // /2
  UCA0BR1 = 0x00;                           //
  UCA0MCTL = 0x00;                          // No modulation
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

  DMACTL0 |= DMA1TSEL_9+DMA0TSEL_10;        // DMA0 - UCA0TXIFG
 
  DMA0SA = (int)&TxString;                           // Src = RAM memory
  DMA0DA = (int)&UCA0TXBUF;   
 
                                            // Destination single address
  DMA0SZ = 1;                               // Block size
  DMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL;  // inc src

  // Setup DMA1
  DMA1SA = (int)&UCA0RXBUF;                           // Src = RAM memory
  DMA1DA = 0x2000;
 
  DMA1SZ = 1;                               // Block size
  DMA1CTL = DMADSTINCR_3+DMASBDB+DMALEVEL;  // inc dst

  TxString = RxString = 0;                  // Clear TxString
   __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3 w/ interrupts
  __no_operation();                         // Required only for debugger
}

// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
  if(TxString-1 == RxString)
    P1OUT |= 0x01;                          // Set P1.0 if True
  else
    P1OUT &= ~0x01;                         // Clear P1.0 if False

  TxString++;                               // Increment TxString counter
  DMA0CTL |= DMAEN;                         // DMA0 Enable
  DMA1CTL |= DMAEN;                         // DMA1 Enable
 //DMA2CTL |= DMAEN;                         // DMA2 Enable}
}

  • the RxString is 0x00;

       

      DMA0SA = (int)&TxString;                           // Src = RAM memory
      DMA0DA = (int)&UCA0TXBUF;   
     
                                                // Destination single address
      DMA0SZ = 1;                               // Block size
      DMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL;  // inc src

      // Setup DMA1
      DMA1SA = (int)&UCA0RXBUF;                           // Src = RAM memory
      DMA1DA =(int)&RxString;

  • From uses guide:

    "For proper operation, level-sensitive triggers can only be used when external trigger DMAE0 is selected as the trigger"

    If using the USCI as trigger source, you need to set it to edge-sensitive. (and this also exposes a problem for TX, as TXIFG is always set as soon as you clear SWRST - so you need to writ ethe wirst byte manually to TXBUF)

    However, you use DMASRCINCR_3 for TX and (worse) DMADSTINCR_3 for TX DMA, but your TX and RX "string" buffers are just one byte long. If you ever change the DMA transfer size to >1, this will corrupt your memory.

    Also, your initial code used fixed 0x2000 address and not RxString as destination.

    And in your ISR, you do nto increment the TxString pointer to the next char in the string, you increment the value of the TxString variable.

    Finally, the check in your timer ISR isn't very useful. timer ISR and DMA are not synchronized so depending on current timings, you may or may not have received the answer to the last TX DMA transfer (I assume you externally shorted SIMO and SOMI) (well, if you'd receive anything at all)

    But if I read the users guide right (and ther eis no bug in the table), the main problem is that DMAxTSEL_9 and DMAxTSEL_10 are triggered by USC1xXIFG. and you are using USCIA0. Bit this may well be a typo in the users guide.
    Well, it might really be a typo as there are not many 2x family MSPs with an USCIA1 and it makes not much sense having it for a trigger but not the USCIA0.
    Especially since TX seems to work, if I interpret your screenshot right (Which makes it even more strange that RX doesn't)

**Attention** This is a public forum