gobot.io/x/gobot/v2@v2.1.0/drivers/spi/spi_driver.go (about)

     1  package spi
     2  
     3  import (
     4  	"sync"
     5  
     6  	"gobot.io/x/gobot/v2"
     7  )
     8  
     9  const (
    10  	// NotInitialized is the initial value for a bus/chip
    11  	NotInitialized = -1
    12  )
    13  
    14  // Connector lets Adaptors provide the interface for Drivers
    15  // to get access to the SPI buses on platforms that support SPI.
    16  type Connector interface {
    17  	// GetSpiConnection returns a connection to a SPI device at the specified bus and chip.
    18  	// Bus numbering starts at index 0, the range of valid buses is
    19  	// platform specific. Same with chip numbering.
    20  	GetSpiConnection(busNum, chip, mode, bits int, maxSpeed int64) (device Connection, err error)
    21  
    22  	// SpiDefaultBusNumber returns the default SPI bus index
    23  	SpiDefaultBusNumber() int
    24  
    25  	// SpiDefaultChipNumber returns the default SPI chip index
    26  	SpiDefaultChipNumber() int
    27  
    28  	// DefaultMode returns the default SPI mode (0/1/2/3)
    29  	SpiDefaultMode() int
    30  
    31  	// SpiDefaultBitCount returns the default SPI number of bits (8)
    32  	SpiDefaultBitCount() int
    33  
    34  	// SpiDefaultMaxSpeed returns the max SPI speed
    35  	SpiDefaultMaxSpeed() int64
    36  }
    37  
    38  // Connection is a connection to a SPI device with a specific bus/chip.
    39  // Provided by an Adaptor, usually just by calling the spi package's GetSpiConnection() function.
    40  type Connection gobot.SpiOperations
    41  
    42  // Config is the interface which describes how a Driver can specify
    43  // optional SPI params such as which SPI bus it wants to use.
    44  type Config interface {
    45  	// SetBusNumber sets which bus to use
    46  	SetBusNumber(int)
    47  
    48  	// GetBusNumberOrDefault gets which bus to use
    49  	GetBusNumberOrDefault(def int) int
    50  
    51  	// SetChipNumber sets which chip to use
    52  	SetChipNumber(int)
    53  
    54  	// GetChipNumberOrDefault gets which chip to use
    55  	GetChipNumberOrDefault(def int) int
    56  
    57  	// SetMode sets which mode to use
    58  	SetMode(int)
    59  
    60  	// GetModeOrDefault gets which mode to use
    61  	GetModeOrDefault(def int) int
    62  
    63  	// SetUsedBits sets how many bits to use
    64  	SetBitCount(int)
    65  
    66  	// GetBitCountOrDefault gets how many bits to use
    67  	GetBitCountOrDefault(def int) int
    68  
    69  	// SetSpeed sets which speed to use (in Hz)
    70  	SetSpeed(int64)
    71  
    72  	// GetSpeedOrDefault gets which speed to use (in Hz)
    73  	GetSpeedOrDefault(def int64) int64
    74  }
    75  
    76  // Driver implements the interface gobot.Driver for SPI devices.
    77  type Driver struct {
    78  	name       string
    79  	connector  Connector
    80  	connection Connection
    81  	afterStart func() error
    82  	beforeHalt func() error
    83  	Config
    84  	gobot.Commander
    85  	mutex sync.Mutex
    86  }
    87  
    88  // NewDriver creates a new generic and basic SPI gobot driver.
    89  func NewDriver(a Connector, name string, options ...func(Config)) *Driver {
    90  	d := &Driver{
    91  		name:       gobot.DefaultName(name),
    92  		connector:  a,
    93  		afterStart: func() error { return nil },
    94  		beforeHalt: func() error { return nil },
    95  		Config:     NewConfig(),
    96  		Commander:  gobot.NewCommander(),
    97  	}
    98  	for _, option := range options {
    99  		option(d)
   100  	}
   101  	return d
   102  }
   103  
   104  // Name returns the name of the device.
   105  func (d *Driver) Name() string { return d.name }
   106  
   107  // SetName sets the name of the device.
   108  func (d *Driver) SetName(n string) { d.name = n }
   109  
   110  // Connection returns the Connection of the device.
   111  func (d *Driver) Connection() gobot.Connection { return d.connector.(gobot.Connection) }
   112  
   113  // Start initializes the driver.
   114  func (d *Driver) Start() error {
   115  	d.mutex.Lock()
   116  	defer d.mutex.Unlock()
   117  
   118  	bus := d.GetBusNumberOrDefault(d.connector.SpiDefaultBusNumber())
   119  	chip := d.GetChipNumberOrDefault(d.connector.SpiDefaultChipNumber())
   120  	mode := d.GetModeOrDefault(d.connector.SpiDefaultMode())
   121  	bits := d.GetBitCountOrDefault(d.connector.SpiDefaultBitCount())
   122  	maxSpeed := d.GetSpeedOrDefault(d.connector.SpiDefaultMaxSpeed())
   123  
   124  	var err error
   125  	d.connection, err = d.connector.GetSpiConnection(bus, chip, mode, bits, maxSpeed)
   126  	if err != nil {
   127  		return err
   128  	}
   129  	return d.afterStart()
   130  }
   131  
   132  // Halt stops the driver.
   133  func (d *Driver) Halt() (err error) {
   134  	d.mutex.Lock()
   135  	defer d.mutex.Unlock()
   136  
   137  	if err := d.beforeHalt(); err != nil {
   138  		return err
   139  	}
   140  
   141  	// currently there is nothing to do here for the driver, the connection is cached on adaptor side
   142  	// and will be closed on adaptor Finalize()
   143  	return nil
   144  }