WIP: interrupt API

This commit is contained in:
Ayke van Laethem
2019-12-15 14:16:22 +01:00
parent 084386262a
commit 9cdc2fa768
18 changed files with 412 additions and 89 deletions
+25
View File
@@ -0,0 +1,25 @@
// Package interrupt provides access to hardware interrupts. It provides a way
// to define interrupts and to enable/disable them.
package interrupt
// Interrupt provides direct access to hardware interrupts. You can configure
// this interrupt through this interface.
//
// Do not use the zero value of an Interrupt object. Instead, call New to obtain
// an interrupt handle.
type Interrupt struct {
// Make this number unexported so it cannot be set directly. This provides
// some encapsulation.
num int
}
// New is a compiler intrinsic that creates a new Interrupt object. You may call
// it only once, and must pass constant parameters to it. That means that the
// interrupt ID must be a Go constant and that the handler must be a simple
// function: closures are not supported.
func New(id int, handler func(Interrupt)) Interrupt
// Register is used to declare an interrupt. You should not normally call this
// function: it is only for telling the compiler about the mapping between an
// interrupt number and the interrupt handler name.
func Register(id int, handlerName string) int
@@ -0,0 +1,23 @@
// +build cortexm
package interrupt
import (
"device/arm"
)
// Enable enables this interrupt. Right after calling this function, the
// interrupt may be invoked if it was already pending.
func (irq Interrupt) Enable() {
arm.EnableIRQ(uint32(irq.num))
}
// SetPriority sets the interrupt priority for this interrupt. A lower number
// means a higher priority. Additionally, most hardware doesn't implement all
// priority bits (only the uppoer bits).
//
// Examples: 0xff (lowest priority), 0xc0 (low priority), 0x00 (highest possible
// priority).
func (irq Interrupt) SetPriority(priority uint8) {
arm.SetPriority(uint32(irq.num), uint32(priority))
}
+9 -10
View File
@@ -6,6 +6,7 @@ import (
"device/arm"
"device/sam"
"machine"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
)
@@ -214,8 +215,14 @@ func initRTC() {
sam.RTC_MODE0.CTRL.SetBits(sam.RTC_MODE0_CTRL_ENABLE)
waitForSync()
arm.SetPriority(sam.IRQ_RTC, 0xc0)
arm.EnableIRQ(sam.IRQ_RTC)
intr := interrupt.New(sam.IRQ_RTC, func(intr interrupt.Interrupt) {
// disable IRQ for CMP0 compare
sam.RTC_MODE0.INTFLAG.Set(sam.RTC_MODE0_INTENSET_CMP0)
timerWakeup.Set(1)
})
intr.SetPriority(0xc0)
intr.Enable()
}
func waitForSync() {
@@ -286,14 +293,6 @@ func timerSleep(ticks uint32) {
}
}
//go:export RTC_IRQHandler
func handleRTC() {
// disable IRQ for CMP0 compare
sam.RTC_MODE0.INTFLAG.Set(sam.RTC_MODE0_INTENSET_CMP0)
timerWakeup.Set(1)
}
func initUSBClock() {
// Turn on clock for USB
sam.PM.APBBMASK.SetBits(sam.PM_APBBMASK_USB_)
+8 -9
View File
@@ -6,6 +6,7 @@ import (
"device/arm"
"device/nrf"
"machine"
"runtime/interrupt"
"runtime/volatile"
)
@@ -43,8 +44,13 @@ func initLFCLK() {
func initRTC() {
nrf.RTC1.TASKS_START.Set(1)
arm.SetPriority(nrf.IRQ_RTC1, 0xc0) // low priority
arm.EnableIRQ(nrf.IRQ_RTC1)
intr := interrupt.New(nrf.IRQ_RTC1, func(intr interrupt.Interrupt) {
nrf.RTC1.INTENCLR.Set(nrf.RTC_INTENSET_COMPARE0)
nrf.RTC1.EVENTS_COMPARE[0].Set(0)
rtc_wakeup.Set(1)
})
intr.SetPriority(0xc0) // low priority
intr.Enable()
}
func putchar(c byte) {
@@ -96,10 +102,3 @@ func rtc_sleep(ticks uint32) {
arm.Asm("wfi")
}
}
//go:export RTC1_IRQHandler
func handleRTC1() {
nrf.RTC1.INTENCLR.Set(nrf.RTC_INTENSET_COMPARE0)
nrf.RTC1.EVENTS_COMPARE[0].Set(0)
rtc_wakeup.Set(1)
}