Skip to content

Commit b2393dc

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 5a1f8c1 commit b2393dc

File tree

7 files changed

+104
-32
lines changed

7 files changed

+104
-32
lines changed

cores/arduino/pins_arduino.h

Lines changed: 3 additions & 1 deletion
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

cores/arduino/stm32/analog.h

Lines changed: 1 addition & 1 deletion
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);

cores/arduino/wiring_analog.c

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,78 @@ 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_16B)
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_16B)
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
int _writeResolution = PWM_RESOLUTION;
3667
static uint32_t _writeFreq = PWM_FREQUENCY;
3768

3869
void analogReadResolution(int res)
3970
{
40-
_readResolution = res;
71+
if ((res > 0) && (res <= 32)) {
72+
_readResolution = res;
73+
_internalReadResolution = _readResolution;
74+
if (_readResolution > MAX_ADC_RESOLUTION) {
75+
_internalReadResolution = MAX_ADC_RESOLUTION;
76+
} else {
77+
#ifdef ADC_RESOLUTION_12B
78+
#ifndef ADC_RESOLUTION_16B
79+
if (_internalReadResolution <= 6) {
80+
_internalReadResolution = 6;
81+
} else
82+
#endif
83+
if (_internalReadResolution <= 8) {
84+
_internalReadResolution = 8;
85+
} else if (_internalReadResolution <= 10) {
86+
_internalReadResolution = 10;
87+
} else if (_internalReadResolution <= 12) {
88+
_internalReadResolution = 12;
89+
}
90+
#ifdef ADC_RESOLUTION_16B
91+
else if (_internalReadResolution <= 14) {
92+
_internalReadResolution = 14;
93+
} else if (_internalReadResolution <= 16) {
94+
_internalReadResolution = 16;
95+
}
96+
#endif
97+
#else
98+
_internalReadResolution = 12;
99+
#endif
100+
}
101+
} else {
102+
Error_Handler();
103+
}
41104
}
42105

43106
void analogWriteResolution(int res)
@@ -73,16 +136,16 @@ void analogReference(eAnalogReference ulMode)
73136
UNUSED(ulMode);
74137
}
75138

76-
//perform the read operation on the selected analog pin.
77-
//the initialization of the analog PIN is done through this function
139+
// Perform the read operation on the selected analog pin.
140+
// the initialization of the analog PIN is done through this function
78141
uint32_t analogRead(uint32_t ulPin)
79142
{
80143
uint32_t value = 0;
81144
#if defined(HAL_ADC_MODULE_ENABLED) && !defined(HAL_ADC_MODULE_ONLY)
82145
PinName p = analogInputToPinName(ulPin);
83146
if (p != NC) {
84-
value = adc_read_value(p);
85-
value = mapResolution(value, ADC_RESOLUTION, _readResolution);
147+
value = adc_read_value(p, _internalReadResolution);
148+
value = mapResolution(value, _internalReadResolution, _readResolution);
86149
}
87150
#else
88151
UNUSED(ulPin);

libraries/SrcWrapper/src/stm32/analog.cpp

Lines changed: 29 additions & 2 deletions
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,33 @@ 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+
#ifndef ADC_RESOLUTION_16B
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_16B
815+
case 14:
816+
AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */
817+
break;
818+
case 16:
819+
AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */
820+
break;
821+
#endif
822+
}
823+
#else
824+
UNUSED(resolution);
798825
#endif
799826
#ifdef ADC_DATAALIGN_RIGHT
800827
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */

variants/BLACK_F407XX/variant.h

Lines changed: 0 additions & 10 deletions
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

variants/BLUE_F407VE_Mini/variant.h

Lines changed: 0 additions & 10 deletions
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

variants/board_template/variant.h

Lines changed: 2 additions & 2 deletions
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)