From 4e706ab449c11ffc894d4117c787a3185a9c1f30 Mon Sep 17 00:00:00 2001 From: paradajz <2544094+paradajz@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:12:00 +0000 Subject: [PATCH] buttons: rewrite the button debouncer The previous implementation actually did nothing. --- src/firmware/application/io/buttons/Filter.h | 36 ++++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/firmware/application/io/buttons/Filter.h b/src/firmware/application/io/buttons/Filter.h index 39234b06b..b72807a14 100644 --- a/src/firmware/application/io/buttons/Filter.h +++ b/src/firmware/application/io/buttons/Filter.h @@ -31,12 +31,15 @@ namespace io bool isFiltered(size_t index, uint8_t& numberOfReadings, uint16_t& states) override { - // this is a board-optimized debouncer - // by the time processing of buttons takes place, more than 5ms has already passed - // 5ms is release debounce time - // take into account only two latest readings - // if any of those is 1 (pressed), consider the button pressed - // otherwise, button is considered released + /* + This filter makes use of the fact that the difference between digital readings is 1ms. + If the _debounceState is 0xFF or 0x00, the button is considered debounced. Since all bits + are used in a byte variable, and each reading takes 1ms, the debounce time is 8ms. + + Technically, two readings are possible since maximum number of board readings is 16, and + full debounce cycle takes 8 readings. Assume the boards aren't that slow that the difference + between two calls of this function for the same button index is more than 8ms. + */ numberOfReadings = 1; @@ -47,23 +50,28 @@ namespace io return true; } - states &= 0x03; + _debounceState[index] <<= numberOfReadings; + _debounceState[index] |= static_cast(states); - if (numberOfReadings >= 2) + if (_debounceState[index] == 0xFF) + { + states = 1; + } + else if (_debounceState[index] == 0) { - if (states) - { - // button is pressed - states = 0x01; - } + states = 0; } else { - states &= 0x01; + // not debounced yet + return false; } return true; } + + private: + uint8_t _debounceState[io::Buttons::Collection::SIZE(io::Buttons::GROUP_DIGITAL_INPUTS)] = {}; }; } // namespace io