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
55 changes: 27 additions & 28 deletions bits_button.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,58 +398,57 @@ size_t get_bits_btn_buffer_capacity(void)
#endif
}

int32_t bits_button_init(button_obj_t* btns , \
uint16_t btns_cnt , \
button_obj_combo_t *btns_combo , \
uint16_t btns_combo_cnt , \
bits_btn_read_button_level read_button_level_func , \
bits_btn_result_callback bits_btn_result_cb , \
bits_btn_debug_printf_func bis_btn_debug_printf \
)
int32_t bits_button_init(const bits_btn_config_t *config)
{
bits_button_t *button = &bits_btn_entity;
debug_printf = bis_btn_debug_printf;

if ((btns == NULL)
|| (btns_cnt == 0)
|| (read_button_level_func == NULL)
|| (btns_combo_cnt > 0 && btns_combo == NULL))
if (config == NULL)
{
return -2;
}

debug_printf = config->bits_btn_debug_printf;

if ((config->btns == NULL)
|| (config->btns_cnt == 0)
|| (config->read_button_level_func == NULL)
|| (config->btns_combo_cnt > 0 && config->btns_combo == NULL))
{
if(debug_printf)
debug_printf("Invalid init parameters !\n");
return -2;
}

if (btns_cnt > BITS_BTN_MAX_BUTTONS)
if (config->btns_cnt > BITS_BTN_MAX_BUTTONS)
{
if (debug_printf)
debug_printf("Error: Too many buttons (%d > max %d)\n", btns_cnt, (int)BITS_BTN_MAX_BUTTONS);
debug_printf("Error: Too many buttons (%d > max %d)\n", config->btns_cnt, (int)BITS_BTN_MAX_BUTTONS);
return -5;
}

memset(button, 0, sizeof(bits_button_t));

button->btns = btns;
button->btns_cnt = btns_cnt;
button->btns_combo = btns_combo;
button->btns_combo_cnt = btns_combo_cnt;
button->_read_button_level = read_button_level_func;
button->bits_btn_result_cb = bits_btn_result_cb;
button->btns = config->btns;
button->btns_cnt = config->btns_cnt;
button->btns_combo = config->btns_combo;
button->btns_combo_cnt = config->btns_combo_cnt;
button->_read_button_level = config->read_button_level_func;
button->bits_btn_result_cb = config->bits_btn_result_cb;

if (btns_combo_cnt > BITS_BTN_MAX_COMBO_BUTTONS)
if (config->btns_combo_cnt > BITS_BTN_MAX_COMBO_BUTTONS)
{
if (debug_printf)
{
debug_printf("Error: Too many combo buttons (%d > max %d)\n",
btns_combo_cnt, BITS_BTN_MAX_COMBO_BUTTONS);
config->btns_combo_cnt, BITS_BTN_MAX_COMBO_BUTTONS);
}
return -3;
}

