Skip to content

Commit

Permalink
Update beaglebone package for new gpio interface
Browse files Browse the repository at this point in the history
  • Loading branch information
zankich committed Nov 16, 2014
1 parent 7474b15 commit c5906a9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 64 deletions.
3 changes: 2 additions & 1 deletion examples/beaglebone_direct_pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ func main() {

work := func() {
gobot.Every(500*time.Millisecond, func() {
if button.DigitalRead() == 1 {
val, _ := button.DigitalRead()
if val == 1 {
led.DigitalWrite(1)
} else {
led.DigitalWrite(0)
Expand Down
110 changes: 69 additions & 41 deletions platforms/beaglebone/beaglebone_adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bufio"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -144,18 +143,28 @@ func NewBeagleboneAdaptor(name string) *BeagleboneAdaptor {

// Connect returns true on a succesful connection to beaglebone board.
// It initializes digital, pwm and analog pins
func (b *BeagleboneAdaptor) Connect() error {
ensureSlot(b.slots, "cape-bone-iio")
ensureSlot(b.slots, "am33xx_pwm")
func (b *BeagleboneAdaptor) Connect() (err error) {
err = ensureSlot(b.slots, "cape-bone-iio")
if err != nil {
return
}

err = ensureSlot(b.slots, "am33xx_pwm")
if err != nil {
return
}

g, _ := glob(fmt.Sprintf("%v/helper.*", b.ocp))
g, err := glob(fmt.Sprintf("%v/helper.*", b.ocp))
if err != nil {
return
}
b.helper = g[0]

return nil
return
}

// Finalize returns true when board connection is finalized correctly.
func (b *BeagleboneAdaptor) Finalize() error {
func (b *BeagleboneAdaptor) Finalize() (err error) {
for _, pin := range b.pwmPins {
if pin != nil {
pin.release()
Expand All @@ -173,60 +182,66 @@ func (b *BeagleboneAdaptor) Finalize() error {
}

// PwmWrite writes value in specified pin
func (b *BeagleboneAdaptor) PwmWrite(pin string, val byte) {
b.pwmWrite(pin, val)
func (b *BeagleboneAdaptor) PwmWrite(pin string, val byte) (err error) {
return b.pwmWrite(pin, val)
}

// InitServo starts servo (not yet implemented)
func (b *BeagleboneAdaptor) InitServo() {}
func (b *BeagleboneAdaptor) InitServo() (err error) { return nil }

// ServoWrite writes scaled value to servo in specified pin
func (b *BeagleboneAdaptor) ServoWrite(pin string, val byte) {
i := b.pwmPin(pin)
func (b *BeagleboneAdaptor) ServoWrite(pin string, val byte) (err error) {
i, err := b.pwmPin(pin)
if err != nil {
return err
}
period := 20000000.0
duty := gobot.FromScale(float64(^val), 0, 180.0)
b.pwmPins[i].pwmWrite(strconv.Itoa(int(period)), strconv.Itoa(int(period*duty)))
return b.pwmPins[i].pwmWrite(strconv.Itoa(int(period)), strconv.Itoa(int(period*duty)))
}

// DigitalRead returns a digital value from specified pin
func (b *BeagleboneAdaptor) DigitalRead(pin string) (i int) {
i, _ = b.digitalPin(pin, sysfs.IN).Read()
return
func (b *BeagleboneAdaptor) DigitalRead(pin string) (val int, err error) {
return b.digitalPin(pin, sysfs.IN).Read()
}

// DigitalWrite writes a digital value to specified pin.
// valid usr pin values are usr0, usr1, usr2 and usr3
func (b *BeagleboneAdaptor) DigitalWrite(pin string, val byte) {
func (b *BeagleboneAdaptor) DigitalWrite(pin string, val byte) (err error) {
if strings.Contains(pin, "usr") {
fi, err := sysfs.OpenFile(usrLed+pin+"/brightness", os.O_WRONLY|os.O_APPEND, 0666)
defer fi.Close()
if err != nil {
log.Fatal(err)
return err
}
fi.WriteString(strconv.Itoa(int(val)))
} else {
b.digitalPin(pin, sysfs.OUT).Write(int(val))
_, err = fi.WriteString(strconv.Itoa(int(val)))
return err
}
return b.digitalPin(pin, sysfs.OUT).Write(int(val))
}

// AnalogRead returns an analog value from specified pin
func (b *BeagleboneAdaptor) AnalogRead(pin string) int {
func (b *BeagleboneAdaptor) AnalogRead(pin string) (val int, err error) {
fi, err := sysfs.OpenFile(fmt.Sprintf("%v/%v", b.helper, b.translateAnalogPin(pin)), os.O_RDONLY, 0644)
defer fi.Close()

if err != nil {
panic(err)
return
}

var buf = make([]byte, 1024)
fi.Read(buf)
_, err = fi.Read(buf)
if err != nil {
return
}

i, _ := strconv.Atoi(strings.Split(string(buf), "\n")[0])
return i
val, _ = strconv.Atoi(strings.Split(string(buf), "\n")[0])
return
}

// AnalogWrite writes an analog value to specified pin
func (b *BeagleboneAdaptor) AnalogWrite(pin string, val byte) {
b.pwmWrite(pin, val)
func (b *BeagleboneAdaptor) AnalogWrite(pin string, val byte) (err error) {
return b.pwmWrite(pin, val)
}

// I2cStart starts a i2c device in specified address
Expand Down Expand Up @@ -291,29 +306,35 @@ func (b *BeagleboneAdaptor) digitalPin(pin string, dir string) sysfs.DigitalPin
}

// pwPin retrieves pwm pin value by name
func (b *BeagleboneAdaptor) pwmPin(pin string) string {
i := b.translatePwmPin(pin)
func (b *BeagleboneAdaptor) pwmPin(pin string) (i string, err error) {
i = b.translatePwmPin(pin)
if b.pwmPins[i] == nil {
ensureSlot(b.slots, fmt.Sprintf("bone_pwm_%v", pin))
b.pwmPins[i] = newPwmPin(i, b.ocp)
err = ensureSlot(b.slots, fmt.Sprintf("bone_pwm_%v", pin))
if err != nil {
return
}
b.pwmPins[i], err = newPwmPin(i, b.ocp)
}
return i
return
}

// pwmWrite writes pwm value to specified pin
func (b *BeagleboneAdaptor) pwmWrite(pin string, val byte) {
i := b.pwmPin(pin)
func (b *BeagleboneAdaptor) pwmWrite(pin string, val byte) (err error) {
i, err := b.pwmPin(pin)
if err != nil {
return
}
period := 500000.0
duty := gobot.FromScale(float64(^val), 0, 255.0)
b.pwmPins[i].pwmWrite(strconv.Itoa(int(period)), strconv.Itoa(int(period*duty)))
return b.pwmPins[i].pwmWrite(strconv.Itoa(int(period)), strconv.Itoa(int(period*duty)))
}

func ensureSlot(slots, item string) {
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 {
panic(err)
return
}
defer fi.Close()

// ensure the slot is not already written into the capemanager
// (from: https://github.com/mrmorphic/hwio/blob/master/module_bb_pwm.go#L190)
Expand All @@ -325,8 +346,14 @@ func ensureSlot(slots, item string) {
}
}

fi.WriteString(item)
fi.Sync()
_, err = fi.WriteString(item)
if err != nil {
return err
}
err = fi.Sync()
if err != nil {
return nil
}

scanner = bufio.NewScanner(fi)
for scanner.Scan() {
Expand All @@ -335,4 +362,5 @@ func ensureSlot(slots, item string) {
return
}
}
return
}
4 changes: 2 additions & 2 deletions platforms/beaglebone/beaglebone_adaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func TestBeagleboneAdaptor(t *testing.T) {

// Analog
fs.Files["/sys/devices/ocp.3/helper.5/AIN1"].Contents = "567\n"
i := a.AnalogRead("P9_40")
i, _ := a.AnalogRead("P9_40")
gobot.Assert(t, i, 567)

// DigitalIO
Expand All @@ -98,7 +98,7 @@ func TestBeagleboneAdaptor(t *testing.T) {
gobot.Assert(t, fs.Files["/sys/class/gpio/gpio60/value"].Contents, "1")

fs.Files["/sys/class/gpio/gpio10/value"].Contents = "1"
i = a.DigitalRead("P8_31")
i, _ = a.DigitalRead("P8_31")
gobot.Assert(t, i, 1)

// I2c
Expand Down
55 changes: 35 additions & 20 deletions platforms/beaglebone/pwm_pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,69 +13,84 @@ type pwmPin struct {
}

// newPwmPin creates a new pwm pin with specified pin number
func newPwmPin(pinNum string, ocp string) *pwmPin {
func newPwmPin(pinNum string, ocp string) (p *pwmPin, err error) {
var fi sysfs.File

d := &pwmPin{
p = &pwmPin{
pinNum: strings.ToUpper(pinNum),
}

pwmDevice, err := glob(fmt.Sprintf("%v/pwm_test_%v.*", ocp, d.pinNum))
pwmDevice, err := glob(fmt.Sprintf("%v/pwm_test_%v.*", ocp, p.pinNum))
if err != nil {
panic(err)
return
}

d.pwmDevice = pwmDevice[0]
p.pwmDevice = pwmDevice[0]

for i := 0; i < 10; i++ {
fi, err = sysfs.OpenFile(fmt.Sprintf("%v/run", d.pwmDevice), os.O_RDWR|os.O_APPEND, 0666)
fi, err = sysfs.OpenFile(fmt.Sprintf("%v/run", p.pwmDevice), os.O_RDWR|os.O_APPEND, 0666)
defer fi.Close()
if err != nil && i == 9 {
panic(err)
return
} else {
break
}
}

fi.WriteString("1")
fi.Sync()
_, err = fi.WriteString("1")
if err != nil {
return
}
err = fi.Sync()
if err != nil {
return
}

for {
if _, err := sysfs.OpenFile(fmt.Sprintf("%v/period", d.pwmDevice), os.O_RDONLY, 0644); err == nil {
if _, err := sysfs.OpenFile(fmt.Sprintf("%v/period", p.pwmDevice), os.O_RDONLY, 0644); err == nil {
break
}
}
for {
if _, err := sysfs.OpenFile(fmt.Sprintf("%v/duty", d.pwmDevice), os.O_RDONLY, 0644); err == nil {
if _, err := sysfs.OpenFile(fmt.Sprintf("%v/duty", p.pwmDevice), os.O_RDONLY, 0644); err == nil {
break
}
}
return d
return
}

// pwmWrite writes to a pwm pin with specified period and duty
func (p *pwmPin) pwmWrite(period string, duty string) {
func (p *pwmPin) pwmWrite(period string, duty string) (err error) {
f1, err := sysfs.OpenFile(fmt.Sprintf("%v/period", p.pwmDevice), os.O_WRONLY|os.O_APPEND, 0666)
defer f1.Close()
if err != nil {
panic(err)
return
}
_, err = f1.WriteString(period)
if err != nil {
return
}
f1.WriteString(period)

f2, err := sysfs.OpenFile(fmt.Sprintf("%v/duty", p.pwmDevice), os.O_WRONLY|os.O_APPEND, 0666)
defer f2.Close()
if err != nil {
panic(err)
return
}
_, err = f2.WriteString(duty)
if err != nil {
return
}
f2.WriteString(duty)

return
}

// releae writes string to close a pwm pin
func (p *pwmPin) release() {
func (p *pwmPin) release() (err error) {
fi, err := sysfs.OpenFile(fmt.Sprintf("%v/run", p.pwmDevice), os.O_WRONLY|os.O_APPEND, 0666)
defer fi.Close()
if err != nil {
panic(err)
return
}
fi.WriteString("0")
_, err = fi.WriteString("0")
return
}

0 comments on commit c5906a9

Please sign in to comment.