gobot.io/x/gobot/v2@v2.1.0/platforms/adaptors/spibusadaptor.go (about) 1 package adaptors 2 3 import ( 4 "fmt" 5 "sync" 6 7 multierror "github.com/hashicorp/go-multierror" 8 "gobot.io/x/gobot/v2/drivers/spi" 9 "gobot.io/x/gobot/v2/system" 10 ) 11 12 type spiBusNumberValidator func(busNumber int) error 13 14 // SpiBusAdaptor is a adaptor for SPI bus, normally used for composition in platforms. 15 type SpiBusAdaptor struct { 16 sys *system.Accesser 17 validateBusNumber spiBusNumberValidator 18 defaultBusNumber int 19 defaultChipNumber int 20 defaultMode int 21 defaultBitCount int 22 defaultMaxSpeed int64 23 mutex sync.Mutex 24 connections map[string]spi.Connection 25 } 26 27 // NewSpiBusAdaptor provides the access to SPI buses of the board. The validator is used to check the 28 // bus number (given by user) to the abilities of the board. 29 func NewSpiBusAdaptor(sys *system.Accesser, v spiBusNumberValidator, busNum, chipNum, mode, bits int, 30 maxSpeed int64) *SpiBusAdaptor { 31 a := &SpiBusAdaptor{ 32 sys: sys, 33 validateBusNumber: v, 34 defaultBusNumber: busNum, 35 defaultChipNumber: chipNum, 36 defaultMode: mode, 37 defaultBitCount: bits, 38 defaultMaxSpeed: maxSpeed, 39 } 40 return a 41 } 42 43 // Connect prepares the connection to SPI buses. 44 func (a *SpiBusAdaptor) Connect() error { 45 a.mutex.Lock() 46 defer a.mutex.Unlock() 47 48 a.connections = make(map[string]spi.Connection) 49 return nil 50 } 51 52 // Finalize closes all SPI connections. 53 func (a *SpiBusAdaptor) Finalize() error { 54 a.mutex.Lock() 55 defer a.mutex.Unlock() 56 57 var err error 58 for _, con := range a.connections { 59 if con != nil { 60 if e := con.Close(); e != nil { 61 err = multierror.Append(err, e) 62 } 63 } 64 } 65 a.connections = nil 66 return err 67 } 68 69 // GetSpiConnection returns an spi connection to a device on a specified bus. 70 // Valid bus numbers range between 0 and 65536, valid chip numbers are 0 ... 255. 71 func (a *SpiBusAdaptor) GetSpiConnection(busNum, chipNum, mode, bits int, maxSpeed int64) (spi.Connection, error) { 72 a.mutex.Lock() 73 defer a.mutex.Unlock() 74 75 if a.connections == nil { 76 return nil, fmt.Errorf("not connected") 77 } 78 79 id := fmt.Sprintf("%d_%d", busNum, chipNum) 80 81 con := a.connections[id] 82 if con == nil { 83 if err := a.validateBusNumber(busNum); err != nil { 84 return nil, err 85 } 86 var err error 87 bus, err := a.sys.NewSpiDevice(busNum, chipNum, mode, bits, maxSpeed) 88 if err != nil { 89 return nil, err 90 } 91 con = spi.NewConnection(bus) 92 a.connections[id] = con 93 } 94 95 return con, nil 96 } 97 98 // SpiDefaultBusNumber returns the default bus number for this platform. 99 func (a *SpiBusAdaptor) SpiDefaultBusNumber() int { 100 return a.defaultBusNumber 101 } 102 103 // SpiDefaultChipNumber returns the default chip number for this platform. 104 func (a *SpiBusAdaptor) SpiDefaultChipNumber() int { 105 return a.defaultChipNumber 106 } 107 108 // SpiDefaultMode returns the default SPI mode for this platform. 109 func (a *SpiBusAdaptor) SpiDefaultMode() int { 110 return a.defaultMode 111 } 112 113 // SpiDefaultBitCount returns the default number of bits used for this platform. 114 func (a *SpiBusAdaptor) SpiDefaultBitCount() int { 115 return a.defaultBitCount 116 } 117 118 // SpiDefaultMaxSpeed returns the default maximal speed for this platform. 119 func (a *SpiBusAdaptor) SpiDefaultMaxSpeed() int64 { 120 return a.defaultMaxSpeed 121 }