90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package adaptors
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
multierror "github.com/hashicorp/go-multierror"
|
|
|
|
"gobot.io/x/gobot/v2"
|
|
"gobot.io/x/gobot/v2/drivers/i2c"
|
|
"gobot.io/x/gobot/v2/system"
|
|
)
|
|
|
|
type i2cBusNumberValidator func(busNumber int) error
|
|
|
|
// I2cBusAdaptor is a adaptor for i2c bus, normally used for composition in platforms.
|
|
type I2cBusAdaptor struct {
|
|
sys *system.Accesser
|
|
validateNumber i2cBusNumberValidator
|
|
defaultBusNumber int
|
|
mutex sync.Mutex
|
|
buses map[int]gobot.I2cSystemDevicer
|
|
}
|
|
|
|
// NewI2cBusAdaptor provides the access to i2c buses of the board. The validator is used to check the bus number,
|
|
// which is given by user, to the abilities of the board.
|
|
func NewI2cBusAdaptor(sys *system.Accesser, v i2cBusNumberValidator, defaultBusNr int) *I2cBusAdaptor {
|
|
a := &I2cBusAdaptor{
|
|
sys: sys,
|
|
validateNumber: v,
|
|
defaultBusNumber: defaultBusNr,
|
|
}
|
|
return a
|
|
}
|
|
|
|
// Connect prepares the connection to i2c buses.
|
|
func (a *I2cBusAdaptor) Connect() error {
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
|
|
a.buses = make(map[int]gobot.I2cSystemDevicer)
|
|
return nil
|
|
}
|
|
|
|
// Finalize closes all i2c buses.
|
|
func (a *I2cBusAdaptor) Finalize() error {
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
|
|
var err error
|
|
for _, bus := range a.buses {
|
|
if bus != nil {
|
|
if e := bus.Close(); e != nil {
|
|
err = multierror.Append(err, e)
|
|
}
|
|
}
|
|
}
|
|
a.buses = nil
|
|
return err
|
|
}
|
|
|
|
// GetI2cConnection returns a connection to a device on a specified i2c bus
|
|
func (a *I2cBusAdaptor) GetI2cConnection(address int, busNum int) (i2c.Connection, error) {
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
|
|
if a.buses == nil {
|
|
return nil, fmt.Errorf("not connected")
|
|
}
|
|
|
|
bus := a.buses[busNum]
|
|
if bus == nil {
|
|
err := a.validateNumber(busNum)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
bus, err = a.sys.NewI2cDevice(fmt.Sprintf("/dev/i2c-%d", busNum))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
a.buses[busNum] = bus
|
|
}
|
|
return i2c.NewConnection(bus, address), nil
|
|
}
|
|
|
|
// DefaultI2cBus returns the default i2c bus number for this platform.
|
|
func (a *I2cBusAdaptor) DefaultI2cBus() int {
|
|
return a.defaultBusNumber
|
|
}
|