Updated debounce_multi_bit tests

This commit is contained in:
John Wellbelove 2026-11-05 23:23:49 +00:00
parent 0a27322a2b
commit bdaa515d4c
2 changed files with 731 additions and 52 deletions

View File

@ -100,7 +100,21 @@ namespace etl
typedef TValue value_type;
typedef TCount count_type;
typedef uint_least8_t state_type;
typedef uint_least8_t state_id_type;
//***************************************************************************
/// State fit in 2 bits, state_lo & state_hi.
//***************************************************************************
struct state_id
{
enum
{
Off = 0, // Debounced state is Off.
On = 1, // Debounced state is On.
Held = 2, // Debounced state is Held. Implies On.
Repeating = 3 // Debounced state is Repeating. Implies Held and On.
};
};
//***************************************************************************
/// Constructor. All bits start in the 'clear' state.
@ -210,10 +224,10 @@ namespace etl
//***************************************************************************
bool is_set(size_t n) const
{
const value_type bit = bit_mask(n);
const state_type state = get_bit_state(bit);
const value_type bit = bit_mask(n);
const state_id_type state = get_bit_state(bit);
return (state == On) || (state == Held) || (state == Repeating);
return (state >= state_id::On);
}
//***************************************************************************
@ -222,10 +236,10 @@ namespace etl
//***************************************************************************
bool is_held(size_t n) const
{
const value_type bit = bit_mask(n);
const state_type state = get_bit_state(bit);
const value_type bit = bit_mask(n);
const state_id_type state = get_bit_state(bit);
return (state == Held) || (state == Repeating);
return (state >= state_id::Held);
}
//***************************************************************************
@ -234,10 +248,10 @@ namespace etl
//***************************************************************************
bool is_repeating(size_t n) const
{
const value_type bit = bit_mask(n);
const state_type state = get_bit_state(bit);
const value_type bit = bit_mask(n);
const state_id_type state = get_bit_state(bit);
return (state == Repeating);
return (state == state_id::Repeating);
}
//***************************************************************************
@ -249,7 +263,7 @@ namespace etl
}
//***************************************************************************
/// Returns the current state.
/// Returns the current state of all bits as a value_type.
//***************************************************************************
value_type get_state() const
{
@ -258,24 +272,24 @@ namespace etl
for (size_t i = 0; i < Width; ++i)
{
result |= (get_bit_state(bit) >= On) ? bit : 0;
result |= (get_bit_state(bit) >= state_id::On) ? bit : 0;
bit <<= 1;
}
return result;
}
private:
//***************************************************************************
/// State fit in 2 bits, state_lo & state_hi.
/// Returns the current state id of a bit.
//***************************************************************************
enum state_id
state_id_type get_state(size_t n) const
{
Off = 0, // Debounced state is Off.
On = 1, // Debounced state is On.
Held = 2, // Debounced state is Held. Implies On.
Repeating = 3 // Debounced state is Repeating. Implies Held and On.
};
value_type bit = bit_mask(n);
return get_bit_state(bit);
}
private:
//***************************************************************************
/// Updates a bit.
@ -292,25 +306,25 @@ namespace etl
switch (get_bit_state(bit))
{
case Off:
case state_id::Off:
{
handle_off(pcount, bit, bit_is_set);
break;
}
case On:
case state_id::On:
{
handle_on(pcount, bit, bit_is_set);
break;
}
case Held:
case state_id::Held:
{
handle_held(pcount, bit, bit_is_set);
break;
}
case Repeating:
case state_id::Repeating:
{
handle_repeating(pcount, bit, bit_is_set);
break;
@ -322,19 +336,19 @@ namespace etl
/// Gets the current debounce state for a specific bit.
///\return The current state of the bit.
//***************************************************************************
state_type get_bit_state(const value_type bit) const
state_id_type get_bit_state(const value_type bit) const
{
const state_type lo = static_cast<state_type>((state_lo & bit) > 0);
const state_type hi = static_cast<state_type>((state_hi & bit) > 0);
const state_id_type lo = static_cast<state_id_type>((state_lo & bit) > 0);
const state_id_type hi = static_cast<state_id_type>((state_hi & bit) > 0);
return static_cast<state_type>(lo | (hi << 1));
return static_cast<state_id_type>(lo | (hi << 1));
}
//***************************************************************************
/// Gets the current debounce state for a specific bit.
///\return The current state of the bit.
//***************************************************************************
void set_bit_state(state_type state, const value_type bit)
void set_bit_state(state_id_type state, const value_type bit)
{
state_lo = state & 1 ? state_lo | bit : state_lo & ~bit;
state_hi = state & 2 ? state_hi | bit : state_hi & ~bit;
@ -344,7 +358,7 @@ namespace etl
/// Increments *pcount; if it reaches 'threshold' the bit moves to
/// 'new_state', the changed flag is set, and the timer is reset.
//***************************************************************************
void try_transition(count_type* pcount, uint32_t threshold, state_type new_state, value_type bit)
void check_for_transition(count_type* pcount, uint32_t threshold, state_id_type new_state, value_type bit)
{
++(*pcount);
@ -363,7 +377,7 @@ namespace etl
{
if (bit_is_set)
{
try_transition(pcount, Valid_Count, On, bit);
check_for_transition(pcount, Valid_Count, state_id::On, bit);
}
}
@ -376,12 +390,12 @@ namespace etl
{
if ETL_IF_CONSTEXPR (Hold_Count > 0)
{
try_transition(pcount, Hold_Count, Held, bit);
check_for_transition(pcount, Hold_Count, state_id::Held, bit);
}
}
else
{
try_transition(pcount, Valid_Count, Off, bit);
check_for_transition(pcount, Valid_Count, state_id::Off, bit);
}
}
@ -394,12 +408,12 @@ namespace etl
{
if ETL_IF_CONSTEXPR (Repeat_Count > 0)
{
try_transition(pcount, Repeat_Count, Repeating, bit);
check_for_transition(pcount, Repeat_Count, state_id::Repeating, bit);
}
}
else
{
try_transition(pcount, Valid_Count, Off, bit);
check_for_transition(pcount, Valid_Count, state_id::Off, bit);
}
}
@ -410,11 +424,11 @@ namespace etl
{
if (bit_is_set)
{
try_transition(pcount, Repeat_Count, Repeating, bit);
check_for_transition(pcount, Repeat_Count, state_id::Repeating, bit);
}
else
{
try_transition(pcount, Valid_Count, Off, bit);
check_for_transition(pcount, Valid_Count, state_id::Off, bit);
}
}
@ -426,7 +440,7 @@ namespace etl
return static_cast<value_type>(value_type(1) << n);
}
value_type sample; // The last known state of the bits.
value_type sample; // The last known value of the bits. Note, this is not the same as the 'state' of the bits.
value_type state_lo; // Low bits of the state.
value_type state_hi; // High bits of the state. Combined with state_lo to form a 2-bit state for each bit in the field.
value_type changed; // Bits that have changed at the last update.

View File

@ -30,6 +30,7 @@ SOFTWARE.
#include "etl/debounce_multi_bit.h"
#include <array>
#include <vector>
namespace
@ -47,14 +48,28 @@ namespace
const value_type Bit1 = 1;
const value_type Bit2 = 2;
using debounce_valid = etl::debounce_multi_bit<value_type, count_type, 1, Valid_Count>;
using debounce_valid_hold = etl::debounce_multi_bit<value_type, count_type, 1, Valid_Count, Hold_Count>;
using debounce_valid_hold_repeat = etl::debounce_multi_bit<value_type, count_type, 1, Valid_Count, Hold_Count, Repeat_Count>;
const size_t NBits = 3;
using debounce_valid = etl::debounce_multi_bit<value_type, count_type, NBits, Valid_Count>;
using debounce_valid_hold = etl::debounce_multi_bit<value_type, count_type, NBits, Valid_Count, Hold_Count>;
using debounce_valid_hold_repeat = etl::debounce_multi_bit<value_type, count_type, NBits, Valid_Count, Hold_Count, Repeat_Count>;
SUITE(test_debounce_multi_bit)
{
//*************************************************************************
TEST(test_debounce_no_hold_or_repeat)
TEST(test_debounce_status)
{
debounce_valid_hold_repeat value;
CHECK_EQUAL(NBits, value.get_width());
CHECK_EQUAL(0, value.get_state());
CHECK_EQUAL(debounce_valid_hold_repeat::state_id::Off, value.get_state(0));
CHECK_EQUAL(debounce_valid_hold_repeat::state_id::Off, value.get_state(1));
CHECK_EQUAL(debounce_valid_hold_repeat::state_id::Off, value.get_state(2));
}
//*************************************************************************
TEST(test_debounce_valid)
{
debounce_valid value(Initial_Value);
@ -99,7 +114,7 @@ namespace
}
//*************************************************************************
TEST(test_debounce_no_hold_or_repeat_incremental)
TEST(test_debounce_valid_incremental)
{
debounce_valid value(Initial_Value);
@ -115,10 +130,6 @@ namespace
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
CHECK_TRUE(value.update_incremental(1));
@ -135,10 +146,6 @@ namespace
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
CHECK_TRUE(value.update_incremental(1));
@ -164,5 +171,663 @@ namespace
CHECK_FALSE(value.is_repeating(Bit0));
}
}
//*************************************************************************
TEST(test_debounce_valid_hold)
{
debounce_valid_hold value(Initial_Value);
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
CHECK_EQUAL(0, value.get_state());
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
CHECK_EQUAL(0, value.get_state());
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
CHECK_EQUAL(1, value.get_state());
//*******************************
// Transition from On to Held.
for (size_t i = 0; i < Hold_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Ensure no more transitions.
for (size_t i = 0; i < Valid_Count + Hold_Count; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
}
//*************************************************************************
TEST(test_debounce_valid_hold_incremental)
{
debounce_valid_hold value(Initial_Value);
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from On to Held.
for (size_t i = 0; i < Hold_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Ensure no more transitions.
for (size_t i = 0; i < Valid_Count + Hold_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
}
//*************************************************************************
TEST(test_debounce_valid_hold_repeat)
{
debounce_valid_hold_repeat value(Initial_Value);
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
CHECK_EQUAL(0, value.get_state());
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
CHECK_EQUAL(0, value.get_state());
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
CHECK_EQUAL(1, value.get_state());
//*******************************
// Transition from On to Held.
for (size_t i = 0; i < Hold_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Held to Repeating.
for (size_t i = 0; i < Repeat_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
//*******************************
// Check for more repeat transitions.
for (size_t i = 0; i < Repeat_Count - 1; ++i)
{
CHECK_FALSE(value.update(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
}
// Changed.
CHECK_TRUE(value.update(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
}
//*************************************************************************
TEST(test_debounce_valid_hold_repeat_incremental)
{
debounce_valid_hold_repeat value(Initial_Value);
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from On to Held.
for (size_t i = 0; i < Hold_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Held to Repeating.
for (size_t i = 0; i < Repeat_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
//*******************************
// Check for more repeat transitions.
for (size_t i = 0; i < Repeat_Count - 1; ++i)
{
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_FALSE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
}
// Final incremental update.
// Changed.
for (size_t j = 0; j < value.get_width() - 1; ++j)
{
CHECK_FALSE(value.update_incremental(1));
}
CHECK_TRUE(value.update_incremental(1));
CHECK_TRUE(value.has_changed(Bit0));
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
}
//*************************************************************************
TEST(test_debounce_valid_hold_repeat_check_return_to_off)
{
debounce_valid_hold_repeat value(Initial_Value);
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(1);
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from On to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(0);
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to Held.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(1);
}
for (size_t i = 0; i < Hold_Count; ++i)
{
value.update(1);
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Held to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(0);
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to Repeating.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(1);
}
for (size_t i = 0; i < Hold_Count; ++i)
{
value.update(1);
}
for (size_t i = 0; i < Repeat_Count; ++i)
{
value.update(1);
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
//*******************************
// Transition from Repeating to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(0);
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
//*************************************************************************
TEST(test_debounce_valid_hold_repeat_check_return_to_off_incremental)
{
debounce_valid_hold_repeat value(Initial_Value);
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from On to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(0);
}
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to Held.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
for (size_t i = 0; i < Hold_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Held to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(0);
}
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to Repeating.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
for (size_t i = 0; i < Hold_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
for (size_t i = 0; i < Repeat_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(1);
}
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_TRUE(value.is_held(Bit0));
CHECK_TRUE(value.is_repeating(Bit0));
//*******************************
// Transition from Repeating to Off.
for (size_t i = 0; i < Valid_Count; ++i)
{
for (size_t j = 0; j < value.get_width(); ++j)
{
value.update_incremental(0);
}
}
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
//*************************************************************************
TEST(test_debounce_valid_hold_repeat_then_reset)
{
debounce_valid_hold_repeat value(Initial_Value);
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(1);
}
//*******************************
// Transition from On to Held.
for (size_t i = 0; i < Hold_Count; ++i)
{
value.update(1);
}
//*******************************
// Partly transition from Held to Repeating.
for (size_t i = 0; i < Repeat_Count - 1; ++i)
{
value.update(1);
}
value.reset(Initial_Value);
CHECK_FALSE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
//*******************************
// Transition from Off to On.
for (size_t i = 0; i < Valid_Count; ++i)
{
value.update(1);
}
CHECK_TRUE(value.is_set(Bit0));
CHECK_FALSE(value.is_held(Bit0));
CHECK_FALSE(value.is_repeating(Bit0));
}
//*************************************************************************
TEST(debounce_valid_hold_repeat_multiple_bits)
{
std::array<uint8_t, 45> input = {1, 0, 1, 0, 1, 3, 1, 3, 1, 3, 3, 3, 3, 7, 3, 6, 3, 6, 7, 6, 4, 6, 4,
7, 5, 4, 5, 5, 1, 5, 1, 5, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0};
using state_id_type = debounce_valid_hold_repeat::state_id_type;
using state_id = debounce_valid_hold_repeat::state_id;
std::array<state_id_type, 45> expected0 = {
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::On, state_id::On, state_id::On, state_id::Held, state_id::Held,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::On,
state_id::On, state_id::On, state_id::Held, state_id::Held, state_id::Repeating, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Off};
std::array<state_id_type, 45> expected1 = {
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::On, state_id::On, state_id::On, state_id::Held, state_id::Held, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off};
std::array<state_id_type, 45> expected2 = {
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::On, state_id::On, state_id::On, state_id::Held,
state_id::Held, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating,
state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Repeating, state_id::Off,
state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off, state_id::Off,
state_id::Off, state_id::Off, state_id::Off};
debounce_valid_hold_repeat value;
for (size_t i = 0; i < input.size(); ++i)
{
value.update(input[i]);
CHECK_EQUAL(int(expected0[i]), int(value.get_state(0)));
CHECK_EQUAL(int(expected1[i]), int(value.get_state(1)));
CHECK_EQUAL(int(expected2[i]), int(value.get_state(2)));
}
}
}
} // namespace