2024-12-09 11:41:44 +08:00
|
|
|
#include "bsp_key.h"
|
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
#include "flexible_button.h"
|
2024-12-09 11:41:44 +08:00
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
#include "bsp_uart.h"
|
|
|
|
#include "log.h"
|
2024-12-09 11:41:44 +08:00
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
#include "SLEEP.h"
|
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
// https://www.cnblogs.com/iot-fan/p/14304943.html
|
2024-12-09 11:41:44 +08:00
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
#undef LOG_ENABLE
|
|
|
|
#define LOG_ENABLE 1
|
2024-12-09 11:41:44 +08:00
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
#undef LOG_TAG
|
|
|
|
#define LOG_TAG "key"
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
USER_BUTTON_0 = 0,
|
|
|
|
USER_BUTTON_MAX
|
|
|
|
} user_button_t;
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
#define ENUM_TO_STR(e) (#e)
|
|
|
|
static char *enum_event_string[] = {
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_DOWN),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_CLICK),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_DOUBLE_CLICK),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_REPEAT_CLICK),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_SHORT_START),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_SHORT_UP),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_LONG_START),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_LONG_UP),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_LONG_HOLD),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_LONG_HOLD_UP),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_MAX),
|
|
|
|
ENUM_TO_STR(FLEX_BTN_PRESS_NONE),
|
|
|
|
};
|
|
|
|
|
|
|
|
static char *enum_btn_id_string[] = {
|
|
|
|
ENUM_TO_STR(USER_BUTTON_0),
|
|
|
|
ENUM_TO_STR(USER_BUTTON_MAX),
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static flex_button_t user_button[USER_BUTTON_MAX];
|
|
|
|
|
|
|
|
tmosTaskID key_task_id = INVALID_TASK_ID;
|
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
volatile uint8_t key_wakeup_flag = 0;
|
|
|
|
volatile uint8_t key_timeout_flag = 0;
|
2024-12-14 13:31:23 +08:00
|
|
|
|
|
|
|
static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
|
|
|
|
{
|
|
|
|
switch (pMsg->event)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
logDebug("pMsg->event %04x", pMsg->event);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
|
|
|
{
|
|
|
|
if (events & SYS_EVENT_MSG)
|
|
|
|
{
|
|
|
|
uint8_t *pMsg;
|
|
|
|
if ((pMsg = tmos_msg_receive(key_task_id)) != NULL)
|
|
|
|
{
|
|
|
|
KEY_Task_ProcessTmosMsg((tmos_event_hdr_t *)pMsg);
|
|
|
|
// Release the TMOS message
|
|
|
|
tmos_msg_deallocate(pMsg);
|
|
|
|
}
|
|
|
|
// return unprocessed events
|
|
|
|
return (events ^ SYS_EVENT_MSG);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (events & KEY_SCAN_EVT)
|
|
|
|
{
|
|
|
|
static volatile uint8_t key_vaild_times = 0;
|
|
|
|
static volatile bool key_vaild_for_long_press = false;
|
|
|
|
if (IS_KEY_Vaild())
|
|
|
|
{
|
|
|
|
if (key_vaild_times > 100)
|
|
|
|
{ //> 20ms*100=2000ms
|
|
|
|
if (false == key_vaild_for_long_press)
|
|
|
|
{
|
|
|
|
if (NULL != p_handler)
|
|
|
|
{
|
|
|
|
p_handler(kKeyLong);
|
|
|
|
}
|
|
|
|
// PRINT("WE should power switch here\r\n");
|
|
|
|
key_vaild_for_long_press = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
key_vaild_times++;
|
|
|
|
}
|
|
|
|
key_timeout_cnt = 10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // button release
|
|
|
|
|
|
|
|
if (key_vaild_times)
|
|
|
|
{
|
|
|
|
if ((key_vaild_times) < 100)
|
|
|
|
{
|
|
|
|
p_handler(kKeyShort);
|
|
|
|
}
|
|
|
|
key_vaild_times = 0;
|
|
|
|
// PRINT("KEY VAILED\r\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
key_vaild_for_long_press = false;
|
|
|
|
}
|
|
|
|
if (key_timeout_cnt)
|
|
|
|
{
|
|
|
|
key_timeout_cnt--;
|
|
|
|
tmos_start_task(key_task_id, KEY_SCAN_EVT, 64); // 40ms
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p_handler(kKeyRelease);
|
|
|
|
}
|
|
|
|
return (events ^ KEY_SCAN_EVT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Discard unknown events
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// 由按键中断唤醒后开启按键扫描
|
|
|
|
void BSP_KEY_EnterLowpower(void)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
key_wakeup_flag = 0;
|
2024-12-14 13:31:23 +08:00
|
|
|
tmos_stop_task(key_task_id, KEY_SCAN_EVT);
|
|
|
|
|
|
|
|
// R16_PB_INT_MODE |= KEY_B_PIN; // edge mode
|
|
|
|
// GPIOB_ResetBits(KEY_B_PIN); // edge fall
|
|
|
|
// R16_PB_INT_IF = KEY_B_PIN;
|
|
|
|
// R16_PB_INT_EN |= KEY_B_PIN;
|
|
|
|
|
|
|
|
// TODO:按键电平触发设置
|
|
|
|
// 下降沿触发
|
|
|
|
GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);
|
|
|
|
|
|
|
|
// 开启GPIO的睡眠唤醒,如果需要的话
|
|
|
|
// PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
|
|
|
|
PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
|
|
|
|
|
|
|
|
// 开启GPIOB中断
|
|
|
|
PFIC_EnableIRQ(GPIO_B_IRQn);
|
2024-12-14 16:00:58 +08:00
|
|
|
|
|
|
|
BSP_RequestSleep();
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void BSP_KEY_ExitLowpower(void)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
BSP_BlockSleep();
|
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
// 关闭GPIOB中断
|
|
|
|
PFIC_DisableIRQ(GPIO_B_IRQn);
|
|
|
|
PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
|
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
// tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
|
|
|
// tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(30));
|
|
|
|
// tmos_start_reload_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(30));
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
__HIGH_CODE
|
|
|
|
__attribute__((noinline))
|
2024-12-14 13:31:23 +08:00
|
|
|
void KEY_ProcessLoop(void)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
// if (R16_PB_INT_IF & KEY_B_PIN)
|
|
|
|
// {
|
|
|
|
// R16_PB_INT_IF = KEY_B_PIN;
|
|
|
|
// tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
|
|
|
// logDebug("KEY_ProcessLoop");
|
|
|
|
// }
|
|
|
|
if (key_wakeup_flag)
|
2024-12-14 13:31:23 +08:00
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
key_wakeup_flag = 0;
|
|
|
|
tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
|
|
|
// tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(20));
|
|
|
|
// tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(1000 * 10));
|
|
|
|
logDebug("key_wakeup_flag");
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t common_btn_read(void *arg)
|
|
|
|
{
|
|
|
|
uint8_t value = 0;
|
|
|
|
|
|
|
|
flex_button_t *btn = (flex_button_t *)arg;
|
|
|
|
|
|
|
|
switch (btn->id)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
case USER_BUTTON_0:
|
|
|
|
value = (uint8_t)GPIOB_ReadPortPin(KEY_B_PIN);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
logAssert(0, while (1));
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void common_btn_evt_cb(void *arg)
|
|
|
|
{
|
|
|
|
flex_button_t *btn = (flex_button_t *)arg;
|
|
|
|
|
|
|
|
logDebug("id: [%d - %s] event: [%d - %30s] repeat: %d",
|
2024-12-14 16:00:58 +08:00
|
|
|
btn->id, enum_btn_id_string[btn->id],
|
|
|
|
btn->event, enum_event_string[btn->event],
|
|
|
|
btn->click_cnt);
|
|
|
|
if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_CLICK)
|
|
|
|
{
|
|
|
|
logDebug("USER_BUTTON_0 PRESS_CLICK");
|
|
|
|
BSP_KEY_EnterLowpower();
|
|
|
|
}
|
|
|
|
else if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_DOUBLE_CLICK)
|
|
|
|
{
|
|
|
|
logDebug("USER_BUTTON_0 PRESS_LONG_HOLD")
|
|
|
|
BSP_KEY_EnterLowpower();
|
|
|
|
}
|
|
|
|
else if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_LONG_START)
|
|
|
|
{
|
|
|
|
logDebug("USER_BUTTON_0 FLEX_BTN_PRESS_LONG_START");
|
|
|
|
BSP_KEY_EnterLowpower();
|
|
|
|
}
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
|
|
|
{
|
|
|
|
if (events & SYS_EVENT_MSG)
|
|
|
|
{
|
|
|
|
uint8_t *pMsg;
|
|
|
|
if ((pMsg = tmos_msg_receive(key_task_id)) != NULL)
|
|
|
|
{
|
|
|
|
KEY_Task_ProcessTmosMsg((tmos_event_hdr_t *)pMsg);
|
|
|
|
// Release the TMOS message
|
|
|
|
tmos_msg_deallocate(pMsg);
|
|
|
|
}
|
|
|
|
// return unprocessed events
|
|
|
|
return (events ^ SYS_EVENT_MSG);
|
|
|
|
}
|
2024-12-14 16:00:58 +08:00
|
|
|
// if (events & KEY_WAKEUP_EVT)
|
|
|
|
// {
|
|
|
|
// logDebug("KEY_WAKEUP_EVT");
|
2024-12-14 13:31:23 +08:00
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
// BSP_KEY_ExitLowpower();
|
|
|
|
// return (events ^ KEY_WAKEUP_EVT);
|
|
|
|
// }
|
2024-12-14 13:31:23 +08:00
|
|
|
if (events & KEY_SCAN_EVT)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
if (0 == key_timeout_flag)
|
|
|
|
{
|
|
|
|
if (IS_KEY_Vaild())
|
|
|
|
{
|
|
|
|
tmos_stop_task(key_task_id, KEY_IDLE_TIMEOUT_EVT);
|
|
|
|
tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(1000 * 5));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logDebug("0");
|
|
|
|
}
|
|
|
|
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(20));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logDebug("KEY_SCAN_EVT timeout");
|
|
|
|
BSP_KEY_EnterLowpower();
|
|
|
|
}
|
|
|
|
// logDebug("KEY_SCAN_EVT");
|
2024-12-14 13:31:23 +08:00
|
|
|
flex_button_scan();
|
2024-12-14 16:00:58 +08:00
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
return (events ^ KEY_SCAN_EVT);
|
|
|
|
}
|
2024-12-14 16:00:58 +08:00
|
|
|
if (events & KEY_IDLE_TIMEOUT_EVT)
|
|
|
|
{
|
|
|
|
logDebug("KEY_IDLE_TIMEOUT_EVT");
|
|
|
|
key_timeout_flag = 1;
|
|
|
|
return (events ^ KEY_IDLE_TIMEOUT_EVT);
|
|
|
|
}
|
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
|
|
|
|
// Discard unknown events
|
|
|
|
return 0;
|
|
|
|
}
|
2024-12-09 11:41:44 +08:00
|
|
|
|
|
|
|
void BSP_KEY_Init(void)
|
|
|
|
{
|
2024-12-14 13:31:23 +08:00
|
|
|
/* 初始化按键数据结构 */
|
|
|
|
tmos_memset(&user_button[0], 0x0, sizeof(user_button));
|
|
|
|
|
2024-12-09 11:41:44 +08:00
|
|
|
// 由外部上拉电阻了
|
2024-12-14 13:31:23 +08:00
|
|
|
// 设置为浮空输入模式
|
2024-12-14 16:00:58 +08:00
|
|
|
GPIOB_SetBits(KEY_B_PIN);
|
2024-12-14 13:31:23 +08:00
|
|
|
GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
|
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
for (uint8_t i = 0; i < USER_BUTTON_MAX; i++)
|
2024-12-14 13:31:23 +08:00
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
user_button[i].id = i;
|
|
|
|
user_button[i].usr_button_read = common_btn_read;
|
|
|
|
user_button[i].cb = common_btn_evt_cb;
|
|
|
|
user_button[i].pressed_logic_level = 0;
|
2024-12-14 13:31:23 +08:00
|
|
|
user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);
|
2024-12-14 16:00:58 +08:00
|
|
|
user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(3000);
|
|
|
|
// user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(4500);
|
2024-12-14 13:31:23 +08:00
|
|
|
|
|
|
|
flex_button_register(&user_button[i]);
|
|
|
|
}
|
|
|
|
|
2024-12-14 16:00:58 +08:00
|
|
|
// 下降沿触发
|
|
|
|
GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);
|
|
|
|
|
|
|
|
// 开启GPIO的睡眠唤醒,如果需要的话
|
|
|
|
// PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
|
|
|
|
PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
|
|
|
|
|
|
|
|
// 开启GPIOB中断
|
|
|
|
PFIC_EnableIRQ(GPIO_B_IRQn);
|
|
|
|
|
2024-12-14 13:31:23 +08:00
|
|
|
key_task_id = TMOS_ProcessEventRegister(KEY_Task_ProcessEvent);
|
2024-12-14 16:00:58 +08:00
|
|
|
// tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(20));
|
|
|
|
|
|
|
|
//开始一个定时事件,不断的执行,除非运行tmos_stop_task关掉,
|
|
|
|
//tmosTimer具体是 1600 = 1s
|
|
|
|
// tmos_start_reload_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(20));
|
|
|
|
// BSP_KEY_EnterLowpower();
|
2024-12-14 13:31:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
__INTERRUPT // 告诉编译器使用硬件压栈
|
2024-12-14 16:00:58 +08:00
|
|
|
__HIGH_CODE // 放到RAM里
|
2024-12-14 13:31:23 +08:00
|
|
|
void GPIOB_IRQHandler(void)
|
|
|
|
{
|
2024-12-14 16:00:58 +08:00
|
|
|
// 阻止睡眠
|
|
|
|
BSP_BlockSleep();
|
|
|
|
// 关按键中断
|
|
|
|
BSP_KEY_ExitLowpower();
|
|
|
|
|
|
|
|
logDebug("KEY IRQ");
|
|
|
|
|
|
|
|
GPIOB_ClearITFlagBit(KEY_B_PIN);
|
|
|
|
|
|
|
|
key_wakeup_flag = 1;
|
|
|
|
key_timeout_flag = 0;
|
|
|
|
|
|
|
|
// BSP_BlockSleep();
|
|
|
|
|
|
|
|
// if (R16_PB_INT_IF & KEY_B_PIN)
|
|
|
|
// {
|
|
|
|
// R16_PB_INT_IF = KEY_B_PIN;
|
|
|
|
// // tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
|
|
|
// BSP_KEY_ExitLowpower();
|
|
|
|
// }
|
2024-12-14 13:31:23 +08:00
|
|
|
// tmos_set_event(key_task_id,KEY_SCAN_EVT);
|
2024-12-09 11:41:44 +08:00
|
|
|
}
|