mirror of
https://github.com/kidoman/embd
synced 2024-09-21 23:11:40 +02:00
Refactored Interruptable GPIO codes
Created two new Interface and hid implementation details as much as possible.
This commit is contained in:
parent
a54e7dc7ff
commit
919b01a3a2
40
gpio.go
40
gpio.go
@ -23,9 +23,13 @@ const (
|
|||||||
High
|
High
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Edge trigger for GPIO Interrupt
|
||||||
type Edge string
|
type Edge string
|
||||||
|
|
||||||
|
// IRQ event function definition
|
||||||
type IRQEvent func(pin DigitalPin)
|
type IRQEvent func(pin DigitalPin)
|
||||||
|
|
||||||
|
// Available Edge trigger for Interrupt
|
||||||
const (
|
const (
|
||||||
EdgeNone Edge = "none"
|
EdgeNone Edge = "none"
|
||||||
EdgeRising Edge = "rising"
|
EdgeRising Edge = "rising"
|
||||||
@ -33,8 +37,25 @@ const (
|
|||||||
EdgeBoth Edge = "both"
|
EdgeBoth Edge = "both"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// InterruptPin implements access to a Interruptable capable GPIO pin.
|
||||||
|
type InterruptPin interface {
|
||||||
|
// return file handler for GPIO
|
||||||
|
Fd() int
|
||||||
|
|
||||||
|
// Start watching this pin for interrupt
|
||||||
|
Watch(edge Edge, callback IRQEvent) error
|
||||||
|
|
||||||
|
// Stop watching this pin for interrupt
|
||||||
|
StopWatching() error
|
||||||
|
|
||||||
|
// Signal that an Interrupt has happened
|
||||||
|
Signal()
|
||||||
|
}
|
||||||
|
|
||||||
// DigitalPin implements access to a digital IO capable GPIO pin.
|
// DigitalPin implements access to a digital IO capable GPIO pin.
|
||||||
type DigitalPin interface {
|
type DigitalPin interface {
|
||||||
|
InterruptPin
|
||||||
|
|
||||||
// N returns the logical GPIO number.
|
// N returns the logical GPIO number.
|
||||||
N() int
|
N() int
|
||||||
|
|
||||||
@ -60,11 +81,6 @@ type DigitalPin interface {
|
|||||||
// PullDown pulls the pin down.
|
// PullDown pulls the pin down.
|
||||||
PullDown() error
|
PullDown() error
|
||||||
|
|
||||||
Watch(edge Edge, callback IRQEvent) error
|
|
||||||
StopWatching() error
|
|
||||||
|
|
||||||
Signal()
|
|
||||||
|
|
||||||
// Close releases the resources associated with the pin.
|
// Close releases the resources associated with the pin.
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
@ -116,13 +132,17 @@ type PWMPin interface {
|
|||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GPIOInterrupt interface {
|
||||||
|
// Register a pin as an interrupt
|
||||||
|
RegisterInterrupt(p InterruptPin) error
|
||||||
|
|
||||||
|
// Unregister a pin as an interrupt
|
||||||
|
UnregisterInterrupt(p InterruptPin) error
|
||||||
|
}
|
||||||
|
|
||||||
// GPIODriver implements a generic GPIO driver.
|
// GPIODriver implements a generic GPIO driver.
|
||||||
type GPIODriver interface {
|
type GPIODriver interface {
|
||||||
// Register a pin as an interrupt pin
|
GPIOInterrupt
|
||||||
RegisterInterrupt(fd int, p DigitalPin) error
|
|
||||||
|
|
||||||
// Unregister the file handler from the Interrupt handler
|
|
||||||
UnregisterInterrupt(fd int) error
|
|
||||||
|
|
||||||
// Unregister unregisters the pin from the driver. Should be called when the pin is closed.
|
// Unregister unregisters the pin from the driver. Should be called when the pin is closed.
|
||||||
Unregister(string) error
|
Unregister(string) error
|
||||||
|
@ -27,7 +27,7 @@ type gpioDriver struct {
|
|||||||
apf analogPinFactory
|
apf analogPinFactory
|
||||||
ppf pwmPinFactory
|
ppf pwmPinFactory
|
||||||
|
|
||||||
watchEventCallbacks map[int]DigitalPin
|
watchEventCallbacks map[int]InterruptPin
|
||||||
initializedPins map[string]pin
|
initializedPins map[string]pin
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ func NewGPIODriver(pinMap PinMap, dpf digitalPinFactory, apf analogPinFactory, p
|
|||||||
apf: apf,
|
apf: apf,
|
||||||
ppf: ppf,
|
ppf: ppf,
|
||||||
|
|
||||||
watchEventCallbacks: map[int]DigitalPin{},
|
watchEventCallbacks: map[int]InterruptPin{},
|
||||||
initializedPins: map[string]pin{},
|
initializedPins: map[string]pin{},
|
||||||
}
|
}
|
||||||
return driver
|
return driver
|
||||||
@ -72,12 +72,14 @@ func (io *gpioDriver) initializeEpoll() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (io *gpioDriver) RegisterInterrupt(fd int, p DigitalPin) error {
|
func (io *gpioDriver) RegisterInterrupt(p InterruptPin) error {
|
||||||
|
|
||||||
if epollFD == 0 {
|
if epollFD == 0 {
|
||||||
io.initializeEpoll()
|
io.initializeEpoll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd := p.Fd()
|
||||||
|
|
||||||
var event syscall.EpollEvent
|
var event syscall.EpollEvent
|
||||||
event.Events = syscall.EPOLLIN | (syscall.EPOLLET & 0xffffffff) | syscall.EPOLLPRI
|
event.Events = syscall.EPOLLIN | (syscall.EPOLLET & 0xffffffff) | syscall.EPOLLPRI
|
||||||
|
|
||||||
@ -96,8 +98,9 @@ func (io *gpioDriver) RegisterInterrupt(fd int, p DigitalPin) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (io *gpioDriver) UnregisterInterrupt(fd int) error {
|
func (io *gpioDriver) UnregisterInterrupt(p InterruptPin) error {
|
||||||
|
|
||||||
|
fd := p.Fd()
|
||||||
if err := syscall.EpollCtl(epollFD, syscall.EPOLL_CTL_DEL, fd, nil); err != nil {
|
if err := syscall.EpollCtl(epollFD, syscall.EPOLL_CTL_DEL, fd, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,10 @@ func (p *digitalPin) activeLowFile() (*os.File, error) {
|
|||||||
return p.openFile(path.Join(p.basePath(), "active_low"))
|
return p.openFile(path.Join(p.basePath(), "active_low"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *digitalPin) Fd() int {
|
||||||
|
return int(p.val.Fd())
|
||||||
|
}
|
||||||
|
|
||||||
func (p *digitalPin) setEdge(edge embd.Edge) error {
|
func (p *digitalPin) setEdge(edge embd.Edge) error {
|
||||||
file, err := p.openFile(path.Join(p.basePath(), "edge"))
|
file, err := p.openFile(path.Join(p.basePath(), "edge"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -127,11 +131,11 @@ func (p *digitalPin) Watch(edge embd.Edge, callback embd.IRQEvent) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.callback = callback
|
p.callback = callback
|
||||||
return p.drv.RegisterInterrupt(int(p.val.Fd()), p)
|
return p.drv.RegisterInterrupt(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *digitalPin) StopWatching() error {
|
func (p *digitalPin) StopWatching() error {
|
||||||
return p.drv.UnregisterInterrupt(int(p.val.Fd()))
|
return p.drv.UnregisterInterrupt(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *digitalPin) Signal() {
|
func (p *digitalPin) Signal() {
|
||||||
|
Loading…
Reference in New Issue
Block a user