Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package gobot

import "fmt"

func Debuglnf(isDebug bool, format string, a ...interface{}) {
if isDebug {
msg := fmt.Sprintf(format, a...)
fmt.Printf("<Debug>: %s\n", msg)
}
}
52 changes: 45 additions & 7 deletions platforms/adaptors/analogpinsadaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,65 @@ import (

type analogPinTranslator func(pin string) (path string, w bool, readBufLen uint16, err error)

// analogPinsConfiguration contains all changeable attributes of the adaptor.
type analogPinsConfiguration struct {
debug bool
}

// AnalogPinsAdaptor is a adaptor for analog pins, normally used for composition in platforms.
// It is also usable for general sysfs access.
type AnalogPinsAdaptor struct {
sys *system.Accesser
translate analogPinTranslator
pins map[string]gobot.AnalogPinner
mutex sync.Mutex
sys *system.Accesser
analogPinsCfg *analogPinsConfiguration
translate analogPinTranslator
pins map[string]gobot.AnalogPinner
mutex sync.Mutex
}

// NewAnalogPinsAdaptor provides the access to analog pins of the board. Usually sysfs system drivers are used.
// The translator is used to adapt the pin header naming, which is given by user, to the internal file name
// nomenclature. This varies by each platform.
func NewAnalogPinsAdaptor(sys *system.Accesser, t analogPinTranslator) *AnalogPinsAdaptor {
//
// Options:
//
// "WithAnalogPinDebug"
func NewAnalogPinsAdaptor(
sys *system.Accesser,
t analogPinTranslator,
opts ...AnalogPinsOptionApplier,
) *AnalogPinsAdaptor {
a := AnalogPinsAdaptor{
sys: sys,
translate: t,
sys: sys,
analogPinsCfg: &analogPinsConfiguration{},
translate: t,
}

for _, o := range opts {
o.apply(a.analogPinsCfg)
}

sys.AddAnalogSupport()

return &a
}

// WithAnalogPinDebug can be used to switch on debugging for analog pins implementation.
func WithAnalogPinDebug() analogPinsDebugOption {
return analogPinsDebugOption(true)
}

// Connect prepare new connection to analog pins.
func (a *AnalogPinsAdaptor) Connect() error {
a.mutex.Lock()
defer a.mutex.Unlock()

if a.pins != nil {
return fmt.Errorf("analog pin adaptor already connected, please call Finalize() for re-connect")
}

a.pins = make(map[string]gobot.AnalogPinner)
a.debuglnf("connect the analog pins adaptor done")

return nil
}

Expand All @@ -47,7 +77,11 @@ func (a *AnalogPinsAdaptor) Finalize() error {
a.mutex.Lock()
defer a.mutex.Unlock()

// nothing to do at the moment, because the file access for each pin will be closed immediately after read/write

a.pins = nil
a.debuglnf("finalize the analog pins adaptor done")

return nil
}

Expand Down Expand Up @@ -96,3 +130,7 @@ func (a *AnalogPinsAdaptor) analogPin(id string) (gobot.AnalogPinner, error) {

return pin, nil
}

func (a *AnalogPinsAdaptor) debuglnf(format string, p ...interface{}) {
gobot.Debuglnf(a.analogPinsCfg.debug, format, p...)
}
19 changes: 19 additions & 0 deletions platforms/adaptors/analogpinsadaptoroptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package adaptors

// AnalogPinsOptionApplier is the interface for analog pins adaptor options. This provides the possibility for change
// the platform behavior by the user when creating the platform, e.g. by "NewAdaptor()".
// The interface needs to be implemented by each configurable option type.
type AnalogPinsOptionApplier interface {
apply(cfg *analogPinsConfiguration)
}

// analogPinsDebugOption is the type to switch on analog pins related debug messages.
type analogPinsDebugOption bool

func (o analogPinsDebugOption) String() string {
return "switch on debugging for analog pins option"
}

func (o analogPinsDebugOption) apply(cfg *analogPinsConfiguration) {
cfg.debug = bool(o)
}
18 changes: 18 additions & 0 deletions platforms/adaptors/analogpinsadaptoroptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package adaptors

import (
"testing"

"github.com/stretchr/testify/assert"

"gobot.io/x/gobot/v2/system"
)

func TestWithAnalogPinDebug(t *testing.T) {
// This is a general test, that options are applied in constructor. Further tests for options
// can also be done by call of "WithOption(val).apply(cfg)".
// arrange & act
a := NewAnalogPinsAdaptor(system.NewAccesser(), nil, WithAnalogPinDebug())
// assert
assert.True(t, a.analogPinsCfg.debug)
}
22 changes: 12 additions & 10 deletions platforms/adaptors/digitalpinsadaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func NewDigitalPinsAdaptor(
return &a
}

// WithDigitalPinDebug can be used to switch on debugging for SPI implementation.
// WithDigitalPinDebug can be used to switch on debugging for digital pins implementation.
func WithDigitalPinDebug() digitalPinsDebugOption {
return digitalPinsDebugOption(true)
}
Expand Down Expand Up @@ -163,15 +163,12 @@ func (a *DigitalPinsAdaptor) Connect() error {
a.mutex.Lock()
defer a.mutex.Unlock()

if a.digitalPinsCfg.debug {
fmt.Println("connect the digital pins adaptor")
}

if a.pins != nil {
return fmt.Errorf("digital pin adaptor already connected, please call Finalize() for re-connect")
}

a.pins = make(map[string]gobot.DigitalPinner)
a.debuglnf("connect the digital pins adaptor done")

return nil
}
Expand All @@ -181,19 +178,20 @@ func (a *DigitalPinsAdaptor) Finalize() error {
a.mutex.Lock()
defer a.mutex.Unlock()

if a.digitalPinsCfg.debug {
fmt.Println("finalize the digital pins adaptor")
}
a.debuglnf("finalize the digital pins adaptor with %d pins...", len(a.pins))

var err error
for _, pin := range a.pins {
for id, pin := range a.pins {
if pin != nil {
if e := pin.Unexport(); e != nil {
e := pin.Unexport()
if e != nil {
err = multierror.Append(err, e)
}
a.debuglnf("finalize the digital pin '%s' done with error: %v", id, e)
}
}
a.pins = nil
a.debuglnf("finalize the digital pins adaptor done with error: %v", err)

return err
}
Expand Down Expand Up @@ -260,3 +258,7 @@ func (a *DigitalPinsAdaptor) digitalPin(

return pin, nil
}

func (a *DigitalPinsAdaptor) debuglnf(format string, p ...interface{}) {
gobot.Debuglnf(a.digitalPinsCfg.debug, format, p...)
}
12 changes: 10 additions & 2 deletions platforms/adaptors/digitalpinsadaptoroptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@ import (
func TestDigitalPinsWithGpiosActiveLow(t *testing.T) {
// This is a general test, that options are applied in constructor. Further tests for options
// can also be done by call of "WithOption(val).apply(cfg)".
// arrange & act, connect is mandatory to set options to the system
// arrange & act
a := NewDigitalPinsAdaptor(system.NewAccesser(), nil, WithGpiosActiveLow("1", "12", "33"))
require.NoError(t, a.Connect())
// assert
assert.Len(t, a.digitalPinsCfg.pinOptions, 3)
}

func TestWithDigitalPinDebug(t *testing.T) {
// arrange
cfg := &digitalPinsConfiguration{debug: false}
// act
WithDigitalPinDebug().apply(cfg)
// assert
assert.True(t, cfg.debug)
}

func TestDigitalPinsWithDigitalPinInitializer(t *testing.T) {
// arrange
const (
Expand Down
47 changes: 44 additions & 3 deletions platforms/adaptors/i2cbusadaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ import (

type i2cBusNumberValidator func(busNumber int) error

// i2cBusConfiguration contains all changeable attributes of the adaptor.
type i2cBusConfiguration struct {
debug bool
}

// I2cBusAdaptor is a adaptor for i2c bus, normally used for composition in platforms.
type I2cBusAdaptor struct {
sys *system.Accesser
i2cBusCfg *i2cBusConfiguration
validateNumber i2cBusNumberValidator
defaultBusNumber int
mutex sync.Mutex
Expand All @@ -24,24 +30,49 @@ type I2cBusAdaptor struct {

// NewI2cBusAdaptor provides the access to i2c buses of the board. The validator is used to check the bus number,
// which is given by user, to the abilities of the board.
func NewI2cBusAdaptor(sys *system.Accesser, v i2cBusNumberValidator, defaultBusNr int) *I2cBusAdaptor {
//
// Options:
//
// "WithI2cDebug"
func NewI2cBusAdaptor(
sys *system.Accesser,
v i2cBusNumberValidator,
defaultBusNr int,
opts ...I2CBusOptionApplier,
) *I2cBusAdaptor {
a := I2cBusAdaptor{
sys: sys,
i2cBusCfg: &i2cBusConfiguration{},
validateNumber: v,
defaultBusNumber: defaultBusNr,
}

for _, o := range opts {
o.apply(a.i2cBusCfg)
}

sys.AddI2CSupport()

return &a
}

// WithI2cDebug can be used to switch on debugging for I2C implementation.
func WithI2cDebug() i2cBusDebugOption {
return i2cBusDebugOption(true)
}

// Connect prepares the connection to i2c buses.
func (a *I2cBusAdaptor) Connect() error {
a.mutex.Lock()
defer a.mutex.Unlock()

if a.buses != nil {
return fmt.Errorf("I2C bus adaptor already connected, please call Finalize() for re-connect")
}

a.buses = make(map[int]gobot.I2cSystemDevicer)
a.debuglnf("connect the I2C bus adaptor done")

return nil
}

Expand All @@ -50,15 +81,21 @@ func (a *I2cBusAdaptor) Finalize() error {
a.mutex.Lock()
defer a.mutex.Unlock()

a.debuglnf("finalize the I2C bus adaptor for %d buses...", len(a.buses))

var err error
for _, bus := range a.buses {
for busNum, bus := range a.buses {
if bus != nil {
if e := bus.Close(); e != nil {
e := bus.Close()
if e != nil {
err = multierror.Append(err, e)
}
a.debuglnf("I2C bus %d closed with error: %v", busNum, e)
}
}
a.buses = nil
a.debuglnf("finalize the I2C bus adaptor done with error: %v", err)

return err
}

Expand Down Expand Up @@ -90,3 +127,7 @@ func (a *I2cBusAdaptor) GetI2cConnection(address int, busNum int) (i2c.Connectio
func (a *I2cBusAdaptor) DefaultI2cBus() int {
return a.defaultBusNumber
}

func (a *I2cBusAdaptor) debuglnf(format string, p ...interface{}) {
gobot.Debuglnf(a.i2cBusCfg.debug, format, p...)
}
19 changes: 19 additions & 0 deletions platforms/adaptors/i2cbusadaptoroptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package adaptors

// I2CBusOptionApplier is the interface for I2C bus adaptors options. This provides the possibility for change the
// platform behavior by the user when creating the platform, e.g. by "NewAdaptor()".
// The interface needs to be implemented by each configurable option type.
type I2CBusOptionApplier interface {
apply(cfg *i2cBusConfiguration)
}

// i2cBusDebugOption is the type to switch on I2C related debug messages.
type i2cBusDebugOption bool

func (o i2cBusDebugOption) String() string {
return "switch on debugging for I2C option"
}

func (o i2cBusDebugOption) apply(cfg *i2cBusConfiguration) {
cfg.debug = bool(o)
}
18 changes: 18 additions & 0 deletions platforms/adaptors/i2cbusadaptoroptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package adaptors

import (
"testing"

"github.com/stretchr/testify/assert"

"gobot.io/x/gobot/v2/system"
)

func TestWithI2cDebug(t *testing.T) {
// This is a general test, that options are applied in constructor. Further tests for options
// can also be done by call of "WithOption(val).apply(cfg)".
// arrange & act
a := NewI2cBusAdaptor(system.NewAccesser(), nil, 0, WithI2cDebug())
// assert
assert.True(t, a.i2cBusCfg.debug)
}
Loading