mfbd_sd.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  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-07-22 smartmx add MFBD_MBTN_MULTICLICK_LONG_EVT and MFBD_MBTN_CONTINUE_LONG_COUNT option.
  11. * 2023-09-19 smartmx improve performance, add MFBD_BTN_STATE_SKIP.
  12. *
  13. */
  14. #include "mfbd_sd.h"
  15. #if MFBD_USE_SECTION_DEFINITION
  16. #define MFBD_BTN_IN_FUC (_pbtn_info->btn)
  17. #define MFBD_BTN_INFO_IN_FUC (_pbtn_info)
  18. #if MFBD_PARAMS_SAME_IN_GROUP
  19. /* filter_time */
  20. #define MFBD_FILTER_TIME_IN_FUC (_pbtn_group->filter_time)
  21. /* long_time */
  22. #define MFBD_LONG_TIME_IN_FUC (_pbtn_group->long_time)
  23. /* repeat_time */
  24. #define MFBD_REPEAT_TIME_IN_FUC (_pbtn_group->repeat_time)
  25. /* multiclick_time */
  26. #define MFBD_MULTICLICK_TIME_IN_FUC (_pbtn_group->multiclick_time)
  27. #else
  28. /* filter_time */
  29. #define MFBD_FILTER_TIME_IN_FUC (_pbtn_info->filter_time)
  30. /* long_time */
  31. #define MFBD_LONG_TIME_IN_FUC (_pbtn_info->long_time)
  32. /* repeat_time */
  33. #define MFBD_REPEAT_TIME_IN_FUC (_pbtn_info->repeat_time)
  34. /* multiclick_time */
  35. #define MFBD_MULTICLICK_TIME_IN_FUC (_pbtn_info->multiclick_time)
  36. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  37. #if MFBD_USE_TINY_BUTTON
  38. /**
  39. * @brief scan all tiny buttons, and report button event value if event happened.
  40. *
  41. * @param _pbtn_group is a pointer of mfbd_group_t.
  42. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_tbtn_info_t.
  43. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_tbtn_info_t.
  44. *
  45. * @return None.
  46. */
  47. 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)
  48. {
  49. const mfbd_tbtn_info_t *_pbtn_info = _pbtn_info_start;
  50. MFBD_BTN_STATE_t btn_state;
  51. while (1)
  52. {
  53. if (_pbtn_info_end <= _pbtn_info)
  54. {
  55. break;
  56. }
  57. btn_state = _pbtn_group->is_btn_down_func(MFBD_BTN_INFO_IN_FUC->btn_index);
  58. if (btn_state == MFBD_BTN_STATE_DOWN)
  59. {
  60. if (MFBD_BTN_IN_FUC->filter_count >= ((MFBD_FILTER_TIME_IN_FUC) * 2))
  61. {
  62. /* it means the button is down for over filter_time. */
  63. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_UP)
  64. {
  65. if (MFBD_BTN_INFO_IN_FUC->btn_down_code > 0)
  66. {
  67. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code);
  68. }
  69. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_DOWN;
  70. }
  71. }
  72. else if (MFBD_BTN_IN_FUC->filter_count >= (MFBD_FILTER_TIME_IN_FUC))
  73. {
  74. MFBD_BTN_IN_FUC->filter_count++;
  75. }
  76. else
  77. {
  78. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  79. }
  80. }
  81. else if (btn_state == MFBD_BTN_STATE_UP)
  82. {
  83. if (MFBD_BTN_IN_FUC->filter_count == 0)
  84. {
  85. if (MFBD_BTN_IN_FUC->state != MFBD_BTN_STATE_UP)
  86. {
  87. if (MFBD_BTN_INFO_IN_FUC->btn_up_code > 0)
  88. {
  89. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_up_code);
  90. }
  91. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  92. }
  93. }
  94. else
  95. {
  96. if (MFBD_BTN_IN_FUC->filter_count > (MFBD_FILTER_TIME_IN_FUC))
  97. {
  98. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  99. }
  100. else if (MFBD_BTN_IN_FUC->filter_count != 0)
  101. {
  102. MFBD_BTN_IN_FUC->filter_count--;
  103. }
  104. }
  105. }
  106. _pbtn_info++;
  107. }
  108. }
  109. /**
  110. * @brief reset all tiny buttons' params.
  111. *
  112. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_tbtn_info_t.
  113. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_tbtn_info_t.
  114. *
  115. * @return None.
  116. */
  117. void mfbd_tbtn_reset(const mfbd_tbtn_info_t *_pbtn_info_start, const mfbd_tbtn_info_t *_pbtn_info_end)
  118. {
  119. const mfbd_tbtn_info_t *_pbtn_info = _pbtn_info_start;
  120. while (1)
  121. {
  122. if (_pbtn_info_end <= _pbtn_info)
  123. {
  124. break;
  125. }
  126. MFBD_BTN_IN_FUC->filter_count = 0;
  127. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  128. _pbtn_info++;
  129. }
  130. }
  131. #endif /* MFBD_USE_TINY_BUTTON */
  132. #if MFBD_USE_NORMAL_BUTTON
  133. /**
  134. * @brief scan all normal buttons, and report button event value if event happened.
  135. *
  136. * @param _pbtn_group is a pointer of mfbd_group_t.
  137. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_nbtn_info_t.
  138. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_nbtn_info_t.
  139. *
  140. * @return None
  141. */
  142. 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)
  143. {
  144. const mfbd_nbtn_info_t *_pbtn_info = _pbtn_info_start;
  145. MFBD_BTN_STATE_t btn_state;
  146. while (1)
  147. {
  148. if (_pbtn_info_end <= _pbtn_info)
  149. {
  150. break;
  151. }
  152. btn_state = _pbtn_group->is_btn_down_func(MFBD_BTN_INFO_IN_FUC->btn_index);
  153. if (btn_state == MFBD_BTN_STATE_DOWN)
  154. {
  155. if (MFBD_BTN_IN_FUC->filter_count >= ((MFBD_FILTER_TIME_IN_FUC) * 2))
  156. {
  157. /* it means the button is down for over filter_time. */
  158. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG)
  159. {
  160. /* MFBD_BTN_STATE_LONG */
  161. if (MFBD_BTN_IN_FUC->repeat_count > 0)
  162. {
  163. MFBD_BTN_IN_FUC->repeat_count++;
  164. if (MFBD_BTN_IN_FUC->repeat_count > (MFBD_REPEAT_TIME_IN_FUC))
  165. {
  166. /* repeat event has happened, reset repeat_count to 1. */
  167. MFBD_BTN_IN_FUC->repeat_count = 1;
  168. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code);
  169. }
  170. }
  171. }
  172. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  173. {
  174. if (MFBD_BTN_IN_FUC->long_count > 0)
  175. {
  176. /* if long_time is 0 or long_code is 0, disable long and repeat check. */
  177. if (MFBD_BTN_IN_FUC->long_count <= (MFBD_LONG_TIME_IN_FUC))
  178. {
  179. MFBD_BTN_IN_FUC->long_count++;
  180. if (MFBD_BTN_IN_FUC->long_count > (MFBD_LONG_TIME_IN_FUC))
  181. {
  182. /* it means the button is down for over long_time. */
  183. if (((MFBD_REPEAT_TIME_IN_FUC) > 0) && (MFBD_BTN_INFO_IN_FUC->btn_down_code != 0))
  184. {
  185. /* repeat event is enabled in this btn. */
  186. MFBD_BTN_IN_FUC->repeat_count = 1;
  187. }
  188. else
  189. {
  190. /* repeat event is disabled in this btn. */
  191. MFBD_BTN_IN_FUC->repeat_count = 0;
  192. }
  193. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_long_code);
  194. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_LONG;
  195. }
  196. }
  197. }
  198. }
  199. else
  200. {
  201. /* MFBD_BTN_STATE_UP */
  202. /* clear long_count. */
  203. if (((MFBD_LONG_TIME_IN_FUC) > 0) && (MFBD_BTN_INFO_IN_FUC->btn_long_code != 0))
  204. {
  205. /* long event is enabled in this btn. */
  206. MFBD_BTN_IN_FUC->long_count = 1;
  207. }
  208. else
  209. {
  210. /* long event is disabled in this btn. */
  211. MFBD_BTN_IN_FUC->long_count = 0;
  212. }
  213. if (MFBD_BTN_INFO_IN_FUC->btn_down_code > 0)
  214. {
  215. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code);
  216. }
  217. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_DOWN;
  218. }
  219. }
  220. else if (MFBD_BTN_IN_FUC->filter_count >= (MFBD_FILTER_TIME_IN_FUC))
  221. {
  222. MFBD_BTN_IN_FUC->filter_count++;
  223. }
  224. else
  225. {
  226. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  227. }
  228. }
  229. else if (btn_state == MFBD_BTN_STATE_UP)
  230. {
  231. if (MFBD_BTN_IN_FUC->filter_count == 0)
  232. {
  233. if (MFBD_BTN_IN_FUC->state != MFBD_BTN_STATE_UP)
  234. {
  235. if (MFBD_BTN_INFO_IN_FUC->btn_up_code > 0)
  236. {
  237. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_up_code);
  238. }
  239. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  240. }
  241. }
  242. else
  243. {
  244. if (MFBD_BTN_IN_FUC->filter_count > (MFBD_FILTER_TIME_IN_FUC))
  245. {
  246. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  247. }
  248. else if (MFBD_BTN_IN_FUC->filter_count != 0)
  249. {
  250. MFBD_BTN_IN_FUC->filter_count--;
  251. }
  252. }
  253. }
  254. _pbtn_info++;
  255. }
  256. }
  257. /**
  258. * @brief skip some times of mfbd_btn_count_t with last state.
  259. *
  260. * @param _pbtn_group is a pointer of mfbd_group_t.
  261. * @param times is times need to skip.
  262. *
  263. * @return None.
  264. */
  265. 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)
  266. {
  267. const mfbd_nbtn_info_t *_pbtn_info = _pbtn_info_start;
  268. while (1)
  269. {
  270. if (_pbtn_info_end <= _pbtn_info)
  271. {
  272. break;
  273. }
  274. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  275. {
  276. if ((MFBD_BTN_IN_FUC->long_count > 0) && (MFBD_BTN_IN_FUC->long_count < (MFBD_LONG_TIME_IN_FUC)))
  277. {
  278. if (((MFBD_LONG_TIME_IN_FUC) - MFBD_BTN_IN_FUC->long_count) > times)
  279. {
  280. MFBD_BTN_IN_FUC->long_count = MFBD_BTN_IN_FUC->long_count + times;
  281. }
  282. else
  283. {
  284. MFBD_BTN_IN_FUC->long_count = MFBD_LONG_TIME_IN_FUC;
  285. }
  286. }
  287. }
  288. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG)
  289. {
  290. if ((MFBD_BTN_IN_FUC->repeat_count > 0) && (MFBD_BTN_IN_FUC->repeat_count < (MFBD_REPEAT_TIME_IN_FUC)))
  291. {
  292. if (((MFBD_REPEAT_TIME_IN_FUC) - MFBD_BTN_IN_FUC->repeat_count) > times)
  293. {
  294. MFBD_BTN_IN_FUC->repeat_count = MFBD_BTN_IN_FUC->repeat_count + times;
  295. }
  296. else
  297. {
  298. MFBD_BTN_IN_FUC->repeat_count = MFBD_REPEAT_TIME_IN_FUC;
  299. }
  300. }
  301. }
  302. _pbtn_info++;
  303. }
  304. }
  305. /**
  306. * @brief reset all normal buttons' params.
  307. *
  308. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_nbtn_info_t.
  309. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_nbtn_info_t.
  310. *
  311. * @return None.
  312. */
  313. void mfbd_nbtn_reset(const mfbd_nbtn_info_t *_pbtn_info_start, const mfbd_nbtn_info_t *_pbtn_info_end)
  314. {
  315. const mfbd_nbtn_info_t *_pbtn_info = _pbtn_info_start;
  316. while (1)
  317. {
  318. if (_pbtn_info_end <= _pbtn_info)
  319. {
  320. break;
  321. }
  322. MFBD_BTN_IN_FUC->filter_count = 0;
  323. MFBD_BTN_IN_FUC->long_count = 0;
  324. MFBD_BTN_IN_FUC->repeat_count = 0;
  325. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  326. _pbtn_info++;
  327. }
  328. }
  329. #endif /* MFBD_USE_NORMAL_BUTTON */
  330. #if MFBD_USE_MULTIFUCNTION_BUTTON
  331. /**
  332. * @brief scan all multi-function buttons, and report button event value if event happened.
  333. *
  334. * @param _pbtn_group is a pointer of mfbd_group_t.
  335. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_mbtn_info_t.
  336. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_mbtn_info_t.
  337. *
  338. * @return None.
  339. */
  340. 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)
  341. {
  342. const mfbd_mbtn_info_t *_pbtn_info = _pbtn_info_start;
  343. MFBD_BTN_STATE_t btn_state;
  344. while (1)
  345. {
  346. if (_pbtn_info_end <= _pbtn_info)
  347. {
  348. break;
  349. }
  350. btn_state = _pbtn_group->is_btn_down_func(MFBD_BTN_INFO_IN_FUC->btn_index);
  351. if (btn_state == MFBD_BTN_STATE_DOWN)
  352. {
  353. if (MFBD_BTN_IN_FUC->filter_count >= ((MFBD_FILTER_TIME_IN_FUC) * 2))
  354. {
  355. /* it means the button is down for over filter_time. */
  356. #if MFBD_MBTN_CONTINUE_LONG_COUNT
  357. #if MFBD_MBTN_MULTICLICK_LONG_EVT
  358. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG)
  359. {
  360. /* MFBD_BTN_STATE_LONG */
  361. if (MFBD_BTN_IN_FUC->repeat_count > 0)
  362. {
  363. MFBD_BTN_IN_FUC->repeat_count++;
  364. if (MFBD_BTN_IN_FUC->repeat_count > (MFBD_REPEAT_TIME_IN_FUC))
  365. {
  366. /* repeat event has happened, clear repeat_count. */
  367. MFBD_BTN_IN_FUC->repeat_count = 1;
  368. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code[MFBD_BTN_IN_FUC->multiclick_state]);
  369. }
  370. }
  371. }
  372. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  373. {
  374. if (MFBD_BTN_IN_FUC->long_count > 0)
  375. {
  376. /* if long_time is 0 or long_code is 0, disable long and repeat check. */
  377. if (MFBD_BTN_IN_FUC->long_count <= (MFBD_LONG_TIME_IN_FUC))
  378. {
  379. MFBD_BTN_IN_FUC->long_count++;
  380. if (MFBD_BTN_IN_FUC->long_count > (MFBD_LONG_TIME_IN_FUC))
  381. {
  382. /* it means the button is down for over long_time. */
  383. if (((MFBD_REPEAT_TIME_IN_FUC) > 0) && (MFBD_BTN_INFO_IN_FUC->btn_down_code[MFBD_BTN_IN_FUC->multiclick_state] != 0))
  384. {
  385. /* repeat event is enabled in this btn. */
  386. MFBD_BTN_IN_FUC->repeat_count = 1;
  387. }
  388. else
  389. {
  390. /* repeat event is disabled in this btn. */
  391. MFBD_BTN_IN_FUC->repeat_count = 0;
  392. }
  393. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_long_code);
  394. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_LONG;
  395. }
  396. }
  397. }
  398. }
  399. #else
  400. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG)
  401. {
  402. /* we don't support repeat event here.*/
  403. }
  404. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  405. {
  406. if (MFBD_BTN_IN_FUC->long_count > 0)
  407. {
  408. /* if long_time is 0 or long_code is 0, disable long and repeat check. */
  409. if (MFBD_BTN_IN_FUC->long_count <= (MFBD_LONG_TIME_IN_FUC))
  410. {
  411. MFBD_BTN_IN_FUC->long_count++;
  412. if (MFBD_BTN_IN_FUC->long_count > (MFBD_LONG_TIME_IN_FUC))
  413. {
  414. /* it means the button is down for over long_time. */
  415. if (MFBD_BTN_IN_FUC->multiclick_state == 0)
  416. {
  417. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_long_code);
  418. }
  419. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_LONG;
  420. }
  421. }
  422. }
  423. }
  424. #endif /* MFBD_MBTN_MULTICLICK_LONG_EVT */
  425. #else
  426. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG)
  427. {
  428. /* MFBD_BTN_STATE_LONG */
  429. if (MFBD_BTN_IN_FUC->repeat_count > 0)
  430. {
  431. MFBD_BTN_IN_FUC->repeat_count++;
  432. if (MFBD_BTN_IN_FUC->repeat_count > (MFBD_REPEAT_TIME_IN_FUC))
  433. {
  434. /* repeat event has happened, clear repeat_count. */
  435. MFBD_BTN_IN_FUC->repeat_count = 1;
  436. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code[0]);
  437. }
  438. }
  439. }
  440. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  441. {
  442. if (MFBD_BTN_IN_FUC->multiclick_state == 0)
  443. {
  444. if (MFBD_BTN_IN_FUC->long_count > 0)
  445. {
  446. /* if long_time is 0 or long_code is 0, disable long and repeat check. */
  447. if (MFBD_BTN_IN_FUC->long_count <= (MFBD_LONG_TIME_IN_FUC))
  448. {
  449. MFBD_BTN_IN_FUC->long_count++;
  450. if (MFBD_BTN_IN_FUC->long_count > (MFBD_LONG_TIME_IN_FUC))
  451. {
  452. /* it means the button is down for over long_time. */
  453. if (((MFBD_REPEAT_TIME_IN_FUC) > 0) && (MFBD_BTN_INFO_IN_FUC->btn_down_code[0] != 0))
  454. {
  455. /* repeat event is enabled in this btn. */
  456. MFBD_BTN_IN_FUC->repeat_count = 1;
  457. }
  458. else
  459. {
  460. /* repeat event is disabled in this btn. */
  461. MFBD_BTN_IN_FUC->repeat_count = 0;
  462. }
  463. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_long_code);
  464. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_LONG;
  465. }
  466. }
  467. }
  468. }
  469. }
  470. #endif /* MFBD_MBTN_CONTINUE_LONG_COUNT */
  471. else
  472. {
  473. /* MFBD_BTN_STATE_UP */
  474. /* clear long_count. */
  475. if (((MFBD_LONG_TIME_IN_FUC) > 0) && (MFBD_BTN_INFO_IN_FUC->btn_long_code != 0))
  476. {
  477. /* long event is enabled in this btn. */
  478. MFBD_BTN_IN_FUC->long_count = 1;
  479. }
  480. else
  481. {
  482. /* long event is disabled in this btn. */
  483. MFBD_BTN_IN_FUC->long_count = 0;
  484. }
  485. if (MFBD_BTN_INFO_IN_FUC->btn_down_code[MFBD_BTN_IN_FUC->multiclick_state] > 0)
  486. {
  487. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_down_code[MFBD_BTN_IN_FUC->multiclick_state]);
  488. }
  489. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_DOWN;
  490. }
  491. }
  492. else if (MFBD_BTN_IN_FUC->filter_count >= (MFBD_FILTER_TIME_IN_FUC))
  493. {
  494. MFBD_BTN_IN_FUC->filter_count++;
  495. }
  496. else
  497. {
  498. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  499. }
  500. }
  501. else if (btn_state == MFBD_BTN_STATE_UP)
  502. {
  503. if (MFBD_BTN_IN_FUC->filter_count == 0)
  504. {
  505. if (MFBD_BTN_IN_FUC->state != MFBD_BTN_STATE_UP)
  506. {
  507. #if MFBD_MULTICLICK_STATE_AUTO_RESET
  508. /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */
  509. if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0)
  510. && (MFBD_BTN_IN_FUC->multiclick_state < MFBD_BTN_INFO_IN_FUC->max_multiclick_state)
  511. #if (MFBD_MBTN_CONTINUE_LONG_COUNT==0)
  512. && (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  513. #endif /* (MFBD_MBTN_CONTINUE_LONG_COUNT==0) */
  514. )
  515. {
  516. MFBD_BTN_IN_FUC->multiclick_state++;
  517. MFBD_BTN_IN_FUC->multiclick_count = 0;
  518. }
  519. #else
  520. /* if multiclick_state is not 0 and less than max_multiclick_state, inc multiclick_state */
  521. if (((MFBD_MULTICLICK_TIME_IN_FUC) != 0)
  522. #if (MFBD_MBTN_CONTINUE_LONG_COUNT==0)
  523. && (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  524. #endif /* (MFBD_MBTN_CONTINUE_LONG_COUNT==0) */
  525. )
  526. {
  527. if (MFBD_BTN_IN_FUC->multiclick_state < MFBD_BTN_INFO_IN_FUC->max_multiclick_state)
  528. {
  529. MFBD_BTN_IN_FUC->multiclick_state++;
  530. }
  531. MFBD_BTN_IN_FUC->multiclick_count = 0;
  532. }
  533. #endif /* MFBD_MULTICLICK_STATE_AUTO_RESET */
  534. else
  535. {
  536. /* over max multi-click times or (long event and repeat event) happened, reset to 0. */
  537. MFBD_BTN_IN_FUC->multiclick_state = 0;
  538. }
  539. if (MFBD_BTN_INFO_IN_FUC->btn_up_code > 0)
  540. {
  541. _pbtn_group->btn_value_report(MFBD_BTN_INFO_IN_FUC->btn_up_code);
  542. }
  543. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  544. }
  545. else
  546. {
  547. if (MFBD_BTN_IN_FUC->multiclick_state != 0)
  548. {
  549. MFBD_BTN_IN_FUC->multiclick_count++;
  550. if (MFBD_BTN_IN_FUC->multiclick_count >= (MFBD_MULTICLICK_TIME_IN_FUC))
  551. {
  552. MFBD_BTN_IN_FUC->multiclick_state = 0;
  553. }
  554. }
  555. }
  556. }
  557. else
  558. {
  559. if (MFBD_BTN_IN_FUC->filter_count > (MFBD_FILTER_TIME_IN_FUC))
  560. {
  561. MFBD_BTN_IN_FUC->filter_count = (MFBD_FILTER_TIME_IN_FUC);
  562. }
  563. else if (MFBD_BTN_IN_FUC->filter_count != 0)
  564. {
  565. MFBD_BTN_IN_FUC->filter_count--;
  566. }
  567. }
  568. }
  569. _pbtn_info++;
  570. }
  571. }
  572. /**
  573. * @brief skip some times of mfbd_btn_count_t with last state.
  574. *
  575. * @param _pbtn_group is a pointer of mfbd_group_t.
  576. * @param times is times need to skip.
  577. *
  578. * @return None.
  579. */
  580. 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)
  581. {
  582. const mfbd_mbtn_info_t *_pbtn_info = _pbtn_info_start;
  583. while (1)
  584. {
  585. if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_UP)
  586. {
  587. if (MFBD_BTN_IN_FUC->multiclick_state != 0)
  588. {
  589. if (MFBD_BTN_IN_FUC->multiclick_count < (MFBD_MULTICLICK_TIME_IN_FUC))
  590. {
  591. if (((MFBD_MULTICLICK_TIME_IN_FUC) - MFBD_BTN_IN_FUC->multiclick_count) > times)
  592. {
  593. MFBD_BTN_IN_FUC->multiclick_count = MFBD_BTN_IN_FUC->multiclick_count + times;
  594. }
  595. else
  596. {
  597. MFBD_BTN_IN_FUC->multiclick_state = 0;
  598. }
  599. }
  600. }
  601. }
  602. #if MFBD_MBTN_CONTINUE_LONG_COUNT
  603. #if MFBD_MBTN_MULTICLICK_LONG_EVT
  604. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  605. {
  606. if ((MFBD_BTN_IN_FUC->long_count > 0) && (MFBD_BTN_IN_FUC->long_count < (MFBD_LONG_TIME_IN_FUC)))
  607. {
  608. if (((MFBD_LONG_TIME_IN_FUC) - MFBD_BTN_IN_FUC->long_count) > times)
  609. {
  610. MFBD_BTN_IN_FUC->long_count = MFBD_BTN_IN_FUC->long_count + times;
  611. }
  612. else
  613. {
  614. MFBD_BTN_IN_FUC->long_count = MFBD_LONG_TIME_IN_FUC;
  615. }
  616. }
  617. }
  618. else
  619. {
  620. /* MFBD_BTN_STATE_LONG, if(MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG) */
  621. if ((MFBD_BTN_IN_FUC->repeat_count > 0) && (MFBD_BTN_IN_FUC->repeat_count < (MFBD_REPEAT_TIME_IN_FUC)))
  622. {
  623. if (((MFBD_REPEAT_TIME_IN_FUC) - MFBD_BTN_IN_FUC->repeat_count) > times)
  624. {
  625. MFBD_BTN_IN_FUC->repeat_count = MFBD_BTN_IN_FUC->repeat_count + times;
  626. }
  627. else
  628. {
  629. MFBD_BTN_IN_FUC->repeat_count = MFBD_REPEAT_TIME_IN_FUC;
  630. }
  631. }
  632. }
  633. #else
  634. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  635. {
  636. if ((MFBD_BTN_IN_FUC->long_count > 0) && (MFBD_BTN_IN_FUC->long_count < (MFBD_LONG_TIME_IN_FUC)))
  637. {
  638. /* if long_time is 0 or long_code is 0, disable long and repeat check. */
  639. if (((MFBD_LONG_TIME_IN_FUC) - MFBD_BTN_IN_FUC->long_count) > times)
  640. {
  641. MFBD_BTN_IN_FUC->long_count = MFBD_BTN_IN_FUC->long_count + times;
  642. }
  643. else
  644. {
  645. MFBD_BTN_IN_FUC->long_count = MFBD_LONG_TIME_IN_FUC;
  646. }
  647. }
  648. }
  649. else
  650. {
  651. /* MFBD_BTN_STATE_LONG, if(MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG) */
  652. /* we don't support repeat event here.*/
  653. }
  654. #endif /* MFBD_MBTN_MULTICLICK_LONG_EVT */
  655. #else
  656. else if (MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_DOWN)
  657. {
  658. if ((MFBD_BTN_IN_FUC->long_count > 0) && (MFBD_BTN_IN_FUC->long_count < (MFBD_LONG_TIME_IN_FUC)))
  659. {
  660. if (((MFBD_LONG_TIME_IN_FUC) - MFBD_BTN_IN_FUC->long_count) > times)
  661. {
  662. MFBD_BTN_IN_FUC->long_count = MFBD_BTN_IN_FUC->long_count + times;
  663. }
  664. else
  665. {
  666. MFBD_BTN_IN_FUC->long_count = MFBD_LONG_TIME_IN_FUC;
  667. }
  668. }
  669. }
  670. else
  671. {
  672. /* MFBD_BTN_STATE_LONG, if(MFBD_BTN_IN_FUC->state == MFBD_BTN_STATE_LONG) */
  673. if ((MFBD_BTN_IN_FUC->repeat_count > 0) && (MFBD_BTN_IN_FUC->repeat_count < (MFBD_REPEAT_TIME_IN_FUC)))
  674. {
  675. if (((MFBD_REPEAT_TIME_IN_FUC) - MFBD_BTN_IN_FUC->repeat_count) > times)
  676. {
  677. MFBD_BTN_IN_FUC->repeat_count = MFBD_BTN_IN_FUC->repeat_count + times;
  678. }
  679. else
  680. {
  681. MFBD_BTN_IN_FUC->repeat_count = MFBD_REPEAT_TIME_IN_FUC;
  682. }
  683. }
  684. }
  685. #endif /* MFBD_MBTN_CONTINUE_LONG_COUNT */
  686. _pbtn_info++;
  687. }
  688. }
  689. /**
  690. * @brief reset all multi-function buttons' params.
  691. *
  692. * @param _pbtn_info_start is a pointer to the start address in flash with type mfbd_mbtn_info_t.
  693. * @param _pbtn_info_end is a pointer to the end address in flash with type mfbd_mbtn_info_t.
  694. *
  695. * @return None.
  696. */
  697. void mfbd_mbtn_reset(const mfbd_mbtn_info_t *_pbtn_info_start, const mfbd_mbtn_info_t *_pbtn_info_end)
  698. {
  699. const mfbd_mbtn_info_t *_pbtn_info = _pbtn_info_start;
  700. while (1)
  701. {
  702. if (_pbtn_info_end <= _pbtn_info)
  703. {
  704. break;
  705. }
  706. MFBD_BTN_IN_FUC->filter_count = 0;
  707. MFBD_BTN_IN_FUC->long_count = 0;
  708. MFBD_BTN_IN_FUC->multiclick_count = 0;
  709. MFBD_BTN_IN_FUC->multiclick_state = 0;
  710. MFBD_BTN_IN_FUC->repeat_count = 0;
  711. MFBD_BTN_IN_FUC->state = MFBD_BTN_STATE_UP;
  712. _pbtn_info++;
  713. }
  714. }
  715. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  716. #endif /* MFBD_USE_SECTION_DEFINITION */