From 631591fc014b4efa91f9a2dd975eebfa26ee4697 Mon Sep 17 00:00:00 2001 From: Drahoslav Date: Sat, 1 Dec 2018 05:25:08 +0100 Subject: [PATCH] Add IRQ enable/disable --- rpio.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/rpio.go b/rpio.go index f4aeef3..7e8f28d 100644 --- a/rpio.go +++ b/rpio.go @@ -90,6 +90,7 @@ const ( clkOffset = 0x101000 pwmOffset = 0x20C000 spiOffset = 0x204000 + intrOffset = 0x00B000 memLength = 4096 ) @@ -99,6 +100,9 @@ var ( clkBase int64 pwmBase int64 spiBase int64 + intrBase int64 + + irqsBackup uint64 ) func init() { @@ -107,6 +111,7 @@ func init() { clkBase = base + clkOffset pwmBase = base + pwmOffset spiBase = base + spiOffset + intrBase = base + intrOffset } // Pin mode, a pin can be set in Input or Output, Clock or Pwm mode @@ -146,10 +151,12 @@ var ( clkMem []uint32 pwmMem []uint32 spiMem []uint32 + intrMem []uint32 gpioMem8 []uint8 clkMem8 []uint8 pwmMem8 []uint8 spiMem8 []uint8 + intrMem8 []uint8 ) // Set pin as Input @@ -584,6 +591,32 @@ func StartPwm() { pwmMem[pwmCtlReg] |= pwen<<8 | pwen } +// Enables given IRQs (by setting bit to 1 at intended position). +// See 'ARM peripherals interrupts table' in pheripherals datasheet. +// WARNING: you can corrupt your system, only use this if you know what you are doing. +func EnableIRQs(irqs uint64) { + const irqEnable1 = 0x210 / 4 + const irqEnable2 = 0x214 / 4 + intrMem[irqEnable1] = uint32(irqs) // IRQ 0..31 + intrMem[irqEnable2] = uint32(irqs >> 32) // IRQ 32..63 +} + +// Disables given IRQs (by setting bit to 1 at intended position). +// See 'ARM peripherals interrupts table' in pheripherals datasheet. +// WARNING: you can corrupt your system, only use this if you know what you are doing. +func DisableIRQs(irqs uint64) { + const irqDisable1 = 0x21C / 4 + const irqDisable2 = 0x220 / 4 + intrMem[irqDisable1] = uint32(irqs) // IRQ 0..31 + intrMem[irqDisable2] = uint32(irqs >> 32) // IRQ 32..63 +} + +func backupIRQs() { + const irqEnable1 = 0x210 / 4 + const irqEnable2 = 0x214 / 4 + irqsBackup = uint64(intrMem[irqEnable2])<<32 | uint64(intrMem[irqEnable1]) +} + // Open and memory map GPIO memory range from /dev/mem . // Some reflection magic is used to convert it to a unsafe []uint32 pointer func Open() (err error) { @@ -627,6 +660,14 @@ func Open() (err error) { return } + // Memory map interruption registers to slice + intrMem, intrMem8, err = memMap(file.Fd(), intrBase) + if err != nil { + return + } + + backupIRQs() // back up enabled IRQs, to restore it later + return nil } @@ -653,18 +694,12 @@ func memMap(fd uintptr, base int64) (mem []uint32, mem8 []byte, err error) { func Close() error { memlock.Lock() defer memlock.Unlock() - if err := syscall.Munmap(gpioMem8); err != nil { - return err - } - if err := syscall.Munmap(clkMem8); err != nil { - return err - } - if err := syscall.Munmap(pwmMem8); err != nil { - return err - } - if err := syscall.Munmap(spiMem8); err != nil { - return err + for _, mem8 := range [][]uint8{gpioMem8, clkMem8, pwmMem8, spiMem8, intrMem8} { + if err := syscall.Munmap(mem8); err != nil { + return err + } } + EnableIRQs(irqsBackup) // Return IRQs to state where it was before - just to be nice return nil }