You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

204 lines
6.2 KiB

  1. /***************************************************************************
  2. * Copyright (C) 11/2014 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License, *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <avr/io.h>
  20. #include <avr/interrupt.h>
  21. #include "event.h"
  22. #include "input.h"
  23. #include "timer.h"
  24. /* *********************************************************************** */
  25. #define INPUT_DEBOUNCE_TIMER 60
  26. /* *********************************************************************** */
  27. static uint8_t pcint_old;
  28. static uint8_t quad_state;
  29. static uint8_t quad_state_old;
  30. static uint8_t debounce_timer[2];
  31. static uint8_t input_old_state[2];
  32. /* *********************************************************************** */
  33. static void input_send_event(uint8_t type, uint8_t num, uint8_t state)
  34. {
  35. if ((debounce_timer[num] == 0) &&
  36. (state != input_old_state[num])
  37. )
  38. {
  39. debounce_timer[num] = 1;
  40. event_queue(type, num, state);
  41. event_queue(EVENT_TYPE_TIMER_SET, num, INPUT_DEBOUNCE_TIMER);
  42. input_old_state[num] = state;
  43. }
  44. } /* input_send_event */
  45. ISR(PCINT1_vect)
  46. {
  47. uint8_t pcint_new = PINC & PCMSK1;
  48. uint8_t pcint = pcint_new ^ pcint_old;
  49. uint8_t quad_state_new = quad_state;
  50. /* quadruple decoder A changed */
  51. if (pcint & (1<<PINC0))
  52. {
  53. /* positive edge */
  54. if (pcint_new & (1<<PINC0))
  55. {
  56. if ((quad_state == 0) || (quad_state == 2))
  57. {
  58. quad_state_new++;
  59. }
  60. }
  61. /* negative edge */
  62. else
  63. {
  64. if ((quad_state == 1) || (quad_state == 3))
  65. {
  66. quad_state_new--;
  67. }
  68. }
  69. }
  70. /* quadruple decoder B changed */
  71. else if (pcint & (1<<PINC1))
  72. {
  73. /* positive edge */
  74. if (pcint_new & (1<<PINC1))
  75. {
  76. if ((quad_state == 0) || (quad_state == 1))
  77. {
  78. quad_state_new += 2;
  79. }
  80. }
  81. /* negative edge */
  82. else
  83. {
  84. if ((quad_state == 2) || (quad_state == 3))
  85. {
  86. quad_state_new -= 2;
  87. }
  88. }
  89. }
  90. /* quadruple decoder switch changed */
  91. else if (pcint & (1<<PINC2))
  92. {
  93. input_send_event(EVENT_TYPE_INPUT_BUTTON,
  94. EVENT_NUM_INPUT_BUTTON,
  95. !!(pcint_new & (1<<PINC2)));
  96. }
  97. /* door switch changed */
  98. else if (pcint & (1<<PINC3))
  99. {
  100. input_send_event(EVENT_TYPE_INPUT_SWITCH,
  101. EVENT_NUM_INPUT_DOOR,
  102. !(pcint_new & (1<<PINC3)));
  103. }
  104. /* one revolution completed? */
  105. if ((quad_state_new == 3) && (quad_state_old == 0))
  106. {
  107. /* counter clock wise */
  108. if (quad_state == 1)
  109. {
  110. event_queue(EVENT_TYPE_INPUT_INCDEC,
  111. EVENT_NUM_INPUT_QUAD,
  112. EVENT_VALUE_INPUT_QUAD_DEC);
  113. }
  114. /* clock wise */
  115. else if (quad_state == 2)
  116. {
  117. event_queue(EVENT_TYPE_INPUT_INCDEC,
  118. EVENT_NUM_INPUT_QUAD,
  119. EVENT_VALUE_INPUT_QUAD_INC);
  120. }
  121. }
  122. /* remember every two states */
  123. if ((quad_state_new == 0) || (quad_state_new == 3))
  124. {
  125. quad_state_old = quad_state_new;
  126. }
  127. quad_state = quad_state_new;
  128. pcint_old = pcint_new;
  129. } /* PCINT1_vect */
  130. void input_event_handler(struct event_entry *event)
  131. {
  132. if (event->type == EVENT_TYPE_TIMER_ELAPSED)
  133. {
  134. if (event->num == EVENT_NUM_TIMER_DEBOUNCE1)
  135. {
  136. debounce_timer[EVENT_NUM_INPUT_BUTTON] = 0;
  137. input_send_event(EVENT_TYPE_INPUT_SWITCH,
  138. EVENT_NUM_INPUT_BUTTON,
  139. !!(PINC & (1<<PINC2)));
  140. }
  141. else if (event->num == EVENT_NUM_TIMER_DEBOUNCE2)
  142. {
  143. debounce_timer[EVENT_NUM_INPUT_DOOR] = 0;
  144. input_send_event(EVENT_TYPE_INPUT_SWITCH,
  145. EVENT_NUM_INPUT_DOOR,
  146. !!(PINC & (1<<PINC3)));
  147. }
  148. }
  149. } /* input_event_handler */
  150. uint8_t input_get_sleep_mode(void)
  151. {
  152. return SLEEP_MODE_PWR_DOWN;
  153. } /* input_get_sleep_mode */
  154. void input_init(void)
  155. {
  156. /* pullup on all inputs */
  157. DDRC &= ~((1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0));
  158. PORTC |= (1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0);
  159. /* Pinchange Interrupts enabled */
  160. PCMSK1 = (1<<PCINT11) | (1<<PCINT10) | (1<<PCINT9) | (1<<PCINT8);
  161. PCICR = (1<<PCIE1);
  162. /* initial pin interrupt state */
  163. pcint_old = PINC & PCMSK1;
  164. /* initial quadruple decoder state */
  165. quad_state = PINC & ((1<<PINC0) | (1<<PINC1));
  166. /* send button state */
  167. input_send_event(EVENT_TYPE_INPUT_BUTTON,
  168. EVENT_NUM_INPUT_BUTTON,
  169. !!(PINC & (1<<PINC2)));
  170. /* send door state */
  171. input_send_event(EVENT_TYPE_INPUT_SWITCH,
  172. EVENT_NUM_INPUT_DOOR,
  173. !(PINC & (1<<PINC3)));
  174. } /* input_init */