Semi-decennial update. 50% code inflation.
[cbaos.git] / drivers / misc / debounce.c
blob1f226659ade910b5fba684a7505993bff5434626
1 /* Author: Domen Puncer Kugler <domen@cba.si>. License: WTFPL, see file LICENSE */
3 /* see A guide to debouncing: http://www.eng.utah.edu/~cs5780/debouncing.pdf */
6 /* Feature requests:
7 * - how long is the switch held
8 */
10 #include <stdio.h>
12 #include <drivers/debounce.h>
13 #include <gpio.h>
16 /* debounce_periodic should be called every 5ms or so.
17 * With 8 pulses this makes it 40ms delay, which should not be noticeable */
19 /* It is assumed debounce_register is never called after debounce_periodic */
21 #define DEBOUNCE_PULSES 8
23 static LIST_DECLARE_INIT(debounce_list);
24 //static LOCK_DECLARE_INIT(debounce_list_lock);
26 int debounce_register(struct debounce_info *deb)
28 // lock(&debounce_list_lock);
29 list_add_tail(&debounce_list, &deb->list);
30 deb->history = 0xffffff * gpio_get(deb->pin);
31 // unlock(&debounce_list_lock);
33 return 0;
36 #define DEBOUNCE_BITS_MASK ((1<<(DEBOUNCE_PULSES+1))-1) /* 0x1ff */
37 #define DEBOUNCE_BITS_FALLING (1<<DEBOUNCE_PULSES) /* 0x100 */
38 #define DEBOUNCE_BITS_RISING ((1<<DEBOUNCE_PULSES)-1) /* 0x0ff */
39 int debounce_periodic()
41 // lock(&debounce_list_lock);
42 struct list *it;
43 list_for_each(&debounce_list, it) {
44 struct debounce_info *deb = list_entry(it, struct debounce_info, list);
45 u32 h = (deb->history<<1) | gpio_get(deb->pin);
46 h &= DEBOUNCE_BITS_MASK;
47 deb->history = h;
49 if ((deb->settings & DEBOUNCE_FALLING) && h == DEBOUNCE_BITS_FALLING)
50 deb->callback(deb->pin, 0);
51 if ((deb->settings & DEBOUNCE_RISING) && h == DEBOUNCE_BITS_RISING)
52 deb->callback(deb->pin, 1);
54 // unlock(&debounce_list_lock);
55 return 0;