1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-05-02 22:17:12 +08:00
hybridgroup.gobot/platforms/raspi/raspi_adaptor.go

247 lines
4.5 KiB
Go
Raw Normal View History

2014-11-04 17:14:36 -08:00
package raspi
import (
"errors"
2014-11-04 17:14:36 -08:00
"fmt"
"io"
"io/ioutil"
"os/exec"
"strconv"
"strings"
"github.com/hybridgroup/gobot"
"github.com/hybridgroup/gobot/sysfs"
)
var _ gobot.Adaptor = (*RaspiAdaptor)(nil)
var boardRevision = func() (string, string) {
2014-11-04 17:14:36 -08:00
cat, _ := exec.Command("cat", "/proc/cpuinfo").Output()
grep := exec.Command("grep", "Revision")
in, _ := grep.StdinPipe()
out, _ := grep.StdoutPipe()
grep.Start()
in.Write([]byte(string(cat)))
in.Close()
buf, _ := ioutil.ReadAll(out)
grep.Wait()
s := strings.Split(string(buf), " ")
a := fmt.Sprintf("0x%v", strings.TrimSuffix(s[len(s)-1], "\n"))
d, _ := strconv.ParseInt(a, 0, 64)
rev := ""
if d <= 3 {
rev = "1"
} else if d <= 15 {
rev = "2"
} else {
rev = "3"
}
if rev == "1" {
return rev, "/dev/i2c-0"
}
return rev, "/dev/i2c-1"
2014-11-04 17:14:36 -08:00
}
type RaspiAdaptor struct {
name string
2014-11-04 17:14:36 -08:00
revision string
i2cLocation string
2014-11-04 17:14:36 -08:00
digitalPins map[int]sysfs.DigitalPin
i2cDevice io.ReadWriteCloser
}
var pins = map[string]map[string]int{
"3": map[string]int{
"1": 0,
"2": 2,
"3": 2,
},
"5": map[string]int{
"1": 1,
"2": 3,
"3": 3,
},
"7": map[string]int{
"*": 4,
},
"8": map[string]int{
"*": 14,
},
"10": map[string]int{
"*": 15,
},
"11": map[string]int{
"*": 17,
},
"12": map[string]int{
"*": 18,
},
"13": map[string]int{
"1": 21,
"2": 27,
"3": 27,
},
"15": map[string]int{
"*": 22,
},
"16": map[string]int{
"*": 23,
},
"18": map[string]int{
"*": 24,
},
"19": map[string]int{
"*": 10,
},
"21": map[string]int{
"*": 9,
},
"22": map[string]int{
"*": 25,
},
"23": map[string]int{
"*": 11,
},
"24": map[string]int{
"*": 8,
},
"26": map[string]int{
"*": 7,
},
"29": map[string]int{
"3": 5,
},
"31": map[string]int{
"3": 6,
},
"32": map[string]int{
"3": 12,
},
"33": map[string]int{
"3": 13,
},
"35": map[string]int{
"3": 19,
},
"36": map[string]int{
"3": 16,
},
"37": map[string]int{
"3": 26,
},
"38": map[string]int{
"3": 20,
},
"40": map[string]int{
"3": 21,
},
}
// NewRaspiAdaptor creates a RaspiAdaptor with specified name and
func NewRaspiAdaptor(name string) *RaspiAdaptor {
r := &RaspiAdaptor{
name: name,
2014-11-04 17:14:36 -08:00
digitalPins: make(map[int]sysfs.DigitalPin),
}
rev, i2cLoc := boardRevision()
r.revision = rev
r.i2cLocation = i2cLoc
return r
2014-11-04 17:14:36 -08:00
}
func (r *RaspiAdaptor) Name() string { return r.name }
2014-11-04 17:14:36 -08:00
// Connect starts conection with board and creates
// digitalPins and pwmPins adaptor maps
func (r *RaspiAdaptor) Connect() (errs []error) {
return
2014-11-04 17:14:36 -08:00
}
// Finalize closes connection to board and pins
func (r *RaspiAdaptor) Finalize() (errs []error) {
2014-11-04 17:14:36 -08:00
for _, pin := range r.digitalPins {
if pin != nil {
if err := pin.Unexport(); err != nil {
errs = append(errs, err)
}
2014-11-04 17:14:36 -08:00
}
}
if r.i2cDevice != nil {
if err := r.i2cDevice.Close(); err != nil {
errs = append(errs, err)
}
2014-11-04 17:14:36 -08:00
}
return errs
2014-11-04 17:14:36 -08:00
}
// digitalPin returns matched digitalPin for specified values
func (r *RaspiAdaptor) digitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPin, err error) {
2014-11-04 17:14:36 -08:00
var i int
if val, ok := pins[pin][r.revision]; ok {
i = val
} else if val, ok := pins[pin]["*"]; ok {
i = val
} else {
err = errors.New("Not a valid pin")
return
2014-11-04 17:14:36 -08:00
}
if r.digitalPins[i] == nil {
r.digitalPins[i] = sysfs.NewDigitalPin(i)
if err = r.digitalPins[i].Export(); err != nil {
return
}
2014-11-04 17:14:36 -08:00
}
if err = r.digitalPins[i].Direction(dir); err != nil {
return
}
2014-11-04 17:14:36 -08:00
return r.digitalPins[i], nil
2014-11-04 17:14:36 -08:00
}
// DigitalRead reads digital value from pin
func (r *RaspiAdaptor) DigitalRead(pin string) (val int, err error) {
sysfsPin, err := r.digitalPin(pin, sysfs.IN)
if err != nil {
return
}
return sysfsPin.Read()
2014-11-04 17:14:36 -08:00
}
// DigitalWrite writes digital value to specified pin
func (r *RaspiAdaptor) DigitalWrite(pin string, val byte) (err error) {
sysfsPin, err := r.digitalPin(pin, sysfs.OUT)
if err != nil {
return err
}
return sysfsPin.Write(int(val))
2014-11-04 17:14:36 -08:00
}
// PwmWrite Not Implemented
func (r *RaspiAdaptor) PwmWrite(pin string, val byte) (err error) {
return errors.New("PwmWrite is not yet implemented.")
2014-11-04 17:14:36 -08:00
}
// I2cStart starts a i2c device in specified address
func (r *RaspiAdaptor) I2cStart(address byte) (err error) {
r.i2cDevice, err = sysfs.NewI2cDevice(r.i2cLocation, address)
return err
2014-11-04 17:14:36 -08:00
}
// I2CWrite writes data to i2c device
func (r *RaspiAdaptor) I2cWrite(data []byte) (err error) {
_, err = r.i2cDevice.Write(data)
return
2014-11-04 17:14:36 -08:00
}
// I2cRead returns value from i2c device using specified size
func (r *RaspiAdaptor) I2cRead(size uint) (data []byte, err error) {
data = make([]byte, size)
_, err = r.i2cDevice.Read(data)
return
2014-11-04 17:14:36 -08:00
}