]>
Commit | Line | Data |
---|---|---|
c935d3bd WD |
1 | /* |
2 | * (C) Copyright 2003, Li-Pro.Net <www.li-pro.net> | |
3 | * Stephan Linz <linz@li-pro.net> | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | * | |
23 | * common/sevenseg.c | |
24 | * | |
25 | * NIOS PIO based seven segment led support functions | |
26 | */ | |
27 | ||
28 | #include <common.h> | |
29 | #include <nios-io.h> | |
30 | ||
31 | #ifdef CONFIG_SEVENSEG | |
32 | ||
33 | #define SEVENDEG_MASK_DP ((SEVENSEG_DIGIT_DP << 8) | SEVENSEG_DIGIT_DP) | |
34 | ||
35 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
36 | #if (SEVENSEG_ACTIVE == 0) | |
37 | static unsigned int sevenseg_portval = ~0; | |
38 | #else | |
39 | static unsigned int sevenseg_portval = 0; | |
40 | #endif | |
41 | #endif | |
42 | ||
43 | static int sevenseg_init_done = 0; | |
44 | ||
45 | static inline void __sevenseg_set_masked (unsigned int mask, int value) | |
46 | { | |
5653fc33 | 47 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
48 | |
49 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
50 | ||
51 | #if (SEVENSEG_ACTIVE == 0) | |
52 | if (value) | |
53 | sevenseg_portval &= ~mask; | |
54 | else | |
55 | sevenseg_portval |= mask; | |
56 | #else | |
57 | if (value) | |
58 | sevenseg_portval |= mask; | |
59 | else | |
60 | sevenseg_portval &= ~mask; | |
61 | #endif | |
62 | ||
63 | piop->data = sevenseg_portval; | |
64 | ||
65 | #else /* !SEVENSEG_WRONLY */ | |
66 | ||
67 | #if (SEVENSEG_ACTIVE == 0) | |
68 | if (value) | |
69 | piop->data &= ~mask; | |
70 | else | |
71 | piop->data |= mask; | |
72 | #else | |
73 | if (value) | |
74 | piop->data |= mask; | |
75 | else | |
76 | piop->data &= ~mask; | |
77 | #endif | |
78 | ||
79 | #endif /* SEVENSEG_WRONLY */ | |
80 | } | |
81 | ||
82 | static inline void __sevenseg_toggle_masked (unsigned int mask) | |
83 | { | |
84 | nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; | |
85 | ||
86 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
87 | ||
88 | sevenseg_portval ^= mask; | |
89 | piop->data = sevenseg_portval; | |
90 | ||
91 | #else /* !SEVENSEG_WRONLY */ | |
92 | ||
93 | piop->data ^= mask; | |
94 | ||
95 | #endif /* SEVENSEG_WRONLY */ | |
96 | } | |
97 | ||
98 | static inline void __sevenseg_set (unsigned int value) | |
99 | { | |
5653fc33 | 100 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
101 | |
102 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
103 | ||
104 | #if (SEVENSEG_ACTIVE == 0) | |
105 | sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP) | |
106 | | ((~value) & (~SEVENDEG_MASK_DP)); | |
107 | #else | |
108 | sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP) | |
109 | | (value); | |
110 | #endif | |
111 | ||
112 | piop->data = sevenseg_portval; | |
113 | ||
114 | #else /* !SEVENSEG_WRONLY */ | |
115 | ||
116 | #if (SEVENSEG_ACTIVE == 0) | |
117 | piop->data = (piop->data & SEVENDEG_MASK_DP) | |
118 | | ((~value) & (~SEVENDEG_MASK_DP)); | |
119 | #else | |
120 | piop->data = (piop->data & SEVENDEG_MASK_DP) | |
121 | | (value); | |
122 | #endif | |
123 | ||
124 | #endif /* SEVENSEG_WRONLY */ | |
125 | } | |
126 | ||
127 | static inline void __sevenseg_init (void) | |
128 | { | |
5653fc33 | 129 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
130 | |
131 | __sevenseg_set(0); | |
132 | ||
133 | #ifndef SEVENSEG_WRONLY /* setup direction */ | |
134 | ||
135 | piop->direction |= mask; | |
136 | ||
137 | #endif /* SEVENSEG_WRONLY */ | |
138 | } | |
139 | ||
140 | ||
141 | void sevenseg_set(int value) | |
142 | { | |
143 | unsigned char digits[] = { | |
144 | SEVENSEG_DIGITS_0, | |
145 | SEVENSEG_DIGITS_1, | |
146 | SEVENSEG_DIGITS_2, | |
147 | SEVENSEG_DIGITS_3, | |
148 | SEVENSEG_DIGITS_4, | |
149 | SEVENSEG_DIGITS_5, | |
150 | SEVENSEG_DIGITS_6, | |
151 | SEVENSEG_DIGITS_7, | |
152 | SEVENSEG_DIGITS_8, | |
153 | SEVENSEG_DIGITS_9, | |
154 | SEVENSEG_DIGITS_A, | |
155 | SEVENSEG_DIGITS_B, | |
156 | SEVENSEG_DIGITS_C, | |
157 | SEVENSEG_DIGITS_D, | |
158 | SEVENSEG_DIGITS_E, | |
159 | SEVENSEG_DIGITS_F | |
160 | }; | |
161 | ||
162 | if (!sevenseg_init_done) { | |
163 | __sevenseg_init(); | |
164 | sevenseg_init_done++; | |
165 | } | |
166 | ||
167 | switch (value & SEVENSEG_MASK_CTRL) { | |
168 | ||
169 | case SEVENSEG_RAW: | |
170 | __sevenseg_set( ( | |
171 | (digits[((value & SEVENSEG_MASK_VAL) >> 4)] << 8) | | |
172 | digits[((value & SEVENSEG_MASK_VAL) & 0xf)] ) ); | |
173 | return; | |
174 | break; /* paranoia */ | |
175 | ||
176 | case SEVENSEG_OFF: | |
177 | __sevenseg_set(0); | |
178 | __sevenseg_set_masked(SEVENDEG_MASK_DP, 0); | |
179 | return; | |
180 | break; /* paranoia */ | |
181 | ||
182 | case SEVENSEG_SET_DPL: | |
183 | __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 1); | |
184 | return; | |
185 | break; /* paranoia */ | |
186 | ||
187 | case SEVENSEG_SET_DPH: | |
188 | __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 1); | |
189 | return; | |
190 | break; /* paranoia */ | |
191 | ||
192 | case SEVENSEG_RES_DPL: | |
193 | __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 0); | |
194 | return; | |
195 | break; /* paranoia */ | |
196 | ||
197 | case SEVENSEG_RES_DPH: | |
198 | __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 0); | |
199 | return; | |
200 | break; /* paranoia */ | |
201 | ||
202 | case SEVENSEG_TOG_DPL: | |
203 | __sevenseg_toggle_masked(SEVENSEG_DIGIT_DP); | |
204 | return; | |
205 | break; /* paranoia */ | |
206 | ||
207 | case SEVENSEG_TOG_DPH: | |
208 | __sevenseg_toggle_masked((SEVENSEG_DIGIT_DP << 8)); | |
209 | return; | |
210 | break; /* paranoia */ | |
211 | ||
212 | case SEVENSEG_LO: | |
213 | case SEVENSEG_HI: | |
214 | case SEVENSEG_STR: | |
215 | default: | |
216 | break; | |
217 | } | |
218 | } | |
219 | ||
220 | #endif /* CONFIG_SEVENSEG */ |