2014-11-04 17:14:36 -08:00
|
|
|
package raspi
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/hybridgroup/gobot"
|
|
|
|
"github.com/hybridgroup/gobot/sysfs"
|
|
|
|
)
|
|
|
|
|
2014-11-07 16:57:05 -08:00
|
|
|
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"
|
|
|
|
}
|
2014-11-07 16:57:05 -08:00
|
|
|
|
|
|
|
if rev == "1" {
|
|
|
|
return rev, "/dev/i2c-0"
|
|
|
|
}
|
|
|
|
return rev, "/dev/i2c-1"
|
2014-11-04 17:14:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
type RaspiAdaptor struct {
|
|
|
|
gobot.Adaptor
|
|
|
|
revision string
|
2014-11-07 16:57:05 -08:00
|
|
|
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 {
|
2014-11-07 16:57:05 -08:00
|
|
|
r := &RaspiAdaptor{
|
2014-11-04 17:14:36 -08:00
|
|
|
Adaptor: *gobot.NewAdaptor(
|
|
|
|
name,
|
|
|
|
"RaspiAdaptor",
|
|
|
|
),
|
|
|
|
digitalPins: make(map[int]sysfs.DigitalPin),
|
|
|
|
}
|
2014-11-07 16:57:05 -08:00
|
|
|
rev, i2cLoc := boardRevision()
|
|
|
|
r.revision = rev
|
|
|
|
r.i2cLocation = i2cLoc
|
|
|
|
return r
|
2014-11-04 17:14:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Connect starts conection with board and creates
|
|
|
|
// digitalPins and pwmPins adaptor maps
|
|
|
|
func (r *RaspiAdaptor) Connect() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finalize closes connection to board and pins
|
|
|
|
func (r *RaspiAdaptor) Finalize() bool {
|
|
|
|
for _, pin := range r.digitalPins {
|
|
|
|
if pin != nil {
|
|
|
|
pin.Unexport()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.i2cDevice != nil {
|
|
|
|
r.i2cDevice.Close()
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// digitalPin returns matched digitalPin for specified values
|
|
|
|
func (r *RaspiAdaptor) digitalPin(pin string, dir string) sysfs.DigitalPin {
|
|
|
|
var i int
|
|
|
|
|
|
|
|
if val, ok := pins[pin][r.revision]; ok {
|
|
|
|
i = val
|
|
|
|
} else if val, ok := pins[pin]["*"]; ok {
|
|
|
|
i = val
|
|
|
|
} else {
|
|
|
|
panic("not valid pin")
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.digitalPins[i] == nil {
|
|
|
|
r.digitalPins[i] = sysfs.NewDigitalPin(i)
|
|
|
|
r.digitalPins[i].Export()
|
|
|
|
}
|
|
|
|
|
|
|
|
r.digitalPins[i].Direction(dir)
|
|
|
|
|
|
|
|
return r.digitalPins[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
// DigitalRead reads digital value from pin
|
|
|
|
func (r *RaspiAdaptor) DigitalRead(pin string) (i int) {
|
|
|
|
i, _ = r.digitalPin(pin, sysfs.IN).Read()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// DigitalWrite writes digital value to specified pin
|
|
|
|
func (r *RaspiAdaptor) DigitalWrite(pin string, val byte) {
|
|
|
|
r.digitalPin(pin, sysfs.OUT).Write(int(val))
|
|
|
|
}
|
|
|
|
|
|
|
|
// PwmWrite Not Implemented
|
|
|
|
func (r *RaspiAdaptor) PwmWrite(pin string, val byte) {
|
|
|
|
fmt.Println("PwmWrite Is Not Implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
// I2cStart starts a i2c device in specified address
|
|
|
|
func (r *RaspiAdaptor) I2cStart(address byte) {
|
2014-11-07 16:57:05 -08:00
|
|
|
r.i2cDevice, _ = sysfs.NewI2cDevice(r.i2cLocation, address)
|
2014-11-04 17:14:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// I2CWrite writes data to i2c device
|
|
|
|
func (r *RaspiAdaptor) I2cWrite(data []byte) {
|
|
|
|
r.i2cDevice.Write(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// I2cRead returns value from i2c device using specified size
|
|
|
|
func (r *RaspiAdaptor) I2cRead(size uint) []byte {
|
|
|
|
buf := make([]byte, size)
|
|
|
|
r.i2cDevice.Read(buf)
|
|
|
|
return buf
|
|
|
|
}
|