31#ifndef ETL_DEBOUNCE_INCLUDED
32#define ETL_DEBOUNCE_INCLUDED
35#include "static_assert.h"
41 namespace private_debounce
47 typedef uint_least8_t flags_t;
48 typedef uint16_t count_t;
58 if (sample != ((flags & Sample) != 0))
61 flags =
static_cast<flags_t
>((flags &
static_cast<flags_t
>(~Sample)) | (sample ? Sample : 0));
64 flags &=
static_cast<flags_t
>(~Change);
73 return (flags & Change) != 0;
82 return ((flags & State) > Off);
91 return (flags & State) > On;
100 return ((flags & State) == Repeating);
120 : flags(initial_state ? On : Off)
133 void get_next(
bool sample,
bool condition_set,
bool condition_clear,
const uint_least8_t state_table[][2])
135 int index1 = ((flags & State) * 2) + (sample ? 1 : 0);
136 int index2 = (sample ? (condition_set ? 0 : 1) : (condition_clear ? 0 : 1));
138 flags_t next = flags;
140 next &=
static_cast<flags_t
>(~State);
141 next |= state_table[index1][index2];
149 next &=
static_cast<flags_t
>(~Change);
166 debounce2(
bool initial_state)
179 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
181 static ETL_CONSTANT uint_least8_t state_table[4][2] = {
182 {debounce_base::Off, debounce_base::Off},
183 {debounce_base::On, debounce_base::Off},
184 {debounce_base::Off, debounce_base::On},
185 {debounce_base::On, debounce_base::On},
188 get_next(sample, condition_set, condition_clear, state_table);
194 bool process(
bool sample, count_t valid_count)
198 if (count < UINT16_MAX)
202 bool valid = (count == valid_count);
204 switch (flags & State)
208 set_state(sample, valid, valid);
214 set_state(sample, valid, valid);
230 return (flags & Change);
241 debounce3(
bool initial_state)
254 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
256 static ETL_CONSTANT uint_least8_t state_table[6][2] = { {debounce_base::Off, debounce_base::Off},
257 {debounce_base::On, debounce_base::Off},
258 {debounce_base::Off, debounce_base::On},
259 {debounce_base::Held, debounce_base::On},
260 {debounce_base::Off, debounce_base::Held},
261 {debounce_base::Held, debounce_base::Held}};
263 get_next(sample, condition_set, condition_clear, state_table);
269 bool process(
bool sample, count_t valid_count, count_t hold_count)
273 if (count < UINT16_MAX)
277 bool valid = (count == valid_count);
278 bool hold = (count == hold_count);
280 switch (flags & State)
284 set_state(sample, valid, valid);
290 set_state(sample, hold, valid);
296 set_state(sample, hold, valid);
312 return (flags & Change);
323 debounce4(
bool initial_state)
336 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
338 static ETL_CONSTANT uint_least8_t state_table[8][2] = { {debounce_base::Off, debounce_base::Off},
339 {debounce_base::On, debounce_base::Off},
340 {debounce_base::Off, debounce_base::On},
341 {debounce_base::Held, debounce_base::On},
342 {debounce_base::Off, debounce_base::Held},
343 {debounce_base::Repeating, debounce_base::Held},
344 {debounce_base::Off, debounce_base::Repeating},
346 {debounce_base::Repeating, debounce_base::Repeating}};
348 get_next(sample, condition_set, condition_clear, state_table);
354 bool process(
bool sample, count_t valid_count, count_t hold_count, count_t repeat_count)
358 if (count < UINT16_MAX)
362 bool valid = (count == valid_count);
363 bool hold = (count == hold_count);
364 bool repeat = (count == repeat_count);
366 switch (flags & State)
370 set_state(sample, valid, valid);
376 set_state(sample, hold, valid);
382 set_state(sample, repeat, valid);
388 set_state(sample, repeat, valid);
390 if (sample && repeat)
410 return (flags & Change);
419 template <const u
int16_t VALID_COUNT = 0, const u
int16_t HOLD_COUNT = 0, const u
int16_t REPEAT_COUNT = 0>
428 : debounce4(initial_state)
440 return process(sample, VALID_COUNT, HOLD_COUNT, REPEAT_COUNT);
448 template <const u
int16_t VALID_COUNT, const u
int16_t HOLD_COUNT>
457 : debounce3(initial_state)
472 return process(sample, VALID_COUNT, HOLD_COUNT);
480 template <const u
int16_t VALID_COUNT>
489 : debounce2(initial_state)
503 return process(sample, VALID_COUNT);
521 : debounce4(initial_state)
535 debounce(count_t valid, count_t hold = 0, count_t repeat = 0)
538 set(valid, hold, repeat);
544 void set(count_t valid, count_t hold = 0, count_t repeat = 0)
548 repeat_count = repeat;
563 return process(sample, valid_count, hold_count, repeat_count);
570 count_t repeat_count;
bool add(bool sample)
Definition debounce.h:561
void set(count_t valid, count_t hold=0, count_t repeat=0)
Constructor.
Definition debounce.h:544
debounce(count_t valid, count_t hold=0, count_t repeat=0)
Definition debounce.h:535
debounce(bool initial_state=false)
Definition debounce.h:520
bool add(bool sample)
Definition debounce.h:501
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:488
bool add(bool sample)
Definition debounce.h:470
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:456
bool add(bool sample)
Definition debounce.h:438
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:427
State change logic for 2 state debounce.
Definition debounce.h:163
~debounce2()
Destructor.
Definition debounce.h:174
State change logic for 3 state debounce.
Definition debounce.h:238
~debounce3()
Destructor.
Definition debounce.h:249
State change logic for 4 state debounce.
Definition debounce.h:320
~debounce4()
Destructor.
Definition debounce.h:331
bool has_changed() const
Definition debounce.h:71
void add_sample(bool sample)
Definition debounce.h:55
bool is_repeating() const
Definition debounce.h:98
debounce_base(bool initial_state)
Constructor.
Definition debounce.h:119
bool is_set() const
Definition debounce.h:80
bool is_held() const
Definition debounce.h:89
void get_next(bool sample, bool condition_set, bool condition_clear, const uint_least8_t state_table[][2])
Gets the next state based on the inputs.
Definition debounce.h:133
~debounce_base()
Destructor.
Definition debounce.h:128
bitset_ext
Definition absolute.h:40