1
0
mirror of https://github.com/kidoman/embd synced 2024-06-15 15:19:52 +02:00

Refactored Interruptable GPIO codes

Created two new Interface and hid implementation details as much as possible.
This commit is contained in:
SjB 2014-04-09 00:01:05 -04:00
parent a54e7dc7ff
commit 919b01a3a2
3 changed files with 43 additions and 16 deletions

40
gpio.go
View File

@ -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

View File

@ -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
} }

View File

@ -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() {