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.

MSP430F5438A: Using DMA to transfer ADC Values to UART Configuration issue

Part Number: MSP430F5438A
Other Parts Discussed in Thread: MSP430WARE

Hi,

I am trying to configure DMA0 to transfer data from the ADC to a buffer and DMA1 to transfer data from circularBuffer0 to UART. The adc is sampled based on a timer trigger.

When debugging the ADC samples correctly and I can send and receive information via UART however there is no DMA transfer from ADC result memory to the buffer and to the UART.

Am I initialising the DMA correctly?

Thank you,

Vlad

#include <msp430.h>
#include <stdint.h>

#define No_Buf_Samples 1376 // Definition of number of samples to be store in the buffer

volatile int circularBuffer0[No_Buf_Samples];

void DMA_Init()
{

DMACTL0 |= DMA0TSEL_24; // DMA0 trigger from ADC12IFGx

// TEST - Read in the test array
DMA0SZ = No_Buf_Samples; // Block size

DMACTL4 = DMARMWDIS; // Read-modify-write disable
DMA0CTL &= ~DMAIFG; // Clear DMA interrupt flag
// DMA0CTL |= DMADT_4 + DMASRCINCR_0 + DMADSTINCR_3 + DMASBDB + DMAIE ;//Repeat single transfer, Source address constant, Destination address incremented,

//DMA1 to UART
DMACTL0 |= DMA1TSEL_30; // DMA1 Trigger from DMA0IFG
DMA1CTL |= DMADT_6 + DMASRCINCR_3+ DMADSTINCR_0 + DMASBDB + DMALEVEL; //Burst block transfer, Increment source address, Destination address unchanged , enable , level sensitive

}



void DMA_ADC_Transfer()
{
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0);
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &circularBuffer0);

DMA0CTL |= DMAEN; // Enable DMA0

DMA0CTL |= DMAREQ; // Trigger block transfer
}

// DMA Uart Transfer Function

void DMA_UART_Transfer()
{
DMA1SZ = sizeof (circularBuffer0); // Block size
__data16_write_addr((unsigned short) &DMA1SA,(unsigned long) &circularBuffer0);
__data16_write_addr((unsigned short) &DMA1DA,(unsigned long) &UCA1TXBUF);
DMA1CTL |= DMAEN; // // Enable DMA1
DMA1CTL |= DMAREQ; // Trigger block transfer
}



void Timer_B_Init(void)
{
//TB0CCTL0 = CCIE; // CCR0 interrupt enabled
TB0CCR0 = 80; // Init TBCCR0 w/ sample period
TB0CCR1 = 40; // Trigger for ADC12 Sample Conversion
TB0CCTL1 = OUTMOD_4; // Trigger ADC Conversion Mode OutMOD Set/Reset
TB0CTL |= TASSEL_2 + MC_1 + TACLR ; // SMCLK, up mode
}

void UART_Init(void)

{

P5SEL |= 0xC0; // P5.6,7 = USCI_A1 TXD/RXD

UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_2; // SMCLK

// 16MHz Baud 115200
UCA1BR0 = 0x45; // Clock 16MHz, Baud 115200
UCA1BR1 = 0x00; // Clock 16MHz, Baud 115200
UCA1MCTL |= UCBRS_4 + UCBRF_0; // Modulation UCBRSx=4, UCBRFx=0, UCOS16 =0


UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt

}



void ADC_Init(int ADC_Sampling_Channel,int ADC_Sampling_Mode)
{


P6SEL |= (1<<BIT7); // Enable selected A/D Channel Peripheral Function
P6DIR &= ~BIT7; // ADC Input Direction

ADC12CTL0 &= (~(1<<ADC12ENC)); // Allows setting of ADC registers

ADC12CTL0 |= ADC12SHT0_0 + ADC12ON;// Turn On ADC12,4 clk cycles sampling, ADC Reference Set at +AVcc and -AVss

ADC12CTL1 |= ADC12SHS_3 + ADC12SHP + ADC12SSEL_0;// Sample-and-hold pulse mode, TB0.1 Sample Source, ADC12OSC Source

ADC12CTL2 |=ADC12RES_2 + ADC12TCOFF; // ADC 12 bit res, Temperature sensor off

ADC12MCTL0 = ADC12INCH_7 + ADC12EOS; // map CH 7 to MEM0, End of Sampling

void ADC_Init(int ADC_Sampling_Channel,int ADC_Sampling_Mode)
{


P6SEL |= (1<<BIT7); // Enable selected A/D Channel Peripheral Function
P6DIR &= ~BIT7; // ADC Input Direction

ADC12CTL0 &= (~(1<<ADC12ENC)); // Allows setting of ADC registers

ADC12CTL0 |= ADC12SHT0_0 + ADC12ON;// Turn On ADC12,4 clk cycles sampling, ADC Reference Set at +AVcc and -AVss

ADC12CTL1 |= ADC12SHS_3 + ADC12SHP + ADC12SSEL_0;// Sample-and-hold pulse mode, TB0.1 Sample Source, ADC12OSC Source

ADC12CTL2 |=ADC12RES_2 + ADC12TCOFF; // ADC 12 bit res, Temperature sensor off

ADC12MCTL0 = ADC12INCH_7 + ADC12EOS; // map CH 7 to MEM0, End of Sampling

ADC12CTL1 |= ADC12CONSEQ_0; 

ADC12IE = ADC12IE0; // Enable interrupt

}

void ADC_Start(void)
{
ADC12CTL0 |= ADC12ENC + ADC12SC; // Enable Conversion

}



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

//Initialise The DMA Functionality
DMA_Init();

//Initialise the UART A1
UART_Init();

//Initialise the Timer A0 - used for power saving and TB0.1 - ADC tirgger
Timer_B_Init();

ADC_Init(7,SingleChannel_SingleMeasurement); // Initialise ADC Function

ADC_Start();

DMA_ADC_Transfer();
DMA_UART_Transfer();

__bis_SR_register(GIE); //interrupts enabled

while(1)

{

 // do nothing

}



}

  • Hello Vlad,

    Debugging DMA transfers can be tricky to do. I would suggest breaking up the DMA - UART transfer and the ADC-DMA transfer and debug these separately. That being said, we do provide a DMA -ADC12 code example you can use to compare with your code. The key point I would look at is to make sure you have your DMA triggers correct.

    the code example I am referring to is found within TI Resource Explorer -> SW -> MSP430Ware -> Devices -> MSP430F5xx_6xx - > MSP430F5438A -> Peripheral Examples -> Register Level -> msp430x54xA_dma_04.c

    You can find TI Resource Explorer and MSP430Ware within CCS or at the cloud version linked below.
    dev.ti.com/.../

**Attention** This is a public forum