gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/generic_driver.go (about)

     1  package i2c
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  )
     7  
     8  // GenericDriver implements the interface gobot.Driver.
     9  type GenericDriver struct {
    10  	*Driver
    11  }
    12  
    13  // NewGenericDriver creates a new generic i2c gobot driver, which just forwards all connection functions.
    14  func NewGenericDriver(c Connector, name string, address int, options ...func(Config)) *GenericDriver {
    15  	return &GenericDriver{Driver: NewDriver(c, name, address, options...)}
    16  }
    17  
    18  // WriteByte writes one byte to the i2c device.
    19  func (d *GenericDriver) WriteByte(val byte) error {
    20  	d.mutex.Lock()
    21  	defer d.mutex.Unlock()
    22  
    23  	return d.connection.WriteByte(val)
    24  }
    25  
    26  // WriteByteData writes the given byte value to the given register of an i2c device.
    27  func (d *GenericDriver) WriteByteData(reg uint8, val byte) error {
    28  	d.mutex.Lock()
    29  	defer d.mutex.Unlock()
    30  
    31  	return d.connection.WriteByteData(reg, val)
    32  }
    33  
    34  // WriteWordData writes the given 16 bit value to the given register of an i2c device.
    35  func (d *GenericDriver) WriteWordData(reg uint8, val uint16) error {
    36  	d.mutex.Lock()
    37  	defer d.mutex.Unlock()
    38  
    39  	return d.connection.WriteWordData(reg, val)
    40  }
    41  
    42  // WriteBlockData writes the given buffer to the given register of an i2c device.
    43  func (d *GenericDriver) WriteBlockData(reg uint8, data []byte) error {
    44  	d.mutex.Lock()
    45  	defer d.mutex.Unlock()
    46  
    47  	return d.connection.WriteBlockData(reg, data)
    48  }
    49  
    50  // WriteData writes the given buffer to the given register of an i2c device.
    51  // It uses plain write to prevent WriteBlockData(), which is sometimes not supported by adaptor.
    52  func (d *GenericDriver) WriteData(reg uint8, data []byte) error {
    53  	d.mutex.Lock()
    54  	defer d.mutex.Unlock()
    55  
    56  	buf := make([]byte, len(data)+1)
    57  	copy(buf[1:], data)
    58  	buf[0] = reg
    59  
    60  	return d.writeAndCheckCount(buf)
    61  }
    62  
    63  // Write writes the given buffer to the i2c device.
    64  func (d *GenericDriver) Write(data []byte) error {
    65  	d.mutex.Lock()
    66  	defer d.mutex.Unlock()
    67  
    68  	return d.writeAndCheckCount(data)
    69  }
    70  
    71  // ReadByte reads a byte from the current register of an i2c device.
    72  func (d *GenericDriver) ReadByte() (byte, error) {
    73  	d.mutex.Lock()
    74  	defer d.mutex.Unlock()
    75  
    76  	return d.connection.ReadByte()
    77  }
    78  
    79  // ReadByteData reads a byte from the given register of an i2c device.
    80  func (d *GenericDriver) ReadByteData(reg uint8) (byte, error) {
    81  	d.mutex.Lock()
    82  	defer d.mutex.Unlock()
    83  
    84  	return d.connection.ReadByteData(reg)
    85  }
    86  
    87  // ReadWordData reads a 16 bit value starting from the given register of an i2c device.
    88  func (d *GenericDriver) ReadWordData(reg uint8) (uint16, error) {
    89  	d.mutex.Lock()
    90  	defer d.mutex.Unlock()
    91  
    92  	return d.connection.ReadWordData(reg)
    93  }
    94  
    95  // ReadBlockData fills the given buffer with reads starting from the given register of an i2c device.
    96  func (d *GenericDriver) ReadBlockData(reg uint8, data []byte) error {
    97  	d.mutex.Lock()
    98  	defer d.mutex.Unlock()
    99  
   100  	return d.connection.ReadBlockData(reg, data)
   101  }
   102  
   103  // ReadData fills the given buffer with reads from the given register of an i2c device.
   104  // It uses plain read to prevent ReadBlockData(), which is sometimes not supported by adaptor.
   105  func (d *GenericDriver) ReadData(reg uint8, data []byte) error {
   106  	d.mutex.Lock()
   107  	defer d.mutex.Unlock()
   108  
   109  	if err := d.connection.WriteByte(reg); err != nil {
   110  		return err
   111  	}
   112  
   113  	// write process needs some time, so wait at least 5ms before read a value
   114  	// when decreasing to much, the check below will fail
   115  	time.Sleep(10 * time.Millisecond)
   116  
   117  	return d.readAndCheckCount(data)
   118  }
   119  
   120  // Read fills the given buffer with reads of an i2c device.
   121  func (d *GenericDriver) Read(data []byte) error {
   122  	d.mutex.Lock()
   123  	defer d.mutex.Unlock()
   124  
   125  	return d.readAndCheckCount(data)
   126  }
   127  
   128  func (d *GenericDriver) writeAndCheckCount(data []byte) error {
   129  	n, err := d.connection.Write(data)
   130  	if err != nil {
   131  		return err
   132  	}
   133  	if n != len(data) {
   134  		return fmt.Errorf("written count (%d) differ from expected (%d)", n, len(data))
   135  	}
   136  	return nil
   137  }
   138  
   139  func (d *GenericDriver) readAndCheckCount(data []byte) error {
   140  	n, err := d.connection.Read(data)
   141  	if err != nil {
   142  		return err
   143  	}
   144  	if n != len(data) {
   145  		return fmt.Errorf("read count (%d) differ from expected (%d)", n, len(data))
   146  	}
   147  	return nil
   148  }