gobot.io/x/gobot/v2@v2.1.0/platforms/adaptors/i2cbusadaptor.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"
     9  	"gobot.io/x/gobot/v2/drivers/i2c"
    10  	"gobot.io/x/gobot/v2/system"
    11  )
    12  
    13  type i2cBusNumberValidator func(busNumber int) error
    14  
    15  // I2cBusAdaptor is a adaptor for i2c bus, normally used for composition in platforms.
    16  type I2cBusAdaptor struct {
    17  	sys              *system.Accesser
    18  	validateNumber   i2cBusNumberValidator
    19  	defaultBusNumber int
    20  	mutex            sync.Mutex
    21  	buses            map[int]gobot.I2cSystemDevicer
    22  }
    23  
    24  // NewI2cBusAdaptor provides the access to i2c buses of the board. The validator is used to check the bus number,
    25  // which is given by user, to the abilities of the board.
    26  func NewI2cBusAdaptor(sys *system.Accesser, v i2cBusNumberValidator, defaultBusNr int) *I2cBusAdaptor {
    27  	a := &I2cBusAdaptor{
    28  		sys:              sys,
    29  		validateNumber:   v,
    30  		defaultBusNumber: defaultBusNr,
    31  	}
    32  	return a
    33  }
    34  
    35  // Connect prepares the connection to i2c buses.
    36  func (a *I2cBusAdaptor) Connect() error {
    37  	a.mutex.Lock()
    38  	defer a.mutex.Unlock()
    39  
    40  	a.buses = make(map[int]gobot.I2cSystemDevicer)
    41  	return nil
    42  }
    43  
    44  // Finalize closes all i2c buses.
    45  func (a *I2cBusAdaptor) Finalize() error {
    46  	a.mutex.Lock()
    47  	defer a.mutex.Unlock()
    48  
    49  	var err error
    50  	for _, bus := range a.buses {
    51  		if bus != nil {
    52  			if e := bus.Close(); e != nil {
    53  				err = multierror.Append(err, e)
    54  			}
    55  		}
    56  	}
    57  	a.buses = nil
    58  	return err
    59  }
    60  
    61  // GetI2cConnection returns a connection to a device on a specified i2c bus
    62  func (a *I2cBusAdaptor) GetI2cConnection(address int, busNum int) (i2c.Connection, error) {
    63  	a.mutex.Lock()
    64  	defer a.mutex.Unlock()
    65  
    66  	if a.buses == nil {
    67  		return nil, fmt.Errorf("not connected")
    68  	}
    69  
    70  	bus := a.buses[busNum]
    71  	if bus == nil {
    72  		err := a.validateNumber(busNum)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		bus, err = a.sys.NewI2cDevice(fmt.Sprintf("/dev/i2c-%d", busNum))
    77  		if err != nil {
    78  			return nil, err
    79  		}
    80  		a.buses[busNum] = bus
    81  	}
    82  	return i2c.NewConnection(bus, address), nil
    83  }
    84  
    85  // DefaultI2cBus returns the default i2c bus number for this platform.
    86  func (a *I2cBusAdaptor) DefaultI2cBus() int {
    87  	return a.defaultBusNumber
    88  }