1/* $NetBSD: iq80310_7seg.c,v 1.9 2005/12/11 12:17:09 christos 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 IQ80310. 40 */ 41 42#include <sys/cdefs.h> 43__KERNEL_RCSID(0, "$NetBSD: iq80310_7seg.c,v 1.9 2005/12/11 12:17:09 christos Exp $"); 44 45#include <sys/param.h> 46#include <sys/systm.h> 47 48#include <sys/bus.h> 49 50#include <evbarm/iq80310/iq80310reg.h> 51#include <evbarm/iq80310/iq80310var.h> 52#include <evbarm/iq80310/obiovar.h> 53 54static int snakestate; 55 56/* 57 * The 7-segment display looks like so: 58 * 59 * A 60 * +-----+ 61 * | | 62 * F | | B 63 * | G | 64 * +-----+ 65 * | | 66 * E | | C 67 * | D | 68 * +-----+ o DP 69 * 70 * Setting a bit clears the corresponding segment on the 71 * display. 72 */ 73#define SEG_A (1 << 0) 74#define SEG_B (1 << 1) 75#define SEG_C (1 << 2) 76#define SEG_D (1 << 3) 77#define SEG_E (1 << 4) 78#define SEG_F (1 << 5) 79#define SEG_G (1 << 6) 80#define SEG_DP (1 << 7) 81 82static const uint8_t digitmap[] = { 83/* +#####+ 84 * # # 85 * # # 86 * # # 87 * +-----+ 88 * # # 89 * # # 90 * # # 91 * +#####+ 92 */ 93 SEG_G, 94 95/* +-----+ 96 * | # 97 * | # 98 * | # 99 * +-----+ 100 * | # 101 * | # 102 * | # 103 * +-----+ 104 */ 105 SEG_A|SEG_D|SEG_E|SEG_F|SEG_G, 106 107/* +#####+ 108 * | # 109 * | # 110 * | # 111 * +#####+ 112 * # | 113 * # | 114 * # | 115 * +#####+ 116 */ 117 SEG_C|SEG_F, 118 119/* +#####+ 120 * | # 121 * | # 122 * | # 123 * +#####+ 124 * | # 125 * | # 126 * | # 127 * +#####+ 128 */ 129 SEG_E|SEG_F, 130 131/* +-----+ 132 * # # 133 * # # 134 * # # 135 * +#####+ 136 * | # 137 * | # 138 * | # 139 * +-----+ 140 */ 141 SEG_A|SEG_D|SEG_E, 142 143/* +#####+ 144 * # | 145 * # | 146 * # | 147 * +#####+ 148 * | # 149 * | # 150 * | # 151 * +#####+ 152 */ 153 SEG_B|SEG_E, 154 155/* +#####+ 156 * # | 157 * # | 158 * # | 159 * +#####+ 160 * # # 161 * # # 162 * # # 163 * +#####+ 164 */ 165 SEG_B, 166 167/* +#####+ 168 * | # 169 * | # 170 * | # 171 * +-----+ 172 * | # 173 * | # 174 * | # 175 * +-----+ 176 */ 177 SEG_D|SEG_E|SEG_F, 178 179/* +#####+ 180 * # # 181 * # # 182 * # # 183 * +#####+ 184 * # # 185 * # # 186 * # # 187 * +#####+ 188 */ 189 0, 190 191/* +#####+ 192 * # # 193 * # # 194 * # # 195 * +#####+ 196 * | # 197 * | # 198 * | # 199 * +-----+ 200 */ 201 SEG_D|SEG_E, 202}; 203 204static uint8_t 205iq80310_7seg_xlate(char c) 206{ 207 uint8_t rv; 208 209 if (c >= '0' && c <= '9') 210 rv = digitmap[c - '0']; 211 else if (c == '.') 212 rv = (uint8_t) ~SEG_DP; 213 else 214 rv = 0xff; 215 216 return (rv); 217} 218 219void 220iq80310_7seg(char a, char b) 221{ 222 uint8_t msb, lsb; 223 224 msb = iq80310_7seg_xlate(a); 225 lsb = iq80310_7seg_xlate(b); 226 227 snakestate = 0; 228 229 CPLD_WRITE(IQ80310_7SEG_MSB, msb); 230 CPLD_WRITE(IQ80310_7SEG_LSB, lsb); 231} 232 233static const uint8_t snakemap[][2] = { 234 235/* +#####+ +#####+ 236 * | | | | 237 * | | | | 238 * | | | | 239 * +-----+ +-----+ 240 * | | | | 241 * | | | | 242 * | | | | 243 * +-----+ +-----+ 244 */ 245 { ~SEG_A, ~SEG_A }, 246 247/* +-----+ +-----+ 248 * # | | # 249 * # | | # 250 * # | | # 251 * +-----+ +-----+ 252 * | | | | 253 * | | | | 254 * | | | | 255 * +-----+ +-----+ 256 */ 257 { ~SEG_F, ~SEG_B }, 258 259/* +-----+ +-----+ 260 * | | | | 261 * | | | | 262 * | | | | 263 * +#####+ +#####+ 264 * | | | | 265 * | | | | 266 * | | | | 267 * +-----+ +-----+ 268 */ 269 { ~SEG_G, ~SEG_G }, 270 271/* +-----+ +-----+ 272 * | | | | 273 * | | | | 274 * | | | | 275 * +-----+ +-----+ 276 * | # # | 277 * | # # | 278 * | # # | 279 * +-----+ +-----+ 280 */ 281 { ~SEG_C, ~SEG_E }, 282 283/* +-----+ +-----+ 284 * | | | | 285 * | | | | 286 * | | | | 287 * +-----+ +-----+ 288 * | | | | 289 * | | | | 290 * | | | | 291 * +#####+ +#####+ 292 */ 293 { ~SEG_D, ~SEG_D }, 294 295/* +-----+ +-----+ 296 * | | | | 297 * | | | | 298 * | | | | 299 * +-----+ +-----+ 300 * # | | # 301 * # | | # 302 * # | | # 303 * +-----+ +-----+ 304 */ 305 { ~SEG_E, ~SEG_C }, 306 307/* +-----+ +-----+ 308 * | | | | 309 * | | | | 310 * | | | | 311 * +#####+ +#####+ 312 * | | | | 313 * | | | | 314 * | | | | 315 * +-----+ +-----+ 316 */ 317 { ~SEG_G, ~SEG_G }, 318 319/* +-----+ +-----+ 320 * | # # | 321 * | # # | 322 * | # # | 323 * +-----+ +-----+ 324 * | | | | 325 * | | | | 326 * | | | | 327 * +-----+ +-----+ 328 */ 329 { ~SEG_B, ~SEG_F }, 330}; 331 332void 333iq80310_7seg_snake(void) 334{ 335 int cur = snakestate; 336 337 CPLD_WRITE(IQ80310_7SEG_MSB, snakemap[cur][0]); 338 CPLD_WRITE(IQ80310_7SEG_LSB, snakemap[cur][1]); 339 340 snakestate = (cur + 1) & 7; 341} 342