I'm using MSP430F2618 to build a sensing pipeline. TimerB periodically triggers the ADC sampling. Once each ADC sample is obtained, the ADC12IFG triggers DMA0 to transfer the ADC values to a RAM location. Once the DMA0 transfer is done, the DMA0 should trigger another DMA transfer (DMA1) to transfer the RAM data to UART. However, the last step, where the DMA0 triggers the DMA1 transfer fails. I spent long time on debugging and still cannot figure out the bug. Can you guys help figure out the possible reason? Attached are my codes.
#include "msp430x26x.h"
void Record(void);
volatile char buf[2000];
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// voltage sampling configuration.
P4DIR |= BIT3;
P4OUT |= BIT3;
// config uart
P3SEL |= BIT6 + BIT7; // P3.6,7 = USART1 TXD/RXD
UCA1CTL1 = UCSSEL_1; // ACLK
UCA1BR0 = 0x01; // 32768Hz 9600 32k/9600=3.41
UCA1BR1 = 0x00;
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
// config adc
P6SEL |= BIT4;
ADC12MCTL4 = SREF_0 + INCH_4; // Channel A4, Vref+
ADC12IFG = 0;
ADC12CTL1 = CSTARTADD_4 + SHS_3 + CONSEQ_2; // S&H TB.OUT1, rep. single chan
ADC12CTL0 = ADC12ON+SHT0_0; // VRef ADC12 on, enabled
// config dma0 - adc to ram
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM4);
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &buf);
DMA0SZ = 1; // words
DMACTL0 = DMA0TSEL_6; // ADC12IFGx triggers DMA0
DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAIE + DMAEN; // Config
// config dma1 - adc to ram
__data16_write_addr((unsigned short) &DMA1SA,(unsigned long) &buf);
__data16_write_addr((unsigned short) &DMA1DA,(unsigned long) &UCA1TXBUF);
DMA1SZ = 3;
DMACTL0 |= DMA1TSEL_14;
DMA1CTL = DMADT_5 + DMASRCINCR_3 + DMASBDB + DMAEN; // Config
// turn on adc
ADC12CTL1 |= CONSEQ_2;
ADC12CTL0 |= ENC;
// turn on timer
TBCCR0 = 30000; // Init TBCCR0 w/ sample prd
TBCCR1 = 70; // Trigger for ADC12 SC
TBCCTL1 = OUTMOD_7; // Reset OUT1 on EQU1, set on EQU0
TBCTL = TBSSEL_1 + MC_1 + TBCLR; // SMCLK, clear TBR, up mode
__bis_SR_register(LPM0_bits + GIE);
while(1)
{
P1OUT |= DEBUG_1_7;
P1OUT &= ~DEBUG_1_7;
}
}
void Record(void)
{
// turn on adc
ADC12CTL1 |= CONSEQ_2;
ADC12CTL0 |= ENC;
// turn on timer
TBCCR0 = 3000; // Init TBCCR0 w/ sample prd
TBCCR1 = 70; // Trigger for ADC12 SC
TBCCTL1 = OUTMOD_7; // Reset OUT1 on EQU1, set on EQU0
TBCTL = TBSSEL_1 + MC_1 + TBCLR; // SMCLK, clear TBR, up mode
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
}
#pragma vector = DMA_VECTOR
__interrupt void DMA_ISR(void)
{
//ADC12CTL1 &= ~CONSEQ_2; // Stop conversion immediately
//ADC12CTL0 &= ~ENC; // Disable ADC12 conversion
//TBCTL = 0; // Disable Timer_B
DMA0CTL &= ~DMAIFG; // Clear DMA0 interrupt flag
//P1OUT |= DEBUG_1_7;
//P1OUT &= ~DEBUG_1_7;
//__bic_SR_register_on_exit(LPM0_bits); // Exit LPMx, interrupts enabled
}