hsc26-artemis2/firmware/app/ui/btn.c
true fe169b64f6 basic button handler routines added, hard buttons tested
touch sensors were also preliminary tested but not all have been analyzed yet.
2026-05-08 20:07:06 -07:00

102 lines
2.1 KiB
C

/*
* btn.c: handler for user interface with real or capacitive buttons
*/
#include "ch32x035_conf.h"
#include "btn.h"
#include "driver/adc.h"
BtnSub btn[BTN_COUNT];
uint16_t btn_pushed;
uint16_t btn_held;
void btn_push_cb(uint8_t idx)
{
if (!(btn_pushed & (1 << idx))) {
btn_pushed |= (1 << idx);
if (btn[idx].cb_push) btn[idx].cb_push(idx);
}
}
void btn_hold_cb(uint8_t idx)
{
btn_held |= (1 << idx);
if (btn[idx].cb_hold) btn[idx].cb_hold(idx);
}
void btn_release_cb(uint8_t idx)
{
btn_pushed &= ~(1 << idx);
btn_held &= ~(1 << idx);
if (btn[idx].cb_release) btn[idx].cb_release(idx);
}
void btn_process()
{
uint16_t i;
uint32_t x;
uint16_t btn_state[4] = {0};
// fill button bitfield
for (i = 0; i < BTN_COUNT; i++) {
if (i == 0) {
// GPIOC pulldown button
x = GPIOC->INDR & (1 << 10); // PC10 (or PC17)
} else if (i < 3) {
// GPIOB pullup buttons
x = !(GPIOB->INDR & (1 << (i + 10))); // PB11, PB12
} else {
// touch sensors
x = adc_get_tkey(i - 3);
}
// is pushed?
if (x) {
if (btn[i].hold != 0xffff)
btn[i].hold++;
if (btn[i].hold == DEBOUNCE) {
btn_state[1] |= (1 << (i + 3));
}
}
// is held?
if (btn[i].hold == HOLD_COUNTS) {
btn_state[2] |= (1 << (i + 3));
}
// is repeated?
if (btn[i].repeat && (btn[i].hold == (HOLD_COUNTS + btn[i].repeat))) {
btn_state[2] |= (1 << (i + 3));
btn[i].hold = HOLD_COUNTS;
}
// is released?
if (!x) {
if (btn[i].hold) {
btn[i].hold = 0;
btn_state[3] |= (1 << (i + 3));
}
}
}
// process callbacks for new events
for (i = 0; i < BTN_COUNT; i++) {
if (btn_state[1] & (1 << i)) {
btn_push_cb(i);
}
if (btn_state[2] & (1 << i)) {
btn_hold_cb(i);
}
if (btn_state[3] & (1 << i)) {
btn_release_cb(i);
}
}
}