// Check single button param pointers
for (uint16_t i = 0; i < btns_cnt; i++)
for (uint16_t i = 0; i < config->btns_cnt; i++)
{
if (btns[i].param == NULL)
if (config->btns[i].param == NULL)
{
if (debug_printf)
debug_printf("Error: Button[%d] param is NULL\n", i);
Expand All @@ -458,17 +457,17 @@ int32_t bits_button_init(button_obj_t* btns
}

// Check combo button param pointers
for (uint16_t i = 0; i < btns_combo_cnt; i++)
for (uint16_t i = 0; i < config->btns_combo_cnt; i++)
{
if (btns_combo[i].btn.param == NULL)
if (config->btns_combo[i].btn.param == NULL)
{
if (debug_printf)
debug_printf("Error: Combo button[%d] param is NULL\n", i);
return -7;
}
}

for(uint16_t i = 0; i < btns_combo_cnt; i++)
for(uint16_t i = 0; i < config->btns_combo_cnt; i++)
{
button_obj_combo_t *combo = &button->btns_combo[i];
combo->combo_mask = 0;
Expand Down
46 changes: 19 additions & 27 deletions bits_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ extern "C" {
#include <stdint.h>
#include <stdio.h>

// The maximum number of combined buttons supported
#ifndef BITS_BTN_MAX_COMBO_BUTTONS
#define BITS_BTN_MAX_COMBO_BUTTONS 8 // 默认最大支持8个组合按钮
#define BITS_BTN_MAX_COMBO_BUTTONS 8
#endif

typedef uint32_t key_value_type_t;
Expand Down Expand Up @@ -154,43 +155,34 @@ typedef struct
uint8_t (*peek)(bits_btn_result_t *result);
} bits_btn_buffer_ops_t;

typedef struct
{
button_obj_t *btns;
uint16_t btns_cnt;
button_obj_combo_t *btns_combo;
uint16_t btns_combo_cnt;
bits_btn_read_button_level read_button_level_func;
bits_btn_result_callback bits_btn_result_cb;
bits_btn_debug_printf_func bits_btn_debug_printf;
} bits_btn_config_t;

/**
* @brief Initialize the button structure and configure button detection parameters.
* This function sets up the button system, including single and combination buttons,
* and registers callback functions for button state changes.
* This function sets up the button system using the provided configuration.
*
* @param btns: Pointer to an array of button objects. Each object contains button-specific
* parameters such as key ID, debounce time, and callback functions.
* @param btns_cnt: Number of button objects in the array (i.e., the number of single buttons).
* @param btns_combo: Pointer to an array of button combination objects. These define
* multi-button presses (e.g., simultaneous key combinations).
* @param btns_combo_cnt: Number of button combination objects.
* @param read_button_level_func: Function pointer to the button level reading function.
* This function should return the current state (pressed/released)
* of the physical button.
* @param bits_btn_result_cb: Callback function pointer for button state changes.
* This function is called when a button event (press, release, etc.) is detected.
* @param bis_btn_debug_printf: Function pointer for debug logging. Pass NULL if debug output is not needed.
* @param config: Pointer to the configuration structure containing all initialization parameters.
*
* @retval Status code indicating the result of the initialization:
* @retval Status code indicating the result of the initialization:
* - 0: Success. All parameters are valid, and the button system is initialized.
* - -1: Invalid key ID in combination button configuration. A key ID specified in a
* combination button configuration does not exist in the single button array.
* - -2: Invalid input parameters. Returned if either `btns` or `read_button_level_func` is NULL.
* - -1: Invalid key ID in combination button configuration.
* - -2: Invalid input parameters. Returned if config is NULL or required fields are missing.
* - -3: Too many combo buttons. The number of combo buttons exceeds BITS_BTN_MAX_COMBO_BUTTONS.
* - -4: User buffer mode requires setting buffer ops before init.
* - -5: Too many buttons. The number of buttons exceeds BITS_BTN_MAX_BUTTONS.
* - -6: Button param is NULL. A single button has NULL param pointer.
* - -7: Combo button param is NULL. A combo button has NULL param pointer.
*/
int32_t bits_button_init(button_obj_t* btns , \
uint16_t btns_cnt , \
button_obj_combo_t *btns_combo , \
uint16_t btns_combo_cnt , \
bits_btn_read_button_level read_button_level_func , \
bits_btn_result_callback bits_btn_result_cb , \
bits_btn_debug_printf_func bis_btn_debug_printf \
);
int32_t bits_button_init(const bits_btn_config_t *config);

/**
* @brief Background ticks function, called repeatedly by the timer with an interval of 5ms.
Expand Down
51 changes: 31 additions & 20 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,23 @@
### 初始化函数

```c
int32_t bits_button_init(button_obj_t* btns,
uint16_t btns_cnt,
button_obj_combo_t *btns_combo,
uint16_t btns_combo_cnt,
uint8_t (*read_button_level_func)(struct button_obj_t *btn),
void (*bits_btn_result_cb)(struct button_obj_t *btn, struct bits_btn_result button_result),
int (*bis_btn_debug_printf)(const char* format, ...));
int32_t bits_button_init(const bits_btn_config_t *config);
```

初始化按键检测库,传入单按键数组、组合按键数组、按键状态读取函数、结果回调函数和日志打印函数
使用配置结构体初始化按键检测库

**参数:**
- `btns`: 单按键对象数组
- `btns_cnt`: 单按键对象数量
- `btns_combo`: 组合按键对象数组
- `btns_combo_cnt`: 组合按键对象数量
- `read_button_level_func`: 读取按键状态的回调函数
- `bits_btn_result_cb`: 按键事件结果回调函数
- `bis_btn_debug_printf`: 日志打印函数
- `config`: 指向配置结构体的指针,包含所有初始化参数

**返回值:**
- 0: 成功
- -1: 组合按键配置中存在无效的按键ID
- -2: 输入参数无效
- -3: 组合按键过多
- -4: 需要外部缓冲区操作但未设置
- -5: 按键数量过多
- -6: 单按键参数无效
- -7: 组合按键参数无效

---

Expand Down Expand Up @@ -135,6 +127,20 @@ void bits_btn_register_result_filter_callback(bits_btn_result_user_filter_callba

## 数据结构

### 配置结构体

```c
typedef struct {
button_obj_t *btns; // 单按键对象数组
uint16_t btns_cnt; // 单按键对象数量
button_obj_combo_t *btns_combo; // 组合按键对象数组
uint16_t btns_combo_cnt; // 组合按键对象数量
bits_btn_read_button_level read_button_level_func; // 状态读取函数
bits_btn_result_callback bits_btn_result_cb; // 结果回调函数
bits_btn_debug_printf_func bits_btn_debug_printf; // 日志打印函数
} bits_btn_config_t;
```

### 按键结果结构

```c
Expand Down Expand Up @@ -199,11 +205,16 @@ typedef struct button_obj_combo

```c
// 初始化按键库
int32_t ret = bits_button_init(btns, BTN_CNT,
combo_btns, COMBO_BTN_COUNT,
read_button_level_func,
result_callback,
debug_printf_func);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = BTN_CNT,
.btns_combo = combo_btns,
.btns_combo_cnt = COMBO_BTN_COUNT,
.read_button_level_func = read_button_level_func,
.bits_btn_result_cb = result_callback,
.bits_btn_debug_printf = debug_printf_func
};
int32_t ret = bits_button_init(&config);
if(ret != 0) {
printf("Init failed, code: %d\n", ret);
}
Expand Down
26 changes: 22 additions & 4 deletions docs/usage_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,16 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
int main()
{
// 6. 按键初始化;
int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, bits_btn_result_cb, my_log_printf);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = ARRAY_SIZE(btns),
.btns_combo = btns_combo,
.btns_combo_cnt = ARRAY_SIZE(btns_combo),
.read_button_level_func = read_key_state,
.bits_btn_result_cb = bits_btn_result_cb,
.bits_btn_debug_printf = my_log_printf
};
int32_t ret = bits_button_init(&config);
if(ret)
{
printf("bits button init failed, ret:%d \r\n", ret);
Expand Down Expand Up @@ -276,7 +285,16 @@ int my_log_printf(const char* format, ...) {
int main()
{
// 5. 按键初始化;
int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, NULL, my_log_printf);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = ARRAY_SIZE(btns),
.btns_combo = btns_combo,
.btns_combo_cnt = ARRAY_SIZE(btns_combo),
.read_button_level_func = read_key_state,
.bits_btn_result_cb = NULL,
.bits_btn_debug_printf = my_log_printf
};
int32_t ret = bits_button_init(&config);
if(ret)
{
printf("bits button init failed, ret:%d \r\n", ret);
Expand Down Expand Up @@ -305,7 +323,7 @@ int main()

### 按键初始化

使用`bits_button_init()`函数初始化按键系统,需要提供单按键数组、组合按键数组、状态读取函数、结果回调函数和日志函数。
使用`bits_button_init()`函数初始化按键系统,需要提供`bits_btn_config_t`配置结构体,包含单按键数组、组合按键数组、状态读取函数、结果回调函数和日志函数。

### 事件类型

Expand Down Expand Up @@ -383,4 +401,4 @@ void low_power_handler(void) {
2. **按键ID**:使用有意义的枚举值,避免冲突
3. **激活电平**:根据硬件电路确定(上拉电阻用1,下拉电阻用0)
4. **参数调优**:根据实际用户体验调整时间参数
5. **错误处理**:在初始化函数调用后检查返回值
5. **错误处理**:在初始化函数调用后检查返回值
13 changes: 11 additions & 2 deletions examples/example_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,16 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
int main()
{
// 6. 按键初始化;
int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, bits_btn_result_cb, my_log_printf);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = ARRAY_SIZE(btns),
.btns_combo = btns_combo,
.btns_combo_cnt = ARRAY_SIZE(btns_combo),
.read_button_level_func = read_key_state,
.bits_btn_result_cb = bits_btn_result_cb,
.bits_btn_debug_printf = my_log_printf
};
int32_t ret = bits_button_init(&config);
if(ret)
{
printf("bits button init failed, ret:%d \r\n", ret);
Expand All @@ -150,4 +159,4 @@ int main()

while(1)
{}
}
}
11 changes: 10 additions & 1 deletion examples/example_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,16 @@ int my_log_printf(const char* format, ...) {
int main()
{
// 5. 按键初始化;
int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, NULL, my_log_printf);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = ARRAY_SIZE(btns),
.btns_combo = btns_combo,
.btns_combo_cnt = ARRAY_SIZE(btns_combo),
.read_button_level_func = read_key_state,
.bits_btn_result_cb = NULL,
.bits_btn_debug_printf = my_log_printf
};
int32_t ret = bits_button_init(&config);
if(ret)
{
printf("bits button init failed, ret:%d \r\n", ret);
Expand Down
12 changes: 10 additions & 2 deletions simulator/adapter_layer/button_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,16 @@ void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)

// 初始化适配器
__attribute__((constructor)) static void init_adapter() {
// int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, bits_btn_result_cb, my_log_printf);
int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo), read_key_state, bits_btn_result_cb, NULL);
bits_btn_config_t config = {
.btns = btns,
.btns_cnt = ARRAY_SIZE(btns),
.btns_combo = btns_combo,
.btns_combo_cnt = ARRAY_SIZE(btns_combo),
.read_button_level_func = read_key_state,
.bits_btn_result_cb = bits_btn_result_cb,
.bits_btn_debug_printf = NULL
};
int32_t ret = bits_button_init(&config);
if(ret)
{
printf("bits button init failed, ret:%d \r\n", ret);
Expand Down
Loading
Loading