BLE_TYQ_CH584M/BSP/src/bsp_key.c

330 lines
7.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_key.h"
// #include "bsp_uart.h"
#include "log.h"
#include "SLEEP.h"
#include "bsp_valve.h"
#include "bsp_iwdg.h"
// https://www.cnblogs.com/iot-fan/p/14304943.html
#undef LOG_ENABLE
#define LOG_ENABLE 1
#undef LOG_TAG
#define LOG_TAG "key"
tmosTaskID key_task_id = INVALID_TASK_ID;
volatile uint8_t key_wakeup_flag = 0;
volatile uint8_t key_timeout_flag = 0;
static app_task_evt_handler_t p_handler = NULL;
static volatile uint8_t key_timeout_cnt = 0;
static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
{
switch (pMsg->event)
{
default:
logDebug("pMsg->event %04x", pMsg->event);
break;
}
}
#if 1
__HIGH_CODE
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)
{
// FEED_IWDG();
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 > (KEY_LONG_PRESS_MS / KEY_SACN_MS))
{ //> 20ms*100=2000ms
if (false == key_vaild_for_long_press)
{
if (NULL != p_handler)
{
p_handler(kKeyLong);
}
key_vaild_for_long_press = true;
}
}
else
{
key_vaild_times++;
}
key_timeout_cnt = KEY_TIMOUT_MS / KEY_SACN_MS;
}
else
{
if (key_vaild_times)
{
if ((key_vaild_times) < (KEY_LONG_PRESS_MS / KEY_SACN_MS))
{
p_handler(kKeyShort);
}
key_vaild_times = 0;
}
key_vaild_for_long_press = false;
}
if (key_timeout_cnt)
{
key_timeout_cnt--;
// logDebug("key_timeout_cnt %d", key_timeout_cnt);
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS)); // 40ms
}
else
{
p_handler(kKeyRelease);
}
return (events ^ KEY_SCAN_EVT);
}
// Discard unknown events
return 0;
}
#endif
__HIGH_CODE
// 由按键中断唤醒后开启按键扫描
void BSP_KEY_EnterLowpower(void)
{
// https://www.cnblogs.com/frontier/p/18743204
#if 1
// TODO:按键电平触发设置
// GPIOB_ModeCfg( KEY_B_PIN, GPIO_ModeIN_PU );
// 下降沿触发
GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);
// 开启GPIOB中断
PFIC_EnableIRQ(GPIO_B_IRQn);
// 开启GPIO的睡眠唤醒,如果需要的话
// PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE | RB_SLP_BAT_WAKE, Long_Delay);
BSP_RequestSleep();
#endif
}
__HIGH_CODE
void BSP_KEY_ExitLowpower(void)
{
#if 1
BSP_BlockSleep();
// 关闭GPIOB中断
PFIC_DisableIRQ(GPIO_B_IRQn);
PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
// PWR_PeriphWakeUpCfg(DISABLE, RB_SLP_GPIO_WAKE, Long_Delay);
#endif
}
#if 0
uint8_t read_button_GPIO(uint8_t button_id)
{
// you can share the GPIO read function with multiple Buttons
switch(button_id)
{
case btn1_id:
return (uint8_t)GPIOB_ReadPortPin(KEY_B_PIN);
default:
// logAssert(0, while (1));
return 0;
}
}
void BTN1_PRESS_DOWN_Handler(void* btn)
{
logDebug("BTN1_PRESS_DOWN_Handler");
// BSP_KEY_EnterLowpower();
}
void BTN1_PRESS_UP_Handler(void* btn)
{
logDebug("BTN1_PRESS_UP_Handler");
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));
logDebug("tmos_start_task KEY_IDLE_TIMEOUT_EVT");
// BSP_KEY_EnterLowpower();
}
void BTN1_SINGLE_Click_Handler(void* btn)
{
logDebug("BTN1_SINGLE_Click_Handler");
// BSP_KEY_EnterLowpower();
}
void BTN1_DOUBLE_Click_Handler(void* btn)
{
logDebug("BTN1_DOUBLE_Click_Handler");
// BSP_KEY_EnterLowpower();
}
void BTN1_LONG_PRESS_START_Handler(void* btn)
{
logDebug("BTN1_LONG_PRESS_START_Handler");
// BSP_KEY_EnterLowpower();
}
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_WAKEUP_EVT)
// {
// logDebug("KEY_WAKEUP_EVT");
// BSP_KEY_ExitLowpower();
// return (events ^ KEY_WAKEUP_EVT);
// }
if (events & KEY_SCAN_EVT)
{
// 按键没抬起来就继续扫描
if (0 == key_timeout_flag)
{
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(5));
}
else
{
logDebug("KEY_SCAN_EVT timeout");
BSP_KEY_EnterLowpower();
}
// logDebug("KEY_SCAN_EVT");
button_ticks();
return (events ^ KEY_SCAN_EVT);
}
if (events & KEY_IDLE_TIMEOUT_EVT)
{
tmos_stop_task(key_task_id, KEY_SCAN_EVT);
BSP_KEY_EnterLowpower();
logDebug("KEY_IDLE_TIMEOUT_EVT");
key_timeout_flag = 1;
return (events ^ KEY_IDLE_TIMEOUT_EVT);
}
// Discard unknown events
return 0;
}
#endif
void BSP_KEY_Init(app_task_evt_handler_t handler)
{
p_handler = handler;
key_task_id = TMOS_ProcessEventRegister(KEY_Task_ProcessEvent);
// // https://www.wch.cn/bbs/thread-98540-1.html
// R16_PIN_ALTERNATE |= RB_PIN_INTX;
// 由外部上拉电阻了
// 设置为浮空输入模式
// MCU_LDECT
// GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);
// GPIOB_ModeCfg(GPIO_Pin_16, GPIO_ModeIN_Floating);
GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
// GPIOB_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_PU);
// GPIOB_ModeCfg(GPIO_Pin_1, GPIO_ModeIN_Floating);
#if 1
// 下降沿触发
GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);
// GPIOB_ITModeCfg(GPIO_Pin_1, GPIO_ITMode_FallEdge);
// 开启GPIOB中断
PFIC_EnableIRQ(GPIO_B_IRQn);
// 开启GPIO的睡眠唤醒,如果需要的话
// PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS));
#endif
logDebug("BSP_KEY_Init=%d", IS_KEY_Vaild());
}
__HIGH_CODE
__attribute__((noinline))
void KEY_ProcessLoop(void)
{
if (key_wakeup_flag)
{
// 阻止睡眠
// BSP_BlockSleep();
// BSP_RequestBoost();
// 关按键中断
BSP_KEY_ExitLowpower();
// PRINT("KEY IRQ\n");
// GPIOB_ClearITFlagBit(KEY_B_PIN);
key_wakeup_flag = 0;
tmos_set_event(key_task_id, KEY_SCAN_EVT);
logDebug("KEY_ProcessLoop");
}
}
__INTERRUPT // 告诉编译器使用硬件压栈
__HIGH_CODE // 放到RAM里
void GPIOB_IRQHandler(void)
{
// // 阻止睡眠
// BSP_BlockSleep();
// // 关按键中断
// BSP_KEY_ExitLowpower();
// PRINT("KEY IRQ\n");
key_wakeup_flag = 1;
// GPIO唤醒会进中断要清除GPIO中断
GPIOB_ClearITFlagBit(KEY_B_PIN);
// tmos_set_event(key_task_id, KEY_SCAN_EVT);
// logDebug("KEY_ProcessLoop");
}