Handle button events outside interrupt context (#125)
A lot of the button tasks configure TMOS tasks, which causes a lot of graphical glitches, when the bluetooth icon is drawn but the other tasks for rendering the effects still run. This also fixes the "WFI inside the interrupt handler" issue causing poweroff to hang.
This commit is contained in:
parent
1d46c5edd1
commit
5df3122a75
59
src/button.c
59
src/button.c
@ -1,4 +1,6 @@
|
||||
#include "CH58xBLE_LIB.h"
|
||||
#include "button.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEBOUNCE_HIGH_THRES (200) // 0-255
|
||||
#define DEBOUNCE_LOW_THRES (55) // 0-255
|
||||
@ -8,6 +10,13 @@
|
||||
static volatile void (*onePressHandler[KEY_INDEX])(void) = { NULL };
|
||||
static volatile void (*longPressHandler[KEY_INDEX])(void) = { NULL };
|
||||
|
||||
static volatile bool onePressPending[KEY_INDEX] = { false };
|
||||
static volatile bool longPressPending[KEY_INDEX] = { false };
|
||||
|
||||
static tmosTaskID button_task_id = INVALID_TASK_ID;
|
||||
#define BTN_PRESS (1 << 0)
|
||||
static uint16_t btn_task(tmosTaskID, uint16_t);
|
||||
|
||||
void btn_init()
|
||||
{
|
||||
GPIOA_ModeCfg(KEY1_PIN, GPIO_ModeIN_PD);
|
||||
@ -18,6 +27,11 @@ void btn_init()
|
||||
PFIC_EnableIRQ(TMR3_IRQn);
|
||||
}
|
||||
|
||||
void btn_init_task(void)
|
||||
{
|
||||
button_task_id = TMOS_ProcessEventRegister(btn_task);
|
||||
}
|
||||
|
||||
void btn_onOnePress(int key, void (*handler)(void))
|
||||
{
|
||||
if (key >= KEY_INDEX) return;
|
||||
@ -30,6 +44,41 @@ void btn_onLongPress(int key, void (*handler)(void))
|
||||
longPressHandler[key] = handler;
|
||||
}
|
||||
|
||||
void btn_tick(void)
|
||||
{
|
||||
for (int i = 0; i < KEY_INDEX; i++) {
|
||||
if (onePressPending[i]) {
|
||||
onePressPending[i] = false;
|
||||
if (onePressHandler[i]) onePressHandler[i]();
|
||||
}
|
||||
if (longPressPending[i]) {
|
||||
longPressPending[i] = false;
|
||||
if (longPressHandler[i]) longPressHandler[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t btn_task(tmosTaskID id, uint16_t events)
|
||||
{
|
||||
|
||||
if(events & SYS_EVENT_MSG) {
|
||||
uint8 *pMsg = tmos_msg_receive(button_task_id);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if (events & BTN_PRESS) {
|
||||
btn_tick();
|
||||
return (events ^ BTN_PRESS);
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
__HIGH_CODE
|
||||
static int debounce(int key, int is_press)
|
||||
{
|
||||
@ -59,11 +108,17 @@ static void check(int k)
|
||||
hold[k]++;
|
||||
if (hold[k] >= LONGPRESS_THRES && is_longpress[k] == 0) {
|
||||
is_longpress[k] = 1;
|
||||
if (longPressHandler[k]) longPressHandler[k]();
|
||||
longPressPending[k] = true;
|
||||
if (button_task_id != INVALID_TASK_ID) {
|
||||
tmos_set_event(button_task_id, BTN_PRESS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hold[k] > 0 && hold[k] < LONGPRESS_THRES) {
|
||||
if (onePressHandler[k]) onePressHandler[k]();
|
||||
onePressPending[k] = true;
|
||||
if (button_task_id != INVALID_TASK_ID) {
|
||||
tmos_set_event(button_task_id, BTN_PRESS);
|
||||
}
|
||||
}
|
||||
is_longpress[k] = 0;
|
||||
hold[k] = 0;
|
||||
|
||||
@ -19,5 +19,7 @@ enum keys {
|
||||
void btn_onOnePress(int key, void (*handler)(void));
|
||||
void btn_onLongPress(int key, void (*handler)(void));
|
||||
void btn_init();
|
||||
void btn_init_task(void);
|
||||
void btn_tick(void);
|
||||
|
||||
#endif /* __BUTTON_H__ */
|
||||
|
||||
@ -344,6 +344,7 @@ static void disp_charging()
|
||||
{
|
||||
int blink = 0;
|
||||
while (mode == BOOT) {
|
||||
btn_tick();
|
||||
int percent = batt_raw2percent(batt_raw());
|
||||
|
||||
if (charging_status()) {
|
||||
@ -446,6 +447,7 @@ int main()
|
||||
ble_setup();
|
||||
|
||||
spawn_tasks();
|
||||
btn_init_task();
|
||||
|
||||
mode = NORMAL;
|
||||
while (1) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user