Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
[fw/altos] / src / drivers / ao_seven_segment.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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include <ao.h>
19 #include <ao_seven_segment.h>
20 #include <ao_lcd_stm.h>
21
22 /*
23  *         0
24  *      -------
25  *     |       |  
26  *   1 |       | 2
27  *     |   3   |
28  *      -------
29  *     |       |
30  *   4 |       | 5
31  *     |   6   |
32  *      -------
33  *              [] 7
34  *
35  */
36
37 #ifndef SEVEN_SEGMENT_DEBUG
38 #define SEVEN_SEGMENT_DEBUG 0
39 #endif
40
41 static const uint8_t ao_segments[] = {
42         (1 << 0) |
43         (1 << 1) |
44         (1 << 2) |
45         (0 << 3) |
46         (1 << 4) |
47         (1 << 5) |
48         (1 << 6),               /* 0 */
49
50         (0 << 0) |
51         (0 << 1) |
52         (1 << 2) |
53         (0 << 3) |
54         (0 << 4) |
55         (1 << 5) |
56         (0 << 6),               /* 1 */
57
58         (1 << 0) |
59         (0 << 1) |
60         (1 << 2) |
61         (1 << 3) |
62         (1 << 4) |
63         (0 << 5) |
64         (1 << 6),               /* 2 */
65
66         (1 << 0) |
67         (0 << 1) |
68         (1 << 2) |
69         (1 << 3) |
70         (0 << 4) |
71         (1 << 5) |
72         (1 << 6),               /* 3 */
73
74         (0 << 0) |
75         (1 << 1) |
76         (1 << 2) |
77         (1 << 3) |
78         (0 << 4) |
79         (1 << 5) |
80         (0 << 6),               /* 4 */
81
82         (1 << 0) |
83         (1 << 1) |
84         (0 << 2) |
85         (1 << 3) |
86         (0 << 4) |
87         (1 << 5) |
88         (1 << 6),               /* 5 */
89
90         (1 << 0) |
91         (1 << 1) |
92         (0 << 2) |
93         (1 << 3) |
94         (1 << 4) |
95         (1 << 5) |
96         (1 << 6),               /* 6 */
97
98         (1 << 0) |
99         (0 << 1) |
100         (1 << 2) |
101         (0 << 3) |
102         (0 << 4) |
103         (1 << 5) |
104         (0 << 6),               /* 7 */
105
106         (1 << 0) |
107         (1 << 1) |
108         (1 << 2) |
109         (1 << 3) |
110         (1 << 4) |
111         (1 << 5) |
112         (1 << 6),               /* 8 */
113
114         (1 << 0) |
115         (1 << 1) |
116         (1 << 2) |
117         (1 << 3) |
118         (0 << 4) |
119         (1 << 5) |
120         (1 << 6),               /* 9 */
121
122         (1 << 0) |
123         (1 << 1) |
124         (1 << 2) |
125         (1 << 3) |
126         (1 << 4) |
127         (1 << 5) |
128         (0 << 6),               /* A */
129
130         (0 << 0) |
131         (1 << 1) |
132         (0 << 2) |
133         (1 << 3) |
134         (1 << 4) |
135         (1 << 5) |
136         (1 << 6),               /* b */
137
138         (1 << 0) |
139         (1 << 1) |
140         (0 << 2) |
141         (0 << 3) |
142         (1 << 4) |
143         (0 << 5) |
144         (1 << 6),               /* c */
145
146         (0 << 0) |
147         (0 << 1) |
148         (1 << 2) |
149         (1 << 3) |
150         (1 << 4) |
151         (1 << 5) |
152         (1 << 6),               /* d */
153
154         (1 << 0) |
155         (1 << 1) |
156         (0 << 2) |
157         (1 << 3) |
158         (1 << 4) |
159         (0 << 5) |
160         (1 << 6),               /* E */
161
162         (1 << 0) |
163         (1 << 1) |
164         (0 << 2) |
165         (1 << 3) |
166         (1 << 4) |
167         (0 << 5) |
168         (0 << 6),               /* F */
169 };
170
171
172 void
173 ao_seven_segment_direct(uint8_t digit, uint8_t segments)
174 {
175         uint8_t s;
176
177         for (s = 0; s <= 7; s++)
178                 ao_lcd_set(digit, s, !!(segments & (1 << s)));
179         ao_lcd_flush();
180 }
181
182 void
183 ao_seven_segment_set(uint8_t digit, uint8_t value)
184 {
185         uint8_t segments;
186
187         if (value == AO_SEVEN_SEGMENT_CLEAR)
188                 segments = 0;
189         else {
190                 segments = ao_segments[value & 0xf];
191
192                 /* Check for decimal point */
193                 if (value & 0x10)
194                         segments |= (1 << 7);
195         }
196         ao_seven_segment_direct(digit, segments);
197 }
198
199 void
200 ao_seven_segment_clear(void)
201 {
202         ao_lcd_clear();
203 }
204
205
206 #if SEVEN_SEGMENT_DEBUG
207 static void
208 ao_seven_segment_show(void)
209 {
210         uint8_t digit, value;
211         ao_cmd_decimal();
212         digit = ao_cmd_lex_i;
213         ao_cmd_decimal();
214         value = ao_cmd_lex_i;
215         ao_seven_segment_set(digit, value);
216 }
217
218
219 static const struct ao_cmds ao_seven_segment_cmds[] = {
220         { ao_seven_segment_show,        "S <digit> <value>\0Set LCD digit" },
221         { 0, NULL },
222 };
223 #endif
224
225 void
226 ao_seven_segment_init(void)
227 {
228 #if SEVEN_SEGMENT_DEBUG
229         ao_cmd_register(ao_seven_segment_cmds);
230 #endif
231 }