Commit 425e719a authored by Sandeep Mistry's avatar Sandeep Mistry Committed by GitHub

Merge pull request #142 from carlosperate/adc

Fix ADC prescaler reg config, add prescaler options
parents bf534ec4 023b94f9
......@@ -26,7 +26,7 @@ extern "C" {
#endif
/*
* \brief SAMD products have only one reference for ADC
* \brief nRF51 and nRF52 have different reference options.
*/
#ifdef NRF52
typedef enum _eAnalogReference
......
......@@ -48,6 +48,7 @@ static struct PWMContext pwmContext[PWM_COUNT] = {
static int timerEnabled = 0;
static uint32_t adcReference = ADC_CONFIG_REFSEL_VBG;
static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
static uint32_t readResolution = 10;
static uint32_t writeResolution = 8;
......@@ -80,10 +81,11 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
}
/*
* Internal Reference is at 1.0v
* External Reference should be between 1v and VDDANA-0.6v=2.7v
* Internal VBG Reference is 1.2 V.
* External References AREF0 and AREF1 should be between 0.83 V - 1.3 V.
*
* Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum
* Warning : ADC should not be exposed to > 2.4 V, calculated after prescaling.
* GPIO pins must not be exposed to higher voltage than VDD + 0.3 V.
*/
void analogReference( eAnalogReference ulMode )
{
......@@ -91,23 +93,34 @@ void analogReference( eAnalogReference ulMode )
case AR_DEFAULT:
case AR_VBG:
default:
// 1.2 Reference, 1/3 prescaler = 0 V - 3.6 V range
// Minimum VDD for full range in safe operation = 3.3V
adcReference = ADC_CONFIG_REFSEL_VBG;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
break;
case AR_SUPPLY_ONE_HALF:
// 1/2 VDD Reference, 2/3 prescaler = 0 V - 0.75VDD range
adcReference = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break;
case AR_SUPPLY_ONE_THIRD:
// 1/3 VDD Reference, 1/3 prescaler = 0 V - VDD range
adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
break;
case AR_EXT0:
// ARF0 reference, 2/3 prescaler = 0 V - 1.5 ARF0
adcReference = ADC_CONFIG_REFSEL_External | (ADC_CONFIG_EXTREFSEL_AnalogReference0 << ADC_CONFIG_EXTREFSEL_Pos);
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break;
case AR_EXT1:
// ARF1 reference, 2/3 prescaler = 0 V - 1.5 ARF1
adcReference = (ADC_CONFIG_REFSEL_External | ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos);
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break;
}
}
......@@ -178,7 +191,7 @@ uint32_t analogRead( uint32_t ulPin )
uint32_t config_reg = 0;
config_reg |= ((uint32_t)adcResolution << ADC_CONFIG_RES_Pos) & ADC_CONFIG_RES_Msk;
config_reg |= ((uint32_t)ADC_CONFIG_RES_10bit << ADC_CONFIG_INPSEL_Pos) & ADC_CONFIG_INPSEL_Msk;
config_reg |= ((uint32_t)adcPrescaling << ADC_CONFIG_INPSEL_Pos) & ADC_CONFIG_INPSEL_Msk;
config_reg |= ((uint32_t)adcReference << ADC_CONFIG_REFSEL_Pos) & ADC_CONFIG_REFSEL_Msk;
if (adcReference & ADC_CONFIG_EXTREFSEL_Msk)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment