mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 03:27:48 +00:00
all: add compiler support for interrupts
This commit lets the compiler know about interrupts and allows optimizations to be performed based on that: interrupts are eliminated when they appear to be unused in a program. This is done with a new pseudo-call (runtime/interrupt.New) that is treated specially by the compiler.
This commit is contained in:
committed by
Ron Evans
parent
3729fcfa9e
commit
a5ed993f8d
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/sam"
|
||||
import (
|
||||
"device/sam"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// UART1 on the Arduino Nano 33 connects to the onboard NINA-W102 WiFi chip.
|
||||
var (
|
||||
@@ -13,11 +16,6 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM3_IRQHandler
|
||||
func handleUART1() {
|
||||
defaultUART1Handler()
|
||||
}
|
||||
|
||||
// UART2 on the Arduino Nano 33 connects to the normal TX/RX pins.
|
||||
var (
|
||||
UART2 = UART{
|
||||
@@ -27,11 +25,9 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM5_IRQHandler
|
||||
func handleUART2() {
|
||||
// should reset IRQ
|
||||
UART2.Receive(byte((UART2.Bus.DATA.Get() & 0xFF)))
|
||||
UART2.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM3, UART1.handleInterrupt)
|
||||
UART2.Interrupt = interrupt.New(sam.IRQ_SERCOM5, UART2.handleInterrupt)
|
||||
}
|
||||
|
||||
// I2C on the Arduino Nano 33.
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/stm32"
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// https://wiki.stm32duino.com/index.php?title=File:Bluepillpinout.gif
|
||||
const (
|
||||
@@ -61,14 +64,12 @@ var (
|
||||
UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART1,
|
||||
IRQVal: stm32.IRQ_USART1,
|
||||
}
|
||||
UART1 = &UART0
|
||||
)
|
||||
|
||||
//go:export USART1_IRQHandler
|
||||
func handleUART1() {
|
||||
UART1.Receive(byte((UART1.Bus.DR.Get() & 0xFF)))
|
||||
func init() {
|
||||
UART0.Interrupt = interrupt.New(stm32.IRQ_USART1, UART0.handleInterrupt)
|
||||
}
|
||||
|
||||
// SPI pins
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/sam"
|
||||
import (
|
||||
"device/sam"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// UART1 on the Circuit Playground Express.
|
||||
var (
|
||||
@@ -13,9 +16,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM1_IRQHandler
|
||||
func handleUART1() {
|
||||
defaultUART1Handler()
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM4, UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
// I2C on the Circuit Playground Express.
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/sam"
|
||||
import (
|
||||
"device/sam"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// used to reset into bootloader
|
||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
||||
@@ -60,9 +63,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM1_IRQHandler
|
||||
func handleUART1() {
|
||||
defaultUART1Handler()
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM1, UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
// I2C pins
|
||||
|
||||
@@ -4,6 +4,7 @@ package machine
|
||||
|
||||
import (
|
||||
"device/sam"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// used to reset into bootloader
|
||||
@@ -62,9 +63,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM1_IRQHandler
|
||||
func handleUART1() {
|
||||
defaultUART1Handler()
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM1, UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
// I2C pins
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/stm32"
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
PA0 = portA + 0
|
||||
@@ -100,14 +103,12 @@ var (
|
||||
UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART2,
|
||||
IRQVal: stm32.IRQ_USART2,
|
||||
}
|
||||
UART2 = &UART0
|
||||
)
|
||||
|
||||
//go:export USART2_IRQHandler
|
||||
func handleUART2() {
|
||||
UART2.Receive(byte((UART2.Bus.DR.Get() & 0xFF)))
|
||||
func init() {
|
||||
UART0.Interrupt = interrupt.New(stm32.IRQ_USART2, UART0.handleInterrupt)
|
||||
}
|
||||
|
||||
// SPI pins
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package machine
|
||||
|
||||
import "device/sam"
|
||||
import (
|
||||
"device/sam"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// used to reset into bootloader
|
||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
||||
@@ -51,9 +54,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//go:export SERCOM1_IRQHandler
|
||||
func handleUART1() {
|
||||
defaultUART1Handler()
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM0, UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
// SPI pins
|
||||
|
||||
@@ -4,6 +4,7 @@ package machine
|
||||
|
||||
import (
|
||||
"device/avr"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
@@ -232,6 +233,18 @@ func (uart UART) Configure(config UARTConfig) {
|
||||
config.BaudRate = 9600
|
||||
}
|
||||
|
||||
// Register the UART interrupt.
|
||||
interrupt.New(avr.IRQ_USART_RX, func(intr interrupt.Interrupt) {
|
||||
// Read register to clear it.
|
||||
data := avr.UDR0.Get()
|
||||
|
||||
// Ensure no error.
|
||||
if !avr.UCSR0A.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
|
||||
// Put data from UDR register into buffer.
|
||||
UART0.Receive(byte(data))
|
||||
}
|
||||
})
|
||||
|
||||
// Set baud rate based on prescale formula from
|
||||
// https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_wrong_baud_rate.html
|
||||
// ((F_CPU + UART_BAUD_RATE * 8L) / (UART_BAUD_RATE * 16L) - 1)
|
||||
@@ -254,15 +267,3 @@ func (uart UART) WriteByte(c byte) error {
|
||||
avr.UDR0.Set(c) // send char
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:interrupt USART_RX_vect
|
||||
func handleUSART_RX() {
|
||||
// Read register to clear it.
|
||||
data := avr.UDR0.Get()
|
||||
|
||||
// Ensure no error.
|
||||
if !avr.UCSR0A.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
|
||||
// Put data from UDR register into buffer.
|
||||
UART0.Receive(byte(data))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"device/arm"
|
||||
"device/sam"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -292,9 +293,10 @@ func waitADCSync() {
|
||||
|
||||
// UART on the SAMD21.
|
||||
type UART struct {
|
||||
Buffer *RingBuffer
|
||||
Bus *sam.SERCOM_USART_Type
|
||||
SERCOM uint8
|
||||
Buffer *RingBuffer
|
||||
Bus *sam.SERCOM_USART_Type
|
||||
SERCOM uint8
|
||||
Interrupt interrupt.Interrupt
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -401,10 +403,7 @@ func (uart UART) Configure(config UARTConfig) error {
|
||||
uart.Bus.INTENSET.Set(sam.SERCOM_USART_INTENSET_RXC)
|
||||
|
||||
// Enable RX IRQ.
|
||||
// IRQ lines are in the same order as SERCOM instance numbers on SAMD21
|
||||
// chips, so the IRQ number can be trivially determined from the SERCOM
|
||||
// number.
|
||||
arm.EnableIRQ(sam.IRQ_SERCOM0 + uint32(uart.SERCOM))
|
||||
uart.Interrupt.Enable()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -432,11 +431,12 @@ func (uart UART) WriteByte(c byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultUART1Handler handles the UART1 IRQ.
|
||||
func defaultUART1Handler() {
|
||||
// handleInterrupt should be called from the appropriate interrupt handler for
|
||||
// this UART instance.
|
||||
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
|
||||
// should reset IRQ
|
||||
UART1.Receive(byte((UART1.Bus.DATA.Get() & 0xFF)))
|
||||
UART1.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
||||
uart.Receive(byte((uart.Bus.DATA.Get() & 0xFF)))
|
||||
uart.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
||||
}
|
||||
|
||||
// I2C on the SAMD21.
|
||||
@@ -1368,7 +1368,8 @@ func (usbcdc USBCDC) Configure(config UARTConfig) {
|
||||
sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_ENABLE)
|
||||
|
||||
// enable IRQ
|
||||
arm.EnableIRQ(sam.IRQ_USB)
|
||||
intr := interrupt.New(sam.IRQ_USB, handleUSB)
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
func handlePadCalibration() {
|
||||
@@ -1414,8 +1415,7 @@ func handlePadCalibration() {
|
||||
sam.USB_DEVICE.PADCAL.SetBits(calibTrim << sam.USB_DEVICE_PADCAL_TRIM_Pos)
|
||||
}
|
||||
|
||||
//go:export USB_IRQHandler
|
||||
func handleUSB() {
|
||||
func handleUSB(intr interrupt.Interrupt) {
|
||||
// reset all interrupt flags
|
||||
flags := sam.USB_DEVICE.INTFLAG.Get()
|
||||
sam.USB_DEVICE.INTFLAG.Set(flags)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"device/arm"
|
||||
"device/sam"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -1547,11 +1548,11 @@ func (usbcdc USBCDC) Configure(config UARTConfig) {
|
||||
// enable USB
|
||||
sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_ENABLE)
|
||||
|
||||
// enable IRQ
|
||||
arm.EnableIRQ(sam.IRQ_USB_OTHER)
|
||||
arm.EnableIRQ(sam.IRQ_USB_SOF_HSOF)
|
||||
arm.EnableIRQ(sam.IRQ_USB_TRCPT0)
|
||||
arm.EnableIRQ(sam.IRQ_USB_TRCPT1)
|
||||
// enable IRQ at highest priority
|
||||
interrupt.New(sam.IRQ_USB_OTHER, handleUSBIRQ).Enable()
|
||||
interrupt.New(sam.IRQ_USB_SOF_HSOF, handleUSBIRQ).Enable()
|
||||
interrupt.New(sam.IRQ_USB_TRCPT0, handleUSBIRQ).Enable()
|
||||
interrupt.New(sam.IRQ_USB_TRCPT1, handleUSBIRQ).Enable()
|
||||
}
|
||||
|
||||
func handlePadCalibration() {
|
||||
@@ -1597,27 +1598,7 @@ func handlePadCalibration() {
|
||||
sam.USB_DEVICE.PADCAL.SetBits(calibTrim << sam.USB_DEVICE_PADCAL_TRIM_Pos)
|
||||
}
|
||||
|
||||
//go:export USB_OTHER_IRQHandler
|
||||
func handleUSBOther() {
|
||||
handleUSBIRQ()
|
||||
}
|
||||
|
||||
//go:export USB_SOF_HSOF_IRQHandler
|
||||
func handleUSBSOFHSOF() {
|
||||
handleUSBIRQ()
|
||||
}
|
||||
|
||||
//go:export USB_TRCPT0_IRQHandler
|
||||
func handleUSBTRCPT0() {
|
||||
handleUSBIRQ()
|
||||
}
|
||||
|
||||
//go:export USB_TRCPT1_IRQHandler
|
||||
func handleUSBTRCPT1() {
|
||||
handleUSBIRQ()
|
||||
}
|
||||
|
||||
func handleUSBIRQ() {
|
||||
func handleUSBIRQ(interrupt.Interrupt) {
|
||||
// reset all interrupt flags
|
||||
flags := sam.USB_DEVICE.INTFLAG.Get()
|
||||
sam.USB_DEVICE.INTFLAG.Set(flags)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/nrf"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -88,8 +88,9 @@ func (uart UART) Configure(config UARTConfig) {
|
||||
nrf.UART0.INTENSET.Set(nrf.UART_INTENSET_RXDRDY_Msk)
|
||||
|
||||
// Enable RX IRQ.
|
||||
arm.SetPriority(nrf.IRQ_UART0, 0xc0) // low priority
|
||||
arm.EnableIRQ(nrf.IRQ_UART0)
|
||||
intr := interrupt.New(nrf.IRQ_UART0, UART0.handleInterrupt)
|
||||
intr.SetPriority(0xc0) // low priority
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
// SetBaudRate sets the communication speed for the UART.
|
||||
@@ -116,7 +117,7 @@ func (uart UART) WriteByte(c byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uart UART) handleInterrupt() {
|
||||
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
|
||||
if nrf.UART0.EVENTS_RXDRDY.Get() != 0 {
|
||||
uart.Receive(byte(nrf.UART0.RXD.Get()))
|
||||
nrf.UART0.EVENTS_RXDRDY.Set(0x0)
|
||||
|
||||
@@ -20,11 +20,6 @@ func (uart UART) setPins(tx, rx Pin) {
|
||||
nrf.UART0.PSELRXD.Set(uint32(rx))
|
||||
}
|
||||
|
||||
//go:export UART0_IRQHandler
|
||||
func handleUART0() {
|
||||
UART0.handleInterrupt()
|
||||
}
|
||||
|
||||
func (i2c I2C) setPins(scl, sda Pin) {
|
||||
i2c.Bus.PSELSCL.Set(uint32(scl))
|
||||
i2c.Bus.PSELSDA.Set(uint32(sda))
|
||||
|
||||
@@ -21,11 +21,6 @@ func (uart UART) setPins(tx, rx Pin) {
|
||||
nrf.UART0.PSELRXD.Set(uint32(rx))
|
||||
}
|
||||
|
||||
//go:export UARTE0_UART0_IRQHandler
|
||||
func handleUART0() {
|
||||
UART0.handleInterrupt()
|
||||
}
|
||||
|
||||
func (i2c I2C) setPins(scl, sda Pin) {
|
||||
i2c.Bus.PSELSCL.Set(uint32(scl))
|
||||
i2c.Bus.PSELSDA.Set(uint32(sda))
|
||||
|
||||
@@ -77,11 +77,6 @@ func (uart UART) setPins(tx, rx Pin) {
|
||||
nrf.UART0.PSEL.RXD.Set(uint32(rx))
|
||||
}
|
||||
|
||||
//go:export UARTE0_UART0_IRQHandler
|
||||
func handleUART0() {
|
||||
UART0.handleInterrupt()
|
||||
}
|
||||
|
||||
func (i2c I2C) setPins(scl, sda Pin) {
|
||||
i2c.Bus.PSEL.SCL.Set(uint32(scl))
|
||||
i2c.Bus.PSEL.SDA.Set(uint32(sda))
|
||||
|
||||
@@ -5,9 +5,9 @@ package machine
|
||||
// Peripheral abstraction layer for the stm32.
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/stm32"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
@@ -111,9 +111,9 @@ func (p Pin) Get() bool {
|
||||
|
||||
// UART
|
||||
type UART struct {
|
||||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
IRQVal uint32
|
||||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
Interrupt interrupt.Interrupt
|
||||
}
|
||||
|
||||
// Configure the UART.
|
||||
@@ -155,8 +155,8 @@ func (uart UART) Configure(config UARTConfig) {
|
||||
uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
|
||||
|
||||
// Enable RX IRQ
|
||||
arm.SetPriority(uart.IRQVal, 0xc0)
|
||||
arm.EnableIRQ(uart.IRQVal)
|
||||
uart.Interrupt.SetPriority(0xc0)
|
||||
uart.Interrupt.Enable()
|
||||
}
|
||||
|
||||
// SetBaudRate sets the communication speed for the UART.
|
||||
@@ -182,6 +182,12 @@ func (uart UART) WriteByte(c byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleInterrupt should be called from the appropriate interrupt handler for
|
||||
// this UART instance.
|
||||
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
|
||||
uart.Receive(byte((uart.Bus.DR.Get() & 0xFF)))
|
||||
}
|
||||
|
||||
// SPI on the STM32.
|
||||
type SPI struct {
|
||||
Bus *stm32.SPI_Type
|
||||
|
||||
@@ -5,8 +5,8 @@ package machine
|
||||
// Peripheral abstraction layer for the stm32.
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
@@ -203,8 +203,11 @@ func (uart UART) Configure(config UARTConfig) {
|
||||
stm32.USART2.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
|
||||
|
||||
// Enable RX IRQ.
|
||||
arm.SetPriority(stm32.IRQ_USART2, 0xc0)
|
||||
arm.EnableIRQ(stm32.IRQ_USART2)
|
||||
intr := interrupt.New(stm32.IRQ_USART2, func(interrupt.Interrupt) {
|
||||
UART1.Receive(byte((stm32.USART2.DR.Get() & 0xFF)))
|
||||
})
|
||||
intr.SetPriority(0xc0)
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
// WriteByte writes a byte of data to the UART.
|
||||
@@ -215,8 +218,3 @@ func (uart UART) WriteByte(c byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:export USART2_IRQHandler
|
||||
func handleUSART2() {
|
||||
UART1.Receive(byte((stm32.USART2.DR.Get() & 0xFF)))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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
|
||||
|
||||
// handle is used internally, between IR generation and interrupt lowering. The
|
||||
// frontend will create runtime/interrupt.handle objects, cast them to an int,
|
||||
// and use that in an Interrupt object. That way the compiler will be able to
|
||||
// optimize away all interrupt handles that are never used in a program.
|
||||
// This system only works when interrupts need to be enabled before use and this
|
||||
// is done only through calling Enable() on this object. If interrups cannot
|
||||
// individually be enabled/disabled, the compiler should create a pseudo-call
|
||||
// (like runtime/interrupt.use()) that keeps the interrupt alive.
|
||||
type handle struct {
|
||||
handler func(Interrupt)
|
||||
Interrupt
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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_)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"device/arm"
|
||||
"device/sam"
|
||||
"machine"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
@@ -202,8 +203,14 @@ func initRTC() {
|
||||
for sam.RTC_MODE0.SYNCBUSY.HasBits(sam.RTC_MODE0_SYNCBUSY_ENABLE) {
|
||||
}
|
||||
|
||||
arm.SetPriority(sam.IRQ_RTC, 0xc0)
|
||||
arm.EnableIRQ(sam.IRQ_RTC)
|
||||
irq := interrupt.New(sam.IRQ_RTC, func(interrupt.Interrupt) {
|
||||
// disable IRQ for CMP0 compare
|
||||
sam.RTC_MODE0.INTFLAG.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
|
||||
|
||||
timerWakeup.Set(1)
|
||||
})
|
||||
irq.SetPriority(0xc0)
|
||||
irq.Enable()
|
||||
}
|
||||
|
||||
func waitForSync() {
|
||||
@@ -271,14 +278,6 @@ func timerSleep(ticks uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
//go:export RTC_IRQHandler
|
||||
func handleRTC() {
|
||||
// disable IRQ for CMP0 compare
|
||||
sam.RTC_MODE0.INTFLAG.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
|
||||
|
||||
timerWakeup.Set(1)
|
||||
}
|
||||
|
||||
func initUSBClock() {
|
||||
// Turn on clock(s) for USB
|
||||
//MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"device/arm"
|
||||
"device/stm32"
|
||||
"machine"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
@@ -101,8 +102,9 @@ func initRTC() {
|
||||
func initTIM() {
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
|
||||
|
||||
arm.SetPriority(stm32.IRQ_TIM3, 0xc3)
|
||||
arm.EnableIRQ(stm32.IRQ_TIM3)
|
||||
intr := interrupt.New(stm32.IRQ_TIM3, handleTIM3)
|
||||
intr.SetPriority(0xc3)
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
const asyncScheduler = false
|
||||
@@ -186,8 +188,7 @@ func timerSleep(ticks uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
//go:export TIM3_IRQHandler
|
||||
func handleTIM3() {
|
||||
func handleTIM3(interrupt.Interrupt) {
|
||||
if stm32.TIM3.SR.HasBits(stm32.TIM_SR_UIF) {
|
||||
// Disable the timer.
|
||||
stm32.TIM3.CR1.ClearBits(stm32.TIM_CR1_CEN)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"device/arm"
|
||||
"device/stm32"
|
||||
"machine"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
@@ -121,8 +122,9 @@ var timerWakeup volatile.Register8
|
||||
func initTIM3() {
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
|
||||
|
||||
arm.SetPriority(stm32.IRQ_TIM3, 0xc3)
|
||||
arm.EnableIRQ(stm32.IRQ_TIM3)
|
||||
intr := interrupt.New(stm32.IRQ_TIM3, handleTIM3)
|
||||
intr.SetPriority(0xc3)
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
// Enable the TIM7 clock.(tick count)
|
||||
@@ -139,8 +141,9 @@ func initTIM7() {
|
||||
// Enable the timer.
|
||||
stm32.TIM7.CR1.SetBits(stm32.TIM_CR1_CEN)
|
||||
|
||||
arm.SetPriority(stm32.IRQ_TIM7, 0xc1)
|
||||
arm.EnableIRQ(stm32.IRQ_TIM7)
|
||||
intr := interrupt.New(stm32.IRQ_TIM7, handleTIM7)
|
||||
intr.SetPriority(0xc1)
|
||||
intr.Enable()
|
||||
}
|
||||
|
||||
const asyncScheduler = false
|
||||
@@ -183,8 +186,7 @@ func timerSleep(ticks uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
//go:export TIM3_IRQHandler
|
||||
func handleTIM3() {
|
||||
func handleTIM3(interrupt.Interrupt) {
|
||||
if stm32.TIM3.SR.HasBits(stm32.TIM_SR_UIF) {
|
||||
// Disable the timer.
|
||||
stm32.TIM3.CR1.ClearBits(stm32.TIM_CR1_CEN)
|
||||
@@ -197,8 +199,7 @@ func handleTIM3() {
|
||||
}
|
||||
}
|
||||
|
||||
//go:export TIM7_IRQHandler
|
||||
func handleTIM7() {
|
||||
func handleTIM7(interrupt.Interrupt) {
|
||||
if stm32.TIM7.SR.HasBits(stm32.TIM_SR_UIF) {
|
||||
// clear the update flag
|
||||
stm32.TIM7.SR.ClearBits(stm32.TIM_SR_UIF)
|
||||
|
||||
Reference in New Issue
Block a user