d2e1248f70f61e12f9fc3dee48005700ca5f8f8c
[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; 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 #include <ao_seven_segment.h>
21 #include <ao_lcd_stm.h>
22
23 /*
24  *         0
25  *      -------
26  *     |       |  
27  *   1 |       | 2
28  *     |   3   |
29  *      -------
30  *     |       |
31  *   4 |       | 5
32  *     |   6   |
33  *      -------
34  *              [] 7
35  *
36  */
37
38 #ifndef SEVEN_SEGMENT_DEBUG
39 #define SEVEN_SEGMENT_DEBUG 0
40 #endif
41
42 static const uint8_t ao_segments[] = {
43         (1 << 0) |
44         (1 << 1) |
45         (1 << 2) |
46         (0 << 3) |
47         (1 << 4) |
48         (1 << 5) |
49         (1 << 6),               /* 0 */
50
51         (0 << 0) |
52         (0 << 1) |
53         (1 << 2) |
54         (0 << 3) |
55         (0 << 4) |
56         (1 << 5) |
57         (0 << 6),               /* 1 */
58
59         (1 << 0) |
60         (0 << 1) |
61         (1 << 2) |
62         (1 << 3) |
63         (1 << 4) |
64         (0 << 5) |
65         (1 << 6),               /* 2 */
66
67         (1 << 0) |
68         (0 << 1) |
69         (1 << 2) |
70         (1 << 3) |
71         (0 << 4) |
72         (1 << 5) |
73         (1 << 6),               /* 3 */
74
75         (0 << 0) |
76         (1 << 1) |
77         (1 << 2) |
78         (1 << 3) |
79         (0 << 4) |
80         (1 << 5) |
81         (0 << 6),               /* 4 */
82
83         (1 << 0) |
84         (1 << 1) |
85         (0 << 2) |
86         (1 << 3) |
87         (0 << 4) |
88         (1 << 5) |
89         (1 << 6),               /* 5 */
90
91         (1 << 0) |
92         (1 << 1) |
93         (0 << 2) |
94         (1 << 3) |
95         (1 << 4) |
96         (1 << 5) |
97         (1 << 6),               /* 6 */
98
99         (1 << 0) |
100         (0 << 1) |
101         (1 << 2) |
102         (0 << 3) |
103         (0 << 4) |
104         (1 << 5) |
105         (0 << 6),               /* 7 */
106
107         (1 << 0) |
108         (1 << 1) |
109         (1 << 2) |
110         (1 << 3) |
111         (1 << 4) |
112         (1 << 5) |
113         (1 << 6),               /* 8 */
114
115         (1 << 0) |
116         (1 << 1) |
117         (1 << 2) |
118         (1 << 3) |
119         (0 << 4) |
120         (1 << 5) |
121         (1 << 6),               /* 9 */
122
123         (1 << 0) |
124         (1 << 1) |
125         (1 << 2) |
126         (1 << 3) |
127         (1 << 4) |
128         (1 << 5) |
129         (0 << 6),               /* A */
130
131         (0 << 0) |
132         (1 << 1) |
133         (0 << 2) |
134         (1 << 3) |
135         (1 << 4) |
136         (1 << 5) |
137         (1 << 6),               /* b */
138
139         (1 << 0) |
140         (1 << 1) |
141         (0 << 2) |
142         (0 << 3) |
143         (1 << 4) |
144         (0 << 5) |
145         (1 << 6),               /* c */
146
147         (0 << 0) |
148         (0 << 1) |
149         (1 << 2) |
150         (1 << 3) |
151         (1 << 4) |
152         (1 << 5) |
153         (1 << 6),               /* d */
154
155         (1 << 0) |
156         (1 << 1) |
157         (0 << 2) |
158         (1 << 3) |
159         (1 << 4) |
160         (0 << 5) |
161         (1 << 6),               /* E */
162
163         (1 << 0) |
164         (1 << 1) |
165         (0 << 2) |
166         (1 << 3) |
167         (1 << 4) |
168         (0 << 5) |
169         (0 << 6),               /* F */
170 };
171
172
173 void
174 ao_seven_segment_direct(uint8_t digit, uint8_t segments)
175 {
176         uint8_t s;
177
178         for (s = 0; s <= 7; s++)
179                 ao_lcd_set(digit, s, !!(segments & (1 << s)));
180         ao_lcd_flush();
181 }
182
183 void
184 ao_seven_segment_set(uint8_t digit, uint8_t value)
185 {
186         uint8_t segments;
187
188         if (value == AO_SEVEN_SEGMENT_CLEAR)
189                 segments = 0;
190         else {
191                 segments = ao_segments[value & 0xf];
192
193                 /* Check for decimal point */
194                 if (value & 0x10)
195                         segments |= (1 << 7);
196         }
197         ao_seven_segment_direct(digit, segments);
198 }
199
200 void
201 ao_seven_segment_clear(void)
202 {
203         ao_lcd_clear();
204 }
205
206
207 #if SEVEN_SEGMENT_DEBUG
208 static void
209 ao_seven_segment_show(void)
210 {
211         uint8_t digit, value;
212         ao_cmd_decimal();
213         digit = ao_cmd_lex_i;
214         ao_cmd_decimal();
215         value = ao_cmd_lex_i;
216         ao_seven_segment_set(digit, value);
217 }
218
219
220 static const struct ao_cmds ao_seven_segment_cmds[] = {
221         { ao_seven_segment_show,        "S <digit> <value>\0Set LCD digit" },
222         { 0, NULL },
223 };
224 #endif
225
226 void
227 ao_seven_segment_init(void)
228 {
229 #if SEVEN_SEGMENT_DEBUG
230         ao_cmd_register(ao_seven_segment_cmds);
231 #endif
232 }