diff --git a/cores/arduino/HardwareTimer.cpp b/cores/arduino/HardwareTimer.cpp index c3174cc1ba..04c6a34d7a 100644 --- a/cores/arduino/HardwareTimer.cpp +++ b/cores/arduino/HardwareTimer.cpp @@ -538,11 +538,23 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC case PERCENT_COMPARE_FORMAT: CCR_RegisterValue = ((__HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)) + 1) * compare) / 100; break; + case RESOLUTION_1B_COMPARE_FORMAT: + case RESOLUTION_2B_COMPARE_FORMAT: + case RESOLUTION_3B_COMPARE_FORMAT: + case RESOLUTION_4B_COMPARE_FORMAT: + case RESOLUTION_5B_COMPARE_FORMAT: + case RESOLUTION_6B_COMPARE_FORMAT: + case RESOLUTION_7B_COMPARE_FORMAT: case RESOLUTION_8B_COMPARE_FORMAT: - CCR_RegisterValue = ((__HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)) + 1) * compare) / 255 ; - break; + case RESOLUTION_9B_COMPARE_FORMAT: + case RESOLUTION_10B_COMPARE_FORMAT: + case RESOLUTION_11B_COMPARE_FORMAT: case RESOLUTION_12B_COMPARE_FORMAT: - CCR_RegisterValue = ((__HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)) + 1) * compare) / 4095 ; + case RESOLUTION_13B_COMPARE_FORMAT: + case RESOLUTION_14B_COMPARE_FORMAT: + case RESOLUTION_15B_COMPARE_FORMAT: + case RESOLUTION_16B_COMPARE_FORMAT: + CCR_RegisterValue = ((__HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)) + 1) * compare) / ((1 << format) - 1) ; break; case TICK_COMPARE_FORMAT: default : @@ -584,11 +596,23 @@ uint32_t HardwareTimer::getCaptureCompare(uint32_t channel, TimerCompareFormat_ case PERCENT_COMPARE_FORMAT: return_value = (CCR_RegisterValue * 100) / __HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)); break; + case RESOLUTION_1B_COMPARE_FORMAT: + case RESOLUTION_2B_COMPARE_FORMAT: + case RESOLUTION_3B_COMPARE_FORMAT: + case RESOLUTION_4B_COMPARE_FORMAT: + case RESOLUTION_5B_COMPARE_FORMAT: + case RESOLUTION_6B_COMPARE_FORMAT: + case RESOLUTION_7B_COMPARE_FORMAT: case RESOLUTION_8B_COMPARE_FORMAT: - return_value = (CCR_RegisterValue * 255) / __HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)); - break; + case RESOLUTION_9B_COMPARE_FORMAT: + case RESOLUTION_10B_COMPARE_FORMAT: + case RESOLUTION_11B_COMPARE_FORMAT: case RESOLUTION_12B_COMPARE_FORMAT: - return_value = (CCR_RegisterValue * 4095) / __HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)); + case RESOLUTION_13B_COMPARE_FORMAT: + case RESOLUTION_14B_COMPARE_FORMAT: + case RESOLUTION_15B_COMPARE_FORMAT: + case RESOLUTION_16B_COMPARE_FORMAT: + return_value = (CCR_RegisterValue * ((1 << format) - 1)) / __HAL_TIM_GET_AUTORELOAD(&(_timerObj.handle)); break; case TICK_COMPARE_FORMAT: default : diff --git a/cores/arduino/HardwareTimer.h b/cores/arduino/HardwareTimer.h index b67c1253f3..cbf1ecbebc 100644 --- a/cores/arduino/HardwareTimer.h +++ b/cores/arduino/HardwareTimer.h @@ -66,12 +66,27 @@ typedef enum { } TimerFormat_t; typedef enum { - TICK_COMPARE_FORMAT, // default + RESOLUTION_1B_COMPARE_FORMAT = 1, // used for Dutycycle: [0 .. 1] + RESOLUTION_2B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 3] + RESOLUTION_3B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 7] + RESOLUTION_4B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 15] + RESOLUTION_5B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 31] + RESOLUTION_6B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 63] + RESOLUTION_7B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 127] + RESOLUTION_8B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 255] + RESOLUTION_9B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 511] + RESOLUTION_10B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 1023] + RESOLUTION_11B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 2047] + RESOLUTION_12B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 4095] + RESOLUTION_13B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 8191] + RESOLUTION_14B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 16383] + RESOLUTION_15B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 32767] + RESOLUTION_16B_COMPARE_FORMAT, // used for Dutycycle: [0 .. 65535] + + TICK_COMPARE_FORMAT = 0x80, // default MICROSEC_COMPARE_FORMAT, HERTZ_COMPARE_FORMAT, - PERCENT_COMPARE_FORMAT, // used for Dutycycle - RESOLUTION_8B_COMPARE_FORMAT, // used for Dutycycle: [0.. 255] - RESOLUTION_12B_COMPARE_FORMAT // used for Dutycycle: [0.. 4095] + PERCENT_COMPARE_FORMAT, // used for Dutycycle } TimerCompareFormat_t; #ifdef __cplusplus diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h index 17b70996d7..8a289c3c05 100644 --- a/cores/arduino/pins_arduino.h +++ b/cores/arduino/pins_arduino.h @@ -313,7 +313,7 @@ PinName analogInputToPinName(uint32_t pin); #define DACC_RESOLUTION 12 #endif #ifndef PWM_RESOLUTION -#define PWM_RESOLUTION 12 +#define PWM_RESOLUTION 8 #endif #ifndef PWM_FREQUENCY #define PWM_FREQUENCY 1000 diff --git a/cores/arduino/stm32/analog.h b/cores/arduino/stm32/analog.h index 4e1a660501..2fac4ae16d 100644 --- a/cores/arduino/stm32/analog.h +++ b/cores/arduino/stm32/analog.h @@ -42,6 +42,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32_def.h" #include "PeripheralPins.h" +#include "HardwareTimer.h" #ifdef __cplusplus extern "C" { @@ -51,7 +52,7 @@ extern "C" { 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); -void pwm_start(PinName pin, uint32_t clock_freq, uint32_t value); +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 355da374f4..1a5a92875b 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -30,7 +30,7 @@ uint32_t g_anOutputPinConfigured[MAX_NB_PORT] = {0}; #endif static int _readResolution = 10; -static int _writeResolution = 8; +int _writeResolution = PWM_RESOLUTION; static uint32_t _writeFreq = PWM_FREQUENCY; void analogReadResolution(int res) @@ -115,8 +115,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) if (is_pin_configured(p, g_anOutputPinConfigured) == false) { set_pin_configured(p, g_anOutputPinConfigured); } - ulValue = mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); - pwm_start(p, _writeFreq, ulValue); + pwm_start(p, _writeFreq, ulValue, _writeResolution); } else #endif /* HAL_TIM_MODULE_ENABLED && !HAL_TIM_MODULE_ONLY */ { diff --git a/keywords.txt b/keywords.txt index ca313026a2..113230a3a4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -860,8 +860,23 @@ TICK_COMPARE_FORMAT LITERAL1 MICROSEC_COMPARE_FORMAT LITERAL1 HERTZ_COMPARE_FORMAT LITERAL1 PERCENT_COMPARE_FORMAT LITERAL1 +RESOLUTION_1B_COMPARE_FORMAT LITERAL1 +RESOLUTION_2B_COMPARE_FORMAT LITERAL1 +RESOLUTION_3B_COMPARE_FORMAT LITERAL1 +RESOLUTION_4B_COMPARE_FORMAT LITERAL1 +RESOLUTION_5B_COMPARE_FORMAT LITERAL1 +RESOLUTION_6B_COMPARE_FORMAT LITERAL1 +RESOLUTION_7B_COMPARE_FORMAT LITERAL1 RESOLUTION_8B_COMPARE_FORMAT LITERAL1 +RESOLUTION_9B_COMPARE_FORMAT LITERAL1 +RESOLUTION_10B_COMPARE_FORMAT LITERAL1 +RESOLUTION_11B_COMPARE_FORMAT LITERAL1 RESOLUTION_12B_COMPARE_FORMAT LITERAL1 +RESOLUTION_13B_COMPARE_FORMAT LITERAL1 +RESOLUTION_14B_COMPARE_FORMAT LITERAL1 +RESOLUTION_15B_COMPARE_FORMAT LITERAL1 +RESOLUTION_16B_COMPARE_FORMAT LITERAL1 + HardwareTimer KEYWORD1 diff --git a/libraries/SrcWrapper/src/stm32/analog.cpp b/libraries/SrcWrapper/src/stm32/analog.cpp index 62f81723f6..f0cbd3a962 100644 --- a/libraries/SrcWrapper/src/stm32/analog.cpp +++ b/libraries/SrcWrapper/src/stm32/analog.cpp @@ -37,7 +37,6 @@ */ #include "stm32_def.h" #include "analog.h" -#include "HardwareTimer.h" #include "PinAF_STM32F1.h" #include "stm32yyxx_ll_adc.h" @@ -995,7 +994,7 @@ uint16_t adc_read_value(PinName pin) * @param value : the value to push on the PWM output * @retval None */ -void pwm_start(PinName pin, uint32_t PWM_freq, uint32_t value) +void pwm_start(PinName pin, uint32_t PWM_freq, uint32_t value, TimerCompareFormat_t resolution) { TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin, PinMap_PWM); HardwareTimer *HT; @@ -1010,7 +1009,7 @@ void pwm_start(PinName pin, uint32_t PWM_freq, uint32_t value) HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin); HT->setOverflow(PWM_freq, HERTZ_FORMAT); - HT->setCaptureCompare(channel, value, RESOLUTION_12B_COMPARE_FORMAT); + HT->setCaptureCompare(channel, value, resolution); HT->resume(); } /** diff --git a/variants/ARMED_V1/variant.h b/variants/ARMED_V1/variant.h index ee44eabfea..b91ffd830d 100644 --- a/variants/ARMED_V1/variant.h +++ b/variants/ARMED_V1/variant.h @@ -115,7 +115,6 @@ extern "C" { #define NUM_ANALOG_FIRST 32 // PWM resolution -#define PWM_RESOLUTION 8 #define PWM_FREQUENCY 20000 // >= 20 Khz => inaudible noise for fans #define PWM_MAX_DUTY_CYCLE 255 diff --git a/variants/REMRAM_V1/variant.h b/variants/REMRAM_V1/variant.h index fde8e3208c..f25a023383 100644 --- a/variants/REMRAM_V1/variant.h +++ b/variants/REMRAM_V1/variant.h @@ -146,7 +146,6 @@ extern "C" #define NUM_ANALOG_FIRST 64 // PWM resolution -#define PWM_RESOLUTION 8 #define PWM_FREQUENCY 20000 // >= 20 Khz => inaudible noise for fans #define PWM_MAX_DUTY_CYCLE 255 diff --git a/variants/RUMBA32_F446VE/variant.h b/variants/RUMBA32_F446VE/variant.h index 44f19c5ede..a255cfedc2 100644 --- a/variants/RUMBA32_F446VE/variant.h +++ b/variants/RUMBA32_F446VE/variant.h @@ -115,7 +115,6 @@ extern "C" { #define NUM_ANALOG_FIRST 80 // PWM resolution -#define PWM_RESOLUTION 8 #define PWM_FREQUENCY 20000 // >= 20 Khz => inaudible noise for fans #define PWM_MAX_DUTY_CYCLE 255