mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-03 14:37:46 +00:00
tester: add very basic mock structs for testing i2c devices, based on work done by @rogpeppe
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
@@ -2,4 +2,7 @@ module tinygo.org/x/drivers
|
||||
|
||||
go 1.14
|
||||
|
||||
require github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||
github.com/frankban/quicktest v1.10.2
|
||||
)
|
||||
|
||||
@@ -1,2 +1,13 @@
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/frankban/quicktest v1.10.2 h1:19ARM85nVi4xH7xPXuc5eM/udya5ieh7b/Sv+d844Tk=
|
||||
github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package drivers
|
||||
|
||||
// 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
|
||||
Tx(addr uint16, w, r []byte) error
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package tester
|
||||
|
||||
import (
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
const maxRegisters = 200
|
||||
|
||||
// I2CDevice represents a mock I2C device on a mock I2C bus.
|
||||
type I2CDevice struct {
|
||||
C *qt.C
|
||||
Addr uint8
|
||||
// Registers holds the device registers. It can be inspected
|
||||
// or changed as desired for testing.
|
||||
Registers [maxRegisters]uint8
|
||||
// If Err is non-nil, it will be returned as the error from the
|
||||
// I2C methods.
|
||||
Err error
|
||||
}
|
||||
|
||||
// NewI2CDevice returns a new mock I2C device.
|
||||
func NewI2CDevice(c *qt.C, addr uint8) *I2CDevice {
|
||||
return &I2CDevice{
|
||||
C: c,
|
||||
Addr: addr,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadRegister implements I2C.ReadRegister.
|
||||
func (d *I2CDevice) ReadRegister(r uint8, buf []byte) error {
|
||||
if d.Err != nil {
|
||||
return d.Err
|
||||
}
|
||||
d.AssertRegisterRange(r, buf)
|
||||
copy(buf, d.Registers[r:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteRegister implements I2C.WriteRegister.
|
||||
func (d *I2CDevice) WriteRegister(r uint8, buf []byte) error {
|
||||
if d.Err != nil {
|
||||
return d.Err
|
||||
}
|
||||
d.AssertRegisterRange(r, buf)
|
||||
copy(d.Registers[r:], buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertRegisterRange asserts that reading or writing the given
|
||||
// register and subsequent registers is in range of the available registers.
|
||||
func (d *I2CDevice) AssertRegisterRange(r uint8, buf []byte) {
|
||||
if int(r) >= len(d.Registers) {
|
||||
d.C.Fatalf("register read/write [%#x, %#x] start out of range", r, int(r)+len(buf))
|
||||
}
|
||||
if int(r)+len(buf) > len(d.Registers) {
|
||||
d.C.Fatalf("register read/write [%#x, %#x] end out of range", r, int(r)+len(buf))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package tester
|
||||
|
||||
import (
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
// I2CBus implements the I2C interface in memory for testing.
|
||||
type I2CBus struct {
|
||||
C *qt.C
|
||||
Devices []*I2CDevice
|
||||
}
|
||||
|
||||
// NewI2CBus returns an I2CBus mock I2C instance that uses c to flag errors
|
||||
// if they happen. After creating a I2C instance, add devices
|
||||
// to it with addDevice before using NewI2CBus interface.
|
||||
func NewI2CBus(c *qt.C) *I2CBus {
|
||||
return &I2CBus{
|
||||
C: c,
|
||||
}
|
||||
}
|
||||
|
||||
// AddDevice adds a new mock device to the mock I2C bus.
|
||||
func (bus *I2CBus) AddDevice(d *I2CDevice) {
|
||||
bus.Devices = append(bus.Devices, d)
|
||||
}
|
||||
|
||||
// ReadRegister implements I2C.ReadRegister.
|
||||
func (bus *I2CBus) ReadRegister(addr uint8, r uint8, buf []byte) error {
|
||||
return bus.FindDevice(addr).ReadRegister(r, buf)
|
||||
}
|
||||
|
||||
// WriteRegister implements I2C.WriteRegister.
|
||||
func (bus *I2CBus) WriteRegister(addr uint8, r uint8, buf []byte) error {
|
||||
return bus.FindDevice(addr).WriteRegister(r, buf)
|
||||
}
|
||||
|
||||
// Tx implements I2C.Tx.
|
||||
func (bus *I2CBus) Tx(addr uint16, input, output []byte) error {
|
||||
// TODO: implement this
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindDevice returns the device with the given address.
|
||||
func (bus *I2CBus) FindDevice(addr uint8) *I2CDevice {
|
||||
for _, dev := range bus.Devices {
|
||||
if dev.Addr == addr {
|
||||
return dev
|
||||
}
|
||||
}
|
||||
bus.C.Fatalf("invalid device addr %#x passed to i2c bus", addr)
|
||||
panic("unreachable")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Package tester contains mock structs to make it easier to test I2C devices.
|
||||
//
|
||||
// TODO: info on how to use this.
|
||||
//
|
||||
package tester // import "tinygo.org/x/drivers/tester"
|
||||
Reference in New Issue
Block a user