diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h index 8a289c3c05..e5900f9c6b 100644 --- a/cores/arduino/pins_arduino.h +++ b/cores/arduino/pins_arduino.h @@ -307,14 +307,20 @@ PinName analogInputToPinName(uint32_t pin); // Default Definitions, could be redefined in variant.h #ifndef ADC_RESOLUTION -#define ADC_RESOLUTION 12 +#define ADC_RESOLUTION 10 #endif -#ifndef DACC_RESOLUTION + #define DACC_RESOLUTION 12 -#endif + #ifndef PWM_RESOLUTION #define PWM_RESOLUTION 8 #endif + +_Static_assert((ADC_RESOLUTION > 0) &&(ADC_RESOLUTION <= 32), + "ADC_RESOLUTION must be 0 < x <= 32!"); +_Static_assert((PWM_RESOLUTION > 0) &&(PWM_RESOLUTION <= 32), + "PWM_RESOLUTION must be 0 < x <= 32!"); + #ifndef PWM_FREQUENCY #define PWM_FREQUENCY 1000 #endif diff --git a/cores/arduino/stm32/analog.h b/cores/arduino/stm32/analog.h index 2fac4ae16d..4ae2edd33b 100644 --- a/cores/arduino/stm32/analog.h +++ b/cores/arduino/stm32/analog.h @@ -51,7 +51,7 @@ extern "C" { /* Exported functions ------------------------------------------------------- */ void dac_write_value(PinName pin, uint32_t value, uint8_t do_init); void dac_stop(PinName pin); -uint16_t adc_read_value(PinName pin); +uint16_t adc_read_value(PinName pin, uint32_t resolution); void pwm_start(PinName pin, uint32_t clock_freq, uint32_t value, TimerCompareFormat_t resolution); void pwm_stop(PinName pin); uint32_t get_pwm_channel(PinName pin); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 1a5a92875b..83fe6fcb99 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -29,18 +29,104 @@ extern "C" { uint32_t g_anOutputPinConfigured[MAX_NB_PORT] = {0}; #endif -static int _readResolution = 10; -int _writeResolution = PWM_RESOLUTION; +#if !defined(ADC_RESOLUTION_16B) +#define MAX_ADC_RESOLUTION 12 +#else +#define MAX_ADC_RESOLUTION 16 +#endif +#define MAX_PWM_RESOLUTION 16 + +static int _readResolution = ADC_RESOLUTION; +static int _internalReadResolution = +#if ADC_RESOLUTION > MAX_ADC_RESOLUTION + MAX_ADC_RESOLUTION +#else + +#ifdef ADC_RESOLUTION_12B + +#if ADC_RESOLUTION <= 6 && defined(ADC_RESOLUTION_6B) + 6 +#elif ADC_RESOLUTION <= 8 + 8 +#elif ADC_RESOLUTION <= 10 + 10 +#elif ADC_RESOLUTION <= 12 + 12 +#elif ADC_RESOLUTION <= 14 && defined(ADC_RESOLUTION_14B) + 14 +#elif defined(ADC_RESOLUTION_16B) + 16 +#endif +#else /* ADC_RESOLUTION_12B */ + 12 +#endif /* ADC_RESOLUTION_12B */ +#endif /* ADC_RESOLUTION > MAX_ADC_RESOLUTION */ + ; + +static int _writeResolution = PWM_RESOLUTION; +static int _internalWriteResolution = +#if PWM_RESOLUTION > MAX_PWM_RESOLUTION + MAX_PWM_RESOLUTION +#else + PWM_RESOLUTION +#endif + ; + static uint32_t _writeFreq = PWM_FREQUENCY; void analogReadResolution(int res) { - _readResolution = res; + if ((res > 0) && (res <= 32)) { + _readResolution = res; + _internalReadResolution = _readResolution; + if (_readResolution > MAX_ADC_RESOLUTION) { + _internalReadResolution = MAX_ADC_RESOLUTION; + } else { +#ifdef ADC_RESOLUTION_12B +#ifdef ADC_RESOLUTION_6B + if (_internalReadResolution <= 6) { + _internalReadResolution = 6; + } else +#endif + if (_internalReadResolution <= 8) { + _internalReadResolution = 8; + } else if (_internalReadResolution <= 10) { + _internalReadResolution = 10; + } else if (_internalReadResolution <= 12) { + _internalReadResolution = 12; + } +#ifdef ADC_RESOLUTION_14B + else if (_internalReadResolution <= 14) { + _internalReadResolution = 14; + } +#endif +#ifdef ADC_RESOLUTION_16B + else if (_internalReadResolution <= 16) { + _internalReadResolution = 16; + } +#endif +#else + /* STM32F1xx have no ADC_RESOLUTION_xB */ + _internalReadResolution = 12; +#endif + } + } else { + Error_Handler(); + } } void analogWriteResolution(int res) { - _writeResolution = res; + if ((res > 0) && (res <= 32)) { + _writeResolution = res; + if (_writeResolution > MAX_ADC_RESOLUTION) { + _internalWriteResolution = MAX_ADC_RESOLUTION; + } else { + _internalWriteResolution = _writeResolution; + } + } else { + Error_Handler(); + } } void analogWriteFrequency(uint32_t freq) @@ -67,16 +153,16 @@ void analogReference(eAnalogReference ulMode) UNUSED(ulMode); } -//perform the read operation on the selected analog pin. -//the initialization of the analog PIN is done through this function +// Perform the read operation on the selected analog pin. +// the initialization of the analog PIN is done through this function uint32_t analogRead(uint32_t ulPin) { uint32_t value = 0; #if defined(HAL_ADC_MODULE_ENABLED) && !defined(HAL_ADC_MODULE_ONLY) PinName p = analogInputToPinName(ulPin); if (p != NC) { - value = adc_read_value(p); - value = mapResolution(value, ADC_RESOLUTION, _readResolution); + value = adc_read_value(p, _internalReadResolution); + value = mapResolution(value, _internalReadResolution, _readResolution); } #else UNUSED(ulPin); @@ -115,7 +201,8 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) if (is_pin_configured(p, g_anOutputPinConfigured) == false) { set_pin_configured(p, g_anOutputPinConfigured); } - pwm_start(p, _writeFreq, ulValue, _writeResolution); + ulValue = mapResolution(ulValue, _writeResolution, _internalWriteResolution); + pwm_start(p, _writeFreq, ulValue, _internalWriteResolution); } else #endif /* HAL_TIM_MODULE_ENABLED && !HAL_TIM_MODULE_ONLY */ { diff --git a/libraries/SrcWrapper/src/stm32/analog.cpp b/libraries/SrcWrapper/src/stm32/analog.cpp index f0cbd3a962..13eeac5147 100644 --- a/libraries/SrcWrapper/src/stm32/analog.cpp +++ b/libraries/SrcWrapper/src/stm32/analog.cpp @@ -758,9 +758,10 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc) /** * @brief This function will set the ADC to the required value * @param pin : the pin to use + * @param resolution : resolution for converted data: 6/8/10/12/14/16 * @retval the value of the adc */ -uint16_t adc_read_value(PinName pin) +uint16_t adc_read_value(PinName pin, uint32_t resolution) { ADC_HandleTypeDef AdcHandle = {}; ADC_ChannelConfTypeDef AdcChannelConf = {}; @@ -794,7 +795,35 @@ uint16_t adc_read_value(PinName pin) AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */ #endif #ifdef ADC_RESOLUTION_12B - AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ + switch (resolution) { +#ifdef ADC_RESOLUTION_6B + case 6: + AdcHandle.Init.Resolution = ADC_RESOLUTION_6B; /* resolution for converted data */ + break; +#endif + case 8: + AdcHandle.Init.Resolution = ADC_RESOLUTION_8B; /* resolution for converted data */ + break; + case 10: + AdcHandle.Init.Resolution = ADC_RESOLUTION_10B; /* resolution for converted data */ + break; + case 12: + default: + AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* resolution for converted data */ + break; +#ifdef ADC_RESOLUTION_14B + case 14: + AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */ + break; +#endif +#ifdef ADC_RESOLUTION_16B + case 16: + AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */ + break; +#endif + } +#else + UNUSED(resolution); #endif #ifdef ADC_DATAALIGN_RIGHT AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ diff --git a/variants/BLACK_F407XX/variant.h b/variants/BLACK_F407XX/variant.h index 79035a9968..6b98a273f8 100644 --- a/variants/BLACK_F407XX/variant.h +++ b/variants/BLACK_F407XX/variant.h @@ -123,17 +123,6 @@ extern "C" { #define NUM_ANALOG_INPUTS 14 #define NUM_ANALOG_FIRST 44 -// Below ADC, DAC and PWM definitions already done in the core -// Could be redefined here if needed -// ADC resolution is 12bits -//#define ADC_RESOLUTION 12 -//#define DACC_RESOLUTION 12 - -// PWM resolution -//#define PWM_RESOLUTION 8 -//#define PWM_FREQUENCY 1000 -//#define PWM_MAX_DUTY_CYCLE 255 - // On-board LED pin number #define LED_D2 PA6 #define LED_D3 PA7 diff --git a/variants/BLUE_F407VE_Mini/variant.h b/variants/BLUE_F407VE_Mini/variant.h index 9ec1c11b62..93dd2cd88f 100644 --- a/variants/BLUE_F407VE_Mini/variant.h +++ b/variants/BLUE_F407VE_Mini/variant.h @@ -140,17 +140,6 @@ extern "C" { #define NUM_ANALOG_INPUTS 14 #define NUM_ANALOG_FIRST 80 -// Below ADC, DAC and PWM definitions already done in the core -// Could be redefined here if needed -// ADC resolution is 12bits -//#define ADC_RESOLUTION 12 -//#define DACC_RESOLUTION 12 - -// PWM resolution -//#define PWM_RESOLUTION 8 -//#define PWM_FREQUENCY 1000 -//#define PWM_MAX_DUTY_CYCLE 255 - // On-board LED pin number #define LED_BUILTIN PB9 diff --git a/variants/board_template/variant.h b/variants/board_template/variant.h index 3f7fc312bd..01e02fac96 100644 --- a/variants/board_template/variant.h +++ b/variants/board_template/variant.h @@ -68,11 +68,10 @@ extern "C" { // First analog pin value (A0) must be greater than or equal to NUM_ANALOG_INPUTS #define NUM_ANALOG_FIRST 0 -// Below ADC, DAC and PWM definitions already done in the core +// Below ADC and PWM definitions already done in the core // Could be redefined here if needed -// ADC resolution is 12bits -//#define ADC_RESOLUTION 12 -//#define DACC_RESOLUTION 12 +// ADC resolution is 10 bits +//#define ADC_RESOLUTION 10 // PWM resolution //#define PWM_RESOLUTION 8