Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions bits_button.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ static bits_button_t bits_btn_entity;
static bits_btn_debug_printf_func debug_printf = NULL;
static void debug_print_binary(key_value_type_t num);

// Internal state machine states (not exposed to users)
typedef enum {
BTN_STATE_IDLE ,
BTN_STATE_PRESSED ,
BTN_STATE_LONG_PRESS ,
BTN_STATE_RELEASE ,
BTN_STATE_RELEASE_WINDOW ,
BTN_STATE_FINISH
} bits_btn_state_t;

static bits_btn_event_t state_to_event(bits_btn_state_t state)
{
switch (state) {
case BTN_STATE_PRESSED: return BTN_EVENT_PRESSED;
case BTN_STATE_LONG_PRESS: return BTN_EVENT_LONG_PRESS;
case BTN_STATE_RELEASE: return BTN_EVENT_RELEASE;
case BTN_STATE_FINISH: return BTN_EVENT_FINISH;
default: return (bits_btn_event_t)0;
}
}

// ============================================================================
// Buffer Implementation Selection
// ============================================================================
Expand Down Expand Up @@ -665,7 +686,7 @@ static void bits_btn_report_event(struct button_obj_t* button, bits_btn_result_t

#ifndef BITS_BTN_DISABLE_BUFFER
uint8_t is_user_result_filter_exist = (bits_btn_result_user_filter_cb != NULL);
uint8_t default_result_filter_triger = (result->event == BTN_STATE_LONG_PRESS) || (result->event == BTN_STATE_FINISH);
uint8_t default_result_filter_triger = (result->event == BTN_EVENT_LONG_PRESS) || (result->event == BTN_EVENT_FINISH);

if (bits_btn_buffer_ops && bits_btn_buffer_ops->write)
{
Expand Down Expand Up @@ -719,7 +740,7 @@ static void update_button_state_machine(struct button_obj_t* button, uint8_t btn
button->state_entry_time = current_time;

result.key_value = button->state_bits;
result.event = button->current_state;
result.event = state_to_event((bits_btn_state_t)button->current_state);
bits_btn_report_event(button, &result);
}
break;
Expand All @@ -733,7 +754,7 @@ static void update_button_state_machine(struct button_obj_t* button, uint8_t btn
button->long_press_period_trigger_cnt = 0;

result.key_value = button->state_bits;
result.event = button->current_state;
result.event = state_to_event((bits_btn_state_t)button->current_state);
bits_btn_report_event(button, &result);
}
else if (btn_pressed == 0)
Expand All @@ -758,7 +779,7 @@ static void update_button_state_machine(struct button_obj_t* button, uint8_t btn
}

result.key_value = button->state_bits;
result.event = button->current_state;
result.event = state_to_event((bits_btn_state_t)button->current_state);
result.long_press_period_trigger_cnt = button->long_press_period_trigger_cnt;
bits_btn_report_event(button, &result);
}
Expand All @@ -767,7 +788,7 @@ static void update_button_state_machine(struct button_obj_t* button, uint8_t btn
__append_bit(&button->state_bits, 0);

result.key_value = button->state_bits;
result.event = BTN_STATE_RELEASE;
result.event = BTN_EVENT_RELEASE;
bits_btn_report_event(button, &result);

button->current_state = BTN_STATE_RELEASE_WINDOW;
Expand All @@ -789,7 +810,7 @@ static void update_button_state_machine(struct button_obj_t* button, uint8_t btn
case BTN_STATE_FINISH:

result.key_value = button->state_bits;
result.event = BTN_STATE_FINISH;
result.event = BTN_EVENT_FINISH;
bits_btn_report_event(button, &result);

button->state_bits = 0;
Expand Down
14 changes: 6 additions & 8 deletions bits_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,11 @@ typedef enum {


typedef enum {
BTN_STATE_IDLE ,
BTN_STATE_PRESSED ,
BTN_STATE_LONG_PRESS ,
BTN_STATE_RELEASE ,
BTN_STATE_RELEASE_WINDOW ,
BTN_STATE_FINISH
} bits_btn_state_t;
BTN_EVENT_PRESSED = 1, // Button pressed (after debounce)
BTN_EVENT_LONG_PRESS = 2, // Long press detected or holding
BTN_EVENT_RELEASE = 3, // Button released
BTN_EVENT_FINISH = 5, // Button sequence completed (after time window)
} bits_btn_event_t;

//According to your need to modify the constants.
#ifndef BITS_BTN_TICKS_INTERVAL
Expand Down Expand Up @@ -284,7 +282,7 @@ size_t get_bits_btn_buffer_capacity(void);
* @param cb: Pointer to the user-defined filter callback function. The callback should
* return 1 to write the event to buffer, 0 to filter it out. Pass NULL to disable.
* @retval None
* @note Only available in buffer mode. Default behavior writes BTN_STATE_LONG_PRESS and BTN_STATE_FINISH events.
* @note Only available in buffer mode. Default behavior writes BTN_EVENT_LONG_PRESS and BTN_EVENT_FINISH events.
*/
void bits_btn_register_result_filter_callback(bits_btn_result_user_filter_callback cb);

Expand Down
25 changes: 18 additions & 7 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,23 @@ typedef struct button_obj_combo

## 事件类型

- `BTN_STATE_IDLE`: 空闲状态
- `BTN_STATE_PRESSED`: 按下
- `BTN_STATE_LONG_PRESS`: 长按
- `BTN_STATE_RELEASE`: 抬起
- `BTN_STATE_RELEASE_WINDOW`: 释放窗口
- `BTN_STATE_FINISH`: 完成
用户可见的事件类型通过 `bits_btn_event_t` 枚举定义:

```c
typedef enum {
BTN_EVENT_PRESSED = 1, // 按键按下(消抖后)
BTN_EVENT_LONG_PRESS = 2, // 长按检测或保持中
BTN_EVENT_RELEASE = 3, // 按键释放
BTN_EVENT_FINISH = 5, // 按键序列完成(时间窗口结束后)
} bits_btn_event_t;
```

- `BTN_EVENT_PRESSED`: 按键按下(消抖后触发)
- `BTN_EVENT_LONG_PRESS`: 长按开始或长按保持中
- `BTN_EVENT_RELEASE`: 按键释放
- `BTN_EVENT_FINISH`: 按键动作完成(时间窗口结束,可判断单击/双击/连击等)

> **注意**: 内部状态机状态(如 IDLE, RELEASE_WINDOW 等)不再暴露给用户,仅在库内部使用。

## 错误码枚举

Expand Down Expand Up @@ -250,7 +261,7 @@ while(bits_button_get_key_result(&result)) {
bits_btn_result_t preview;
if(bits_button_peek_key_result(&preview)) {
// 根据预览的事件决定是否进一步处理
if(preview.event == BTN_STATE_PRESSED) {
if(preview.event == BTN_EVENT_PRESSED) {
// 消费事件
bits_button_get_key_result(&result);
// 实际处理
Expand Down
4 changes: 2 additions & 2 deletions docs/peek_feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ uint8_t bits_button_peek_key_result(bits_btn_result_t *result);
bits_btn_result_t preview_result;
if (bits_button_peek_key_result(&preview_result)) {
// 根据事件类型决定是否深度处理
if (preview_result.event == BTN_STATE_PRESSED) {
if (preview_result.event == BTN_EVENT_PRESSED) {
// 特定事件才消费并处理
bits_btn_result_t actual_result;
if (bits_button_get_key_result(&actual_result)) {
// 实际处理事件
handle_single_click(&actual_result);
}
} else if (preview_result.event == BTN_STATE_LONG_PRESS) {
} else if (preview_result.event == BTN_EVENT_LONG_PRESS) {
// 长按开始事件,可能需要不同处理
bits_btn_result_t actual_result;
if (bits_button_get_key_result(&actual_result)) {
Expand Down
2 changes: 1 addition & 1 deletion docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void test_example_functionality(void) {
// 验证结果
bits_btn_result_t result;
TEST_ASSERT_TRUE(bits_button_get_key_result(&result));
TEST_ASSERT_EQUAL(BTN_STATE_FINISH, result.event);
TEST_ASSERT_EQUAL(BTN_EVENT_FINISH, result.event);
TEST_ASSERT_EQUAL(KEY_ID_1, result.key_id);

// 清理
Expand Down
24 changes: 13 additions & 11 deletions docs/usage_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,17 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
{
printf("id:%d, event:%d, key_value:%d, long press period trigger cnt:%d \r\n", result.key_id, result.event, result.key_value, result.long_press_period_trigger_cnt);

if(result.event == BTN_STATE_PRESSED)
if(result.event == BTN_EVENT_PRESSED)
{
printf("id:%d pressed \n", result.key_id);
}

if(result.event == BTN_STATE_RELEASE)
if(result.event == BTN_EVENT_RELEASE)
{
printf("id:%d release\n", result.key_id);
}

if(result.event == BTN_STATE_LONG_PRESS)
if(result.event == BTN_EVENT_LONG_PRESS)
{
if(result.key_value == 0b11)
printf("id:%d, long press start\n", result.key_id);
Expand All @@ -141,7 +141,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
printf("id:%d, double click and long press start\n", result.key_id);
}

if(result.event == BTN_STATE_FINISH)
if(result.event == BTN_EVENT_FINISH)
{
switch(result.key_value)
{
Expand All @@ -158,7 +158,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
}

// 通用的长按保持处理(不同的方式判别长按保持)
if(result.event == BTN_STATE_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
if(result.event == BTN_EVENT_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
{
printf("[%d] 长按保持 周期:%d\r\n",
result.key_id,
Expand Down Expand Up @@ -327,10 +327,12 @@ int main()

### 事件类型

- `BTN_STATE_PRESSED`:按键按下
- `BTN_STATE_RELEASE`:按键释放
- `BTN_STATE_LONG_PRESS`:长按事件
- `BTN_STATE_FINISH`:按键动作完成
用户可见的事件类型通过 `bits_btn_event_t` 枚举定义:

- `BTN_EVENT_PRESSED`:按键按下(消抖后触发)
- `BTN_EVENT_RELEASE`:按键释放
- `BTN_EVENT_LONG_PRESS`:长按开始或长按保持中
- `BTN_EVENT_FINISH`:按键动作完成(时间窗口结束,可判断单击/双击/连击等)

### 组合按键

Expand All @@ -346,12 +348,12 @@ void low_power_handler(void) {
// 先预览事件类型,决定是否完全处理
bits_btn_result_t preview;
if(bits_button_peek_key_result(&preview)) {
if(preview.event == BTN_STATE_LONG_PRESS && preview.key_id == POWER_KEY_ID) {
if(preview.event == BTN_EVENT_LONG_PRESS && preview.key_id == POWER_KEY_ID) {
// 电源键长按,执行关机
bits_btn_result_t actual;
bits_button_get_key_result(&actual); // 消费事件
system_shutdown();
} else if(preview.event == BTN_STATE_PRESSED && preview.key_id == WAKEUP_KEY_ID) {
} else if(preview.event == BTN_EVENT_PRESSED && preview.key_id == WAKEUP_KEY_ID) {
// 唤醒键单击,恢复正常模式
bits_btn_result_t actual;
bits_button_get_key_result(&actual); // 消费事件
Expand Down
10 changes: 5 additions & 5 deletions examples/example_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,17 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
{
printf("id:%d, event:%d, key_value:%d, long press period trigger cnt:%d \r\n", result.key_id, result.event, result.key_value, result.long_press_period_trigger_cnt);

if(result.event == BTN_STATE_PRESSED)
if(result.event == BTN_EVENT_PRESSED)
{
printf("id:%d pressed \n", result.key_id);
}

if(result.event == BTN_STATE_RELEASE)
if(result.event == BTN_EVENT_RELEASE)
{
printf("id:%d release\n", result.key_id);
}

if(result.event == BTN_STATE_LONG_PRESS)
if(result.event == BTN_EVENT_LONG_PRESS)
{
if(result.key_value == 0b11)
printf("id:%d, long press start\n", result.key_id);
Expand All @@ -108,7 +108,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
printf("id:%d, double click and long press start\n", result.key_id);
}

if(result.event == BTN_STATE_FINISH)
if(result.event == BTN_EVENT_FINISH)
{
switch(result.key_value)
{
Expand All @@ -125,7 +125,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
}

// 通用的长按保持处理(不同的方式判别长按保持)
if(result.event == BTN_STATE_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
if(result.event == BTN_EVENT_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
{
printf("[%d] 长按保持 周期:%d\r\n",
result.key_id,
Expand Down
10 changes: 5 additions & 5 deletions simulator/adapter_layer/button_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
{
printf("id:%d, event:%d, key_value:%d, long press period trigger cnt:%d \r\n", result.key_id, result.event, result.key_value, result.long_press_period_trigger_cnt);

if(result.event == BTN_STATE_PRESSED)
if(result.event == BTN_EVENT_PRESSED)
{
printf("id:%d pressed \n", result.key_id);
}

if(result.event == BTN_STATE_RELEASE)
if(result.event == BTN_EVENT_RELEASE)
{
printf("id:%d release\n", result.key_id);
}

if(result.event == BTN_STATE_LONG_PRESS)
if(result.event == BTN_EVENT_LONG_PRESS)
{
if(result.key_value == 0b11)
printf("id:%d, long press start\n", result.key_id);
Expand All @@ -93,7 +93,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
printf("id:%d, double click and long press start\n", result.key_id);
}

if(result.event == BTN_STATE_FINISH)
if(result.event == BTN_EVENT_FINISH)
{
switch(result.key_value)
{
Expand All @@ -110,7 +110,7 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
}

// 通用的长按保持处理(不同的方式判别长按保持)
if(result.event == BTN_STATE_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
if(result.event == BTN_EVENT_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
{
printf("[%d] long press hold, period:%d\r\n",
result.key_id,
Expand Down
16 changes: 8 additions & 8 deletions test/cases/basic/test_initialization.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void test_successful_initialization(void) {
mock_button_click(1, STANDARD_CLICK_TIME_MS);
time_simulate_time_window_end();

ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);

printf("成功初始化测试通过: 返回码0,基本功能正常\n");
}
Expand Down Expand Up @@ -77,7 +77,7 @@ void test_different_active_levels(void) {
mock_button_click(1, STANDARD_CLICK_TIME_MS);
time_simulate_time_window_end();

ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);

// 清空事件
test_framework_clear_events();
Expand All @@ -86,7 +86,7 @@ void test_different_active_levels(void) {
mock_button_click(2, STANDARD_CLICK_TIME_MS);
time_simulate_time_window_end();

ASSERT_EVENT_EXISTS(2, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(2, BTN_EVENT_FINISH);

printf("不同激活电平测试通过: 多个按键都正常工作\n");
}
Expand Down Expand Up @@ -143,13 +143,13 @@ void test_custom_parameters(void) {
mock_button_click(1, STANDARD_CLICK_TIME_MS);
time_simulate_time_window_end();

ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);
printf("自定义参数测试通过: 默认参数正常工作\n");
return;
}

// 应该是单击
ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);

printf("自定义参数测试通过: 自定义参数正确生效\n");
}
Expand Down Expand Up @@ -186,7 +186,7 @@ void test_multiple_button_initialization(void) {

// 验证所有按键都产生了事件
for (int i = 0; i < test_count; i++) {
ASSERT_EVENT_EXISTS(i + 1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(i + 1, BTN_EVENT_FINISH);
}

printf("多按键初始化测试通过: %d个按键都正常工作\n", test_count);
Expand Down Expand Up @@ -218,7 +218,7 @@ void test_callback_functions(void) {
time_simulate_time_window_end();

// 验证事件回调正常工作
ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);
printf("✓ 事件回调正常工作\n");

// 清空事件
Expand Down Expand Up @@ -304,7 +304,7 @@ void test_callback_functions(void) {
mock_button_click(1, STANDARD_CLICK_TIME_MS);
time_simulate_time_window_end();

ASSERT_EVENT_EXISTS(1, BTN_STATE_FINISH);
ASSERT_EVENT_EXISTS(1, BTN_EVENT_FINISH);
printf("✓ 完整回调配置正常工作\n");

printf("✓ 回调函数测试通过: 所有回调组合都经过验证\n");
Expand Down
Loading
Loading