From 0d9356c0e7e60bcdef6868c3d6dd9fcf9e890e2a Mon Sep 17 00:00:00 2001 From: victhor Date: Sun, 12 Jul 2026 11:30:44 +0200 Subject: [PATCH 1/8] Try removing a lot of noise --- Inc/HALAL/Models/TimerDomain/TimerDomain.hpp | 6 ++++ .../Services/InputCapture/InputCapture.hpp | 3 +- Src/HALAL/Models/TimerDomain/TimerDomain.cpp | 32 +++++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index 680bf82bf..c5c10ed9c 100644 --- a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -746,6 +746,12 @@ struct TimerDomain { Scheduler_global_timer = cmsis_timers[timer_idxmap[SCHEDULER_TIMER_DOMAIN]]; rcc_enable_timer(Scheduler_global_timer); + for(uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) { + for(uint32_t ch = 0; i < TimerDomain::input_capture_channels; ch++) { + input_capture_info[inst][ch] = &input_capture_info_dummy; + } + } + TimerDomain::callbacks[0] = TIM_Default_Callback; TimerDomain::callbacks[1] = TIM_Default_Callback; TimerDomain::callbacks[2] = TIM_Default_Callback; diff --git a/Inc/HALAL/Services/InputCapture/InputCapture.hpp b/Inc/HALAL/Services/InputCapture/InputCapture.hpp index b843bfdb6..562906392 100644 --- a/Inc/HALAL/Services/InputCapture/InputCapture.hpp +++ b/Inc/HALAL/Services/InputCapture/InputCapture.hpp @@ -59,7 +59,8 @@ class InputCapture { .ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING, .ICSelection = TIM_ICSELECTION_DIRECTTI, .ICPrescaler = TIM_ICPSC_DIV1, - .ICFilter = 0, + /* filter out with hardware some noise */ + .ICFilter = 0x03, }; timer->template config_input_compare_channel(&sConfigIC); diff --git a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp index 370135ded..4f7167f11 100644 --- a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp +++ b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp @@ -27,12 +27,17 @@ void* TimerDomain::callback_data[TimerDomain::max_instances] = {nullptr}; TimerDomain::InputCaptureInfo input_capture_info_dummy = { .channel_rising = 0xFF, // any value that isn't possible here .channel_falling = 0xFF, // any value that isn't possible here + + .value_rising = 0, + .value_falling = 0, + .period = 0, + + .duty_cycle = 0, + .frequency = 0, }; TimerDomain::InputCaptureInfo* TimerDomain::input_capture_info[max_instances] - [input_capture_channels] = { - {&input_capture_info_dummy} -}; + [input_capture_channels]; TimerDomain::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances] [input_capture_channels]; @@ -40,11 +45,18 @@ static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) { TIM_HandleTypeDef* htim = TimerDomain::hal_handles[timer_idx]; TimerDomain::InputCaptureInfo* info = TimerDomain::input_capture_info[timer_idx][channel]; + uint32_t current = (*(((volatile uint32_t*)&htim->Instance->CCR1) + channel)); if (info->channel_rising == channel) { // NOTE: CCR1 - CCR4 are contiguous // NOTE: CCxIF flag is cleared by software by reading the captured data in CCRx - uint32_t current = (*(((volatile uint32_t*)&htim->Instance->CCR1) + channel)); - uint32_t period = current - info->value_rising; + uint32_t period; + if (current >= info->value_rising) { + period = current - info->value_rising; + } else { + // counter wrap around + uint32_t max_count = htim->Instance->ARR - 1; + period = (current + max_count) - info->value_rising; + } if ((period != 0) && (info->value_falling < period)) { uint32_t ref_clock = @@ -55,8 +67,14 @@ static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) { } info->value_rising = current; } else if (info->channel_falling == channel) { - uint32_t falling_value = - *(((volatile uint32_t*)&htim->Instance->CCR1) + channel) - info->value_rising; + uint32_t falling_value; + if (current >= info->value_rising) { + falling_value = current - info->value_rising; + } else { + uint32_t max_count = htim->Instance->ARR - 1; + falling_value = (current + max_count) - info->value_rising; + } + if (falling_value < info->period) info->value_falling = falling_value; } else [[unlikely]] { From cd0b27da9e7b38be2aa3c8ef2faa588e5257e48d Mon Sep 17 00:00:00 2001 From: victhor Date: Sun, 12 Jul 2026 11:34:11 +0200 Subject: [PATCH 2/8] try to fix compile errors --- Inc/HALAL/Models/TimerDomain/TimerDomain.hpp | 27 +++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index c5c10ed9c..8d8048b0d 100644 --- a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -218,6 +218,20 @@ enum class PWM_Frequency_Mode { SPEED, }; +struct InputCaptureInfo { + uint8_t channel_rising; + uint8_t channel_falling; + + uint32_t value_rising; + uint32_t value_falling; + uint32_t period; + + float duty_cycle; + uint32_t frequency; +}; + +extern ST_LIB::InputCaptureInfo input_capture_info_dummy; + constexpr std::array create_timer_idxmap() { std::array result{}; @@ -267,17 +281,6 @@ struct TimerDomain { static constexpr std::size_t max_instances = 16; static constexpr std::size_t input_capture_channels = 4; - struct InputCaptureInfo { - uint8_t channel_rising; - uint8_t channel_falling; - - uint32_t value_rising; - uint32_t value_falling; - uint32_t period; - - float duty_cycle; - uint32_t frequency; - }; /* 2x as big as necessary but this makes indexing easier & faster */ static InputCaptureInfo* input_capture_info[max_instances][input_capture_channels]; static InputCaptureInfo input_capture_info_backing[max_instances][input_capture_channels]; @@ -747,7 +750,7 @@ struct TimerDomain { rcc_enable_timer(Scheduler_global_timer); for(uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) { - for(uint32_t ch = 0; i < TimerDomain::input_capture_channels; ch++) { + for(uint32_t ch = 0; ch < TimerDomain::input_capture_channels; ch++) { input_capture_info[inst][ch] = &input_capture_info_dummy; } } From 4e675e6f8ea3d392202aca23feb2398953def37b Mon Sep 17 00:00:00 2001 From: victhor Date: Sun, 12 Jul 2026 11:34:35 +0200 Subject: [PATCH 3/8] try to fix compile errors part 2 --- Src/HALAL/Models/TimerDomain/TimerDomain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp index 4f7167f11..d213dbd63 100644 --- a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp +++ b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp @@ -24,7 +24,7 @@ TIM_HandleTypeDef htim24; void (*TimerDomain::callbacks[TimerDomain::max_instances])(void*) = {nullptr}; void* TimerDomain::callback_data[TimerDomain::max_instances] = {nullptr}; -TimerDomain::InputCaptureInfo input_capture_info_dummy = { +ST_LIB::InputCaptureInfo input_capture_info_dummy = { .channel_rising = 0xFF, // any value that isn't possible here .channel_falling = 0xFF, // any value that isn't possible here @@ -36,15 +36,15 @@ TimerDomain::InputCaptureInfo input_capture_info_dummy = { .frequency = 0, }; -TimerDomain::InputCaptureInfo* TimerDomain::input_capture_info[max_instances] +ST_LIB::InputCaptureInfo* TimerDomain::input_capture_info[max_instances] [input_capture_channels]; -TimerDomain::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances] +ST_LIB::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances] [input_capture_channels]; static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) { TIM_HandleTypeDef* htim = TimerDomain::hal_handles[timer_idx]; - TimerDomain::InputCaptureInfo* info = TimerDomain::input_capture_info[timer_idx][channel]; + ST_LIB::InputCaptureInfo* info = TimerDomain::input_capture_info[timer_idx][channel]; uint32_t current = (*(((volatile uint32_t*)&htim->Instance->CCR1) + channel)); if (info->channel_rising == channel) { // NOTE: CCR1 - CCR4 are contiguous From 6f9dca1ae48db57ed1a744bd94b50ee2f8ccb105 Mon Sep 17 00:00:00 2001 From: victhor Date: Sun, 12 Jul 2026 11:35:58 +0200 Subject: [PATCH 4/8] compile errors... --- Inc/HALAL/Services/InputCapture/InputCapture.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Inc/HALAL/Services/InputCapture/InputCapture.hpp b/Inc/HALAL/Services/InputCapture/InputCapture.hpp index 562906392..15d8e9f61 100644 --- a/Inc/HALAL/Services/InputCapture/InputCapture.hpp +++ b/Inc/HALAL/Services/InputCapture/InputCapture.hpp @@ -26,7 +26,7 @@ class InputCapture { friend struct TimerWrapper; TimerWrapper* timer = nullptr; - TimerDomain::InputCaptureInfo* info = nullptr; + ST_LIB::InputCaptureInfo* info = nullptr; bool is_on = false; bool is_initialized = false; InputCapture(TimerWrapper* tim) : timer(tim) {} From aa48117428f6ad4db5e1dd038992dec59eab46d7 Mon Sep 17 00:00:00 2001 From: Jorge Date: Sun, 12 Jul 2026 11:44:23 +0200 Subject: [PATCH 5/8] fix compile errors --- Inc/HALAL/Models/TimerDomain/TimerDomain.hpp | 14 +++++++++++++- Src/HALAL/Models/TimerDomain/TimerDomain.cpp | 12 ------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index 8d8048b0d..94bed8cac 100644 --- a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -230,7 +230,7 @@ struct InputCaptureInfo { uint32_t frequency; }; -extern ST_LIB::InputCaptureInfo input_capture_info_dummy; +static ST_LIB::InputCaptureInfo input_capture_info_dummy; constexpr std::array create_timer_idxmap() { std::array result{}; @@ -749,6 +749,18 @@ struct TimerDomain { Scheduler_global_timer = cmsis_timers[timer_idxmap[SCHEDULER_TIMER_DOMAIN]]; rcc_enable_timer(Scheduler_global_timer); + input_capture_info_dummy = ST_LIB::InputCaptureInfo{ + .channel_rising = 0xFF, // any value that isn't possible here + .channel_falling = 0xFF, // any value that isn't possible here + + .value_rising = 0, + .value_falling = 0, + .period = 0, + + .duty_cycle = 0, + .frequency = 0, + }; + for(uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) { for(uint32_t ch = 0; ch < TimerDomain::input_capture_channels; ch++) { input_capture_info[inst][ch] = &input_capture_info_dummy; diff --git a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp index d213dbd63..053f0dfb6 100644 --- a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp +++ b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp @@ -24,18 +24,6 @@ TIM_HandleTypeDef htim24; void (*TimerDomain::callbacks[TimerDomain::max_instances])(void*) = {nullptr}; void* TimerDomain::callback_data[TimerDomain::max_instances] = {nullptr}; -ST_LIB::InputCaptureInfo input_capture_info_dummy = { - .channel_rising = 0xFF, // any value that isn't possible here - .channel_falling = 0xFF, // any value that isn't possible here - - .value_rising = 0, - .value_falling = 0, - .period = 0, - - .duty_cycle = 0, - .frequency = 0, -}; - ST_LIB::InputCaptureInfo* TimerDomain::input_capture_info[max_instances] [input_capture_channels]; ST_LIB::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances] From 23ef7cedc9af5f58252d4b9a7afd2e98a18c472c Mon Sep 17 00:00:00 2001 From: Jorge Date: Sun, 12 Jul 2026 11:53:29 +0200 Subject: [PATCH 6/8] remove extra return statement --- Inc/HALAL/Services/InputCapture/InputCapture.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Inc/HALAL/Services/InputCapture/InputCapture.hpp b/Inc/HALAL/Services/InputCapture/InputCapture.hpp index 15d8e9f61..454df03f2 100644 --- a/Inc/HALAL/Services/InputCapture/InputCapture.hpp +++ b/Inc/HALAL/Services/InputCapture/InputCapture.hpp @@ -74,7 +74,6 @@ class InputCapture { void turn_on(void) { if (is_initialized == false) { init(); - return; } if (is_on) return; From 36b51185ee3541173062dc5ae05b9756f63d4c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Mon, 13 Jul 2026 11:56:03 +0200 Subject: [PATCH 7/8] applied formatter --- Inc/HALAL/Models/TimerDomain/TimerDomain.hpp | 8 ++++---- Src/HALAL/Models/TimerDomain/TimerDomain.cpp | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index 94bed8cac..17b71ff06 100644 --- a/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ b/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -750,8 +750,8 @@ struct TimerDomain { rcc_enable_timer(Scheduler_global_timer); input_capture_info_dummy = ST_LIB::InputCaptureInfo{ - .channel_rising = 0xFF, // any value that isn't possible here - .channel_falling = 0xFF, // any value that isn't possible here + .channel_rising = 0xFF, // any value that isn't possible here + .channel_falling = 0xFF, // any value that isn't possible here .value_rising = 0, .value_falling = 0, @@ -761,8 +761,8 @@ struct TimerDomain { .frequency = 0, }; - for(uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) { - for(uint32_t ch = 0; ch < TimerDomain::input_capture_channels; ch++) { + for (uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) { + for (uint32_t ch = 0; ch < TimerDomain::input_capture_channels; ch++) { input_capture_info[inst][ch] = &input_capture_info_dummy; } } diff --git a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp index 053f0dfb6..9a6a6d0c3 100644 --- a/Src/HALAL/Models/TimerDomain/TimerDomain.cpp +++ b/Src/HALAL/Models/TimerDomain/TimerDomain.cpp @@ -24,10 +24,9 @@ TIM_HandleTypeDef htim24; void (*TimerDomain::callbacks[TimerDomain::max_instances])(void*) = {nullptr}; void* TimerDomain::callback_data[TimerDomain::max_instances] = {nullptr}; -ST_LIB::InputCaptureInfo* TimerDomain::input_capture_info[max_instances] - [input_capture_channels]; +ST_LIB::InputCaptureInfo* TimerDomain::input_capture_info[max_instances][input_capture_channels]; ST_LIB::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances] - [input_capture_channels]; + [input_capture_channels]; static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) { TIM_HandleTypeDef* htim = TimerDomain::hal_handles[timer_idx]; @@ -39,7 +38,7 @@ static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) { // NOTE: CCxIF flag is cleared by software by reading the captured data in CCRx uint32_t period; if (current >= info->value_rising) { - period = current - info->value_rising; + period = current - info->value_rising; } else { // counter wrap around uint32_t max_count = htim->Instance->ARR - 1; From 13f9a0e12f9f081e7c22c7ac4fdb6fc2d469b401 Mon Sep 17 00:00:00 2001 From: victhor Date: Mon, 13 Jul 2026 12:06:48 +0200 Subject: [PATCH 8/8] add changeset --- .changesets/fix-ic-noise.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changesets/fix-ic-noise.md diff --git a/.changesets/fix-ic-noise.md b/.changesets/fix-ic-noise.md new file mode 100644 index 000000000..96c257f06 --- /dev/null +++ b/.changesets/fix-ic-noise.md @@ -0,0 +1,2 @@ +release: patch +summary: try to fix input capture by reducing noise in interrupt callback and add hardware filtering when configuring the input capture