IoT_SCV_CH584M/bsp/src/bsp_key.c

411 lines
11 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_motor.h"
#include "bsp_uart.h"
#include "bsp_led.h"
#include "bsp_ml307r.h"
#include "log.h"
#include "SLEEP.h"
#include "bsp_valve.h"
// https://www.cnblogs.com/iot-fan/p/14304943.html
#undef LOG_ENABLE
#define LOG_ENABLE 1
#undef LOG_TAG
#define LOG_TAG "key"
uint8_t motor_flag;
tmosTaskID key_task_id = INVALID_TASK_ID;
volatile uint8_t key_wakeup_flag = 0;
volatile uint8_t key_timeout_flag = 0;
volatile uint8_t press_count = 0;
static app_task_evt_handler_t p_handler = NULL;
static volatile uint8_t key_timeout_cnt = 0;
void app_task_handler(TeAppEvtType app_evt_type)
{
switch(app_evt_type)
{
case kKeyShort:{
logDebug("button short press");
break;
}
case kKeyLong:
logDebug("button long press");
break;
case kKeyRelease:
BSP_KEY_EnterLowpower();
// DelayMs(10);
BSP_RequestSleep();
logDebug("gpio relase;BSP_RequestSleep ");
break;
default:
break;
}
}
static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
{
switch (pMsg->event)
{
default:
logDebug("pMsg->event %04x", pMsg->event);
break;
}
}
#if 1
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 uint8_t key_run = 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_run = 1;
}
// 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) < (KEY_LONG_PRESS_MS / KEY_SACN_MS))
{
p_handler(kKeyShort);
key_run = 1;
}
key_vaild_times = 0;
// PRINT("KEY VAILED\r\n");
}
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
{
// if(key_run == 1)
// {
// p_handler(kKeyRelease);
// key_run = 0;
// }
if(key_run == 1)
{
// 确保按键已真正释放后再触发释放事件
if (!IS_KEY_Vaild()) {
p_handler(kKeyRelease);
key_run = 0;
} else {
// 按键仍未释放,继续检测
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS));
}
}
}
return (events ^ KEY_SCAN_EVT);
}
if (events & KEY_IDLE_TIMEOUT_EVT)
{
press_count = 0;
return (events ^ KEY_IDLE_TIMEOUT_EVT);
}
// Discard unknown events
return 0;
}
#endif
// 由按键中断唤醒后开启按键扫描
void BSP_KEY_EnterLowpower(void)
{
// key_wakeup_flag = 0;
// 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;
// 由外部上拉电阻了
// 设置为浮空输入模式
// GPIOB_SetBits(KEY_B_PIN);
// GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
// TODO:按键电平触发设置
// 下降沿触发
GPIOA_ITModeCfg(KEY_A_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_A_IRQn);
}
void BSP_KEY_ExitLowpower(void)
{
BSP_BlockSleep();
// 关闭GPIOB中断
PFIC_DisableIRQ(GPIO_A_IRQn);
PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
}
#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);
// 由外部上拉电阻了
// 设置为浮空输入模式
// GPIOB_SetBits(KEY_B_PIN);
GPIOA_ModeCfg(KEY_A_PIN, GPIO_ModeIN_PU);
// 下降沿触发
GPIOA_ITModeCfg(KEY_A_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_A_IRQn);
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS));
// tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(5));
//开始一个定时事件,不断的执行,除非运行tmos_stop_task关掉,
//tmosTimer具体是 1600 = 1s
// BSP_KEY_EnterLowpower();
}
__HIGH_CODE
__attribute__((noinline))
void KEY_ProcessLoop(void)
{
// static uint8_t key_flag = 0;
if (key_wakeup_flag)
{
key_wakeup_flag = 0;
press_count++;
if (press_count == 1)
{
motor_flag = 3;
logDebug("motor_flag_start = %d",motor_flag);
tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(KEY_IDLE_TIMEOUT_MS));
}
else if (press_count == 2)
{
// tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(KEY_IDLE_TIMEOUT_MS));
if(gValveData.switch_status == kClosed)
{
motor_flag = 1;
logDebug("motor open");
}else
{
motor_flag = 2;
logDebug("motor close");
}
// key_flag = !key_flag;
// if(key_flag)
// {
// motor_flag = 1;
// logDebug("motor open");
// }
// else {
// motor_flag = 2;
// logDebug("motor close");
// }
press_count = 0;
}
tmos_set_event(key_task_id, KEY_SCAN_EVT);
logDebug("KEY_ProcessLoop");
}
}
__INTERRUPT // 告诉编译器使用硬件压栈
__HIGH_CODE // 放到RAM里
void GPIOB_IRQHandler(void)
{
/* // 清除中断标志位
GPIOA_ClearITFlagBit(KEY_A_PIN);
// 检查是否为真实按键事件通过确认电平是否真的接近0V
if (GPIOA_ReadPortPin(KEY_A_PIN) == 0) {
// 再次确认是否真的为低电平接近0V
DelayUs(50); // 短暂延时
if (GPIOA_ReadPortPin(KEY_A_PIN) == 0) {
// 确认是真实按键事件
// 阻止睡眠
BSP_BlockSleep();
// 关按键中断
BSP_KEY_ExitLowpower();
printf("KEY IRQ");
key_wakeup_flag = 1;
}
} else {
// 可能是电源波动导致的中断,忽略此次中断
printf("Power Fluctuation - Ignored");
} */
// // 阻止睡眠
// BSP_BlockSleep();
// // 关按键中断
// BSP_KEY_ExitLowpower();
// printf("KEY IRQ");
// GPIOB_ClearITFlagBit(KEY_B_PIN);
// key_wakeup_flag = 1;
}