|
25 | 25 | #ifdef HAL_STM32
|
26 | 26 |
|
27 | 27 | #include "../../inc/MarlinConfig.h"
|
28 |
| - |
29 |
| -// Array to support sticky frequency sets per timer |
30 |
| -static uint16_t timer_freq[TIMER_NUM]; |
| 28 | +#include "timers.h" |
31 | 29 |
|
32 | 30 | void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
33 |
| - if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer |
34 |
| - const PinName pin_name = digitalPinToPinName(pin); |
35 |
| - TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); |
| 31 | + if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer |
| 32 | + |
| 33 | + PinName pin_name = digitalPinToPinName(pin); |
| 34 | + TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); |
| 35 | + |
| 36 | + uint16_t adj_val = Instance->ARR * v / v_size; |
| 37 | + if (invert) adj_val = Instance->ARR - adj_val; |
| 38 | + switch (get_pwm_channel(pin_name)) { |
| 39 | + case TIM_CHANNEL_1: LL_TIM_OC_SetCompareCH1(Instance, adj_val); break; |
| 40 | + case TIM_CHANNEL_2: LL_TIM_OC_SetCompareCH2(Instance, adj_val); break; |
| 41 | + case TIM_CHANNEL_3: LL_TIM_OC_SetCompareCH3(Instance, adj_val); break; |
| 42 | + case TIM_CHANNEL_4: LL_TIM_OC_SetCompareCH4(Instance, adj_val); break; |
| 43 | + } |
| 44 | +} |
36 | 45 |
|
37 |
| - const timer_index_t index = get_timer_index(Instance); |
38 |
| - const bool needs_freq = (HardwareTimer_Handle[index] == nullptr); |
39 |
| - if (needs_freq) // A new instance must be set to the default frequency of PWM_FREQUENCY |
40 |
| - HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM)); |
| 46 | +#if NEEDS_HARDWARE_PWM |
41 | 47 |
|
42 |
| - HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this); |
43 |
| - const uint32_t channel = STM_PIN_CHANNEL(pinmap_function(pin_name, PinMap_PWM)); |
44 |
| - const TimerModes_t previousMode = HT->getMode(channel); |
45 |
| - if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) |
46 |
| - HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin); |
| 48 | + void set_pwm_frequency(const pin_t pin, int f_desired) { |
| 49 | + if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer |
47 | 50 |
|
48 |
| - if (needs_freq && timer_freq[index] == 0) // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY |
49 |
| - set_pwm_frequency(pin_name, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. |
| 51 | + PinName pin_name = digitalPinToPinName(pin); |
| 52 | + TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance |
50 | 53 |
|
51 |
| - // Note the resolution is sticky here, the input can be upto 16 bits and that would require RESOLUTION_16B_COMPARE_FORMAT (16) |
52 |
| - // If such a need were to manifest then we would need to calc the resolution based on the v_size parameter and add code for it. |
53 |
| - const uint16_t value = invert ? v_size - v : v; |
54 |
| - HT->setCaptureCompare(channel, value, RESOLUTION_8B_COMPARE_FORMAT); // Sets the duty, the calc is done in the library :) |
55 |
| - pinmap_pinout(pin_name, PinMap_PWM); // Make sure the pin output state is set. |
56 |
| - if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) HT->resume(); |
57 |
| -} |
| 54 | + LOOP_S_L_N(i, 0, NUM_HARDWARE_TIMERS) // Protect used timers |
| 55 | + if (timer_instance[i] && timer_instance[i]->getHandle()->Instance == Instance) |
| 56 | + return; |
58 | 57 |
|
59 |
| -void set_pwm_frequency(const pin_t pin, int f_desired) { |
60 |
| - if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer |
61 |
| - const PinName pin_name = digitalPinToPinName(pin); |
62 |
| - TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance |
63 |
| - const timer_index_t index = get_timer_index(Instance); |
| 58 | + pwm_start(pin_name, f_desired, 0, RESOLUTION_8B_COMPARE_FORMAT); |
| 59 | + } |
64 | 60 |
|
65 |
| - // Protect used timers. |
66 |
| - #ifdef STEP_TIMER |
67 |
| - if (index == TIMER_INDEX(STEP_TIMER)) return; |
68 |
| - #endif |
69 |
| - #ifdef TEMP_TIMER |
70 |
| - if (index == TIMER_INDEX(TEMP_TIMER)) return; |
71 |
| - #endif |
72 |
| - #if defined(PULSE_TIMER) && MF_TIMER_PULSE != MF_TIMER_STEP |
73 |
| - if (index == TIMER_INDEX(PULSE_TIMER)) return; |
74 |
| - #endif |
75 |
| - |
76 |
| - if (HardwareTimer_Handle[index] == nullptr) // If frequency is set before duty we need to create a handle here. |
77 |
| - HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM)); |
78 |
| - HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this); |
79 |
| - HT->setOverflow(f_desired, HERTZ_FORMAT); |
80 |
| - timer_freq[index] = f_desired; // Save the last frequency so duty will not set the default for this timer number. |
81 |
| -} |
| 61 | +#endif |
82 | 62 |
|
83 | 63 | #endif // HAL_STM32
|
0 commit comments