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

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package i2c
     5  
     6  import (
     7  	"errors"
     8  	"testing"
     9  
    10  	"syscall"
    11  	"unsafe"
    12  
    13  	"gobot.io/x/gobot/v2"
    14  	"gobot.io/x/gobot/v2/gobottest"
    15  	"gobot.io/x/gobot/v2/system"
    16  )
    17  
    18  const dev = "/dev/i2c-1"
    19  
    20  func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
    21  	// bit 0: error on function query
    22  	// bit 1: error on set address
    23  	// bit 2: error on command
    24  	return func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
    25  		// function query
    26  		if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_FUNCS) {
    27  			if errorMask&0x01 == 0x01 {
    28  				return 0, 0, 1
    29  			}
    30  
    31  			var funcPtr *uint64 = (*uint64)(unsafe.Pointer(a3))
    32  			*funcPtr = system.I2C_FUNC_SMBUS_READ_BYTE | system.I2C_FUNC_SMBUS_READ_BYTE_DATA |
    33  				system.I2C_FUNC_SMBUS_READ_WORD_DATA |
    34  				system.I2C_FUNC_SMBUS_WRITE_BYTE | system.I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
    35  				system.I2C_FUNC_SMBUS_WRITE_WORD_DATA
    36  		}
    37  		// set address
    38  		if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_SLAVE) {
    39  			if errorMask&0x02 == 0x02 {
    40  				return 0, 0, 1
    41  			}
    42  		}
    43  		// command
    44  		if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_SMBUS) {
    45  			if errorMask&0x04 == 0x04 {
    46  				return 0, 0, 1
    47  			}
    48  		}
    49  		// Let all operations succeed
    50  		return 0, 0, 0
    51  	}
    52  }
    53  
    54  func initI2CDevice() gobot.I2cSystemDevicer {
    55  	a := system.NewAccesser()
    56  	a.UseMockFilesystem([]string{dev})
    57  	msc := a.UseMockSyscall()
    58  	msc.Impl = getSyscallFuncImpl(0x00)
    59  
    60  	d, _ := a.NewI2cDevice(dev)
    61  	return d
    62  }
    63  
    64  func initI2CDeviceAddressError() gobot.I2cSystemDevicer {
    65  	a := system.NewAccesser()
    66  	a.UseMockFilesystem([]string{dev})
    67  	msc := a.UseMockSyscall()
    68  	msc.Impl = getSyscallFuncImpl(0x02)
    69  
    70  	d, _ := a.NewI2cDevice(dev)
    71  	return d
    72  }
    73  
    74  func TestI2CAddress(t *testing.T) {
    75  	c := NewConnection(initI2CDevice(), 0x66)
    76  	gobottest.Assert(t, c.address, 0x66)
    77  }
    78  
    79  func TestI2CClose(t *testing.T) {
    80  	c := NewConnection(initI2CDevice(), 0x06)
    81  	gobottest.Assert(t, c.Close(), nil)
    82  }
    83  
    84  func TestI2CRead(t *testing.T) {
    85  	c := NewConnection(initI2CDevice(), 0x06)
    86  	i, _ := c.Read([]byte{})
    87  	gobottest.Assert(t, i, 0)
    88  }
    89  
    90  func TestI2CReadAddressError(t *testing.T) {
    91  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
    92  	_, err := c.Read([]byte{})
    93  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
    94  }
    95  
    96  func TestI2CWrite(t *testing.T) {
    97  	c := NewConnection(initI2CDevice(), 0x06)
    98  	i, _ := c.Write([]byte{0x01})
    99  	gobottest.Assert(t, i, 1)
   100  }
   101  
   102  func TestI2CWriteAddressError(t *testing.T) {
   103  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   104  	_, err := c.Write([]byte{0x01})
   105  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   106  }
   107  
   108  func TestI2CReadByte(t *testing.T) {
   109  	c := NewConnection(initI2CDevice(), 0x06)
   110  	v, _ := c.ReadByte()
   111  	gobottest.Assert(t, v, uint8(0xFC))
   112  }
   113  
   114  func TestI2CReadByteAddressError(t *testing.T) {
   115  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   116  	_, err := c.ReadByte()
   117  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   118  }
   119  
   120  func TestI2CReadByteData(t *testing.T) {
   121  	c := NewConnection(initI2CDevice(), 0x06)
   122  	v, _ := c.ReadByteData(0x01)
   123  	gobottest.Assert(t, v, uint8(0xFD))
   124  }
   125  
   126  func TestI2CReadByteDataAddressError(t *testing.T) {
   127  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   128  	_, err := c.ReadByteData(0x01)
   129  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   130  }
   131  
   132  func TestI2CReadWordData(t *testing.T) {
   133  	c := NewConnection(initI2CDevice(), 0x06)
   134  	v, _ := c.ReadWordData(0x01)
   135  	gobottest.Assert(t, v, uint16(0xFFFE))
   136  }
   137  
   138  func TestI2CReadWordDataAddressError(t *testing.T) {
   139  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   140  	_, err := c.ReadWordData(0x01)
   141  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   142  }
   143  
   144  func TestI2CWriteByte(t *testing.T) {
   145  	c := NewConnection(initI2CDevice(), 0x06)
   146  	err := c.WriteByte(0x01)
   147  	gobottest.Assert(t, err, nil)
   148  }
   149  
   150  func TestI2CWriteByteAddressError(t *testing.T) {
   151  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   152  	err := c.WriteByte(0x01)
   153  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   154  }
   155  
   156  func TestI2CWriteByteData(t *testing.T) {
   157  	c := NewConnection(initI2CDevice(), 0x06)
   158  	err := c.WriteByteData(0x01, 0x01)
   159  	gobottest.Assert(t, err, nil)
   160  }
   161  
   162  func TestI2CWriteByteDataAddressError(t *testing.T) {
   163  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   164  	err := c.WriteByteData(0x01, 0x01)
   165  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   166  }
   167  
   168  func TestI2CWriteWordData(t *testing.T) {
   169  	c := NewConnection(initI2CDevice(), 0x06)
   170  	err := c.WriteWordData(0x01, 0x01)
   171  	gobottest.Assert(t, err, nil)
   172  }
   173  
   174  func TestI2CWriteWordDataAddressError(t *testing.T) {
   175  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   176  	err := c.WriteWordData(0x01, 0x01)
   177  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   178  }
   179  
   180  func TestI2CWriteBlockData(t *testing.T) {
   181  	c := NewConnection(initI2CDevice(), 0x06)
   182  	err := c.WriteBlockData(0x01, []byte{0x01, 0x02})
   183  	gobottest.Assert(t, err, nil)
   184  }
   185  
   186  func TestI2CWriteBlockDataAddressError(t *testing.T) {
   187  	c := NewConnection(initI2CDeviceAddressError(), 0x06)
   188  	err := c.WriteBlockData(0x01, []byte{0x01, 0x02})
   189  	gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted"))
   190  }
   191  
   192  func Test_setBit(t *testing.T) {
   193  	var expectedVal uint8 = 129
   194  	actualVal := setBit(1, 7)
   195  	gobottest.Assert(t, expectedVal, actualVal)
   196  }
   197  
   198  func Test_clearBit(t *testing.T) {
   199  	var expectedVal uint8
   200  	actualVal := clearBit(128, 7)
   201  	gobottest.Assert(t, expectedVal, actualVal)
   202  }