From e9644287beba09ef29d22004a4d8a134bb970849 Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Mon, 3 Jul 2023 21:29:04 +0800 Subject: [PATCH 1/6] section definition version --- mfbd.c | 5 + mfbd.h | 5 + mfbd_cfg.h | 9 + mfbd_sd.c | 420 +++++++++++++++++++++++++++++++++ mfbd_sd.h | 675 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1114 insertions(+) create mode 100644 mfbd_sd.c create mode 100644 mfbd_sd.h diff --git a/mfbd.c b/mfbd.c index 7fdac0b..6cca8a6 100644 --- a/mfbd.c +++ b/mfbd.c @@ -10,11 +10,14 @@ * 2022-04-16 smartmx drop list definitions, use arraylist, each group has all btn types. * 2022-08-05 smartmx add reset params function. * 2023-03-15 smartmx add state declaration. + * 2023-07-03 smartmx add Section Definition option. * */ #include "mfbd.h" +#if (MFBD_USE_SECTION_DEFINITION == 0) + #if MFBD_PARAMS_SAME_IN_GROUP /* filter_time */ @@ -493,3 +496,5 @@ void mfbd_group_reset(const mfbd_group_t *_pbtn_group) #endif } + +#endif /* (MFBD_USE_SECTION_DEFINITION == 0) */ diff --git a/mfbd.h b/mfbd.h index 1c69e2c..98d0f17 100644 --- a/mfbd.h +++ b/mfbd.h @@ -12,6 +12,7 @@ * 2022-08-15 smartmx fix bugs. * 2022-09-07 smartmx add default define apis. * 2023-03-15 smartmx add state declaration. + * 2023-07-03 smartmx add Section Definition option. * */ @@ -20,6 +21,8 @@ #include "mfbd_cfg.h" +#if (MFBD_USE_SECTION_DEFINITION == 0) + typedef enum { MFBD_BTN_STATE_UP = 0, @@ -430,4 +433,6 @@ extern void mfbd_group_scan(const mfbd_group_t *_pbtn_group); extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); +#endif /* (MFBD_USE_SECTION_DEFINITION == 0) */ + #endif diff --git a/mfbd_cfg.h b/mfbd_cfg.h index 7e11593..4b3f219 100644 --- a/mfbd_cfg.h +++ b/mfbd_cfg.h @@ -11,6 +11,7 @@ * 2022-08-05 smartmx add reset params function. * 2022-12-04 smartmx change some definitions, add rtconfig.h. * 2023-03-25 smartmx add some comment. + * 2023-07-03 smartmx add Section Definition option. * */ @@ -26,6 +27,14 @@ #define NULL 0 #endif +/* use section definitions can simplify the code, but limited with the complier. */ +#ifdef PKG_MFBD_USE_SECTION_DEFINITION + #define MFBD_USE_SECTION_DEFINITION 1 +#else + /* if you are not use mfbd in rt-thread, you can change this instead. */ + #define MFBD_USE_SECTION_DEFINITION 0 +#endif + /* mfbd_btn_code_t is the type of value for every button event. */ #ifdef PKG_MFBD_BTN_CODE_SIZE #if PKG_MFBD_BTN_CODE_SIZE==1 diff --git a/mfbd_sd.c b/mfbd_sd.c new file mode 100644 index 0000000..e255c19 --- /dev/null +++ b/mfbd_sd.c @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2022-2023, smartmx + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-03 smartmx the first version, Multi-Function Button Dectection with Section Definition. + * + */ + +#include "mfbd_sd.h" + +#if MFBD_USE_SECTION_DEFINITION + +#if MFBD_PARAMS_SAME_IN_GROUP + +/* filter_time */ +#define MFBD_FILTER_TIME_IN_FUC (_pbtn_group->filter_time) +/* long_time */ +#define MFBD_LONG_TIME_IN_FUC (_pbtn_group->long_time) +/* repeat_time */ +#define MFBD_REPEAT_TIME_IN_FUC (_pbtn_group->repeat_time) +/* multiclick_time */ +#define MFBD_MULTICLICK_TIME_IN_FUC (_pbtn_group->multiclick_time) + +#else + +/* filter_time */ +#define MFBD_FILTER_TIME_IN_FUC (_pbtn_info->filter_time) +/* long_time */ +#define MFBD_LONG_TIME_IN_FUC (_pbtn_info->long_time) +/* repeat_time */ +#define MFBD_REPEAT_TIME_IN_FUC (_pbtn_info->repeat_time) +/* multiclick_time */ +#define MFBD_MULTICLICK_TIME_IN_FUC (_pbtn_info->multiclick_time) + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + + +#if MFBD_USE_TINY_BUTTON +/** + * @brief scan all tiny buttons, and report button event value if event happened. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None. + */ +void mfbd_tbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end) +{ + const mfbd_tbtn_info_t *_pbtn_info = _pbtn_info_start; + + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + if (_pbtn_group->is_btn_down_func(_pbtn_info->btn_index) != MFBD_BTN_STATE_UP) + { + if (_pbtn_info->btn->filter_count < (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count < ((MFBD_FILTER_TIME_IN_FUC) * 2)) + { + _pbtn_info->btn->filter_count++; + } + else + { + /* it means the button is down for over filter_time. */ + if (_pbtn_info->btn->state == MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_DOWN; + if (_pbtn_info->btn_down_code > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_down_code); + } + } + } + } + else + { + if (_pbtn_info->btn->filter_count > (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count != 0) + { + _pbtn_info->btn->filter_count--; + } + else + { + if (_pbtn_info->btn->state != MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + if (_pbtn_info->btn_up_code > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_up_code); + } + } + } + } + _pbtn_info++; + } +} + +/** + * @brief reset all tiny buttons' params. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None. + */ +void mfbd_tbtn_reset(const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end) +{ + const mfbd_tbtn_info_t *_pbtn_info = _pbtn_info_start; + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + _pbtn_info->btn->filter_count = 0; + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + + _pbtn_info++; + } +} + +#endif + + +#if MFBD_USE_NORMAL_BUTTON + +/** + * @brief scan all normal buttons, and report button event value if event happened. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None + */ +void mfbd_nbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end) +{ + const mfbd_nbtn_info_t *_pbtn_info = _pbtn_info_start; + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + if (_pbtn_group->is_btn_down_func(_pbtn_info->btn_index) != MFBD_BTN_STATE_UP) + { + if (_pbtn_info->btn->filter_count < (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count < ((MFBD_FILTER_TIME_IN_FUC) * 2)) + { + _pbtn_info->btn->filter_count++; + } + else + { + /* it means the button is down for over filter_time. */ + if (_pbtn_info->btn->state == MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_DOWN; + /* clear long_count. */ + _pbtn_info->btn->long_count = 0; + if (_pbtn_info->btn_down_code > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_down_code); + } + } + else + { + if (((MFBD_LONG_TIME_IN_FUC) > 0) && (_pbtn_info->btn_long_code != 0)) + { + /* if long_time is 0 or long_code is 0, disable long and repeat check. */ + if (_pbtn_info->btn->long_count < (MFBD_LONG_TIME_IN_FUC)) + { + _pbtn_info->btn->long_count++; + if (_pbtn_info->btn->long_count >= (MFBD_LONG_TIME_IN_FUC)) + { + /* it means the button is down for over long_time. */ + _pbtn_info->btn->state = MFBD_BTN_STATE_LONG; + _pbtn_info->btn->repeat_count = 0; /* long event has happened, clear repeat_count. */ + _pbtn_group->btn_value_report(_pbtn_info->btn_long_code); + } + } + else + { + if (((MFBD_REPEAT_TIME_IN_FUC) > 0) && (_pbtn_info->btn_down_code != 0)) + { + _pbtn_info->btn->repeat_count++; + if (_pbtn_info->btn->repeat_count >= (MFBD_REPEAT_TIME_IN_FUC)) + { + /* repeat event has happened, clear repeat_count. */ + _pbtn_info->btn->repeat_count = 0; + _pbtn_group->btn_value_report(_pbtn_info->btn_down_code); + } + } + } + } + } + } + } + else + { + if (_pbtn_info->btn->filter_count > (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count != 0) + { + _pbtn_info->btn->filter_count--; + } + else + { + if (_pbtn_info->btn->state != MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + if (_pbtn_info->btn_up_code > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_up_code); + } + } + } + } + _pbtn_info++; + } +} + +/** + * @brief reset all normal buttons' params. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None. + */ +void mfbd_nbtn_reset(const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end) +{ + const mfbd_nbtn_info_t *_pbtn_info = _pbtn_info_start; + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + _pbtn_info->btn->filter_count = 0; + _pbtn_info->btn->long_count = 0; + _pbtn_info->btn->repeat_count = 0; + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + + _pbtn_info++; + } +} + +#endif + + +#if MFBD_USE_MULTIFUCNTION_BUTTON + +/** + * @brief scan all multi-function buttons, and report button event value if event happened. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None. + */ +void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end) +{ + const mfbd_mbtn_info_t *_pbtn_info = _pbtn_info_start; + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + + if (_pbtn_group->is_btn_down_func(_pbtn_info->btn_index) != MFBD_BTN_STATE_UP) + { + if (_pbtn_info->btn->filter_count < (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count < ((MFBD_FILTER_TIME_IN_FUC) * 2)) + { + _pbtn_info->btn->filter_count++; + } + else + { + /* it means the button is down for over filter_time. */ + if (_pbtn_info->btn->state == MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_DOWN; + /* clear long_count. */ + _pbtn_info->btn->long_count = 0; + if (_pbtn_info->btn_down_code[_pbtn_info->btn->multiclick_state] > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_down_code[_pbtn_info->btn->multiclick_state]); + } + } + else + { + if (_pbtn_info->btn->multiclick_state == 0) + { + if (((MFBD_LONG_TIME_IN_FUC) > 0) && (_pbtn_info->btn_long_code != 0)) + { + /* if long_time is 0 or long_code is 0, disable long and repeat check. */ + if (_pbtn_info->btn->long_count < (MFBD_LONG_TIME_IN_FUC)) + { + _pbtn_info->btn->long_count++; + if (_pbtn_info->btn->long_count >= (MFBD_LONG_TIME_IN_FUC)) + { + /* it means the button is down for over long_time. */ + _pbtn_info->btn->state = MFBD_BTN_STATE_LONG; + _pbtn_info->btn->repeat_count = 0; /* long event has happened, clear repeat_count. */ + _pbtn_group->btn_value_report(_pbtn_info->btn_long_code); + } + } + else + { + if (((MFBD_REPEAT_TIME_IN_FUC) > 0) && (_pbtn_info->btn_down_code[0] != 0)) + { + _pbtn_info->btn->repeat_count++; + if (_pbtn_info->btn->repeat_count >= (MFBD_REPEAT_TIME_IN_FUC)) + { + /* repeat event has happened, clear repeat_count. */ + _pbtn_info->btn->repeat_count = 0; + _pbtn_group->btn_value_report(_pbtn_info->btn_down_code[0]); + } + } + } + } + } + } + } + } + else + { + if (_pbtn_info->btn->filter_count > (MFBD_FILTER_TIME_IN_FUC)) + { + _pbtn_info->btn->filter_count = (MFBD_FILTER_TIME_IN_FUC); + } + else if (_pbtn_info->btn->filter_count != 0) + { + _pbtn_info->btn->filter_count--; + } + else + { + if (_pbtn_info->btn->state != MFBD_BTN_STATE_UP) + { + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + if (_pbtn_info->btn_up_code > 0) + { + _pbtn_group->btn_value_report(_pbtn_info->btn_up_code); + } + + /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */ + if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0) \ + && (_pbtn_info->btn->multiclick_state < _pbtn_info->max_multiclick_state) \ + && (!((((MFBD_LONG_TIME_IN_FUC) > 0) && (_pbtn_info->btn_long_code != 0)) && (_pbtn_info->btn->long_count >= (MFBD_LONG_TIME_IN_FUC))))) + { + _pbtn_info->btn->multiclick_state++; + _pbtn_info->btn->multiclick_count = 0; + } + else + { + /* over max multi-click times or (long event and repeat event) happened, reset to 0. */ + _pbtn_info->btn->multiclick_state = 0; + } + } + else + { + if (_pbtn_info->btn->multiclick_state != 0) + { + _pbtn_info->btn->multiclick_count++; + if (_pbtn_info->btn->multiclick_count >= (MFBD_MULTICLICK_TIME_IN_FUC)) + { + _pbtn_info->btn->multiclick_state = 0; + } + } + } + } + } + _pbtn_info++; + } +} + +/** + * @brief reset all multi-function buttons' params. + * + * @param _pbtn_group is a pointer of mfbd_group_t. + * + * @return None. + */ +void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end) +{ + const mfbd_mbtn_info_t *_pbtn_info = _pbtn_info_start; + while (1) + { + if (_pbtn_info_end <= _pbtn_info) + { + break; + } + _pbtn_info->btn->filter_count = 0; + _pbtn_info->btn->long_count = 0; + _pbtn_info->btn->multiclick_count = 0; + _pbtn_info->btn->multiclick_state = 0; + _pbtn_info->btn->repeat_count = 0; + _pbtn_info->btn->state = MFBD_BTN_STATE_UP; + + _pbtn_info++; + } +} + +#endif + +#endif /*MFBD_USE_SECTION_DEFINITION*/ diff --git a/mfbd_sd.h b/mfbd_sd.h new file mode 100644 index 0000000..5edb677 --- /dev/null +++ b/mfbd_sd.h @@ -0,0 +1,675 @@ +/* + * Copyright (c) 2022-2023, smartmx + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-03 smartmx the first version, Multi-Function Button Dectection with Section Definition. + * + */ + +#ifndef _MFBD_SD_H_ +#define _MFBD_SD_H_ + +#include "mfbd_cfg.h" + +#if MFBD_USE_SECTION_DEFINITION + +typedef enum +{ + MFBD_BTN_STATE_UP = 0, + MFBD_BTN_STATE_DOWN, + MFBD_BTN_STATE_LONG, +} MFBD_BTN_STATE_t; + +//#define __CC_ARM +//#define __IAR_SYSTEMS_ICC__ +//#define __GNUC__ + +#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */ +#define __MFBD_SECTION(x) __attribute__((section(x))) +#define MFBD_USED __attribute__((used)) +#define _MFBD_SECTION_START(X) X##$$Base +#define _MFBD_SECTION_END(X) X##$$Limit +#elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */ +#define __MFBD_SECTION(x) @ x +#define MFBD_USED __root +#define _MFBD_SECTION_START(X) __section_begin(#X) +#define _MFBD_SECTION_END(X) __section_end(#X) +#elif defined (__GNUC__) /* GNU GCC Compiler */ +#define __MFBD_SECTION(x) __attribute__((section(x))) +#define MFBD_USED __attribute__((used)) +#define _MFBD_SECTION_START(X) X##_start +#define _MFBD_SECTION_END(X) X##_end +#else +#error "not supported tool chain..." +#endif + +#define _MFBD_SECTION(X) __MFBD_SECTION(#X) +#define MFBD_SECTION(GROUP, BTN_KIND) _MFBD_SECTION(GROUP##_##BTN_KIND) + +#define MFBD_SECTION_START(GROUP, BTN_KIND) _MFBD_SECTION_START(GROUP##_##BTN_KIND) +#define MFBD_SECTION_END(GROUP, BTN_KIND) _MFBD_SECTION_END(GROUP##_##BTN_KIND) + + +/* tiny button definitions, tiny button functions only support down and up event. */ +typedef struct _mfbd_tiny_btn_struct +{ + mfbd_btn_count_t filter_count; /* filter time count when button state changed. */ + unsigned char state; /* the state of button, up or down. */ +} mfbd_tbtn_t; + +#if MFBD_PARAMS_SAME_IN_GROUP + +typedef struct _mfbd_tbtn_info_struct +{ + mfbd_tbtn_t *btn; /* a pointer to mfbd_tbtn_t. */ + mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ +} mfbd_tbtn_info_t; + +#else + +typedef struct _mfbd_tbtn_info_struct +{ + mfbd_tbtn_t *btn; /* a pointer to mfbd_tbtn_t. */ + mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ +} mfbd_tbtn_info_t; + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +#if MFBD_PARAMS_SAME_IN_GROUP + +#define MFBD_TBTN_DEFINE(GROUP, NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE) \ + MFBD_USED mfbd_tbtn_t NAME = { \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \ + &NAME, \ + BTN_DOWN_CODE, \ + BTN_UP_CODE, \ + BTN_INDEX, \ + } + +#define MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX) \ + MFBD_USED mfbd_tbtn_t NAME = { \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \ + &NAME, \ + NAME##_DOWN_CODE, \ + NAME##_UP_CODE, \ + BTN_INDEX, \ + } + +#else + +#define MFBD_TBTN_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) \ + MFBD_USED mfbd_tbtn_t NAME = { \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \ + &NAME, \ + BTN_DOWN_CODE, \ + BTN_UP_CODE, \ + FILTER_TIME, \ + BTN_INDEX, \ + } + +#define MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME) \ + MFBD_USED mfbd_tbtn_t NAME = { \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \ + &NAME, \ + NAME##_DOWN_CODE, \ + NAME##_UP_CODE, \ + FILTER_TIME, \ + BTN_INDEX, \ + } + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +#define MFBD_TBTN_EXTERN(NAME) extern mfbd_tbtn_t NAME + + +/* normal button definitions, normal button functions support down, up and long-press event. */ +typedef struct _mfbd_normal_btn_struct +{ + mfbd_btn_count_t filter_count; /* filter time count when button state changed. */ + mfbd_btn_count_t long_count; /* long time count when button still down. */ + mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */ + unsigned char state; /* the state of button, up or down. */ +} mfbd_nbtn_t; + +#if MFBD_PARAMS_SAME_IN_GROUP + +typedef struct _mfbd_nbtn_info_struct +{ + mfbd_nbtn_t *btn; /* a pointer to mfbd_nbtn_t. */ + mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code instead. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ +} mfbd_nbtn_info_t; + +#else + +typedef struct _mfbd_nbtn_info_struct +{ + mfbd_nbtn_t *btn; /* a pointer to mfbd_nbtn_t. */ + mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */ + mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */ + mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */ + mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code instead. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ +} mfbd_nbtn_info_t; + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + + +#if MFBD_PARAMS_SAME_IN_GROUP + +#define MFBD_NBTN_DEFINE(GROUP, NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \ + MFBD_USED mfbd_nbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \ + &NAME, \ + BTN_DOWN_CODE, \ + BTN_UP_CODE, \ + BTN_LONG_CODE, \ + BTN_INDEX, \ + } + +#define MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX) \ + mfbd_nbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \ + &NAME, \ + NAME##_DOWN_CODE, \ + NAME##_UP_CODE, \ + NAME##_LONG_CODE, \ + BTN_INDEX, \ + } + +#else + +#define MFBD_NBTN_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \ + mfbd_nbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \ + &NAME, \ + FILTER_TIME, \ + REPEAT_TIME, \ + LONG_TIME, \ + BTN_DOWN_CODE, \ + BTN_UP_CODE, \ + BTN_LONG_CODE, \ + BTN_INDEX, \ + } + +#define MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) \ + mfbd_nbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \ + &NAME, \ + FILTER_TIME, \ + REPEAT_TIME, \ + LONG_TIME, \ + NAME##_DOWN_CODE, \ + NAME##_UP_CODE, \ + NAME##_LONG_CODE, \ + BTN_INDEX, \ + } + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +#define MFBD_NBTN_EXTERN(NAME) extern mfbd_nbtn_t NAME + + +/* multi-function button definitions, multi-function button functions support down, up, long-press and multi-click event. */ + +/* + * @Note: + * repeat_count and long_count are conflict to multi-click. + * repeat_count and long_count only check in the first button down event, and will disable in next multi-click event. + * also, if repeat_count and long_count event has happened in the first down event, it will reset multiclick_state. + */ +typedef struct _mfbd_multifuction_btn_struct +{ + mfbd_btn_count_t filter_count; /* filter time count when button state changed. */ + mfbd_btn_count_t long_count; /* long time count when button still down. */ + mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */ + mfbd_btn_count_t multiclick_count; /* multi-click time count when button is up. */ + unsigned char multiclick_state; /* multi-click count when button is in multi-click state. */ + unsigned char state; /* the state of button, up or down. */ +} mfbd_mbtn_t; + +#if MFBD_PARAMS_SAME_IN_GROUP + +typedef struct _mfbd_mbtn_info_struct +{ + mfbd_mbtn_t *btn; /* a pointer to mfbd_mbtn_t. */ + const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code[0] instead. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ + unsigned char max_multiclick_state; /* max multiclick states. */ +} mfbd_mbtn_info_t; + +#else + +typedef struct _mfbd_mbtn_info_struct +{ + mfbd_mbtn_t *btn; /* a pointer to mfbd_mbtn_t. */ + const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */ + mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */ + mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */ + mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */ + mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */ + mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */ + mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code[0] instead. */ + mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */ + unsigned char max_multiclick_state; /* max multiclick states. */ +} mfbd_mbtn_info_t; + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +#if MFBD_PARAMS_SAME_IN_GROUP + +#define MFBD_MBTN_DEFINE(GROUP, NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) \ + static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \ + mfbd_mbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \ + &NAME, \ + NAME##_down_codes, \ + BTN_UP_CODE, \ + BTN_LONG_CODE, \ + BTN_INDEX, \ + MAX_MULTICLICK_STATE, \ + } + +#define MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, MAX_MULTICLICK_STATE) \ + mfbd_mbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \ + &NAME, \ + NAME##_DOWN_CODES, \ + NAME##_UP_CODE, \ + NAME##_LONG_CODE, \ + BTN_INDEX, \ + MAX_MULTICLICK_STATE, \ + } + +#else + +#define MFBD_MBTN_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) \ + static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \ + mfbd_mbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \ + &NAME, \ + NAME##_down_codes, \ + FILTER_TIME, \ + REPEAT_TIME, \ + LONG_TIME, \ + MULTICLICK_TIME, \ + BTN_UP_CODE, \ + BTN_LONG_CODE, \ + BTN_INDEX, \ + MAX_MULTICLICK_STATE, \ + } + +#define MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE) \ + mfbd_mbtn_t NAME = { \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + }; \ + MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \ + &NAME, \ + NAME##_DOWN_CODES, \ + FILTER_TIME, \ + REPEAT_TIME, \ + LONG_TIME, \ + MULTICLICK_TIME, \ + NAME##_UP_CODE, \ + NAME##_LONG_CODE, \ + BTN_INDEX, \ + MAX_MULTICLICK_STATE, \ + } + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +#define MFBD_MBTN_EXTERN(NAME) extern mfbd_mbtn_t NAME + + +/* mfbd group struct */ +typedef struct _mfbd_group_struct +{ + /* used to read whether button is down. */ + unsigned char (*is_btn_down_func)(mfbd_btn_index_t btn_index); + + /* used to report btn_value, must have a legal value, must not be NULL. */ + void (*btn_value_report)(mfbd_btn_code_t btn_value); + + /* if set MFBD_PARAMS_SAME_IN_GROUP to 1, all btns in group has same params. */ +#if MFBD_PARAMS_SAME_IN_GROUP + +#if MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON + mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */ +#endif /* MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */ + +#if MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON + + mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */ + + mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */ + +#endif /* MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */ + +#if MFBD_USE_MULTIFUCNTION_BUTTON + + mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */ + +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ + +#endif + +#if MFBD_USE_BTN_SCAN_PRE_FUNC + /* prepare function when start to scan buttons for each group. */ + void (*btn_scan_prepare)(void); +#endif + +#if MFBD_USE_BTN_SCAN_AFTER_FUNC + /* function after scanning buttons for each group. */ + void (*btn_scan_after)(void); +#endif + +} mfbd_group_t; + +#define MFBD_GROUP_NAME(GROUP) mfbd_group_##GROUP +#define MFBD_GROUP_EXTERN(GROUP) extern const mfbd_group_t MFBD_GROUP_NAME(GROUP) + +#define MFBD_GROUP_DEFINE(GROUP, IS_BTN_DOWN_FUNC, BTN_VALUE_REPORT_FUNC, ...) \ + const mfbd_group_t MFBD_GROUP_NAME(GROUP) = { \ + IS_BTN_DOWN_FUNC, \ + BTN_VALUE_REPORT_FUNC, \ + __VA_ARGS__ \ + } + +extern void mfbd_tbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end); +extern void mfbd_tbtn_reset(const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end); + +extern void mfbd_nbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end); +extern void mfbd_nbtn_reset(const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end); + +extern void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end); +extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end); + +#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */ + +#if MFBD_USE_TINY_BUTTON +#define MFBD_GROUP_SCAN_TBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, tbtn); \ + extern const int MFBD_SECTION_END(GROUP, tbtn); \ + mfbd_tbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, tbtn)), &(MFBD_SECTION_END(GROUP, tbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_TBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, tbtn); \ + extern const int MFBD_SECTION_END(GROUP, tbtn); \ + mfbd_tbtn_reset(&(MFBD_SECTION_START(GROUP, tbtn)), &(MFBD_SECTION_END(GROUP, tbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_TBTN(GROUP) do{} while(0) +#endif + +#if MFBD_USE_NORMAL_BUTTON +#define MFBD_GROUP_SCAN_NBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, nbtn); \ + extern const int MFBD_SECTION_END(GROUP, nbtn); \ + mfbd_nbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, nbtn)), &(MFBD_SECTION_END(GROUP, nbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_NBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, nbtn); \ + extern const int MFBD_SECTION_END(GROUP, nbtn); \ + mfbd_nbtn_reset(&(MFBD_SECTION_START(GROUP, nbtn)), &(MFBD_SECTION_END(GROUP, nbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0) +#endif + +#if MFBD_USE_MULTIFUCNTION_BUTTON +#define MFBD_GROUP_SCAN_MBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, mbtn); \ + extern const int MFBD_SECTION_END(GROUP, mbtn); \ + mfbd_mbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, mbtn)), &(MFBD_SECTION_END(GROUP, mbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_MBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, mbtn); \ + extern const int MFBD_SECTION_END(GROUP, mbtn); \ + mfbd_mbtn_reset(&(MFBD_SECTION_START(GROUP, mbtn)), &(MFBD_SECTION_END(GROUP, mbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0) +#endif + +#elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */ + +#if MFBD_USE_TINY_BUTTON +#define MFBD_GROUP_SCAN_TBTN(GROUP) \ + do \ + { \ + mfbd_tbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, tbtn), MFBD_SECTION_END(GROUP, tbtn)); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0) +#endif +#if MFBD_USE_NORMAL_BUTTON +#define MFBD_GROUP_SCAN_NBTN(GROUP) \ + do \ + { \ + mfbd_nbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, nbtn), MFBD_SECTION_END(GROUP, nbtn)); \ + } while (0) +#define MFBD_GROUP_RESET_NBTN(GROUP) \ + do \ + { \ + mfbd_nbtn_reset(MFBD_SECTION_START(GROUP, nbtn), MFBD_SECTION_END(GROUP, nbtn)); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0) +#endif +#if MFBD_USE_MULTIFUCNTION_BUTTON +#define MFBD_GROUP_SCAN_MBTN(GROUP) \ + do \ + { \ + mfbd_mbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, mbtn), MFBD_SECTION_END(GROUP, mbtn)); \ + } while (0) +#define MFBD_GROUP_RESET_MBTN(GROUP) \ + do \ + { \ + mfbd_mbtn_reset(MFBD_SECTION_START(GROUP, mbtn), MFBD_SECTION_END(GROUP, mbtn)); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0) +#endif + +#elif defined (__GNUC__) /* GNU GCC Compiler */ + +#if MFBD_USE_TINY_BUTTON +#define MFBD_GROUP_SCAN_TBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, tbtn); \ + extern const int MFBD_SECTION_END(GROUP, tbtn); \ + mfbd_tbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_TBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, tbtn); \ + extern const int MFBD_SECTION_END(GROUP, tbtn); \ + mfbd_tbtn_reset((const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_TBTN(GROUP) do{} while(0) +#endif + +#if MFBD_USE_NORMAL_BUTTON +#define MFBD_GROUP_SCAN_NBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, nbtn); \ + extern const int MFBD_SECTION_END(GROUP, nbtn); \ + mfbd_nbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_NBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, nbtn); \ + extern const int MFBD_SECTION_END(GROUP, nbtn); \ + mfbd_nbtn_reset((const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0) +#endif + +#if MFBD_USE_MULTIFUCNTION_BUTTON +#define MFBD_GROUP_SCAN_MBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, mbtn); \ + extern const int MFBD_SECTION_END(GROUP, mbtn); \ + mfbd_mbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \ + } while (0) +#define MFBD_GROUP_RESET_MBTN(GROUP) \ + do \ + { \ + extern const int MFBD_SECTION_START(GROUP, mbtn); \ + extern const int MFBD_SECTION_END(GROUP, mbtn); \ + mfbd_mbtn_reset((const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \ + } while (0) +#else +#define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0) +#define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0) +#endif + +#else +#error "not supported tool chain..." +#endif + +#if MFBD_USE_BTN_SCAN_PRE_FUNC +#define MFBD_GROUP_SCAN_PREPARE(GROUP) \ + do \ + { \ + if(MFBD_GROUP_NAME(GROUP).btn_scan_prepare!= NULL) \ + { \ + MFBD_GROUP_NAME(GROUP).btn_scan_prepare(); \ + } \ + } while(0) +#else +#define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) +#endif /* MFBD_USE_BTN_SCAN_PRE_FUNC */ + +#if MFBD_USE_BTN_SCAN_AFTER_FUNC +#define MFBD_GROUP_SCAN_AFTER(GROUP) \ + do \ + { \ + if(MFBD_GROUP_NAME(GROUP).btn_scan_after!= NULL) \ + { \ + MFBD_GROUP_NAME(GROUP).btn_scan_after(); \ + } \ + } while(0) +#else +#define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) +#endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */ + +#define MFBD_GROUP_SCAN(GROUP) \ + do \ + { \ + MFBD_GROUP_SCAN_PREPARE(GROUP); \ + MFBD_GROUP_SCAN_TBTN(GROUP); \ + MFBD_GROUP_SCAN_NBTN(GROUP); \ + MFBD_GROUP_SCAN_MBTN(GROUP); \ + MFBD_GROUP_SCAN_AFTER(GROUP); \ + } while (0) + +#define MFBD_GROUP_RESET(GROUP) \ + do \ + { \ + MFBD_GROUP_RESET_TBTN(GROUP); \ + MFBD_GROUP_RESET_NBTN(GROUP); \ + MFBD_GROUP_RESET_MBTN(GROUP); \ + } while (0) + +#endif /*MFBD_USE_SECTION_DEFINITION*/ + +#endif From 76b69324d4e90d7cf05991c75c4dcead107d060d Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Mon, 3 Jul 2023 22:10:11 +0800 Subject: [PATCH 2/6] some fix --- README.md | 19 +++++++++++++++++++ mfbd_sd.h | 5 +---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aa2d583..87ae1a7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,16 @@ MFBD尽可能的减少了RAM的使用,将能保存在Flash中的参数都保 MFBD通过类似电脑对按键的处理方式,将每个按键的不同操作分配不同的键值。 同时mfbd采用了回调函数的机制,通过回调函数将键值上报到上层应用程序,当然用户也可以直接在回调函数中进行操作。 +## MFBD版本 + +MFBD有传统定义方式和利用编译器特性的段定义(Section-Definition)方式。 +使用段定义方式将会极大程度减少代码编写量,但是会受限于编译器,目前仅支持`Keil`,`IAR`,`GCC`。 +通过配置`mfbd_cfg.h`中的`MFBD_USE_SECTION_DEFINITION`为`0`或`非0`,为`非0`时即可启用段定义。即使用`mfbd_sd.c`和`mfbd_sd.h`中的API。 + +普通定义请看[如下章节](#mfbd-button定义) + +段定义请看[如下章节](#mfbd段定义) + ## MFBD移植和配置 MFBD移植只需将文件添加到工程目录即可,配置项都已经汇总到mfbd_cfg.h中: @@ -389,6 +399,15 @@ extern void mfbd_group_scan(const mfbd_group_t *_pbtn_group); extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); ``` +## MFBD段定义 + +段定义(Section-Definition) + +### 段定义调用按键检测 + +```c +``` + ## 移植使用示例工程 MFBD提供了下面的测试例程,如果你使用其他开发板和其他RTOS,可以参考例程移植即可。 diff --git a/mfbd_sd.h b/mfbd_sd.h index 5edb677..617c7af 100644 --- a/mfbd_sd.h +++ b/mfbd_sd.h @@ -23,10 +23,6 @@ typedef enum MFBD_BTN_STATE_LONG, } MFBD_BTN_STATE_t; -//#define __CC_ARM -//#define __IAR_SYSTEMS_ICC__ -//#define __GNUC__ - #if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */ #define __MFBD_SECTION(x) __attribute__((section(x))) #define MFBD_USED __attribute__((used)) @@ -652,6 +648,7 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd #define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */ +/* this in a example for how to scan or reset the mfbd group, if some group has not all btn types, you should write code by youself. */ #define MFBD_GROUP_SCAN(GROUP) \ do \ { \ From c23995d46bb7c8414b67707eec0d67ea4497dbba Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Mon, 3 Jul 2023 22:22:59 +0800 Subject: [PATCH 3/6] Update README.md --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 87ae1a7..e2d5e01 100644 --- a/README.md +++ b/README.md @@ -401,13 +401,52 @@ extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); ## MFBD段定义 -段定义(Section-Definition) +段定义(Section-Definition)是程序编译期间会将不同的程序内容放到不同的程序段中,再通过链接器链接为固件。 + +### GROUP命名和其他对应名称关系 + +### MDK和IAR编译器使用方法 + +MDK和IAR中都在软件内部进行更改了代码编译后的链接操作,可以很方便的使用,无需修改工程文件。 + +### GCC使用方法 ### 段定义调用按键检测 +由于使用了段定义,所以程序无法判断一个组是否有所有的按键种类。所以可能会出错,此时需要通过自行调整检测宏来进行按键检测。 + +默认的按键扫描宏如下: + ```c +#define MFBD_GROUP_SCAN(GROUP) \ + do \ + { \ + MFBD_GROUP_SCAN_PREPARE(GROUP); \ + MFBD_GROUP_SCAN_TBTN(GROUP); \ + MFBD_GROUP_SCAN_NBTN(GROUP); \ + MFBD_GROUP_SCAN_MBTN(GROUP); \ + MFBD_GROUP_SCAN_AFTER(GROUP); \ + } while (0) ``` +如果在`mfbd_cfg.h`中使能了`mbtn`,但是这个组又没有用到`mbtn`,那么就会出错,因为程序中没有`mbtn`对应的这个段。这时,自行将上述宏复制到程序中: + +```c + do + { + MFBD_GROUP_SCAN_PREPARE(GROUP); + MFBD_GROUP_SCAN_TBTN(GROUP); + MFBD_GROUP_SCAN_NBTN(GROUP); + MFBD_GROUP_SCAN_AFTER(GROUP); + } while (0) +``` + +这样就可以进行正确的通过编译了。 + +### 段定义调用按键复位 + +和段定义调用按键检测一样,需要自行调整程序。 + ## 移植使用示例工程 MFBD提供了下面的测试例程,如果你使用其他开发板和其他RTOS,可以参考例程移植即可。 From 03bfb4ff3f1ba5fda1b45de44e9e92aea0591dc3 Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Tue, 4 Jul 2023 06:12:28 +0800 Subject: [PATCH 4/6] update some comments --- README.md | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++- mfbd_sd.h | 6 ++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e2d5e01..b0bfd81 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ MFBD有传统定义方式和利用编译器特性的段定义(Section-Definiti 段定义请看[如下章节](#mfbd段定义) +两者之间程序不兼容,需要重新写程序。 + ## MFBD移植和配置 MFBD移植只需将文件添加到工程目录即可,配置项都已经汇总到mfbd_cfg.h中: @@ -405,12 +407,95 @@ extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); ### GROUP命名和其他对应名称关系 +按键依靠组名分类,同样的组必须在一块,所以,使用段定义时,必须使用宏定义的方式来定义按键。 +首先需要给组起一个名字,例如:`test_btns`。 + +那么通过以下定义: + +```c +#define MFBD_GROUP_NAME(GROUP) mfbd_group_##GROUP +#define MFBD_GROUP_EXTERN(GROUP) extern const mfbd_group_t MFBD_GROUP_NAME(GROUP) +``` + +程序中真实的组名为`mfbd_group_test_btns` + +使用`MFBD_GROUP_DEFINE`宏不需要考虑名称,他里面自动生成名字: + +```c +#define MFBD_GROUP_DEFINE(GROUP, IS_BTN_DOWN_FUNC, BTN_VALUE_REPORT_FUNC, ...) \ + const mfbd_group_t MFBD_GROUP_NAME(GROUP) = { \ + IS_BTN_DOWN_FUNC, \ + BTN_VALUE_REPORT_FUNC, \ + __VA_ARGS__ \ + } +``` + +同样的,通过以下宏定义,将给每组按键中不同的按键类型定义不同的段名(section name): + +```c +#define _MFBD_SECTION(X) __MFBD_SECTION(#X) +#define MFBD_SECTION(GROUP, BTN_KIND) _MFBD_SECTION(GROUP##_##BTN_KIND) + +#define MFBD_SECTION_START(GROUP, BTN_KIND) _MFBD_SECTION_START(GROUP##_##BTN_KIND) +#define MFBD_SECTION_END(GROUP, BTN_KIND) _MFBD_SECTION_END(GROUP##_##BTN_KIND) +``` + +例如,按键组为`test_btns`,则默认: + +组内的`tbtn`对应的段名为`test_btns_tbtn` +组内的`nbtn`对应的段名为`test_btns_nbtn` +组内的`mbtn`对应的段名为`test_btns_mbtn` + ### MDK和IAR编译器使用方法 MDK和IAR中都在软件内部进行更改了代码编译后的链接操作,可以很方便的使用,无需修改工程文件。 ### GCC使用方法 +GUN gcc工程需要在工程的ld文件中找到`rodata`的初始化链接代码。并添加ld文件指定的函数。 + +例如,按键组为`test_btns`,则默认: + +组内的`tbtn`对应的段名开始地址为`test_btns_tbtn_start`,结束地址为`test_btns_tbtn_end` +组内的`nbtn`对应的段名为`test_btns_nbtn_start`,结束地址为`test_btns_nbtn_end` +组内的`mbtn`对应的段名为`test_btns_mbtn_start`,结束地址为`test_btns_mbtn_end` + +```ld + .text : + { + . = ALIGN(4); + KEEP(*(SORT_NONE(.handle_reset))) + *(.text) + *(.text.*) + + /* this is for tbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_tbtn_start = .); + KEEP(*(test_btns_tbtn*)) + PROVIDE(test_btns_tbtn_end = .); + + /* this is for nbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_nbtn_start = .); + KEEP(*(test_btns_nbtn*)) + PROVIDE(test_btns_nbtn_end = .); + + /* this is for mbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_mbtn_start = .); + KEEP(*(test_btns_mbtn*)) + PROVIDE(test_btns_mbtn_end = .); + + *(.rodata) + *(.rodata*) + *(.sdata2.*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH +``` + ### 段定义调用按键检测 由于使用了段定义,所以程序无法判断一个组是否有所有的按键种类。所以可能会出错,此时需要通过自行调整检测宏来进行按键检测。 @@ -429,7 +514,7 @@ MDK和IAR中都在软件内部进行更改了代码编译后的链接操作, } while (0) ``` -如果在`mfbd_cfg.h`中使能了`mbtn`,但是这个组又没有用到`mbtn`,那么就会出错,因为程序中没有`mbtn`对应的这个段。这时,自行将上述宏复制到程序中: +如果在`mfbd_cfg.h`中使能了`mbtn`,但是这个组又没有用到`mbtn`,那么就会出错,因为程序中没有`mbtn`对应的这个段。这时,自行将上述宏复制到程序中,删除没有用到的`MFBD_GROUP_SCAN_NBTN(GROUP);`即可: ```c do @@ -445,7 +530,29 @@ MDK和IAR中都在软件内部进行更改了代码编译后的链接操作, ### 段定义调用按键复位 -和段定义调用按键检测一样,需要自行调整程序。 +和段定义调用按键检测一样,需要自行调整程序,删除组内没有用到的按键复位函数宏。 + +默认的按键复位宏如下: + +```c +#define MFBD_GROUP_RESET(GROUP) \ + do \ + { \ + MFBD_GROUP_RESET_TBTN(GROUP); \ + MFBD_GROUP_RESET_NBTN(GROUP); \ + MFBD_GROUP_RESET_MBTN(GROUP); \ + } while (0) +``` + +如果在`mfbd_cfg.h`中使能了`mbtn`,但是这个组又没有用到`mbtn`,那么就会出错,因为程序中没有`mbtn`对应的这个段。这时,自行将上述宏复制到程序中,删除没有用到的`MFBD_GROUP_RESET_MBTN(GROUP);`即可: + +```c + do + { + MFBD_GROUP_RESET_TBTN(GROUP); + MFBD_GROUP_RESET_NBTN(GROUP); + } while (0) +``` ## 移植使用示例工程 diff --git a/mfbd_sd.h b/mfbd_sd.h index 617c7af..740b503 100644 --- a/mfbd_sd.h +++ b/mfbd_sd.h @@ -648,7 +648,11 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd #define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */ -/* this in a example for how to scan or reset the mfbd group, if some group has not all btn types, you should write code by youself. */ +/* + * @Note: + * this in a example for how to scan or reset the mfbd group, + * if some group has not all btn types, you should write code by youself. + */ #define MFBD_GROUP_SCAN(GROUP) \ do \ { \ From 19ae09e9d9c15925936c0bcc0ab649d123a73c2c Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Tue, 4 Jul 2023 07:55:44 +0800 Subject: [PATCH 5/6] fix some bugs --- examples/mfbd_demo_rtt.c | 89 ++++++++++++++++++++++++++++++++++++++++ mfbd_sd.h | 31 ++++++++------ 2 files changed, 107 insertions(+), 13 deletions(-) diff --git a/examples/mfbd_demo_rtt.c b/examples/mfbd_demo_rtt.c index b40df67..23c6c9e 100644 --- a/examples/mfbd_demo_rtt.c +++ b/examples/mfbd_demo_rtt.c @@ -10,12 +10,14 @@ * 2022-04-16 smartmx drop list definitions, use arraylist, each group has all btn types. * 2022-08-05 smartmx add reset params function. * 2022-08-15 smartmx fix bugs. + * 2023-07-03 smartmx add Section Definition option. * */ #include #include #include "mfbd.h" +#include "mfbd_sd.h" void bsp_btn_value_report(mfbd_btn_code_t btn_value); unsigned char bsp_btn_check(mfbd_btn_index_t btn_index); @@ -36,6 +38,81 @@ unsigned char bsp_btn_check(mfbd_btn_index_t btn_index); #define BTN_WK_UP GET_PIN(A, 0) #endif +#if MFBD_USE_SECTION_DEFINITION +/* use section definition. */ + +#if MFBD_PARAMS_SAME_IN_GROUP + +/* tbtn test */ +#if MFBD_USE_TINY_BUTTON +/* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ +MFBD_TBTN_DEFINE(test_btns, test_tbtn, 1, 0x1201, 0x1200); +#endif /* MFBD_USE_TINY_BUTTON */ + +/* nbtn test */ +#if MFBD_USE_NORMAL_BUTTON +/* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ +MFBD_NBTN_DEFINE(test_btns, test_nbtn1, 3, 0x1401, 0x1400, 0x1402); + +MFBD_NBTN_DEFINE(test_btns, test_nbtn, 2, 0x1301, 0x1300, 0x1301); +#endif /* MFBD_USE_NORMAL_BUTTON */ + +/* mbtn test */ +#if MFBD_USE_MULTIFUCNTION_BUTTON +/* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ +MFBD_MBTN_DEFINE(test_btns, test_mbtn, 4, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ + +#else + +/* tbtn test */ +#if MFBD_USE_TINY_BUTTON +/* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ +MFBD_TBTN_DEFINE(test_btns, test_tbtn, 1, 3, 0x1201, 0x1200); +#endif /* MFBD_USE_TINY_BUTTON */ + +/* nbtn test */ +#if MFBD_USE_NORMAL_BUTTON +/* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ +MFBD_NBTN_DEFINE(test_btns, test_nbtn1, 3, 3, 0, 150, 0x1401, 0x1400, 0x1402); + +MFBD_NBTN_DEFINE(test_btns, test_nbtn, 2, 3, 30, 150, 0x1301, 0x1300, 0x1301); +#endif /* MFBD_USE_NORMAL_BUTTON */ + +/* mbtn test */ +#if MFBD_USE_MULTIFUCNTION_BUTTON +/* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ +MFBD_MBTN_DEFINE(test_btns, test_mbtn, 4, 3, 30, 150, 75, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ + +//MFBD_GROUP_DEFINE(test_btns, bsp_btn_check, bsp_btn_value_report, 3, 30, 150, 75); +//MFBD_GROUP_DEFINE(test_btns, bsp_btn_check, bsp_btn_value_report); + +const mfbd_group_t MFBD_GROUP_NAME(test_btns) = { + bsp_btn_check, + bsp_btn_value_report, +#if MFBD_PARAMS_SAME_IN_GROUP + +#if MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON + 3, +#endif /* MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */ + +#if MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON + 30, + 150, +#endif /* MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */ + +#if MFBD_USE_MULTIFUCNTION_BUTTON + 75, +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ + +#endif /*MFBD_PARAMS_SAME_IN_GROUP*/ +}; + +#else + #if MFBD_PARAMS_SAME_IN_GROUP /* tbtn test */ @@ -130,6 +207,8 @@ const mfbd_group_t test_btn_group = }; +#endif /*MFBD_USE_SECTION_DEFINITION*/ + unsigned char bsp_btn_check(mfbd_btn_index_t btn_index) { switch (btn_index) @@ -173,7 +252,17 @@ static void mfbd_scan(void *arg) { while (1) { + #if MFBD_USE_SECTION_DEFINITION + /* use section definition. */ + + MFBD_GROUP_SCAN(test_btns); + + #else + mfbd_group_scan(&test_btn_group); /* scan button group */ + + #endif /*MFBD_USE_SECTION_DEFINITION*/ + rt_thread_mdelay(10); /* scan period: 10ms */ } } diff --git a/mfbd_sd.h b/mfbd_sd.h index 740b503..0d416f3 100644 --- a/mfbd_sd.h +++ b/mfbd_sd.h @@ -460,14 +460,14 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd { \ extern const int MFBD_SECTION_START(GROUP, tbtn); \ extern const int MFBD_SECTION_END(GROUP, tbtn); \ - mfbd_tbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, tbtn)), &(MFBD_SECTION_END(GROUP, tbtn))); \ + mfbd_tbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \ } while (0) #define MFBD_GROUP_RESET_TBTN(GROUP) \ do \ { \ extern const int MFBD_SECTION_START(GROUP, tbtn); \ extern const int MFBD_SECTION_END(GROUP, tbtn); \ - mfbd_tbtn_reset(&(MFBD_SECTION_START(GROUP, tbtn)), &(MFBD_SECTION_END(GROUP, tbtn))); \ + mfbd_tbtn_reset((const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \ } while (0) #else #define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0) @@ -480,14 +480,14 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd { \ extern const int MFBD_SECTION_START(GROUP, nbtn); \ extern const int MFBD_SECTION_END(GROUP, nbtn); \ - mfbd_nbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, nbtn)), &(MFBD_SECTION_END(GROUP, nbtn))); \ + mfbd_nbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \ } while (0) #define MFBD_GROUP_RESET_NBTN(GROUP) \ do \ { \ extern const int MFBD_SECTION_START(GROUP, nbtn); \ extern const int MFBD_SECTION_END(GROUP, nbtn); \ - mfbd_nbtn_reset(&(MFBD_SECTION_START(GROUP, nbtn)), &(MFBD_SECTION_END(GROUP, nbtn))); \ + mfbd_nbtn_reset((const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \ } while (0) #else #define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0) @@ -500,14 +500,14 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd { \ extern const int MFBD_SECTION_START(GROUP, mbtn); \ extern const int MFBD_SECTION_END(GROUP, mbtn); \ - mfbd_mbtn_scan(&(MFBD_GROUP_NAME(GROUP)), &(MFBD_SECTION_START(GROUP, mbtn)), &(MFBD_SECTION_END(GROUP, mbtn))); \ + mfbd_mbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \ } while (0) #define MFBD_GROUP_RESET_MBTN(GROUP) \ do \ { \ extern const int MFBD_SECTION_START(GROUP, mbtn); \ extern const int MFBD_SECTION_END(GROUP, mbtn); \ - mfbd_mbtn_reset(&(MFBD_SECTION_START(GROUP, mbtn)), &(MFBD_SECTION_END(GROUP, mbtn))); \ + mfbd_mbtn_reset((const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \ } while (0) #else #define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0) @@ -520,7 +520,12 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd #define MFBD_GROUP_SCAN_TBTN(GROUP) \ do \ { \ - mfbd_tbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, tbtn), MFBD_SECTION_END(GROUP, tbtn)); \ + mfbd_tbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_tbtn_info_t *)MFBD_SECTION_START(GROUP, tbtn), (const mfbd_tbtn_info_t *)MFBD_SECTION_END(GROUP, tbtn)); \ + } while (0) +#define MFBD_GROUP_RESET_TBTN(GROUP) \ + do \ + { \ + mfbd_tbtn_reset((const mfbd_tbtn_info_t *)MFBD_SECTION_START(GROUP, nbtn), (const mfbd_tbtn_info_t *)MFBD_SECTION_END(GROUP, nbtn)); \ } while (0) #else #define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0) @@ -529,12 +534,12 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd #define MFBD_GROUP_SCAN_NBTN(GROUP) \ do \ { \ - mfbd_nbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, nbtn), MFBD_SECTION_END(GROUP, nbtn)); \ + mfbd_nbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_nbtn_info_t *)MFBD_SECTION_START(GROUP, nbtn), (const mfbd_nbtn_info_t *)MFBD_SECTION_END(GROUP, nbtn)); \ } while (0) #define MFBD_GROUP_RESET_NBTN(GROUP) \ do \ { \ - mfbd_nbtn_reset(MFBD_SECTION_START(GROUP, nbtn), MFBD_SECTION_END(GROUP, nbtn)); \ + mfbd_nbtn_reset((const mfbd_nbtn_info_t *)MFBD_SECTION_START(GROUP, nbtn), (const mfbd_nbtn_info_t *)MFBD_SECTION_END(GROUP, nbtn)); \ } while (0) #else #define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0) @@ -544,12 +549,12 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd #define MFBD_GROUP_SCAN_MBTN(GROUP) \ do \ { \ - mfbd_mbtn_scan(&(MFBD_GROUP_NAME(GROUP)), MFBD_SECTION_START(GROUP, mbtn), MFBD_SECTION_END(GROUP, mbtn)); \ + mfbd_mbtn_scan((const mfbd_group_t *)&(MFBD_GROUP_NAME(GROUP)), (const mfbd_mbtn_info_t *)MFBD_SECTION_START(GROUP, mbtn), (const mfbd_mbtn_info_t *)MFBD_SECTION_END(GROUP, mbtn)); \ } while (0) #define MFBD_GROUP_RESET_MBTN(GROUP) \ do \ { \ - mfbd_mbtn_reset(MFBD_SECTION_START(GROUP, mbtn), MFBD_SECTION_END(GROUP, mbtn)); \ + mfbd_mbtn_reset((const mfbd_mbtn_info_t *)MFBD_SECTION_START(GROUP, mbtn), (const mfbd_mbtn_info_t *)MFBD_SECTION_END(GROUP, mbtn)); \ } while (0) #else #define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0) @@ -632,7 +637,7 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd } \ } while(0) #else -#define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) +#define MFBD_GROUP_SCAN_PREPARE(GROUP) do{} while(0) #endif /* MFBD_USE_BTN_SCAN_PRE_FUNC */ #if MFBD_USE_BTN_SCAN_AFTER_FUNC @@ -645,7 +650,7 @@ extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd } \ } while(0) #else -#define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) +#define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0) #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */ /* From 2719211d7fbbb430e1a85cc6d6322fc5da08a8ec Mon Sep 17 00:00:00 2001 From: CoderNotCute <30313912+smartmx@users.noreply.github.com> Date: Tue, 4 Jul 2023 21:01:06 +0800 Subject: [PATCH 6/6] update update demo and somecomments. --- README.md | 112 +++++++++++++++++++++--------------- examples/mfbd_demo_rtt.c | 121 +++++++++++++++++++++++++++++++++------ mfbd.c | 14 ++++- mfbd.h | 5 ++ mfbd_cfg.h | 8 +++ mfbd_sd.c | 14 ++++- mfbd_sd.h | 11 +++- 7 files changed, 217 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index b0bfd81..f13d8b3 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,9 @@ typedef uint32_t mfbd_btn_index_t; */ #define MFBD_PARAMS_SAME_IN_GROUP 1 +/* set MFBD_MULTICLICK_STATE_AUTO_RESET to 1 will auto set multiclick state to 0 when reach to max multicick state. */ +#define MFBD_MULTICLICK_STATE_AUTO_RESET 1 + ``` `mfbd_btn_code_t`:按键键值的类型。 @@ -87,6 +90,8 @@ typedef uint32_t mfbd_btn_index_t; `MFBD_PARAMS_SAME_IN_GROUP`:当所有按键的扫描滤波时间、长按时间、重复上报时间、连击释放时间一致的时候,可以将该宏置为`1`。此时,每个按键的info结构体中将不再存放上述事件参数,而把时间参数存放在group结构体中。当该选项使能的时候,无法在启用长按事件(long count)的时候单独禁用某个按键的重复上报事件(repeat count),但可以通过设置`repeat_time = 0`禁用全部按键的重复上报事件。 +`MFBD_MULTICLICK_STATE_AUTO_RESET`:当mbtn达到最大连击次数时,连击次数是否自动返回未连击状态。为`1`,则自动返回0状态,下次连击则返回按键连击0按键码,为`0`,则必须等带连击释放时间达到后,才会自动返回0状态,下次连击则返回按键连击最高状态按键码。 + ## MFBD按键事件 ### 单击事件 @@ -291,6 +296,22 @@ MFBD_MBTN_DEFAULT_DEFINE(NAME, ...); ```MFBD_MBTN_DEFAULT_DEFINE(HI, ...)```,将会默认使用```HI_UP_CODE```和```HI_LONG_CODE```作为按键值。所以程序中需要准备好该两个名称的按键值枚举变量或宏定义。另外MBTN需要提供一个变量名为```HI_DOWN_CODES```的按键值数组,作为多次连击的按键值。 +可以通过在枚举变量时,使用如下宏定义,来快速生成名称: + +```c +#define MFBD_DOWN_CODE_NAME(NAME) NAME##_DOWN_CODE /* when using tbtn/nbtn default define api, this is down-code name. */ +#define MFBD_UP_CODE_NAME(NAME) NAME##_UP_CODE /* when using tbtn/nbtn/mbtn default define api, this is up-code name. */ +#define MFBD_LONG_CODE_NAME(NAME) NAME##_LONG_CODE /* when using nbtn/mbtn default define api, this is long-code name. */ +``` + +mbtn需要提供数组来代表各种连击时发送的按键值,数组名参考下面的宏定义: + +```c +#define MFBD_DOWN_CODES_NAME(NAME) NAME##_DOWN_CODES /* when using mbtn default define api, this is long-codes name. */ + +mfbd_btn_code_t MFBD_DOWN_CODES_DEF(mbtn)[4] = {0x1501, 0x1511, 0x1521, 0x1531}; /* example */ +``` + ## MFBD 使用示例 这里使用上方MFBD定义示例中宏定义的方式定义按键进行操作 @@ -403,7 +424,7 @@ extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); ## MFBD段定义 -段定义(Section-Definition)是程序编译期间会将不同的程序内容放到不同的程序段中,再通过链接器链接为固件。 +段定义(Section-Definition)是程序编译期间会将不同的程序内容放到不同的程序段中,再通过链接器链接为固件。段定义同样也支持默认定义方式。 ### GROUP命名和其他对应名称关系 @@ -417,16 +438,16 @@ extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); #define MFBD_GROUP_EXTERN(GROUP) extern const mfbd_group_t MFBD_GROUP_NAME(GROUP) ``` -程序中真实的组名为`mfbd_group_test_btns` +程序中真实的变量组名为`mfbd_group_test_btns` -使用`MFBD_GROUP_DEFINE`宏不需要考虑名称,他里面自动生成名字: +使用`MFBD_GROUP_DEFINE`宏不需要考虑名称,宏定义里面会自动生成名字: ```c #define MFBD_GROUP_DEFINE(GROUP, IS_BTN_DOWN_FUNC, BTN_VALUE_REPORT_FUNC, ...) \ const mfbd_group_t MFBD_GROUP_NAME(GROUP) = { \ - IS_BTN_DOWN_FUNC, \ - BTN_VALUE_REPORT_FUNC, \ - __VA_ARGS__ \ + IS_BTN_DOWN_FUNC, \ + BTN_VALUE_REPORT_FUNC, \ + __VA_ARGS__ \ } ``` @@ -442,13 +463,15 @@ extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group); 例如,按键组为`test_btns`,则默认: -组内的`tbtn`对应的段名为`test_btns_tbtn` -组内的`nbtn`对应的段名为`test_btns_nbtn` -组内的`mbtn`对应的段名为`test_btns_mbtn` +组内的`tbtn`对应的段名为`test_btns_tbtn`。 + +组内的`nbtn`对应的段名为`test_btns_nbtn`。 + +组内的`mbtn`对应的段名为`test_btns_mbtn`。 ### MDK和IAR编译器使用方法 -MDK和IAR中都在软件内部进行更改了代码编译后的链接操作,可以很方便的使用,无需修改工程文件。 +MDK和IAR中都在软件内部进行更改了代码编译后的链接操作,可以很方便的使用,无需修改工程文件,直接使用宏定义即可。 ### GCC使用方法 @@ -461,44 +484,43 @@ GUN gcc工程需要在工程的ld文件中找到`rodata`的初始化链接代码 组内的`mbtn`对应的段名为`test_btns_mbtn_start`,结束地址为`test_btns_mbtn_end` ```ld - .text : - { - . = ALIGN(4); - KEEP(*(SORT_NONE(.handle_reset))) - *(.text) - *(.text.*) - - /* this is for tbtn in test_btns. */ - . = ALIGN(4); - PROVIDE(test_btns_tbtn_start = .); - KEEP(*(test_btns_tbtn*)) - PROVIDE(test_btns_tbtn_end = .); - - /* this is for nbtn in test_btns. */ - . = ALIGN(4); - PROVIDE(test_btns_nbtn_start = .); - KEEP(*(test_btns_nbtn*)) - PROVIDE(test_btns_nbtn_end = .); - - /* this is for mbtn in test_btns. */ - . = ALIGN(4); - PROVIDE(test_btns_mbtn_start = .); - KEEP(*(test_btns_mbtn*)) - PROVIDE(test_btns_mbtn_end = .); - - *(.rodata) - *(.rodata*) - *(.sdata2.*) - *(.glue_7) - *(.glue_7t) - *(.gnu.linkonce.t.*) - . = ALIGN(4); - } >FLASH AT>FLASH +.text : +{ + . = ALIGN(4); + KEEP(*(SORT_NONE(.handle_reset))) + *(.text) + *(.text.*) + + /* this is for tbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_tbtn_start = .); + KEEP(*(test_btns_tbtn*)) + PROVIDE(test_btns_tbtn_end = .); + + /* this is for nbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_nbtn_start = .); + KEEP(*(test_btns_nbtn*)) + PROVIDE(test_btns_nbtn_end = .); + + /* this is for mbtn in test_btns. */ + . = ALIGN(4); + PROVIDE(test_btns_mbtn_start = .); + KEEP(*(test_btns_mbtn*)) + PROVIDE(test_btns_mbtn_end = .); + + *(.rodata) + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t.*) + . = ALIGN(4); +} >FLASH AT>FLASH ``` ### 段定义调用按键检测 -由于使用了段定义,所以程序无法判断一个组是否有所有的按键种类。所以可能会出错,此时需要通过自行调整检测宏来进行按键检测。 +由于使用了段定义,所以程序无法判断一个组是否有所有的使能的按键种类。所以可能会出错,此时需要通过自行调整检测的宏来进行按键检测。 默认的按键扫描宏如下: @@ -526,8 +548,6 @@ GUN gcc工程需要在工程的ld文件中找到`rodata`的初始化链接代码 } while (0) ``` -这样就可以进行正确的通过编译了。 - ### 段定义调用按键复位 和段定义调用按键检测一样,需要自行调整程序,删除组内没有用到的按键复位函数宏。 diff --git a/examples/mfbd_demo_rtt.c b/examples/mfbd_demo_rtt.c index 23c6c9e..290db9f 100644 --- a/examples/mfbd_demo_rtt.c +++ b/examples/mfbd_demo_rtt.c @@ -19,6 +19,8 @@ #include "mfbd.h" #include "mfbd_sd.h" +#define MFBD_DEMO_USE_DEFAULT_DEFINE 1 /* set to 1, you can study how to use default define APIs. */ + void bsp_btn_value_report(mfbd_btn_code_t btn_value); unsigned char bsp_btn_check(mfbd_btn_index_t btn_index); @@ -38,6 +40,31 @@ unsigned char bsp_btn_check(mfbd_btn_index_t btn_index); #define BTN_WK_UP GET_PIN(A, 0) #endif +/* default definition example */ +#if MFBD_DEMO_USE_DEFAULT_DEFINE + +enum +{ + MFBD_DOWN_CODE_NAME(test_tbtn) = 0x1201, + MFBD_UP_CODE_NAME(test_tbtn) = 0x1200, + MFBD_LONG_CODE_NAME(test_tbtn) = 0x1202, + + MFBD_DOWN_CODE_NAME(test_nbtn) = 0x1301, + MFBD_UP_CODE_NAME(test_nbtn) = 0x1300, + MFBD_LONG_CODE_NAME(test_nbtn) = 0x1301, + + MFBD_DOWN_CODE_NAME(test_nbtn1) = 0x1401, + MFBD_UP_CODE_NAME(test_nbtn1) = 0x1400, + MFBD_LONG_CODE_NAME(test_nbtn1) = 0x1402, + + MFBD_UP_CODE_NAME(test_mbtn) = 0x1500, + MFBD_LONG_CODE_NAME(test_mbtn) = 0x1502, +}; + +mfbd_btn_code_t MFBD_DOWN_CODES_NAME(test_mbtn)[4] = {0x1501, 0x1511, 0x1521, 0x1531}; + +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ + #if MFBD_USE_SECTION_DEFINITION /* use section definition. */ @@ -45,45 +72,75 @@ unsigned char bsp_btn_check(mfbd_btn_index_t btn_index); /* tbtn test */ #if MFBD_USE_TINY_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX) */ +MFBD_TBTN_DEFAULT_DEFINE(test_btns, test_tbtn, 1); +#else /* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ MFBD_TBTN_DEFINE(test_btns, test_tbtn, 1, 0x1201, 0x1200); -#endif /* MFBD_USE_TINY_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_TINY_BUTTON */ /* nbtn test */ #if MFBD_USE_NORMAL_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) */ +MFBD_NBTN_DEFAULT_DEFINE(test_btns, test_nbtn1, 3); +MFBD_NBTN_DEFAULT_DEFINE(test_btns, test_nbtn, 2); +#else /* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ MFBD_NBTN_DEFINE(test_btns, test_nbtn1, 3, 0x1401, 0x1400, 0x1402); - MFBD_NBTN_DEFINE(test_btns, test_nbtn, 2, 0x1301, 0x1300, 0x1301); -#endif /* MFBD_USE_NORMAL_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_NORMAL_BUTTON */ /* mbtn test */ #if MFBD_USE_MULTIFUCNTION_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, MAX_MULTICLICK_STATE) */ +MFBD_MBTN_DEFAULT_DEFINE(test_btns, test_mbtn, 4, 3); +#else /* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ MFBD_MBTN_DEFINE(test_btns, test_mbtn, 4, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); -#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ #else /* tbtn test */ #if MFBD_USE_TINY_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME) */ +MFBD_TBTN_DEFAULT_DEFINE(test_btns, test_tbtn, 1, 3); +#else /* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ MFBD_TBTN_DEFINE(test_btns, test_tbtn, 1, 3, 0x1201, 0x1200); -#endif /* MFBD_USE_TINY_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_TINY_BUTTON */ /* nbtn test */ #if MFBD_USE_NORMAL_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) */ +MFBD_NBTN_DEFAULT_DEFINE(test_btns, test_nbtn1, 3, 3, 0, 150); +MFBD_NBTN_DEFAULT_DEFINE(test_btns, test_nbtn, 2, 3, 30, 150); +#else /* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ MFBD_NBTN_DEFINE(test_btns, test_nbtn1, 3, 3, 0, 150, 0x1401, 0x1400, 0x1402); - MFBD_NBTN_DEFINE(test_btns, test_nbtn, 2, 3, 30, 150, 0x1301, 0x1300, 0x1301); -#endif /* MFBD_USE_NORMAL_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_NORMAL_BUTTON */ /* mbtn test */ #if MFBD_USE_MULTIFUCNTION_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE) */ +MFBD_MBTN_DEFAULT_DEFINE(test_btns, test_mbtn, 4, 3, 30, 150, 75, 3); +#else /* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ MFBD_MBTN_DEFINE(test_btns, test_mbtn, 4, 3, 30, 150, 75, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); -#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ #endif /*MFBD_PARAMS_SAME_IN_GROUP*/ @@ -117,45 +174,75 @@ const mfbd_group_t MFBD_GROUP_NAME(test_btns) = { /* tbtn test */ #if MFBD_USE_TINY_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_TBTN_DEFAULT_DEFINE(NAME, BTN_INDEX) */ +MFBD_TBTN_DEFAULT_DEFINE(test_tbtn, 1); +#else /* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ MFBD_TBTN_DEFINE(test_tbtn, 1, 0x1201, 0x1200); -#endif /* MFBD_USE_TINY_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_TINY_BUTTON */ /* nbtn test */ #if MFBD_USE_NORMAL_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_NBTN_DEFAULT_DEFINE(NAME, BTN_INDEX) */ +MFBD_NBTN_DEFAULT_DEFINE(test_nbtn1, 3); +MFBD_NBTN_DEFAULT_DEFINE(test_nbtn, 2); +#else /* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ MFBD_NBTN_DEFINE(test_nbtn1, 3, 0x1401, 0x1400, 0x1402); - MFBD_NBTN_DEFINE(test_nbtn, 2, 0x1301, 0x1300, 0x1301); -#endif /* MFBD_USE_NORMAL_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_NORMAL_BUTTON */ /* mbtn test */ #if MFBD_USE_MULTIFUCNTION_BUTTON -/* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_MBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE) */ +MFBD_MBTN_DEFAULT_DEFINE(test_mbtn, 4, 3); +#else +/* FBD_MBTN_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ MFBD_MBTN_DEFINE(test_mbtn, 4, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); -#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ #else /* tbtn test */ #if MFBD_USE_TINY_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_TBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME) */ +MFBD_TBTN_DEFAULT_DEFINE(test_tbtn, 1, 3); +#else /* MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) */ MFBD_TBTN_DEFINE(test_tbtn, 1, 3, 0x1201, 0x1200); -#endif /* MFBD_USE_TINY_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_TINY_BUTTON */ /* nbtn test */ #if MFBD_USE_NORMAL_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_NBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) */ +MFBD_NBTN_DEFAULT_DEFINE(test_nbtn1, 3, 3, 0, 150); +MFBD_NBTN_DEFAULT_DEFINE(test_nbtn, 2, 3, 30, 150); +#else /* MFBD_NBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) */ MFBD_NBTN_DEFINE(test_nbtn1, 3, 3, 0, 150, 0x1401, 0x1400, 0x1402); - MFBD_NBTN_DEFINE(test_nbtn, 2, 3, 30, 150, 0x1301, 0x1300, 0x1301); -#endif /* MFBD_USE_NORMAL_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_NORMAL_BUTTON */ /* mbtn test */ #if MFBD_USE_MULTIFUCNTION_BUTTON +#if MFBD_DEMO_USE_DEFAULT_DEFINE +/* MFBD_MBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE) */ +MFBD_MBTN_DEFAULT_DEFINE(test_mbtn, 4, 3, 30, 150, 75, 3); +#else /* MFBD_MBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) */ MFBD_MBTN_DEFINE(test_mbtn, 4, 3, 30, 150, 75, 3, 0x1501, 0x1500, 0x1501, 0x1511, 0x1521, 0x1531); -#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ +#endif /* MFBD_DEMO_USE_DEFAULT_DEFINE */ +#endif /* MFBD_USE_MULTIFUCNTION_BUTTON */ #endif /*MFBD_PARAMS_SAME_IN_GROUP*/ diff --git a/mfbd.c b/mfbd.c index 6cca8a6..ca787bb 100644 --- a/mfbd.c +++ b/mfbd.c @@ -348,7 +348,7 @@ void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group) { _pbtn_group->btn_value_report(_pbtn->btn_info->btn_up_code); } - +#if MFBD_MULTICLICK_STATE_AUTO_RESET /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */ if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0) \ && (_pbtn->multiclick_state < _pbtn->btn_info->max_multiclick_state) \ @@ -357,6 +357,18 @@ void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group) _pbtn->multiclick_state++; _pbtn->multiclick_count = 0; } +#else + /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */ + if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0) \ + && (!((((MFBD_LONG_TIME_IN_FUC) > 0) && (_pbtn->btn_info->btn_long_code != 0)) && (_pbtn->long_count >= (MFBD_LONG_TIME_IN_FUC))))) + { + if(_pbtn->multiclick_state < _pbtn->btn_info->max_multiclick_state) + { + _pbtn->multiclick_state++; + } + _pbtn->multiclick_count = 0; + } +#endif else { /* over max multi-click times or (long event and repeat event) happened, reset to 0. */ diff --git a/mfbd.h b/mfbd.h index 98d0f17..e6c825b 100644 --- a/mfbd.h +++ b/mfbd.h @@ -30,6 +30,11 @@ typedef enum MFBD_BTN_STATE_LONG, } MFBD_BTN_STATE_t; +#define MFBD_DOWN_CODE_NAME(NAME) NAME##_DOWN_CODE /* when using tbtn/nbtn default define api, this is down-code name. */ +#define MFBD_UP_CODE_NAME(NAME) NAME##_UP_CODE /* when using tbtn/nbtn/mbtn default define api, this is up-code name. */ +#define MFBD_LONG_CODE_NAME(NAME) NAME##_LONG_CODE /* when using nbtn/mbtn default define api, this is long-code name. */ +#define MFBD_DOWN_CODES_NAME(NAME) NAME##_DOWN_CODES /* when using mbtn default define api, this is long-codes name. */ + /* tiny button definitions, tiny button functions only support down and up event. */ #if MFBD_PARAMS_SAME_IN_GROUP diff --git a/mfbd_cfg.h b/mfbd_cfg.h index 4b3f219..badc903 100644 --- a/mfbd_cfg.h +++ b/mfbd_cfg.h @@ -144,4 +144,12 @@ #define MFBD_PARAMS_SAME_IN_GROUP 0 #endif +/* set MFBD_MULTICLICK_STATE_AUTO_RESET to 1 will auto reset multiclick state to 0 when reach to max multicick state. */ +#ifdef PKG_MFBD_MULTICLICK_STATE_AUTO_RESET + #define MFBD_MULTICLICK_STATE_AUTO_RESET 1 +#else + /* if you are not use mfbd in rt-thread, you can change this instead. */ + #define MFBD_MULTICLICK_STATE_AUTO_RESET 0 +#endif + #endif /* _MFBD_CFG_H_ */ diff --git a/mfbd_sd.c b/mfbd_sd.c index e255c19..864e3ca 100644 --- a/mfbd_sd.c +++ b/mfbd_sd.c @@ -356,7 +356,7 @@ void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_mbtn_info_t *_pb { _pbtn_group->btn_value_report(_pbtn_info->btn_up_code); } - +#if MFBD_MULTICLICK_STATE_AUTO_RESET /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */ if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0) \ && (_pbtn_info->btn->multiclick_state < _pbtn_info->max_multiclick_state) \ @@ -365,6 +365,18 @@ void mfbd_mbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_mbtn_info_t *_pb _pbtn_info->btn->multiclick_state++; _pbtn_info->btn->multiclick_count = 0; } +#else + /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */ + if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0) \ + && (!((((MFBD_LONG_TIME_IN_FUC) > 0) && (_pbtn_info->btn_long_code != 0)) && (_pbtn_info->btn->long_count >= (MFBD_LONG_TIME_IN_FUC))))) + { + if(_pbtn_info->btn->multiclick_state < _pbtn_info->max_multiclick_state) + { + _pbtn_info->btn->multiclick_state++; + } + _pbtn_info->btn->multiclick_count = 0; + } +#endif else { /* over max multi-click times or (long event and repeat event) happened, reset to 0. */ diff --git a/mfbd_sd.h b/mfbd_sd.h index 0d416f3..83a4d10 100644 --- a/mfbd_sd.h +++ b/mfbd_sd.h @@ -23,6 +23,11 @@ typedef enum MFBD_BTN_STATE_LONG, } MFBD_BTN_STATE_t; +#define MFBD_DOWN_CODE_NAME(NAME) NAME##_DOWN_CODE /* when using tbtn/nbtn default define api, this is down-code name. */ +#define MFBD_UP_CODE_NAME(NAME) NAME##_UP_CODE /* when using tbtn/nbtn/mbtn default define api, this is up-code name. */ +#define MFBD_LONG_CODE_NAME(NAME) NAME##_LONG_CODE /* when using nbtn/mbtn default define api, this is long-code name. */ +#define MFBD_DOWN_CODES_NAME(NAME) NAME##_DOWN_CODES /* when using mbtn default define api, this is long-codes name. */ + #if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */ #define __MFBD_SECTION(x) __attribute__((section(x))) #define MFBD_USED __attribute__((used)) @@ -438,9 +443,9 @@ typedef struct _mfbd_group_struct #define MFBD_GROUP_DEFINE(GROUP, IS_BTN_DOWN_FUNC, BTN_VALUE_REPORT_FUNC, ...) \ const mfbd_group_t MFBD_GROUP_NAME(GROUP) = { \ - IS_BTN_DOWN_FUNC, \ - BTN_VALUE_REPORT_FUNC, \ - __VA_ARGS__ \ + IS_BTN_DOWN_FUNC, \ + BTN_VALUE_REPORT_FUNC, \ + __VA_ARGS__ \ } extern void mfbd_tbtn_scan(const mfbd_group_t *_pbtn_group, const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end);