embd/gpio.go

280 lines
6.1 KiB
Go

// GPIO support.
package embd
import "time"
// The Direction type indicates the direction of a GPIO pin.
type Direction int
// The Edge trigger for the GPIO Interrupt
type Edge string
const (
// In represents read mode.
In Direction = iota
// Out represents write mode.
Out
)
const (
// Low represents 0.
Low int = iota
// High represents 1.
High
)
const (
EdgeNone Edge = "none"
EdgeRising Edge = "rising"
EdgeFalling Edge = "falling"
EdgeBoth Edge = "both"
)
// InterruptPin implements access to an interrupt capable GPIO pin.
// The basic capability provided is to watch for a transition on the pin and
// generate a callback to a handler when a transition occurs.
// On Linux the underlying implementation generally uses epoll to receive the
// interrupts at user-level.
type InterruptPin interface {
// Start watching this pin for interrupt
Watch(edge Edge, handler func(DigitalPin)) error
// Stop watching this pin for interrupt
StopWatching() error
}
// DigitalPin implements access to a digital IO capable GPIO pin.
type DigitalPin interface {
InterruptPin
// N returns the logical GPIO number.
N() int
// Write writes the provided value to the pin.
Write(val int) error
// Read reads the value from the pin.
Read() (int, error)
// TimePulse measures the duration of a pulse on the pin.
TimePulse(state int) (time.Duration, error)
// SetDirection sets the direction of the pin (in/out).
SetDirection(dir Direction) error
// ActiveLow makes the pin active low. A low logical state is represented by
// a high state on the physical pin, and vice-versa.
ActiveLow(b bool) error
// PullUp pulls the pin up.
PullUp() error
// PullDown pulls the pin down.
PullDown() error
// Close releases the resources associated with the pin.
Close() error
}
// AnalogPin implements access to a analog IO capable GPIO pin.
type AnalogPin interface {
// N returns the logical GPIO number.
N() int
// Read reads the value from the pin.
Read() (int, error)
// Close releases the resources associated with the pin.
Close() error
}
// The Polarity type indicates the polarity of a pwm pin.
type Polarity int
const (
// Positive represents (default) positive polarity.
Positive Polarity = iota
// Negative represents negative polarity.
Negative
)
// PWMPin implements access to a pwm capable GPIO pin.
type PWMPin interface {
// N returns the logical PWM id.
N() string
// SetPeriod sets the period of a pwm pin.
SetPeriod(ns int) error
// SetDuty sets the duty of a pwm pin.
SetDuty(ns int) error
// SetPolarity sets the polarity of a pwm pin.
SetPolarity(pol Polarity) error
// SetMicroseconds sends a command to the PWM driver to generate a us wide pulse.
SetMicroseconds(us int) error
// SetAnalog allows easy manipulation of the PWM based on a (0-255) range value.
SetAnalog(value byte) error
// Close releases the resources associated with the pin.
Close() error
}
// GPIODriver implements a generic GPIO driver.
type GPIODriver interface {
// PinMap returns the pinmap for this driver.
PinMap() PinMap
// Unregister unregisters the pin from the driver. Should be called when the pin is closed.
Unregister(string) error
// DigitalPin returns a pin capable of doing digital IO.
DigitalPin(key interface{}) (DigitalPin, error)
// AnalogPin returns a pin capable of doing analog IO.
AnalogPin(key interface{}) (AnalogPin, error)
// PWMPin returns a pin capable of generating PWM.
PWMPin(key interface{}) (PWMPin, error)
// Close releases the resources associated with the driver.
Close() error
}
var gpioDriverInitialized bool
var gpioDriverInstance GPIODriver
// InitGPIO initializes the GPIO driver.
func InitGPIO() error {
if gpioDriverInitialized {
return nil
}
desc, err := DescribeHost()
if err != nil {
return err
}
if desc.GPIODriver == nil {
return ErrFeatureNotSupported
}
gpioDriverInstance = desc.GPIODriver()
gpioDriverInitialized = true
return nil
}
// CloseGPIO releases resources associated with the GPIO driver.
func CloseGPIO() error {
return gpioDriverInstance.Close()
}
// NewDigitalPin returns a DigitalPin interface which allows control over
// the digital GPIO pin.
func NewDigitalPin(key interface{}) (DigitalPin, error) {
if err := InitGPIO(); err != nil {
return nil, err
}
return gpioDriverInstance.DigitalPin(key)
}
// DigitalWrite writes val to the pin.
func DigitalWrite(key interface{}, val int) error {
pin, err := NewDigitalPin(key)
if err != nil {
return err
}
return pin.Write(val)
}
// DigitalRead reads a value from the pin.
func DigitalRead(key interface{}) (int, error) {
pin, err := NewDigitalPin(key)
if err != nil {
return 0, err
}
return pin.Read()
}
// SetDirection sets the direction of the pin (in/out).
func SetDirection(key interface{}, dir Direction) error {
pin, err := NewDigitalPin(key)
if err != nil {
return err
}
return pin.SetDirection(dir)
}
// ActiveLow makes the pin active low. A low logical state is represented by
// a high state on the physical pin, and vice-versa.
func ActiveLow(key interface{}, b bool) error {
pin, err := NewDigitalPin(key)
if err != nil {
return err
}
return pin.ActiveLow(b)
}
// PullUp pulls the pin up.
func PullUp(key interface{}) error {
pin, err := NewDigitalPin(key)
if err != nil {
return err
}
return pin.PullUp()
}
// PullDown pulls the pin down.
func PullDown(key interface{}) error {
pin, err := NewDigitalPin(key)
if err != nil {
return err
}
return pin.PullDown()
}
// NewAnalogPin returns a AnalogPin interface which allows control over
// the analog GPIO pin.
func NewAnalogPin(key interface{}) (AnalogPin, error) {
if err := InitGPIO(); err != nil {
return nil, err
}
return gpioDriverInstance.AnalogPin(key)
}
// AnalogWrite reads a value from the pin.
func AnalogRead(key interface{}) (int, error) {
pin, err := NewAnalogPin(key)
if err != nil {
return 0, err
}
return pin.Read()
}
// NewPWMPin returns a PWMPin interface which allows PWM signal
// generation over a the PWM pin.
func NewPWMPin(key interface{}) (PWMPin, error) {
if err := InitGPIO(); err != nil {
return nil, err
}
return gpioDriverInstance.PWMPin(key)
}