mfbd_sd.h 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /*
  2. * Copyright (c) 2022-2023, smartmx <smartmx@qq.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-07-03 smartmx the first version, Multi-Function Button Dectection with Section Definition.
  9. * 2023-07-15 smartmx add skip function, to reduce calling of scan functions.
  10. * 2023-09-19 smartmx improve performance, add MFBD_BTN_STATE_SKIP.
  11. *
  12. */
  13. #ifndef _MFBD_SD_H_
  14. #define _MFBD_SD_H_
  15. #include "mfbd_cfg.h"
  16. #if MFBD_USE_SECTION_DEFINITION
  17. typedef enum
  18. {
  19. MFBD_BTN_STATE_UP = 0,
  20. MFBD_BTN_STATE_DOWN,
  21. MFBD_BTN_STATE_LONG,
  22. MFBD_BTN_STATE_SKIP = 0xff,
  23. } MFBD_BTN_STATE_t;
  24. #define MFBD_DOWN_CODE_NAME(NAME) NAME##_DOWN_CODE /* when using tbtn/nbtn default define api, this is down-code name. */
  25. #define MFBD_UP_CODE_NAME(NAME) NAME##_UP_CODE /* when using tbtn/nbtn/mbtn default define api, this is up-code name. */
  26. #define MFBD_LONG_CODE_NAME(NAME) NAME##_LONG_CODE /* when using nbtn/mbtn default define api, this is long-code name. */
  27. #define MFBD_DOWN_CODES_NAME(NAME) NAME##_DOWN_CODES /* when using mbtn default define api, this is down-codes name. */
  28. #if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */
  29. #define __MFBD_SECTION(x) __attribute__((section(x)))
  30. #define MFBD_USED __attribute__((used))
  31. #define _MFBD_SECTION_START(X) X##$$Base
  32. #define _MFBD_SECTION_END(X) X##$$Limit
  33. #elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */
  34. #define __MFBD_SECTION(x) @ x
  35. #define MFBD_USED __root
  36. #define _MFBD_SECTION_START(X) __section_begin(#X)
  37. #define _MFBD_SECTION_END(X) __section_end(#X)
  38. #elif defined (__GNUC__) /* GNU GCC Compiler */
  39. #define __MFBD_SECTION(x) __attribute__((section(x)))
  40. #define MFBD_USED __attribute__((used))
  41. #define _MFBD_SECTION_START(X) X##_start
  42. #define _MFBD_SECTION_END(X) X##_end
  43. #else
  44. #error "not supported tool chain..."
  45. #endif
  46. #define _MFBD_SECTION(X) __MFBD_SECTION(#X)
  47. #define MFBD_SECTION(GROUP, BTN_KIND) _MFBD_SECTION(GROUP##_##BTN_KIND)
  48. #define MFBD_SECTION_START(GROUP, BTN_KIND) _MFBD_SECTION_START(GROUP##_##BTN_KIND)
  49. #define MFBD_SECTION_END(GROUP, BTN_KIND) _MFBD_SECTION_END(GROUP##_##BTN_KIND)
  50. /* tiny button definitions, tiny button functions only support down and up event. */
  51. typedef struct _mfbd_tiny_btn_struct
  52. {
  53. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  54. unsigned char state; /* the state of button, up or down. */
  55. } mfbd_tbtn_t;
  56. #if MFBD_PARAMS_SAME_IN_GROUP
  57. typedef struct _mfbd_tbtn_info_struct
  58. {
  59. mfbd_tbtn_t *btn; /* a pointer to mfbd_tbtn_t. */
  60. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  61. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  62. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  63. } mfbd_tbtn_info_t;
  64. #else
  65. typedef struct _mfbd_tbtn_info_struct
  66. {
  67. mfbd_tbtn_t *btn; /* a pointer to mfbd_tbtn_t. */
  68. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  69. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  70. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  71. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  72. } mfbd_tbtn_info_t;
  73. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  74. #if MFBD_PARAMS_SAME_IN_GROUP
  75. #define MFBD_TBTN_DEFINE(GROUP, NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE) \
  76. MFBD_USED mfbd_tbtn_t NAME = { \
  77. 0, \
  78. 0, \
  79. }; \
  80. MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \
  81. &NAME, \
  82. BTN_DOWN_CODE, \
  83. BTN_UP_CODE, \
  84. BTN_INDEX, \
  85. }
  86. #define MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX) \
  87. MFBD_USED mfbd_tbtn_t NAME = { \
  88. 0, \
  89. 0, \
  90. }; \
  91. MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \
  92. &NAME, \
  93. NAME##_DOWN_CODE, \
  94. NAME##_UP_CODE, \
  95. BTN_INDEX, \
  96. }
  97. #else
  98. #define MFBD_TBTN_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) \
  99. MFBD_USED mfbd_tbtn_t NAME = { \
  100. 0, \
  101. 0, \
  102. }; \
  103. MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \
  104. &NAME, \
  105. BTN_DOWN_CODE, \
  106. BTN_UP_CODE, \
  107. FILTER_TIME, \
  108. BTN_INDEX, \
  109. }
  110. #define MFBD_TBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME) \
  111. MFBD_USED mfbd_tbtn_t NAME = { \
  112. 0, \
  113. 0, \
  114. }; \
  115. MFBD_USED static const mfbd_tbtn_info_t NAME##_info MFBD_SECTION(GROUP, tbtn)= { \
  116. &NAME, \
  117. NAME##_DOWN_CODE, \
  118. NAME##_UP_CODE, \
  119. FILTER_TIME, \
  120. BTN_INDEX, \
  121. }
  122. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  123. #define MFBD_TBTN_EXTERN(NAME) extern mfbd_tbtn_t NAME
  124. /* normal button definitions, normal button functions support down, up and long-press event. */
  125. typedef struct _mfbd_normal_btn_struct
  126. {
  127. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  128. mfbd_btn_count_t long_count; /* long time count when button still down. */
  129. mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */
  130. unsigned char state; /* the state of button, up or down. */
  131. } mfbd_nbtn_t;
  132. #if MFBD_PARAMS_SAME_IN_GROUP
  133. typedef struct _mfbd_nbtn_info_struct
  134. {
  135. mfbd_nbtn_t *btn; /* a pointer to mfbd_nbtn_t. */
  136. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  137. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  138. 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. */
  139. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  140. } mfbd_nbtn_info_t;
  141. #else
  142. typedef struct _mfbd_nbtn_info_struct
  143. {
  144. mfbd_nbtn_t *btn; /* a pointer to mfbd_nbtn_t. */
  145. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  146. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  147. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  148. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  149. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  150. 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. */
  151. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  152. } mfbd_nbtn_info_t;
  153. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  154. #if MFBD_PARAMS_SAME_IN_GROUP
  155. #define MFBD_NBTN_DEFINE(GROUP, NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \
  156. MFBD_USED mfbd_nbtn_t NAME = { \
  157. 0, \
  158. 0, \
  159. 0, \
  160. 0, \
  161. }; \
  162. MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \
  163. &NAME, \
  164. BTN_DOWN_CODE, \
  165. BTN_UP_CODE, \
  166. BTN_LONG_CODE, \
  167. BTN_INDEX, \
  168. }
  169. #define MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX) \
  170. mfbd_nbtn_t NAME = { \
  171. 0, \
  172. 0, \
  173. 0, \
  174. 0, \
  175. }; \
  176. MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \
  177. &NAME, \
  178. NAME##_DOWN_CODE, \
  179. NAME##_UP_CODE, \
  180. NAME##_LONG_CODE, \
  181. BTN_INDEX, \
  182. }
  183. #else
  184. #define MFBD_NBTN_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \
  185. mfbd_nbtn_t NAME = { \
  186. 0, \
  187. 0, \
  188. 0, \
  189. 0, \
  190. }; \
  191. MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \
  192. &NAME, \
  193. FILTER_TIME, \
  194. REPEAT_TIME, \
  195. LONG_TIME, \
  196. BTN_DOWN_CODE, \
  197. BTN_UP_CODE, \
  198. BTN_LONG_CODE, \
  199. BTN_INDEX, \
  200. }
  201. #define MFBD_NBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) \
  202. mfbd_nbtn_t NAME = { \
  203. 0, \
  204. 0, \
  205. 0, \
  206. 0, \
  207. }; \
  208. MFBD_USED static const mfbd_nbtn_info_t NAME##_info MFBD_SECTION(GROUP, nbtn)= { \
  209. &NAME, \
  210. FILTER_TIME, \
  211. REPEAT_TIME, \
  212. LONG_TIME, \
  213. NAME##_DOWN_CODE, \
  214. NAME##_UP_CODE, \
  215. NAME##_LONG_CODE, \
  216. BTN_INDEX, \
  217. }
  218. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  219. #define MFBD_NBTN_EXTERN(NAME) extern mfbd_nbtn_t NAME
  220. /* multi-function button definitions, multi-function button functions support down, up, long-press and multi-click event. */
  221. /*
  222. * @Note:
  223. * repeat_count and long_count are conflict to multi-click.
  224. * repeat_count and long_count only check in the first button down event, and will disable in next multi-click event.
  225. * also, if repeat_count and long_count event has happened in the first down event, it will reset multiclick_state.
  226. */
  227. typedef struct _mfbd_multifuction_btn_struct
  228. {
  229. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  230. mfbd_btn_count_t long_count; /* long time count when button still down. */
  231. mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */
  232. mfbd_btn_count_t multiclick_count; /* multi-click time count when button is up. */
  233. unsigned char multiclick_state; /* multi-click count when button is in multi-click state. */
  234. unsigned char state; /* the state of button, up or down. */
  235. } mfbd_mbtn_t;
  236. #if MFBD_PARAMS_SAME_IN_GROUP
  237. typedef struct _mfbd_mbtn_info_struct
  238. {
  239. mfbd_mbtn_t *btn; /* a pointer to mfbd_mbtn_t. */
  240. const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */
  241. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  242. 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. */
  243. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  244. unsigned char max_multiclick_state; /* max multiclick states. */
  245. } mfbd_mbtn_info_t;
  246. #else
  247. typedef struct _mfbd_mbtn_info_struct
  248. {
  249. mfbd_mbtn_t *btn; /* a pointer to mfbd_mbtn_t. */
  250. const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */
  251. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  252. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  253. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  254. mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */
  255. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  256. 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. */
  257. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  258. unsigned char max_multiclick_state; /* max multiclick states. */
  259. } mfbd_mbtn_info_t;
  260. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  261. #if MFBD_PARAMS_SAME_IN_GROUP
  262. #define MFBD_MBTN_DEFINE(GROUP, NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) \
  263. static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \
  264. mfbd_mbtn_t NAME = { \
  265. 0, \
  266. 0, \
  267. 0, \
  268. 0, \
  269. 0, \
  270. 0, \
  271. }; \
  272. MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \
  273. &NAME, \
  274. NAME##_down_codes, \
  275. BTN_UP_CODE, \
  276. BTN_LONG_CODE, \
  277. BTN_INDEX, \
  278. MAX_MULTICLICK_STATE, \
  279. }
  280. #define MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, MAX_MULTICLICK_STATE) \
  281. mfbd_mbtn_t NAME = { \
  282. 0, \
  283. 0, \
  284. 0, \
  285. 0, \
  286. 0, \
  287. 0, \
  288. }; \
  289. MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \
  290. &NAME, \
  291. NAME##_DOWN_CODES, \
  292. NAME##_UP_CODE, \
  293. NAME##_LONG_CODE, \
  294. BTN_INDEX, \
  295. MAX_MULTICLICK_STATE, \
  296. }
  297. #else
  298. #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, ...) \
  299. static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \
  300. mfbd_mbtn_t NAME = { \
  301. 0, \
  302. 0, \
  303. 0, \
  304. 0, \
  305. 0, \
  306. 0, \
  307. }; \
  308. MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \
  309. &NAME, \
  310. NAME##_down_codes, \
  311. FILTER_TIME, \
  312. REPEAT_TIME, \
  313. LONG_TIME, \
  314. MULTICLICK_TIME, \
  315. BTN_UP_CODE, \
  316. BTN_LONG_CODE, \
  317. BTN_INDEX, \
  318. MAX_MULTICLICK_STATE, \
  319. }
  320. #define MFBD_MBTN_DEFAULT_DEFINE(GROUP, NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE) \
  321. mfbd_mbtn_t NAME = { \
  322. 0, \
  323. 0, \
  324. 0, \
  325. 0, \
  326. 0, \
  327. 0, \
  328. }; \
  329. MFBD_USED static const mfbd_mbtn_info_t NAME##_info MFBD_SECTION(GROUP, mbtn)= { \
  330. &NAME, \
  331. NAME##_DOWN_CODES, \
  332. FILTER_TIME, \
  333. REPEAT_TIME, \
  334. LONG_TIME, \
  335. MULTICLICK_TIME, \
  336. NAME##_UP_CODE, \
  337. NAME##_LONG_CODE, \
  338. BTN_INDEX, \
  339. MAX_MULTICLICK_STATE, \
  340. }
  341. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  342. #define MFBD_MBTN_EXTERN(NAME) extern mfbd_mbtn_t NAME
  343. /* mfbd group struct */
  344. typedef struct _mfbd_group_struct
  345. {
  346. /* used to read whether button is down. */
  347. unsigned char (*is_btn_down_func)(mfbd_btn_index_t btn_index);
  348. /* used to report btn_value, must have a legal value, must not be NULL. */
  349. void (*btn_value_report)(mfbd_btn_code_t btn_value);
  350. /* if set MFBD_PARAMS_SAME_IN_GROUP to 1, all btns in group has same params. */
  351. #if MFBD_PARAMS_SAME_IN_GROUP
  352. #if MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON
  353. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  354. #endif /* MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */
  355. #if MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON
  356. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  357. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  358. #endif /* MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */
  359. #if MFBD_USE_MULTIFUCNTION_BUTTON
  360. mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */
  361. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  362. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  363. #if MFBD_USE_BTN_SCAN_PRE_FUNC
  364. /* prepare function when start to scan buttons for each group. */
  365. void (*btn_scan_prepare)(void);
  366. #endif /* MFBD_USE_BTN_SCAN_PRE_FUNC */
  367. #if MFBD_USE_BTN_SCAN_AFTER_FUNC
  368. /* function after scanning buttons for each group. */
  369. void (*btn_scan_after)(void);
  370. #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */
  371. } mfbd_group_t;
  372. #define MFBD_GROUP_NAME(GROUP) mfbd_group_##GROUP
  373. #define MFBD_GROUP_EXTERN(GROUP) extern const mfbd_group_t MFBD_GROUP_NAME(GROUP)
  374. #define MFBD_GROUP_DEFINE(GROUP, IS_BTN_DOWN_FUNC, BTN_VALUE_REPORT_FUNC, ...) \
  375. const mfbd_group_t MFBD_GROUP_NAME(GROUP) = { \
  376. IS_BTN_DOWN_FUNC, \
  377. BTN_VALUE_REPORT_FUNC, \
  378. __VA_ARGS__ \
  379. }
  380. 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);
  381. extern void mfbd_tbtn_reset(const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end);
  382. 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);
  383. extern void mfbd_nbtn_skip(const mfbd_group_t *_pbtn_group, const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end, mfbd_btn_count_t times);
  384. extern void mfbd_nbtn_reset(const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end);
  385. 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);
  386. extern void mfbd_mbtn_skip(const mfbd_group_t *_pbtn_group, const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end, mfbd_btn_count_t times);
  387. extern void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end);
  388. #if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM Compiler */
  389. #if MFBD_USE_TINY_BUTTON
  390. #define MFBD_GROUP_SCAN_TBTN(GROUP) \
  391. do \
  392. { \
  393. extern const int MFBD_SECTION_START(GROUP, tbtn); \
  394. extern const int MFBD_SECTION_END(GROUP, tbtn); \
  395. 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))); \
  396. } while (0)
  397. #define MFBD_GROUP_RESET_TBTN(GROUP) \
  398. do \
  399. { \
  400. extern const int MFBD_SECTION_START(GROUP, tbtn); \
  401. extern const int MFBD_SECTION_END(GROUP, tbtn); \
  402. mfbd_tbtn_reset((const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \
  403. } while (0)
  404. #else
  405. #define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0)
  406. #define MFBD_GROUP_RESET_TBTN(GROUP) do{} while(0)
  407. #endif /* MFBD_USE_TINY_BUTTON */
  408. #if MFBD_USE_NORMAL_BUTTON
  409. #define MFBD_GROUP_SCAN_NBTN(GROUP) \
  410. do \
  411. { \
  412. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  413. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  414. 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))); \
  415. } while (0)
  416. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) \
  417. do \
  418. { \
  419. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  420. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  421. mfbd_nbtn_skip((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)), TIMES); \
  422. } while (0)
  423. #define MFBD_GROUP_RESET_NBTN(GROUP) \
  424. do \
  425. { \
  426. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  427. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  428. mfbd_nbtn_reset((const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \
  429. } while (0)
  430. #else
  431. #define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0)
  432. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) do{} while(0)
  433. #define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0)
  434. #endif /* MFBD_USE_NORMAL_BUTTON */
  435. #if MFBD_USE_MULTIFUCNTION_BUTTON
  436. #define MFBD_GROUP_SCAN_MBTN(GROUP) \
  437. do \
  438. { \
  439. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  440. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  441. 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))); \
  442. } while (0)
  443. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) \
  444. do \
  445. { \
  446. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  447. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  448. mfbd_mbtn_skip((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)), TIMES); \
  449. } while (0)
  450. #define MFBD_GROUP_RESET_MBTN(GROUP) \
  451. do \
  452. { \
  453. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  454. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  455. mfbd_mbtn_reset((const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \
  456. } while (0)
  457. #else
  458. #define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0)
  459. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) do{} while(0)
  460. #define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0)
  461. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  462. #elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */
  463. #if MFBD_USE_TINY_BUTTON
  464. #define MFBD_GROUP_SCAN_TBTN(GROUP) \
  465. do \
  466. { \
  467. 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)); \
  468. } while (0)
  469. #define MFBD_GROUP_RESET_TBTN(GROUP) \
  470. do \
  471. { \
  472. mfbd_tbtn_reset((const mfbd_tbtn_info_t *)MFBD_SECTION_START(GROUP, nbtn), (const mfbd_tbtn_info_t *)MFBD_SECTION_END(GROUP, nbtn)); \
  473. } while (0)
  474. #else
  475. #define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0)
  476. #endif /* MFBD_USE_TINY_BUTTON */
  477. #if MFBD_USE_NORMAL_BUTTON
  478. #define MFBD_GROUP_SCAN_NBTN(GROUP) \
  479. do \
  480. { \
  481. 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)); \
  482. } while (0)
  483. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) \
  484. do \
  485. { \
  486. mfbd_nbtn_skip((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), TIMES); \
  487. } while (0)
  488. #define MFBD_GROUP_RESET_NBTN(GROUP) \
  489. do \
  490. { \
  491. mfbd_nbtn_reset((const mfbd_nbtn_info_t *)MFBD_SECTION_START(GROUP, nbtn), (const mfbd_nbtn_info_t *)MFBD_SECTION_END(GROUP, nbtn)); \
  492. } while (0)
  493. #else
  494. #define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0)
  495. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) do{} while(0)
  496. #define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0)
  497. #endif /* MFBD_USE_NORMAL_BUTTON */
  498. #if MFBD_USE_MULTIFUCNTION_BUTTON
  499. #define MFBD_GROUP_SCAN_MBTN(GROUP) \
  500. do \
  501. { \
  502. 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)); \
  503. } while (0)
  504. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) \
  505. do \
  506. { \
  507. mfbd_mbtn_skip((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), TIMES); \
  508. } while (0)
  509. #define MFBD_GROUP_RESET_MBTN(GROUP) \
  510. do \
  511. { \
  512. mfbd_mbtn_reset((const mfbd_mbtn_info_t *)MFBD_SECTION_START(GROUP, mbtn), (const mfbd_mbtn_info_t *)MFBD_SECTION_END(GROUP, mbtn)); \
  513. } while (0)
  514. #else
  515. #define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0)
  516. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) do{} while(0)
  517. #define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0)
  518. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  519. #elif defined (__GNUC__) /* GNU GCC Compiler */
  520. #if MFBD_USE_TINY_BUTTON
  521. #define MFBD_GROUP_SCAN_TBTN(GROUP) \
  522. do \
  523. { \
  524. extern const int MFBD_SECTION_START(GROUP, tbtn); \
  525. extern const int MFBD_SECTION_END(GROUP, tbtn); \
  526. 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))); \
  527. } while (0)
  528. #define MFBD_GROUP_RESET_TBTN(GROUP) \
  529. do \
  530. { \
  531. extern const int MFBD_SECTION_START(GROUP, tbtn); \
  532. extern const int MFBD_SECTION_END(GROUP, tbtn); \
  533. mfbd_tbtn_reset((const mfbd_tbtn_info_t *)&(MFBD_SECTION_START(GROUP, tbtn)), (const mfbd_tbtn_info_t *)&(MFBD_SECTION_END(GROUP, tbtn))); \
  534. } while (0)
  535. #else
  536. #define MFBD_GROUP_SCAN_TBTN(GROUP) do{} while(0)
  537. #define MFBD_GROUP_RESET_TBTN(GROUP) do{} while(0)
  538. #endif /* MFBD_USE_TINY_BUTTON */
  539. #if MFBD_USE_NORMAL_BUTTON
  540. #define MFBD_GROUP_SCAN_NBTN(GROUP) \
  541. do \
  542. { \
  543. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  544. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  545. 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))); \
  546. } while (0)
  547. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) \
  548. do \
  549. { \
  550. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  551. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  552. mfbd_nbtn_skip((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)), TIMES); \
  553. } while (0)
  554. #define MFBD_GROUP_RESET_NBTN(GROUP) \
  555. do \
  556. { \
  557. extern const int MFBD_SECTION_START(GROUP, nbtn); \
  558. extern const int MFBD_SECTION_END(GROUP, nbtn); \
  559. mfbd_nbtn_reset((const mfbd_nbtn_info_t *)&(MFBD_SECTION_START(GROUP, nbtn)), (const mfbd_nbtn_info_t *)&(MFBD_SECTION_END(GROUP, nbtn))); \
  560. } while (0)
  561. #else
  562. #define MFBD_GROUP_SCAN_NBTN(GROUP) do{} while(0)
  563. #define MFBD_GROUP_SKIP_NBTN(GROUP, TIMES) do{} while(0)
  564. #define MFBD_GROUP_RESET_NBTN(GROUP) do{} while(0)
  565. #endif /* MFBD_USE_NORMAL_BUTTON */
  566. #if MFBD_USE_MULTIFUCNTION_BUTTON
  567. #define MFBD_GROUP_SCAN_MBTN(GROUP) \
  568. do \
  569. { \
  570. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  571. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  572. 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))); \
  573. } while (0)
  574. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) \
  575. do \
  576. { \
  577. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  578. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  579. mfbd_mbtn_skip((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)), TIMES); \
  580. } while (0)
  581. #define MFBD_GROUP_RESET_MBTN(GROUP) \
  582. do \
  583. { \
  584. extern const int MFBD_SECTION_START(GROUP, mbtn); \
  585. extern const int MFBD_SECTION_END(GROUP, mbtn); \
  586. mfbd_mbtn_reset((const mfbd_mbtn_info_t *)&(MFBD_SECTION_START(GROUP, mbtn)), (const mfbd_mbtn_info_t *)&(MFBD_SECTION_END(GROUP, mbtn))); \
  587. } while (0)
  588. #else
  589. #define MFBD_GROUP_SCAN_MBTN(GROUP) do{} while(0)
  590. #define MFBD_GROUP_SKIP_MBTN(GROUP, TIMES) do{} while(0)
  591. #define MFBD_GROUP_RESET_MBTN(GROUP) do{} while(0)
  592. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  593. #else
  594. #error "not supported tool chain..."
  595. #endif
  596. #if MFBD_USE_BTN_SCAN_PRE_FUNC
  597. #define MFBD_GROUP_SCAN_PREPARE(GROUP) \
  598. do \
  599. { \
  600. if(MFBD_GROUP_NAME(GROUP).btn_scan_prepare!= NULL) \
  601. { \
  602. MFBD_GROUP_NAME(GROUP).btn_scan_prepare(); \
  603. } \
  604. } while(0)
  605. #else
  606. #define MFBD_GROUP_SCAN_PREPARE(GROUP) do{} while(0)
  607. #endif /* MFBD_USE_BTN_SCAN_PRE_FUNC */
  608. #if MFBD_USE_BTN_SCAN_AFTER_FUNC
  609. #define MFBD_GROUP_SCAN_AFTER(GROUP) \
  610. do \
  611. { \
  612. if(MFBD_GROUP_NAME(GROUP).btn_scan_after!= NULL) \
  613. { \
  614. MFBD_GROUP_NAME(GROUP).btn_scan_after(); \
  615. } \
  616. } while(0)
  617. #else
  618. #define MFBD_GROUP_SCAN_AFTER(GROUP) do{} while(0)
  619. #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */
  620. /*
  621. * @Note:
  622. * this in a example for how to scan or reset the mfbd group,
  623. * if some group has not all btn types, you should write code by yourself.
  624. */
  625. #define MFBD_GROUP_SCAN(GROUP) \
  626. do \
  627. { \
  628. MFBD_GROUP_SCAN_PREPARE(GROUP); \
  629. MFBD_GROUP_SCAN_TBTN(GROUP); \
  630. MFBD_GROUP_SCAN_NBTN(GROUP); \
  631. MFBD_GROUP_SCAN_MBTN(GROUP); \
  632. MFBD_GROUP_SCAN_AFTER(GROUP); \
  633. } while (0)
  634. #define MFBD_GROUP_SKIP(GROUP, TIMES) \
  635. do \
  636. { \
  637. MFBD_GROUP_SKIP_NBTN(GROUP, TIMES); \
  638. MFBD_GROUP_SKIP_MBTN(GROUP, TIMES); \
  639. } while (0)
  640. #define MFBD_GROUP_RESET(GROUP) \
  641. do \
  642. { \
  643. MFBD_GROUP_RESET_TBTN(GROUP); \
  644. MFBD_GROUP_RESET_NBTN(GROUP); \
  645. MFBD_GROUP_RESET_MBTN(GROUP); \
  646. } while (0)
  647. #endif /* MFBD_USE_SECTION_DEFINITION */
  648. #endif /* _MFBD_SD_H_ */