altos: Bring up basic TeleTerra v0.2 UI
[fw/altos] / src / cc1111 / ao_button.c
index 3516d55960ebcc7b6c038ff3e779550f23d1873a..77a8dde8b6918f4bbaeb49e7b4199d0c2b20ef84 100644 (file)
 
 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)
@@ -35,52 +43,101 @@ 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;
+       }
 }