411 lines
11 KiB
C
411 lines
11 KiB
C
#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;
|
||
|
||
}
|