I need a straight answer from a straight question after spending too many hours banging my head. My goal is to trigger conversions from timer tb0 running in up mode rolling over at rate in compare register with the adc results going into add memory register 0 and then being transferred to a buffer via dma. I have successively tested the a/d using software triggered conversions. Now I have the timer, add and dma setup best as I can figure. Here is the initialization code:
// set up for single channel conversion triggered on timer and
// data sent to FRAM buffer.
setPortField(ADC12CTL0,1,1,0); // disable adc
setPortField(ADC12CTL0,4,4,1); // turn on adc
setPortField(ADC12CTL0,15,12,0); // ADC12SHT1x 4 clocks
setPortField(ADC12CTL0,11,8,0); // ADC12SHT0x 4 clocks
setPortField(ADC12CTL1,12,10,2); // sample/hold trigger source 2 select, TB0, CCR0
setPortField(ADC12CTL1,9,9,1); // ADC12SHP pulse mode
setPortField(ADC12CTL1,4,3,0b11); // clock source = SMCLK
setPortField(ADC12CTL1,2,1,0); // ADC12CONSEQx -> Single channel, single conversion
setPortField(ADC12CTL3,4,0,0); // conversion result to mem 0
setPortField(ADC12MCTL0,4,0,5); // select A5 for mem 0 in channel, P1.5 single ended
// setup timer TB0
setPortField(TB0CTL,9,8,0B10); // select SMCLK
setPortField(TB0CCTL0,8,8,0); // CAP = 0, compare mode
const float FREQ = 100e3; // 200 khz
const float CLK = 16e6; // timer clock
float periodReg = (CLK/FREQ) - 1;
TB0CCR0 = (periodReg + 0.5);
setPortField(TB0CTL,2,2,1); // clear timer
// config p1.5, the analog input for input with no pullup
setPortField(P1DIR,5,5,0); // input
setPortField(P1REN,5,5,0); // pull up or pull down disabled
// setup DMA, by default, word transfers, edge sensitive triggers
setPortField(DMACTL0,4,0,26); // dma channel 0, trigger 26 (adc eoc)
setPortField(DMA0CTL,14,12,0); // single transfer
setPortField(DMA0CTL,11,10,3); // destination address is incremented
setPortField(DMA0CTL,9,8,0); // source address is unchanged
setPortField(DMA0CTL,7,7,0); // word destination
setPortField(DMA0CTL,6,6,0); // word source
DMA0DA = (__SFR_FARPTR)(unsigned long)bigArray; // starting destination address
DMA0SA = (__SFR_FARPTR)(unsigned long)&ADC12MEM0; // address of current adc result
DMA0SZ = ARRAY_SIZE; // block size
setPortField(DMACTL4,2,0,0b001);
setPortField is function I wrote to write the fourth parameter value into fields specified by parameters 2 to 3 into location specified by the first parameter. Through extensive testing and debugging I know this function works correctly.
When I run my program I can see the the timer is running in the debugger and that the timer interrupt flag is being set What I don't understand well is the mechanism coupling the a/d trigger to the timer hitting the compare register setting. Best I can figure from the appropriate msp30 user and data sheet manuals is that the a/d sample and hold source should be set to source 2, TB0, CCR0, according to the docs.
Here is the code that starts things going and loops waiting for a dam interrupt after filling buffer.
setPortField(ADC12CTL0,1,1,1); // enable adc
setPortField(DMA0CTL,4,4,1); // enable dma
setPortField(TB0CTL,5,4,1); // start adc trigger timer
// for test
// wait for dma burst completion
volatile unsigned int dmaFlags = DMAIV;
while(dmaFlags == 0)
{
dmaFlags = DMAIV;
}
The loop never exits so I pause debugger to look at register values. I see that there is no indication that the a/d ever triggered.
I'm missing something, What is it?