0f39befb9426843f1f63d260ff9c77509b187351
[fw/altos] / src / stmf0 / ao_led.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 __pdata uint16_t ao_led_enable;
22
23 void
24 ao_led_on(uint16_t colors)
25 {
26 #ifdef LED_PORT
27         LED_PORT->bsrr = (colors & ao_led_enable);
28 #else
29 #ifdef LED_PORT_0
30         LED_PORT_0->bsrr = ((colors & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
31 #endif
32 #ifdef LED_PORT_1
33         LED_PORT_1->bsrr = ((colors & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
34 #endif
35 #endif
36 }
37
38 void
39 ao_led_off(uint16_t colors)
40 {
41 #ifdef LED_PORT
42         LED_PORT->bsrr = (uint32_t) (colors & ao_led_enable) << 16;
43 #else
44 #ifdef LED_PORT_0
45         LED_PORT_0->bsrr = ((uint32_t) (colors & ao_led_enable) & LED_PORT_0_MASK) << (LED_PORT_0_SHIFT + 16);
46 #endif
47 #ifdef LED_PORT_1
48         LED_PORT_1->bsrr = ((uint32_t) (colors & ao_led_enable) & LED_PORT_1_MASK) << (LED_PORT_1_SHIFT + 16);
49 #endif
50 #endif
51 }
52
53 void
54 ao_led_set(uint16_t colors)
55 {
56         uint16_t        on = colors & ao_led_enable;
57         uint16_t        off = ~colors & ao_led_enable;
58
59         ao_led_off(off);
60         ao_led_on(on);
61 }
62
63 void
64 ao_led_toggle(uint16_t colors)
65 {
66 #ifdef LED_PORT
67         LED_PORT->odr ^= (colors & ao_led_enable);
68 #else
69 #ifdef LED_PORT_0
70         LED_PORT_0->odr ^= ((colors & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
71 #endif
72 #ifdef LED_PORT_1
73         LED_PORT_1->odr ^= ((colors & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
74 #endif
75 #endif
76 }
77
78 void
79 ao_led_for(uint16_t colors, uint16_t ticks) __reentrant
80 {
81         ao_led_on(colors);
82         ao_delay(ticks);
83         ao_led_off(colors);
84 }
85
86 #define init_led_pin(port, bit) do { \
87                 stm_moder_set(port, bit, STM_MODER_OUTPUT);             \
88                 stm_otyper_set(port, bit, STM_OTYPER_PUSH_PULL);        \
89         } while (0)
90
91 void
92 ao_led_init(uint16_t enable)
93 {
94         int     bit;
95
96         ao_led_enable = enable;
97 #ifdef LED_PORT
98         stm_rcc.ahbenr |= (1 << LED_PORT_ENABLE);
99         LED_PORT->odr &= ~enable;
100 #else
101 #ifdef LED_PORT_0
102         stm_rcc.ahbenr |= (1 << LED_PORT_0_ENABLE);
103         LED_PORT_0->odr &= ~((enable & ao_led_enable) & LED_PORT_0_MASK) << LED_PORT_0_SHIFT;
104 #endif
105 #ifdef LED_PORT_1
106         stm_rcc.ahbenr |= (1 << LED_PORT_1_ENABLE);
107         LED_PORT_1->odr &= ~((enable & ao_led_enable) & LED_PORT_1_MASK) << LED_PORT_1_SHIFT;
108 #endif
109 #endif
110         for (bit = 0; bit < 16; bit++) {
111                 if (enable & (1 << bit)) {
112 #ifdef LED_PORT
113                         init_led_pin(LED_PORT, bit);
114 #else
115 #ifdef LED_PORT_0
116                         if (LED_PORT_0_MASK & (1 << bit))
117                                 init_led_pin(LED_PORT_0, bit + LED_PORT_0_SHIFT);
118 #endif
119 #ifdef LED_PORT_1
120                         if (LED_PORT_1_MASK & (1 << bit))
121                                 init_led_pin(LED_PORT_1, bit + LED_PORT_1_SHIFT);
122 #endif
123 #endif
124                 }
125         }
126 }