hybridgroup.gobot/drivers/i2c/i2c.go

185 lines
4.7 KiB
Go

package i2c
import (
"errors"
"io"
"sync"
)
const (
// Error event
Error = "error"
)
const (
// BusNotInitialized is the initial value for a bus
BusNotInitialized = -1
// AddressNotInitialized is the initial value for an address
AddressNotInitialized = -1
)
var (
ErrEncryptedBytes = errors.New("Encrypted bytes")
ErrNotEnoughBytes = errors.New("Not enough bytes read")
ErrNotReady = errors.New("Device is not ready")
ErrInvalidPosition = errors.New("Invalid position value")
)
type I2cOperations interface {
io.ReadWriteCloser
ReadByte() (val byte, err error)
ReadByteData(reg uint8) (val uint8, err error)
ReadWordData(reg uint8) (val uint16, err error)
WriteByte(val byte) (err error)
WriteByteData(reg uint8, val uint8) (err error)
WriteWordData(reg uint8, val uint16) (err error)
WriteBlockData(reg uint8, b []byte) (err error)
}
// I2cDevice is the interface to a specific i2c bus
type I2cDevice interface {
I2cOperations
SetAddress(int) error
}
// Connector lets Adaptors provide the interface for Drivers
// to get access to the I2C buses on platforms that support I2C.
type Connector interface {
// GetConnection returns a connection to device at the specified address
// and bus. Bus numbering starts at index 0, the range of valid buses is
// platform specific.
GetConnection(address int, bus int) (device Connection, err error)
// GetDefaultBus returns the default I2C bus index
GetDefaultBus() int
}
// Connection is a connection to an I2C device with a specified address
// on a specific bus. Used as an alternative to the I2c interface.
// Implements I2cOperations to talk to the device, wrapping the
// calls in SetAddress to always target the specified device.
// Provided by an Adaptor by implementing the I2cConnector interface.
type Connection I2cOperations
type i2cConnection struct {
bus I2cDevice
address int
mutex *sync.Mutex
}
// NewConnection creates and returns a new connection to a specific
// i2c device on a bus and address.
func NewConnection(bus I2cDevice, address int) (connection *i2cConnection) {
return &i2cConnection{bus: bus, address: address, mutex: &sync.Mutex{}}
}
// Read data from an i2c device.
func (c *i2cConnection) Read(data []byte) (read int, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err = c.bus.SetAddress(c.address); err != nil {
return 0, err
}
read, err = c.bus.Read(data)
return
}
// Write data to an i2c device.
func (c *i2cConnection) Write(data []byte) (written int, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err = c.bus.SetAddress(c.address); err != nil {
return 0, err
}
written, err = c.bus.Write(data)
return
}
// Close connection to i2c device.
func (c *i2cConnection) Close() error {
c.mutex.Lock()
defer c.mutex.Unlock()
return c.bus.Close()
}
// ReadByte reads a single byte from the i2c device.
func (c *i2cConnection) ReadByte() (val byte, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadByte()
}
// ReadByteData reads a byte value for a register on the i2c device.
func (c *i2cConnection) ReadByteData(reg uint8) (val uint8, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadByteData(reg)
}
// ReadWordData reads a word value for a register on the i2c device.
func (c *i2cConnection) ReadWordData(reg uint8) (val uint16, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadWordData(reg)
}
// WriteByte writes a single byte to the i2c device.
func (c *i2cConnection) WriteByte(val byte) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteByte(val)
}
// WriteByteData writes a byte value to a register on the i2c device.
func (c *i2cConnection) WriteByteData(reg uint8, val uint8) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteByteData(reg, val)
}
// WriteWordData writes a word value to a register on the i2c device.
func (c *i2cConnection) WriteWordData(reg uint8, val uint16) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteWordData(reg, val)
}
// WriteBlockData writes a block of bytes to a register on the i2c device.
func (c *i2cConnection) WriteBlockData(reg uint8, b []byte) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteBlockData(reg, b)
}