jumper 1 will set LEDs to a dimmer level. jumper 2 will disable LEDs entirely. jumper 3 will turn the addon and USB ports on and off depending on ambient light level. the levels decided are arbitrary and may be updated with further testing.
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 "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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|