beaglebone: add SPI support and remove last vestiges of slots

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2017-12-19 16:45:16 +01:00
parent c25661a0a1
commit 066a444aec
2 changed files with 62 additions and 59 deletions

View File

@ -1,7 +1,6 @@
package beaglebone
import (
"bufio"
"errors"
"fmt"
"os"
@ -13,6 +12,7 @@ import (
multierror "github.com/hashicorp/go-multierror"
"gobot.io/x/gobot"
"gobot.io/x/gobot/drivers/i2c"
"gobot.io/x/gobot/drivers/spi"
"gobot.io/x/gobot/sysfs"
)
@ -31,12 +31,15 @@ type Adaptor struct {
i2cBuses map[int]i2c.I2cDevice
usrLed string
analogPath string
slots string
pinMap map[string]int
pwmPinMap map[string]pwmPinData
analogPinMap map[string]string
mutex *sync.Mutex
findPin func(pinPath string) (string, error)
spiDefaultBus int
spiBuses [2]spi.SPIDevice
spiDefaultMode int
spiDefaultMaxSpeed int64
}
// NewAdaptor returns a new Beaglebone Black/Green Adaptor
@ -61,9 +64,12 @@ func NewAdaptor() *Adaptor {
}
func (b *Adaptor) setPaths() {
b.slots = "/sys/devices/platform/bone_capemgr/slots"
b.usrLed = "/sys/class/leds/beaglebone:green:"
b.analogPath = "/sys/bus/iio/devices/iio:device0"
b.spiDefaultBus = 0
b.spiDefaultMode = 0
b.spiDefaultMaxSpeed = 500000
}
// Name returns the Adaptor name
@ -103,6 +109,13 @@ func (b *Adaptor) Finalize() (err error) {
}
}
}
for _, bus := range b.spiBuses {
if bus != nil {
if e := bus.Close(); e != nil {
err = multierror.Append(err, e)
}
}
}
return
}
@ -267,6 +280,38 @@ func (b *Adaptor) GetDefaultBus() int {
return 2
}
// GetSpiConnection returns an spi connection to a device on a specified bus.
// Valid bus number is [0..1] which corresponds to /dev/spidev0.0 through /dev/spidev0.1.
func (b *Adaptor) GetSpiConnection(busNum, mode int, maxSpeed int64) (connection spi.Connection, err error) {
b.mutex.Lock()
defer b.mutex.Unlock()
if (busNum < 0) || (busNum > 1) {
return nil, fmt.Errorf("Bus number %d out of range", busNum)
}
if b.spiBuses[busNum] == nil {
b.spiBuses[busNum], err = spi.GetSpiBus(busNum, mode, maxSpeed)
}
return spi.NewConnection(b.spiBuses[busNum]), err
}
// GetSpiDefaultBus returns the default spi bus for this platform.
func (b *Adaptor) GetSpiDefaultBus() int {
return b.spiDefaultBus
}
// GetSpiDefaultMode returns the default spi mode for this platform.
func (b *Adaptor) GetSpiDefaultMode() int {
return b.spiDefaultMode
}
// GetSpiDefaultMaxSpeed returns the default spi bus for this platform.
func (b *Adaptor) GetSpiDefaultMaxSpeed() int64 {
return b.spiDefaultMaxSpeed
}
// translatePin converts digital pin name to pin position
func (b *Adaptor) translatePin(pin string) (value int, err error) {
if val, ok := b.pinMap[pin]; ok {
@ -296,39 +341,6 @@ func (b *Adaptor) translateAnalogPin(pin string) (value string, err error) {
return
}
func ensureSlot(slots, item string) (err error) {
fi, err := sysfs.OpenFile(slots, os.O_RDWR|os.O_APPEND, 0666)
defer fi.Close()
if err != nil {
return
}
// ensure the slot is not already written into the capemanager
// (from: https://github.com/mrmorphic/hwio/blob/master/module_bb_pwm.go#L190)
scanner := bufio.NewScanner(fi)
for scanner.Scan() {
line := scanner.Text()
if strings.Index(line, item) > 0 {
return
}
}
_, err = fi.WriteString(item)
if err != nil {
return err
}
fi.Sync()
scanner = bufio.NewScanner(fi)
for scanner.Scan() {
line := scanner.Text()
if strings.Index(line, item) > 0 {
return
}
}
return
}
func muxPin(pin, cmd string) error {
path := fmt.Sprintf("/sys/devices/platform/ocp/ocp:%s_pinmux/state", pin)
fi, e := sysfs.OpenFile(path, os.O_WRONLY, 0666)

View File

@ -9,6 +9,7 @@ import (
"gobot.io/x/gobot/drivers/aio"
"gobot.io/x/gobot/drivers/gpio"
"gobot.io/x/gobot/drivers/i2c"
"gobot.io/x/gobot/drivers/spi"
"gobot.io/x/gobot/gobottest"
"gobot.io/x/gobot/sysfs"
)
@ -23,6 +24,7 @@ var _ gpio.ServoWriter = (*Adaptor)(nil)
var _ sysfs.DigitalPinnerProvider = (*Adaptor)(nil)
var _ sysfs.PWMPinnerProvider = (*Adaptor)(nil)
var _ i2c.Connector = (*Adaptor)(nil)
var _ spi.Connector = (*Adaptor)(nil)
func initBBBTestAdaptor() (*Adaptor, error) {
a := NewAdaptor()
@ -50,7 +52,6 @@ func TestBeagleboneAdaptor(t *testing.T) {
fs := sysfs.NewMockFilesystem([]string{
"/dev/i2c-2",
"/sys/devices/platform/bone_capemgr",
"/sys/devices/platform/bone_capemgr/slots",
"/sys/devices/platform/ocp/ocp:P8_7_pinmux/state",
"/sys/devices/platform/ocp/ocp:P9_11_pinmux/state",
"/sys/devices/platform/ocp/ocp:P9_12_pinmux/state",
@ -199,19 +200,9 @@ func TestBeagleboneGetConnectionInvalidBus(t *testing.T) {
gobottest.Assert(t, err, errors.New("Bus number 99 out of range"))
}
func TestBeagleboneConnectNoSlot(t *testing.T) {
fs := sysfs.NewMockFilesystem([]string{
"/dev/i2c-2",
})
sysfs.SetFilesystem(fs)
_, err := initBBBTestAdaptor()
gobottest.Assert(t, strings.Contains(err.Error(), "/sys/devices/platform/bone_capemgr/slots: No such file."), true)
}
func TestBeagleboneAnalogReadFileError(t *testing.T) {
fs := sysfs.NewMockFilesystem([]string{
"/sys/devices/platform/bone_capemgr/slots",
"/sys/devices/platform/whatever",
})
sysfs.SetFilesystem(fs)