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 Pin uint8
|
||||||
type State uint8
|
type State uint8
|
||||||
type Pull uint8
|
type Pull uint8
|
||||||
|
type Edge uint8
|
||||||
|
|
||||||
// Memory offsets for gpio, see the spec for more details
|
// Memory offsets for gpio, see the spec for more details
|
||||||
const (
|
const (
|
||||||
|
@ -121,6 +122,14 @@ const (
|
||||||
PullUp
|
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
|
// Arrays for 8 / 32 bit access to memory and a semaphore for write locking
|
||||||
var (
|
var (
|
||||||
memlock sync.Mutex
|
memlock sync.Mutex
|
||||||
|
@ -212,6 +221,16 @@ func (pin Pin) PullOff() {
|
||||||
PullMode(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)
|
// 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.
|
// 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
|
// WritePin sets a given pin High or Low
|
||||||
// by setting the clear or set registers respectively
|
// by setting the clear or set registers respectively
|
||||||
func WritePin(pin Pin, state State) {
|
func WritePin(pin Pin, state State) {
|
||||||
|
|
||||||
p := uint8(pin)
|
p := uint8(pin)
|
||||||
|
|
||||||
// Clear register, 10 / 11 depending on bank
|
// Clear register, 10 / 11 depending on bank
|
||||||
|
@ -278,7 +296,6 @@ func WritePin(pin Pin, state State) {
|
||||||
} else {
|
} else {
|
||||||
gpioMem[setReg] = 1 << (p & 31)
|
gpioMem[setReg] = 1 << (p & 31)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the state of a pin
|
// 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) {
|
func PullMode(pin Pin, pull Pull) {
|
||||||
// Pull up/down/off register has offset 38 / 39, pull is 37
|
// Pull up/down/off register has offset 38 / 39, pull is 37
|
||||||
pullClkReg := pin/32 + 38
|
pullClkReg := pin/32 + 38
|
||||||
|
@ -315,7 +376,7 @@ func PullMode(pin Pin, pull Pull) {
|
||||||
|
|
||||||
switch pull {
|
switch pull {
|
||||||
case PullDown, PullUp:
|
case PullDown, PullUp:
|
||||||
gpioMem[pullReg] = gpioMem[pullReg]&^3 | uint32(pull)
|
gpioMem[pullReg] = gpioMem[pullReg] &^ 3 | uint32(pull)
|
||||||
case PullOff:
|
case PullOff:
|
||||||
gpioMem[pullReg] = gpioMem[pullReg] &^ 3
|
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.
|
// changing frequency for one pin will change it also for all pins within a group.
|
||||||
// The groups are:
|
// The groups are:
|
||||||
// gp_clk0: pins 4, 20, 32, 34
|
// 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
|
// gp_clk2: pins 6 and 43
|
||||||
// pwm_clk: pins 12, 13, 18, 19, 40, 41, 45
|
// pwm_clk: pins 12, 13, 18, 19, 40, 41, 45
|
||||||
func SetFreq(pin Pin, freq int) {
|
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
|
const msen = 1 << 7 // use M/S transition instead of pwm algorithm
|
||||||
|
|
||||||
// reset settings
|
// 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
|
// set duty cycle
|
||||||
pwmMem[pwmDatReg] = dutyLen
|
pwmMem[pwmDatReg] = dutyLen
|
||||||
pwmMem[pwmRngReg] = cycleLen
|
pwmMem[pwmRngReg] = cycleLen
|
||||||
|
|
Loading…
Reference in New Issue
Block a user