Author Topic: ADC not working correctly SAMD20 (No ASF)  (Read 1693 times)

0 Members and 1 Guest are viewing this topic.

Offline matthew_zammitTopic starter

  • Newbie
  • Posts: 8
  • Country: mt
ADC not working correctly SAMD20 (No ASF)
« on: May 04, 2018, 05:48:16 pm »
So, I have an ADC which is software triggered every 30ms via the RTC interrupt handler. The problem is that the ADC produces garbage results no matter the voltage applied at the input. Am I setting it up wrongly?

Code: [Select]
void init_ADC(){
//ADC INPUT PIN INIT
PORT->Group[1].PINCFG[4].reg  = PORT_PINCFG_INEN | PORT_PINCFG_PMUXEN; // INPUT ENABLE AND PERIPHERAL MULTIPLEXING FOR ADC_INPUT
PORT->Group[1].PMUX[2].reg    = PORT_PMUX_PMUXE_B; // ENABLE ANLOUGE INPUT FOR ADC_INPUT
//Clock ADC by GCLK0 
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_WRTLOCK |
   GCLK_CLKCTRL_CLKEN   |
   GCLK_CLKCTRL_ID_ADC  |
   GCLK_CLKCTRL_GEN_GCLK0;
REG_PM_APBCMASK |= PM_APBCMASK_ADC; // enable ADC APB clock BUS
NVIC_SetPriority(ADC_IRQn,0); // SET TO HIGHEST PRIORITY INTERRUPT
NVIC_EnableIRQ( ADC_IRQn );     // enable interrupts for ADC

// 1.65V reference Voltage and (Reference buffer gain compensator -- REMOVE COMMENTS TO ENABLE)
REG_ADC_REFCTRL |= ADC_REFCTRL_REFSEL_INTVCC1;// | ADC_REFCTRL_REFCOMP;
while(ADC->STATUS.bit.SYNCBUSY);   //wait for synchronization

REG_ADC_CTRLB  |= ADC_CTRLB_PRESCALER_DIV4 | ADC_CTRLB_RESSEL_10BIT | ADC_CTRLB_LEFTADJ; //| ADC_CTRLB_CORREN;
while(ADC->STATUS.bit.SYNCBUSY);   //wait for synchronization

//INTERRUPT SET FOR WINDOW MONITOR or result is ready
REG_ADC_INTENSET |= ADC_INTFLAG_RESRDY; 
while(ADC->STATUS.bit.SYNCBUSY);   //wait for synchronization

REG_ADC_INPUTCTRL |= ADC_INPUTCTRL_MUXPOS_PIN12 | ADC_INPUTCTRL_GAIN_DIV2 | ADC_INPUTCTRL_MUXNEG_GND; //PIN MULTIPLEXING FOR ADC INPUT
while(ADC->STATUS.bit.SYNCBUSY);   //wait for synchronization

//Use this to calibrate Adc --- REG_ADC_CALIB = ADC_CALIB_BIAS_CAL() | ADC_CALIB_LINEARITY_CAL();

//This can be adjusted post testing -- REG_ADC_SAMPCTRL = ADC_SAMPCTRL_SAMPLEN(SOME SAMPLE LENGTH);

REG_ADC_CTRLA |= ADC_CTRLA_ENABLE;  //ENABLE ADC
while(ADC->STATUS.bit.SYNCBUSY);   //wait for synchronization
}

The Result register is read in the ADC interrupt handler. I've also tried enabling an LED at different Voltage thresholds but still no luck. :(
« Last Edit: May 04, 2018, 07:55:10 pm by matthew_zammit »
 

Online ajb

  • Super Contributor
  • ***
  • Posts: 2603
  • Country: us
Re: ADC not working correctly SAMD20 (No ASF)
« Reply #1 on: May 04, 2018, 08:35:26 pm »
IIRC, you have to provide some value for the offset and bias cal, I think the reset values will not give correct results.  Anyway, you want to at least load the factory cal values if you're not doing your own calibration.  Forum member ataradov has some example ADC startup code here: https://github.com/ataradov/dgw/blob/master/embedded/adc.c

Also check that your sampling times are reasonable.  For testing purposes, just set the sampling time to maximum to avoid any issues with miscalculated clocks--without knowing what the GCLK source is it's hard to say if the ADC is running at a reasonable rate.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: ADC not working correctly SAMD20 (No ASF)
« Reply #2 on: May 04, 2018, 08:39:31 pm »
What is your frequency on GCLK0? If it is higher than 8 MHz, then you are overclocking the ADC. You need to use the divider to slow down the clock.

The code looks reasonable otherwise.

And yes, calibration data will help, but without it you would be getting just 0, not random values.
« Last Edit: May 04, 2018, 08:41:14 pm by ataradov »
Alex
 

Offline matthew_zammitTopic starter

  • Newbie
  • Posts: 8
  • Country: mt
Re: ADC not working correctly SAMD20 (No ASF)
« Reply #3 on: May 05, 2018, 09:11:04 am »
Yes, using 8-bit mode made it work correctly. I ended up increasing the prescaler to 16 for it to work in 12-bit. Thanks a lot
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: ADC not working correctly SAMD20 (No ASF)
« Reply #4 on: May 05, 2018, 09:13:28 am »
Sample size should not matter. What matters is the input clock frequency. Maximum clock frequency after the prescaler is 2 MHz.
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf