led: support led functionality on the bbb

This commit is contained in:
Karan Misra 2014-03-23 06:25:32 +05:30
parent f7b316332e
commit bf8a4be4d9
9 changed files with 322 additions and 3 deletions

10
bbb.go
View File

@ -16,6 +16,9 @@ func init() {
return newGPIODriver(bbbPins, newDigitalPin, newBBBAnalogPin)
},
I2C: newI2CDriver,
LEDDriver: func() LEDDriver {
return newLEDDriver(bbbLEDMap)
},
}
}
}
@ -88,6 +91,13 @@ var bbbPins = PinMap{
&PinDesc{ID: "P9_40", Aliases: []string{"1", "AIN1"}, Caps: CapAnalog, AnalogLogical: 1},
}
var bbbLEDMap = LEDMap{
"beaglebone:green:usr0": []string{"0", "USR0", "usr0"},
"beaglebone:green:usr1": []string{"1", "USR1", "usr1"},
"beaglebone:green:usr2": []string{"2", "USR2", "usr2"},
"beaglebone:green:usr3": []string{"3", "USR3", "usr3"},
}
type bbbAnalogPin struct {
n int

View File

@ -1,10 +1,14 @@
package embd
import "fmt"
import (
"errors"
"fmt"
)
type Descriptor struct {
GPIO func() GPIO
I2C func() I2C
GPIO func() GPIO
I2C func() I2C
LEDDriver func() LEDDriver
}
type Describer func(rev int) *Descriptor
@ -24,3 +28,5 @@ func DescribeHost() (*Descriptor, error) {
return describer(rev), nil
}
var ErrFeatureNotSupport = errors.New("embd: feature is not supported")

View File

@ -51,6 +51,10 @@ func InitGPIO() error {
return err
}
if desc.GPIO == nil {
return ErrFeatureNotSupport
}
gpioInstance = desc.GPIO()
return nil

4
i2c.go
View File

@ -37,6 +37,10 @@ func InitI2C() error {
return err
}
if desc.I2C == nil {
return ErrFeatureNotSupport
}
i2cInstance = desc.I2C()
return nil

59
led.go Normal file
View File

@ -0,0 +1,59 @@
package embd
type LED interface {
On() error
Off() error
Toggle() error
Close() error
}
type LEDDriver interface {
LED(key interface{}) (LED, error)
Close() error
}
var ledDriverInstance LEDDriver
func InitLED() error {
desc, err := DescribeHost()
if err != nil {
return err
}
if desc.LEDDriver == nil {
return ErrFeatureNotSupport
}
ledDriverInstance = desc.LEDDriver()
return nil
}
func CloseLED() error {
return ledDriverInstance.Close()
}
func NewLED(key interface{}) (LED, error) {
return ledDriverInstance.LED(key)
}
func LEDOn(key interface{}) error {
led, err := NewLED(key)
if err != nil {
return err
}
return led.On()
}
func LEDOff(key interface{}) error {
led, err := NewLED(key)
if err != nil {
return err
}
return led.Off()
}

172
leddriver.go Normal file
View File

@ -0,0 +1,172 @@
package embd
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
)
type LEDMap map[string][]string
type ledDriver struct {
ledMap LEDMap
initializedLEDs map[string]LED
}
func newLEDDriver(ledMap LEDMap) LEDDriver {
return &ledDriver{
ledMap: ledMap,
initializedLEDs: map[string]LED{},
}
}
func (d *ledDriver) lookup(k interface{}) (string, error) {
var ks string
switch key := k.(type) {
case int:
ks = strconv.Itoa(key)
case string:
ks = key
case fmt.Stringer:
ks = key.String()
default:
return "", errors.New("led: invalid key type")
}
for id := range d.ledMap {
for _, alias := range d.ledMap[id] {
if alias == ks {
return id, nil
}
}
}
return "", fmt.Errorf("led: no match found for %q", k)
}
func (d *ledDriver) LED(k interface{}) (LED, error) {
id, err := d.lookup(k)
if err != nil {
return nil, err
}
led := newLED(id)
d.initializedLEDs[id] = led
return led, nil
}
func (d *ledDriver) Close() error {
for _, led := range d.initializedLEDs {
if err := led.Close(); err != nil {
return err
}
}
return nil
}
type led struct {
id string
brightness *os.File
initialized bool
}
func newLED(id string) LED {
return &led{id: id}
}
func (l *led) init() error {
if l.initialized {
return nil
}
var err error
if l.brightness, err = l.brightnessFile(); err != nil {
return err
}
l.initialized = true
return nil
}
func (l *led) brightnessFilePath() string {
return fmt.Sprintf("/sys/class/leds/%v/brightness", l.id)
}
func (l *led) openFile(path string) (*os.File, error) {
return os.OpenFile(path, os.O_RDWR, os.ModeExclusive)
}
func (l *led) brightnessFile() (*os.File, error) {
return l.openFile(l.brightnessFilePath())
}
func (l *led) On() error {
if err := l.init(); err != nil {
return err
}
_, err := l.brightness.WriteString("1")
return err
}
func (l *led) Off() error {
if err := l.init(); err != nil {
return err
}
_, err := l.brightness.WriteString("0")
return err
}
func (l *led) isOn() (bool, error) {
l.brightness.Seek(0, 0)
bytes, err := ioutil.ReadAll(l.brightness)
if err != nil {
return false, err
}
str := string(bytes)
str = strings.TrimSpace(str)
if str == "1" {
return true, nil
}
return false, nil
}
func (l *led) Toggle() error {
if err := l.init(); err != nil {
return err
}
state, err := l.isOn()
if err != nil {
return err
}
if state {
return l.Off()
}
return l.On()
}
func (l *led) Close() error {
if !l.initialized {
return nil
}
if err := l.brightness.Close(); err != nil {
return err
}
l.initialized = false
return nil
}

2
samples/.gitignore vendored
View File

@ -8,6 +8,8 @@ gpiodetect
gpiodirect
gpioshort
l3gd20
led
ledshort
lsm303
mcp4725
pca9685

44
samples/led.go Normal file
View File

@ -0,0 +1,44 @@
// +build ignore
package main
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/kidoman/embd"
)
func main() {
if err := embd.InitLED(); err != nil {
panic(err)
}
defer embd.CloseLED()
led, err := embd.NewLED(3)
if err != nil {
panic(err)
}
defer func() {
led.Off()
led.Close()
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, os.Kill)
defer signal.Stop(quit)
for {
select {
case <-time.After(500 * time.Millisecond):
if err := led.Toggle(); err != nil {
panic(err)
}
fmt.Printf("Toggled\n")
case <-quit:
return
}
}
}

18
samples/ledshort.go Normal file
View File

@ -0,0 +1,18 @@
// +build ignore
package main
import (
"time"
"github.com/kidoman/embd"
)
func main() {
embd.InitLED()
defer embd.CloseLED()
embd.LEDOn(3)
time.Sleep(1 * time.Second)
embd.LEDOff(3)
}