1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-29 13:49:14 +08:00
hybridgroup.gobot/drivers/i2c/generic_driver.go
Thomas Kohler 865e724af0
Build(v2): revert move to v2 subfolder (#932)
* revert move to v2 subfolder
* fix CI and adjust CHANGELOG
2023-05-29 19:23:28 +02:00

149 lines
4.0 KiB
Go

package i2c
import (
"fmt"
"time"
)
// GenericDriver implements the interface gobot.Driver.
type GenericDriver struct {
*Driver
}
// NewGenericDriver creates a new generic i2c gobot driver, which just forwards all connection functions.
func NewGenericDriver(c Connector, name string, address int, options ...func(Config)) *GenericDriver {
return &GenericDriver{Driver: NewDriver(c, name, address, options...)}
}
// WriteByte writes one byte to the i2c device.
func (d *GenericDriver) WriteByte(val byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.WriteByte(val)
}
// WriteByteData writes the given byte value to the given register of an i2c device.
func (d *GenericDriver) WriteByteData(reg uint8, val byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.WriteByteData(reg, val)
}
// WriteWordData writes the given 16 bit value to the given register of an i2c device.
func (d *GenericDriver) WriteWordData(reg uint8, val uint16) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.WriteWordData(reg, val)
}
// WriteBlockData writes the given buffer to the given register of an i2c device.
func (d *GenericDriver) WriteBlockData(reg uint8, data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.WriteBlockData(reg, data)
}
// WriteData writes the given buffer to the given register of an i2c device.
// It uses plain write to prevent WriteBlockData(), which is sometimes not supported by adaptor.
func (d *GenericDriver) WriteData(reg uint8, data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
buf := make([]byte, len(data)+1)
copy(buf[1:], data)
buf[0] = reg
return d.writeAndCheckCount(buf)
}
// Write writes the given buffer to the i2c device.
func (d *GenericDriver) Write(data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.writeAndCheckCount(data)
}
// ReadByte reads a byte from the current register of an i2c device.
func (d *GenericDriver) ReadByte() (byte, error) {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.ReadByte()
}
// ReadByteData reads a byte from the given register of an i2c device.
func (d *GenericDriver) ReadByteData(reg uint8) (byte, error) {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.ReadByteData(reg)
}
// ReadWordData reads a 16 bit value starting from the given register of an i2c device.
func (d *GenericDriver) ReadWordData(reg uint8) (uint16, error) {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.ReadWordData(reg)
}
// ReadBlockData fills the given buffer with reads starting from the given register of an i2c device.
func (d *GenericDriver) ReadBlockData(reg uint8, data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.connection.ReadBlockData(reg, data)
}
// ReadData fills the given buffer with reads from the given register of an i2c device.
// It uses plain read to prevent ReadBlockData(), which is sometimes not supported by adaptor.
func (d *GenericDriver) ReadData(reg uint8, data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
if err := d.connection.WriteByte(reg); err != nil {
return err
}
// write process needs some time, so wait at least 5ms before read a value
// when decreasing to much, the check below will fail
time.Sleep(10 * time.Millisecond)
return d.readAndCheckCount(data)
}
// Read fills the given buffer with reads of an i2c device.
func (d *GenericDriver) Read(data []byte) error {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.readAndCheckCount(data)
}
func (d *GenericDriver) writeAndCheckCount(data []byte) error {
n, err := d.connection.Write(data)
if err != nil {
return err
}
if n != len(data) {
return fmt.Errorf("written count (%d) differ from expected (%d)", n, len(data))
}
return nil
}
func (d *GenericDriver) readAndCheckCount(data []byte) error {
n, err := d.connection.Read(data)
if err != nil {
return err
}
if n != len(data) {
return fmt.Errorf("read count (%d) differ from expected (%d)", n, len(data))
}
return nil
}