AnsweredAssumed Answered

Cannot read an ADC in a timer ISR

Question asked by clive palmer on Jul 4, 2014
Latest reply on Jul 16, 2014 by jeremyzhou

I am trying to read a few ADCs channels on a 4KHZ ish update rate from a timed interrupt.

 

I can read the ADC using my command line parser. I have also checked my TPM timer ISR and it works fine.

and hits the ISR every 244us (4KHZ = 250us)

The ADC has been set for a conversion time of 30uS. I have checked my calculation with the freescale ADC calculator and it should be correct.

I want to read 4 ADC channels (30us * 4 = 120us)

My ADC init routine is:-

 

void adc_init(void)
{

SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; //  enable clock

ADC0_CFG1 = ADC_CFG1_ADICLK(0)   // bus clock 24MHZ
     | ADC_CFG1_ADIV(1)     //ADCK = input clock/2
     | ADC_CFG1_MODE(1);     //12-bit mode

    ADC0_CFG2 &= ~(ADC_CFG2_MUXSEL_MASK  // channel A
             | ADC_CFG2_ADACKEN_MASK);  //asynchronous clock output disabled
    ADC0_CFG2 |= ADC_CFG2_ADHSC_MASK; //HI speed mode

    ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // SW trigger
    ADC0_SC2 |= ADC_SC2_REFSEL(0); //voltage reference source VREFH&L

    ADC0_SC3 = ADC_SC3_ADCO_MASK  //continuous conversion
   | ADC_SC3_AVGE_MASK  //hardware average is enabled
   | ADC_SC3_AVGS(2);   //16 averages
    ADC0_SC1A = ADC_SC1_ADCH(31); // disable module
}

 

At the moment Im just calling a simple ADC read function.

 

unsigned int adc_read(uint8_t channel)      //for CHANNEL-A
{
   CRITICAL_SECTION_BEGIN;
   ADC0_SC1A = ADC_SC1_ADCH(31);           //disable adc

   ADC0_SC1A = channel;

   while((ADC0_SC1A & ADC_SC1_COCO_MASK) == 0){}; // wait for conversion complete int to clear
   CRITICAL_SECTION_END;
   return ADC0_RA;
}

 

Am I being dumb. Is there some good reason why I cannot read an ADC channel from my TPM ISR?

Outcomes