gobot.io/x/gobot/v2@v2.1.0/platforms/firmata/firmata_i2c_test.go (about)

     1  package firmata
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"testing"
     7  	"time"
     8  
     9  	"gobot.io/x/gobot/v2"
    10  	"gobot.io/x/gobot/v2/drivers/i2c"
    11  	"gobot.io/x/gobot/v2/gobottest"
    12  	"gobot.io/x/gobot/v2/platforms/firmata/client"
    13  )
    14  
    15  // make sure that this Adaptor fulfills all required I2C interfaces
    16  var _ i2c.Connector = (*Adaptor)(nil)
    17  
    18  type i2cMockFirmataBoard struct {
    19  	gobot.Eventer
    20  	i2cDataForRead []byte
    21  	numBytesToRead int
    22  	i2cWritten     []byte
    23  	i2cWriteImpl   func([]byte) (int, error)
    24  }
    25  
    26  // setup mock for i2c tests
    27  func (t *i2cMockFirmataBoard) I2cRead(address int, numBytes int) error {
    28  	t.numBytesToRead = numBytes
    29  	i2cReply := client.I2cReply{Data: t.i2cDataForRead}
    30  	go func() {
    31  		<-time.After(10 * time.Millisecond)
    32  		t.Publish(t.Event("I2cReply"), i2cReply)
    33  	}()
    34  	return nil
    35  }
    36  func (t *i2cMockFirmataBoard) I2cWrite(address int, data []byte) error {
    37  	t.i2cWritten = append(t.i2cWritten, data...)
    38  	return nil
    39  }
    40  func (i2cMockFirmataBoard) I2cConfig(int) error { return nil }
    41  
    42  // GPIO, PWM and servo functions unused in this test scenarios
    43  func (i2cMockFirmataBoard) Connect(io.ReadWriteCloser) error { return nil }
    44  func (i2cMockFirmataBoard) Disconnect() error                { return nil }
    45  func (i2cMockFirmataBoard) Pins() []client.Pin               { return nil }
    46  func (i2cMockFirmataBoard) AnalogWrite(int, int) error       { return nil }
    47  func (i2cMockFirmataBoard) SetPinMode(int, int) error        { return nil }
    48  func (i2cMockFirmataBoard) ReportAnalog(int, int) error      { return nil }
    49  func (i2cMockFirmataBoard) ReportDigital(int, int) error     { return nil }
    50  func (i2cMockFirmataBoard) DigitalWrite(int, int) error      { return nil }
    51  func (i2cMockFirmataBoard) ServoConfig(int, int, int) error  { return nil }
    52  
    53  // WriteSysex of the client implementation not tested here
    54  func (i2cMockFirmataBoard) WriteSysex([]byte) error { return nil }
    55  
    56  func newI2cMockFirmataBoard() *i2cMockFirmataBoard {
    57  	m := &i2cMockFirmataBoard{
    58  		Eventer: gobot.NewEventer(),
    59  	}
    60  	m.AddEvent("I2cReply")
    61  	return m
    62  }
    63  
    64  func initTestTestAdaptorWithI2cConnection() (i2c.Connection, *i2cMockFirmataBoard) {
    65  	a := NewAdaptor()
    66  	a.Board = newI2cMockFirmataBoard()
    67  	con, err := a.GetI2cConnection(0, 0)
    68  	if err != nil {
    69  		panic(err)
    70  	}
    71  	return con, a.Board.(*i2cMockFirmataBoard)
    72  }
    73  
    74  func TestClose(t *testing.T) {
    75  	i2c, _ := initTestTestAdaptorWithI2cConnection()
    76  	gobottest.Assert(t, i2c.Close(), nil)
    77  }
    78  
    79  func TestRead(t *testing.T) {
    80  	// arrange
    81  	con, brd := initTestTestAdaptorWithI2cConnection()
    82  	brd.i2cDataForRead = []byte{111}
    83  	buf := []byte{0}
    84  	// act
    85  	countRead, err := con.Read(buf)
    86  	gobottest.Assert(t, err, nil)
    87  	gobottest.Assert(t, countRead, 1)
    88  	gobottest.Assert(t, brd.numBytesToRead, 1)
    89  	gobottest.Assert(t, buf, brd.i2cDataForRead)
    90  	gobottest.Assert(t, len(brd.i2cWritten), 0)
    91  }
    92  
    93  func TestReadByte(t *testing.T) {
    94  	// arrange
    95  	con, brd := initTestTestAdaptorWithI2cConnection()
    96  	brd.i2cDataForRead = []byte{222}
    97  	// act
    98  	val, err := con.ReadByte()
    99  	// assert
   100  	gobottest.Assert(t, err, nil)
   101  	gobottest.Assert(t, brd.numBytesToRead, 1)
   102  	gobottest.Assert(t, val, brd.i2cDataForRead[0])
   103  	gobottest.Assert(t, len(brd.i2cWritten), 0)
   104  }
   105  
   106  func TestReadByteData(t *testing.T) {
   107  	// arrange
   108  	con, brd := initTestTestAdaptorWithI2cConnection()
   109  	brd.i2cDataForRead = []byte{100}
   110  	reg := uint8(0x01)
   111  	// act
   112  	val, err := con.ReadByteData(reg)
   113  	// assert
   114  	gobottest.Assert(t, err, nil)
   115  	gobottest.Assert(t, brd.numBytesToRead, 1)
   116  	gobottest.Assert(t, val, brd.i2cDataForRead[0])
   117  	gobottest.Assert(t, len(brd.i2cWritten), 1)
   118  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   119  }
   120  
   121  func TestReadWordData(t *testing.T) {
   122  	// arrange
   123  	con, brd := initTestTestAdaptorWithI2cConnection()
   124  	lsb := uint8(0x11)
   125  	msb := uint8(0xff)
   126  	brd.i2cDataForRead = []byte{lsb, msb}
   127  	reg := uint8(0x22)
   128  	// act
   129  	val, err := con.ReadWordData(reg)
   130  	// assert
   131  	gobottest.Assert(t, err, nil)
   132  	gobottest.Assert(t, brd.numBytesToRead, 2)
   133  	gobottest.Assert(t, val, uint16(lsb)|uint16(msb)<<8)
   134  	gobottest.Assert(t, len(brd.i2cWritten), 1)
   135  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   136  }
   137  
   138  func TestReadBlockData(t *testing.T) {
   139  	// arrange
   140  	con, brd := initTestTestAdaptorWithI2cConnection()
   141  	brd.i2cDataForRead = []byte{50, 40, 30, 20, 10}
   142  	reg := uint8(0x33)
   143  	buf := []byte{1, 2, 3, 4, 5}
   144  	// act
   145  	err := con.ReadBlockData(reg, buf)
   146  	// assert
   147  	gobottest.Assert(t, err, nil)
   148  	gobottest.Assert(t, brd.numBytesToRead, 5)
   149  	gobottest.Assert(t, buf, brd.i2cDataForRead)
   150  	gobottest.Assert(t, len(brd.i2cWritten), 1)
   151  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   152  }
   153  
   154  func TestWrite(t *testing.T) {
   155  	// arrange
   156  	con, brd := initTestTestAdaptorWithI2cConnection()
   157  	want := []byte{0x00, 0x01}
   158  	wantLen := len(want)
   159  	// act
   160  	written, err := con.Write(want)
   161  	// assert
   162  	gobottest.Assert(t, err, nil)
   163  	gobottest.Assert(t, written, wantLen)
   164  	gobottest.Assert(t, brd.i2cWritten, want)
   165  }
   166  
   167  func TestWrite20bytes(t *testing.T) {
   168  	// arrange
   169  	con, brd := initTestTestAdaptorWithI2cConnection()
   170  	want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
   171  	wantLen := len(want)
   172  	// act
   173  	written, err := con.Write(want)
   174  	// assert
   175  	gobottest.Assert(t, err, nil)
   176  	gobottest.Assert(t, written, wantLen)
   177  	gobottest.Assert(t, brd.i2cWritten, want)
   178  }
   179  
   180  func TestWriteByte(t *testing.T) {
   181  	// arrange
   182  	con, brd := initTestTestAdaptorWithI2cConnection()
   183  	want := uint8(0x11)
   184  	// act
   185  	err := con.WriteByte(want)
   186  	// assert
   187  	gobottest.Assert(t, err, nil)
   188  	gobottest.Assert(t, len(brd.i2cWritten), 1)
   189  	gobottest.Assert(t, brd.i2cWritten[0], want)
   190  }
   191  
   192  func TestWriteByteData(t *testing.T) {
   193  	// arrange
   194  	con, brd := initTestTestAdaptorWithI2cConnection()
   195  	reg := uint8(0x12)
   196  	val := uint8(0x22)
   197  	// act
   198  	err := con.WriteByteData(reg, val)
   199  	// assert
   200  	gobottest.Assert(t, err, nil)
   201  	gobottest.Assert(t, len(brd.i2cWritten), 2)
   202  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   203  	gobottest.Assert(t, brd.i2cWritten[1], val)
   204  }
   205  
   206  func TestWriteWordData(t *testing.T) {
   207  	// arrange
   208  	con, brd := initTestTestAdaptorWithI2cConnection()
   209  	reg := uint8(0x13)
   210  	val := uint16(0x8002)
   211  	// act
   212  	err := con.WriteWordData(reg, val)
   213  	// assert
   214  	gobottest.Assert(t, err, nil)
   215  	gobottest.Assert(t, len(brd.i2cWritten), 3)
   216  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   217  	gobottest.Assert(t, brd.i2cWritten[1], uint8(val&0x00FF))
   218  	gobottest.Assert(t, brd.i2cWritten[2], uint8(val>>8))
   219  }
   220  
   221  func TestWriteBlockData(t *testing.T) {
   222  	// arrange
   223  	con, brd := initTestTestAdaptorWithI2cConnection()
   224  	reg := uint8(0x14)
   225  	val := []byte{}
   226  	// we prepare more than 32 bytes, because the call has to drop it
   227  	for i := uint8(0); i < 40; i++ {
   228  		val = append(val, i)
   229  	}
   230  	// act
   231  	err := con.WriteBlockData(reg, val)
   232  	// assert
   233  	gobottest.Assert(t, err, nil)
   234  	gobottest.Assert(t, len(brd.i2cWritten), 33)
   235  	gobottest.Assert(t, brd.i2cWritten[0], reg)
   236  	gobottest.Assert(t, brd.i2cWritten[1:], val[0:32])
   237  }
   238  
   239  func TestDefaultBus(t *testing.T) {
   240  	a := NewAdaptor()
   241  	gobottest.Assert(t, a.DefaultI2cBus(), 0)
   242  }
   243  
   244  func TestGetI2cConnectionInvalidBus(t *testing.T) {
   245  	a := NewAdaptor()
   246  	_, err := a.GetI2cConnection(0x01, 99)
   247  	gobottest.Assert(t, err, errors.New("Invalid bus number 99, only 0 is supported"))
   248  }