1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-27 13:48:56 +08:00
hybridgroup.gobot/drivers/i2c/i2c_driver.go
Thomas Kohler ad59d23e2e introduce generic i2c.Driver with example for digispark
fix missing/wrong entries in README
stabilize test
2022-10-02 14:18:08 +02:00

131 lines
2.9 KiB
Go

package i2c
import (
"fmt"
"strconv"
"sync"
"gobot.io/x/gobot"
)
// Driver implements the interface gobot.Driver.
type Driver struct {
name string
defaultAddress int
connector Connector
connection Connection
afterStart func() error
beforeHalt func() error
Config
gobot.Commander
mutex *sync.Mutex // mutex often needed to ensure that write-read sequences are not interrupted
}
// NewDriver creates a new generic and basic i2c gobot driver.
func NewDriver(c Connector, name string, address int, options ...func(Config)) *Driver {
d := &Driver{
name: gobot.DefaultName(name),
defaultAddress: address,
connector: c,
afterStart: func() error { return nil },
beforeHalt: func() error { return nil },
Config: NewConfig(),
Commander: gobot.NewCommander(),
mutex: &sync.Mutex{},
}
for _, option := range options {
option(d)
}
return d
}
// Name returns the name of the i2c device.
func (d *Driver) Name() string {
return d.name
}
// SetName sets the name of the i2c device.
func (d *Driver) SetName(name string) {
d.name = name
}
// Connection returns the connection of the i2c device.
func (d *Driver) Connection() gobot.Connection {
return d.connector.(gobot.Connection)
}
// Start initializes the i2c device.
func (d *Driver) Start() error {
d.mutex.Lock()
defer d.mutex.Unlock()
var err error
bus := d.GetBusOrDefault(d.connector.GetDefaultBus())
address := d.GetAddressOrDefault(int(d.defaultAddress))
if d.connection, err = d.connector.GetConnection(address, bus); err != nil {
return err
}
return d.afterStart()
}
// Halt halts the i2c device.
func (d *Driver) Halt() error {
d.mutex.Lock()
defer d.mutex.Unlock()
if err := d.beforeHalt(); err != nil {
return err
}
// currently there is nothing to do here for the driver
return nil
}
// Write implements a simple write mechanism to the given register of an i2c device.
func (d *Driver) Write(pin string, val int) error {
d.mutex.Lock()
defer d.mutex.Unlock()
register, err := driverParseRegister(pin)
if err != nil {
return err
}
// TODO: create buffer from size
// currently only one byte value is supported
b := []byte{uint8(val)}
return d.connection.WriteBlockData(uint8(register), b)
}
// Read implements a simple read mechanism from the given register of an i2c device.
func (d *Driver) Read(pin string) (int, error) {
d.mutex.Lock()
defer d.mutex.Unlock()
register, err := driverParseRegister(pin)
if err != nil {
return 0, err
}
// TODO: create buffer from size
// currently only one byte value is supported
b := []byte{0}
if err := d.connection.ReadBlockData(register, b); err != nil {
return 0, err
}
return int(b[0]), nil
}
func driverParseRegister(pin string) (uint8, error) {
register, err := strconv.ParseUint(pin, 10, 8)
if err != nil {
return 0, fmt.Errorf("Could not parse the register from given pin '%s'", pin)
}
return uint8(register), nil
}