From 9f74349352e2c55984bf362fb473f2199e35f306 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Tue, 3 Dec 2019 10:37:12 +0100 Subject: [PATCH] Rework PWM_RESOLUTION There is no more distinction between pwm resolution at arduino API level and at HardwareTimer level. PWM_RESOLUTION is default resolution (Arduinio API and HardwareTimer) It is set to 8bit like default arduino pwm resolution. HardwareTimer resolution can now take any value from 1bit to 16bit (like Arduino API). Remove variant PWM_RESOLUTION configuration when it is set to 8, as it is already the default value. Fixes #790 --- cores/arduino/HardwareTimer.cpp | 36 +++++++++++++++++++---- cores/arduino/HardwareTimer.h | 23 ++++++++++++--- cores/arduino/pins_arduino.h | 2 +- cores/arduino/stm32/analog.h | 3 +- cores/arduino/wiring_analog.c | 5 ++-- keywords.txt | 15 ++++++++++ libraries/SrcWrapper/src/stm32/analog.cpp | 5 ++-- variants/ARMED_V1/variant.h | 1 - variants/REMRAM_V1/variant.h | 1 - variants/RUMBA32_F446VE/variant.h | 1 - 10 files changed, 71 insertions(+), 21 deletions(-) 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