Skip to content

Commit 6b93c7b

Browse files
committed
ADC_RESOLUTION hardening
Following Arduino API, analogReadResolution range is: 0 < x <= 32 Internal ADC Resolution could be up to 16 bits. Signed-off-by: Frederic Pillon <[email protected]>
1 parent f897ce5 commit 6b93c7b

File tree

7 files changed

+110
-32
lines changed

7 files changed

+110
-32
lines changed

Diff for: cores/arduino/pins_arduino.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ PinName analogInputToPinName(uint32_t pin);
307307

308308
// Default Definitions, could be redefined in variant.h
309309
#ifndef ADC_RESOLUTION
310-
#define ADC_RESOLUTION 12
310+
#define ADC_RESOLUTION 10
311311
#endif
312312

313313
#define DACC_RESOLUTION 12
@@ -316,6 +316,8 @@ PinName analogInputToPinName(uint32_t pin);
316316
#define PWM_RESOLUTION 8
317317
#endif
318318

319+
_Static_assert((ADC_RESOLUTION > 0) &&(ADC_RESOLUTION <= 32),
320+
"ADC_RESOLUTION must be 0 < x <= 32!");
319321
_Static_assert((PWM_RESOLUTION > 0) &&(PWM_RESOLUTION <= 32),
320322
"PWM_RESOLUTION must be 0 < x <= 32!");
321323

Diff for: cores/arduino/stm32/analog.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extern "C" {
5151
/* Exported functions ------------------------------------------------------- */
5252
void dac_write_value(PinName pin, uint32_t value, uint8_t do_init);
5353
void dac_stop(PinName pin);
54-
uint16_t adc_read_value(PinName pin);
54+
uint16_t adc_read_value(PinName pin, uint32_t resolution);
5555
void pwm_start(PinName pin, uint32_t clock_freq, uint32_t value, TimerCompareFormat_t resolution);
5656
void pwm_stop(PinName pin);
5757
uint32_t get_pwm_channel(PinName pin);

Diff for: cores/arduino/wiring_analog.c

+73-6
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,40 @@ extern "C" {
2929
uint32_t g_anOutputPinConfigured[MAX_NB_PORT] = {0};
3030
#endif
3131

32+
#if !defined(ADC_RESOLUTION_16B)
33+
#define MAX_ADC_RESOLUTION 12
34+
#else
35+
#define MAX_ADC_RESOLUTION 16
36+
#endif
3237
#define MAX_PWM_RESOLUTION 16
3338

34-
static int _readResolution = 10;
39+
static int _readResolution = ADC_RESOLUTION;
40+
static int _internalReadResolution =
41+
#if ADC_RESOLUTION > MAX_ADC_RESOLUTION
42+
MAX_ADC_RESOLUTION
43+
#else
44+
45+
#ifdef ADC_RESOLUTION_12B
46+
47+
#if ADC_RESOLUTION <= 6 && defined(ADC_RESOLUTION_6B)
48+
6
49+
#elif ADC_RESOLUTION <= 8
50+
8
51+
#elif ADC_RESOLUTION <= 10
52+
10
53+
#elif ADC_RESOLUTION <= 12
54+
12
55+
#elif ADC_RESOLUTION <= 14 && defined(ADC_RESOLUTION_14B)
56+
14
57+
#elif defined(ADC_RESOLUTION_16B)
58+
16
59+
#endif
60+
#else /* ADC_RESOLUTION_12B */
61+
12
62+
#endif /* ADC_RESOLUTION_12B */
63+
#endif /* ADC_RESOLUTION > MAX_ADC_RESOLUTION */
64+
;
65+
3566
static int _writeResolution = PWM_RESOLUTION;
3667
static int _internalWriteResolution =
3768
#if PWM_RESOLUTION > MAX_PWM_RESOLUTION
@@ -45,7 +76,43 @@ static uint32_t _writeFreq = PWM_FREQUENCY;
4576

4677
void analogReadResolution(int res)
4778
{
48-
_readResolution = res;
79+
if ((res > 0) && (res <= 32)) {
80+
_readResolution = res;
81+
_internalReadResolution = _readResolution;
82+
if (_readResolution > MAX_ADC_RESOLUTION) {
83+
_internalReadResolution = MAX_ADC_RESOLUTION;
84+
} else {
85+
#ifdef ADC_RESOLUTION_12B
86+
#ifdef ADC_RESOLUTION_6B
87+
if (_internalReadResolution <= 6) {
88+
_internalReadResolution = 6;
89+
} else
90+
#endif
91+
if (_internalReadResolution <= 8) {
92+
_internalReadResolution = 8;
93+
} else if (_internalReadResolution <= 10) {
94+
_internalReadResolution = 10;
95+
} else if (_internalReadResolution <= 12) {
96+
_internalReadResolution = 12;
97+
}
98+
#ifdef ADC_RESOLUTION_14B
99+
else if (_internalReadResolution <= 14) {
100+
_internalReadResolution = 14;
101+
}
102+
#endif
103+
#ifdef ADC_RESOLUTION_16B
104+
else if (_internalReadResolution <= 16) {
105+
_internalReadResolution = 16;
106+
}
107+
#endif
108+
#else
109+
/* STM32F1xx have no ADC_RESOLUTION_xB */
110+
_internalReadResolution = 12;
111+
#endif
112+
}
113+
} else {
114+
Error_Handler();
115+
}
49116
}
50117

51118
void analogWriteResolution(int res)
@@ -86,16 +153,16 @@ void analogReference(eAnalogReference ulMode)
86153
UNUSED(ulMode);
87154
}
88155

89-
//perform the read operation on the selected analog pin.
90-
//the initialization of the analog PIN is done through this function
156+
// Perform the read operation on the selected analog pin.
157+
// the initialization of the analog PIN is done through this function
91158
uint32_t analogRead(uint32_t ulPin)
92159
{
93160
uint32_t value = 0;
94161
#if defined(HAL_ADC_MODULE_ENABLED) && !defined(HAL_ADC_MODULE_ONLY)
95162
PinName p = analogInputToPinName(ulPin);
96163
if (p != NC) {
97-
value = adc_read_value(p);
98-
value = mapResolution(value, ADC_RESOLUTION, _readResolution);
164+
value = adc_read_value(p, _internalReadResolution);
165+
value = mapResolution(value, _internalReadResolution, _readResolution);
99166
}
100167
#else
101168
UNUSED(ulPin);

Diff for: libraries/SrcWrapper/src/stm32/analog.cpp

+31-2
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,10 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
758758
/**
759759
* @brief This function will set the ADC to the required value
760760
* @param pin : the pin to use
761+
* @param resolution : resolution for converted data: 6/8/10/12/14/16
761762
* @retval the value of the adc
762763
*/
763-
uint16_t adc_read_value(PinName pin)
764+
uint16_t adc_read_value(PinName pin, uint32_t resolution)
764765
{
765766
ADC_HandleTypeDef AdcHandle = {};
766767
ADC_ChannelConfTypeDef AdcChannelConf = {};
@@ -794,7 +795,35 @@ uint16_t adc_read_value(PinName pin)
794795
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */
795796
#endif
796797
#ifdef ADC_RESOLUTION_12B
797-
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */
798+
switch (resolution) {
799+
#ifdef ADC_RESOLUTION_6B
800+
case 6:
801+
AdcHandle.Init.Resolution = ADC_RESOLUTION_6B; /* resolution for converted data */
802+
break;
803+
#endif
804+
case 8:
805+
AdcHandle.Init.Resolution = ADC_RESOLUTION_8B; /* resolution for converted data */
806+
break;
807+
case 10:
808+
AdcHandle.Init.Resolution = ADC_RESOLUTION_10B; /* resolution for converted data */
809+
break;
810+
case 12:
811+
default:
812+
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* resolution for converted data */
813+
break;
814+
#ifdef ADC_RESOLUTION_14B
815+
case 14:
816+
AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */
817+
break;
818+
#endif
819+
#ifdef ADC_RESOLUTION_16B
820+
case 16:
821+
AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */
822+
break;
823+
#endif
824+
}
825+
#else
826+
UNUSED(resolution);
798827
#endif
799828
#ifdef ADC_DATAALIGN_RIGHT
800829
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */

Diff for: variants/BLACK_F407XX/variant.h

-10
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,6 @@ extern "C" {
123123
#define NUM_ANALOG_INPUTS 14
124124
#define NUM_ANALOG_FIRST 44
125125

126-
// Below ADC and PWM definitions already done in the core
127-
// Could be redefined here if needed
128-
// ADC resolution is 12bits
129-
//#define ADC_RESOLUTION 12
130-
131-
// PWM resolution
132-
//#define PWM_RESOLUTION 8
133-
//#define PWM_FREQUENCY 1000
134-
//#define PWM_MAX_DUTY_CYCLE 255
135-
136126
// On-board LED pin number
137127
#define LED_D2 PA6
138128
#define LED_D3 PA7

Diff for: variants/BLUE_F407VE_Mini/variant.h

-10
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,6 @@ extern "C" {
140140
#define NUM_ANALOG_INPUTS 14
141141
#define NUM_ANALOG_FIRST 80
142142

143-
// Below ADC and PWM definitions already done in the core
144-
// Could be redefined here if needed
145-
// ADC resolution is 12bits
146-
//#define ADC_RESOLUTION 12
147-
148-
// PWM resolution
149-
//#define PWM_RESOLUTION 8
150-
//#define PWM_FREQUENCY 1000
151-
//#define PWM_MAX_DUTY_CYCLE 255
152-
153143
// On-board LED pin number
154144
#define LED_BUILTIN PB9
155145

Diff for: variants/board_template/variant.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ extern "C" {
7070

7171
// Below ADC and PWM definitions already done in the core
7272
// Could be redefined here if needed
73-
// ADC resolution is 12bits
74-
//#define ADC_RESOLUTION 12
73+
// ADC resolution is 10 bits
74+
//#define ADC_RESOLUTION 10
7575

7676
// PWM resolution
7777
//#define PWM_RESOLUTION 8

0 commit comments

Comments
 (0)