Skip to content

Commit

Permalink
Moved gopigo3 to a platform
Browse files Browse the repository at this point in the history
  • Loading branch information
ulisesflynn committed Sep 7, 2017
1 parent 94f5ded commit 4bd3b67
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 122 deletions.
2 changes: 0 additions & 2 deletions drivers/spi/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ go get -d -u gobot.io/x/gobot/...
## Hardware Support
Gobot has a extensible system for connecting to hardware devices. The following spi devices are currently supported:

- GoPiGo3 robotics board (built for Rapsberry Pi, but in theory it could be used in another platform)

More drivers are coming soon...

## Using A Different Bus or Address
Expand Down
40 changes: 0 additions & 40 deletions drivers/spi/spi.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,43 +99,3 @@ func (c *SpiConnection) SetMode(mode xspi.Mode) error {
func (c *SpiConnection) Tx(w, r []byte) error {
return c.bus.Tx(w, r)
}

func (c *SpiConnection) ReadBytes(address byte, msg byte, numBytes int) (val []byte, err error) {
w := make([]byte, numBytes)
w[0] = address
w[1] = msg
r := make([]byte, len(w))
err = c.Tx(w, r)
if err != nil {
return val, err
}
return r, nil
}

func (c *SpiConnection) ReadUint8(address, msg byte) (val uint8, err error) {
r, err := c.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint8(r[4]) << 8, nil
}

func (c *SpiConnection) ReadUint16(address, msg byte) (val uint16, err error) {
r, err := c.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint16(r[4])<<8 | uint16(r[5]), nil
}

func (c *SpiConnection) ReadUint32(address, msg byte) (val uint32, err error) {
r, err := c.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint32(r[4])<<24 | uint32(r[5])<<16 | uint32(r[6])<<8 | uint32(r[7]), nil
}

func (c *SpiConnection) WriteBytes(w []byte) (err error) {
return c.Tx(w, nil)
}
41 changes: 41 additions & 0 deletions examples/gopigo3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// +build example
//
// Do not build by default.

package main

import (
"fmt"
"time"

"gobot.io/x/gobot"
g "gobot.io/x/gobot/platforms/gopigo3"
)

func main() {
gopigo3Adaptor := g.NewAdaptor("/dev/spidev0.1", 0, 500000)
gopigo3 := g.NewGoPiGo3Driver(gopigo3Adaptor)

work := func() {
on := uint8(0xFF)
gobot.Every(1000*time.Millisecond, func() {
err := gopigo3.SetLED(g.LED_EYE_RIGHT, 0x00, 0x00, on)
if err != nil {
fmt.Println(err)
}
err = gopigo3.SetLED(g.LED_EYE_LEFT, ^on, 0x00, 0x00)
if err != nil {
fmt.Println(err)
}
on = ^on
})
}

robot := gobot.NewRobot("gopigo3",
[]gobot.Connection{gopigo3Adaptor},
[]gobot.Device{gopigo3},
work,
)

robot.Start()
}
32 changes: 0 additions & 32 deletions examples/raspi_gopigo3.go

This file was deleted.

52 changes: 52 additions & 0 deletions platforms/gopigo3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# GoPiGo3

The GoPiGo3 is a robotics controller by Dexter Industries that is compatible with the Raspberry Pi.

## How to Install

```
go get -d -u gobot.io/x/gobot/...
```

## How to Use
This example will blink the left and right leds red/blue.

```go
package main

import (
"fmt"
"time"

"gobot.io/x/gobot"
g "gobot.io/x/gobot/platforms/gopigo3"
)

func main() {
gopigo3Adaptor := g.NewAdaptor("/dev/spidev0.1", 0, 500000)
gopigo3 := g.NewGoPiGo3Driver(gopigo3Adaptor)

work := func() {
on := uint8(0xFF)
gobot.Every(1000*time.Millisecond, func() {
err := gopigo3.SetLED(g.LED_EYE_RIGHT, 0x00, 0x00, on)
if err != nil {
fmt.Println(err)
}
err = gopigo3.SetLED(g.LED_EYE_LEFT, ^on, 0x00, 0x00)
if err != nil {
fmt.Println(err)
}
on = ^on
})
}

robot := gobot.NewRobot("gopigo3",
[]gobot.Connection{gopigo3Adaptor},
[]gobot.Device{gopigo3},
work,
)

robot.Start()
}
```
133 changes: 133 additions & 0 deletions platforms/gopigo3/gopigo3_adaptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package gopigo3

import (
"time"

"gobot.io/x/gobot"
"gobot.io/x/gobot/drivers/spi"
xspi "golang.org/x/exp/io/spi"
)

var _ gobot.Adaptor = (*Adaptor)(nil)

type Adaptor struct {
name string
port string
spiMode xspi.Mode
maxSpeed int64
connection spi.SPIDevice
writeBytesChannel chan []byte
finalizeChannel chan struct{}
}

func NewAdaptor(port string, mode int, maxSpeed int64) *Adaptor {
var spiMode xspi.Mode
switch mode {
case 0:
spiMode = xspi.Mode0
case 1:
spiMode = xspi.Mode1
case 2:
spiMode = xspi.Mode2
case 3:
spiMode = xspi.Mode3
default:
spiMode = xspi.Mode0
}
return &Adaptor{
name: "GoPiGo3",
port: port,
spiMode: spiMode,
maxSpeed: maxSpeed,
connection: nil,
writeBytesChannel: make(chan []byte),
finalizeChannel: make(chan struct{}),
}
}

func (a *Adaptor) Name() string {
return a.name
}

func (a *Adaptor) SetName(name string) {
a.name = name
}

func (a *Adaptor) Connect() error {
if a.connection == nil {
devfs := &xspi.Devfs{
Dev: a.port,
Mode: a.spiMode,
MaxSpeed: a.maxSpeed,
}
con, err := xspi.Open(devfs)
if err != nil {
return err
}
a.connection = con
}
go func() {
for {
select {
case bytes := <-a.writeBytesChannel:
a.connection.Tx(bytes, nil)
time.Sleep(10 * time.Millisecond)
case <-a.finalizeChannel:
a.finalizeChannel <- struct{}{}
return
default:
time.Sleep(10 * time.Millisecond)
}
}
}()
return nil
}

func (a *Adaptor) Finalize() error {
a.finalizeChannel <- struct{}{}
<-a.finalizeChannel
if err := a.connection.Close(); err != nil {
return err
}
return nil
}

func (a *Adaptor) ReadBytes(address byte, msg byte, numBytes int) (val []byte, err error) {
w := make([]byte, numBytes)
w[0] = address
w[1] = msg
r := make([]byte, len(w))
err = a.connection.Tx(w, r)
if err != nil {
return val, err
}
return r, nil
}

func (a *Adaptor) ReadUint8(address, msg byte) (val uint8, err error) {
r, err := a.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint8(r[4]) << 8, nil
}

func (a *Adaptor) ReadUint16(address, msg byte) (val uint16, err error) {
r, err := a.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint16(r[4])<<8 | uint16(r[5]), nil
}

func (a *Adaptor) ReadUint32(address, msg byte) (val uint32, err error) {
r, err := a.ReadBytes(address, msg, 8)
if err != nil {
return val, err
}
return uint32(r[4])<<24 | uint32(r[5])<<16 | uint32(r[6])<<8 | uint32(r[7]), nil
}

func (a *Adaptor) WriteBytes(w []byte) (err error) {
return a.connection.Tx(w, nil)
}
Loading

0 comments on commit 4bd3b67

Please sign in to comment.