mirror of
https://github.com/stianeikeland/go-rpio.git
synced 2025-01-22 18:21:04 +01:00
Disable gpio IRQ on Detect edge
This commit is contained in:
parent
631591fc01
commit
84326092ab
13
rpio.go
13
rpio.go
|
@ -372,12 +372,20 @@ func TogglePin(pin Pin) {
|
|||
//
|
||||
// Note that using this function might conflict with the same functionality of other gpio library.
|
||||
//
|
||||
// It also clears previously detected event of this pin if any.
|
||||
// It also clears previously detected event of this pin if there was any.
|
||||
//
|
||||
// Note that call with RiseEdge will disable previously set FallEdge detection and vice versa.
|
||||
// You have to call with AnyEdge, to enable detection for both edges.
|
||||
// To disable previously enabled detection call it with NoEdge.
|
||||
//
|
||||
// WARNING: this might make your Pi unresponsive, if this happens, you should either run the code as root,
|
||||
// or add `dtoverlay=gpio-no-irq` to `/boot/config.txt` and restart your pi,
|
||||
func DetectEdge(pin Pin, edge Edge) {
|
||||
if edge != NoEdge {
|
||||
// disable GPIO event interruption to prevent freezing in some cases
|
||||
DisableIRQs(1<<49 | 1<<52) // gpio_int[0] and gpio_int[3]
|
||||
}
|
||||
|
||||
p := uint8(pin)
|
||||
|
||||
// Rising edge detect enable register (19/20 depending on bank)
|
||||
|
@ -692,6 +700,8 @@ func memMap(fd uintptr, base int64) (mem []uint32, mem8 []byte, err error) {
|
|||
|
||||
// Close unmaps GPIO memory
|
||||
func Close() error {
|
||||
EnableIRQs(irqsBackup) // Return IRQs to state where it was before - just to be nice
|
||||
|
||||
memlock.Lock()
|
||||
defer memlock.Unlock()
|
||||
for _, mem8 := range [][]uint8{gpioMem8, clkMem8, pwmMem8, spiMem8, intrMem8} {
|
||||
|
@ -699,7 +709,6 @@ func Close() error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
EnableIRQs(irqsBackup) // Return IRQs to state where it was before - just to be nice
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
52
rpio_test.go
52
rpio_test.go
|
@ -1,6 +1,7 @@
|
|||
package rpio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -15,6 +16,21 @@ func TestMain(m *testing.M) {
|
|||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestInterrupt(t *testing.T) {
|
||||
logIrqRegs(t)
|
||||
EnableIRQs(1 << 49)
|
||||
EnableIRQs(1 << 50)
|
||||
EnableIRQs(1 << 51)
|
||||
EnableIRQs(1 << 52)
|
||||
logIrqRegs(t)
|
||||
DisableIRQs(1 << 49)
|
||||
DisableIRQs(1 << 50)
|
||||
DisableIRQs(1 << 51)
|
||||
DisableIRQs(1 << 52)
|
||||
logIrqRegs(t)
|
||||
EnableIRQs(irqsBackup)
|
||||
}
|
||||
|
||||
func TestEvent(t *testing.T) {
|
||||
src := Pin(3)
|
||||
src.Mode(Output)
|
||||
|
@ -118,6 +134,33 @@ func TestEvent(t *testing.T) {
|
|||
|
||||
})
|
||||
|
||||
// If this fr⁽eezes your pi,
|
||||
// add `dtoverlay=gpio-no-irq` to `/boot/config.txt` and restart your pi,
|
||||
// or run as root.
|
||||
t.Run("multiple edges", func(t *testing.T) {
|
||||
EnableIRQs(15 << 49) // all 4 gpio_int[]
|
||||
logIrqRegs(t)
|
||||
src.High()
|
||||
pin.Detect(FallEdge)
|
||||
|
||||
logIrqRegs(t)
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
time.Sleep(time.Millisecond)
|
||||
src.High()
|
||||
time.Sleep(time.Millisecond)
|
||||
src.Low()
|
||||
}
|
||||
logIrqRegs(t)
|
||||
if !pin.EdgeDetected() {
|
||||
t.Errorf("Edge not detected")
|
||||
}
|
||||
logIrqRegs(t)
|
||||
pin.Detect(NoEdge)
|
||||
logIrqRegs(t)
|
||||
EnableIRQs(irqsBackup)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkGpio(b *testing.B) {
|
||||
|
@ -191,3 +234,12 @@ func BenchmarkGpio(b *testing.B) {
|
|||
})
|
||||
|
||||
}
|
||||
|
||||
func logIrqRegs(t *testing.T) {
|
||||
fmt.Printf("PENDING(% X) FIQ(% X) ENAB(% X) DISAB(% X)\n",
|
||||
intrMem8[0x200:0x20C],
|
||||
intrMem8[0x20C:0x210],
|
||||
intrMem8[0x210:0x21C],
|
||||
intrMem8[0x21C:0x228],
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user