buttons.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Xytronic LF-1600
  3. * Button routines
  4. *
  5. * Copyright (c) 2015-2017 Michael Buesch <m@bues.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. #include "buttons.h"
  22. #include "timer.h"
  23. #include <string.h>
  24. #define BUTTONS_DDR DDRB
  25. #define BUTTONS_PORT PORTB
  26. #define BUTTONS_PIN PINB
  27. #define BUTTON_BIT_IRON PB0
  28. #define BUTTON_BIT_SET PB2
  29. #define BUTTON_BIT_MINUS PB3
  30. #define BUTTON_BIT_PLUS PB4
  31. #define BUTTONS_MASK ((uint8_t)((1 << BUTTON_BIT_IRON) |\
  32. (1 << BUTTON_BIT_SET) |\
  33. (1 << BUTTON_BIT_MINUS) |\
  34. (1 << BUTTON_BIT_PLUS)))
  35. #define BUTTONS_DEBOUNCE_MS 10
  36. #define BUTTONS_ACTIVE_LOW 1
  37. struct buttons_context {
  38. uint8_t prev_state;
  39. struct timer debounce_timer;
  40. };
  41. static struct buttons_context buttons;
  42. static const uint8_t __flash button_id_to_port_mask[] = {
  43. [BUTTON_SET] = 1u << BUTTON_BIT_SET,
  44. [BUTTON_MINUS] = 1u << BUTTON_BIT_MINUS,
  45. [BUTTON_PLUS] = 1u << BUTTON_BIT_PLUS,
  46. [BUTTON_IRON] = 1u << BUTTON_BIT_IRON,
  47. };
  48. static uint8_t buttons_get_raw(void)
  49. {
  50. uint8_t state;
  51. mb();
  52. state = BUTTONS_PIN;
  53. if (BUTTONS_ACTIVE_LOW)
  54. state = (uint8_t)~state;
  55. state = (uint8_t)(state & BUTTONS_MASK);
  56. return state;
  57. }
  58. uint8_t button_is_pressed(enum button_id button)
  59. {
  60. uint8_t state, mask;
  61. mask = button_id_to_port_mask[button];
  62. state = buttons_get_raw();
  63. return state & mask;
  64. }
  65. void contrtemp_button_handler(enum button_id button,
  66. enum button_state bstate);
  67. void menu_button_handler(enum button_id button,
  68. enum button_state bstate);
  69. static void call_button_handlers(enum button_id id, enum button_state bstate)
  70. {
  71. contrtemp_button_handler(id, bstate);
  72. menu_button_handler(id, bstate);
  73. }
  74. void buttons_work(void)
  75. {
  76. uint8_t state, pos_edge, neg_edge, mask;
  77. int8_t i;
  78. enum button_id id;
  79. if (!timer_expired(&buttons.debounce_timer))
  80. return;
  81. timer_add(&buttons.debounce_timer, BUTTONS_DEBOUNCE_MS);
  82. state = buttons_get_raw();
  83. pos_edge = (state & ~buttons.prev_state) & BUTTONS_MASK;
  84. neg_edge = (~state & buttons.prev_state) & BUTTONS_MASK;
  85. buttons.prev_state = state;
  86. for (i = 0; i < NR_BUTTONS; i++) {
  87. id = (enum button_id)i;
  88. mask = button_id_to_port_mask[i];
  89. if (pos_edge & mask)
  90. call_button_handlers(id, BSTATE_POSEDGE);
  91. else if (neg_edge & mask)
  92. call_button_handlers(id, BSTATE_NEGEDGE);
  93. if (state & mask)
  94. call_button_handlers(id, BSTATE_PRESSED);
  95. }
  96. }
  97. void buttons_init(void)
  98. {
  99. BUTTONS_DDR &= (uint8_t)~BUTTONS_MASK;
  100. BUTTONS_PORT |= BUTTONS_MASK;
  101. _delay_ms(50);
  102. timer_set_now(&buttons.debounce_timer);
  103. }