>Number: 6422
>Category: system
>Synopsis: Patch to add support for 1-Wire counter device>
>Confidential: yes
>Severity: serious
>Priority: medium
>Responsible: bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Tue Jul 06 16:00:02 GMT 2010
>Closed-Date:
>Last-Modified:
>Originator:
>Release:
>Organization:
>Environment:
System : OpenBSD 4.7
Details : OpenBSD 4.7-stable (GENERIC) #39: Tue Jul 6 10:37:36 EDT
2010
r...@xxxxxxxxxxxx:/usr/src/sys/arch/i386/compile/GENERIC
Architecture: OpenBSD.i386
Machine : i386
>Description:
Patch adds a new onewire device owctr (onewire counter). This device
supports the externally triggered counters in the DS2423. The DS2423
contains a 4kbit SRAM and two other SRAM bank write counters but this
driver only supports the two externally triggered counters. This chip
is used in the rain gauge sold by Hobby Boards (model RG1-R1-A).
hw.sensors.owctr0.raw0=9 (Counter A sn 0000000e7163)
hw.sensors.owctr0.raw1=538 (Counter B sn 0000000e7163)
>How-To-Repeat:
>Fix:
This patch doesn't enable the device in GENERIC. Patch is against
-current but tested on i386 4.7-stable.
Index: share/man/man4/Makefile
===================================================================
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.510
diff -N -u -p share/man/man4/Makefile
--- share/man/man4/Makefile 3 Jul 2010 03:59:16 -0000 1.510
+++ share/man/man4/Makefile 6 Jul 2010 15:16:53 -0000
@@ -37,7 +37,7 @@ MAN= aac.4 ac97.4 acphy.4 \
ne.4 neo.4 netintro.4 nfe.4 nge.4 nmea.4 \
noct.4 nofn.4 nsclpcsio.4 nsgphy.4 nsphy.4 nsphyter.4 null.4 nviic.4 \
ohci.4 opl.4 options.4 onewire.4 oosiop.4 osiop.4 otus.4 \
- owid.4 owsbm.4 \
+ owid.4 owctr.4 owsbm.4 \
owtemp.4 pcagpio.4 pcaled.4 pcdisplay.4 pchb.4 pci.4 pcib.4 pcfadc.4 \
pcfiic.4 pciide.4 pckbc.4 pckbd.4 pcmcia.4 pcn.4 pcppi.4 pcscp.4 \
pf.4 pflog.4 pflow.4 pfsync.4 pgt.4 piixpm.4 pim.4 \
Index: share/man/man4/onewire.4
===================================================================
RCS file: /cvs/src/share/man/man4/onewire.4,v
retrieving revision 1.8
diff -N -u -p share/man/man4/onewire.4
--- share/man/man4/onewire.4 16 Nov 2009 20:13:12 -0000 1.8
+++ share/man/man4/onewire.4 6 Jul 2010 14:53:11 -0000
@@ -57,6 +57,8 @@ Octane core system widget
.El
.Sh SUPPORTED SLAVES
.Bl -tag -width 11n -offset ind -compact
+.It Xr owctr 4
+1-Wire counter device
.It Xr owid 4
1-Wire ID device
.It Xr owmac 4
Index: share/man/man4/owctr.4
===================================================================
RCS file: share/man/man4/owctr.4
diff -N -u -p share/man/man4/owctr.4
--- /dev/null 6 Jul 2010 08:59:26 -0000
+++ share/man/man4/owctr.4 6 Jul 2010 14:53:11 -0000
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2010 John L. Scarfone <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: Jul 3 2010 $
+.Dt OWCTR 4
+.Os
+.Sh NAME
+.Nm owctr
+.Nd 1-Wire counter device
+.Sh SYNOPSIS
+.Cd "owctr* at onewire?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the externally triggered counters in the
+DS2423 chip.
+The supported chip contains a 4096 bit SRAM and four 32-bit counters.
+The two externally triggered counters are accessible by the
+.Xr sysctl 8
+interface.
+.Pp
+The following chips are supported by the driver:
+.Pp
+.Bl -bullet -compact -offset indent
+.It
+Maxim/Dallas DS2423
+.El
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr onewire 4 ,
+.Xr owsbm 4 ,
+.Xr owtemp 4 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Ox 4.8 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An John L. Scarfone Aq [email protected] .
Index: sys/dev/onewire/files.onewire
===================================================================
RCS file: /cvs/src/sys/dev/onewire/files.onewire,v
retrieving revision 1.2
diff -N -u -p sys/dev/onewire/files.onewire
--- sys/dev/onewire/files.onewire 28 Feb 2007 21:54:43 -0000 1.2
+++ sys/dev/onewire/files.onewire 6 Jul 2010 14:53:16 -0000
@@ -23,3 +23,8 @@ file dev/onewire/owsbm.c owsbm
device owtemp
attach owtemp at onewire
file dev/onewire/owtemp.c owtemp
+
+# Counter family type device
+device owctr
+attach owctr at onewire
+file dev/onewire/owctr.c owctr
Index: sys/dev/onewire/owctr.c
===================================================================
RCS file: sys/dev/onewire/owctr.c
diff -N -u -p sys/dev/onewire/owctr.c
--- /dev/null 6 Jul 2010 09:00:33 -0000
+++ sys/dev/onewire/owctr.c 6 Jul 2010 14:53:16 -0000
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2010 John L. Scarfone <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DS2423 1-Wire 4kbit SRAM with Counter family type device driver.
+ * Provides 4096 bits of SRAM and four 32-bit, read-only counters.
+ * This driver provides access to the two externally triggered
+ * counters.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/sensors.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+/* Commands */
+#define DSCTR_CMD_READ_MEMCOUNTER 0xa5
+
+/* External counter banks */
+#define DS2423_COUNTER_BANK_A 0x1c0
+#define DS2423_COUNTER_BANK_B 0x1e0
+
+struct owctr_softc {
+ struct device sc_dev;
+
+ void * sc_onewire;
+ u_int64_t sc_rom;
+
+ struct ksensordev sc_sensordev;
+
+ struct ksensor sc_counterA;
+ struct ksensor sc_counterB;
+
+ struct sensor_task *sc_sensortask;
+
+ struct rwlock sc_lock;
+};
+
+int owctr_match(struct device *, void *, void *);
+void owctr_attach(struct device *, struct device *, void *);
+int owctr_detach(struct device *, int);
+int owctr_activate(struct device *, int);
+
+void owctr_update(void *);
+void owctr_update_counter(void *, int);
+
+u_int16_t owctr_crc16(u_int16_t, u_int8_t);
+
+struct cfattach owctr_ca = {
+ sizeof(struct owctr_softc),
+ owctr_match,
+ owctr_attach,
+ owctr_detach,
+ owctr_activate
+};
+
+struct cfdriver owctr_cd = {
+ NULL, "owctr", DV_DULL
+};
+
+static const struct onewire_matchfam owctr_fams[] = {
+ { ONEWIRE_FAMILY_DS2423 }
+};
+
+static const u_int8_t crc16_tablo[] = {
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
+ 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40
+};
+
+static const u_int8_t crc16_tabhi[] = {
+ 0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2,
+ 0xc6, 0x06, 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04,
+ 0xcc, 0x0c, 0x0d, 0xcd, 0x0f, 0xcf, 0xce, 0x0e,
+ 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09, 0x08, 0xc8,
+ 0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a,
+ 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc,
+ 0x14, 0xd4, 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6,
+ 0xd2, 0x12, 0x13, 0xd3, 0x11, 0xd1, 0xd0, 0x10,
+ 0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3, 0xf2, 0x32,
+ 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4,
+ 0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe,
+ 0xfa, 0x3a, 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38,
+ 0x28, 0xe8, 0xe9, 0x29, 0xeb, 0x2b, 0x2a, 0xea,
+ 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed, 0xec, 0x2c,
+ 0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26,
+ 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0,
+ 0xa0, 0x60, 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62,
+ 0x66, 0xa6, 0xa7, 0x67, 0xa5, 0x65, 0x64, 0xa4,
+ 0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f, 0x6e, 0xae,
+ 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68,
+ 0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba,
+ 0xbe, 0x7e, 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c,
+ 0xb4, 0x74, 0x75, 0xb5, 0x77, 0xb7, 0xb6, 0x76,
+ 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71, 0x70, 0xb0,
+ 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
+ 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
+ 0x9c, 0x5c, 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e,
+ 0x5a, 0x9a, 0x9b, 0x5b, 0x99, 0x59, 0x58, 0x98,
+ 0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b, 0x8a, 0x4a,
+ 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c,
+ 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86,
+ 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
+};
+
+int
+owctr_match(struct device *parent, void *match, void *aux)
+{
+ return (onewire_matchbyfam(aux, owctr_fams,
+ sizeof(owctr_fams) /sizeof(owctr_fams[0])));
+}
+
+void
+owctr_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct owctr_softc *sc = (struct owctr_softc *)self;
+ struct onewire_attach_args *oa = aux;
+
+ sc->sc_onewire = oa->oa_onewire;
+ sc->sc_rom = oa->oa_rom;
+
+ /* Initialize counter sensors */
+ strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
+ sizeof(sc->sc_sensordev.xname));
+ sc->sc_counterA.type = SENSOR_INTEGER;
+ snprintf(sc->sc_counterA.desc, sizeof(sc->sc_counterA.desc),
+ "Counter A sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom));
+ sensor_attach(&sc->sc_sensordev, &sc->sc_counterA);
+ sc->sc_counterB.type = SENSOR_INTEGER;
+ snprintf(sc->sc_counterB.desc, sizeof(sc->sc_counterB.desc),
+ "Counter B sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom));
+ sensor_attach(&sc->sc_sensordev, &sc->sc_counterB);
+
+ sc->sc_sensortask = sensor_task_register(sc, owctr_update, 10);
+ if (sc->sc_sensortask == NULL) {
+ printf(": unable to register update task\n");
+ return;
+ }
+
+ sensordev_install(&sc->sc_sensordev);
+
+ rw_init(&sc->sc_lock, sc->sc_dev.dv_xname);
+ printf("\n");
+}
+
+int
+owctr_detach(struct device *self, int flags)
+{
+ struct owctr_softc *sc = (struct owctr_softc *)self;
+
+ rw_enter_write(&sc->sc_lock);
+ sensordev_deinstall(&sc->sc_sensordev);
+ if (sc->sc_sensortask != NULL)
+ sensor_task_unregister(sc->sc_sensortask);
+ rw_exit_write(&sc->sc_lock);
+
+ return (0);
+}
+
+int
+owctr_activate(struct device *self, int act)
+{
+ return (0);
+}
+
+void
+owctr_update(void *arg)
+{
+ owctr_update_counter(arg, DS2423_COUNTER_BANK_A);
+ owctr_update_counter(arg, DS2423_COUNTER_BANK_B);
+}
+
+void
+owctr_update_counter(void *arg, int bank)
+{
+ struct owctr_softc *sc = arg;
+ u_int32_t counter;
+ u_int16_t crc;
+ int data;
+ int i;
+
+ rw_enter_write(&sc->sc_lock);
+ onewire_lock(sc->sc_onewire, 0);
+ if (onewire_reset(sc->sc_onewire) != 0)
+ goto done;
+
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+ onewire_write_byte(sc->sc_onewire, DSCTR_CMD_READ_MEMCOUNTER);
+ crc = owctr_crc16(0, DSCTR_CMD_READ_MEMCOUNTER);
+ onewire_write_byte(sc->sc_onewire, bank);
+ crc = owctr_crc16(crc, bank);
+ onewire_write_byte(sc->sc_onewire, bank >> 8);
+ crc = owctr_crc16(crc, bank >> 8);
+ for (i=0; i<32; ++i)
+ {
+ data = onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ }
+ data = onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ counter = data;
+ data = onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ counter |= data << 8;
+ data = onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ counter |= data << 16;
+ data = onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ counter |= data << 24;
+ for (i=0; i<4; ++i)
+ {
+ onewire_read_byte(sc->sc_onewire);
+ crc = owctr_crc16(crc, data);
+ }
+ data = onewire_read_byte(sc->sc_onewire);
+ crc ^= data;
+ data = onewire_read_byte(sc->sc_onewire);
+ crc ^= data << 8;
+ if ( crc != 0xffff)
+ {
+ printf("%s: invalid CRC\n", sc->sc_dev.dv_xname);
+ if (bank == DS2423_COUNTER_BANK_A) {
+ sc->sc_counterA.value = 0;
+ sc->sc_counterA.status = SENSOR_S_UNKNOWN;
+ sc->sc_counterA.flags |= SENSOR_FUNKNOWN;
+ }
+ else
+ {
+ sc->sc_counterB.value = 0;
+ sc->sc_counterB.status = SENSOR_S_UNKNOWN;
+ sc->sc_counterB.flags |= SENSOR_FUNKNOWN;
+ }
+ }
+ else
+ {
+ if (bank == DS2423_COUNTER_BANK_A)
+ {
+ sc->sc_counterA.value = counter;
+ sc->sc_counterA.status = SENSOR_S_UNSPEC;
+ sc->sc_counterA.flags &= ~SENSOR_FUNKNOWN;
+ }
+ else
+ {
+ sc->sc_counterB.value = counter;
+ sc->sc_counterB.status = SENSOR_S_UNSPEC;
+ sc->sc_counterB.flags &= ~SENSOR_FUNKNOWN;
+ }
+ }
+ onewire_reset(sc->sc_onewire);
+
+done:
+ onewire_unlock(sc->sc_onewire);
+ rw_exit_write(&sc->sc_lock);
+}
+
+u_int16_t
+owctr_crc16(u_int16_t crc16, u_int8_t data)
+{
+ int idx;
+ u_int16_t newcrc16;
+
+ idx = (crc16 & 0xff) ^ data;
+ newcrc16 = crc16_tabhi[idx] << 8;
+ newcrc16 |= crc16_tablo[idx] ^ (crc16 >> 8);
+ return (newcrc16);
+}
>Release-Note:
>Audit-Trail:
>Unformatted: