From 7dc1026c65725548890db00498d329672b63c0cc Mon Sep 17 00:00:00 2001 From: M-A Date: Mon, 25 Sep 2017 09:25:18 -0400 Subject: [PATCH] conn: Add Resource, superseds devices.Device (#162) In practice I want to be able for gpioreg.Register() to eventually enforce that Halt() is implemented on gpio.Pin, so that three's a consistent way to stop gpiostream operations or PWM() output. This requires the interface to live in conn, not in devices. Do not use go1.9 type alias to not break compatibility with older Go version yet. --- devices/apa102/apa102.go | 3 ++- devices/bmxx80/bmxx80.go | 2 +- devices/devices.go | 9 ++------- devices/devicestest/display.go | 5 +++-- devices/ds18b20/ds18b20.go | 5 +++-- devices/ds248x/dev.go | 5 ++--- devices/lepton/cci/cci.go | 23 ++++++++++++----------- devices/lepton/cci/cci_test.go | 32 ++++++++++++++++---------------- devices/lepton/lepton.go | 2 +- devices/ssd1306/ssd1306.go | 2 +- devices/tm1637/tm1637.go | 4 ++-- 11 files changed, 45 insertions(+), 47 deletions(-) diff --git a/devices/apa102/apa102.go b/devices/apa102/apa102.go index 4bcf13e..0f9aa35 100644 --- a/devices/apa102/apa102.go +++ b/devices/apa102/apa102.go @@ -10,6 +10,7 @@ import ( "image" "image/color" + "periph.io/x/periph/conn" "periph.io/x/periph/conn/spi" "periph.io/x/periph/devices" ) @@ -314,6 +315,6 @@ func New(p spi.Port, numPixels int, intensity uint8, temperature uint16) (*Dev, // -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ devices.Display = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/bmxx80/bmxx80.go b/devices/bmxx80/bmxx80.go index 5f57470..28f907d 100644 --- a/devices/bmxx80/bmxx80.go +++ b/devices/bmxx80/bmxx80.go @@ -514,6 +514,6 @@ var defaults = Opts{ Humidity: O4x, } +var _ conn.Resource = &Dev{} var _ devices.Environmental = &Dev{} -var _ devices.Device = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/devices.go b/devices/devices.go index 63d2378..176e3ad 100644 --- a/devices/devices.go +++ b/devices/devices.go @@ -14,14 +14,9 @@ import ( // Device is a basic device. // -// It is expected to implement fmt.Stringer. +// This interface is deprecated and will be removed in v3. Use conn.Resource +// instead. type Device interface { - // Halt stops the device. - // - // Unlike a connection, a device cannot be closed, only the port can be - // closed. On the other hand, a device can be halted. What halting entails - // depends on the actual device but it should stop motion, sensing or light - // emission. Halt() error } diff --git a/devices/devicestest/display.go b/devices/devicestest/display.go index 2a56311..d55c779 100644 --- a/devices/devicestest/display.go +++ b/devices/devicestest/display.go @@ -11,6 +11,7 @@ import ( "image/color" "image/draw" + "periph.io/x/periph/conn" "periph.io/x/periph/devices" ) @@ -23,7 +24,7 @@ func (d *Display) String() string { return "Display" } -// Halt implements devices.Device. It is a noop. +// Halt implements conn.Resource. It is a noop. func (d *Display) Halt() error { return nil } @@ -52,6 +53,6 @@ func (d *Display) Draw(r image.Rectangle, src image.Image, sp image.Point) { draw.Draw(d.Img, r, src, sp, draw.Src) } +var _ conn.Resource = &Display{} var _ devices.Display = &Display{} -var _ devices.Device = &Display{} var _ fmt.Stringer = &Display{} diff --git a/devices/ds18b20/ds18b20.go b/devices/ds18b20/ds18b20.go index 42480d9..caa0fa9 100644 --- a/devices/ds18b20/ds18b20.go +++ b/devices/ds18b20/ds18b20.go @@ -26,6 +26,7 @@ import ( "fmt" "time" + "periph.io/x/periph/conn" "periph.io/x/periph/conn/onewire" "periph.io/x/periph/devices" ) @@ -98,7 +99,7 @@ func (d *Dev) String() string { return fmt.Sprintf("DS18B20{%v}", d.onewire) } -// Halt implements devices.Device. +// Halt implements conn.Resource. func (d *Dev) Halt() error { return nil } @@ -174,5 +175,5 @@ func (d *Dev) readScratchpad() ([]byte, error) { return spad[:8], nil } -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/ds248x/dev.go b/devices/ds248x/dev.go index 2086703..bf1a8fc 100644 --- a/devices/ds248x/dev.go +++ b/devices/ds248x/dev.go @@ -11,7 +11,6 @@ import ( "periph.io/x/periph/conn" "periph.io/x/periph/conn/onewire" - "periph.io/x/periph/devices" ) // Dev is a handle to a ds248x device and it implements the onewire.Bus @@ -43,7 +42,7 @@ func (d *Dev) String() string { return fmt.Sprintf("DS2482-100{%s}", d.i2c) } -// Halt implements devices.Device. +// Halt implements conn.Resource. func (d *Dev) Halt() error { return nil } @@ -197,5 +196,5 @@ type busError string func (e busError) Error() string { return string(e) } func (e busError) BusError() bool { return true } -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/lepton/cci/cci.go b/devices/lepton/cci/cci.go index 5b114ed..95e0004 100644 --- a/devices/lepton/cci/cci.go +++ b/devices/lepton/cci/cci.go @@ -28,6 +28,7 @@ import ( "sync" "time" + "periph.io/x/periph/conn" "periph.io/x/periph/conn/i2c" "periph.io/x/periph/conn/mmr" "periph.io/x/periph/devices" @@ -150,14 +151,14 @@ type FFCMode struct { // // Maximum I²C speed is 1Mhz. type Dev struct { - c conn + c cciConn serial uint64 } // New returns a driver for the FLIR Lepton CCI protocol. func New(i i2c.Bus) (*Dev, error) { d := &Dev{ - c: conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: i, Addr: 0x2A}, Order: internal.Big16}}, + c: cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: i, Addr: 0x2A}, Order: internal.Big16}}, } // Wait for the device to be booted. for { @@ -313,21 +314,21 @@ func (d *Dev) RunFFC() error { // -// conn is the low level connection. +// cciConn is the low level connection. // // It implements the low level protocol to run the GET, SET and RUN commands // via memory mapped registers. -type conn struct { +type cciConn struct { mu sync.Mutex r mmr.Dev16 } -func (c *conn) String() string { +func (c *cciConn) String() string { return fmt.Sprintf("%s", &c.r) } // waitIdle waits for the busy bit to clear. -func (c *conn) waitIdle() (StatusBit, error) { +func (c *cciConn) waitIdle() (StatusBit, error) { // Do not take the lock. for { if s, err := c.r.ReadUint16(regStatus); err != nil || StatusBit(s)&StatusBusy == 0 { @@ -338,7 +339,7 @@ func (c *conn) waitIdle() (StatusBit, error) { } // get returns an attribute by querying the device. -func (c *conn) get(cmd command, data interface{}) error { +func (c *cciConn) get(cmd command, data interface{}) error { if data == nil { return errors.New("lepton-cci: get() argument must not be nil") } @@ -393,7 +394,7 @@ func (c *conn) get(cmd command, data interface{}) error { } // set returns an attribute on the device. -func (c *conn) set(cmd command, data interface{}) error { +func (c *cciConn) set(cmd command, data interface{}) error { if data == nil { return errors.New("lepton-cci: set() argument must not be nil") } @@ -437,7 +438,7 @@ func (c *conn) set(cmd command, data interface{}) error { } // run runs a command on the device that doesn't need any argument. -func (c *conn) run(cmd command) error { +func (c *cciConn) run(cmd command) error { c.mu.Lock() defer c.mu.Unlock() if _, err := c.waitIdle(); err != nil { @@ -557,6 +558,6 @@ const ( // TODO(maruel): Enable RadXXX commands. -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ fmt.Stringer = &Dev{} -var _ fmt.Stringer = &conn{} +var _ fmt.Stringer = &cciConn{} diff --git a/devices/lepton/cci/cci_test.go b/devices/lepton/cci/cci_test.go index 557926f..7cf1d40 100644 --- a/devices/lepton/cci/cci_test.go +++ b/devices/lepton/cci/cci_test.go @@ -105,7 +105,7 @@ func TestWaitIdle(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x00, 0x06}}, } bus := i2ctest.Playback{Ops: ops} - d := Dev{c: conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}}} + d := Dev{c: cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}}} if _, err := d.WaitIdle(); err != nil { t.Fatal(err) } @@ -262,7 +262,7 @@ func TestConn_get(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x08}, R: []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if err := c.get(sysStatus, &v); err != nil { t.Fatal(err) @@ -275,7 +275,7 @@ func TestConn_get(t *testing.T) { for len(ops) != 0 { ops = ops[:len(ops)-1] bus := i2ctest.Playback{Ops: ops, DontPanic: true} - c = conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c = cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if c.get(sysStatus, &v) == nil { t.Fatal("should have failed") @@ -300,7 +300,7 @@ func TestConn_get_large(t *testing.T) { {Addr: 42, W: []byte{0xf8, 0}, R: make([]byte, 2048)}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} v := make([]byte, 2048) if err := c.get(sysStatus, v); err != nil { t.Fatal(err) @@ -322,7 +322,7 @@ func TestConn_get_fail_waitidle(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x01, 0x00}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if c.get(sysStatus, &v) == nil { t.Fatal("waitIdle failed") @@ -334,7 +334,7 @@ func TestConn_get_fail_waitidle(t *testing.T) { func TestConn_get_fail(t *testing.T) { bus := i2ctest.Playback{} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} if c.get(sysStatus, nil) == nil { t.Fatal("nil value") } @@ -365,7 +365,7 @@ func TestConn_set(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x00, 0x06}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if err := c.set(sysStatus, &v); err != nil { t.Fatal(err) @@ -378,7 +378,7 @@ func TestConn_set(t *testing.T) { for len(ops) != 0 { ops = ops[:len(ops)-1] bus := i2ctest.Playback{Ops: ops, DontPanic: true} - c = conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c = cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if c.set(sysStatus, &v) == nil { t.Fatal("should have failed") @@ -403,7 +403,7 @@ func TestConn_set_large(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x00, 0x06}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} v := make([]byte, 2048) if err := c.set(sysStatus, v); err != nil { t.Fatal(err) @@ -427,7 +427,7 @@ func TestConn_set_fail_waitidle(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x0f, 0x00}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} var v internal.Status if c.set(sysStatus, &v) == nil { t.Fatal("waitIdle failed") @@ -439,7 +439,7 @@ func TestConn_set_fail_waitidle(t *testing.T) { func TestConn_set_fail(t *testing.T) { bus := i2ctest.Playback{} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} if c.set(sysStatus, nil) == nil { t.Fatal("nil value") } @@ -465,7 +465,7 @@ func TestConn_run(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x00, 0x06}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} if err := c.run(sysFCCRunNormalization); err != nil { t.Fatal(err) } @@ -477,7 +477,7 @@ func TestConn_run(t *testing.T) { for len(ops) != 0 { ops = ops[:len(ops)-1] bus := i2ctest.Playback{Ops: ops, DontPanic: true} - c = conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c = cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} if c.run(sysFCCRunNormalization) == nil { t.Fatal("should have failed") } @@ -499,7 +499,7 @@ func TestConn_run_fail_waitidle(t *testing.T) { {Addr: 42, W: []byte{0x00, 0x02}, R: []byte{0x0f, 0x00}}, } bus := i2ctest.Playback{Ops: ops} - c := conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} + c := cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: &bus, Addr: 0x2A}, Order: internal.Big16}} if c.run(sysFCCRunNormalization) == nil { t.Fatal("waitIdle failed") } @@ -561,13 +561,13 @@ func TestStrings(t *testing.T) { func getDev(ops []i2ctest.IO) (*i2ctest.Playback, *Dev) { bus := &i2ctest.Playback{Ops: ops} - d := &Dev{c: conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: bus, Addr: 0x2A}, Order: internal.Big16}}} + d := &Dev{c: cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: bus, Addr: 0x2A}, Order: internal.Big16}}} return bus, d } func getDevFail() *Dev { bus := &i2ctest.Playback{DontPanic: true} - d := &Dev{c: conn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: bus, Addr: 0x2A}, Order: internal.Big16}}} + d := &Dev{c: cciConn{r: mmr.Dev16{Conn: &i2c.Dev{Bus: bus, Addr: 0x2A}, Order: internal.Big16}}} return d } diff --git a/devices/lepton/lepton.go b/devices/lepton/lepton.go index 040898e..3cafea8 100644 --- a/devices/lepton/lepton.go +++ b/devices/lepton/lepton.go @@ -454,5 +454,5 @@ func verifyCRC(d []byte) bool { return internal.CRC16(tmp) == internal.Big16.Uint16(d[2:]) } -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/ssd1306/ssd1306.go b/devices/ssd1306/ssd1306.go index 044080b..eb55dbc 100644 --- a/devices/ssd1306/ssd1306.go +++ b/devices/ssd1306/ssd1306.go @@ -488,6 +488,6 @@ const ( i2cData = 0x40 // I²C transaction has stream of data bytes ) +var _ conn.Resource = &Dev{} var _ devices.Display = &Dev{} -var _ devices.Device = &Dev{} var _ fmt.Stringer = &Dev{} diff --git a/devices/tm1637/tm1637.go b/devices/tm1637/tm1637.go index 111c604..793a3e2 100644 --- a/devices/tm1637/tm1637.go +++ b/devices/tm1637/tm1637.go @@ -15,8 +15,8 @@ import ( "runtime" "time" + "periph.io/x/periph/conn" "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/devices" "periph.io/x/periph/host/cpu" ) @@ -200,5 +200,5 @@ func (d *Dev) sleepHalfCycle() { cpu.Nanospin(clockHalfCycle) } -var _ devices.Device = &Dev{} +var _ conn.Resource = &Dev{} var _ fmt.Stringer = &Dev{}