gobot.io/x/gobot/v2@v2.1.0/system/spi_mock.go (about)

     1  package system
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"gobot.io/x/gobot/v2"
     7  )
     8  
     9  // MockSpiAccess contains parameters of mocked SPI access
    10  type MockSpiAccess struct {
    11  	CreateError bool
    12  	busNum      int
    13  	chipNum     int
    14  	mode        int
    15  	bits        int
    16  	maxSpeed    int64
    17  	sysdev      *spiMock
    18  }
    19  
    20  func (spi *MockSpiAccess) createDevice(busNum, chipNum, mode, bits int, maxSpeed int64) (gobot.SpiSystemDevicer, error) {
    21  	spi.busNum = busNum
    22  	spi.chipNum = chipNum
    23  	spi.mode = mode
    24  	spi.bits = bits
    25  	spi.maxSpeed = maxSpeed
    26  	spi.sysdev = newSpiMock(busNum, chipNum, mode, bits, maxSpeed)
    27  	var err error
    28  	if spi.CreateError {
    29  		err = fmt.Errorf("error while create SPI connection in mock")
    30  	}
    31  	return spi.sysdev, err
    32  }
    33  
    34  func (*MockSpiAccess) isSupported() bool {
    35  	return true
    36  }
    37  
    38  // SetReadError can be used to simulate a read error.
    39  func (spi *MockSpiAccess) SetReadError(val bool) {
    40  	spi.sysdev.simReadErr = val
    41  }
    42  
    43  // SetWriteError can be used to simulate a write error.
    44  func (spi *MockSpiAccess) SetWriteError(val bool) {
    45  	spi.sysdev.simWriteErr = val
    46  }
    47  
    48  // SetCloseError can be used to simulate a error on Close().
    49  func (spi *MockSpiAccess) SetCloseError(val bool) {
    50  	spi.sysdev.simCloseErr = val
    51  }
    52  
    53  // SetSimRead is used to set the byte stream for next read.
    54  func (spi *MockSpiAccess) SetSimRead(data []byte) {
    55  	spi.sysdev.simRead = make([]byte, len(data))
    56  	copy(spi.sysdev.simRead, data)
    57  }
    58  
    59  // Written returns the byte stream which was last written.
    60  func (spi *MockSpiAccess) Written() []byte {
    61  	return spi.sysdev.written
    62  }
    63  
    64  // Reset resets the last written values.
    65  func (spi *MockSpiAccess) Reset() {
    66  	spi.sysdev.written = []byte{}
    67  }
    68  
    69  // spiMock is the a mock implementation, used in tests
    70  type spiMock struct {
    71  	id          string
    72  	simReadErr  bool
    73  	simWriteErr bool
    74  	simCloseErr bool
    75  	written     []byte
    76  	simRead     []byte
    77  }
    78  
    79  // newSpiMock creates and returns a new connection to a specific
    80  // spi device on a bus/chip using the periph.io interface.
    81  func newSpiMock(busNum, chipNum, mode, bits int, maxSpeed int64) *spiMock {
    82  	return &spiMock{id: fmt.Sprintf("bu:%d, c:%d, m:%d, bi:%d, s:%d", busNum, chipNum, mode, bits, maxSpeed)}
    83  }
    84  
    85  // Close the SPI connection to the device. Implements gobot.SpiSystemDevicer.
    86  func (c *spiMock) Close() error {
    87  	if c.simCloseErr {
    88  		return fmt.Errorf("error while SPI close in mock")
    89  	}
    90  	return nil
    91  }
    92  
    93  // TxRx uses the SPI device TX to send/receive data. gobot.SpiSystemDevicer.
    94  func (c *spiMock) TxRx(tx []byte, rx []byte) error {
    95  	if c.simReadErr {
    96  		return fmt.Errorf("error while SPI read in mock")
    97  	}
    98  	c.written = append(c.written, tx...)
    99  	// the answer can be one cycle behind, this must be considered in test setup
   100  	copy(rx, c.simRead)
   101  	return nil
   102  }