Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor of the debounce change calculation #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions firmware/debounce.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

#include <stdint.h>

/*
each of these 8 bit variables are storing the state for 8 keys

so for key 0, the counter is represented by db0[0] and db1[0]
and the state in state[0].
*/
typedef struct {
uint8_t db0; // counter bit 0
uint8_t db1; // counter bit 1
Expand All @@ -15,24 +21,45 @@ typedef struct {
* will increment that bit's counter. When it overflows, the change is
* comitted to the final debounced state and the changed bit returned.
*
* Because each key's counter and state are stored in this stacked way,
* 8 keys are processed in parallel at each operation.
*
* args:
* sample - the current state
* debouncer - the state variables of the debouncer
*
* returns: bits that have changed in the final debounced state
*
* handy XOR truth table: A B O
* 0 0 0
* 0 1 1
* 1 0 1
* 1 1 0
*
* This is used below as a difference detector:
* if A ^ B is true, A and B are different.
*
* And a way to flip selected bits in a variable or register:
* Set B to 1, then A ^ B = !A
*/
static inline uint8_t debounce(uint8_t sample, debounce_t *debouncer) {
uint8_t delta, changes;

// Set delta to changes from last stable state
// Use xor to detect changes from last stable state:
// if a key has changed, it's bit will be 1, otherwise 0
delta = sample ^ debouncer->state;

// Increment counters and reset any unchanged bits
// Increment counters and reset any unchanged bits:
// increment bit 1 for all changed keys
debouncer->db1 = ((debouncer->db1) ^ (debouncer->db0)) & delta;
debouncer->db0 = ~(debouncer->db0) & delta;
// increment bit 0 for all changed keys
debouncer->db0 = ~(debouncer->db0) & delta;

// Calculate returned change set: if delta is still true
// and the counter has wrapped back to 0, the key is changed.
changes = delta & ~debouncer->db0 & ~debouncer->db1;

// update state & calculate returned change set
changes = ~(~delta | (debouncer->db0) | (debouncer->db1));
// Update state: in this case use xor to flip any bit that is true in changes.
debouncer->state ^= changes;

return changes;
Expand Down