mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 22:59:47 +08:00
Updated debounce_multi_bit tests
This commit is contained in:
parent
0a27322a2b
commit
bdaa515d4c
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user