parent
6dd9ceb94e
commit
6eb62a809f
@ -0,0 +1,90 @@ |
||||
#include "debounce.h" |
||||
#include "timebase.h" |
||||
|
||||
static bool task_registered = false; |
||||
void debo_task(void); |
||||
|
||||
// ms debounce time
|
||||
#define DEBO_TIME 20 |
||||
#define DEBO_PIN_COUNT 10 |
||||
|
||||
typedef struct { |
||||
uint32_t gpio; |
||||
uint32_t bit_n; |
||||
void (*falling_cb)(void); |
||||
void (*rising_cb)(void); |
||||
uint32_t counter_0; |
||||
uint32_t counter_1; |
||||
bool status; |
||||
} debo_entry_t; |
||||
|
||||
int debo_pin_n = 0; |
||||
debo_entry_t debo_pins[DEBO_PIN_COUNT]; |
||||
|
||||
|
||||
|
||||
bool register_debounced_pin(uint32_t gpio, uint8_t n, void (*rising_cb)(void), void (*falling_cb)(void)) |
||||
{ |
||||
if (!task_registered) { |
||||
register_periodic_task(debo_task, 1); |
||||
} |
||||
|
||||
if (debo_pin_n >= DEBO_PIN_COUNT) return false; |
||||
|
||||
// add the task
|
||||
debo_entry_t *pin = &debo_pins[debo_pin_n++]; |
||||
pin->bit_n = n; |
||||
pin->gpio = gpio; |
||||
pin->falling_cb = falling_cb; |
||||
pin->rising_cb = rising_cb; |
||||
pin->counter_0 = 0; |
||||
pin->counter_1 = 0; |
||||
|
||||
io32_t IDR = P_REG(pin->gpio, GPIO_IDR_offs); |
||||
pin->status = *IDR & BIT(pin->bit_n); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
void debo_task(void) |
||||
{ |
||||
io32_t IDR; |
||||
bool status; |
||||
|
||||
for (int i = 0; i < debo_pin_n; i++) { |
||||
debo_entry_t *pin = &debo_pins[i]; |
||||
|
||||
IDR = P_REG(pin->gpio, GPIO_IDR_offs); |
||||
|
||||
status = *IDR & BIT(pin->bit_n); |
||||
if (pin->status != status) { |
||||
if (status == 0) { |
||||
// falling
|
||||
|
||||
if (pin->counter_0++ == DEBO_TIME) { |
||||
pin->status = 0; |
||||
|
||||
if (pin->falling_cb != NULL) { |
||||
pin->falling_cb(); |
||||
} |
||||
} |
||||
} else { |
||||
// rising
|
||||
|
||||
if (pin->counter_1++ == DEBO_TIME) { |
||||
pin->status = 1; |
||||
|
||||
if (pin->rising_cb != NULL) { |
||||
pin->rising_cb(); |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
// rewind counters
|
||||
pin->counter_0 = 0; |
||||
pin->counter_1 = 0; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,6 @@ |
||||
#pragma once |
||||
#include <common.h> |
||||
|
||||
// Debouncer requires that you setup SysTick first.
|
||||
|
||||
bool register_debounced_pin(uint32_t gpio, uint8_t n, void (*rising_cb)(void), void (*falling_cb)(void)); |
@ -1,13 +1,17 @@ |
||||
#pragma once |
||||
#include <common.h> |
||||
|
||||
/** Global millisecond time base */ |
||||
extern volatile uint32_t TIME_MS; |
||||
|
||||
/** Millisecond delay */ |
||||
void delay_ms(uint32_t ms); |
||||
|
||||
/** Second delay */ |
||||
void delay_s(uint32_t s); |
||||
|
||||
/** Schedule a periodic task (like a cron job). Returns success. */ |
||||
bool register_periodic_task(void (*callback) (void), uint32_t interval_ms); |
||||
|
||||
/** Schedule a future one-off task. Returns success. */ |
||||
bool register_future_task(void (*callback)(void), uint32_t delay_ms); |
||||
bool schedule_task(void (*callback)(void), uint32_t delay_ms); |
||||
|
Loading…
Reference in new issue