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.

CCS/MSP430F5525: Trouble with ADC triggerd DMA

Part Number: MSP430F5525
Other Parts Discussed in Thread: MSP430WARE

Tool/software: Code Composer Studio

Hello! I am trying to do an AD conversion of the readings of a joystick and with direct memory access storing the last 500 values of each axis of the joystick in two diferent vectors. For some reason, only the X axis vector is registering anything, the other one remains empty.

#include <msp430.h>

#define ADC12MEM0ADDR (__SFR_FARPTR) 0x0720
#define ADC12MEM1ADDR (__SFR_FARPTR) 0x0722

void ADC_Configure(void);
void CLK_Configure(void);
void TA0_Configure(void);
void DMA_Configure(void);

int analogX[500]; //X axis
int analogY[500]; //Y axis

int main(void) {

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

CLK_Configure();
TA0_Configure();
ADC_Configure();
DMA_Configure();

P6SEL |= BIT0 | BIT1;

__enable_interrupt();

while(1);
}

#pragma vector= TIMER0_A1_VECTOR

__interrupt void ISR_TA0(){

int n;
n = __even_in_range(TA0IV,0XE);
switch(n){

case 0xE:

TA0CTL &= ~TAIFG;

ADC12CTL0 &= ~ADC12SC; //ADC12SC = 0

ADC12CTL0 |= ADC12SC; //ADC12SC = 1

ADC12CTL0 &= ~ADC12SC; //ADC12SC = 0

break;

default: break;
}
}

void DMA_Configure(void){

DMACTL0 = DMA0TSEL_24 | DMA1TSEL_24; //Trigger ADC
DMA0CTL = DMAEN | 
                       DMADSTINCR_3 | 
                       DMADT_4; 
DMA1CTL = DMAEN | 
                        DMADSTINCR_3 | 
                        DMADT_4; 
DMA0SA = ADC12MEM0ADDR; //ADC MEM0
DMA1SA = ADC12MEM1ADDR; //ADC MEM1
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &analogX[0]); 
__data16_write_addr((unsigned short) &DMA1DA,(unsigned long) &analogY[0]); 
DMA0SZ = 500; 
DMA1SZ = 500; 

}


void ADC_Configure(void){

ADC12CTL0 &= ~ADC12ENC; 

ADC12CTL0 |= ADC12SHT0_0 | ADC12ON; //4 ciclos do ADC12CLK == 2us / Ligar ADC

ADC12CTL1 |= ADC12CSTARTADD_0 | //ADC12MEM0
                             ADC12SHS_0 | // Timer = ADC12SC
                             ADC12SHP | 
                             ADC12DIV_0 | 
                             ADC12SSEL_1 | //CLOCK = ACLK = 2MHz --> ADC12CLK = 500ns
                             ADC12CONSEQ_1; 

ADC12CTL2 |= ADC12TCOFF | 
                             ADC12RES_2; //12 bits

ADC12MCTL0 |= ADC12EOS | 
                                ADC12SREF_0 | //VR+ = AVcc e VR- = AVss
                                ADC12INCH_0 | // A0 = P6.0
                                ADC12INCH_1; // A1 = P6.1

ADC12CTL0|= ADC12ENC; 

}


void CLK_Configure(void){

P5SEL |= BIT2|BIT3|BIT4|BIT5;

//SMCLK = 1MHz 
//MCLK = 2MHz (tsample > 1,5us)

UCSCTL1|= DCORSEL_1; 

UCSCTL2|= FLLD_0; 

UCSCTL2|= 243; 

UCSCTL3|= SELREF_2; 

UCSCTL3|= FLLREFDIV_1; 

UCSCTL4 |= SELS_3 | // SMCLK = DCO
                        SELA_3; // ACLK = DCO
UCSCTL5 |= DIVS_2 | // SMCLK/1 = 1MHz
                        DIVA_1; // ACLK/2 = 2MHz
}

void TA0_Configure(void){

TA0CTL = TASSEL_2|ID_0|MC_1|TAIE; 
TA0CTL &= ~TACLR;
TA0EX0 = TAIDEX_0; 
TA0CCR0 = 10000; // SMCLK x 100000 = 10ms

}

  • Helena, 

    After looking through your code, I have a few comments:

    CLK_Configure function:

    • Why are you setting up the HFXT and LFXT pins?
    • I calculated your DCO and MCLK to be ~4MHz and not the 2MHz your comment specifies
      • Fdcoclkdiv = (N+1)*(Fref/n) = (243+1) * (32768/2) = ~4MHz

    TA0_Configure:

    • Why are you clearing TACLR from TA0CTL?
      • To clear the TimerA count register, you want to set this bit and it will be cleared automatically
      • I recommend setting it like this: TA0CTL = TASSEL_2|ID_0|MC_1|TAIE|TACLR;

    ADC_Configure:

    • You are not setting things up correctly for a sequence of conversions
    • ADC12MCTL0 controls the settings for ADC12MEM0, not both ADC12MEM1 and ADC12MEM0
      • You need to setup ADC12MEM1 settings if you intend to use this register (ADC12MCTL1)
    • Please take a look at the examples in MSP430Ware for the proper way to setup a sequence of conversions

    DMA_Configure:

    • Setup your source addresses in this fashion:
      • __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); 

    TimerA ISR:

    • There's no need to clear the SC bit before setting it. You should however check the ADC busy bit in ADC12CTL1 before starting a new conversion

    It looks like you've got a lot of changes that need to be made to the code. I recommend looking the the MSP430Ware examples and taking it one module at a time. If you have questions along the way let me know.

    Best regards, 

    Caleb Overbay

  • Hi,

    Have you been able to make the necessary changes and test your code?

    Best regards,
    Caleb Overbay

**Attention** This is a public forum