#include "bsp_key.h" #include "bsp_motor.h" #include "bsp_uart.h" #include "bsp_led.h" #include "log.h" #include "SLEEP.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; 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 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 > (KEY_LONG_PRESS_MS / KEY_SACN_MS)) { //> 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) < (KEY_LONG_PRESS_MS / KEY_SACN_MS)) { 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--; 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 // 由按键中断唤醒后开启按键扫描 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:按键电平触发设置 // 下降沿触发 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); BSP_RequestSleep(); } void BSP_KEY_ExitLowpower(void) { BSP_BlockSleep(); // 关闭GPIOB中断 PFIC_DisableIRQ(GPIO_B_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); GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU); // 下降沿触发 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); 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 (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) { key_wakeup_flag = 0; key_flag = !key_flag; if(key_flag) { motor_flag = 1; logDebug("motor open"); } else { motor_flag = 2; logDebug("motor close"); } tmos_set_event(key_task_id, KEY_SCAN_EVT); logDebug("KEY_ProcessLoop"); } // if (key_wakeup_flag) // { // 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"); // } } __INTERRUPT // 告诉编译器使用硬件压栈 __HIGH_CODE // 放到RAM里 void GPIOB_IRQHandler(void) { // 阻止睡眠 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(); // } // tmos_set_event(key_task_id,KEY_SCAN_EVT); }