components/u8g2/csrc/u8x8_debounce.c

changeset 0
88d965579617
equal deleted inserted replaced
-1:000000000000 0:88d965579617
1 /*
2
3 u8x8_debounce.c
4
5 Key/button simple debounce algorithm (Addon for u8x8)
6
7 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
8
9 Copyright (c) 2016, olikraus@gmail.com
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 * Redistributions of source code must retain the above copyright notice, this list
16 of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above copyright notice, this
19 list of conditions and the following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36 */
37
38 #include "u8x8.h"
39
40 static uint8_t u8x8_read_pin_state(u8x8_t *u8x8)
41 {
42 uint8_t i;
43 uint8_t pin_state;
44
45 pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */
46 for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ )
47 {
48 pin_state <<= 1;
49
50 /* the callback function should put the return value into this variable */
51 u8x8->gpio_result = 1;
52 u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0);
53 pin_state |= u8x8->gpio_result & 1;
54 }
55
56 return pin_state;
57 }
58
59 /*
60 return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference
61 return U8X8_PIN_INPUT_CNT if there is no difference
62 */
63 static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b)
64 {
65 uint8_t mask;
66 uint8_t i;
67 mask = 1;
68 i = U8X8_PIN_INPUT_CNT;
69 do
70 {
71 i--;
72 if ( (a & mask) != (b & mask) )
73 return i;
74 mask <<= 1;
75 } while( i > 0 );
76 return U8X8_PIN_INPUT_CNT;
77 }
78
79 /*
80 State A:
81 u8x8->debounce_last_pin_state == current_state
82 --> State A
83 u8x8->debounce_last_pin_state != current_state
84 --> u8x8->debounce_last_pin_state = current_state
85 --> State B + cnt
86
87 State B + cnt
88 --> state--
89
90 State B
91 u8x8->debounce_last_pin_state == current_state
92 --> keypress detected
93 --> State C
94 u8x8->debounce_last_pin_state != current_state
95 --> State A
96
97 State C
98 u8x8->debounce_last_pin_state == current_state
99 --> State C
100 u8x8->debounce_last_pin_state != current_state
101 --> State A
102
103 */
104
105 #ifdef __unix__xxxxxx_THIS_IS_DISABLED
106
107 #include <stdio.h>
108 #include <stdlib.h>
109 uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
110 {
111 int c;
112 c = getc(stdin);
113 switch(c)
114 {
115 case 'n':
116 return U8X8_MSG_GPIO_MENU_NEXT;
117 case 'p':
118 return U8X8_MSG_GPIO_MENU_PREV;
119 case 's':
120 return U8X8_MSG_GPIO_MENU_SELECT;
121 case 'h':
122 return U8X8_MSG_GPIO_MENU_HOME;
123 case 'x':
124 exit(0);
125 default:
126 puts("press n, p, s, h or x");
127 break;
128 }
129 return 0;
130 }
131
132
133 #else /* __unix__ */
134
135
136 #define U8X8_DEBOUNCE_WAIT 2
137 /* do debounce and return a GPIO msg which indicates the event */
138 /* returns 0, if there is no event */
139 #if defined(__GNUC__) && !defined(__CYGWIN__)
140 # pragma weak u8x8_GetMenuEvent
141 #endif
142 uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
143 {
144 uint8_t pin_state;
145 uint8_t result_msg = 0; /* invalid message, no event */
146
147 pin_state = u8x8_read_pin_state(u8x8);
148
149 /* States A, B, C & D are encoded in the upper 4 bit*/
150 switch(u8x8->debounce_state)
151 {
152 case 0x00: /* State A, default state */
153 if ( u8x8->debounce_default_pin_state != pin_state )
154 {
155 //u8x8->debounce_last_pin_state = pin_state;
156 u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT;
157 }
158 break;
159 case 0x10: /* State B */
160 //if ( u8x8->debounce_last_pin_state != pin_state )
161 if ( u8x8->debounce_default_pin_state == pin_state )
162 {
163 u8x8->debounce_state = 0x00; /* back to state A */
164 }
165 else
166 {
167 /* keypress detected */
168 u8x8->debounce_last_pin_state = pin_state;
169 //result_msg = U8X8_MSG_GPIO_MENU_NEXT;
170 u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */
171 }
172 break;
173
174 case 0x20: /* State C */
175 if ( u8x8->debounce_last_pin_state != pin_state )
176 {
177 u8x8->debounce_state = 0x00; /* back to state A */
178 }
179 else
180 {
181 u8x8->debounce_state = 0x030; /* got to state D */
182 }
183 break;
184
185 case 0x30: /* State D */
186 /* wait until key release */
187 if ( u8x8->debounce_default_pin_state == pin_state )
188 {
189 u8x8->debounce_state = 0x00; /* back to state A */
190 result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT);
191 }
192 else
193 {
194 //result_msg = U8X8_MSG_GPIO_MENU_NEXT;
195 // maybe implement autorepeat here
196 }
197 break;
198 default:
199 u8x8->debounce_state--; /* count down, until there is a valid state */
200 break;
201 }
202 return result_msg;
203 }
204
205 #endif /* __unix__ */

mercurial