#!/bin/sh -
#
-# $OpenBSD: MAKEDEV,v 1.10 1996/11/11 23:51:38 kstailey Exp $
+# $OpenBSD: MAKEDEV,v 1.11 1997/01/13 00:29:28 kstailey Exp $
# $NetBSD: MAKEDEV,v 1.8 1996/03/03 16:54:17 thorpej Exp $
#
# Copyright (c) 1990 The Regents of the University of California.
mk klog c 16 0 600
mk fb c 22 0
mk kbd c 29 0
+ mk leds c 3 13 644
mk stdin c 23 0
mk stdout c 23 1
mk stderr c 23 2
# from: @(#)Makefile 8.2 (Berkeley) 2/16/94
+# $OpenBSD: Makefile,v 1.2 1997/01/13 00:29:27 kstailey Exp $
# $NetBSD: Makefile,v 1.1.1.1 1995/08/08 20:18:53 gwr Exp $
-MAN= bwtwo.4 cgtwo.4 cgfour.4 ie.4 le.4 mem.4
+MAN= bwtwo.4 cgtwo.4 cgfour.4 ie.4 le.4 leds.4 mem.4
MLINKS= mem.4 kmem.4
MANSUBDIR=/sun3
--- /dev/null
+.\" $OpenBSD: leds.4,v 1.1 1997/01/13 00:29:27 kstailey Exp $
+.\"
+.Dd March 2, 1996
+.Dt LEDS 4 sun3
+.Os OpenBSD 2.0
+.Sh NAME
+.Nm leds
+.Nd back-panel LEDs
+.Sh DESCRIPTION
+The file
+.Nm /dev/leds
+is an interface to the diagnostic array of 8 light-emitting diodes on
+the back of the computer.
+.Pp
+This file contains two
+.Sy unsigned int Ns s
+(in native byte order, as would be written by passing the address of an
+.Sy unsigned int
+to
+.Xr write 2 ,
+which on a Sun-3 means big-endian), followed by a string of bytes. The
+string of bytes gives the successive patterns to be displayed on the
+LEDs; each byte's bits are taken and used to drive the LEDs. A 0 bit
+illuminates the corresponding LED; a 1 bit leaves the corresponding LED
+dark. The first
+.Sy unsigned int
+gives the number of clock ticks that are skipped after each pattern is
+loaded before the next is loaded. For example, if this value is 0, a
+new pattern is loaded each clock tick; if it is 3, a new pattern will
+be loaded every fourth clock tick (ie, three ticks will be skipped
+between loads). The second
+.Sy unsigned int
+gives the number of patterns in the list, that is, the number of bytes
+following the two
+.Sy unsigned int Ns s.
+.Pp
+There are limits on the two integer values; attempting a write that
+would cause either of them to take on too large a value causes the
+write to return EIO without affecting anything. The limits are
+compiled into the kernel; as of this writing, the first one can be at
+most 128, the second at most 10240.
+.Sh EXAMPLES
+This example displays a single lit LED scrolling from one end of the
+display to the other, over and over, moving every six clock ticks. The
+first eight bytes supply the two
+.Sy unsigned int Ns s
+mentioned above; the other eight specify the patterns. (Convert them
+to binary, and remember that 0 bits mean lit LEDs.)
+.Bd -ragged -offset -ident
+# echo 0 0 0 5 0 0 0 8 254 253 250 247 239 223 175 127 |
+ awk '{ for (i=1;i<=NF;i++) printf("%c",$i+0); }' > /dev/leds
+.Ed
+.Sh FILES
+.Bl -tag -width /dev/leds -compact
+.It Pa /dev/leds
+.El
+.Sh HISTORY
+.Nm /dev/leds
+appeared in post-2.0 OpenBSD.
+# $OpenBSD: files.sun3,v 1.9 1997/01/13 00:29:26 kstailey Exp $
# $NetBSD: files.sun3,v 1.26 1996/10/29 19:58:14 gwr Exp $
#
file arch/sun3/sun3/fpu.c
file arch/sun3/sun3/isr.c
file arch/sun3/sun3/kgdb_stub.c kgdb
+file arch/sun3/sun3/leds.c
file arch/sun3/sun3/machdep.c
file arch/sun3/sun3/mem.c
file arch/sun3/sun3/pmap.c
+/* $OpenBSD: clock.c,v 1.6 1997/01/13 00:29:23 kstailey Exp $ */
/* $NetBSD: clock.c,v 1.31 1996/10/30 00:24:42 gwr Exp $ */
/*
#include "intersil7170.h"
#include "interreg.h"
+#include "ledsvar.h"
#define CLOCK_PRI 5
* This is is called by the "custom" interrupt handler
* after it has reset the pending bit in the clock.
*/
-int clock_count = 0;
void clock_intr(frame)
struct clockframe *frame;
{
- static unsigned char led_pattern = 0xFE;
+ unsigned int i;
#ifdef DIAGNOSTIC
if (!clk_intr_ready)
#endif
/* XXX - Move this LED frobbing to the idle loop? */
- clock_count++;
- if ((clock_count & 7) == 0) {
- led_pattern = (led_pattern << 1) | 1;
- if (led_pattern == 0xFF)
- led_pattern = 0xFE;
- set_control_byte((char *) DIAG_REG, led_pattern);
- }
+ i = led_countdown;
+ if (i == 0) {
+ led_countdown = led_countmax;
+ i = led_px;
+ set_control_byte((char *) DIAG_REG, led_patterns[i]);
+ if (i == 0)
+ i = led_n_patterns;
+ led_px = i - 1;
+ } else
+ led_countdown = i - 1;
hardclock(frame);
}
--- /dev/null
+/* $OpenBSD: leds.c,v 1.1 1997/01/13 00:29:24 kstailey Exp $ */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <machine/psl.h>
+
+#include "leds-extern.h"
+
+#define MAXPVLEN 10240
+#define MAXCDOWN 128
+
+static volatile unsigned char pattern[MAXPVLEN] =
+ { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
+ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
+ };
+
+volatile unsigned int led_n_patterns = 16;
+volatile const unsigned char * volatile led_patterns = &pattern[0];
+volatile unsigned int led_countmax = 5;
+volatile unsigned int led_countdown = 0;
+volatile unsigned int led_px = 0;
+
+int ledrw(struct uio *uio)
+{
+ unsigned int v[2];
+ int s;
+ unsigned int o;
+ int err;
+
+ if (uio->uio_offset > MAXPVLEN+sizeof(v)) return(0);
+ s = splhigh();
+ v[0] = led_countmax;
+ v[1] = led_n_patterns;
+ splx(s);
+ o = uio->uio_offset;
+ if (o < sizeof(v))
+ { err = uiomove(((caddr_t)&v[0])+o,sizeof(v)-o,uio);
+ if (err) return(err);
+ o = sizeof(v);
+ if (uio->uio_rw == UIO_WRITE)
+ { if ((v[0] > MAXCDOWN) || (v[1] < 1) || (v[1] > MAXPVLEN)) return(EIO);
+ s = splhigh();
+ led_countmax = v[0];
+ led_n_patterns = v[1];
+ led_countdown = 0;
+ led_px = 0;
+ splx(s);
+ }
+ }
+ o -= sizeof(v);
+ if (o >= v[1]) return(0);
+ if (uio->uio_resid > 0)
+ { err = uiomove((caddr_t)&pattern[o],v[1]-o,uio);
+ if (err) return(err);
+ }
+ return(0);
+}
--- /dev/null
+/* $OpenBSD: ledsvar.h,v 1.1 1997/01/13 00:29:25 kstailey Exp $ */
+
+extern volatile unsigned int led_n_patterns;
+extern volatile unsigned int led_countmax;
+extern volatile const unsigned char * volatile led_patterns;
+extern volatile unsigned int led_countdown;
+extern volatile unsigned int led_px;
error = uiomove(zeropage, c, uio);
continue;
+/* minor device 13 (/dev/leds) accesses the blinkenlights */
+ case 13:
+ error = ledrw(uio);
+ return(error);
+
default:
return (ENXIO);
}