31#ifndef ETL_DEBOUNCE_INCLUDED
32#define ETL_DEBOUNCE_INCLUDED
38 namespace private_debounce
44 typedef uint_least8_t flags_t;
45 typedef uint16_t count_t;
55 if (sample != ((flags & Sample) != 0))
58 flags =
static_cast<flags_t
>((flags &
static_cast<flags_t
>(~Sample)) | (sample ? Sample : 0));
61 flags &=
static_cast<flags_t
>(~Change);
70 return (flags & Change) != 0;
79 return ((flags & State) > Off);
88 return (flags & State) > On;
97 return ((flags & State) == Repeating);
117 : flags(initial_state ? On : Off)
130 void get_next(
bool sample,
bool condition_set,
bool condition_clear,
const uint_least8_t state_table[][2])
132 int index1 = ((flags & State) * 2) + (sample ? 1 : 0);
133 int index2 = (sample ? (condition_set ? 0 : 1) : (condition_clear ? 0 : 1));
135 flags_t next = flags;
137 next &=
static_cast<flags_t
>(~State);
138 next |= state_table[index1][index2];
146 next &=
static_cast<flags_t
>(~Change);
163 debounce2(
bool initial_state)
176 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
178 static ETL_CONSTANT uint_least8_t state_table[4][2] = {
179 {debounce_base::Off, debounce_base::Off},
180 {debounce_base::On, debounce_base::Off},
181 {debounce_base::Off, debounce_base::On},
182 {debounce_base::On, debounce_base::On},
185 get_next(sample, condition_set, condition_clear, state_table);
191 bool process(
bool sample, count_t valid_count)
195 if (count < UINT16_MAX)
199 bool valid = (count == valid_count);
201 switch (flags & State)
205 set_state(sample, valid, valid);
211 set_state(sample, valid, valid);
227 return (flags & Change);
238 debounce3(
bool initial_state)
251 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
253 static ETL_CONSTANT uint_least8_t state_table[6][2] = { {debounce_base::Off, debounce_base::Off},
254 {debounce_base::On, debounce_base::Off},
255 {debounce_base::Off, debounce_base::On},
256 {debounce_base::Held, debounce_base::On},
257 {debounce_base::Off, debounce_base::Held},
258 {debounce_base::Held, debounce_base::Held}};
260 get_next(sample, condition_set, condition_clear, state_table);
266 bool process(
bool sample, count_t valid_count, count_t hold_count)
270 if (count < UINT16_MAX)
274 bool valid = (count == valid_count);
275 bool hold = (count == hold_count);
277 switch (flags & State)
281 set_state(sample, valid, valid);
287 set_state(sample, hold, valid);
293 set_state(sample, hold, valid);
309 return (flags & Change);
320 debounce4(
bool initial_state)
333 void set_state(
bool sample,
bool condition_set,
bool condition_clear)
335 static ETL_CONSTANT uint_least8_t state_table[8][2] = { {debounce_base::Off, debounce_base::Off},
336 {debounce_base::On, debounce_base::Off},
337 {debounce_base::Off, debounce_base::On},
338 {debounce_base::Held, debounce_base::On},
339 {debounce_base::Off, debounce_base::Held},
340 {debounce_base::Repeating, debounce_base::Held},
341 {debounce_base::Off, debounce_base::Repeating},
343 {debounce_base::Repeating, debounce_base::Repeating}};
345 get_next(sample, condition_set, condition_clear, state_table);
351 bool process(
bool sample, count_t valid_count, count_t hold_count, count_t repeat_count)
355 if (count < UINT16_MAX)
359 bool valid = (count == valid_count);
360 bool hold = (count == hold_count);
361 bool repeat = (count == repeat_count);
363 switch (flags & State)
367 set_state(sample, valid, valid);
373 set_state(sample, hold, valid);
379 set_state(sample, repeat, valid);
385 set_state(sample, repeat, valid);
387 if (sample && repeat)
407 return (flags & Change);
416 template <const u
int16_t VALID_COUNT = 0, const u
int16_t HOLD_COUNT = 0, const u
int16_t REPEAT_COUNT = 0>
425 : debounce4(initial_state)
437 return process(sample, VALID_COUNT, HOLD_COUNT, REPEAT_COUNT);
445 template <const u
int16_t VALID_COUNT, const u
int16_t HOLD_COUNT>
454 : debounce3(initial_state)
469 return process(sample, VALID_COUNT, HOLD_COUNT);
477 template <const u
int16_t VALID_COUNT>
486 : debounce2(initial_state)
500 return process(sample, VALID_COUNT);
518 : debounce4(initial_state)
532 debounce(count_t valid, count_t hold = 0, count_t repeat = 0)
535 set(valid, hold, repeat);
541 void set(count_t valid, count_t hold = 0, count_t repeat = 0)
545 repeat_count = repeat;
560 return process(sample, valid_count, hold_count, repeat_count);
567 count_t repeat_count;
bool add(bool sample)
Definition debounce.h:558
void set(count_t valid, count_t hold=0, count_t repeat=0)
Constructor.
Definition debounce.h:541
debounce(count_t valid, count_t hold=0, count_t repeat=0)
Definition debounce.h:532
debounce(bool initial_state=false)
Definition debounce.h:517
bool add(bool sample)
Definition debounce.h:498
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:485
bool add(bool sample)
Definition debounce.h:467
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:453
bool add(bool sample)
Definition debounce.h:435
debounce(bool initial_state=false)
Constructor.
Definition debounce.h:424
State change logic for 2 state debounce.
Definition debounce.h:160
~debounce2()
Destructor.
Definition debounce.h:171
State change logic for 3 state debounce.
Definition debounce.h:235
~debounce3()
Destructor.
Definition debounce.h:246
State change logic for 4 state debounce.
Definition debounce.h:317
~debounce4()
Destructor.
Definition debounce.h:328
bool has_changed() const
Definition debounce.h:68
void add_sample(bool sample)
Definition debounce.h:52
bool is_repeating() const
Definition debounce.h:95
debounce_base(bool initial_state)
Constructor.
Definition debounce.h:116
bool is_set() const
Definition debounce.h:77
bool is_held() const
Definition debounce.h:86
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:130
~debounce_base()
Destructor.
Definition debounce.h:125