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" { ...@@ -26,7 +26,7 @@ extern "C" {
#endif #endif
/* /*
* \brief SAMD products have only one reference for ADC * \brief nRF51 and nRF52 have different reference options.
*/ */
#ifdef NRF52 #ifdef NRF52
typedef enum _eAnalogReference typedef enum _eAnalogReference
......
...@@ -48,6 +48,7 @@ static struct PWMContext pwmContext[PWM_COUNT] = { ...@@ -48,6 +48,7 @@ static struct PWMContext pwmContext[PWM_COUNT] = {
static int timerEnabled = 0; static int timerEnabled = 0;
static uint32_t adcReference = ADC_CONFIG_REFSEL_VBG; static uint32_t adcReference = ADC_CONFIG_REFSEL_VBG;
static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
static uint32_t readResolution = 10; static uint32_t readResolution = 10;
static uint32_t writeResolution = 8; static uint32_t writeResolution = 8;
...@@ -80,10 +81,11 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to ...@@ -80,10 +81,11 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
} }
/* /*
* Internal Reference is at 1.0v * Internal VBG Reference is 1.2 V.
* External Reference should be between 1v and VDDANA-0.6v=2.7v * 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 ) void analogReference( eAnalogReference ulMode )
{ {
...@@ -91,23 +93,34 @@ void analogReference( eAnalogReference ulMode ) ...@@ -91,23 +93,34 @@ void analogReference( eAnalogReference ulMode )
case AR_DEFAULT: case AR_DEFAULT:
case AR_VBG: case AR_VBG:
default: 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; adcReference = ADC_CONFIG_REFSEL_VBG;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
break; break;
case AR_SUPPLY_ONE_HALF: case AR_SUPPLY_ONE_HALF:
// 1/2 VDD Reference, 2/3 prescaler = 0 V - 0.75VDD range
adcReference = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling; adcReference = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break; break;
case AR_SUPPLY_ONE_THIRD: case AR_SUPPLY_ONE_THIRD:
// 1/3 VDD Reference, 1/3 prescaler = 0 V - VDD range
adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling; adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling;
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
break; break;
case AR_EXT0: 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); adcReference = ADC_CONFIG_REFSEL_External | (ADC_CONFIG_EXTREFSEL_AnalogReference0 << ADC_CONFIG_EXTREFSEL_Pos);
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break; break;
case AR_EXT1: 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); adcReference = (ADC_CONFIG_REFSEL_External | ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos);
adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling;
break; break;
} }
} }
...@@ -178,7 +191,7 @@ uint32_t analogRead( uint32_t ulPin ) ...@@ -178,7 +191,7 @@ uint32_t analogRead( uint32_t ulPin )
uint32_t config_reg = 0; uint32_t config_reg = 0;
config_reg |= ((uint32_t)adcResolution << ADC_CONFIG_RES_Pos) & ADC_CONFIG_RES_Msk; 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; config_reg |= ((uint32_t)adcReference << ADC_CONFIG_REFSEL_Pos) & ADC_CONFIG_REFSEL_Msk;
if (adcReference & ADC_CONFIG_EXTREFSEL_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