altos: Add support for TeleBT v3.0
[fw/altos] / src / stm / ao_led.c
index 0574aa2a087ce33bb46831f1bbdfc0aa8d599d3e..9b61cf622e6f7e1fef9a05e47b4663b49a3f9c8d 100644 (file)
 
 #include "ao.h"
 
-__pdata uint8_t ao_led_enable;
+__pdata uint16_t ao_led_enable;
 
 void
-ao_led_on(uint8_t colors)
+ao_led_on(uint16_t colors)
 {
-       LED_PORT.odr |= (colors & ao_led_enable);
+#ifdef LED_PORT
+       LED_PORT->bsrr = (colors & ao_led_enable);
+#else
+#ifdef LED_PORT_0
+       LED_PORT_0->bsrr = ((colors & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
+#endif
+#ifdef LED_PORT_1
+       LED_PORT_1->bsrr = ((colors & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
+#endif
+#endif
 }
 
 void
-ao_led_off(uint8_t colors)
+ao_led_off(uint16_t colors)
 {
-       LED_PORT.odr &= ~(colors & ao_led_enable);
+#ifdef LED_PORT
+       LED_PORT->bsrr = (uint32_t) (colors & ao_led_enable) << 16;
+#else
+#ifdef LED_PORT_0
+       LED_PORT_0->bsrr = ((uint32_t) (colors & ao_led_enable) & LED_PORT_0_MASK) << (LED_PORT_0_SHIFT + 16);
+#endif
+#ifdef LED_PORT_1
+       LED_PORT_1->bsrr = ((uint32_t) (colors & ao_led_enable) & LED_PORT_1_MASK) << (LED_PORT_1_SHIFT + 16);
+#endif
+#endif
 }
 
 void
-ao_led_set(uint8_t colors)
+ao_led_set(uint16_t colors)
 {
-       LED_PORT.odr = (LED_PORT.odr & ~(ao_led_enable)) | (colors & ao_led_enable);
+       uint16_t        on = colors & ao_led_enable;
+       uint16_t        off = ~colors & ao_led_enable;
+
+       ao_led_off(off);
+       ao_led_on(on);
 }
 
 void
-ao_led_toggle(uint8_t colors)
+ao_led_toggle(uint16_t colors)
 {
-       LED_PORT.odr ^= (colors & ao_led_enable);
+#ifdef LED_PORT
+       LED_PORT->odr ^= (colors & ao_led_enable);
+#else
+#ifdef LED_PORT_0
+       LED_PORT_0->odr ^= ((colors & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
+#endif
+#ifdef LED_PORT_1
+       LED_PORT_1->odr ^= ((colors & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
+#endif
+#endif
 }
 
 void
-ao_led_for(uint8_t colors, uint16_t ticks) __reentrant
+ao_led_for(uint16_t colors, uint16_t ticks) __reentrant
 {
        ao_led_on(colors);
        ao_delay(ticks);
        ao_led_off(colors);
 }
 
+#define init_led_pin(port, bit) do { \
+               stm_moder_set(port, bit, STM_MODER_OUTPUT);             \
+               stm_otyper_set(port, bit, STM_OTYPER_PUSH_PULL);        \
+       } while (0)
+
 void
-ao_led_init(uint8_t enable)
+ao_led_init(uint16_t enable)
 {
        int     bit;
 
-       stm_rcc.ahbenr |= (1 << LED_PORT_ENABLE);
        ao_led_enable = enable;
-       LED_PORT.odr &= ~enable;
+#ifdef LED_PORT
+       stm_rcc.ahbenr |= (1 << LED_PORT_ENABLE);
+       LED_PORT->odr &= ~enable;
+#else
+#ifdef LED_PORT_0
+       stm_rcc.ahbenr |= (1 << LED_PORT_0_ENABLE);
+       LED_PORT_0->odr &= ~((enable & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
+#endif
+#ifdef LED_PORT_1
+       stm_rcc.ahbenr |= (1 << LED_PORT_1_ENABLE);
+       LED_PORT_1->odr &= ~((enable & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
+#endif
+#endif
        for (bit = 0; bit < 16; bit++) {
                if (enable & (1 << bit)) {
-                       stm_moder_set(&LED_PORT, bit, STM_MODER_OUTPUT);
-                       stm_otyper_set(&LED_PORT, bit, STM_OTYPER_PUSH_PULL);
+#ifdef LED_PORT
+                       init_led_pin(LED_PORT, bit);
+#else
+#ifdef LED_PORT_0
+                       if (LED_PORT_0_MASK & (1 << bit))
+                               init_led_pin(LED_PORT_0, bit + LED_PORT_0_SHIFT);
+#endif
+#ifdef LED_PORT_1
+                       if (LED_PORT_1_MASK & (1 << bit))
+                               init_led_pin(LED_PORT_1, bit + LED_PORT_1_SHIFT);
+#endif
+#endif
                }
        }
 }