Skip to content
Snippets Groups Projects
Commit e9a40fad authored by Erik Strand's avatar Erik Strand
Browse files

Expand initADC

parent 5fe09109
No related branches found
No related tags found
No related merge requests found
......@@ -23,13 +23,53 @@ static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to)
return value << (to-from);
}
/* ----------------------------------------------------------------------------------------------
* Initialize Analog Controller
*/
void bm_initADC(void) {
// Load ADC factory calibration values
#if !defined(DISABLE_ADC_CALIBRATION)
// ADC Bias Calibration
uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos;
// ADC Linearity bits 4:0
uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
// ADC Linearity bits 7:5
linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity);
syncADC(); // Wait for synchronization of registers between the clock domains
#endif
// Setting clock, prescaler and resolution
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_ADC ) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN ;
while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY );
ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 | // Divide Clock by 512.
ADC_CTRLB_RESSEL_10BIT; // 10 bits resolution as default
syncADC(); // Wait for synchronization of registers between the clock domains
// Setting configuration
ADC->SAMPCTRL.reg = 0x3f; // Set max Sampling Time Length
syncADC(); // Wait for synchronization of registers between the clock domains
ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND; // No Negative input (Internal Ground)
syncADC(); // Wait for synchronization of registers between the clock domains
// Averaging (see datasheet table in AVGCTRL register description)
ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // 1 sample only (no oversampling nor averaging)
ADC_AVGCTRL_ADJRES(0x0ul); // Adjusting result by 0
syncADC(); // Wait for synchronization of registers between the clock domains
analogReference( VARIANT_AR_DEFAULT ) ; // Use default reference from variant.h
}
void init_pin_adc(uint32_t pin) {
uint8_t const pinPort = GetPort(pin);
uint8_t const pinNum = GetPin(pin);
// Preserve state of pullup/pulldown enable, clear the rest of the bits
uint8_t pinCfg = (PORT->Group[pinPort].PINCFG[pinNum].reg & PORT_PINCFG_PULLEN);
if ( pinNum & 1 ) // is pin odd?
{
// Get whole current setup for both odd and even pins and remove odd one, then set new muxing
......@@ -43,12 +83,14 @@ void init_pin_adc(uint32_t pin) {
PORT->Group[pinPort].PMUX[pinNum >> 1].reg = temp | PORT_PMUX_PMUXE(PER_ANALOG) ;
}
// Set pin drive strength to normal, leave the input pullup setting alone, clear INEN, and
// enable peripheral mux.
uint8_t pinCfg = (PORT->Group[pinPort].PINCFG[pinNum].reg & PORT_PINCFG_PULLEN);
pinCfg |= PORT_PINCFG_PMUXEN; // Enable peripheral mux
// Set pin drive strength, enable/disable pull resistor, enable/disable INEN, and enable/disable the peripheral mux
PORT->Group[pinPort].PINCFG[pinNum].reg = (uint8_t)pinCfg ;
}
uint32_t bm_analogRead( uint32_t pin )
{
uint32_t valueRead = 0;
......@@ -72,7 +114,7 @@ void setup() {
digitalWrite(CHARGE_LINE_0, LOW);
// Initialize the ADC
initADC();
bm_initADC();
// Everything seems to function if I don't do this, but I'm leaving it in until I have a chance
// to investigate what's happening.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment