2022-12-17 18:56:11 +08:00
|
|
|
package spi
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
2023-05-20 20:25:21 +08:00
|
|
|
"gobot.io/x/gobot/v2"
|
2022-12-17 18:56:11 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// NotInitialized is the initial value for a bus/chip
|
|
|
|
NotInitialized = -1
|
|
|
|
)
|
|
|
|
|
|
|
|
// Connector lets Adaptors provide the interface for Drivers
|
|
|
|
// to get access to the SPI buses on platforms that support SPI.
|
|
|
|
type Connector interface {
|
|
|
|
// GetSpiConnection returns a connection to a SPI device at the specified bus and chip.
|
|
|
|
// Bus numbering starts at index 0, the range of valid buses is
|
|
|
|
// platform specific. Same with chip numbering.
|
|
|
|
GetSpiConnection(busNum, chip, mode, bits int, maxSpeed int64) (device Connection, err error)
|
|
|
|
|
|
|
|
// SpiDefaultBusNumber returns the default SPI bus index
|
|
|
|
SpiDefaultBusNumber() int
|
|
|
|
|
|
|
|
// SpiDefaultChipNumber returns the default SPI chip index
|
|
|
|
SpiDefaultChipNumber() int
|
|
|
|
|
|
|
|
// DefaultMode returns the default SPI mode (0/1/2/3)
|
|
|
|
SpiDefaultMode() int
|
|
|
|
|
|
|
|
// SpiDefaultBitCount returns the default SPI number of bits (8)
|
|
|
|
SpiDefaultBitCount() int
|
|
|
|
|
|
|
|
// SpiDefaultMaxSpeed returns the max SPI speed
|
|
|
|
SpiDefaultMaxSpeed() int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connection is a connection to a SPI device with a specific bus/chip.
|
|
|
|
// Provided by an Adaptor, usually just by calling the spi package's GetSpiConnection() function.
|
|
|
|
type Connection gobot.SpiOperations
|
|
|
|
|
|
|
|
// Config is the interface which describes how a Driver can specify
|
|
|
|
// optional SPI params such as which SPI bus it wants to use.
|
|
|
|
type Config interface {
|
|
|
|
// SetBusNumber sets which bus to use
|
|
|
|
SetBusNumber(int)
|
|
|
|
|
|
|
|
// GetBusNumberOrDefault gets which bus to use
|
|
|
|
GetBusNumberOrDefault(def int) int
|
|
|
|
|
|
|
|
// SetChipNumber sets which chip to use
|
|
|
|
SetChipNumber(int)
|
|
|
|
|
|
|
|
// GetChipNumberOrDefault gets which chip to use
|
|
|
|
GetChipNumberOrDefault(def int) int
|
|
|
|
|
|
|
|
// SetMode sets which mode to use
|
|
|
|
SetMode(int)
|
|
|
|
|
|
|
|
// GetModeOrDefault gets which mode to use
|
|
|
|
GetModeOrDefault(def int) int
|
|
|
|
|
|
|
|
// SetUsedBits sets how many bits to use
|
|
|
|
SetBitCount(int)
|
|
|
|
|
|
|
|
// GetBitCountOrDefault gets how many bits to use
|
|
|
|
GetBitCountOrDefault(def int) int
|
|
|
|
|
|
|
|
// SetSpeed sets which speed to use (in Hz)
|
|
|
|
SetSpeed(int64)
|
|
|
|
|
|
|
|
// GetSpeedOrDefault gets which speed to use (in Hz)
|
|
|
|
GetSpeedOrDefault(def int64) int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// Driver implements the interface gobot.Driver for SPI devices.
|
|
|
|
type Driver struct {
|
|
|
|
name string
|
|
|
|
connector Connector
|
|
|
|
connection Connection
|
|
|
|
afterStart func() error
|
|
|
|
beforeHalt func() error
|
|
|
|
Config
|
|
|
|
gobot.Commander
|
|
|
|
mutex sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewDriver creates a new generic and basic SPI gobot driver.
|
|
|
|
func NewDriver(a Connector, name string, options ...func(Config)) *Driver {
|
|
|
|
d := &Driver{
|
|
|
|
name: gobot.DefaultName(name),
|
|
|
|
connector: a,
|
|
|
|
afterStart: func() error { return nil },
|
|
|
|
beforeHalt: func() error { return nil },
|
|
|
|
Config: NewConfig(),
|
|
|
|
Commander: gobot.NewCommander(),
|
|
|
|
}
|
|
|
|
for _, option := range options {
|
|
|
|
option(d)
|
|
|
|
}
|
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
|
|
|
// Name returns the name of the device.
|
|
|
|
func (d *Driver) Name() string { return d.name }
|
|
|
|
|
|
|
|
// SetName sets the name of the device.
|
|
|
|
func (d *Driver) SetName(n string) { d.name = n }
|
|
|
|
|
|
|
|
// Connection returns the Connection of the device.
|
|
|
|
func (d *Driver) Connection() gobot.Connection { return d.connector.(gobot.Connection) }
|
|
|
|
|
|
|
|
// Start initializes the driver.
|
|
|
|
func (d *Driver) Start() error {
|
|
|
|
d.mutex.Lock()
|
|
|
|
defer d.mutex.Unlock()
|
|
|
|
|
|
|
|
bus := d.GetBusNumberOrDefault(d.connector.SpiDefaultBusNumber())
|
|
|
|
chip := d.GetChipNumberOrDefault(d.connector.SpiDefaultChipNumber())
|
|
|
|
mode := d.GetModeOrDefault(d.connector.SpiDefaultMode())
|
|
|
|
bits := d.GetBitCountOrDefault(d.connector.SpiDefaultBitCount())
|
|
|
|
maxSpeed := d.GetSpeedOrDefault(d.connector.SpiDefaultMaxSpeed())
|
|
|
|
|
|
|
|
var err error
|
|
|
|
d.connection, err = d.connector.GetSpiConnection(bus, chip, mode, bits, maxSpeed)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return d.afterStart()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Halt stops the driver.
|
|
|
|
func (d *Driver) Halt() (err error) {
|
|
|
|
d.mutex.Lock()
|
|
|
|
defer d.mutex.Unlock()
|
|
|
|
|
|
|
|
if err := d.beforeHalt(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// currently there is nothing to do here for the driver, the connection is cached on adaptor side
|
|
|
|
// and will be closed on adaptor Finalize()
|
|
|
|
return nil
|
|
|
|
}
|