forked from hybridgroup/gobot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
system(gpio): add edge polling function (hybridgroup#1015)
- Loading branch information
1 parent
002c75c
commit 1f09353
Showing
10 changed files
with
737 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package system | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
"time" | ||
) | ||
|
||
func startEdgePolling( | ||
pinLabel string, | ||
pinReadFunc func() (int, error), | ||
pollInterval time.Duration, | ||
wantedEdge int, | ||
eventHandler func(offset int, t time.Duration, et string, sn uint32, lsn uint32), | ||
quitChan chan struct{}, | ||
) error { | ||
if eventHandler == nil { | ||
return fmt.Errorf("an event handler is mandatory for edge polling") | ||
} | ||
if quitChan == nil { | ||
return fmt.Errorf("the quit channel is mandatory for edge polling") | ||
} | ||
|
||
const allEdges = "all" | ||
|
||
triggerEventOn := "none" | ||
switch wantedEdge { | ||
case digitalPinEventOnFallingEdge: | ||
triggerEventOn = DigitalPinEventFallingEdge | ||
case digitalPinEventOnRisingEdge: | ||
triggerEventOn = DigitalPinEventRisingEdge | ||
case digitalPinEventOnBothEdges: | ||
triggerEventOn = allEdges | ||
default: | ||
return fmt.Errorf("unsupported edge type %d for edge polling", wantedEdge) | ||
} | ||
|
||
wg := sync.WaitGroup{} | ||
wg.Add(1) | ||
|
||
go func() { | ||
var oldState int | ||
var readStart time.Time | ||
var firstLoopDone bool | ||
for { | ||
select { | ||
case <-quitChan: | ||
return | ||
default: | ||
// note: pure reading takes between 30us and 1ms on rasperry Pi1, typically 50us, with sysfs also 500us | ||
// can happen, so we use the time stamp before start of reading to reduce random duration offset | ||
readStart = time.Now() | ||
readValue, err := pinReadFunc() | ||
if err != nil { | ||
fmt.Printf("edge polling error occurred while reading the pin %s: %v", pinLabel, err) | ||
readValue = oldState // keep the value | ||
} | ||
if readValue != oldState { | ||
detectedEdge := DigitalPinEventRisingEdge | ||
if readValue < oldState { | ||
detectedEdge = DigitalPinEventFallingEdge | ||
} | ||
if firstLoopDone && (triggerEventOn == allEdges || triggerEventOn == detectedEdge) { | ||
eventHandler(0, time.Duration(readStart.UnixNano()), detectedEdge, 0, 0) | ||
} | ||
oldState = readValue | ||
} | ||
// the real poll interval is increased by the reading time, see also note above | ||
// negative or zero duration causes no sleep | ||
time.Sleep(pollInterval - time.Since(readStart)) | ||
if !firstLoopDone { | ||
wg.Done() | ||
firstLoopDone = true | ||
} | ||
} | ||
} | ||
}() | ||
|
||
wg.Wait() | ||
return nil | ||
} |
Oops, something went wrong.