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  }