Skip to content

Commit eb2060c

Browse files
victor-Lopez25jorgecanutjorgesg82
authored
Try removing a lot of noise to fix input capture readings (#675)
* Try removing a lot of noise * try to fix compile errors * try to fix compile errors part 2 * compile errors... * fix compile errors * remove extra return statement * applied formatter * add changeset --------- Co-authored-by: Jorge <jorgecaru3@gmail.com> Co-authored-by: Jorge Sáez <jorgeesg82@gmail.com>
1 parent 78afba3 commit eb2060c

4 files changed

Lines changed: 58 additions & 30 deletions

File tree

.changesets/fix-ic-noise.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
release: patch
2+
summary: try to fix input capture by reducing noise in interrupt callback and add hardware filtering when configuring the input capture

Inc/HALAL/Models/TimerDomain/TimerDomain.hpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,20 @@ enum class PWM_Frequency_Mode {
218218
SPEED,
219219
};
220220

221+
struct InputCaptureInfo {
222+
uint8_t channel_rising;
223+
uint8_t channel_falling;
224+
225+
uint32_t value_rising;
226+
uint32_t value_falling;
227+
uint32_t period;
228+
229+
float duty_cycle;
230+
uint32_t frequency;
231+
};
232+
233+
static ST_LIB::InputCaptureInfo input_capture_info_dummy;
234+
221235
constexpr std::array<uint8_t, 25> create_timer_idxmap() {
222236
std::array<uint8_t, 25> result{};
223237

@@ -267,17 +281,6 @@ struct TimerDomain {
267281
static constexpr std::size_t max_instances = 16;
268282
static constexpr std::size_t input_capture_channels = 4;
269283

270-
struct InputCaptureInfo {
271-
uint8_t channel_rising;
272-
uint8_t channel_falling;
273-
274-
uint32_t value_rising;
275-
uint32_t value_falling;
276-
uint32_t period;
277-
278-
float duty_cycle;
279-
uint32_t frequency;
280-
};
281284
/* 2x as big as necessary but this makes indexing easier & faster */
282285
static InputCaptureInfo* input_capture_info[max_instances][input_capture_channels];
283286
static InputCaptureInfo input_capture_info_backing[max_instances][input_capture_channels];
@@ -746,6 +749,24 @@ struct TimerDomain {
746749
Scheduler_global_timer = cmsis_timers[timer_idxmap[SCHEDULER_TIMER_DOMAIN]];
747750
rcc_enable_timer(Scheduler_global_timer);
748751

752+
input_capture_info_dummy = ST_LIB::InputCaptureInfo{
753+
.channel_rising = 0xFF, // any value that isn't possible here
754+
.channel_falling = 0xFF, // any value that isn't possible here
755+
756+
.value_rising = 0,
757+
.value_falling = 0,
758+
.period = 0,
759+
760+
.duty_cycle = 0,
761+
.frequency = 0,
762+
};
763+
764+
for (uint32_t inst = 0; inst < TimerDomain::max_instances; inst++) {
765+
for (uint32_t ch = 0; ch < TimerDomain::input_capture_channels; ch++) {
766+
input_capture_info[inst][ch] = &input_capture_info_dummy;
767+
}
768+
}
769+
749770
TimerDomain::callbacks[0] = TIM_Default_Callback;
750771
TimerDomain::callbacks[1] = TIM_Default_Callback;
751772
TimerDomain::callbacks[2] = TIM_Default_Callback;

Inc/HALAL/Services/InputCapture/InputCapture.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class InputCapture {
2626
friend struct TimerWrapper<dev>;
2727

2828
TimerWrapper<dev>* timer = nullptr;
29-
TimerDomain::InputCaptureInfo* info = nullptr;
29+
ST_LIB::InputCaptureInfo* info = nullptr;
3030
bool is_on = false;
3131
bool is_initialized = false;
3232
InputCapture(TimerWrapper<dev>* tim) : timer(tim) {}
@@ -59,7 +59,8 @@ class InputCapture {
5959
.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING,
6060
.ICSelection = TIM_ICSELECTION_DIRECTTI,
6161
.ICPrescaler = TIM_ICPSC_DIV1,
62-
.ICFilter = 0,
62+
/* filter out with hardware some noise */
63+
.ICFilter = 0x03,
6364
};
6465
timer->template config_input_compare_channel<pin_rising.channel>(&sConfigIC);
6566

@@ -73,7 +74,6 @@ class InputCapture {
7374
void turn_on(void) {
7475
if (is_initialized == false) {
7576
init();
76-
return;
7777
}
7878
if (is_on)
7979
return;

Src/HALAL/Models/TimerDomain/TimerDomain.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,26 @@ TIM_HandleTypeDef htim24;
2424
void (*TimerDomain::callbacks[TimerDomain::max_instances])(void*) = {nullptr};
2525
void* TimerDomain::callback_data[TimerDomain::max_instances] = {nullptr};
2626

27-
TimerDomain::InputCaptureInfo input_capture_info_dummy = {
28-
.channel_rising = 0xFF, // any value that isn't possible here
29-
.channel_falling = 0xFF, // any value that isn't possible here
30-
};
31-
32-
TimerDomain::InputCaptureInfo* TimerDomain::input_capture_info[max_instances]
33-
[input_capture_channels] = {
34-
{&input_capture_info_dummy}
35-
};
36-
TimerDomain::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances]
37-
[input_capture_channels];
27+
ST_LIB::InputCaptureInfo* TimerDomain::input_capture_info[max_instances][input_capture_channels];
28+
ST_LIB::InputCaptureInfo TimerDomain::input_capture_info_backing[max_instances]
29+
[input_capture_channels];
3830

3931
static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) {
4032
TIM_HandleTypeDef* htim = TimerDomain::hal_handles[timer_idx];
4133

42-
TimerDomain::InputCaptureInfo* info = TimerDomain::input_capture_info[timer_idx][channel];
34+
ST_LIB::InputCaptureInfo* info = TimerDomain::input_capture_info[timer_idx][channel];
35+
uint32_t current = (*(((volatile uint32_t*)&htim->Instance->CCR1) + channel));
4336
if (info->channel_rising == channel) {
4437
// NOTE: CCR1 - CCR4 are contiguous
4538
// NOTE: CCxIF flag is cleared by software by reading the captured data in CCRx
46-
uint32_t current = (*(((volatile uint32_t*)&htim->Instance->CCR1) + channel));
47-
uint32_t period = current - info->value_rising;
39+
uint32_t period;
40+
if (current >= info->value_rising) {
41+
period = current - info->value_rising;
42+
} else {
43+
// counter wrap around
44+
uint32_t max_count = htim->Instance->ARR - 1;
45+
period = (current + max_count) - info->value_rising;
46+
}
4847

4948
if ((period != 0) && (info->value_falling < period)) {
5049
uint32_t ref_clock =
@@ -55,8 +54,14 @@ static void TIM_IC_CaptureCallback(const uint32_t timer_idx, uint32_t channel) {
5554
}
5655
info->value_rising = current;
5756
} else if (info->channel_falling == channel) {
58-
uint32_t falling_value =
59-
*(((volatile uint32_t*)&htim->Instance->CCR1) + channel) - info->value_rising;
57+
uint32_t falling_value;
58+
if (current >= info->value_rising) {
59+
falling_value = current - info->value_rising;
60+
} else {
61+
uint32_t max_count = htim->Instance->ARR - 1;
62+
falling_value = (current + max_count) - info->value_rising;
63+
}
64+
6065
if (falling_value < info->period)
6166
info->value_falling = falling_value;
6267
} else [[unlikely]] {

0 commit comments

Comments
 (0)