暂存flexibleButton不太行?
This commit is contained in:
parent
3791a5d416
commit
f8cec39611
|
@ -15,7 +15,8 @@
|
||||||
"cstddef": "cpp",
|
"cstddef": "cpp",
|
||||||
"type_traits": "cpp",
|
"type_traits": "cpp",
|
||||||
"shell.h": "c",
|
"shell.h": "c",
|
||||||
"ch59x_common.h": "c"
|
"ch59x_common.h": "c",
|
||||||
|
"flexible_button.h": "c"
|
||||||
},
|
},
|
||||||
"marscode.chatLanguage": "cn"
|
"marscode.chatLanguage": "cn"
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#undef LOG_ENABLE
|
#undef LOG_ENABLE
|
||||||
#define LOG_ENABLE 1
|
#define LOG_ENABLE 0
|
||||||
|
|
||||||
#undef LOG_TAG
|
#undef LOG_TAG
|
||||||
#define LOG_TAG "peripheral"
|
#define LOG_TAG "peripheral"
|
||||||
|
|
|
@ -36,9 +36,29 @@
|
||||||
|
|
||||||
// static uint8_t main_task_id = INVALID_TASK_ID;
|
// static uint8_t main_task_id = INVALID_TASK_ID;
|
||||||
|
|
||||||
|
|
||||||
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||||
|
|
||||||
|
// void app_task_handler(TeAppEvtType app_evt_type)
|
||||||
|
// {
|
||||||
|
// switch(app_evt_type)
|
||||||
|
// {
|
||||||
|
// case kKeyShort:{
|
||||||
|
// PRINT("button short press\r\n");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// case kKeyLong:
|
||||||
|
// PRINT("button long press\r\n");
|
||||||
|
|
||||||
|
// break;
|
||||||
|
// case kKeyRelease:
|
||||||
|
// PRINT("gpio relase\r\n");
|
||||||
|
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* @fn Main_Circulation
|
* @fn Main_Circulation
|
||||||
*
|
*
|
||||||
|
@ -53,6 +73,7 @@ void Main_Circulation()
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
TMOS_SystemProcess();
|
TMOS_SystemProcess();
|
||||||
|
KEY_ProcessLoop();
|
||||||
// BSP_UART1_TxLoop();
|
// BSP_UART1_TxLoop();
|
||||||
#if 0
|
#if 0
|
||||||
if (GPIOB_ReadPortPin(GPIO_Pin_7) == 0)
|
if (GPIOB_ReadPortPin(GPIO_Pin_7) == 0)
|
||||||
|
@ -167,7 +188,7 @@ int main(void)
|
||||||
logError("中文测试 %2.2f", 123.456);
|
logError("中文测试 %2.2f", 123.456);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DelayMs(1000 * 3);
|
// DelayMs(1000 * 3);
|
||||||
|
|
||||||
BOOST_OFF_DEINIT;
|
BOOST_OFF_DEINIT;
|
||||||
BEEP_OFF_DEINIT;
|
BEEP_OFF_DEINIT;
|
||||||
|
@ -175,9 +196,7 @@ int main(void)
|
||||||
EMV_CHARGE_OFF_DEINIT;
|
EMV_CHARGE_OFF_DEINIT;
|
||||||
EMV_OFF_DEINIT;
|
EMV_OFF_DEINIT;
|
||||||
|
|
||||||
// BSP_KEY_Init();
|
// BSP_ADC_Init();
|
||||||
|
|
||||||
BSP_ADC_Init();
|
|
||||||
CH59x_BLEInit();
|
CH59x_BLEInit();
|
||||||
logDebug("%s\n", VER_LIB);
|
logDebug("%s\n", VER_LIB);
|
||||||
uint8_t MacAddr[6];
|
uint8_t MacAddr[6];
|
||||||
|
@ -190,7 +209,7 @@ int main(void)
|
||||||
LL_AdvertiseEventRegister(BLE_AdvertiseEventCB);
|
LL_AdvertiseEventRegister(BLE_AdvertiseEventCB);
|
||||||
|
|
||||||
// DelayMs(100);
|
// DelayMs(100);
|
||||||
GXHTC3C_Init();
|
// GXHTC3C_Init();
|
||||||
// while (1)
|
// while (1)
|
||||||
// {
|
// {
|
||||||
// DelayMs(100);
|
// DelayMs(100);
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define KEY_SCAN_EVT (0x0001 << 0)
|
#define KEY_SCAN_EVT (0x0001 << 0)
|
||||||
#define DEMO_TASK_TMOS_EVT_TEST_2 (0x0001 << 1)
|
#define KEY_WAKEUP_EVT (0x0001 << 1)
|
||||||
#define DEMO_TASK_TMOS_EVT_TEST_3 (0x0001 << 2)
|
#define KEY_RELEASE_EVT (0x0001 << 2)
|
||||||
#define DEMO_TASK_TMOS_EVT_TEST_4 (0x0001 << 3)
|
#define KEY_IDLE_TIMEOUT_EVT (0x0001 << 2)
|
||||||
#define DEMO_TASK_TMOS_EVT_TEST_5 (0x0001 << 4)
|
|
||||||
|
|
||||||
// KEY_B_PIN at PB7,low->active
|
// KEY_B_PIN at PB7,low->active
|
||||||
#define KEY_B_PIN GPIO_Pin_7
|
#define KEY_B_PIN GPIO_Pin_7
|
||||||
|
@ -22,7 +21,7 @@ typedef enum
|
||||||
kKeyShort = 0,
|
kKeyShort = 0,
|
||||||
kKeyLong,
|
kKeyLong,
|
||||||
kKeyRelease,
|
kKeyRelease,
|
||||||
} TeKeyEvtType;
|
} TeAppEvtType;
|
||||||
|
|
||||||
|
|
||||||
void BSP_KEY_EnterLowpower(void);
|
void BSP_KEY_EnterLowpower(void);
|
||||||
|
@ -30,4 +29,7 @@ void BSP_KEY_ExitLowpower(void);
|
||||||
|
|
||||||
void BSP_KEY_Init(void);
|
void BSP_KEY_Init(void);
|
||||||
|
|
||||||
|
void KEY_ProcessLoop(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // !__BSP_KEY_H__
|
#endif // !__BSP_KEY_H__
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "bsp_uart.h"
|
#include "bsp_uart.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#include "SLEEP.h"
|
||||||
|
|
||||||
// https://www.cnblogs.com/iot-fan/p/14304943.html
|
// https://www.cnblogs.com/iot-fan/p/14304943.html
|
||||||
|
|
||||||
#undef LOG_ENABLE
|
#undef LOG_ENABLE
|
||||||
|
@ -14,7 +16,6 @@
|
||||||
#define LOG_TAG "key"
|
#define LOG_TAG "key"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
USER_BUTTON_0 = 0,
|
USER_BUTTON_0 = 0,
|
||||||
|
@ -48,7 +49,8 @@ static flex_button_t user_button[USER_BUTTON_MAX];
|
||||||
|
|
||||||
tmosTaskID key_task_id = INVALID_TASK_ID;
|
tmosTaskID key_task_id = INVALID_TASK_ID;
|
||||||
|
|
||||||
volatile uint8_t key_process_flag = 0;
|
volatile uint8_t key_wakeup_flag = 0;
|
||||||
|
volatile uint8_t key_timeout_flag = 0;
|
||||||
|
|
||||||
static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
|
static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +138,7 @@ static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||||
// 由按键中断唤醒后开启按键扫描
|
// 由按键中断唤醒后开启按键扫描
|
||||||
void BSP_KEY_EnterLowpower(void)
|
void BSP_KEY_EnterLowpower(void)
|
||||||
{
|
{
|
||||||
key_process_flag = 0;
|
key_wakeup_flag = 0;
|
||||||
tmos_stop_task(key_task_id, KEY_SCAN_EVT);
|
tmos_stop_task(key_task_id, KEY_SCAN_EVT);
|
||||||
|
|
||||||
// R16_PB_INT_MODE |= KEY_B_PIN; // edge mode
|
// R16_PB_INT_MODE |= KEY_B_PIN; // edge mode
|
||||||
|
@ -154,23 +156,40 @@ void BSP_KEY_EnterLowpower(void)
|
||||||
|
|
||||||
// 开启GPIOB中断
|
// 开启GPIOB中断
|
||||||
PFIC_EnableIRQ(GPIO_B_IRQn);
|
PFIC_EnableIRQ(GPIO_B_IRQn);
|
||||||
|
|
||||||
|
BSP_RequestSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSP_KEY_ExitLowpower(void)
|
void BSP_KEY_ExitLowpower(void)
|
||||||
{
|
{
|
||||||
|
BSP_BlockSleep();
|
||||||
|
|
||||||
// 关闭GPIOB中断
|
// 关闭GPIOB中断
|
||||||
PFIC_DisableIRQ(GPIO_B_IRQn);
|
PFIC_DisableIRQ(GPIO_B_IRQn);
|
||||||
PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
|
PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
|
||||||
|
|
||||||
tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
// tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
||||||
key_process_flag = 1;
|
// 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__HIGH_CODE
|
||||||
|
__attribute__((noinline))
|
||||||
void KEY_ProcessLoop(void)
|
void KEY_ProcessLoop(void)
|
||||||
{
|
{
|
||||||
if (key_process_flag)
|
// 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)
|
||||||
{
|
{
|
||||||
/* code */
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +202,7 @@ static uint8_t common_btn_read(void *arg)
|
||||||
switch (btn->id)
|
switch (btn->id)
|
||||||
{
|
{
|
||||||
case USER_BUTTON_0:
|
case USER_BUTTON_0:
|
||||||
value = GPIOB_ReadPortPin(KEY_B_PIN);
|
value = (uint8_t)GPIOB_ReadPortPin(KEY_B_PIN);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logAssert(0, while (1));
|
logAssert(0, while (1));
|
||||||
|
@ -200,6 +219,21 @@ static void common_btn_evt_cb(void *arg)
|
||||||
btn->id, enum_btn_id_string[btn->id],
|
btn->id, enum_btn_id_string[btn->id],
|
||||||
btn->event, enum_event_string[btn->event],
|
btn->event, enum_event_string[btn->event],
|
||||||
btn->click_cnt);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||||
|
@ -216,13 +250,45 @@ static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||||
// return unprocessed events
|
// return unprocessed events
|
||||||
return (events ^ SYS_EVENT_MSG);
|
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 (events & KEY_SCAN_EVT)
|
||||||
{
|
{
|
||||||
|
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");
|
||||||
flex_button_scan();
|
flex_button_scan();
|
||||||
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(30));
|
|
||||||
return (events ^ KEY_SCAN_EVT);
|
return (events ^ KEY_SCAN_EVT);
|
||||||
}
|
}
|
||||||
|
if (events & KEY_IDLE_TIMEOUT_EVT)
|
||||||
|
{
|
||||||
|
logDebug("KEY_IDLE_TIMEOUT_EVT");
|
||||||
|
key_timeout_flag = 1;
|
||||||
|
return (events ^ KEY_IDLE_TIMEOUT_EVT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Discard unknown events
|
// Discard unknown events
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,6 +301,7 @@ void BSP_KEY_Init(void)
|
||||||
|
|
||||||
// 由外部上拉电阻了
|
// 由外部上拉电阻了
|
||||||
// 设置为浮空输入模式
|
// 设置为浮空输入模式
|
||||||
|
GPIOB_SetBits(KEY_B_PIN);
|
||||||
GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
|
GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < USER_BUTTON_MAX; i++)
|
for (uint8_t i = 0; i < USER_BUTTON_MAX; i++)
|
||||||
|
@ -245,26 +312,53 @@ void BSP_KEY_Init(void)
|
||||||
user_button[i].pressed_logic_level = 0;
|
user_button[i].pressed_logic_level = 0;
|
||||||
user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);
|
user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);
|
||||||
user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(3000);
|
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);
|
// user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(4500);
|
||||||
|
|
||||||
flex_button_register(&user_button[i]);
|
flex_button_register(&user_button[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下降沿触发
|
||||||
|
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);
|
||||||
|
|
||||||
key_task_id = TMOS_ProcessEventRegister(KEY_Task_ProcessEvent);
|
key_task_id = TMOS_ProcessEventRegister(KEY_Task_ProcessEvent);
|
||||||
tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(30));
|
// 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
__INTERRUPT // 告诉编译器使用硬件压栈
|
__INTERRUPT // 告诉编译器使用硬件压栈
|
||||||
__HIGH_CODE // 放到RAM里
|
__HIGH_CODE // 放到RAM里
|
||||||
void GPIOB_IRQHandler(void)
|
void GPIOB_IRQHandler(void)
|
||||||
{
|
{
|
||||||
if (R16_PB_INT_IF & KEY_B_PIN)
|
// 阻止睡眠
|
||||||
{
|
BSP_BlockSleep();
|
||||||
R16_PB_INT_IF = KEY_B_PIN;
|
// 关按键中断
|
||||||
tmos_set_event(key_task_id, KEY_SCAN_EVT);
|
|
||||||
BSP_KEY_ExitLowpower();
|
BSP_KEY_ExitLowpower();
|
||||||
|
|
||||||
logDebug("KEY IRQ");
|
logDebug("KEY IRQ");
|
||||||
}
|
|
||||||
// GPIOB_ClearITFlagBit(KEY_B_PIN);
|
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);
|
// tmos_set_event(key_task_id,KEY_SCAN_EVT);
|
||||||
}
|
}
|
||||||
|
|
27
HAL/SLEEP.c
27
HAL/SLEEP.c
|
@ -16,8 +16,28 @@
|
||||||
|
|
||||||
#include "bsp_key.h"
|
#include "bsp_key.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "bsp_uart.h"
|
||||||
|
|
||||||
|
|
||||||
|
#undef LOG_ENABLE
|
||||||
|
#define LOG_ENABLE 1
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "sleep"
|
||||||
|
|
||||||
|
static volatile bool block_sleep_flag = false;
|
||||||
|
|
||||||
|
void BSP_RequestSleep(void)
|
||||||
|
{
|
||||||
|
block_sleep_flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_BlockSleep(void)
|
||||||
|
{
|
||||||
|
block_sleep_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* @fn CH59x_LowPower
|
* @fn CH59x_LowPower
|
||||||
*
|
*
|
||||||
|
@ -29,6 +49,11 @@
|
||||||
*/
|
*/
|
||||||
uint32_t CH59x_LowPower(uint32_t time)
|
uint32_t CH59x_LowPower(uint32_t time)
|
||||||
{
|
{
|
||||||
|
if( true == block_sleep_flag)
|
||||||
|
{
|
||||||
|
// logDebug("block_sleep");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#if (defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
#if (defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
||||||
volatile uint32_t i;
|
volatile uint32_t i;
|
||||||
uint32_t time_sleep, time_curr;
|
uint32_t time_sleep, time_curr;
|
||||||
|
@ -87,7 +112,7 @@ uint32_t CH59x_LowPower(uint32_t time)
|
||||||
i = RTC_GetCycle32k();
|
i = RTC_GetCycle32k();
|
||||||
while (i == RTC_GetCycle32k());
|
while (i == RTC_GetCycle32k());
|
||||||
|
|
||||||
// BSP_KEY_ExitLowpower();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ extern "C" {
|
||||||
* GLOBAL VARIABLES
|
* GLOBAL VARIABLES
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void BSP_RequestSleep(void);
|
||||||
|
void BSP_BlockSleep(void);
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* FUNCTIONS
|
* FUNCTIONS
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* @Author : stark1898y 1658608470@qq.com
|
* @Author : stark1898y 1658608470@qq.com
|
||||||
* @Date : 2024-07-04 16:13:57
|
* @Date : 2024-07-04 16:13:57
|
||||||
* @LastEditors : stark1898y 1658608470@qq.com
|
* @LastEditors : stark1898y 1658608470@qq.com
|
||||||
* @LastEditTime : 2024-09-25 14:33:23
|
* @LastEditTime : 2024-12-14 15:56:11
|
||||||
* @FilePath : \JT-DT-YD4N02A_RTT_MRS\packages\FlexibleButton-2.0.1\flexible_button.h
|
* @FilePath : \BLE_TYQ_CH592F\common\FlexibleButton-2.0.1\flexible_button.h
|
||||||
* @Description :
|
* @Description :
|
||||||
*
|
*
|
||||||
* Copyright (c) 2024 by yzy, All Rights Reserved.
|
* Copyright (c) 2024 by yzy, All Rights Reserved.
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
#define FLEX_BTN_SCAN_FREQ_HZ 40 // How often flex_button_scan () is called
|
#define FLEX_BTN_SCAN_FREQ_HZ 50 // How often flex_button_scan () is called
|
||||||
#define FLEX_MS_TO_SCAN_CNT(ms) (ms / (1000 / FLEX_BTN_SCAN_FREQ_HZ)) //
|
#define FLEX_MS_TO_SCAN_CNT(ms) (ms / (1000 / FLEX_BTN_SCAN_FREQ_HZ)) //
|
||||||
/* Multiple clicks interval, default 300ms */
|
/* Multiple clicks interval, default 300ms */
|
||||||
#define MAX_MULTIPLE_CLICKS_INTERVAL (FLEX_MS_TO_SCAN_CNT(300))
|
#define MAX_MULTIPLE_CLICKS_INTERVAL (FLEX_MS_TO_SCAN_CNT(300))
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Zibin Zheng
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,131 @@
|
||||||
|
# MultiButton
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
1.先申请一个按键结构
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct Button button1;
|
||||||
|
```
|
||||||
|
2.初始化按键对象,绑定按键的GPIO电平读取接口**read_button_pin()** ,后一个参数设置有效触发电平
|
||||||
|
|
||||||
|
```c
|
||||||
|
button_init(&button1, read_button_pin, 0, 0);
|
||||||
|
```
|
||||||
|
3.注册按键事件
|
||||||
|
|
||||||
|
```c
|
||||||
|
button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler);
|
||||||
|
button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler);
|
||||||
|
...
|
||||||
|
```
|
||||||
|
4.启动按键
|
||||||
|
|
||||||
|
```c
|
||||||
|
button_start(&button1);
|
||||||
|
```
|
||||||
|
5.设置一个5ms间隔的定时器循环调用后台处理函数
|
||||||
|
|
||||||
|
```c
|
||||||
|
while(1) {
|
||||||
|
...
|
||||||
|
if(timer_ticks == 5) {
|
||||||
|
timer_ticks = 0;
|
||||||
|
|
||||||
|
button_ticks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
MultiButton 使用C语言实现,基于面向对象方式设计思路,每个按键对象单独用一份数据结构管理:
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct Button {
|
||||||
|
uint16_t ticks;
|
||||||
|
uint8_t repeat: 4;
|
||||||
|
uint8_t event : 4;
|
||||||
|
uint8_t state : 3;
|
||||||
|
uint8_t debounce_cnt : 3;
|
||||||
|
uint8_t active_level : 1;
|
||||||
|
uint8_t button_level : 1;
|
||||||
|
uint8_t button_id;
|
||||||
|
uint8_t (*hal_button_Level)(uint8_t button_id_);
|
||||||
|
BtnCallback cb[number_of_event];
|
||||||
|
struct Button* next;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
这样每个按键使用单向链表相连,依次进入 button_handler(struct Button* handle) 状态机处理,所以每个按键的状态彼此独立。
|
||||||
|
|
||||||
|
|
||||||
|
## 按键事件
|
||||||
|
|
||||||
|
事件 | 说明
|
||||||
|
---|---
|
||||||
|
PRESS_DOWN | 按键按下,每次按下都触发
|
||||||
|
PRESS_UP | 按键弹起,每次松开都触发
|
||||||
|
PRESS_REPEAT | 重复按下触发,变量repeat计数连击次数
|
||||||
|
SINGLE_CLICK | 单击按键事件
|
||||||
|
DOUBLE_CLICK | 双击按键事件
|
||||||
|
LONG_PRESS_START | 达到长按时间阈值时触发一次
|
||||||
|
LONG_PRESS_HOLD | 长按期间一直触发
|
||||||
|
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "button.h"
|
||||||
|
|
||||||
|
unit8_t btn1_id = 0;
|
||||||
|
|
||||||
|
struct Button btn1;
|
||||||
|
|
||||||
|
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 HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void BTN1_PRESS_DOWN_Handler(void* btn)
|
||||||
|
{
|
||||||
|
//do something...
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTN1_PRESS_UP_Handler(void* btn)
|
||||||
|
{
|
||||||
|
//do something...
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
button_init(&btn1, read_button_GPIO, 0, btn1_id);
|
||||||
|
button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);
|
||||||
|
button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
|
||||||
|
button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler);
|
||||||
|
button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler);
|
||||||
|
button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler);
|
||||||
|
button_attach(&btn1, LONG_PRESS_START, BTN1_LONG_PRESS_START_Handler);
|
||||||
|
button_attach(&btn1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler);
|
||||||
|
button_start(&btn1);
|
||||||
|
|
||||||
|
//make the timer invoking the button_ticks() interval 5ms.
|
||||||
|
//This function is implemented by yourself.
|
||||||
|
__timer_start(button_ticks, 0, 5);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "multi_button.h"
|
||||||
|
|
||||||
|
enum Button_IDs {
|
||||||
|
btn1_id,
|
||||||
|
btn2_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Button btn1;
|
||||||
|
struct Button btn2;
|
||||||
|
|
||||||
|
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 HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
|
||||||
|
case btn2_id:
|
||||||
|
return HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
button_init(&btn1, read_button_GPIO, 0, btn1_id);
|
||||||
|
button_init(&btn2, read_button_GPIO, 0, btn2_id);
|
||||||
|
|
||||||
|
button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);
|
||||||
|
button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
|
||||||
|
button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler);
|
||||||
|
button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler);
|
||||||
|
button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler);
|
||||||
|
button_attach(&btn1, LONG_PRESS_START, BTN1_LONG_PRESS_START_Handler);
|
||||||
|
button_attach(&btn1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler);
|
||||||
|
|
||||||
|
button_attach(&btn2, PRESS_DOWN, BTN2_PRESS_DOWN_Handler);
|
||||||
|
button_attach(&btn2, PRESS_UP, BTN2_PRESS_UP_Handler);
|
||||||
|
button_attach(&btn2, PRESS_REPEAT, BTN2_PRESS_REPEAT_Handler);
|
||||||
|
button_attach(&btn2, SINGLE_CLICK, BTN2_SINGLE_Click_Handler);
|
||||||
|
button_attach(&btn2, DOUBLE_CLICK, BTN2_DOUBLE_Click_Handler);
|
||||||
|
button_attach(&btn2, LONG_PRESS_START, BTN2_LONG_PRESS_START_Handler);
|
||||||
|
button_attach(&btn2, LONG_PRESS_HOLD, BTN2_LONG_PRESS_HOLD_Handler);
|
||||||
|
|
||||||
|
button_start(&btn1);
|
||||||
|
button_start(&btn2);
|
||||||
|
|
||||||
|
//make the timer invoking the button_ticks() interval 5ms.
|
||||||
|
//This function is implemented by yourself.
|
||||||
|
__timer_start(button_ticks, 0, 5);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTN1_PRESS_DOWN_Handler(void* btn)
|
||||||
|
{
|
||||||
|
//do something...
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTN1_PRESS_UP_Handler(void* btn)
|
||||||
|
{
|
||||||
|
//do something...
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "multi_button.h"
|
||||||
|
|
||||||
|
unit8_t btn1_id = 0;
|
||||||
|
struct Button btn1;
|
||||||
|
|
||||||
|
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 HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
static PressEvent btn1_event_val;
|
||||||
|
|
||||||
|
button_init(&btn1, read_button_GPIO, 0, btn1_id);
|
||||||
|
button_start(&btn1);
|
||||||
|
|
||||||
|
//make the timer invoking the button_ticks() interval 5ms.
|
||||||
|
//This function is implemented by yourself.
|
||||||
|
__timer_start(button_ticks, 0, 5);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(btn1_event_val != get_button_event(&btn1)) {
|
||||||
|
btn1_event_val = get_button_event(&btn1);
|
||||||
|
|
||||||
|
if(btn1_event_val == PRESS_DOWN) {
|
||||||
|
//do something
|
||||||
|
} else if(btn1_event_val == PRESS_UP) {
|
||||||
|
//do something
|
||||||
|
} else if(btn1_event_val == LONG_PRESS_HOLD) {
|
||||||
|
//do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "multi_button.h"
|
||||||
|
|
||||||
|
#define EVENT_CB(ev) if(handle->cb[ev])handle->cb[ev]((void*)handle)
|
||||||
|
#define PRESS_REPEAT_MAX_NUM 15 /*!< The maximum value of the repeat counter */
|
||||||
|
|
||||||
|
//button handle list head.
|
||||||
|
static struct Button* head_handle = NULL;
|
||||||
|
|
||||||
|
static void button_handler(struct Button* handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the button struct handle.
|
||||||
|
* @param handle: the button handle struct.
|
||||||
|
* @param pin_level: read the HAL GPIO of the connected button level.
|
||||||
|
* @param active_level: pressed GPIO level.
|
||||||
|
* @param button_id: the button id.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void button_init(struct Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id)
|
||||||
|
{
|
||||||
|
memset(handle, 0, sizeof(struct Button));
|
||||||
|
handle->event = (uint8_t)NONE_PRESS;
|
||||||
|
handle->hal_button_Level = pin_level;
|
||||||
|
handle->button_level = !active_level;
|
||||||
|
handle->active_level = active_level;
|
||||||
|
handle->button_id = button_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attach the button event callback function.
|
||||||
|
* @param handle: the button handle struct.
|
||||||
|
* @param event: trigger event type.
|
||||||
|
* @param cb: callback function.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void button_attach(struct Button* handle, PressEvent event, BtnCallback cb)
|
||||||
|
{
|
||||||
|
handle->cb[event] = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inquire the button event happen.
|
||||||
|
* @param handle: the button handle struct.
|
||||||
|
* @retval button event.
|
||||||
|
*/
|
||||||
|
PressEvent get_button_event(struct Button* handle)
|
||||||
|
{
|
||||||
|
return (PressEvent)(handle->event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Button driver core function, driver state machine.
|
||||||
|
* @param handle: the button handle struct.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void button_handler(struct Button* handle)
|
||||||
|
{
|
||||||
|
uint8_t read_gpio_level = handle->hal_button_Level(handle->button_id);
|
||||||
|
|
||||||
|
//ticks counter working..
|
||||||
|
if((handle->state) > 0) handle->ticks++;
|
||||||
|
|
||||||
|
/*------------button debounce handle---------------*/
|
||||||
|
if(read_gpio_level != handle->button_level) { //not equal to prev one
|
||||||
|
//continue read 3 times same new level change
|
||||||
|
if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) {
|
||||||
|
handle->button_level = read_gpio_level;
|
||||||
|
handle->debounce_cnt = 0;
|
||||||
|
}
|
||||||
|
} else { //level not change ,counter reset.
|
||||||
|
handle->debounce_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------State machine-------------------*/
|
||||||
|
switch (handle->state) {
|
||||||
|
case 0:
|
||||||
|
if(handle->button_level == handle->active_level) { //start press down
|
||||||
|
handle->event = (uint8_t)PRESS_DOWN;
|
||||||
|
EVENT_CB(PRESS_DOWN);
|
||||||
|
handle->ticks = 0;
|
||||||
|
handle->repeat = 1;
|
||||||
|
handle->state = 1;
|
||||||
|
} else {
|
||||||
|
handle->event = (uint8_t)NONE_PRESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if(handle->button_level != handle->active_level) { //released press up
|
||||||
|
handle->event = (uint8_t)PRESS_UP;
|
||||||
|
EVENT_CB(PRESS_UP);
|
||||||
|
handle->ticks = 0;
|
||||||
|
handle->state = 2;
|
||||||
|
} else if(handle->ticks > LONG_TICKS) {
|
||||||
|
handle->event = (uint8_t)LONG_PRESS_START;
|
||||||
|
EVENT_CB(LONG_PRESS_START);
|
||||||
|
handle->state = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if(handle->button_level == handle->active_level) { //press down again
|
||||||
|
handle->event = (uint8_t)PRESS_DOWN;
|
||||||
|
EVENT_CB(PRESS_DOWN);
|
||||||
|
if(handle->repeat != PRESS_REPEAT_MAX_NUM) {
|
||||||
|
handle->repeat++;
|
||||||
|
}
|
||||||
|
EVENT_CB(PRESS_REPEAT); // repeat hit
|
||||||
|
handle->ticks = 0;
|
||||||
|
handle->state = 3;
|
||||||
|
} else if(handle->ticks > SHORT_TICKS) { //released timeout
|
||||||
|
if(handle->repeat == 1) {
|
||||||
|
handle->event = (uint8_t)SINGLE_CLICK;
|
||||||
|
EVENT_CB(SINGLE_CLICK);
|
||||||
|
} else if(handle->repeat == 2) {
|
||||||
|
handle->event = (uint8_t)DOUBLE_CLICK;
|
||||||
|
EVENT_CB(DOUBLE_CLICK); // repeat hit
|
||||||
|
}
|
||||||
|
handle->state = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(handle->button_level != handle->active_level) { //released press up
|
||||||
|
handle->event = (uint8_t)PRESS_UP;
|
||||||
|
EVENT_CB(PRESS_UP);
|
||||||
|
if(handle->ticks < SHORT_TICKS) {
|
||||||
|
handle->ticks = 0;
|
||||||
|
handle->state = 2; //repeat press
|
||||||
|
} else {
|
||||||
|
handle->state = 0;
|
||||||
|
}
|
||||||
|
} else if(handle->ticks > SHORT_TICKS) { // SHORT_TICKS < press down hold time < LONG_TICKS
|
||||||
|
handle->state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if(handle->button_level == handle->active_level) {
|
||||||
|
//continue hold trigger
|
||||||
|
handle->event = (uint8_t)LONG_PRESS_HOLD;
|
||||||
|
EVENT_CB(LONG_PRESS_HOLD);
|
||||||
|
} else { //released
|
||||||
|
handle->event = (uint8_t)PRESS_UP;
|
||||||
|
EVENT_CB(PRESS_UP);
|
||||||
|
handle->state = 0; //reset
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handle->state = 0; //reset
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start the button work, add the handle into work list.
|
||||||
|
* @param handle: target handle struct.
|
||||||
|
* @retval 0: succeed. -1: already exist.
|
||||||
|
*/
|
||||||
|
int button_start(struct Button* handle)
|
||||||
|
{
|
||||||
|
struct Button* target = head_handle;
|
||||||
|
while(target) {
|
||||||
|
if(target == handle) return -1; //already exist.
|
||||||
|
target = target->next;
|
||||||
|
}
|
||||||
|
handle->next = head_handle;
|
||||||
|
head_handle = handle;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the button work, remove the handle off work list.
|
||||||
|
* @param handle: target handle struct.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void button_stop(struct Button* handle)
|
||||||
|
{
|
||||||
|
struct Button** curr;
|
||||||
|
for(curr = &head_handle; *curr; ) {
|
||||||
|
struct Button* entry = *curr;
|
||||||
|
if(entry == handle) {
|
||||||
|
*curr = entry->next;
|
||||||
|
// free(entry);
|
||||||
|
return;//glacier add 2021-8-18
|
||||||
|
} else {
|
||||||
|
curr = &entry->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief background ticks, timer repeat invoking interval 5ms.
|
||||||
|
* @param None.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void button_ticks(void)
|
||||||
|
{
|
||||||
|
struct Button* target;
|
||||||
|
for(target=head_handle; target; target=target->next) {
|
||||||
|
button_handler(target);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MULTI_BUTTON_H_
|
||||||
|
#define _MULTI_BUTTON_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//According to your need to modify the constants.
|
||||||
|
#define TICKS_INTERVAL 5 //ms
|
||||||
|
#define DEBOUNCE_TICKS 3 //MAX 7 (0 ~ 7)
|
||||||
|
#define SHORT_TICKS (300 /TICKS_INTERVAL)
|
||||||
|
#define LONG_TICKS (1000 /TICKS_INTERVAL)
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*BtnCallback)(void*);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRESS_DOWN = 0,
|
||||||
|
PRESS_UP,
|
||||||
|
PRESS_REPEAT,
|
||||||
|
SINGLE_CLICK,
|
||||||
|
DOUBLE_CLICK,
|
||||||
|
LONG_PRESS_START,
|
||||||
|
LONG_PRESS_HOLD,
|
||||||
|
number_of_event,
|
||||||
|
NONE_PRESS
|
||||||
|
}PressEvent;
|
||||||
|
|
||||||
|
typedef struct Button {
|
||||||
|
uint16_t ticks;
|
||||||
|
uint8_t repeat : 4;
|
||||||
|
uint8_t event : 4;
|
||||||
|
uint8_t state : 3;
|
||||||
|
uint8_t debounce_cnt : 3;
|
||||||
|
uint8_t active_level : 1;
|
||||||
|
uint8_t button_level : 1;
|
||||||
|
uint8_t button_id;
|
||||||
|
uint8_t (*hal_button_Level)(uint8_t button_id_);
|
||||||
|
BtnCallback cb[number_of_event];
|
||||||
|
struct Button* next;
|
||||||
|
}Button;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void button_init(struct Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id);
|
||||||
|
void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);
|
||||||
|
PressEvent get_button_event(struct Button* handle);
|
||||||
|
int button_start(struct Button* handle);
|
||||||
|
void button_stop(struct Button* handle);
|
||||||
|
void button_ticks(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue