Current Path : /sys/arm/xscale/i80321/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //sys/arm/xscale/i80321/iq31244_7seg.c |
/* $NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $ */ /*- * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Support for the 7-segment display on the Intel IQ31244. */ #include <sys/cdefs.h> __FBSDID("$FreeBSD: release/9.1.0/sys/arm/xscale/i80321/iq31244_7seg.c 146618 2005-05-25 13:44:55Z cognet $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/bus.h> #include <sys/sysctl.h> #include <machine/bus.h> #include <arm/xscale/i80321/iq80321reg.h> #include <arm/xscale/i80321/iq80321var.h> #define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v) static int snakestate; /* * The 7-segment display looks like so: * * A * +-----+ * | | * F | | B * | G | * +-----+ * | | * E | | C * | D | * +-----+ o DP * * Setting a bit clears the corresponding segment on the * display. */ #define SEG_A (1 << 0) #define SEG_B (1 << 1) #define SEG_C (1 << 2) #define SEG_D (1 << 3) #define SEG_E (1 << 4) #define SEG_F (1 << 5) #define SEG_G (1 << 6) #define SEG_DP (1 << 7) static const uint8_t digitmap[] = { /* +#####+ * # # * # # * # # * +-----+ * # # * # # * # # * +#####+ */ SEG_G, /* +-----+ * | # * | # * | # * +-----+ * | # * | # * | # * +-----+ */ SEG_A|SEG_D|SEG_E|SEG_F|SEG_G, /* +#####+ * | # * | # * | # * +#####+ * # | * # | * # | * +#####+ */ SEG_C|SEG_F, /* +#####+ * | # * | # * | # * +#####+ * | # * | # * | # * +#####+ */ SEG_E|SEG_F, /* +-----+ * # # * # # * # # * +#####+ * | # * | # * | # * +-----+ */ SEG_A|SEG_D|SEG_E, /* +#####+ * # | * # | * # | * +#####+ * | # * | # * | # * +#####+ */ SEG_B|SEG_E, /* +#####+ * # | * # | * # | * +#####+ * # # * # # * # # * +#####+ */ SEG_B, /* +#####+ * | # * | # * | # * +-----+ * | # * | # * | # * +-----+ */ SEG_D|SEG_E|SEG_F, /* +#####+ * # # * # # * # # * +#####+ * # # * # # * # # * +#####+ */ 0, /* +#####+ * # # * # # * # # * +#####+ * | # * | # * | # * +-----+ */ SEG_D|SEG_E, }; static uint8_t iq80321_7seg_xlate(char c) { uint8_t rv; if (c >= '0' && c <= '9') rv = digitmap[c - '0']; else if (c == '.') rv = (uint8_t) ~SEG_DP; else rv = 0xff; return (rv); } void iq80321_7seg(char a, char b) { uint8_t msb, lsb; msb = iq80321_7seg_xlate(a); lsb = iq80321_7seg_xlate(b); snakestate = 0; WRITE(IQ80321_7SEG_MSB, msb); WRITE(IQ80321_7SEG_LSB, lsb); } static const uint8_t snakemap[][2] = { /* +#####+ +#####+ * | | | | * | | | | * | | | | * +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ */ { ~SEG_A, ~SEG_A }, /* +-----+ +-----+ * # | | # * # | | # * # | | # * +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ */ { ~SEG_F, ~SEG_B }, /* +-----+ +-----+ * | | | | * | | | | * | | | | * +#####+ +#####+ * | | | | * | | | | * | | | | * +-----+ +-----+ */ { ~SEG_G, ~SEG_G }, /* +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ * | # # | * | # # | * | # # | * +-----+ +-----+ */ { ~SEG_C, ~SEG_E }, /* +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ * | | | | * | | | | * | | | | * +#####+ +#####+ */ { ~SEG_D, ~SEG_D }, /* +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ * # | | # * # | | # * # | | # * +-----+ +-----+ */ { ~SEG_E, ~SEG_C }, /* +-----+ +-----+ * | | | | * | | | | * | | | | * +#####+ +#####+ * | | | | * | | | | * | | | | * +-----+ +-----+ */ { ~SEG_G, ~SEG_G }, /* +-----+ +-----+ * | # # | * | # # | * | # # | * +-----+ +-----+ * | | | | * | | | | * | | | | * +-----+ +-----+ */ { ~SEG_B, ~SEG_F }, }; SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg"); static int freq = 20; SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0, "7 Seg update frequency"); static void iq31244_7seg_snake(void) { static int snakefreq; int cur = snakestate; snakefreq++; if ((snakefreq % freq)) return; WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]); WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]); snakestate = (cur + 1) & 7; } struct iq31244_7seg_softc { device_t dev; }; static int iq31244_7seg_probe(device_t dev) { device_set_desc(dev, "IQ31244 7seg"); return (0); } extern void (*i80321_hardclock_hook)(void); static int iq31244_7seg_attach(device_t dev) { i80321_hardclock_hook = iq31244_7seg_snake; return (0); } static device_method_t iq31244_7seg_methods[] = { DEVMETHOD(device_probe, iq31244_7seg_probe), DEVMETHOD(device_attach, iq31244_7seg_attach), {0, 0}, }; static driver_t iq31244_7seg_driver = { "iqseg", iq31244_7seg_methods, sizeof(struct iq31244_7seg_softc), }; static devclass_t iq31244_7seg_devclass; DRIVER_MODULE(iqseg, iq, iq31244_7seg_driver, iq31244_7seg_devclass, 0, 0);