@@ -48,6 +48,7 @@ static struct PWMContext pwmContext[PWM_COUNT] = {
4848static int timerEnabled = 0 ;
4949
5050static uint32_t adcReference = ADC_CONFIG_REFSEL_VBG ;
51+ static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling ;
5152
5253static uint32_t readResolution = 10 ;
5354static uint32_t writeResolution = 8 ;
@@ -80,34 +81,46 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
8081}
8182
8283/*
83- * Internal Reference is at 1.0v
84- * External Reference should be between 1v and VDDANA-0.6v=2.7v
84+ * Internal VBG Reference is 1.2 V.
85+ * External References AREF0 and AREF1 should be between 0.83 V - 1.3 V.
8586 *
86- * Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum
87+ * Warning : ADC should not be exposed to > 2.4 V, calculated after prescaling.
88+ * GPIO pins must not be exposed to higher voltage than VDD + 0.3 V.
8789 */
8890void analogReference ( eAnalogReference ulMode )
8991{
9092 switch ( ulMode ) {
9193 case AR_DEFAULT :
9294 case AR_VBG :
9395 default :
96+ // 1.2 Reference, 1/3 prescaler = 0 V - 3.6 V range
97+ // Minimum VDD for full range in safe operation = 3.3V
9498 adcReference = ADC_CONFIG_REFSEL_VBG ;
99+ adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling ;
95100 break ;
96101
97102 case AR_SUPPLY_ONE_HALF :
103+ // 1/2 VDD Reference, 2/3 prescaler = 0 V - 0.75VDD range
98104 adcReference = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling ;
105+ adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling ;
99106 break ;
100107
101108 case AR_SUPPLY_ONE_THIRD :
109+ // 1/3 VDD Reference, 1/3 prescaler = 0 V - VDD range
102110 adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling ;
111+ adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling ;
103112 break ;
104113
105114 case AR_EXT0 :
115+ // ARF0 reference, 2/3 prescaler = 0 V - 1.5 ARF0
106116 adcReference = ADC_CONFIG_REFSEL_External | (ADC_CONFIG_EXTREFSEL_AnalogReference0 << ADC_CONFIG_EXTREFSEL_Pos );
117+ adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling ;
107118 break ;
108119
109120 case AR_EXT1 :
121+ // ARF1 reference, 2/3 prescaler = 0 V - 1.5 ARF1
110122 adcReference = (ADC_CONFIG_REFSEL_External | ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos );
123+ adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling ;
111124 break ;
112125 }
113126}
@@ -178,7 +191,7 @@ uint32_t analogRead( uint32_t ulPin )
178191 uint32_t config_reg = 0 ;
179192
180193 config_reg |= ((uint32_t )adcResolution << ADC_CONFIG_RES_Pos ) & ADC_CONFIG_RES_Msk ;
181- config_reg |= ((uint32_t )ADC_CONFIG_RES_10bit << ADC_CONFIG_INPSEL_Pos ) & ADC_CONFIG_INPSEL_Msk ;
194+ config_reg |= ((uint32_t )adcPrescaling << ADC_CONFIG_INPSEL_Pos ) & ADC_CONFIG_INPSEL_Msk ;
182195 config_reg |= ((uint32_t )adcReference << ADC_CONFIG_REFSEL_Pos ) & ADC_CONFIG_REFSEL_Msk ;
183196
184197 if (adcReference & ADC_CONFIG_EXTREFSEL_Msk )
0 commit comments