diff --git a/internal/legacy/i2clegacy.go b/internal/legacy/i2clegacy.go index 284343c..ace7727 100644 --- a/internal/legacy/i2clegacy.go +++ b/internal/legacy/i2clegacy.go @@ -2,14 +2,13 @@ package legacy import "tinygo.org/x/drivers" -type I2C struct { - i2c drivers.I2C +func ReadRegister(bus drivers.I2C, addr uint8, reg uint8, data []byte) error { + return bus.Tx(uint16(addr), []byte{reg}, data) } -func ReadRegister(i2c drivers.I2C, addr uint8, reg uint8, buf []byte) error { - return i2c.Tx(uint16(addr), []byte{reg}, buf) -} - -func WriteRegister(i2c drivers.I2C, addr uint8, reg uint8, buf []byte) error { - return i2c.Tx(uint16(addr), append([]byte{reg}, buf...), nil) +func WriteRegister(bus drivers.I2C, addr uint8, reg uint8, data []byte) error { + buf := make([]uint8, len(data)+1) + buf[0] = reg + copy(buf[1:], data) + return bus.Tx(uint16(addr), buf, nil) } diff --git a/mcp23017/device.go b/mcp23017/device.go index 6138c14..444a314 100644 --- a/mcp23017/device.go +++ b/mcp23017/device.go @@ -9,6 +9,7 @@ package mcp23017 import ( "errors" + "tinygo.org/x/drivers" "tinygo.org/x/drivers/internal/legacy" ) @@ -77,19 +78,12 @@ const ( // address pins). var ErrInvalidHWAddress = errors.New("invalid hardware address") -// I2C represents an I2C bus. It is notably implemented by the -// machine.I2C type. -type I2C interface { - ReadRegister(addr uint8, r uint8, buf []byte) error - WriteRegister(addr uint8, r uint8, buf []byte) error -} - // New returns a new MCP23017 device at the given I2C address // on the given bus. // It returns ErrInvalidHWAddress if the address isn't possible for the device. // // By default all pins are configured as inputs. -func NewI2C(bus I2C, address uint8) (*Device, error) { +func NewI2C(bus drivers.I2C, address uint8) (*Device, error) { if address&hwAddressMask != hwAddress { return nil, ErrInvalidHWAddress } @@ -117,7 +111,7 @@ type Device struct { // bus holds the reference the I2C bus that the device lives on. // It's an interface so that we can write tests for it. - bus I2C + bus drivers.I2C addr uint8 // pins caches the most recent pin values that have been set. // This enables us to change individual pin values without diff --git a/mcp23017/multidevice.go b/mcp23017/multidevice.go index fa13520..100dc68 100644 --- a/mcp23017/multidevice.go +++ b/mcp23017/multidevice.go @@ -1,5 +1,7 @@ package mcp23017 +import "tinygo.org/x/drivers" + // All is a convenience value that represents all pins high (or all mask bits one). var All = PinSlice{0xffff} @@ -12,7 +14,7 @@ type Devices []*Device // NewI2CDevices returns a Devices slice holding the Device values // for all the given addresses on the given bus. // When more than one bus is in use, create the slice yourself. -func NewI2CDevices(bus I2C, addrs ...uint8) (Devices, error) { +func NewI2CDevices(bus drivers.I2C, addrs ...uint8) (Devices, error) { devs := make(Devices, len(addrs)) for i, addr := range addrs { dev, err := NewI2C(bus, addr) diff --git a/tester/device16.go b/tester/device16.go index 4c6c81c..b424462 100644 --- a/tester/device16.go +++ b/tester/device16.go @@ -75,6 +75,16 @@ func (d *I2CDevice16) WriteRegister(r uint8, buf []byte) error { // Tx implements I2C.Tx. func (bus *I2CDevice16) Tx(w, r []byte) error { - // TODO: implement this - return nil + switch len(w) { + case 0: + bus.c.Fatalf("i2c mock: need a write byte") + return nil + case 1: + return bus.ReadRegister(w[0], r) + default: + if len(r) > 0 || len(w) == 1 { + bus.c.Fatalf("i2c mock: unsupported lengths in Tx(%d, %d)", len(w), len(r)) + } + return bus.WriteRegister(w[0], w[1:]) + } } diff --git a/tester/device8.go b/tester/device8.go index 114cf53..7fa5a40 100644 --- a/tester/device8.go +++ b/tester/device8.go @@ -38,6 +38,9 @@ func (d *I2CDevice8) ReadRegister(r uint8, buf []byte) error { if d.Err != nil { return d.Err } + if len(buf) == 0 { + d.c.Fatalf("no register buffer to read into") + } d.assertRegisterRange(r, buf) copy(buf, d.Registers[r:]) return nil @@ -55,8 +58,18 @@ func (d *I2CDevice8) WriteRegister(r uint8, buf []byte) error { // Tx implements I2C.Tx. func (bus *I2CDevice8) Tx(w, r []byte) error { - // TODO: implement this - return nil + switch len(w) { + case 0: + bus.c.Fatalf("i2c mock: need a write byte") + return nil + case 1: + return bus.ReadRegister(w[0], r) + default: + if len(r) > 0 || len(w) == 1 { + bus.c.Fatalf("i2c mock: unsupported lengths in Tx(%d, %d)", len(w), len(r)) + } + return bus.WriteRegister(w[0], w[1:]) + } } // assertRegisterRange asserts that reading or writing the given