From 07a24b2f6977e24bc41c13e1ff8128e6782916bf Mon Sep 17 00:00:00 2001 From: deadprogram Date: Thu, 14 Dec 2017 14:54:42 +0100 Subject: [PATCH] beaglebone: handle gpio pinmux without relying on specific pre-existing setup Signed-off-by: deadprogram --- platforms/beaglebone/beaglebone_adaptor.go | 53 ++++++++++++------- .../beaglebone/beaglebone_adaptor_test.go | 7 ++- platforms/beaglebone/beaglebone_pins.go | 13 ++--- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/platforms/beaglebone/beaglebone_adaptor.go b/platforms/beaglebone/beaglebone_adaptor.go index e1fbfb51..c341259d 100644 --- a/platforms/beaglebone/beaglebone_adaptor.go +++ b/platforms/beaglebone/beaglebone_adaptor.go @@ -15,28 +15,39 @@ import ( "gobot.io/x/gobot/sysfs" ) +type pwmPinData struct { + channel int + path string +} + const pwmDefaultPeriod = 500000 // Adaptor is the gobot.Adaptor representation for the Beaglebone type Adaptor struct { - name string - digitalPins []*sysfs.DigitalPin - pwmPins map[string]*sysfs.PWMPin - i2cBuses map[int]i2c.I2cDevice - usrLed string - analogPath string - slots string - mutex *sync.Mutex + name string + digitalPins []*sysfs.DigitalPin + pwmPins map[string]*sysfs.PWMPin + 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 } // NewAdaptor returns a new Beaglebone Adaptor func NewAdaptor() *Adaptor { b := &Adaptor{ - name: gobot.DefaultName("Beaglebone"), - digitalPins: make([]*sysfs.DigitalPin, 120), - pwmPins: make(map[string]*sysfs.PWMPin), - i2cBuses: make(map[int]i2c.I2cDevice), - mutex: &sync.Mutex{}, + name: gobot.DefaultName("Beaglebone"), + digitalPins: make([]*sysfs.DigitalPin, 120), + pwmPins: make(map[string]*sysfs.PWMPin), + i2cBuses: make(map[int]i2c.I2cDevice), + mutex: &sync.Mutex{}, + pinMap: bbbPinMap, + pwmPinMap: bbbPwmPinMap, + analogPinMap: bbbAnalogPinMap, } b.setSlots() @@ -163,6 +174,10 @@ func (b *Adaptor) DigitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPinn } if b.digitalPins[i] == nil { b.digitalPins[i] = sysfs.NewDigitalPin(i) + if err = muxPin(pin, "gpio"); err != nil { + return + } + err := b.digitalPins[i].Export() if err != nil { return nil, err @@ -188,7 +203,7 @@ func (b *Adaptor) PWMPin(pin string) (sysfsPin sysfs.PWMPinner, err error) { newPin := sysfs.NewPWMPin(pinInfo.channel) newPin.Path = pinInfo.path - if err = muxPWMPin(pin); err != nil { + if err = muxPin(pin, "pwm"); err != nil { return } if err = newPin.Export(); err != nil { @@ -256,7 +271,7 @@ func (b *Adaptor) GetDefaultBus() int { // translatePin converts digital pin name to pin position func (b *Adaptor) translatePin(pin string) (value int, err error) { - if val, ok := pins[pin]; ok { + if val, ok := b.pinMap[pin]; ok { value = val } else { err = errors.New("Not a valid pin") @@ -265,7 +280,7 @@ func (b *Adaptor) translatePin(pin string) (value int, err error) { } func (b *Adaptor) translatePwmPin(pin string) (p pwmPinData, err error) { - if val, ok := pwmPins[pin]; ok { + if val, ok := b.pwmPinMap[pin]; ok { p = val } else { err = errors.New("Not a valid PWM pin") @@ -275,7 +290,7 @@ func (b *Adaptor) translatePwmPin(pin string) (p pwmPinData, err error) { // translateAnalogPin converts analog pin name to pin position func (b *Adaptor) translateAnalogPin(pin string) (value string, err error) { - if val, ok := analogPins[pin]; ok { + if val, ok := b.analogPinMap[pin]; ok { value = val } else { err = errors.New("Not a valid analog pin") @@ -316,13 +331,13 @@ func ensureSlot(slots, item string) (err error) { return } -func muxPWMPin(pin string) error { +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) defer fi.Close() if e != nil { return e } - _, e = fi.WriteString("pwm") + _, e = fi.WriteString(cmd) return e } diff --git a/platforms/beaglebone/beaglebone_adaptor_test.go b/platforms/beaglebone/beaglebone_adaptor_test.go index 2c5d4724..87a6b508 100644 --- a/platforms/beaglebone/beaglebone_adaptor_test.go +++ b/platforms/beaglebone/beaglebone_adaptor_test.go @@ -29,8 +29,11 @@ func TestBeagleboneAdaptor(t *testing.T) { "/dev/i2c-2", "/sys/devices/platform/bone_capemgr", "/sys/devices/platform/bone_capemgr/slots", - "/sys/devices/platform/ocp/ocp:P9_21_pinmux/state", + "/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", "/sys/devices/platform/ocp/ocp:P9_22_pinmux/state", + "/sys/devices/platform/ocp/ocp:P9_21_pinmux/state", "/sys/class/leds/beaglebone:green:usr1/brightness", "/sys/bus/iio/devices/iio:device0/in_voltage1_raw", "/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/export", @@ -204,6 +207,7 @@ func TestBeagleboneDigitalPinDirectionFileError(t *testing.T) { "/sys/devices/platform/bone_capemgr/slots", "/sys/class/gpio/export", "/sys/class/gpio/gpio60/value", + "/sys/devices/platform/ocp/ocp:P9_12_pinmux/state", }) sysfs.SetFilesystem(fs) @@ -223,6 +227,7 @@ func TestBeagleboneDigitalPinFinalizeFileError(t *testing.T) { "/sys/class/gpio/export", "/sys/class/gpio/gpio60/value", "/sys/class/gpio/gpio60/direction", + "/sys/devices/platform/ocp/ocp:P9_12_pinmux/state", }) sysfs.SetFilesystem(fs) diff --git a/platforms/beaglebone/beaglebone_pins.go b/platforms/beaglebone/beaglebone_pins.go index b70d639f..4e6700cf 100644 --- a/platforms/beaglebone/beaglebone_pins.go +++ b/platforms/beaglebone/beaglebone_pins.go @@ -1,11 +1,6 @@ package beaglebone -type pwmPinData struct { - channel int - path string -} - -var pins = map[string]int{ +var bbbPinMap = map[string]int{ // P8_1 - P8_2 GND // P8_3 - P8_6 EMCC "P8_7": 66, @@ -54,7 +49,7 @@ var pins = map[string]int{ "P9_31": 110, } -var pwmPins = map[string]pwmPinData{ +var bbbPwmPinMap = map[string]pwmPinData{ "P8_13": {path: "/sys/devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip4", channel: 1}, "P8_19": {path: "/sys/devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip4", channel: 0}, @@ -62,10 +57,10 @@ var pwmPins = map[string]pwmPinData{ "P9_16": {path: "/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip2", channel: 1}, "P9_21": {path: "/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0", channel: 1}, "P9_22": {path: "/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0", channel: 0}, - //"P9_42": {path: "", channel: 0}, TODO: implement this pwm + "P9_42": {path: "/sys/devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0", channel: 0}, } -var analogPins = map[string]string{ +var bbbAnalogPinMap = map[string]string{ "P9_39": "in_voltage0_raw", "P9_40": "in_voltage1_raw", "P9_37": "in_voltage2_raw",