gobot.io/x/gobot@v1.16.0/platforms/digispark/digispark_i2c.go (about)

     1  package digispark
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  type digisparkI2cConnection struct {
     9  	address uint8
    10  	adaptor *Adaptor
    11  }
    12  
    13  // NewDigisparkI2cConnection creates an i2c connection to an i2c device at
    14  // the specified address
    15  func NewDigisparkI2cConnection(adaptor *Adaptor, address uint8) (connection *digisparkI2cConnection) {
    16  	return &digisparkI2cConnection{adaptor: adaptor, address: address}
    17  }
    18  
    19  // Init makes sure that the i2c device is already initialized
    20  func (c *digisparkI2cConnection) Init() (err error) {
    21  	if !c.adaptor.i2c {
    22  		if err = c.adaptor.littleWire.i2cInit(); err != nil {
    23  			return
    24  		}
    25  		c.adaptor.i2c = true
    26  	}
    27  	return
    28  }
    29  
    30  // Test tests i2c connection with the given address
    31  func (c *digisparkI2cConnection) Test(address uint8) error {
    32  	if !c.adaptor.i2c {
    33  		return errors.New("Digispark i2c not initialized")
    34  	}
    35  	return c.adaptor.littleWire.i2cStart(address, 0)
    36  }
    37  
    38  // UpdateDelay updates i2c signal delay amount; tune if neccessary to fit your requirements
    39  func (c *digisparkI2cConnection) UpdateDelay(duration uint) error {
    40  	if !c.adaptor.i2c {
    41  		return errors.New("Digispark i2c not initialized")
    42  	}
    43  	return c.adaptor.littleWire.i2cUpdateDelay(duration)
    44  }
    45  
    46  // Read tries to read a full buffer from the i2c device.
    47  // Returns an empty array if the response from the board has timed out.
    48  func (c *digisparkI2cConnection) Read(b []byte) (countRead int, err error) {
    49  	if !c.adaptor.i2c {
    50  		err = errors.New("Digispark i2c not initialized")
    51  		return
    52  	}
    53  	if err = c.adaptor.littleWire.i2cStart(c.address, 1); err != nil {
    54  		return
    55  	}
    56  	l := 8
    57  	stop := uint8(0)
    58  
    59  	for stop == 0 {
    60  		if countRead+l >= len(b) {
    61  			l = len(b) - countRead
    62  			stop = 1
    63  		}
    64  		if err = c.adaptor.littleWire.i2cRead(b[countRead:countRead+l], l, stop); err != nil {
    65  			return
    66  		}
    67  		countRead += l
    68  	}
    69  	return
    70  }
    71  
    72  // Write writes the buffer content in data to the i2c device.
    73  func (c *digisparkI2cConnection) Write(data []byte) (countWritten int, err error) {
    74  	if !c.adaptor.i2c {
    75  		err = errors.New("Digispark i2c not initialized")
    76  		return
    77  	}
    78  	if err = c.adaptor.littleWire.i2cStart(c.address, 0); err != nil {
    79  		return
    80  	}
    81  	l := 4
    82  	stop := uint8(0)
    83  
    84  	for stop == 0 {
    85  		if countWritten+l >= len(data) {
    86  			l = len(data) - countWritten
    87  			stop = 1
    88  		}
    89  		if err = c.adaptor.littleWire.i2cWrite(data[countWritten:countWritten+l], l, stop); err != nil {
    90  			return
    91  		}
    92  		countWritten += l
    93  	}
    94  	return
    95  }
    96  
    97  // Close do nothing than return nil.
    98  func (c *digisparkI2cConnection) Close() error {
    99  	return nil
   100  }
   101  
   102  // ReadByte reads one byte from the i2c device.
   103  func (c *digisparkI2cConnection) ReadByte() (val byte, err error) {
   104  	buf := []byte{0}
   105  	if err = c.readAndCheckCount(buf); err != nil {
   106  		return
   107  	}
   108  	val = buf[0]
   109  	return
   110  }
   111  
   112  // ReadByteData reads one byte of the given register address from the i2c device.
   113  func (c *digisparkI2cConnection) ReadByteData(reg uint8) (val uint8, err error) {
   114  	if err = c.WriteByte(reg); err != nil {
   115  		return
   116  	}
   117  	return c.ReadByte()
   118  }
   119  
   120  // ReadWordData reads two bytes of the given register address from the i2c device.
   121  func (c *digisparkI2cConnection) ReadWordData(reg uint8) (val uint16, err error) {
   122  	if err = c.WriteByte(reg); err != nil {
   123  		return
   124  	}
   125  
   126  	buf := []byte{0, 0}
   127  	if err = c.readAndCheckCount(buf); err != nil {
   128  		return
   129  	}
   130  	low, high := buf[0], buf[1]
   131  
   132  	val = (uint16(high) << 8) | uint16(low)
   133  	return
   134  }
   135  
   136  // WriteByte writes one byte to the i2c device.
   137  func (c *digisparkI2cConnection) WriteByte(val byte) (err error) {
   138  	buf := []byte{val}
   139  	return c.writeAndCheckCount(buf)
   140  }
   141  
   142  // WriteByteData writes one byte to the given register address of the i2c device.
   143  func (c *digisparkI2cConnection) WriteByteData(reg uint8, val byte) (err error) {
   144  	buf := []byte{reg, val}
   145  	return c.writeAndCheckCount(buf)
   146  }
   147  
   148  // WriteWordData writes two bytes to the given register address of the i2c device.
   149  func (c *digisparkI2cConnection) WriteWordData(reg uint8, val uint16) (err error) {
   150  	low := uint8(val & 0xff)
   151  	high := uint8((val >> 8) & 0xff)
   152  	buf := []byte{reg, low, high}
   153  	return c.writeAndCheckCount(buf)
   154  }
   155  
   156  // WriteBlockData writes a block of maximum 32 bytes to the given register address of the i2c device.
   157  func (c *digisparkI2cConnection) WriteBlockData(reg uint8, data []byte) (err error) {
   158  	if len(data) > 32 {
   159  		data = data[:32]
   160  	}
   161  
   162  	buf := make([]byte, len(data)+1)
   163  	copy(buf[:1], data)
   164  	buf[0] = reg
   165  	return c.writeAndCheckCount(buf)
   166  }
   167  
   168  func (c *digisparkI2cConnection) writeAndCheckCount(buf []byte) (err error) {
   169  	countWritten := 0
   170  	if countWritten, err = c.Write(buf); err != nil {
   171  		return
   172  	}
   173  	expectedCount := len(buf)
   174  	if countWritten != expectedCount {
   175  		err = fmt.Errorf("Digispark i2c write %d bytes, expected %d bytes", countWritten, expectedCount)
   176  		return
   177  	}
   178  	return
   179  }
   180  
   181  func (c *digisparkI2cConnection) readAndCheckCount(buf []byte) (err error) {
   182  	countRead := 0
   183  	if countRead, err = c.Read(buf); err != nil {
   184  		return
   185  	}
   186  	expectedCount := len(buf)
   187  	if countRead != expectedCount {
   188  		err = fmt.Errorf("Digispark i2c read %d bytes, expected %d bytes", countRead, expectedCount)
   189  		return
   190  	}
   191  	return
   192  }