2014-03-23 09:39:31 +01:00
|
|
|
// GPIO support.
|
|
|
|
|
2014-03-02 20:21:23 +01:00
|
|
|
package embd
|
2014-03-01 15:49:44 +01:00
|
|
|
|
2014-04-05 00:36:40 +02:00
|
|
|
import "time"
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// The Direction type indicates the direction of a GPIO pin.
|
2014-02-16 23:11:53 +01:00
|
|
|
type Direction int
|
|
|
|
|
2014-08-31 06:39:41 +02:00
|
|
|
// The Edge trigger for the GPIO Interrupt
|
|
|
|
type Edge string
|
|
|
|
|
2014-02-16 23:11:53 +01:00
|
|
|
const (
|
2014-03-23 09:39:31 +01:00
|
|
|
// In represents read mode.
|
2014-02-26 23:54:53 +01:00
|
|
|
In Direction = iota
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// Out represents write mode.
|
2014-02-26 23:54:53 +01:00
|
|
|
Out
|
2014-02-16 23:11:53 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2014-03-23 09:39:31 +01:00
|
|
|
// Low represents 0.
|
2014-02-26 23:54:53 +01:00
|
|
|
Low int = iota
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// High represents 1.
|
2014-02-16 23:11:53 +01:00
|
|
|
High
|
|
|
|
)
|
|
|
|
|
2014-08-31 06:39:41 +02:00
|
|
|
const (
|
|
|
|
EdgeNone Edge = "none"
|
|
|
|
EdgeRising Edge = "rising"
|
|
|
|
EdgeFalling Edge = "falling"
|
|
|
|
EdgeBoth Edge = "both"
|
|
|
|
)
|
|
|
|
|
2016-09-09 08:28:20 +02:00
|
|
|
// 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.
|
2014-08-31 06:39:41 +02:00
|
|
|
type InterruptPin interface {
|
|
|
|
|
|
|
|
// Start watching this pin for interrupt
|
|
|
|
Watch(edge Edge, handler func(DigitalPin)) error
|
|
|
|
|
|
|
|
// Stop watching this pin for interrupt
|
|
|
|
StopWatching() error
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// DigitalPin implements access to a digital IO capable GPIO pin.
|
2014-02-26 23:54:53 +01:00
|
|
|
type DigitalPin interface {
|
2014-08-31 06:39:41 +02:00
|
|
|
InterruptPin
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// N returns the logical GPIO number.
|
2014-03-23 00:29:35 +01:00
|
|
|
N() int
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// Write writes the provided value to the pin.
|
2014-02-26 23:54:53 +01:00
|
|
|
Write(val int) error
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// Read reads the value from the pin.
|
2014-02-26 23:54:53 +01:00
|
|
|
Read() (int, error)
|
2014-02-16 23:11:53 +01:00
|
|
|
|
2014-04-05 00:36:40 +02:00
|
|
|
// TimePulse measures the duration of a pulse on the pin.
|
|
|
|
TimePulse(state int) (time.Duration, error)
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// SetDirection sets the direction of the pin (in/out).
|
2014-03-01 15:49:44 +01:00
|
|
|
SetDirection(dir Direction) error
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// ActiveLow makes the pin active low. A low logical state is represented by
|
|
|
|
// a high state on the physical pin, and vice-versa.
|
2014-02-26 23:54:53 +01:00
|
|
|
ActiveLow(b bool) error
|
2014-02-16 23:11:53 +01:00
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// PullUp pulls the pin up.
|
2014-03-02 07:39:57 +01:00
|
|
|
PullUp() error
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// PullDown pulls the pin down.
|
2014-03-02 07:39:57 +01:00
|
|
|
PullDown() error
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// Close releases the resources associated with the pin.
|
2014-02-26 23:54:53 +01:00
|
|
|
Close() error
|
2014-02-16 23:11:53 +01:00
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// AnalogPin implements access to a analog IO capable GPIO pin.
|
2014-03-23 00:29:35 +01:00
|
|
|
type AnalogPin interface {
|
2014-03-23 09:39:31 +01:00
|
|
|
// N returns the logical GPIO number.
|
2014-03-23 00:29:35 +01:00
|
|
|
N() int
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// Read reads the value from the pin.
|
2014-03-23 00:29:35 +01:00
|
|
|
Read() (int, error)
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// Close releases the resources associated with the pin.
|
2014-03-23 00:29:35 +01:00
|
|
|
Close() error
|
|
|
|
}
|
|
|
|
|
2014-03-28 03:54:42 +01:00
|
|
|
// 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
|
|
|
|
|
2014-04-02 13:55:28 +02:00
|
|
|
// 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
|
|
|
|
|
2014-03-28 03:54:42 +01:00
|
|
|
// Close releases the resources associated with the pin.
|
|
|
|
Close() error
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// GPIODriver implements a generic GPIO driver.
|
2014-03-23 02:02:24 +01:00
|
|
|
type GPIODriver interface {
|
2015-01-15 01:29:03 +01:00
|
|
|
// PinMap returns the pinmap for this driver.
|
2015-01-13 22:55:11 +01:00
|
|
|
PinMap() PinMap
|
|
|
|
|
2014-04-06 02:00:54 +02:00
|
|
|
// Unregister unregisters the pin from the driver. Should be called when the pin is closed.
|
|
|
|
Unregister(string) error
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// DigitalPin returns a pin capable of doing digital IO.
|
2014-02-26 23:54:53 +01:00
|
|
|
DigitalPin(key interface{}) (DigitalPin, error)
|
2014-03-23 09:39:31 +01:00
|
|
|
|
|
|
|
// AnalogPin returns a pin capable of doing analog IO.
|
2014-03-23 00:29:35 +01:00
|
|
|
AnalogPin(key interface{}) (AnalogPin, error)
|
2014-02-16 23:11:53 +01:00
|
|
|
|
2014-03-28 03:54:42 +01:00
|
|
|
// PWMPin returns a pin capable of generating PWM.
|
|
|
|
PWMPin(key interface{}) (PWMPin, error)
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// Close releases the resources associated with the driver.
|
2014-02-26 23:54:53 +01:00
|
|
|
Close() error
|
2014-02-16 23:11:53 +01:00
|
|
|
}
|
2014-03-01 15:49:44 +01:00
|
|
|
|
2014-04-11 05:49:03 +02:00
|
|
|
var gpioDriverInitialized bool
|
2014-03-23 02:02:24 +01:00
|
|
|
var gpioDriverInstance GPIODriver
|
2014-03-01 15:49:44 +01:00
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// InitGPIO initializes the GPIO driver.
|
2014-03-02 20:21:23 +01:00
|
|
|
func InitGPIO() error {
|
2014-04-11 05:49:03 +02:00
|
|
|
if gpioDriverInitialized {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-03-02 20:21:23 +01:00
|
|
|
desc, err := DescribeHost()
|
2014-03-01 15:49:44 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-03-23 02:02:24 +01:00
|
|
|
if desc.GPIODriver == nil {
|
2014-03-23 02:11:51 +01:00
|
|
|
return ErrFeatureNotSupported
|
2014-03-23 01:55:32 +01:00
|
|
|
}
|
|
|
|
|
2014-03-23 02:02:24 +01:00
|
|
|
gpioDriverInstance = desc.GPIODriver()
|
2014-04-11 05:49:03 +02:00
|
|
|
gpioDriverInitialized = true
|
2014-03-01 15:49:44 +01:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// CloseGPIO releases resources associated with the GPIO driver.
|
2014-03-02 20:21:23 +01:00
|
|
|
func CloseGPIO() error {
|
2014-03-23 02:02:24 +01:00
|
|
|
return gpioDriverInstance.Close()
|
2014-03-01 15:49:44 +01:00
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// NewDigitalPin returns a DigitalPin interface which allows control over
|
|
|
|
// the digital GPIO pin.
|
2014-03-01 15:49:44 +01:00
|
|
|
func NewDigitalPin(key interface{}) (DigitalPin, error) {
|
2014-04-11 05:49:03 +02:00
|
|
|
if err := InitGPIO(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-03-23 02:02:24 +01:00
|
|
|
return gpioDriverInstance.DigitalPin(key)
|
2014-03-01 15:49:44 +01:00
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// DigitalWrite writes val to the pin.
|
2014-03-01 15:49:44 +01:00
|
|
|
func DigitalWrite(key interface{}, val int) error {
|
|
|
|
pin, err := NewDigitalPin(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return pin.Write(val)
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// DigitalRead reads a value from the pin.
|
2014-03-01 15:49:44 +01:00
|
|
|
func DigitalRead(key interface{}) (int, error) {
|
|
|
|
pin, err := NewDigitalPin(key)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return pin.Read()
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// SetDirection sets the direction of the pin (in/out).
|
2014-03-01 15:49:44 +01:00
|
|
|
func SetDirection(key interface{}, dir Direction) error {
|
|
|
|
pin, err := NewDigitalPin(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return pin.SetDirection(dir)
|
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// ActiveLow makes the pin active low. A low logical state is represented by
|
|
|
|
// a high state on the physical pin, and vice-versa.
|
2014-03-01 15:49:44 +01:00
|
|
|
func ActiveLow(key interface{}, b bool) error {
|
|
|
|
pin, err := NewDigitalPin(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return pin.ActiveLow(b)
|
|
|
|
}
|
2014-03-23 00:29:35 +01:00
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// 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.
|
2014-03-23 00:29:35 +01:00
|
|
|
func NewAnalogPin(key interface{}) (AnalogPin, error) {
|
2014-04-11 05:49:03 +02:00
|
|
|
if err := InitGPIO(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-03-23 02:02:24 +01:00
|
|
|
return gpioDriverInstance.AnalogPin(key)
|
2014-03-23 00:29:35 +01:00
|
|
|
}
|
|
|
|
|
2014-03-23 09:39:31 +01:00
|
|
|
// AnalogWrite reads a value from the pin.
|
2014-03-23 00:29:35 +01:00
|
|
|
func AnalogRead(key interface{}) (int, error) {
|
|
|
|
pin, err := NewAnalogPin(key)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return pin.Read()
|
|
|
|
}
|
2014-03-28 03:54:42 +01:00
|
|
|
|
|
|
|
// NewPWMPin returns a PWMPin interface which allows PWM signal
|
|
|
|
// generation over a the PWM pin.
|
|
|
|
func NewPWMPin(key interface{}) (PWMPin, error) {
|
2014-04-11 05:49:03 +02:00
|
|
|
if err := InitGPIO(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-03-28 03:54:42 +01:00
|
|
|
return gpioDriverInstance.PWMPin(key)
|
|
|
|
}
|