Hello All, I am trying to do a simple program which configure ADC to read temperature and use DMA to send the result to UART for transmit. It looks like my ADC is not triggering my DMA, so when I look at the register UCATXBUF is always 0x00.
I am aware that I don't have the UART proportion of the code yet. I have this portion working another project. So here I am concentrating on getting the ADC read out to the UCATXBUF by DMA.
#include <msp430.h>
#include <stdint.h>
#define ADC_RESULTION_BITS 12
void DMA_config (void)
// configure DMA0
{
// Setup DMA0
DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered
DMACTL4 = DMARMWDIS; // Read-modify-write disable
DMA0CTL &= ~DMAIFG;
DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_0+DMASRCINCR_0+DMAIE; // Rpt single tranfer, unchanged src & dst, Int
DMA0SZ = 1; // Block size
__data20_write_long((uintptr_t) &DMA0SA,(uintptr_t) &ADC12MEM0); // Source block address
__data20_write_long((uintptr_t) &DMA0DA,(uintptr_t) &UCA1TXBUF); // Destination single address
}
void ADC_config()
{
// ADC Core control
ADC12CTL0 |= 0x00; // Initialize ADC12CTL0 register (Turn ADC12 OFF before configure it)
ADC12CTL0 |= ADC12SHT00 + ADC12SHT01 + ADC12SHT02 + ADC12SHT03;
ADC12CTL0 |= ADC12SHT10 + ADC12SHT11 + ADC12SHT12 + ADC12SHT13; // Sample-and-hold time set to 1024 ADC12CLK cycle
REFCTL0 |= (REFMSTR + REFON + REFVSEL_3); // Reference voltage 2.5V
ADC12CTL1 |= 0x00; // Initialize ADC12CTL1 register
ADC12CTL1 |= ADC12SHP; // S/H signal comes from Sample Timer
ADC12CTL1 |= ADC12SSEL0; // Set ADC12 clock source to ACLK (32,768kHz)
ADC12CTL1 |= ADC12DIV0 + ADC12DIV1 + ADC12DIV2; // Set ADC12 divider to 8
ADC12MCTL0 |= 0x0A; // Configure 12-bit ADC0 control register to 0x0A (1010b) for temperature diode
ADC12MCTL0 |= ADC12SREF0; // Select reference voltage (VREF+ and VR- = AVSS)
ADC12CTL2 |= 0x00; // Initialize ADC12CTL2 register
ADC12CTL2 |= ADC12PDIV; // Set ADC12 pre-divider to 4
ADC12CTL2 |= ADC12RES_2; // 12-bit resolution
ADC12IE |= ADC12IE0; // Enable ADC12 Interrupt on Memory 0
ADC12IFG |= ADC12IFG0;
ADC12CTL0 |= ADC12ON; // ADC12 Turn ON
ADC12CTL0 |= ADC12ENC | ADC12SC; // Enable ADC
}
int main(void)
{
ADC_config();
DMA_config();
__bis_SR_register(LPM0_bits + GIE); // LPM0 w/ interrupts
__no_operation(); // used for debugging
}
//------------------------------------------------------------------------------
// DMA Interrupt Service Routine
//------------------------------------------------------------------------------
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
switch(__even_in_range(DMAIV,16))
{
case 0: break;
case 2: // DMA0IFG = DMA Channel 0
P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE
break;
case 4: break; // DMA1IFG = DMA Channel 1
case 6: break; // DMA2IFG = DMA Channel 2
case 8: break; // DMA3IFG = DMA Channel 3
case 10: break; // DMA4IFG = DMA Channel 4
case 12: break; // DMA5IFG = DMA Channel 5
case 14: break; // DMA6IFG = DMA Channel 6
case 16: break; // DMA7IFG = DMA Channel 7
default: break;
}
}
ADC Interrupt flag is been set:
but DMA didn't transfer the data to the TxBuffer:
I am fully aware that the reading from 12bit ADC is 1 word wide (16bit) while the destination register UCATXBUF is only 8bit. According to the MSP430 user guide "When transferring word to byte, only the lower byte of the source word is transfered." So in this example, I am expecting 0xED to be written to UCATXBUF, but instead, it's reporting 0x00



