diff --git a/gpio.go b/gpio.go index 8e363fe..ab67ff7 100644 --- a/gpio.go +++ b/gpio.go @@ -23,9 +23,13 @@ const ( High ) +// Edge trigger for GPIO Interrupt type Edge string + +// IRQ event function definition type IRQEvent func(pin DigitalPin) +// Available Edge trigger for Interrupt const ( EdgeNone Edge = "none" EdgeRising Edge = "rising" @@ -33,8 +37,25 @@ const ( 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. type DigitalPin interface { + InterruptPin + // N returns the logical GPIO number. N() int @@ -60,11 +81,6 @@ type DigitalPin interface { // PullDown pulls the pin down. PullDown() error - Watch(edge Edge, callback IRQEvent) error - StopWatching() error - - Signal() - // Close releases the resources associated with the pin. Close() error } @@ -116,13 +132,17 @@ type PWMPin interface { 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. type GPIODriver interface { - // Register a pin as an interrupt pin - RegisterInterrupt(fd int, p DigitalPin) error - - // Unregister the file handler from the Interrupt handler - UnregisterInterrupt(fd int) error + GPIOInterrupt // Unregister unregisters the pin from the driver. Should be called when the pin is closed. Unregister(string) error diff --git a/gpiodriver.go b/gpiodriver.go index 3b3f3cf..a555497 100644 --- a/gpiodriver.go +++ b/gpiodriver.go @@ -27,7 +27,7 @@ type gpioDriver struct { apf analogPinFactory ppf pwmPinFactory - watchEventCallbacks map[int]DigitalPin + watchEventCallbacks map[int]InterruptPin initializedPins map[string]pin } @@ -40,7 +40,7 @@ func NewGPIODriver(pinMap PinMap, dpf digitalPinFactory, apf analogPinFactory, p apf: apf, ppf: ppf, - watchEventCallbacks: map[int]DigitalPin{}, + watchEventCallbacks: map[int]InterruptPin{}, initializedPins: map[string]pin{}, } 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 { io.initializeEpoll() } + fd := p.Fd() + var event syscall.EpollEvent event.Events = syscall.EPOLLIN | (syscall.EPOLLET & 0xffffffff) | syscall.EPOLLPRI @@ -96,8 +98,9 @@ func (io *gpioDriver) RegisterInterrupt(fd int, p DigitalPin) error { 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 { return err } diff --git a/host/generic/digitalpin.go b/host/generic/digitalpin.go index 3abd05f..1a50d5c 100644 --- a/host/generic/digitalpin.go +++ b/host/generic/digitalpin.go @@ -111,6 +111,10 @@ func (p *digitalPin) activeLowFile() (*os.File, error) { 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 { file, err := p.openFile(path.Join(p.basePath(), "edge")) if err != nil { @@ -127,11 +131,11 @@ func (p *digitalPin) Watch(edge embd.Edge, callback embd.IRQEvent) error { return err } p.callback = callback - return p.drv.RegisterInterrupt(int(p.val.Fd()), p) + return p.drv.RegisterInterrupt(p) } func (p *digitalPin) StopWatching() error { - return p.drv.UnregisterInterrupt(int(p.val.Fd())) + return p.drv.UnregisterInterrupt(p) } func (p *digitalPin) Signal() {