2022-12-17 18:56:11 +08:00
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2023-05-20 20:25:21 +08:00
|
|
|
"gobot.io/x/gobot/v2"
|
2022-12-17 18:56:11 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// MockSpiAccess contains parameters of mocked SPI access
|
|
|
|
type MockSpiAccess struct {
|
|
|
|
CreateError bool
|
|
|
|
busNum int
|
|
|
|
chipNum int
|
|
|
|
mode int
|
|
|
|
bits int
|
|
|
|
maxSpeed int64
|
2023-01-06 02:04:32 +08:00
|
|
|
sysdev *spiMock
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (spi *MockSpiAccess) createDevice(
|
|
|
|
busNum, chipNum, mode, bits int,
|
|
|
|
maxSpeed int64,
|
|
|
|
) (gobot.SpiSystemDevicer, error) {
|
2022-12-17 18:56:11 +08:00
|
|
|
spi.busNum = busNum
|
|
|
|
spi.chipNum = chipNum
|
|
|
|
spi.mode = mode
|
|
|
|
spi.bits = bits
|
|
|
|
spi.maxSpeed = maxSpeed
|
2023-01-06 02:04:32 +08:00
|
|
|
spi.sysdev = newSpiMock(busNum, chipNum, mode, bits, maxSpeed)
|
2022-12-17 18:56:11 +08:00
|
|
|
var err error
|
|
|
|
if spi.CreateError {
|
|
|
|
err = fmt.Errorf("error while create SPI connection in mock")
|
|
|
|
}
|
2023-01-06 02:04:32 +08:00
|
|
|
return spi.sysdev, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (*MockSpiAccess) isSupported() bool {
|
|
|
|
return true
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetReadError can be used to simulate a read error.
|
|
|
|
func (spi *MockSpiAccess) SetReadError(val bool) {
|
2023-01-06 02:04:32 +08:00
|
|
|
spi.sysdev.simReadErr = val
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetWriteError can be used to simulate a write error.
|
|
|
|
func (spi *MockSpiAccess) SetWriteError(val bool) {
|
2023-01-06 02:04:32 +08:00
|
|
|
spi.sysdev.simWriteErr = val
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetCloseError can be used to simulate a error on Close().
|
|
|
|
func (spi *MockSpiAccess) SetCloseError(val bool) {
|
2023-01-06 02:04:32 +08:00
|
|
|
spi.sysdev.simCloseErr = val
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetSimRead is used to set the byte stream for next read.
|
2023-01-06 02:04:32 +08:00
|
|
|
func (spi *MockSpiAccess) SetSimRead(data []byte) {
|
|
|
|
spi.sysdev.simRead = make([]byte, len(data))
|
|
|
|
copy(spi.sysdev.simRead, data)
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Written returns the byte stream which was last written.
|
|
|
|
func (spi *MockSpiAccess) Written() []byte {
|
2023-01-06 02:04:32 +08:00
|
|
|
return spi.sysdev.written
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset resets the last written values.
|
|
|
|
func (spi *MockSpiAccess) Reset() {
|
|
|
|
spi.sysdev.written = []byte{}
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// spiMock is the a mock implementation, used in tests
|
|
|
|
type spiMock struct {
|
2022-12-17 18:56:11 +08:00
|
|
|
id string
|
|
|
|
simReadErr bool
|
|
|
|
simWriteErr bool
|
|
|
|
simCloseErr bool
|
|
|
|
written []byte
|
|
|
|
simRead []byte
|
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// newSpiMock creates and returns a new connection to a specific
|
2022-12-17 18:56:11 +08:00
|
|
|
// spi device on a bus/chip using the periph.io interface.
|
2023-01-06 02:04:32 +08:00
|
|
|
func newSpiMock(busNum, chipNum, mode, bits int, maxSpeed int64) *spiMock {
|
|
|
|
return &spiMock{id: fmt.Sprintf("bu:%d, c:%d, m:%d, bi:%d, s:%d", busNum, chipNum, mode, bits, maxSpeed)}
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// Close the SPI connection to the device. Implements gobot.SpiSystemDevicer.
|
|
|
|
func (c *spiMock) Close() error {
|
2022-12-17 18:56:11 +08:00
|
|
|
if c.simCloseErr {
|
|
|
|
return fmt.Errorf("error while SPI close in mock")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// TxRx uses the SPI device TX to send/receive data. gobot.SpiSystemDevicer.
|
|
|
|
func (c *spiMock) TxRx(tx []byte, rx []byte) error {
|
2022-12-17 18:56:11 +08:00
|
|
|
if c.simReadErr {
|
|
|
|
return fmt.Errorf("error while SPI read in mock")
|
|
|
|
}
|
2023-01-06 02:04:32 +08:00
|
|
|
c.written = append(c.written, tx...)
|
|
|
|
// the answer can be one cycle behind, this must be considered in test setup
|
|
|
|
copy(rx, c.simRead)
|
2022-12-17 18:56:11 +08:00
|
|
|
return nil
|
|
|
|
}
|