add correct Tx implementation for mock I2C interfaces

This commit is contained in:
soypat
2023-05-28 22:04:10 -03:00
committed by Ron Evans
parent e6f82fad2e
commit 64029612e0
5 changed files with 40 additions and 22 deletions
+7 -8
View File
@@ -2,14 +2,13 @@ package legacy
import "tinygo.org/x/drivers" import "tinygo.org/x/drivers"
type I2C struct { func ReadRegister(bus drivers.I2C, addr uint8, reg uint8, data []byte) error {
i2c drivers.I2C return bus.Tx(uint16(addr), []byte{reg}, data)
} }
func ReadRegister(i2c drivers.I2C, addr uint8, reg uint8, buf []byte) error { func WriteRegister(bus drivers.I2C, addr uint8, reg uint8, data []byte) error {
return i2c.Tx(uint16(addr), []byte{reg}, buf) buf := make([]uint8, len(data)+1)
} buf[0] = reg
copy(buf[1:], data)
func WriteRegister(i2c drivers.I2C, addr uint8, reg uint8, buf []byte) error { return bus.Tx(uint16(addr), buf, nil)
return i2c.Tx(uint16(addr), append([]byte{reg}, buf...), nil)
} }
+3 -9
View File
@@ -9,6 +9,7 @@ package mcp23017
import ( import (
"errors" "errors"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy" "tinygo.org/x/drivers/internal/legacy"
) )
@@ -77,19 +78,12 @@ const (
// address pins). // address pins).
var ErrInvalidHWAddress = errors.New("invalid hardware address") 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 // New returns a new MCP23017 device at the given I2C address
// on the given bus. // on the given bus.
// It returns ErrInvalidHWAddress if the address isn't possible for the device. // It returns ErrInvalidHWAddress if the address isn't possible for the device.
// //
// By default all pins are configured as inputs. // 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 { if address&hwAddressMask != hwAddress {
return nil, ErrInvalidHWAddress return nil, ErrInvalidHWAddress
} }
@@ -117,7 +111,7 @@ type Device struct {
// bus holds the reference the I2C bus that the device lives on. // bus holds the reference the I2C bus that the device lives on.
// It's an interface so that we can write tests for it. // It's an interface so that we can write tests for it.
bus I2C bus drivers.I2C
addr uint8 addr uint8
// pins caches the most recent pin values that have been set. // pins caches the most recent pin values that have been set.
// This enables us to change individual pin values without // This enables us to change individual pin values without
+3 -1
View File
@@ -1,5 +1,7 @@
package mcp23017 package mcp23017
import "tinygo.org/x/drivers"
// All is a convenience value that represents all pins high (or all mask bits one). // All is a convenience value that represents all pins high (or all mask bits one).
var All = PinSlice{0xffff} var All = PinSlice{0xffff}
@@ -12,7 +14,7 @@ type Devices []*Device
// NewI2CDevices returns a Devices slice holding the Device values // NewI2CDevices returns a Devices slice holding the Device values
// for all the given addresses on the given bus. // for all the given addresses on the given bus.
// When more than one bus is in use, create the slice yourself. // 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)) devs := make(Devices, len(addrs))
for i, addr := range addrs { for i, addr := range addrs {
dev, err := NewI2C(bus, addr) dev, err := NewI2C(bus, addr)
+12 -2
View File
@@ -75,6 +75,16 @@ func (d *I2CDevice16) WriteRegister(r uint8, buf []byte) error {
// Tx implements I2C.Tx. // Tx implements I2C.Tx.
func (bus *I2CDevice16) Tx(w, r []byte) error { func (bus *I2CDevice16) Tx(w, r []byte) error {
// TODO: implement this switch len(w) {
return nil 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:])
}
} }
+15 -2
View File
@@ -38,6 +38,9 @@ func (d *I2CDevice8) ReadRegister(r uint8, buf []byte) error {
if d.Err != nil { if d.Err != nil {
return d.Err return d.Err
} }
if len(buf) == 0 {
d.c.Fatalf("no register buffer to read into")
}
d.assertRegisterRange(r, buf) d.assertRegisterRange(r, buf)
copy(buf, d.Registers[r:]) copy(buf, d.Registers[r:])
return nil return nil
@@ -55,8 +58,18 @@ func (d *I2CDevice8) WriteRegister(r uint8, buf []byte) error {
// Tx implements I2C.Tx. // Tx implements I2C.Tx.
func (bus *I2CDevice8) Tx(w, r []byte) error { func (bus *I2CDevice8) Tx(w, r []byte) error {
// TODO: implement this switch len(w) {
return nil 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 // assertRegisterRange asserts that reading or writing the given