1 /* $NetBSD: iq80321_7seg.c,v 1.6 2005/12/24 20:06:59 perry Exp $ */ 2 3 /* 4 * Copyright (c) 2001, 2002 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 IQ80321. 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: iq80321_7seg.c,v 1.6 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 << 7) 75 #define SEG_B (1 << 6) 76 #define SEG_C (1 << 5) 77 #define SEG_D (1 << 4) 78 #define SEG_E (1 << 3) 79 #define SEG_F (1 << 2) 80 #define SEG_G (1 << 1) 81 #define SEG_DP (1 << 0) 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 = ~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 & 0xff, ~SEG_A & 0xff }, 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