volatile __xdata struct ao_fifo ao_button_fifo;
-#define BUTTON_1_PIN (P0_4)
-#define BUTTON_1_MASK (1 << 4) /* P0_4 */
+static __code struct {
+ uint8_t mask;
+ uint8_t reg;
+} ao_buttons[] = {
+#ifdef BUTTON_1_MASK
+ { BUTTON_1_MASK, BUTTON_1_REG },
+#endif
+#ifdef BUTTON_2_MASK
+ { BUTTON_2_MASK, BUTTON_2_REG },
+#endif
+#ifdef BUTTON_3_MASK
+ { BUTTON_3_MASK, BUTTON_3_REG },
+#endif
+};
-#define BUTTON_2_PIN (P2_3)
-#define BUTTON_2_MASK (1 << 3) /* P2_3 */
-
-#define BUTTON_3_PIN (P2_4)
-#define BUTTON_3_MASK (1 << 4) /* P2_4 */
+#define NUM_BUTTONS ((sizeof ao_buttons) / sizeof (ao_buttons[0]))
static void
ao_button_insert(char n)
ao_wakeup(&ao_button_fifo);
}
+static void
+ao_button_isr(uint8_t flag, uint8_t reg)
+{
+ uint8_t b;
+
+ for (b = 0; b < NUM_BUTTONS; b++)
+ if (ao_buttons[b].reg == reg && (ao_buttons[b].mask & flag))
+ ao_button_insert(b + 1);
+}
+
+static uint8_t
+ao_button_mask(uint8_t reg)
+{
+ uint8_t b;
+ uint8_t mask = 0;
+
+ for (b = 0; b < NUM_BUTTONS; b++)
+ if (ao_buttons[b].reg == reg)
+ mask |= ao_buttons[b].mask;
+ return mask;
+}
+
char
ao_button_get(void) __critical
{
char b;
while (ao_fifo_empty(ao_button_fifo))
- ao_sleep(&ao_button_fifo);
+ if (ao_sleep(&ao_button_fifo))
+ return 0;
ao_fifo_remove(ao_button_fifo, b);
return b;
}
void
-ao_p2_isr(void)
+ao_p0_isr(void) ao_arch_interrupt(13)
{
- if (P2IFG & BUTTON_2_MASK)
- ao_button_insert(2);
- if (P2IFG & BUTTON_3_MASK)
- ao_button_insert(3);
- P2IFG = 0;
+ P0IF = 0;
+ ao_button_isr(P0IFG, 0);
+ P0IFG = 0;
}
void
-ao_p0_isr(void) ao_arch_interrupt(13)
+ao_p1_isr(void) ao_arch_interrupt(15)
{
- P0IF = 0;
- if (P0IFG & BUTTON_1_MASK)
- ao_button_insert(1);
- P0IFG = 0;
+ P1IF = 0;
+ ao_button_isr(P1IFG, 1);
+ P1IFG = 0;
+}
+
+/* Shared with USB */
+void
+ao_p2_isr(void)
+{
+ ao_button_isr(P2IFG, 2);
+ P2IFG = 0;
}
void
ao_button_init(void)
{
+ uint8_t mask;
+
/* Pins are configured as inputs with pull-up by default */
- /* Enable interrupts for P2_0 - P2_4
- * Enable interrupts for P0_4 - P0_7
- * Set P2 interrupts to falling edge
- * Set P0 interrupts to falling edge
- */
-
/* Enable interrupts for P0 inputs */
- IEN1 |= IEN1_P0IE;
+ mask = ao_button_mask(0);
+ if (mask) {
+ if (mask & 0x0f)
+ PICTL |= PICTL_P0IENL;
+ if (mask & 0xf0)
+ PICTL |= PICTL_P0IENH;
+ P0IFG = 0;
+ P0IF = 0;
+ IEN1 |= IEN1_P0IE;
+ PICTL |= PICTL_P0ICON;
+ }
- /* Enable interrupts for P2 inputs */
- IEN2 |= IEN2_P2IE;
+ /* Enable interrupts for P1 inputs */
+ mask = ao_button_mask(1);
+ if (mask) {
+ P1IEN |= mask;
+ P1IFG = 0;
+ P1IF = 0;
+ IEN2 |= IEN2_P1IE;
+ PICTL |= PICTL_P1ICON;
+ }
- PICTL |= PICTL_P2IEN | PICTL_P0IENH | PICTL_P2ICON | PICTL_P0ICON;
+ /* Enable interrupts for P2 inputs */
+ mask = ao_button_mask(2);
+ if (mask) {
+ PICTL |= PICTL_P2IEN;
+ P2IFG = 0;
+ P2IF = 0;
+ IEN2 |= IEN2_P2IE;
+ PICTL |= PICTL_P2ICON;
+ }
}