]>
Commit | Line | Data |
---|---|---|
c935d3bd WD |
1 | /* |
2 | * (C) Copyright 2003, Li-Pro.Net <www.li-pro.net> | |
3 | * Stephan Linz <[email protected]> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
c935d3bd WD |
6 | * |
7 | * common/sevenseg.c | |
8 | * | |
9 | * NIOS PIO based seven segment led support functions | |
10 | */ | |
11 | ||
12 | #include <common.h> | |
13 | #include <nios-io.h> | |
14 | ||
15 | #ifdef CONFIG_SEVENSEG | |
16 | ||
17 | #define SEVENDEG_MASK_DP ((SEVENSEG_DIGIT_DP << 8) | SEVENSEG_DIGIT_DP) | |
18 | ||
19 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
20 | #if (SEVENSEG_ACTIVE == 0) | |
21 | static unsigned int sevenseg_portval = ~0; | |
22 | #else | |
23 | static unsigned int sevenseg_portval = 0; | |
24 | #endif | |
25 | #endif | |
26 | ||
27 | static int sevenseg_init_done = 0; | |
28 | ||
29 | static inline void __sevenseg_set_masked (unsigned int mask, int value) | |
30 | { | |
5653fc33 | 31 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
32 | |
33 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
34 | ||
35 | #if (SEVENSEG_ACTIVE == 0) | |
36 | if (value) | |
37 | sevenseg_portval &= ~mask; | |
38 | else | |
39 | sevenseg_portval |= mask; | |
40 | #else | |
41 | if (value) | |
42 | sevenseg_portval |= mask; | |
43 | else | |
44 | sevenseg_portval &= ~mask; | |
45 | #endif | |
46 | ||
47 | piop->data = sevenseg_portval; | |
48 | ||
49 | #else /* !SEVENSEG_WRONLY */ | |
50 | ||
51 | #if (SEVENSEG_ACTIVE == 0) | |
52 | if (value) | |
53 | piop->data &= ~mask; | |
54 | else | |
55 | piop->data |= mask; | |
56 | #else | |
57 | if (value) | |
58 | piop->data |= mask; | |
59 | else | |
60 | piop->data &= ~mask; | |
61 | #endif | |
62 | ||
63 | #endif /* SEVENSEG_WRONLY */ | |
64 | } | |
65 | ||
66 | static inline void __sevenseg_toggle_masked (unsigned int mask) | |
67 | { | |
68 | nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; | |
69 | ||
70 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
71 | ||
72 | sevenseg_portval ^= mask; | |
73 | piop->data = sevenseg_portval; | |
74 | ||
75 | #else /* !SEVENSEG_WRONLY */ | |
76 | ||
77 | piop->data ^= mask; | |
78 | ||
79 | #endif /* SEVENSEG_WRONLY */ | |
80 | } | |
81 | ||
82 | static inline void __sevenseg_set (unsigned int value) | |
83 | { | |
5653fc33 | 84 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
85 | |
86 | #ifdef SEVENSEG_WRONLY /* emulate read access */ | |
87 | ||
88 | #if (SEVENSEG_ACTIVE == 0) | |
89 | sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP) | |
93e14596 | 90 | | ((~value) & (~SEVENDEG_MASK_DP)); |
c935d3bd WD |
91 | #else |
92 | sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP) | |
93e14596 | 93 | | (value); |
c935d3bd WD |
94 | #endif |
95 | ||
96 | piop->data = sevenseg_portval; | |
97 | ||
98 | #else /* !SEVENSEG_WRONLY */ | |
99 | ||
100 | #if (SEVENSEG_ACTIVE == 0) | |
101 | piop->data = (piop->data & SEVENDEG_MASK_DP) | |
102 | | ((~value) & (~SEVENDEG_MASK_DP)); | |
103 | #else | |
104 | piop->data = (piop->data & SEVENDEG_MASK_DP) | |
105 | | (value); | |
106 | #endif | |
107 | ||
108 | #endif /* SEVENSEG_WRONLY */ | |
109 | } | |
110 | ||
111 | static inline void __sevenseg_init (void) | |
112 | { | |
5653fc33 | 113 | nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE; |
c935d3bd WD |
114 | |
115 | __sevenseg_set(0); | |
116 | ||
117 | #ifndef SEVENSEG_WRONLY /* setup direction */ | |
118 | ||
119 | piop->direction |= mask; | |
120 | ||
121 | #endif /* SEVENSEG_WRONLY */ | |
122 | } | |
123 | ||
124 | ||
125 | void sevenseg_set(int value) | |
126 | { | |
127 | unsigned char digits[] = { | |
128 | SEVENSEG_DIGITS_0, | |
129 | SEVENSEG_DIGITS_1, | |
130 | SEVENSEG_DIGITS_2, | |
131 | SEVENSEG_DIGITS_3, | |
132 | SEVENSEG_DIGITS_4, | |
133 | SEVENSEG_DIGITS_5, | |
134 | SEVENSEG_DIGITS_6, | |
135 | SEVENSEG_DIGITS_7, | |
136 | SEVENSEG_DIGITS_8, | |
137 | SEVENSEG_DIGITS_9, | |
138 | SEVENSEG_DIGITS_A, | |
139 | SEVENSEG_DIGITS_B, | |
140 | SEVENSEG_DIGITS_C, | |
141 | SEVENSEG_DIGITS_D, | |
142 | SEVENSEG_DIGITS_E, | |
143 | SEVENSEG_DIGITS_F | |
144 | }; | |
145 | ||
146 | if (!sevenseg_init_done) { | |
147 | __sevenseg_init(); | |
148 | sevenseg_init_done++; | |
149 | } | |
150 | ||
151 | switch (value & SEVENSEG_MASK_CTRL) { | |
152 | ||
153 | case SEVENSEG_RAW: | |
154 | __sevenseg_set( ( | |
155 | (digits[((value & SEVENSEG_MASK_VAL) >> 4)] << 8) | | |
156 | digits[((value & SEVENSEG_MASK_VAL) & 0xf)] ) ); | |
157 | return; | |
158 | break; /* paranoia */ | |
159 | ||
160 | case SEVENSEG_OFF: | |
161 | __sevenseg_set(0); | |
162 | __sevenseg_set_masked(SEVENDEG_MASK_DP, 0); | |
163 | return; | |
164 | break; /* paranoia */ | |
165 | ||
166 | case SEVENSEG_SET_DPL: | |
167 | __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 1); | |
168 | return; | |
169 | break; /* paranoia */ | |
170 | ||
171 | case SEVENSEG_SET_DPH: | |
172 | __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 1); | |
173 | return; | |
174 | break; /* paranoia */ | |
175 | ||
176 | case SEVENSEG_RES_DPL: | |
177 | __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 0); | |
178 | return; | |
179 | break; /* paranoia */ | |
180 | ||
181 | case SEVENSEG_RES_DPH: | |
182 | __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 0); | |
183 | return; | |
184 | break; /* paranoia */ | |
185 | ||
186 | case SEVENSEG_TOG_DPL: | |
187 | __sevenseg_toggle_masked(SEVENSEG_DIGIT_DP); | |
188 | return; | |
189 | break; /* paranoia */ | |
190 | ||
191 | case SEVENSEG_TOG_DPH: | |
192 | __sevenseg_toggle_masked((SEVENSEG_DIGIT_DP << 8)); | |
193 | return; | |
194 | break; /* paranoia */ | |
195 | ||
196 | case SEVENSEG_LO: | |
197 | case SEVENSEG_HI: | |
198 | case SEVENSEG_STR: | |
199 | default: | |
200 | break; | |
201 | } | |
202 | } | |
203 | ||
204 | #endif /* CONFIG_SEVENSEG */ |