I'm having trouble figuring out how to determine which ADC10 channel's result is in the MEM0 register when doing a sequence of channels. I am using the F5508 device, starting at channel 10 (Temp Sensor) and working down to 0.
My code gets the samples in the ISR and attempts to read the ADC10MCTL0 register to get the channel, but even though I do this first, I don't get the "correct" value, I get the value after it's been decremented.
Some specifics: MCLK = 16MHz, SMCLK = 8MHz, ADC clock is SMCLK/8 = 1 MHz. See the attached code.
What is the best way to get the correllation between MEM0 and channel?
//-----------------------------------------------------------------------------
// FUNCTION: InitAnalog()
//
// DESCRIPTION: This function is called to initialize this module
//
// RETURNS: Nothing
//
//-----------------------------------------------------------------------------
void InitAnalog( void )
{
struct s_TLV_ADC_Cal_Data *ptr;
UNSIGNED8 length;
UNSIGNED8 index;
// Initialze the static data structures
calData = NULL;
for (index=0; index<PFM_ADC_BUFSIZE; index++) SampleBuffer[index] = 0;
// Setup and enable the reference supply
REF_setReferenceVoltage(REF_BASE, PFM_REFSELECT);
if (REF_isRefGenBusy(REF_BASE) == REF_NOTBUSY)
{
REF_enableReferenceVoltage(REF_BASE);
usDelay(PFM_REF_SETTLE_US);
}
// Get the calibration data for the ADC and internal temp sensor
TLV_getInfo(TLV_TAG_ADC10CAL, 0, &length, (unsigned int**)&ptr);
// Get the calibration data from the chip's TLV data
if (ptr != NULL)
{
calData = ptr;
calADC20T30 = calData->adc_ref20_30_temp;
calADC20T85 = calData->adc_ref20_85_temp;
calTempScaleFactor1000x = ((INT32)(85-30)*1000)/(calADC20T85-calADC20T30);
}
else
{
calADC20T30 = 0;
calADC20T85 = 1; // Value chosen to avoid DIV-BY-0 Error
calTempScaleFactor1000x = 1;
}
// Setup the ADC10 parameters and enable the ADC
ADC10_A_init(ADC10_A_BASE, ADC10_A_SAMPLEHOLDSOURCE_SC,
PFM_ADC_CLKSRC, PFM_ADC_CLKDIV);
ADC10_A_setDataReadBackFormat(ADC10_A_BASE, ADC10_A_UNSIGNED_BINARY);
ADC10_A_setupSamplingTimer(ADC10_A_BASE, PFM_ADC_SMP_CYCLES,
ADC10_A_MULTIPLESAMPLESENABLE);
ADC10_A_enable(ADC10_A_BASE);
FirstADCSampled = 0;
SequenceFlag = 0;
}
//-----------------------------------------------------------------------------
// FUNCTION: StartADCConversion()
//
// DESCRIPTION: This function is called to start a conversion sequence in the
// ADC module.
//
// RETURNS: Nothing
//
//-----------------------------------------------------------------------------
void StartADCConversion(void)
{
// Make sure that any pending interrupt flags are cleared
ADC10_A_clearInterrupt(ADC10_A_BASE, ADC10IFG0);
// Setup the starting channel and the +/- reference voltages
ADC10_A_memoryConfigure(ADC10_A_BASE, PFM_ADCCHAN_START,
PFM_VREFPOS_SEL, PFM_VREFNEG_SEL);
// Enable the interrupt source for conversion complete
ADC10_A_enableInterrupt(ADC10_A_BASE, ADC10IFG0);
// Kick off the actual conversion sequence
ADC10_A_startConversion(ADC10_A_BASE, ADC10_A_SEQOFCHANNELS);
}
//-----------------------------------------------------------------------------
// FUNCTION: getCurrentChannel()
//
// DESCRIPTION: This function gets the channel that the most recent conversion
// was done on.
//
// RETURNS: Channel
//
//-----------------------------------------------------------------------------
static UNSIGNED8 getCurrentChannel(void)
{
return(HWREG(ADC10_A_BASE+OFS_ADC10MCTL0)&PFM_ADC_CHSEL_MASK);
}
//-----------------------------------------------------------------------------
// FUNCTION: ADC10_ISR()
//
// DESCRIPTION: This function is the interrupt service routine that handles
// getting the ADC conversion results and stuffing them into
// memory buffer
//
// RETURNS: Nothing
//
//-----------------------------------------------------------------------------
#pragma vector=ADC10_VECTOR
static __interrupt void ADC10_ISR( void )
{
UNSIGNED8 channel = getCurrentChannel();
UNSIGNED16 adcValue = ADC10_A_getResults(ADC10_A_BASE);
//@@ Debug Code
if (FirstADCSampled == 0) FirstADCSampled = channel;
if (channel < PFM_ADC_BUFSIZE)
{
SampleBuffer[channel] = adcValue;
}
//@@ Debug Code
if (channel == 0)
{
SequenceFlag = 1;
}
}