Add support for the CHIP platform
This includes support for GPIO and I2C interfaces. Signed-off-by: Hrishikesh Tapaswi <hrishikesh195@yahoo.com>
This commit is contained in:
parent
ef61647a3a
commit
30d66e2502
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/platforms/chip"
|
||||
"github.com/hybridgroup/gobot/platforms/gpio"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gbot := gobot.NewGobot()
|
||||
|
||||
chipAdaptor := chip.NewChipAdaptor("chip")
|
||||
led := gpio.NewLedDriver(chipAdaptor, "led", "U14_13")
|
||||
|
||||
work := func() {
|
||||
gobot.Every(1*time.Second, func() {
|
||||
led.Toggle()
|
||||
})
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("blinkBot",
|
||||
[]gobot.Connection{chipAdaptor},
|
||||
[]gobot.Device{led},
|
||||
work,
|
||||
)
|
||||
|
||||
gbot.AddRobot(robot)
|
||||
|
||||
gbot.Start()
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/platforms/chip"
|
||||
"github.com/hybridgroup/gobot/platforms/gpio"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gbot := gobot.NewGobot()
|
||||
|
||||
chipAdaptor := chip.NewChipAdaptor("chip")
|
||||
button := gpio.NewButtonDriver(chipAdaptor, "button", "U14_13")
|
||||
|
||||
work := func() {
|
||||
gobot.On(button.Event("push"), func(data interface{}) {
|
||||
fmt.Println("button pressed")
|
||||
})
|
||||
|
||||
gobot.On(button.Event("release"), func(data interface{}) {
|
||||
fmt.Println("button released")
|
||||
})
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("buttonBot",
|
||||
[]gobot.Connection{chipAdaptor},
|
||||
[]gobot.Device{button},
|
||||
work,
|
||||
)
|
||||
gbot.AddRobot(robot)
|
||||
gbot.Start()
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/platforms/chip"
|
||||
"github.com/hybridgroup/gobot/platforms/i2c"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gbot := gobot.NewGobot()
|
||||
|
||||
chipAdaptor := chip.NewChipAdaptor("chip")
|
||||
wiichuck := i2c.NewWiichuckDriver(chipAdaptor, "wiichuck")
|
||||
|
||||
work := func() {
|
||||
gobot.On(wiichuck.Event("joystick"), func(data interface{}) {
|
||||
fmt.Println("joystick", data)
|
||||
})
|
||||
|
||||
gobot.On(wiichuck.Event("c"), func(data interface{}) {
|
||||
fmt.Println("c")
|
||||
})
|
||||
|
||||
gobot.On(wiichuck.Event("z"), func(data interface{}) {
|
||||
fmt.Println("z")
|
||||
})
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("chuck",
|
||||
[]gobot.Connection{chipAdaptor},
|
||||
[]gobot.Device{wiichuck},
|
||||
work,
|
||||
)
|
||||
|
||||
gbot.AddRobot(robot)
|
||||
|
||||
gbot.Start()
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
# CHIP
|
||||
|
||||
The [CHIP](http://www.getchip.com/) is a small, inexpensive ARM based single board computer, with many different IO interfaces available on the [pin headers](http://docs.getchip.com/#pin-headers).
|
||||
|
||||
For documentation about the CHIP platform click [here](http://docs.getchip.com/).
|
||||
|
||||
## How to Install
|
||||
```
|
||||
go get -d -u github.com/hybridgroup/gobot/... && go install github.com/hybridgroup/gobot/platforms/chip
|
||||
```
|
||||
|
||||
## Cross compiling for the CHIP
|
||||
If you're using Go version earlier than 1.5, you must first configure your Go environment for ARM linux cross compiling.
|
||||
|
||||
```bash
|
||||
$ cd $GOROOT/src
|
||||
$ GOOS=linux GOARCH=arm ./make.bash --no-clean
|
||||
```
|
||||
|
||||
The above step is not required for Go >= 1.5
|
||||
|
||||
Then compile your Gobot program with
|
||||
|
||||
```bash
|
||||
$ GOARM=7 GOARCH=arm GOOS=linux go build examples/chip_button.go
|
||||
```
|
||||
|
||||
Then you can simply upload your program to the CHIP and execute it with
|
||||
|
||||
```bash
|
||||
$ scp chip_button root@192.168.1.xx:
|
||||
$ ssh -t root@192.168.1.xx "./chip_button"
|
||||
```
|
||||
|
||||
## How to Use
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/platforms/chip"
|
||||
"github.com/hybridgroup/gobot/platforms/gpio"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gbot := gobot.NewGobot()
|
||||
|
||||
chipAdaptor := chip.NewChipAdaptor("chip")
|
||||
button := gpio.NewButtonDriver(chipAdaptor, "button", "U14_13")
|
||||
|
||||
work := func() {
|
||||
gobot.On(button.Event("push"), func(data interface{}) {
|
||||
fmt.Println("button pressed")
|
||||
})
|
||||
|
||||
gobot.On(button.Event("release"), func(data interface{}) {
|
||||
fmt.Println("button released")
|
||||
})
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("buttonBot",
|
||||
[]gobot.Connection{chipAdaptor},
|
||||
[]gobot.Device{button},
|
||||
work,
|
||||
)
|
||||
gbot.AddRobot(robot)
|
||||
gbot.Start()
|
||||
}
|
||||
```
|
|
@ -0,0 +1,148 @@
|
|||
package chip
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/platforms/gpio"
|
||||
"github.com/hybridgroup/gobot/platforms/i2c"
|
||||
"github.com/hybridgroup/gobot/sysfs"
|
||||
)
|
||||
|
||||
var _ gobot.Adaptor = (*ChipAdaptor)(nil)
|
||||
|
||||
var _ gpio.DigitalReader = (*ChipAdaptor)(nil)
|
||||
var _ gpio.DigitalWriter = (*ChipAdaptor)(nil)
|
||||
|
||||
var _ i2c.I2c = (*ChipAdaptor)(nil)
|
||||
|
||||
type ChipAdaptor struct {
|
||||
name string
|
||||
digitalPins map[int]sysfs.DigitalPin
|
||||
i2cDevice sysfs.I2cDevice
|
||||
}
|
||||
|
||||
var pins = map[string]int{
|
||||
"U14_13": 408,
|
||||
"U14_14": 409,
|
||||
"U14_15": 410,
|
||||
"U14_16": 411,
|
||||
"U14_17": 412,
|
||||
"U14_18": 413,
|
||||
"U14_19": 414,
|
||||
"U14_20": 415,
|
||||
}
|
||||
|
||||
// NewChipAdaptor creates a ChipAdaptor with the specified name
|
||||
func NewChipAdaptor(name string) *ChipAdaptor {
|
||||
c := &ChipAdaptor{
|
||||
name: name,
|
||||
digitalPins: make(map[int]sysfs.DigitalPin),
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Name returns the name of the ChipAdaptor
|
||||
func (c *ChipAdaptor) Name() string { return c.name }
|
||||
|
||||
// Connect initializes the board
|
||||
func (c *ChipAdaptor) Connect() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Finalize closes connection to board and pins
|
||||
func (c *ChipAdaptor) Finalize() (errs []error) {
|
||||
for _, pin := range c.digitalPins {
|
||||
if pin != nil {
|
||||
if err := pin.Unexport(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.i2cDevice != nil {
|
||||
if err := c.i2cDevice.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func (c *ChipAdaptor) translatePin(pin string) (i int, err error) {
|
||||
if val, ok := pins[pin]; ok {
|
||||
i = val
|
||||
} else {
|
||||
err = errors.New("Not a valid pin")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// digitalPin returns matched digitalPin for specified values
|
||||
func (c *ChipAdaptor) digitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPin, err error) {
|
||||
i, err := c.translatePin(pin)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if c.digitalPins[i] == nil {
|
||||
c.digitalPins[i] = sysfs.NewDigitalPin(i)
|
||||
if err = c.digitalPins[i].Export(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = c.digitalPins[i].Direction(dir); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return c.digitalPins[i], nil
|
||||
}
|
||||
|
||||
// DigitalRead reads digital value from the specified pin.
|
||||
// Valids pins are XIO-P0 through XIO-P1 (pins 13-20 on header 14).
|
||||
func (c *ChipAdaptor) DigitalRead(pin string) (val int, err error) {
|
||||
sysfsPin, err := c.digitalPin(pin, sysfs.IN)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return sysfsPin.Read()
|
||||
}
|
||||
|
||||
// DigitalWrite writes digital value to the specified pin.
|
||||
// Valids pins are XIO-P0 through XIO-P1 (pins 13-20 on header 14).
|
||||
func (c *ChipAdaptor) DigitalWrite(pin string, val byte) (err error) {
|
||||
sysfsPin, err := c.digitalPin(pin, sysfs.OUT)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sysfsPin.Write(int(val))
|
||||
}
|
||||
|
||||
// I2cStart starts an i2c device in specified address.
|
||||
// This assumes that the bus used is /dev/i2c-1, which corresponds to
|
||||
// pins labeled TWI1 (pins 9 and 11 on header 13).
|
||||
func (c *ChipAdaptor) I2cStart(address int) (err error) {
|
||||
if c.i2cDevice == nil {
|
||||
c.i2cDevice, err = sysfs.NewI2cDevice("/dev/i2c-1", address)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// I2cWrite writes data to i2c device
|
||||
func (c *ChipAdaptor) I2cWrite(address int, data []byte) (err error) {
|
||||
if err = c.i2cDevice.SetAddress(address); err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.i2cDevice.Write(data)
|
||||
return
|
||||
}
|
||||
|
||||
// I2cRead returns value from i2c device using specified size
|
||||
func (c *ChipAdaptor) I2cRead(address int, size int) (data []byte, err error) {
|
||||
if err = c.i2cDevice.SetAddress(address); err != nil {
|
||||
return
|
||||
}
|
||||
data = make([]byte, size)
|
||||
_, err = c.i2cDevice.Read(data)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package chip
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
"github.com/hybridgroup/gobot/sysfs"
|
||||
)
|
||||
|
||||
type NullReadWriteCloser struct {
|
||||
contents []byte
|
||||
}
|
||||
|
||||
func (n *NullReadWriteCloser) SetAddress(int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NullReadWriteCloser) Write(b []byte) (int, error) {
|
||||
n.contents = make([]byte, len(b))
|
||||
copy(n.contents[:], b[:])
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (n *NullReadWriteCloser) Read(b []byte) (int, error) {
|
||||
copy(b, n.contents)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
var closeErr error = nil
|
||||
|
||||
func (n *NullReadWriteCloser) Close() error {
|
||||
return closeErr
|
||||
}
|
||||
|
||||
func initTestChipAdaptor() *ChipAdaptor {
|
||||
a := NewChipAdaptor("myAdaptor")
|
||||
a.Connect()
|
||||
return a
|
||||
}
|
||||
|
||||
func TestChipAdaptorDigitalIO(t *testing.T) {
|
||||
a := initTestChipAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/sys/class/gpio/export",
|
||||
"/sys/class/gpio/unexport",
|
||||
"/sys/class/gpio/gpio408/value",
|
||||
"/sys/class/gpio/gpio408/direction",
|
||||
"/sys/class/gpio/gpio415/value",
|
||||
"/sys/class/gpio/gpio415/direction",
|
||||
})
|
||||
|
||||
sysfs.SetFilesystem(fs)
|
||||
|
||||
a.DigitalWrite("U14_13", 1)
|
||||
gobot.Assert(t, fs.Files["/sys/class/gpio/gpio408/value"].Contents, "1")
|
||||
|
||||
fs.Files["/sys/class/gpio/gpio415/value"].Contents = "1"
|
||||
i, _ := a.DigitalRead("U14_20")
|
||||
gobot.Assert(t, i, 1)
|
||||
|
||||
gobot.Assert(t, a.DigitalWrite("U13_99", 1), errors.New("Not a valid pin"))
|
||||
}
|
||||
|
||||
func TestChipAdaptorI2c(t *testing.T) {
|
||||
a := initTestChipAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/dev/i2c-1",
|
||||
})
|
||||
sysfs.SetFilesystem(fs)
|
||||
sysfs.SetSyscall(&sysfs.MockSyscall{})
|
||||
a.I2cStart(0xff)
|
||||
a.i2cDevice = &NullReadWriteCloser{}
|
||||
|
||||
a.I2cWrite(0xff, []byte{0x00, 0x01})
|
||||
data, _ := a.I2cRead(0xff, 2)
|
||||
gobot.Assert(t, data, []byte{0x00, 0x01})
|
||||
|
||||
gobot.Assert(t, len(a.Finalize()), 0)
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
Package chip contains the Gobot adaptor for the CHIP
|
||||
|
||||
For further information refer to the chip README:
|
||||
https://github.com/hybridgroup/gobot/blob/master/platforms/chip/README.md
|
||||
*/
|
||||
package chip
|
Loading…
Reference in New Issue