xref: /netbsd/sys/arch/evbarm/iq31244/iq31244_7seg.c (revision 6550d01e)
1 /*	$NetBSD: iq31244_7seg.c,v 1.4 2005/12/24 20:06:59 perry Exp $	*/
2 
3 /*
4  * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed for the NetBSD Project by
20  *	Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * Support for the 7-segment display on the Intel IQ31244.
40  */
41 
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: iq31244_7seg.c,v 1.4 2005/12/24 20:06:59 perry Exp $");
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 
48 #include <machine/bus.h>
49 
50 #include <evbarm/iq80321/iq80321reg.h>
51 #include <evbarm/iq80321/iq80321var.h>
52 
53 #define	WRITE(x, v)	*((volatile uint8_t *) (x)) = (v)
54 
55 static int snakestate;
56 
57 /*
58  * The 7-segment display looks like so:
59  *
60  *         A
61  *	+-----+
62  *	|     |
63  *    F	|     | B
64  *	|  G  |
65  *	+-----+
66  *	|     |
67  *    E	|     | C
68  *	|  D  |
69  *	+-----+ o  DP
70  *
71  * Setting a bit clears the corresponding segment on the
72  * display.
73  */
74 #define	SEG_A			(1 << 0)
75 #define	SEG_B			(1 << 1)
76 #define	SEG_C			(1 << 2)
77 #define	SEG_D			(1 << 3)
78 #define	SEG_E			(1 << 4)
79 #define	SEG_F			(1 << 5)
80 #define	SEG_G			(1 << 6)
81 #define	SEG_DP			(1 << 7)
82 
83 static const uint8_t digitmap[] = {
84 /*	+#####+
85  *	#     #
86  *	#     #
87  *	#     #
88  *	+-----+
89  *	#     #
90  *	#     #
91  *	#     #
92  *	+#####+
93  */
94 	SEG_G,
95 
96 /*	+-----+
97  *	|     #
98  *	|     #
99  *	|     #
100  *	+-----+
101  *	|     #
102  *	|     #
103  *	|     #
104  *	+-----+
105  */
106 	SEG_A|SEG_D|SEG_E|SEG_F|SEG_G,
107 
108 /*	+#####+
109  *	|     #
110  *	|     #
111  *	|     #
112  *	+#####+
113  *	#     |
114  *	#     |
115  *	#     |
116  *	+#####+
117  */
118 	SEG_C|SEG_F,
119 
120 /*	+#####+
121  *	|     #
122  *	|     #
123  *	|     #
124  *	+#####+
125  *	|     #
126  *	|     #
127  *	|     #
128  *	+#####+
129  */
130 	SEG_E|SEG_F,
131 
132 /*	+-----+
133  *	#     #
134  *	#     #
135  *	#     #
136  *	+#####+
137  *	|     #
138  *	|     #
139  *	|     #
140  *	+-----+
141  */
142 	SEG_A|SEG_D|SEG_E,
143 
144 /*	+#####+
145  *	#     |
146  *	#     |
147  *	#     |
148  *	+#####+
149  *	|     #
150  *	|     #
151  *	|     #
152  *	+#####+
153  */
154 	SEG_B|SEG_E,
155 
156 /*	+#####+
157  *	#     |
158  *	#     |
159  *	#     |
160  *	+#####+
161  *	#     #
162  *	#     #
163  *	#     #
164  *	+#####+
165  */
166 	SEG_B,
167 
168 /*	+#####+
169  *	|     #
170  *	|     #
171  *	|     #
172  *	+-----+
173  *	|     #
174  *	|     #
175  *	|     #
176  *	+-----+
177  */
178 	SEG_D|SEG_E|SEG_F,
179 
180 /*	+#####+
181  *	#     #
182  *	#     #
183  *	#     #
184  *	+#####+
185  *	#     #
186  *	#     #
187  *	#     #
188  *	+#####+
189  */
190 	0,
191 
192 /*	+#####+
193  *	#     #
194  *	#     #
195  *	#     #
196  *	+#####+
197  *	|     #
198  *	|     #
199  *	|     #
200  *	+-----+
201  */
202 	SEG_D|SEG_E,
203 };
204 
205 static uint8_t
206 iq80321_7seg_xlate(char c)
207 {
208 	uint8_t rv;
209 
210 	if (c >= '0' && c <= '9')
211 		rv = digitmap[c - '0'];
212 	else if (c == '.')
213 		rv = (uint8_t) ~SEG_DP;
214 	else
215 		rv = 0xff;
216 
217 	return (rv);
218 }
219 
220 void
221 iq80321_7seg(char a, char b)
222 {
223 	uint8_t msb, lsb;
224 
225 	msb = iq80321_7seg_xlate(a);
226 	lsb = iq80321_7seg_xlate(b);
227 
228 	snakestate = 0;
229 
230 	WRITE(IQ80321_7SEG_MSB, msb);
231 	WRITE(IQ80321_7SEG_LSB, lsb);
232 }
233 
234 static const uint8_t snakemap[][2] = {
235 
236 /*	+#####+		+#####+
237  *	|     |		|     |
238  *	|     |		|     |
239  *	|     |		|     |
240  *	+-----+		+-----+
241  *	|     |		|     |
242  *	|     |		|     |
243  *	|     |		|     |
244  *	+-----+		+-----+
245  */
246 	{ ~SEG_A,	~SEG_A },
247 
248 /*	+-----+		+-----+
249  *	#     |		|     #
250  *	#     |		|     #
251  *	#     |		|     #
252  *	+-----+		+-----+
253  *	|     |		|     |
254  *	|     |		|     |
255  *	|     |		|     |
256  *	+-----+		+-----+
257  */
258 	{ ~SEG_F,	~SEG_B },
259 
260 /*	+-----+		+-----+
261  *	|     |		|     |
262  *	|     |		|     |
263  *	|     |		|     |
264  *	+#####+		+#####+
265  *	|     |		|     |
266  *	|     |		|     |
267  *	|     |		|     |
268  *	+-----+		+-----+
269  */
270 	{ ~SEG_G,	~SEG_G },
271 
272 /*	+-----+		+-----+
273  *	|     |		|     |
274  *	|     |		|     |
275  *	|     |		|     |
276  *	+-----+		+-----+
277  *	|     #		#     |
278  *	|     #		#     |
279  *	|     #		#     |
280  *	+-----+		+-----+
281  */
282 	{ ~SEG_C,	~SEG_E },
283 
284 /*	+-----+		+-----+
285  *	|     |		|     |
286  *	|     |		|     |
287  *	|     |		|     |
288  *	+-----+		+-----+
289  *	|     |		|     |
290  *	|     |		|     |
291  *	|     |		|     |
292  *	+#####+		+#####+
293  */
294 	{ ~SEG_D,	~SEG_D },
295 
296 /*	+-----+		+-----+
297  *	|     |		|     |
298  *	|     |		|     |
299  *	|     |		|     |
300  *	+-----+		+-----+
301  *	#     |		|     #
302  *	#     |		|     #
303  *	#     |		|     #
304  *	+-----+		+-----+
305  */
306 	{ ~SEG_E,	~SEG_C },
307 
308 /*	+-----+		+-----+
309  *	|     |		|     |
310  *	|     |		|     |
311  *	|     |		|     |
312  *	+#####+		+#####+
313  *	|     |		|     |
314  *	|     |		|     |
315  *	|     |		|     |
316  *	+-----+		+-----+
317  */
318 	{ ~SEG_G,	~SEG_G },
319 
320 /*	+-----+		+-----+
321  *	|     #		#     |
322  *	|     #		#     |
323  *	|     #		#     |
324  *	+-----+		+-----+
325  *	|     |		|     |
326  *	|     |		|     |
327  *	|     |		|     |
328  *	+-----+		+-----+
329  */
330 	{ ~SEG_B,	~SEG_F },
331 };
332 
333 void
334 iq80321_7seg_snake(void)
335 {
336 	int cur = snakestate;
337 
338 	WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]);
339 	WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]);
340 
341 	snakestate = (cur + 1) & 7;
342 }
343