2022-12-17 18:56:11 +08:00
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"periph.io/x/conn/v3/physic"
|
|
|
|
xspi "periph.io/x/conn/v3/spi"
|
|
|
|
xsysfs "periph.io/x/host/v3/sysfs"
|
|
|
|
)
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// spiPeriphIo is the implementation of the SPI interface using the periph.io sysfs implementation for Linux.
|
|
|
|
type spiPeriphIo struct {
|
2022-12-17 18:56:11 +08:00
|
|
|
port xspi.PortCloser
|
|
|
|
dev xspi.Conn
|
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// newSpiPeriphIo creates and returns a new connection to a specific SPI device on a bus/chip
|
2022-12-17 18:56:11 +08:00
|
|
|
// using the periph.io interface.
|
2023-01-06 02:04:32 +08:00
|
|
|
func newSpiPeriphIo(busNum, chipNum, mode, bits int, maxSpeed int64) (*spiPeriphIo, error) {
|
2022-12-17 18:56:11 +08:00
|
|
|
p, err := xsysfs.NewSPI(busNum, chipNum)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c, err := p.Connect(physic.Frequency(maxSpeed)*physic.Hertz, xspi.Mode(mode), bits)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-01-06 02:04:32 +08:00
|
|
|
return &spiPeriphIo{port: p, dev: c}, nil
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// TxRx uses the SPI device TX to send/receive data. Implements gobot.SpiSystemDevicer.
|
|
|
|
func (c *spiPeriphIo) TxRx(tx []byte, rx []byte) error {
|
|
|
|
dataLen := len(rx)
|
|
|
|
if err := c.dev.Tx(tx, rx); err != nil {
|
2022-12-17 18:56:11 +08:00
|
|
|
return err
|
|
|
|
}
|
2023-01-06 02:04:32 +08:00
|
|
|
if len(rx) != dataLen {
|
|
|
|
return fmt.Errorf("Read length (%d) differ to expected (%d)", len(rx), dataLen)
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-06 02:04:32 +08:00
|
|
|
// Close the SPI connection. Implements gobot.SpiSystemDevicer.
|
|
|
|
func (c *spiPeriphIo) Close() error {
|
|
|
|
return c.port.Close()
|
2022-12-17 18:56:11 +08:00
|
|
|
}
|