I'm trying to trigger ADC10 sample/conversion from TA0 using CCR0 output, without going through ISR.
It seems logical, if I have CCR0 output toggle with OUTMOD_4, and have ADC10CTL1 |= SHS_2, per diagram in SLAU144J, page 535, the trigger should pass through, without need to set ADC10SC.
Although, there is a fine print in ADC10CTL1 register description on page 555, "Timer triggers are from Timer0_Ax if more than one timer module exists on the device.", which makes me think that at least 2 timers should exist in the MSP430x2xx family device.
Well, it does not work. With multiple experiments, it looks like ADC10SC must be set every time sample/conversion needs to be done, and only then CCR0 output will trigger it.
Please confirm or rebut my finding.
Below is the partial code.
#include <msp430g2452.h>
#define LED BIT0
#define CCR0_OUT BIT1
void TA0_init(void);
void ADC_init(void);
void main(void) {
WDTCTL = WDTPW + WDTHOLD;
if (CALBC1_16MHZ==0xFF) {WDTCTL=0xDEAD;}
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
BCSCTL3 |= LFXT1S_2; // VLOCLK selected for ACLK, ~15KHz
BCSCTL1 |= DIVA_0; // ACLK/1, used for TA0 in LPM0
BCSCTL2 |= DIVS_1; // SMCLK/2 =8MHz, used for ADC experiment
P1SEL = CCR0_OUT; // Scope test point for TA0.CCR0 output
P1DIR = LED +CCR0_OUT; // Scope test points for ADC ISR and TA0.CCR0 output
TA0_init();
ADC_init();
_EINT(); // Enable ISR
TA0CTL |= MC_1; // Start the TIMER0 up to CCR0
for(;;){
_BIS_SR(CPUOFF); // Enter LPM0
}
}
void ADC_init(void){ // Read Thermometer, Trigg. from TA0CCR0, clocked ADC10OSC (or SMCLK)
ADC10CTL0 = SREF_0 + ADC10SHT_2 + REF2_5V + REFON + ADC10ON + ADC10IE;
ADC10CTL1 = INCH_10 + SHS_2 + ADC10DIV_0 + ADC10SSEL_0 + CONSEQ_0; // try ADC10SSEL_3
ADC10DTC1 = 0;
ADC10CTL0 |= ENC + ADC10SC; // Set ADC10SC for first sample/conversion
}
void TA0_init(void){ // Timer A for de-bounce and other operations
TA0CTL = TACLR; // Clear TAR
TA0CTL = TASSEL_1 + ID_0; // ACLK (11.5KHz), /1, (+ MC_1 Up TO CCR0 Mode)
TA0CCR0 = 2944; // TA0CCR0=ACLK*T(sec)=256msec
TA0CCTL0 = OUTMOD_4; // Toggle CCR0 OUT
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void){
_nop();
P1OUT ^=LED; // visual/scope output on every ADC10 ISR
volatile int ADC_MEM = (ADC10MEM & 0x03FF); // need to access ADC10MEM to clear ISR
ADC_MEM ^= 0xFFFF; // Do something stupid with ADC_MEM to keep compiler happy
ADC10CTL0 |= ADC10SC; // Set ADC10SC for next sample/conversion triggered be TA0 CCR0 out
}