diff --git a/.changesets/init_timer.md b/.changesets/init_timer.md new file mode 100644 index 000000000..860ffdde4 --- /dev/null +++ b/.changesets/init_timer.md @@ -0,0 +1,2 @@ +release: minor +summary: move initialization outside constructor in PWM, DualPWM, Encoder and InputCapture diff --git a/Inc/HALAL/Services/Encoder/Encoder.hpp b/Inc/HALAL/Services/Encoder/Encoder.hpp index 8e1ddd1b9..0202df3a7 100644 --- a/Inc/HALAL/Services/Encoder/Encoder.hpp +++ b/Inc/HALAL/Services/Encoder/Encoder.hpp @@ -27,15 +27,15 @@ template class Encoder { inline static TimerWrapper* timer; inline static bool is_on = false; + inline static bool is_initialized = false; - Encoder(TimerWrapper* tim) { - if (timer == nullptr) { - init(tim); - } - } + Encoder(TimerWrapper* tim) { timer = tim; } public: static void init(TimerWrapper* tim) { + if (tim == nullptr || tim->instance == nullptr) { + ErrorHandler("Timer instance is not set for encoder"); + } TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; @@ -70,11 +70,13 @@ template class Encoder { } timer = tim; } - static void turn_on() { + if (!is_initialized) { + init(timer); + is_initialized = true; + } if (is_on) return; - if (HAL_TIM_Encoder_GetState(timer->instance->hal_tim) == HAL_TIM_STATE_RESET) { ErrorHandler("Unable to get state from encoder"); return; diff --git a/Inc/HALAL/Services/InputCapture/InputCapture.hpp b/Inc/HALAL/Services/InputCapture/InputCapture.hpp index d031c9c87..7a5f6af61 100644 --- a/Inc/HALAL/Services/InputCapture/InputCapture.hpp +++ b/Inc/HALAL/Services/InputCapture/InputCapture.hpp @@ -28,16 +28,21 @@ class InputCapture { TimerWrapper* timer = nullptr; TimerDomain::InputCaptureInfo* info = nullptr; bool is_on = false; - - InputCapture(TimerWrapper* tim) { - timer = tim; - + bool is_initialized = false; + InputCapture(TimerWrapper* tim) : timer(tim) {} + void init() { + if (is_initialized) + return; + if (timer == nullptr || timer->instance == nullptr || timer->instance->hal_tim == nullptr) { + ErrorHandler("Timer instance is not set for input capture"); + return; + } // Setup TimerDomain uint8_t ch_rising = static_cast(pin_rising.channel) - 1; uint8_t ch_falling = static_cast(channel_falling) - 1; - info = &TimerDomain::input_capture_info_backing[tim->instance->timer_idx][ch_rising]; - TimerDomain::input_capture_info[tim->instance->timer_idx][ch_rising] = info; - TimerDomain::input_capture_info[tim->instance->timer_idx][ch_falling] = info; + info = &TimerDomain::input_capture_info_backing[timer->instance->timer_idx][ch_rising]; + TimerDomain::input_capture_info[timer->instance->timer_idx][ch_rising] = info; + TimerDomain::input_capture_info[timer->instance->timer_idx][ch_falling] = info; info->channel_rising = ch_rising; info->channel_falling = ch_falling; @@ -61,10 +66,15 @@ class InputCapture { sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; timer->template config_input_compare_channel(&sConfigIC); + is_initialized = true; } public: void turn_on(void) { + if (is_initialized == false) { + init(); + return; + } if (is_on) return; diff --git a/Inc/HALAL/Services/PWM/DualPWM.hpp b/Inc/HALAL/Services/PWM/DualPWM.hpp index b0121ec3c..e04e2c21d 100644 --- a/Inc/HALAL/Services/PWM/DualPWM.hpp +++ b/Inc/HALAL/Services/PWM/DualPWM.hpp @@ -22,10 +22,13 @@ class DualPWM { friend TimerWrapper; TimerWrapper* timer; - uint32_t* frequency; float* duty_cycle = nullptr; + uint32_t* frequency; + uint32_t polarity; + uint32_t negated_polarity; bool is_on_positive = false; bool is_on_negative = false; + bool is_initialized = false; /* This constructor is private for a reason. Use TimerWrapper::get_dual_pwm */ DualPWM( @@ -35,10 +38,16 @@ class DualPWM { float* duty_ptr, uint32_t* frequency_ptr ) - : timer(tim) { - duty_cycle = duty_ptr; - frequency = frequency_ptr; + : timer(tim), duty_cycle(duty_ptr), frequency(frequency_ptr), polarity(polarity), + negated_polarity(negated_polarity) {} + + inline void initialize() { + if (is_initialized) + return; + if (timer == nullptr || timer->instance == nullptr || timer->instance->hal_tim == nullptr) { + ErrorHandler("Timer instance is not set for DualPWM"); + } TIM_OC_InitTypeDef sConfigOC = { .OCMode = TIM_OCMODE_PWM1, .Pulse = 0, @@ -53,10 +62,12 @@ class DualPWM { timer->template config_output_compare_channel(&sConfigOC); timer->template set_output_compare_preload_enable(); + is_initialized = true; } public: inline void turn_on() { + initialize(); turn_on_positive(); turn_on_negative(); } @@ -65,7 +76,6 @@ class DualPWM { turn_off_positive(); turn_off_negative(); } - void turn_on_positive() { if (this->is_on_positive) return; diff --git a/Inc/HALAL/Services/PWM/PWM.hpp b/Inc/HALAL/Services/PWM/PWM.hpp index 305e4251c..396d25427 100644 --- a/Inc/HALAL/Services/PWM/PWM.hpp +++ b/Inc/HALAL/Services/PWM/PWM.hpp @@ -21,6 +21,9 @@ template class PWM { uint32_t* frequency; float* duty_cycle = nullptr; bool is_on = false; + bool is_initialized = false; + uint32_t polarity; + uint32_t negated_polarity; /* This constructor is private for a reason. Use TimerWrapper::get_pwm */ PWM(TimerWrapper* tim, @@ -28,10 +31,14 @@ template class PWM { uint32_t negated_polarity, float* duty_ptr, uint32_t* frequency_ptr) - : timer(tim) { - duty_cycle = duty_ptr; - frequency = frequency_ptr; - + : timer(tim), polarity(polarity), negated_polarity(negated_polarity), duty_cycle(duty_ptr), + frequency(frequency_ptr) {} + void init() { + if (is_initialized) + return; + if (timer == nullptr || timer->instance == nullptr || timer->instance->hal_tim == nullptr) { + ErrorHandler("Timer instance is not set for PWM"); + } TIM_OC_InitTypeDef sConfigOC = { .OCMode = TIM_OCMODE_PWM1, .Pulse = 0, @@ -45,10 +52,14 @@ template class PWM { }; timer->template config_output_compare_channel(&sConfigOC); timer->template set_output_compare_preload_enable(); + is_initialized = true; } public: void turn_on() { + if (this->is_initialized == false) { + init(); + } if (this->is_on) return;