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 }