mirror of
https://github.com/stianeikeland/go-rpio.git
synced 2025-02-02 15:30:36 +01:00
Impelement edge event detection
This commit is contained in:
parent
f6236e5866
commit
2ec057fd07
71
rpio.go
71
rpio.go
|
@ -76,6 +76,7 @@ type Mode uint8
|
|||
type Pin uint8
|
||||
type State uint8
|
||||
type Pull uint8
|
||||
type Edge uint8
|
||||
|
||||
// Memory offsets for gpio, see the spec for more details
|
||||
const (
|
||||
|
@ -121,6 +122,14 @@ const (
|
|||
PullUp
|
||||
)
|
||||
|
||||
// Edge events
|
||||
const (
|
||||
NoEdge Edge = iota
|
||||
RiseEdge
|
||||
FallEdge
|
||||
AnyEdge = RiseEdge | FallEdge
|
||||
)
|
||||
|
||||
// Arrays for 8 / 32 bit access to memory and a semaphore for write locking
|
||||
var (
|
||||
memlock sync.Mutex
|
||||
|
@ -212,6 +221,16 @@ func (pin Pin) PullOff() {
|
|||
PullMode(pin, PullOff)
|
||||
}
|
||||
|
||||
// Enable edge event detection on pin
|
||||
func (pin Pin) Detect(edge Edge) {
|
||||
DetectEdge(pin, edge)
|
||||
}
|
||||
|
||||
// Check edge event on pin
|
||||
func (pin Pin) EdgeDetected() bool {
|
||||
return EdgeDetected(pin)
|
||||
}
|
||||
|
||||
// PinMode sets the mode (direction) of a given pin (Input, Output, Clock or Pwm)
|
||||
//
|
||||
// Clock is possible only for pins 4, 5, 6, 20, 21.
|
||||
|
@ -262,7 +281,6 @@ func PinMode(pin Pin, mode Mode) {
|
|||
// WritePin sets a given pin High or Low
|
||||
// by setting the clear or set registers respectively
|
||||
func WritePin(pin Pin, state State) {
|
||||
|
||||
p := uint8(pin)
|
||||
|
||||
// Clear register, 10 / 11 depending on bank
|
||||
|
@ -278,7 +296,6 @@ func WritePin(pin Pin, state State) {
|
|||
} else {
|
||||
gpioMem[setReg] = 1 << (p & 31)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Read the state of a pin
|
||||
|
@ -304,6 +321,50 @@ func TogglePin(pin Pin) {
|
|||
}
|
||||
}
|
||||
|
||||
// Enable edge event detection on pin
|
||||
//
|
||||
// Call with RiseEdge followed by call with FallEdge has the same effect as call with AnyEdge,
|
||||
// to disable previously enabled event call it with NoEdge.
|
||||
//
|
||||
// Combine with pin.EdgeDetected() to check whether event occured.
|
||||
//
|
||||
// It also clears previously detected events of this pin if any.
|
||||
func DetectEdge(pin Pin, edge Edge) {
|
||||
p := uint8(pin)
|
||||
|
||||
// Rising edge detect enable register (19/20 depending on bank)
|
||||
// Falling edge detect enable register (22/23 depending on bank)
|
||||
renReg := p/32 + 19
|
||||
fenReg := p/32 + 23
|
||||
|
||||
if edge == NoEdge { // clear bits
|
||||
gpioMem[renReg] = gpioMem[renReg] &^ (1 << (p&31))
|
||||
gpioMem[fenReg] = gpioMem[fenReg] &^ (1 << (p&31))
|
||||
}
|
||||
if edge & RiseEdge > 0 { // set bit
|
||||
gpioMem[renReg] = gpioMem[renReg] | (1 << (p&31))
|
||||
}
|
||||
if edge & FallEdge > 0 { // set bit
|
||||
gpioMem[fenReg] = gpioMem[fenReg] | (1 << (p&31))
|
||||
}
|
||||
|
||||
EdgeDetected(pin) // to clear outdated detection
|
||||
}
|
||||
|
||||
// Check whether edge event occured
|
||||
//
|
||||
// Event detection has to be enabled first, by pin.Detect(edge)
|
||||
func EdgeDetected(pin Pin) bool {
|
||||
p := uint8(pin)
|
||||
|
||||
// Event detect status register (16/17)
|
||||
edsReg := p/32 + 16
|
||||
|
||||
test := gpioMem[edsReg] & (1 << (p&31))
|
||||
gpioMem[edsReg] = test // set bit to clear it
|
||||
return test > 0
|
||||
}
|
||||
|
||||
func PullMode(pin Pin, pull Pull) {
|
||||
// Pull up/down/off register has offset 38 / 39, pull is 37
|
||||
pullClkReg := pin/32 + 38
|
||||
|
@ -315,7 +376,7 @@ func PullMode(pin Pin, pull Pull) {
|
|||
|
||||
switch pull {
|
||||
case PullDown, PullUp:
|
||||
gpioMem[pullReg] = gpioMem[pullReg]&^3 | uint32(pull)
|
||||
gpioMem[pullReg] = gpioMem[pullReg] &^ 3 | uint32(pull)
|
||||
case PullOff:
|
||||
gpioMem[pullReg] = gpioMem[pullReg] &^ 3
|
||||
}
|
||||
|
@ -343,7 +404,7 @@ func PullMode(pin Pin, pull Pull) {
|
|||
// changing frequency for one pin will change it also for all pins within a group.
|
||||
// The groups are:
|
||||
// gp_clk0: pins 4, 20, 32, 34
|
||||
// gp_clk1: pins 5, 21, 42, 43
|
||||
// gp_clk1: pins 5, 21, 42, 44
|
||||
// gp_clk2: pins 6 and 43
|
||||
// pwm_clk: pins 12, 13, 18, 19, 40, 41, 45
|
||||
func SetFreq(pin Pin, freq int) {
|
||||
|
@ -452,7 +513,7 @@ func SetDutyCycle(pin Pin, dutyLen, cycleLen uint32) {
|
|||
const msen = 1 << 7 // use M/S transition instead of pwm algorithm
|
||||
|
||||
// reset settings
|
||||
pwmMem[pwmCtlReg] = pwmMem[pwmCtlReg]&^(ctlMask<<shift) | msen<<shift | pwen <<shift
|
||||
pwmMem[pwmCtlReg] = pwmMem[pwmCtlReg]&^(ctlMask<<shift) | msen<<shift | pwen<<shift
|
||||
// set duty cycle
|
||||
pwmMem[pwmDatReg] = dutyLen
|
||||
pwmMem[pwmRngReg] = cycleLen
|
||||
|
|
Loading…
Reference in New Issue
Block a user