>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:

Reply via email to