mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 21:09:02 +00:00
device/arm: clear pending interrupts before enabling them
Without this change, a pending interrupt would spuriously trigger
immediately after enabling. This happens if an interrupt is triggered
during flashing (e.g. by DMA), which survives the subsequent reset.
This behaviour matches e.g. `machine.irqSet` in machine_rp2_rp2350.go.
See 7f970a45, whose symptoms were likely caused by spurious interrupts.
This commit is contained in:
@@ -43,8 +43,8 @@ func TestBinarySize(t *testing.T) {
|
|||||||
tests := []sizeTest{
|
tests := []sizeTest{
|
||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
|
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
|
||||||
{"microbit", "examples/serial", 2916, 388, 8, 2272},
|
{"microbit", "examples/serial", 2924, 388, 8, 2272},
|
||||||
{"wioterminal", "examples/pininterrupt", 7359, 1489, 116, 6912},
|
{"wioterminal", "examples/pininterrupt", 7383, 1489, 116, 6912},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
@@ -146,6 +146,11 @@ const (
|
|||||||
SYST_CALIB_NOREF = 0x80000000 // Bit NOREF.
|
SYST_CALIB_NOREF = 0x80000000 // Bit NOREF.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ClearPendingIRQ clears the pending status of the interrupt.
|
||||||
|
func ClearPendingIRQ(irq uint32) {
|
||||||
|
NVIC.ICPR[irq>>5].Set(1 << (irq & 0x1F))
|
||||||
|
}
|
||||||
|
|
||||||
// Enable the given interrupt number.
|
// Enable the given interrupt number.
|
||||||
func EnableIRQ(irq uint32) {
|
func EnableIRQ(irq uint32) {
|
||||||
NVIC.ISER[irq>>5].Set(1 << (irq & 0x1F))
|
NVIC.ISER[irq>>5].Set(1 << (irq & 0x1F))
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import (
|
|||||||
// Enable enables this interrupt. Right after calling this function, the
|
// Enable enables this interrupt. Right after calling this function, the
|
||||||
// interrupt may be invoked if it was already pending.
|
// interrupt may be invoked if it was already pending.
|
||||||
func (irq Interrupt) Enable() {
|
func (irq Interrupt) Enable() {
|
||||||
|
// Clear the ARM pending bit, an asserting device may still
|
||||||
|
// trigger the interrupt once enabled.
|
||||||
|
arm.ClearPendingIRQ(uint32(irq.num))
|
||||||
arm.EnableIRQ(uint32(irq.num))
|
arm.EnableIRQ(uint32(irq.num))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user