altos/micropeak-v2: Erase log space at end of BOOST_DELAY
[fw/altos] / src / stmf0 / ao_led_stmf0.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
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; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "ao.h"
20
21 void
22 ao_led_on(AO_LED_TYPE colors)
23 {
24 #ifdef LED_PORT
25         LED_PORT->bsrr = (colors & LEDS_AVAILABLE);
26 #else
27 #ifdef LED_PORT_0
28         LED_PORT_0->bsrr = ((colors & LEDS_AVAILABLE) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
29 #endif
30 #ifdef LED_PORT_1
31         LED_PORT_1->bsrr = ((colors & LEDS_AVAILABLE) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
32 #endif
33 #endif
34 }
35
36 void
37 ao_led_off(AO_LED_TYPE colors)
38 {
39 #ifdef LED_PORT
40         LED_PORT->bsrr = (uint32_t) (colors & LEDS_AVAILABLE) << 16;
41 #else
42 #ifdef LED_PORT_0
43         LED_PORT_0->bsrr = ((uint32_t) (colors & LEDS_AVAILABLE) & LED_PORT_0_MASK) << (LED_PORT_0_SHIFT + 16);
44 #endif
45 #ifdef LED_PORT_1
46         LED_PORT_1->bsrr = ((uint32_t) (colors & LEDS_AVAILABLE) & LED_PORT_1_MASK) << (LED_PORT_1_SHIFT + 16);
47 #endif
48 #endif
49 }
50
51 void
52 ao_led_set(AO_LED_TYPE colors)
53 {
54         AO_LED_TYPE     on = colors & LEDS_AVAILABLE;
55         AO_LED_TYPE     off = ~colors & LEDS_AVAILABLE;
56
57         ao_led_off(off);
58         ao_led_on(on);
59 }
60
61 void
62 ao_led_toggle(AO_LED_TYPE colors)
63 {
64 #ifdef LED_PORT
65         LED_PORT->odr ^= (colors & LEDS_AVAILABLE);
66 #else
67 #ifdef LED_PORT_0
68         LED_PORT_0->odr ^= ((colors & LEDS_AVAILABLE) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
69 #endif
70 #ifdef LED_PORT_1
71         LED_PORT_1->odr ^= ((colors & LEDS_AVAILABLE) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
72 #endif
73 #endif
74 }
75
76 void
77 ao_led_for(AO_LED_TYPE colors, AO_TICK_TYPE ticks) 
78 {
79         ao_led_on(colors);
80         ao_delay(ticks);
81         ao_led_off(colors);
82 }
83
84 #define init_led_pin(port, bit) do { \
85                 stm_moder_set(port, bit, STM_MODER_OUTPUT);             \
86                 stm_otyper_set(port, bit, STM_OTYPER_PUSH_PULL);        \
87         } while (0)
88
89 void
90 ao_led_init(void)
91 {
92         int     bit;
93
94 #ifdef LED_PORT
95         stm_rcc.ahbenr |= (1 << LED_PORT_ENABLE);
96         LED_PORT->odr &= ~LEDS_AVAILABLE;
97 #else
98 #ifdef LED_PORT_0
99         stm_rcc.ahbenr |= (1 << LED_PORT_0_ENABLE);
100         LED_PORT_0->odr &= (uint32_t) ~(LEDS_AVAILABLE & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
101 #endif
102 #ifdef LED_PORT_1
103         stm_rcc.ahbenr |= (1 << LED_PORT_1_ENABLE);
104         LED_PORT_1->odr &= (uint32_t) ~(LEDS_AVAILABLE & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
105 #endif
106 #endif
107         for (bit = 0; bit < 16; bit++) {
108                 if (LEDS_AVAILABLE & (1 << bit)) {
109 #ifdef LED_PORT
110                         init_led_pin(LED_PORT, bit);
111 #else
112 #ifdef LED_PORT_0
113                         if (LED_PORT_0_MASK & (1 << bit))
114                                 init_led_pin(LED_PORT_0, bit + LED_PORT_0_SHIFT);
115 #endif
116 #ifdef LED_PORT_1
117                         if (LED_PORT_1_MASK & (1 << bit))
118                                 init_led_pin(LED_PORT_1, bit + LED_PORT_1_SHIFT);
119 #endif
120 #endif
121                 }
122         }
123 }