103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
/*
|
|
* btn.c
|
|
*
|
|
* handles buttons as well as the
|
|
* DIP switches (in case action is desired by hot-switching)
|
|
*/
|
|
|
|
|
|
#include <ch32v20x.h>
|
|
|
|
#include "periph/btn.h"
|
|
|
|
|
|
|
|
struct Btn btn[BTN_COUNT] = {0};
|
|
|
|
|
|
|
|
void btn_init()
|
|
{
|
|
uint8_t i;
|
|
|
|
// this function assumes GPIO has been configured already
|
|
|
|
// initialize default setup
|
|
btn[BTN1]._pintype = BTN1_PIN;
|
|
btn[BTN2]._pintype = BTN2_PIN;
|
|
|
|
btn[DIP1]._pintype = DIP1_PIN;
|
|
btn[DIP2]._pintype = DIP2_PIN;
|
|
btn[DIP3]._pintype = DIP3_PIN;
|
|
|
|
for (i = 0; i < BTN_COUNT; i++) {
|
|
btn[i]._mask = BTN_RELEASE;
|
|
|
|
// ignore any currently pressed buttons
|
|
if (!(BTN_PORT->INDR & (1 << (btn[i]._pintype & BTN_PIN_MASK)))) {
|
|
btn[0]._mask |= BTN_IGNORE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void btn_poll()
|
|
{
|
|
uint8_t i;
|
|
uint8_t ignore;
|
|
|
|
uint8_t pushed;
|
|
|
|
for (i = 0; i < BTN_COUNT; i++) {
|
|
ignore = btn[i]._mask & BTN_IGNORE;
|
|
|
|
// active low type buttons
|
|
pushed = BTN_PORT->INDR & (1 << (btn[i]._pintype & BTN_PIN_MASK)) ? 0 : 1;
|
|
|
|
if (pushed) {
|
|
// hold counter
|
|
if (btn[i]._count < 0xffff) btn[i]._count++;
|
|
|
|
// pushed long enough?
|
|
if (btn[i]._count < BTN_DEBOUNCE) continue;
|
|
|
|
// first push?
|
|
if (!(btn[i]._mask & BTN_PUSH)) {
|
|
btn[i]._mask = BTN_PUSH | ignore;
|
|
if (btn[i].cb_push && !ignore) {
|
|
btn[i].cb_push(i);
|
|
btn[i]._mask |= (BTN_PUSH << 4);
|
|
}
|
|
} else if (btn[i]._count >= btn[i].hold) {
|
|
// held to count limit
|
|
|
|
// if button is not repeatable, do not retrigger
|
|
if ((btn[i]._mask & BTN_HOLD) && !btn[i].repeat) continue;
|
|
|
|
btn[i]._mask |= BTN_HOLD;
|
|
// call callback only if not in ignore state
|
|
if (btn[i].cb_hold && !ignore) {
|
|
btn[i].cb_hold(i);
|
|
btn[i]._mask |= (BTN_HOLD << 4);
|
|
}
|
|
|
|
// apply repeat rate to count
|
|
if (btn[i].repeat > btn[i]._count) {
|
|
btn[i]._count = 0;
|
|
} else btn[i]._count -= btn[i].repeat;
|
|
}
|
|
} else {
|
|
// is not pushed
|
|
if (!(btn[i]._mask & BTN_RELEASE)) {
|
|
// note: release will remove ignore status
|
|
btn[i]._mask = BTN_RELEASE;
|
|
btn[i]._count = 0;
|
|
// call callback only if not in ignore state
|
|
if (btn[i].cb_release && !ignore) {
|
|
btn[i].cb_release(i);
|
|
btn[i]._mask |= (BTN_RELEASE << 4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|