Minor cleanups in ds18b20 and ds248x.

Breaking change: removed ds248x.Dev.Close() as it doesn't 'own' anything.
Wrap comments at 80 cols.
Call Playback.Close(), removed extraneous Ops.
Slightly increased coverage.
pull/1/head
Marc-Antoine Ruel 9 years ago
parent daad425c63
commit 2e0e8d4ee9

@ -5,20 +5,28 @@
package ds18b20
import (
"os"
"testing"
"time"
"periph.io/x/periph/conn/onewire"
"periph.io/x/periph/conn/onewire/onewiretest"
"periph.io/x/periph/devices"
"periph.io/x/periph/host"
)
// TestMain lets periph load all drivers and then runs the tests.
func TestMain(m *testing.M) {
host.Init()
os.Exit(m.Run())
func TestNew_resolution(t *testing.T) {
bus := &onewiretest.Playback{}
var addr onewire.Address = 0x740000070e41ac28
if d, err := New(bus, addr, 1); d != nil || err == nil {
t.Fatal("invalid resolution")
}
}
func TestNew_read(t *testing.T) {
bus := &onewiretest.Playback{DontPanic: true}
var addr onewire.Address = 0x740000070e41ac28
if d, err := New(bus, addr, 9); d != nil || err == nil {
t.Fatal("invalid resolution")
}
}
// TestTemperature tests a temperature conversion on a ds18b20 using
@ -27,20 +35,26 @@ func TestTemperature(t *testing.T) {
// set-up playback using the recording output.
ops := []onewiretest.IO{
// Match ROM + Read Scratchpad (init)
{Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0xbe},
Read: []uint8{0xe0, 0x1, 0x0, 0x0, 0x3f, 0xff, 0x10, 0x10, 0x3f}, Pull: false},
{
Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0xbe},
Read: []uint8{0xe0, 0x1, 0x0, 0x0, 0x3f, 0xff, 0x10, 0x10, 0x3f},
},
// Match ROM + Convert
{Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0x44},
Read: []uint8(nil), Pull: true},
{
Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0x44},
Pull: true,
},
// Match ROM + Read Scratchpad (read temp)
{Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0xbe},
Read: []uint8{0xe0, 0x1, 0x0, 0x0, 0x3f, 0xff, 0x10, 0x10, 0x3f}, Pull: false},
{
Write: []uint8{0x55, 0x28, 0xac, 0x41, 0xe, 0x7, 0x0, 0x0, 0x74, 0xbe},
Read: []uint8{0xe0, 0x1, 0x0, 0x0, 0x3f, 0xff, 0x10, 0x10, 0x3f},
},
}
var addr onewire.Address = 0x740000070e41ac28
var temp devices.Celsius = 30000 // 30.000°C
owBus := &onewiretest.Playback{Ops: ops}
bus := onewiretest.Playback{Ops: ops}
// Init the ds18b20.
ds18b20, err := New(owBus, addr, 10)
ds18b20, err := New(&bus, addr, 10)
if err != nil {
t.Fatal(err)
}
@ -59,6 +73,9 @@ func TestTemperature(t *testing.T) {
if dt < 188*time.Millisecond {
t.Errorf("expected conversion to take >187ms, took %s", dt)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
// TestConvertAll tests a temperature conversion on all ds18b20 using
@ -69,16 +86,33 @@ func TestConvertAll(t *testing.T) {
// Skip ROM + Convert
{Write: []uint8{0xcc, 0x44}, Read: []uint8(nil), Pull: true},
}
owBus := &onewiretest.Playback{Ops: ops}
bus := onewiretest.Playback{Ops: ops}
// Perform the conversion
t0 := time.Now()
if err := ConvertAll(owBus, 9); err != nil {
if err := ConvertAll(&bus, 9); err != nil {
t.Fatal(err)
}
// Expect it to take >93ms
if dt := time.Since(t0); dt < 94*time.Millisecond {
t.Errorf("expected conversion to take >93ms, took %s", dt)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestConvertAll_resolution(t *testing.T) {
bus := &onewiretest.Playback{}
if err := ConvertAll(bus, 1); err == nil {
t.Fatal("invalid resolution")
}
}
func TestConvertAll_fail(t *testing.T) {
bus := &onewiretest.Playback{DontPanic: true}
if err := ConvertAll(bus, 9); err == nil {
t.Fatal("invalid resolution")
}
}
/* Commented out in order not to import periph/host, need to move to smoke test

@ -13,15 +13,18 @@ import (
"periph.io/x/periph/conn/onewire"
)
// Dev is a handle to a ds248x device and it implements the onewire.Bus interface.
// Dev is a handle to a ds248x device and it implements the onewire.Bus
// interface.
//
// Dev implements a persistent error model: if a fatal error is encountered it places
// itself into an error state and immediately returns the last error on all subsequent
// calls. A fresh Dev, which reinitializes the hardware, must be created to proceed.
// Dev implements a persistent error model: if a fatal error is encountered it
// places itself into an error state and immediately returns the last error on
// all subsequent calls. A fresh Dev, which reinitializes the hardware, must be
// created to proceed.
//
// A persistent error is only set when there is a problem with the ds248x device itself
// (or the I²C bus used to access it). Errors on the 1-wire bus do not cause persistent
// errors and implement the onewire.BusError interface to indicate this fact.
// A persistent error is only set when there is a problem with the ds248x
// device itself (or the I²C bus used to access it). Errors on the 1-wire bus
// do not cause persistent errors and implement the onewire.BusError interface
// to indicate this fact.
type Dev struct {
sync.Mutex // lock for the bus while a transaction is in progress
i2c conn.Conn // i2c device handle for the ds248x
@ -32,24 +35,16 @@ type Dev struct {
err error // persistent error, device will no longer operate
}
// String
func (d *Dev) String() string {
return fmt.Sprintf("ds248x")
return "ds248x"
}
// Close drops the I²C bus handle and sets a persistent error.
func (d *Dev) Close() error {
d.i2c = nil
d.err = fmt.Errorf("ds248x: invalid operation on closed bus")
return nil
}
// Tx performs a bus transaction, sending and receiving bytes, and
// ending by pulling the bus high either weakly or strongly depending
// on the value of power.
// Tx performs a bus transaction, sending and receiving bytes, and ending by
// pulling the bus high either weakly or strongly depending on the value of
// power.
//
// A strong pull-up is typically required to power temperature conversion
// or EEPROM writes.
// A strong pull-up is typically required to power temperature conversion or
// EEPROM writes.
func (d *Dev) Tx(w, r []byte, power onewire.Pullup) error {
d.Lock()
defer d.Unlock()
@ -85,9 +80,9 @@ func (d *Dev) Tx(w, r []byte, power onewire.Pullup) error {
return d.err
}
// Search performs a "search" cycle on the 1-wire bus and returns the
// addresses of all devices on the bus if alarmOnly is false and of all
// devices in alarm state if alarmOnly is true.
// Search performs a "search" cycle on the 1-wire bus and returns the addresses
// of all devices on the bus if alarmOnly is false and of all devices in alarm
// state if alarmOnly is true.
//
// If an error occurs during the search the already-discovered devices are
// returned with the error.
@ -95,8 +90,8 @@ func (d *Dev) Search(alarmOnly bool) ([]onewire.Address, error) {
return onewire.Search(d, alarmOnly)
}
// SearchTriplet performs a single bit search triplet command on the bus,
// waits for it to complete and returs the outcome.
// SearchTriplet performs a single bit search triplet command on the bus, waits
// for it to complete and returs the outcome.
//
// SearchTriplet should not be used directly, use Search instead.
func (d *Dev) SearchTriplet(direction byte) (onewire.TripletResult, error) {
@ -136,7 +131,8 @@ func (d *Dev) reset() (bool, error) {
return (status & 2) != 0, nil
}
// i2cTx is a helper function to call i2c.Tx and handle the error by persisting it.
// i2cTx is a helper function to call i2c.Tx and handle the error by persisting
// it.
func (d *Dev) i2cTx(w, r []byte) {
if d.err != nil {
return
@ -147,11 +143,11 @@ func (d *Dev) i2cTx(w, r []byte) {
// waitIdle waits for the one wire bus to be idle.
//
// It initially sleeps for the delay and then polls the status register and
// sleeps for a tenth of the delay each time the status register indicates
// that the bus is still busy. The last read status byte is returned.
// sleeps for a tenth of the delay each time the status register indicates that
// the bus is still busy. The last read status byte is returned.
//
// An overall timeout of 3ms is applied to the whole procedure. waitIdle
// uses the persistent error model and returns 0 if there is an error.
// An overall timeout of 3ms is applied to the whole procedure. waitIdle uses
// the persistent error model and returns 0 if there is an error.
func (d *Dev) waitIdle(delay time.Duration) byte {
if d.err != nil {
return 0

@ -6,56 +6,79 @@ package ds248x
import (
"fmt"
"log"
"testing"
"periph.io/x/periph/conn/i2c/i2creg"
"periph.io/x/periph/conn/i2c/i2ctest"
)
// TestInit tests the initialization of a ds2483 using a recording.
func TestInit(t *testing.T) {
var ops = []i2ctest.IO{
{Addr: 0x18, Write: []byte{0xf0}, Read: []byte(nil)},
{Addr: 0x18, Write: []byte{0xe1, 0xf0}, Read: []byte{0x18}},
{Addr: 0x18, Write: []byte{0xd2, 0xe1}, Read: []byte{0x1}},
{Addr: 0x18, Write: []byte{0xe1, 0xb4}, Read: []byte(nil)},
{Addr: 0x18, Write: []byte{0xc3, 0x6, 0x26, 0x46, 0x66, 0x86}, Read: []byte(nil)},
{Addr: 0x18, Write: []byte{0x78, 0x0}, Read: []byte(nil)},
{Addr: 0x18, Write: []byte{}, Read: []byte{0xe8}},
}
bus := &i2ctest.Playback{Ops: ops}
if _, err := New(bus, nil); err != nil {
t.Fatal(err)
}
}
func Example() {
// Open the I²C bus to which the DS248x is connected.
i2cBus, err := i2creg.Open("")
if err != nil {
fmt.Println(err)
return
log.Fatal(err)
}
defer i2cBus.Close()
// Open the DS248x to get a 1-wire bus.
owBus, err := New(i2cBus, nil)
if err != nil {
fmt.Println(err)
return
log.Fatal(err)
}
// Search devices on the bus
devices, err := owBus.Search(false)
if err != nil {
fmt.Println(err)
return
log.Fatal(err)
}
fmt.Printf("Found %d 1-wire devices: ", len(devices))
for _, d := range devices {
fmt.Printf(" %#16x", uint64(d))
}
fmt.Print('\n')
fmt.Print("\n")
}
//
func TestNew(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
{Addr: 0x18, Write: []byte{0xf0}},
{Addr: 0x18, Write: []byte{0xe1, 0xf0}, Read: []byte{0x18}},
{Addr: 0x18, Write: []byte{0xd2, 0xe1}, Read: []byte{0x1}},
{Addr: 0x18, Write: []byte{0xe1, 0xb4}},
{Addr: 0x18, Write: []byte{0xc3, 0x6, 0x26, 0x46, 0x66, 0x86}},
},
}
d, err := New(&bus, nil)
if err != nil {
t.Fatal(err)
}
if s := d.String(); s != "ds248x" {
t.Fatal(s)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestNew_opts(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
{Addr: 0x18, Write: []byte{0xf0}},
{Addr: 0x18, Write: []byte{0xe1, 0xf0}, Read: []byte{0x18}},
{Addr: 0x18, Write: []byte{0xd2, 0xe1}, Read: []byte{0x1}},
{Addr: 0x18, Write: []byte{0xe1, 0xb4}},
{Addr: 0x18, Write: []byte{0xc3, 0x6, 0x26, 0x46, 0x66, 0x86}},
},
}
opts := &Opts{Addr: 0x18}
if _, err := New(&bus, opts); err != nil {
t.Fatal(err)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
/* Commented out in order not to import periph/host, need to move to smoke test

Loading…
Cancel
Save