2 * Copyright © 2011 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 volatile __xdata struct ao_fifo ao_button_fifo;
22 static __code struct {
27 { BUTTON_1_MASK, BUTTON_1_REG },
30 { BUTTON_2_MASK, BUTTON_2_REG },
33 { BUTTON_3_MASK, BUTTON_3_REG },
37 #define NUM_BUTTONS ((sizeof ao_buttons) / sizeof (ao_buttons[0]))
39 static __xdata uint16_t ao_button_tick[NUM_BUTTONS];
42 ao_button_insert(char n)
44 uint16_t now = ao_time();
45 if ((now - ao_button_tick[n]) > 20) {
46 ao_button_tick[n] = now;
47 ao_fifo_insert(ao_button_fifo, n);
48 ao_wakeup(&ao_button_fifo);
53 ao_button_isr(uint8_t flag, uint8_t reg)
57 for (b = 0; b < NUM_BUTTONS; b++)
58 if (ao_buttons[b].reg == reg && (ao_buttons[b].mask & flag))
59 ao_button_insert(b + 1);
63 ao_button_mask(uint8_t reg)
68 for (b = 0; b < NUM_BUTTONS; b++)
69 if (ao_buttons[b].reg == reg)
70 mask |= ao_buttons[b].mask;
75 ao_button_get(void) __critical
79 while (ao_fifo_empty(ao_button_fifo))
80 if (ao_sleep(&ao_button_fifo))
82 ao_fifo_remove(ao_button_fifo, b);
87 ao_button_clear(void) __critical
91 while (!ao_fifo_empty(ao_button_fifo))
92 ao_fifo_remove(ao_button_fifo, b);
96 ao_p0_isr(void) ao_arch_interrupt(13)
99 ao_button_isr(P0IFG, 0);
104 ao_p1_isr(void) ao_arch_interrupt(15)
107 ao_button_isr(P1IFG, 1);
111 /* Shared with USB */
115 ao_button_isr(P2IFG, 2);
124 /* Pins are configured as inputs with pull-up by default */
126 /* Enable interrupts for P0 inputs */
127 mask = ao_button_mask(0);
130 PICTL |= PICTL_P0IENL;
132 PICTL |= PICTL_P0IENH;
136 PICTL |= PICTL_P0ICON;
139 /* Enable interrupts for P1 inputs */
140 mask = ao_button_mask(1);
146 PICTL |= PICTL_P1ICON;
149 /* Enable interrupts for P2 inputs */
150 mask = ao_button_mask(2);
152 PICTL |= PICTL_P2IEN;
156 PICTL |= PICTL_P2ICON;