gobot.io/x/gobot@v1.16.0/drivers/i2c/i2c.go (about)

     1  package i2c
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"sync"
     7  )
     8  
     9  const (
    10  	// Error event
    11  	Error = "error"
    12  )
    13  
    14  const (
    15  	// BusNotInitialized is the initial value for a bus
    16  	BusNotInitialized = -1
    17  
    18  	// AddressNotInitialized is the initial value for an address
    19  	AddressNotInitialized = -1
    20  )
    21  
    22  var (
    23  	ErrEncryptedBytes  = errors.New("Encrypted bytes")
    24  	ErrNotEnoughBytes  = errors.New("Not enough bytes read")
    25  	ErrNotReady        = errors.New("Device is not ready")
    26  	ErrInvalidPosition = errors.New("Invalid position value")
    27  )
    28  
    29  type bitState uint8
    30  
    31  const (
    32  	clear bitState = 0x00
    33  	set            = 0x01
    34  )
    35  
    36  type I2cOperations interface {
    37  	io.ReadWriteCloser
    38  	ReadByte() (val byte, err error)
    39  	ReadByteData(reg uint8) (val uint8, err error)
    40  	ReadWordData(reg uint8) (val uint16, err error)
    41  	WriteByte(val byte) (err error)
    42  	WriteByteData(reg uint8, val uint8) (err error)
    43  	WriteWordData(reg uint8, val uint16) (err error)
    44  	WriteBlockData(reg uint8, b []byte) (err error)
    45  }
    46  
    47  // I2cDevice is the interface to a specific i2c bus
    48  type I2cDevice interface {
    49  	I2cOperations
    50  	SetAddress(int) error
    51  }
    52  
    53  // Connector lets Adaptors provide the interface for Drivers
    54  // to get access to the I2C buses on platforms that support I2C.
    55  type Connector interface {
    56  	// GetConnection returns a connection to device at the specified address
    57  	// and bus. Bus numbering starts at index 0, the range of valid buses is
    58  	// platform specific.
    59  	GetConnection(address int, bus int) (device Connection, err error)
    60  
    61  	// GetDefaultBus returns the default I2C bus index
    62  	GetDefaultBus() int
    63  }
    64  
    65  // Connection is a connection to an I2C device with a specified address
    66  // on a specific bus. Used as an alternative to the I2c interface.
    67  // Implements I2cOperations to talk to the device, wrapping the
    68  // calls in SetAddress to always target the specified device.
    69  // Provided by an Adaptor by implementing the I2cConnector interface.
    70  type Connection I2cOperations
    71  
    72  type i2cConnection struct {
    73  	bus     I2cDevice
    74  	address int
    75  	mutex   *sync.Mutex
    76  }
    77  
    78  // NewConnection creates and returns a new connection to a specific
    79  // i2c device on a bus and address.
    80  func NewConnection(bus I2cDevice, address int) (connection *i2cConnection) {
    81  	return &i2cConnection{bus: bus, address: address, mutex: &sync.Mutex{}}
    82  }
    83  
    84  // Read data from an i2c device.
    85  func (c *i2cConnection) Read(data []byte) (read int, err error) {
    86  	c.mutex.Lock()
    87  	defer c.mutex.Unlock()
    88  
    89  	if err = c.bus.SetAddress(c.address); err != nil {
    90  		return 0, err
    91  	}
    92  	read, err = c.bus.Read(data)
    93  	return
    94  }
    95  
    96  // Write data to an i2c device.
    97  func (c *i2cConnection) Write(data []byte) (written int, err error) {
    98  	c.mutex.Lock()
    99  	defer c.mutex.Unlock()
   100  
   101  	if err = c.bus.SetAddress(c.address); err != nil {
   102  		return 0, err
   103  	}
   104  	written, err = c.bus.Write(data)
   105  	return
   106  }
   107  
   108  // Close connection to i2c device.
   109  func (c *i2cConnection) Close() error {
   110  	c.mutex.Lock()
   111  	defer c.mutex.Unlock()
   112  
   113  	return c.bus.Close()
   114  }
   115  
   116  // ReadByte reads a single byte from the i2c device.
   117  func (c *i2cConnection) ReadByte() (val byte, err error) {
   118  	c.mutex.Lock()
   119  	defer c.mutex.Unlock()
   120  
   121  	if err := c.bus.SetAddress(c.address); err != nil {
   122  		return 0, err
   123  	}
   124  	return c.bus.ReadByte()
   125  }
   126  
   127  // ReadByteData reads a byte value for a register on the i2c device.
   128  func (c *i2cConnection) ReadByteData(reg uint8) (val uint8, err error) {
   129  	c.mutex.Lock()
   130  	defer c.mutex.Unlock()
   131  
   132  	if err := c.bus.SetAddress(c.address); err != nil {
   133  		return 0, err
   134  	}
   135  	return c.bus.ReadByteData(reg)
   136  }
   137  
   138  // ReadWordData reads a word value for a register on the i2c device.
   139  func (c *i2cConnection) ReadWordData(reg uint8) (val uint16, err error) {
   140  	c.mutex.Lock()
   141  	defer c.mutex.Unlock()
   142  
   143  	if err := c.bus.SetAddress(c.address); err != nil {
   144  		return 0, err
   145  	}
   146  	return c.bus.ReadWordData(reg)
   147  }
   148  
   149  // WriteByte writes a single byte to the i2c device.
   150  func (c *i2cConnection) WriteByte(val byte) (err error) {
   151  	c.mutex.Lock()
   152  	defer c.mutex.Unlock()
   153  
   154  	if err := c.bus.SetAddress(c.address); err != nil {
   155  		return err
   156  	}
   157  	return c.bus.WriteByte(val)
   158  }
   159  
   160  // WriteByteData writes a byte value to a register on the i2c device.
   161  func (c *i2cConnection) WriteByteData(reg uint8, val uint8) (err error) {
   162  	c.mutex.Lock()
   163  	defer c.mutex.Unlock()
   164  
   165  	if err := c.bus.SetAddress(c.address); err != nil {
   166  		return err
   167  	}
   168  	return c.bus.WriteByteData(reg, val)
   169  }
   170  
   171  // WriteWordData writes a word value to a register on the i2c device.
   172  func (c *i2cConnection) WriteWordData(reg uint8, val uint16) (err error) {
   173  	c.mutex.Lock()
   174  	defer c.mutex.Unlock()
   175  
   176  	if err := c.bus.SetAddress(c.address); err != nil {
   177  		return err
   178  	}
   179  	return c.bus.WriteWordData(reg, val)
   180  }
   181  
   182  // WriteBlockData writes a block of bytes to a register on the i2c device.
   183  func (c *i2cConnection) WriteBlockData(reg uint8, b []byte) (err error) {
   184  	c.mutex.Lock()
   185  	defer c.mutex.Unlock()
   186  
   187  	if err := c.bus.SetAddress(c.address); err != nil {
   188  		return err
   189  	}
   190  	return c.bus.WriteBlockData(reg, b)
   191  }
   192  
   193  // setBit is used to set a bit at a given position to 1.
   194  func setBit(n uint8, pos uint8) uint8 {
   195  	n |= (1 << pos)
   196  	return n
   197  }
   198  
   199  // clearBit is used to set a bit at a given position to 0.
   200  func clearBit(n uint8, pos uint8) uint8 {
   201  	mask := ^uint8(1 << pos)
   202  	n &= mask
   203  	return n
   204  }