mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 04:53:42 +00:00
teensy40: initial implementation
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// +build nxp,!mimxrt1062
|
||||
|
||||
package runtime
|
||||
|
||||
import "device/nxp"
|
||||
|
||||
const (
|
||||
CFSR_IACCVIOL = nxp.SystemControl_CFSR_IACCVIOL
|
||||
CFSR_DACCVIOL = nxp.SystemControl_CFSR_DACCVIOL
|
||||
CFSR_MUNSTKERR = nxp.SystemControl_CFSR_MUNSTKERR
|
||||
CFSR_MSTKERR = nxp.SystemControl_CFSR_MSTKERR
|
||||
CFSR_MLSPERR = nxp.SystemControl_CFSR_MLSPERR
|
||||
CFSR_IBUSERR = nxp.SystemControl_CFSR_IBUSERR
|
||||
CFSR_PRECISERR = nxp.SystemControl_CFSR_PRECISERR
|
||||
CFSR_IMPRECISERR = nxp.SystemControl_CFSR_IMPRECISERR
|
||||
CFSR_UNSTKERR = nxp.SystemControl_CFSR_UNSTKERR
|
||||
CFSR_STKERR = nxp.SystemControl_CFSR_STKERR
|
||||
CFSR_LSPERR = nxp.SystemControl_CFSR_LSPERR
|
||||
CFSR_UNDEFINSTR = nxp.SystemControl_CFSR_UNDEFINSTR
|
||||
CFSR_INVSTATE = nxp.SystemControl_CFSR_INVSTATE
|
||||
CFSR_INVPC = nxp.SystemControl_CFSR_INVPC
|
||||
CFSR_NOCP = nxp.SystemControl_CFSR_NOCP
|
||||
CFSR_UNALIGNED = nxp.SystemControl_CFSR_UNALIGNED
|
||||
CFSR_DIVBYZERO = nxp.SystemControl_CFSR_DIVBYZERO
|
||||
CFSR_MMARVALID = nxp.SystemControl_CFSR_MMARVALID
|
||||
CFSR_BFARVALID = nxp.SystemControl_CFSR_BFARVALID
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
// +build nxp,mimxrt1062
|
||||
|
||||
package runtime
|
||||
|
||||
import "device/nxp"
|
||||
|
||||
const (
|
||||
CFSR_IACCVIOL = nxp.SCB_CFSR_IACCVIOL
|
||||
CFSR_DACCVIOL = nxp.SCB_CFSR_DACCVIOL
|
||||
CFSR_MUNSTKERR = nxp.SCB_CFSR_MUNSTKERR
|
||||
CFSR_MSTKERR = nxp.SCB_CFSR_MSTKERR
|
||||
CFSR_MLSPERR = nxp.SCB_CFSR_MLSPERR
|
||||
CFSR_IBUSERR = nxp.SCB_CFSR_IBUSERR
|
||||
CFSR_PRECISERR = nxp.SCB_CFSR_PRECISERR
|
||||
CFSR_IMPRECISERR = nxp.SCB_CFSR_IMPRECISERR
|
||||
CFSR_UNSTKERR = nxp.SCB_CFSR_UNSTKERR
|
||||
CFSR_STKERR = nxp.SCB_CFSR_STKERR
|
||||
CFSR_LSPERR = nxp.SCB_CFSR_LSPERR
|
||||
CFSR_UNDEFINSTR = nxp.SCB_CFSR_UNDEFINSTR
|
||||
CFSR_INVSTATE = nxp.SCB_CFSR_INVSTATE
|
||||
CFSR_INVPC = nxp.SCB_CFSR_INVPC
|
||||
CFSR_NOCP = nxp.SCB_CFSR_NOCP
|
||||
CFSR_UNALIGNED = nxp.SCB_CFSR_UNALIGNED
|
||||
CFSR_DIVBYZERO = nxp.SCB_CFSR_DIVBYZERO
|
||||
CFSR_MMARVALID = nxp.SCB_CFSR_MMARVALID
|
||||
CFSR_BFARVALID = nxp.SCB_CFSR_BFARVALID
|
||||
)
|
||||
@@ -8,7 +8,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SystemControl_CFSR_KnownFault = nxp.SystemControl_CFSR_IACCVIOL | nxp.SystemControl_CFSR_DACCVIOL | nxp.SystemControl_CFSR_MUNSTKERR | nxp.SystemControl_CFSR_MSTKERR | nxp.SystemControl_CFSR_MLSPERR | nxp.SystemControl_CFSR_IBUSERR | nxp.SystemControl_CFSR_PRECISERR | nxp.SystemControl_CFSR_IMPRECISERR | nxp.SystemControl_CFSR_UNSTKERR | nxp.SystemControl_CFSR_STKERR | nxp.SystemControl_CFSR_LSPERR | nxp.SystemControl_CFSR_UNDEFINSTR | nxp.SystemControl_CFSR_INVSTATE | nxp.SystemControl_CFSR_INVPC | nxp.SystemControl_CFSR_NOCP | nxp.SystemControl_CFSR_UNALIGNED | nxp.SystemControl_CFSR_DIVBYZERO
|
||||
SystemControl_CFSR_KnownFault = CFSR_IACCVIOL | CFSR_DACCVIOL |
|
||||
CFSR_MUNSTKERR | CFSR_MSTKERR | CFSR_MLSPERR | CFSR_IBUSERR |
|
||||
CFSR_PRECISERR | CFSR_IMPRECISERR | CFSR_UNSTKERR | CFSR_STKERR |
|
||||
CFSR_LSPERR | CFSR_UNDEFINSTR | CFSR_INVSTATE | CFSR_INVPC | CFSR_NOCP |
|
||||
CFSR_UNALIGNED | CFSR_DIVBYZERO
|
||||
)
|
||||
|
||||
// See runtime_cortexm_hardfault.go
|
||||
@@ -128,7 +132,7 @@ func (fs FaultStatus) Unknown() bool { return fs&SystemControl_CFSR_KnownFault =
|
||||
// the faulting instruction. The processor has not written a fault address to
|
||||
// the MMAR."
|
||||
func (fs MemFaultStatus) InstructionAccessViolation() bool {
|
||||
return fs&nxp.SystemControl_CFSR_IACCVIOL != 0
|
||||
return fs&CFSR_IACCVIOL != 0
|
||||
}
|
||||
|
||||
// DataAccessViolation: the processor attempted a load or store at a location
|
||||
@@ -137,7 +141,7 @@ func (fs MemFaultStatus) InstructionAccessViolation() bool {
|
||||
// "When this bit is 1, the PC value stacked for the exception return points to
|
||||
// the faulting instruction. The processor has loaded the MMAR with the address
|
||||
// of the attempted access."
|
||||
func (fs MemFaultStatus) DataAccessViolation() bool { return fs&nxp.SystemControl_CFSR_DACCVIOL != 0 }
|
||||
func (fs MemFaultStatus) DataAccessViolation() bool { return fs&CFSR_DACCVIOL != 0 }
|
||||
|
||||
// WhileUnstackingException: unstack for an exception return has caused one or
|
||||
// more access violations
|
||||
@@ -147,7 +151,7 @@ func (fs MemFaultStatus) DataAccessViolation() bool { return fs&nxp.SystemContro
|
||||
// the SP from the failing return, and has not performed a new save. The
|
||||
// processor has not written a fault address to the MMAR."
|
||||
func (fs MemFaultStatus) WhileUnstackingException() bool {
|
||||
return fs&nxp.SystemControl_CFSR_MUNSTKERR != 0
|
||||
return fs&CFSR_MUNSTKERR != 0
|
||||
}
|
||||
|
||||
// WileStackingException: stacking for an exception entry has caused one or more
|
||||
@@ -156,11 +160,11 @@ func (fs MemFaultStatus) WhileUnstackingException() bool {
|
||||
// "When this bit is 1, the SP is still adjusted but the values in the context
|
||||
// area on the stack might be incorrect. The processor has not written a fault
|
||||
// address to the MMAR."
|
||||
func (fs MemFaultStatus) WileStackingException() bool { return fs&nxp.SystemControl_CFSR_MSTKERR != 0 }
|
||||
func (fs MemFaultStatus) WileStackingException() bool { return fs&CFSR_MSTKERR != 0 }
|
||||
|
||||
// DuringFPLazyStatePres: A MemManage fault occurred during floating-point lazy
|
||||
// state preservation
|
||||
func (fs MemFaultStatus) DuringFPLazyStatePres() bool { return fs&nxp.SystemControl_CFSR_MLSPERR != 0 }
|
||||
func (fs MemFaultStatus) DuringFPLazyStatePres() bool { return fs&CFSR_MLSPERR != 0 }
|
||||
|
||||
// InstructionBusError: instruction bus error
|
||||
//
|
||||
@@ -170,11 +174,11 @@ func (fs MemFaultStatus) DuringFPLazyStatePres() bool { return fs&nxp.SystemCont
|
||||
//
|
||||
// When the processor sets this bit is 1, it does not write a fault address to
|
||||
// the BFAR."
|
||||
func (fs BusFaultStatus) InstructionBusError() bool { return fs&nxp.SystemControl_CFSR_IBUSERR != 0 }
|
||||
func (fs BusFaultStatus) InstructionBusError() bool { return fs&CFSR_IBUSERR != 0 }
|
||||
|
||||
// PreciseDataBusError: a data bus error has occurred, and the PC value stacked
|
||||
// for the exception return points to the instruction that caused the fault
|
||||
func (fs BusFaultStatus) PreciseDataBusError() bool { return fs&nxp.SystemControl_CFSR_PRECISERR != 0 }
|
||||
func (fs BusFaultStatus) PreciseDataBusError() bool { return fs&CFSR_PRECISERR != 0 }
|
||||
|
||||
// ImpreciseDataBusError: a data bus error has occurred, but the return address
|
||||
// in the stack frame is not related to the instruction that caused the error
|
||||
@@ -189,7 +193,7 @@ func (fs BusFaultStatus) PreciseDataBusError() bool { return fs&nxp.SystemContro
|
||||
// enters the handler for the imprecise BusFault, the handler detects both
|
||||
// IMPRECISERR set to 1 and one of the precise fault status bits set to 1."
|
||||
func (fs BusFaultStatus) ImpreciseDataBusError() bool {
|
||||
return fs&nxp.SystemControl_CFSR_IMPRECISERR != 0
|
||||
return fs&CFSR_IMPRECISERR != 0
|
||||
}
|
||||
|
||||
// WhileUnstackingException: unstack for an exception return has caused one or
|
||||
@@ -200,7 +204,7 @@ func (fs BusFaultStatus) ImpreciseDataBusError() bool {
|
||||
// does not adjust the SP from the failing return, does not performed a new
|
||||
// save, and does not write a fault address to the BFAR."
|
||||
func (fs BusFaultStatus) WhileUnstackingException() bool {
|
||||
return fs&nxp.SystemControl_CFSR_UNSTKERR != 0
|
||||
return fs&CFSR_UNSTKERR != 0
|
||||
}
|
||||
|
||||
// WhileStackingException: stacking for an exception entry has caused one or
|
||||
@@ -209,11 +213,11 @@ func (fs BusFaultStatus) WhileUnstackingException() bool {
|
||||
// "When the processor sets this bit to 1, the SP is still adjusted but the
|
||||
// values in the context area on the stack might be incorrect. The processor
|
||||
// does not write a fault address to the BFAR."
|
||||
func (fs BusFaultStatus) WhileStackingException() bool { return fs&nxp.SystemControl_CFSR_STKERR != 0 }
|
||||
func (fs BusFaultStatus) WhileStackingException() bool { return fs&CFSR_STKERR != 0 }
|
||||
|
||||
// DuringFPLazyStatePres: A bus fault occurred during floating-point lazy state
|
||||
// preservation
|
||||
func (fs BusFaultStatus) DuringFPLazyStatePres() bool { return fs&nxp.SystemControl_CFSR_LSPERR != 0 }
|
||||
func (fs BusFaultStatus) DuringFPLazyStatePres() bool { return fs&CFSR_LSPERR != 0 }
|
||||
|
||||
// UndefinedInstruction: the processor has attempted to execute an undefined
|
||||
// instruction
|
||||
@@ -223,7 +227,7 @@ func (fs BusFaultStatus) DuringFPLazyStatePres() bool { return fs&nxp.SystemCont
|
||||
//
|
||||
// An undefined instruction is an instruction that the processor cannot decode."
|
||||
func (fs UsageFaultStatus) UndefinedInstruction() bool {
|
||||
return fs&nxp.SystemControl_CFSR_UNDEFINSTR != 0
|
||||
return fs&CFSR_UNDEFINSTR != 0
|
||||
}
|
||||
|
||||
// IllegalUseOfEPSR: the processor has attempted to execute an instruction that
|
||||
@@ -233,19 +237,19 @@ func (fs UsageFaultStatus) UndefinedInstruction() bool {
|
||||
// points to the instruction that attempted the illegal use of the EPSR.
|
||||
//
|
||||
// This bit is not set to 1 if an undefined instruction uses the EPSR."
|
||||
func (fs UsageFaultStatus) IllegalUseOfEPSR() bool { return fs&nxp.SystemControl_CFSR_INVSTATE != 0 }
|
||||
func (fs UsageFaultStatus) IllegalUseOfEPSR() bool { return fs&CFSR_INVSTATE != 0 }
|
||||
|
||||
// IllegalExceptionReturn: the processor has attempted an illegal load of
|
||||
// EXC_RETURN to the PC
|
||||
//
|
||||
// "When this bit is set to 1, the PC value stacked for the exception return
|
||||
// points to the instruction that tried to perform the illegal load of the PC."
|
||||
func (fs UsageFaultStatus) IllegalExceptionReturn() bool { return fs&nxp.SystemControl_CFSR_INVPC != 0 }
|
||||
func (fs UsageFaultStatus) IllegalExceptionReturn() bool { return fs&CFSR_INVPC != 0 }
|
||||
|
||||
// AttemptedToAccessCoprocessor: the processor has attempted to access a
|
||||
// coprocessor
|
||||
func (fs UsageFaultStatus) AttemptedToAccessCoprocessor() bool {
|
||||
return fs&nxp.SystemControl_CFSR_NOCP != 0
|
||||
return fs&CFSR_NOCP != 0
|
||||
}
|
||||
|
||||
// UnalignedMemoryAccess: the processor has made an unaligned memory access
|
||||
@@ -256,7 +260,7 @@ func (fs UsageFaultStatus) AttemptedToAccessCoprocessor() bool {
|
||||
// Unaligned LDM, STM, LDRD, and STRD instructions always fault irrespective of
|
||||
// the setting of UNALIGN_TRP."
|
||||
func (fs UsageFaultStatus) UnalignedMemoryAccess() bool {
|
||||
return fs&nxp.SystemControl_CFSR_UNALIGNED != 0
|
||||
return fs&CFSR_UNALIGNED != 0
|
||||
}
|
||||
|
||||
// DivideByZero: the processor has executed an SDIV or UDIV instruction with a
|
||||
@@ -267,7 +271,7 @@ func (fs UsageFaultStatus) UnalignedMemoryAccess() bool {
|
||||
//
|
||||
// Enable trapping of divide by zero by setting the DIV_0_TRP bit in the CCR to
|
||||
// 1."
|
||||
func (fs UsageFaultStatus) DivideByZero() bool { return fs&nxp.SystemControl_CFSR_DIVBYZERO != 0 }
|
||||
func (fs UsageFaultStatus) DivideByZero() bool { return fs&CFSR_DIVBYZERO != 0 }
|
||||
|
||||
// Address returns the MemManage Fault Address Register if the fault status
|
||||
// indicates the address is valid.
|
||||
@@ -277,7 +281,7 @@ func (fs UsageFaultStatus) DivideByZero() bool { return fs&nxp.SystemControl_CFS
|
||||
// problems on return to a stacked active MemManage fault handler whose MMAR
|
||||
// value has been overwritten."
|
||||
func (fs MemFaultStatus) Address() (uintptr, bool) {
|
||||
if fs&nxp.SystemControl_CFSR_MMARVALID == 0 {
|
||||
if fs&CFSR_MMARVALID == 0 {
|
||||
return 0, false
|
||||
} else {
|
||||
return uintptr(nxp.SystemControl.MMFAR.Get()), true
|
||||
@@ -296,7 +300,7 @@ func (fs MemFaultStatus) Address() (uintptr, bool) {
|
||||
// returning to a stacked active BusFault handler whose BFAR value has been
|
||||
// overwritten.""
|
||||
func (fs BusFaultStatus) Address() (uintptr, bool) {
|
||||
if fs&nxp.SystemControl_CFSR_BFARVALID == 0 {
|
||||
if fs&CFSR_BFARVALID == 0 {
|
||||
return 0, false
|
||||
} else {
|
||||
return uintptr(nxp.SystemControl.BFAR.Get()), true
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
// +build mimxrt1062
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/nxp"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const asyncScheduler = false
|
||||
|
||||
//go:extern _svectors
|
||||
var _svectors [0]byte
|
||||
|
||||
//go:extern _flexram_cfg
|
||||
var _flexram_cfg [0]byte
|
||||
|
||||
func postinit() {}
|
||||
|
||||
//export Reset_Handler
|
||||
func main() {
|
||||
|
||||
// disable interrupts
|
||||
irq := arm.DisableInterrupts()
|
||||
|
||||
// initialize FPU and VTOR, reset watchdogs
|
||||
initSystem()
|
||||
|
||||
// configure core and peripheral clocks/PLLs/PFDs
|
||||
initClocks()
|
||||
|
||||
// copy data/bss sections from flash to RAM
|
||||
preinit()
|
||||
|
||||
// initialize cache and MPU
|
||||
initCache()
|
||||
|
||||
// enable SysTick, GPIO, and peripherals
|
||||
initPeripherals()
|
||||
|
||||
// reenable interrupts
|
||||
arm.EnableInterrupts(irq)
|
||||
|
||||
run()
|
||||
abort()
|
||||
}
|
||||
|
||||
func initSystem() {
|
||||
|
||||
// configure SRAM capacity
|
||||
ramc := uintptr(unsafe.Pointer(&_flexram_cfg))
|
||||
nxp.IOMUXC_GPR.GPR17.Set(uint32(ramc))
|
||||
nxp.IOMUXC_GPR.GPR16.Set(0x00200007)
|
||||
nxp.IOMUXC_GPR.GPR14.Set(0x00AA0000)
|
||||
|
||||
// use bandgap-based bias currents for best performance (Page 1175) [Teensyduino]
|
||||
nxp.PMU.MISC0_SET.Set(1 << 3)
|
||||
|
||||
// install vector table (TODO: initialize interrupt/exception table?)
|
||||
vtor := uintptr(unsafe.Pointer(&_svectors))
|
||||
nxp.SystemControl.VTOR.Set(uint32(vtor))
|
||||
|
||||
// disable watchdog powerdown counter
|
||||
nxp.WDOG1.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk)
|
||||
nxp.WDOG2.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk)
|
||||
|
||||
// disable watchdog
|
||||
if nxp.WDOG1.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) {
|
||||
nxp.WDOG1.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk)
|
||||
}
|
||||
if nxp.WDOG2.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) {
|
||||
nxp.WDOG2.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk)
|
||||
}
|
||||
if nxp.RTWDOG.CS.HasBits(nxp.RTWDOG_CS_CMD32EN_Msk) {
|
||||
nxp.RTWDOG.CNT.Set(0xD928C520) // 0xD928C520 is the update key
|
||||
} else {
|
||||
nxp.RTWDOG.CNT.Set(0xC520)
|
||||
nxp.RTWDOG.CNT.Set(0xD928)
|
||||
}
|
||||
nxp.RTWDOG.TOVAL.Set(0xFFFF)
|
||||
nxp.RTWDOG.CS.Set((nxp.RTWDOG.CS.Get() & ^uint32(nxp.RTWDOG_CS_EN_Msk)) | nxp.RTWDOG_CS_UPDATE_Msk)
|
||||
}
|
||||
|
||||
func initPeripherals() {
|
||||
|
||||
// enable FPU - set CP10, CP11 full access
|
||||
nxp.SystemControl.CPACR.SetBits((3 << (10 * 2)) | (3 << (11 * 2)))
|
||||
|
||||
enableTimerClocks() // activate GPT/PIT clock gates
|
||||
initSysTick() // enable SysTick
|
||||
|
||||
enablePinClocks() // activate IOMUXC(_GPR)/GPIO clock gates
|
||||
initPins() // configure GPIO
|
||||
|
||||
enablePeripheralClocks() // activate peripheral clock gates
|
||||
}
|
||||
|
||||
func initPins() {
|
||||
// use fast GPIO for all pins (GPIO6-9)
|
||||
nxp.IOMUXC_GPR.GPR26.Set(0xFFFFFFFF)
|
||||
nxp.IOMUXC_GPR.GPR27.Set(0xFFFFFFFF)
|
||||
nxp.IOMUXC_GPR.GPR28.Set(0xFFFFFFFF)
|
||||
nxp.IOMUXC_GPR.GPR29.Set(0xFFFFFFFF)
|
||||
}
|
||||
|
||||
func putchar(c byte) {}
|
||||
|
||||
func abort() {
|
||||
for {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
}
|
||||
|
||||
func waitForEvents() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,349 @@
|
||||
// +build mimxrt1062
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/nxp"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type MPU_Type struct {
|
||||
TYPE volatile.Register32 // 0x000 (R/ ) - MPU Type Register
|
||||
CTRL volatile.Register32 // 0x004 (R/W) - MPU Control Register
|
||||
RNR volatile.Register32 // 0x008 (R/W) - MPU Region RNRber Register
|
||||
RBAR volatile.Register32 // 0x00C (R/W) - MPU Region Base Address Register
|
||||
RASR volatile.Register32 // 0x010 (R/W) - MPU Region Attribute and Size Register
|
||||
RBAR_A1 volatile.Register32 // 0x014 (R/W) - MPU Alias 1 Region Base Address Register
|
||||
RASR_A1 volatile.Register32 // 0x018 (R/W) - MPU Alias 1 Region Attribute and Size Register
|
||||
RBAR_A2 volatile.Register32 // 0x01C (R/W) - MPU Alias 2 Region Base Address Register
|
||||
RASR_A2 volatile.Register32 // 0x020 (R/W) - MPU Alias 2 Region Attribute and Size Register
|
||||
RBAR_A3 volatile.Register32 // 0x024 (R/W) - MPU Alias 3 Region Base Address Register
|
||||
RASR_A3 volatile.Register32 // 0x028 (R/W) - MPU Alias 3 Region Attribute and Size Register
|
||||
}
|
||||
|
||||
var MPU = (*MPU_Type)(unsafe.Pointer(uintptr(0xe000ed90)))
|
||||
|
||||
func initCache() {
|
||||
MPU.initialize()
|
||||
}
|
||||
|
||||
func (mpu *MPU_Type) initialize() {
|
||||
|
||||
mpu.enable(false)
|
||||
|
||||
// -------------------------------------------------------- OVERLAY REGIONS --
|
||||
|
||||
// add Default [0] region to deny access to whole address space to workaround
|
||||
// speculative prefetch. Refer to Arm errata 1013783-B for more details.
|
||||
|
||||
// [0] Default {OVERLAY}:
|
||||
// 4 GiB, -access, @device, -exec, -share, -cache, -buffer, -subregion
|
||||
mpu.setRBAR(0, 0x00000000)
|
||||
mpu.setRASR(rs4GB, apNone, exDevice, false, false, false, false, false)
|
||||
|
||||
// [1] Peripherals {OVERLAY}:
|
||||
// 64 MiB, +ACCESS, @device, +EXEC, -share, -cache, -buffer, -subregion
|
||||
mpu.setRBAR(1, 0x40000000)
|
||||
mpu.setRASR(rs64MB, apFull, exDevice, true, false, false, false, false)
|
||||
|
||||
// [2] RAM {OVERLAY}:
|
||||
// 1 GiB, +ACCESS, @device, +EXEC, -share, -cache, -buffer, -subregion
|
||||
mpu.setRBAR(2, 0x00000000)
|
||||
mpu.setRASR(rs1GB, apFull, exDevice, true, false, false, false, false)
|
||||
|
||||
// ----------------------------------------------------- PERIPHERAL REGIONS --
|
||||
|
||||
// [3] ITCM:
|
||||
// 512 KiB, +ACCESS, #NORMAL, +EXEC, -share, -cache, -buffer, -subregion
|
||||
mpu.setRBAR(3, 0x00000000)
|
||||
mpu.setRASR(rs512KB, apFull, exNormal, true, false, false, false, false)
|
||||
|
||||
// [4] DTCM:
|
||||
// 512 KiB, +ACCESS, #NORMAL, +EXEC, -share, -cache, -buffer, -subregion
|
||||
mpu.setRBAR(4, 0x20000000)
|
||||
mpu.setRASR(rs512KB, apFull, exNormal, true, false, false, false, false)
|
||||
|
||||
// [5] RAM (AXI):
|
||||
// 512 KiB, +ACCESS, #NORMAL, +EXEC, -share, +CACHE, +BUFFER, -subregion
|
||||
mpu.setRBAR(5, 0x20200000)
|
||||
mpu.setRASR(rs512KB, apFull, exNormal, true, false, true, true, false)
|
||||
|
||||
// [6] FlexSPI:
|
||||
// 512 MiB, +ACCESS, #NORMAL, +EXEC, -share, +CACHE, +BUFFER, -subregion
|
||||
mpu.setRBAR(6, 0x70000000)
|
||||
mpu.setRASR(rs512MB, apFull, exNormal, true, false, true, true, false)
|
||||
|
||||
// [7] QSPI flash:
|
||||
// 2 MiB, +ACCESS, #NORMAL, +EXEC, -share, +CACHE, +BUFFER, -subregion
|
||||
mpu.setRBAR(7, 0x60000000)
|
||||
mpu.setRASR(rs2MB, apFull, exNormal, true, false, true, true, false)
|
||||
|
||||
mpu.enable(true)
|
||||
}
|
||||
|
||||
// MPU Type Register Definitions
|
||||
const (
|
||||
MPU_TYPE_IREGION_Pos = 16 // MPU TYPE: IREGION Position
|
||||
MPU_TYPE_IREGION_Msk = 0xFF << MPU_TYPE_IREGION_Pos // MPU TYPE: IREGION Mask
|
||||
MPU_TYPE_DREGION_Pos = 8 // MPU TYPE: DREGION Position
|
||||
MPU_TYPE_DREGION_Msk = 0xFF << MPU_TYPE_DREGION_Pos // MPU TYPE: DREGION Mask
|
||||
MPU_TYPE_SEPARATE_Pos = 0 // MPU TYPE: SEPARATE Position
|
||||
MPU_TYPE_SEPARATE_Msk = 1 // MPU TYPE: SEPARATE Mask
|
||||
)
|
||||
|
||||
// MPU Control Register Definitions
|
||||
const (
|
||||
MPU_CTRL_PRIVDEFENA_Pos = 2 // MPU CTRL: PRIVDEFENA Position
|
||||
MPU_CTRL_PRIVDEFENA_Msk = 1 << MPU_CTRL_PRIVDEFENA_Pos // MPU CTRL: PRIVDEFENA Mask
|
||||
MPU_CTRL_HFNMIENA_Pos = 1 // MPU CTRL: HFNMIENA Position
|
||||
MPU_CTRL_HFNMIENA_Msk = 1 << MPU_CTRL_HFNMIENA_Pos // MPU CTRL: HFNMIENA Mask
|
||||
MPU_CTRL_ENABLE_Pos = 0 // MPU CTRL: ENABLE Position
|
||||
MPU_CTRL_ENABLE_Msk = 1 // MPU CTRL: ENABLE Mask
|
||||
)
|
||||
|
||||
// MPU Region Number Register Definitions
|
||||
const (
|
||||
MPU_RNR_REGION_Pos = 0 // MPU RNR: REGION Position
|
||||
MPU_RNR_REGION_Msk = 0xFF // MPU RNR: REGION Mask
|
||||
)
|
||||
|
||||
// MPU Region Base Address Register Definitions
|
||||
const (
|
||||
MPU_RBAR_ADDR_Pos = 5 // MPU RBAR: ADDR Position
|
||||
MPU_RBAR_ADDR_Msk = 0x7FFFFFF << MPU_RBAR_ADDR_Pos // MPU RBAR: ADDR Mask
|
||||
MPU_RBAR_VALID_Pos = 4 // MPU RBAR: VALID Position
|
||||
MPU_RBAR_VALID_Msk = 1 << MPU_RBAR_VALID_Pos // MPU RBAR: VALID Mask
|
||||
MPU_RBAR_REGION_Pos = 0 // MPU RBAR: REGION Position
|
||||
MPU_RBAR_REGION_Msk = 0xF // MPU RBAR: REGION Mask
|
||||
)
|
||||
|
||||
// MPU Region Attribute and Size Register Definitions
|
||||
const (
|
||||
MPU_RASR_ATTRS_Pos = 16 // MPU RASR: MPU Region Attribute field Position
|
||||
MPU_RASR_ATTRS_Msk = 0xFFFF << MPU_RASR_ATTRS_Pos // MPU RASR: MPU Region Attribute field Mask
|
||||
MPU_RASR_XN_Pos = 28 // MPU RASR: ATTRS.XN Position
|
||||
MPU_RASR_XN_Msk = 1 << MPU_RASR_XN_Pos // MPU RASR: ATTRS.XN Mask
|
||||
MPU_RASR_AP_Pos = 24 // MPU RASR: ATTRS.AP Position
|
||||
MPU_RASR_AP_Msk = 0x7 << MPU_RASR_AP_Pos // MPU RASR: ATTRS.AP Mask
|
||||
MPU_RASR_TEX_Pos = 19 // MPU RASR: ATTRS.TEX Position
|
||||
MPU_RASR_TEX_Msk = 0x7 << MPU_RASR_TEX_Pos // MPU RASR: ATTRS.TEX Mask
|
||||
MPU_RASR_S_Pos = 18 // MPU RASR: ATTRS.S Position
|
||||
MPU_RASR_S_Msk = 1 << MPU_RASR_S_Pos // MPU RASR: ATTRS.S Mask
|
||||
MPU_RASR_C_Pos = 17 // MPU RASR: ATTRS.C Position
|
||||
MPU_RASR_C_Msk = 1 << MPU_RASR_C_Pos // MPU RASR: ATTRS.C Mask
|
||||
MPU_RASR_B_Pos = 16 // MPU RASR: ATTRS.B Position
|
||||
MPU_RASR_B_Msk = 1 << MPU_RASR_B_Pos // MPU RASR: ATTRS.B Mask
|
||||
MPU_RASR_SRD_Pos = 8 // MPU RASR: Sub-Region Disable Position
|
||||
MPU_RASR_SRD_Msk = 0xFF << MPU_RASR_SRD_Pos // MPU RASR: Sub-Region Disable Mask
|
||||
MPU_RASR_SIZE_Pos = 1 // MPU RASR: Region Size Field Position
|
||||
MPU_RASR_SIZE_Msk = 0x1F << MPU_RASR_SIZE_Pos // MPU RASR: Region Size Field Mask
|
||||
MPU_RASR_ENABLE_Pos = 0 // MPU RASR: Region enable bit Position
|
||||
MPU_RASR_ENABLE_Msk = 1 // MPU RASR: Region enable bit Disable Mask
|
||||
)
|
||||
|
||||
const (
|
||||
SCB_DCISW_WAY_Pos = 30 // SCB DCISW: Way Position
|
||||
SCB_DCISW_WAY_Msk = 3 << SCB_DCISW_WAY_Pos // SCB DCISW: Way Mask
|
||||
SCB_DCISW_SET_Pos = 5 // SCB DCISW: Set Position
|
||||
SCB_DCISW_SET_Msk = 0x1FF << SCB_DCISW_SET_Pos // SCB DCISW: Set Mask
|
||||
)
|
||||
|
||||
const (
|
||||
SCB_DCCISW_WAY_Pos = 30 // SCB DCCISW: Way Position
|
||||
SCB_DCCISW_WAY_Msk = 3 << SCB_DCCISW_WAY_Pos // SCB DCCISW: Way Mask
|
||||
SCB_DCCISW_SET_Pos = 5 // SCB DCCISW: Set Position
|
||||
SCB_DCCISW_SET_Msk = 0x1FF << SCB_DCCISW_SET_Pos // SCB DCCISW: Set Mask
|
||||
)
|
||||
|
||||
type regionSize uint32
|
||||
|
||||
const (
|
||||
rs32B regionSize = 0x04 // MPU Region Size 32 Bytes
|
||||
rs64B regionSize = 0x05 // MPU Region Size 64 Bytes
|
||||
rs128B regionSize = 0x06 // MPU Region Size 128 Bytes
|
||||
rs256B regionSize = 0x07 // MPU Region Size 256 Bytes
|
||||
rs512B regionSize = 0x08 // MPU Region Size 512 Bytes
|
||||
rs1KB regionSize = 0x09 // MPU Region Size 1 KByte
|
||||
rs2KB regionSize = 0x0A // MPU Region Size 2 KBytes
|
||||
rs4KB regionSize = 0x0B // MPU Region Size 4 KBytes
|
||||
rs8KB regionSize = 0x0C // MPU Region Size 8 KBytes
|
||||
rs16KB regionSize = 0x0D // MPU Region Size 16 KBytes
|
||||
rs32KB regionSize = 0x0E // MPU Region Size 32 KBytes
|
||||
rs64KB regionSize = 0x0F // MPU Region Size 64 KBytes
|
||||
rs128KB regionSize = 0x10 // MPU Region Size 128 KBytes
|
||||
rs256KB regionSize = 0x11 // MPU Region Size 256 KBytes
|
||||
rs512KB regionSize = 0x12 // MPU Region Size 512 KBytes
|
||||
rs1MB regionSize = 0x13 // MPU Region Size 1 MByte
|
||||
rs2MB regionSize = 0x14 // MPU Region Size 2 MBytes
|
||||
rs4MB regionSize = 0x15 // MPU Region Size 4 MBytes
|
||||
rs8MB regionSize = 0x16 // MPU Region Size 8 MBytes
|
||||
rs16MB regionSize = 0x17 // MPU Region Size 16 MBytes
|
||||
rs32MB regionSize = 0x18 // MPU Region Size 32 MBytes
|
||||
rs64MB regionSize = 0x19 // MPU Region Size 64 MBytes
|
||||
rs128MB regionSize = 0x1A // MPU Region Size 128 MBytes
|
||||
rs256MB regionSize = 0x1B // MPU Region Size 256 MBytes
|
||||
rs512MB regionSize = 0x1C // MPU Region Size 512 MBytes
|
||||
rs1GB regionSize = 0x1D // MPU Region Size 1 GByte
|
||||
rs2GB regionSize = 0x1E // MPU Region Size 2 GBytes
|
||||
rs4GB regionSize = 0x1F // MPU Region Size 4 GBytes
|
||||
)
|
||||
|
||||
type accessPerms uint32
|
||||
|
||||
const (
|
||||
apNone accessPerms = 0 // MPU Access Permission no access
|
||||
apPriv accessPerms = 1 // MPU Access Permission privileged access only
|
||||
apURO accessPerms = 2 // MPU Access Permission unprivileged access read-only
|
||||
apFull accessPerms = 3 // MPU Access Permission full access
|
||||
apPRO accessPerms = 5 // MPU Access Permission privileged access read-only
|
||||
apRO accessPerms = 6 // MPU Access Permission read-only access
|
||||
)
|
||||
|
||||
type extension uint32
|
||||
|
||||
const (
|
||||
exNormal extension = 0
|
||||
exDevice extension = 2
|
||||
)
|
||||
|
||||
func (mpu *MPU_Type) enable(enable bool) {
|
||||
if enable {
|
||||
mpu.CTRL.Set(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk)
|
||||
nxp.SystemControl.SHCSR.SetBits(nxp.SCB_SHCSR_MEMFAULTENA_Msk)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
enableDcache(true)
|
||||
enableIcache(true)
|
||||
} else {
|
||||
enableIcache(false)
|
||||
enableDcache(false)
|
||||
arm.AsmFull(`
|
||||
dmb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.SHCSR.ClearBits(nxp.SCB_SHCSR_MEMFAULTENA_Msk)
|
||||
mpu.CTRL.ClearBits(MPU_CTRL_ENABLE_Msk)
|
||||
}
|
||||
}
|
||||
|
||||
// MPU Region Base Address Register value
|
||||
func (mpu *MPU_Type) setRBAR(region uint32, baseAddress uint32) {
|
||||
mpu.RBAR.Set((baseAddress & MPU_RBAR_ADDR_Msk) |
|
||||
(region & MPU_RBAR_REGION_Msk) | MPU_RBAR_VALID_Msk)
|
||||
}
|
||||
|
||||
// MPU Region Attribute and Size Register value
|
||||
func (mpu *MPU_Type) setRASR(size regionSize, access accessPerms, ext extension, exec, share, cache, buffer, disable bool) {
|
||||
boolBit := func(b bool) uint32 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
attr := ((uint32(ext) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) |
|
||||
((boolBit(share) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) |
|
||||
((boolBit(cache) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) |
|
||||
((boolBit(buffer) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)
|
||||
mpu.RASR.Set(((boolBit(!exec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) |
|
||||
((uint32(access) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) |
|
||||
(attr & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk)) |
|
||||
((boolBit(disable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) |
|
||||
((uint32(size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) |
|
||||
MPU_RASR_ENABLE_Msk)
|
||||
}
|
||||
|
||||
func enableIcache(enable bool) {
|
||||
if enable != nxp.SystemControl.CCR.HasBits(nxp.SCB_CCR_IC_Msk) {
|
||||
if enable {
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.ICIALLU.Set(0)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.CCR.SetBits(nxp.SCB_CCR_IC_Msk)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
} else {
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.CCR.ClearBits(nxp.SCB_CCR_IC_Msk)
|
||||
nxp.SystemControl.ICIALLU.Set(0)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func enableDcache(enable bool) {
|
||||
if enable != nxp.SystemControl.CCR.HasBits(nxp.SCB_CCR_DC_Msk) {
|
||||
if enable {
|
||||
nxp.SystemControl.CSSELR.Set(0)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
`, nil)
|
||||
ccsidr := nxp.SystemControl.CCSIDR.Get()
|
||||
sets := (ccsidr & nxp.SCB_CCSIDR_NUMSETS_Msk) >> nxp.SCB_CCSIDR_NUMSETS_Pos
|
||||
for sets != 0 {
|
||||
ways := (ccsidr & nxp.SCB_CCSIDR_ASSOCIATIVITY_Msk) >> nxp.SCB_CCSIDR_ASSOCIATIVITY_Pos
|
||||
for ways != 0 {
|
||||
nxp.SystemControl.DCISW.Set(
|
||||
((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
|
||||
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk))
|
||||
ways--
|
||||
}
|
||||
sets--
|
||||
}
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.CCR.SetBits(nxp.SCB_CCR_DC_Msk)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
} else {
|
||||
var (
|
||||
ccsidr volatile.Register32
|
||||
sets volatile.Register32
|
||||
ways volatile.Register32
|
||||
)
|
||||
nxp.SystemControl.CSSELR.Set(0)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
`, nil)
|
||||
nxp.SystemControl.CCR.ClearBits(nxp.SCB_CCR_DC_Msk)
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
`, nil)
|
||||
ccsidr.Set(nxp.SystemControl.CCSIDR.Get())
|
||||
sets.Set((ccsidr.Get() & nxp.SCB_CCSIDR_NUMSETS_Msk) >> nxp.SCB_CCSIDR_NUMSETS_Pos)
|
||||
for sets.Get() != 0 {
|
||||
ways.Set((ccsidr.Get() & nxp.SCB_CCSIDR_ASSOCIATIVITY_Msk) >> nxp.SCB_CCSIDR_ASSOCIATIVITY_Pos)
|
||||
for ways.Get() != 0 {
|
||||
nxp.SystemControl.DCCISW.Set(
|
||||
((sets.Get() << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
|
||||
((ways.Get() << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk))
|
||||
ways.Set(ways.Get() - 1)
|
||||
}
|
||||
sets.Set(sets.Get() - 1)
|
||||
}
|
||||
arm.AsmFull(`
|
||||
dsb 0xF
|
||||
isb 0xF
|
||||
`, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// +build mimxrt1062
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/nxp"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
type timeUnit int64
|
||||
|
||||
const (
|
||||
SYST_FREQ = OSC_FREQ // HW divides 24 MHz XTALOSC down to 100 kHz
|
||||
lastCycle = SYST_FREQ/1000 - 1
|
||||
microsPerCycle = 1000000 / SYST_FREQ
|
||||
)
|
||||
|
||||
const (
|
||||
PIT_FREQ = OSC_FREQ // HW divides 24 MHz XTALOSC down to 100 kHz
|
||||
pitMicrosPerCycle = 1000000 / PIT_FREQ
|
||||
pitSleepTimer = 0 // x4 32-bit PIT timers [0..3]
|
||||
)
|
||||
|
||||
var (
|
||||
tickCount volatile.Register64
|
||||
pitActive volatile.Register32
|
||||
pitTimeout interrupt.Interrupt
|
||||
)
|
||||
|
||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||
return int64(ticks) * 1000
|
||||
}
|
||||
|
||||
func nanosecondsToTicks(ns int64) timeUnit {
|
||||
return timeUnit(ns / 1000)
|
||||
}
|
||||
|
||||
func initSysTick() {
|
||||
// disable if already running
|
||||
if arm.SYST.SYST_CSR.HasBits(arm.SYST_CSR_ENABLE_Msk) {
|
||||
arm.SYST.SYST_CSR.ClearBits(arm.SYST_CSR_ENABLE_Msk)
|
||||
}
|
||||
// zeroize the counter
|
||||
tickCount.Set(0)
|
||||
arm.SYST.SYST_RVR.Set(lastCycle)
|
||||
arm.SYST.SYST_CVR.Set(0)
|
||||
arm.SYST.SYST_CSR.Set(arm.SYST_CSR_TICKINT | arm.SYST_CSR_ENABLE)
|
||||
// set SysTick and PendSV priority to 32
|
||||
nxp.SystemControl.SHPR3.Set((0x20 << nxp.SCB_SHPR3_PRI_15_Pos) |
|
||||
(0x20 << nxp.SCB_SHPR3_PRI_14_Pos))
|
||||
// enable PIT, disable counters
|
||||
nxp.PIT.MCR.Set(0)
|
||||
for i := range nxp.PIT.TIMER {
|
||||
nxp.PIT.TIMER[i].TCTRL.Set(0)
|
||||
}
|
||||
// register sleep timer interrupt
|
||||
pitTimeout = interrupt.New(nxp.IRQ_PIT, timerWake)
|
||||
pitTimeout.SetPriority(0x21)
|
||||
pitTimeout.Enable()
|
||||
}
|
||||
|
||||
//go:export SysTick_Handler
|
||||
func tick() {
|
||||
tickCount.Set(tickCount.Get() + 1)
|
||||
}
|
||||
|
||||
func ticks() timeUnit {
|
||||
mask := arm.DisableInterrupts()
|
||||
curr := arm.SYST.SYST_CVR.Get()
|
||||
tick := tickCount.Get()
|
||||
pend := nxp.SystemControl.ICSR.HasBits(nxp.SCB_ICSR_PENDSTSET_Msk)
|
||||
arm.EnableInterrupts(mask)
|
||||
mics := timeUnit(tick * 1000)
|
||||
// if the systick counter was about to reset and ICSR indicates a pending
|
||||
// SysTick IRQ, increment count
|
||||
if pend && (curr > 50) {
|
||||
mics += 1000
|
||||
} else {
|
||||
mics += timeUnit((lastCycle - curr) * microsPerCycle)
|
||||
}
|
||||
return mics
|
||||
}
|
||||
|
||||
func sleepTicks(duration timeUnit) {
|
||||
if duration >= 0 {
|
||||
curr := ticks()
|
||||
last := curr + duration
|
||||
for curr < last {
|
||||
cycles := timeUnit((last - curr) * pitMicrosPerCycle)
|
||||
if cycles > 0xFFFFFFFF {
|
||||
cycles = 0xFFFFFFFF
|
||||
}
|
||||
if !timerSleep(uint32(cycles)) {
|
||||
// return early due to interrupt
|
||||
return
|
||||
}
|
||||
curr = ticks()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func timerSleep(cycles uint32) bool {
|
||||
pitActive.Set(1)
|
||||
nxp.PIT.TIMER[pitSleepTimer].LDVAL.Set(cycles)
|
||||
nxp.PIT.TIMER[pitSleepTimer].TCTRL.Set(nxp.PIT_TIMER_TCTRL_TIE) // enable interrupts
|
||||
nxp.PIT.TIMER[pitSleepTimer].TCTRL.SetBits(nxp.PIT_TIMER_TCTRL_TEN) // start timer
|
||||
for {
|
||||
//arm.Asm("wfi") // TODO: causes hardfault! why?
|
||||
if pitActive.Get() == 0 {
|
||||
return true
|
||||
}
|
||||
if hasScheduler {
|
||||
break // some other interrupt occurred and needs servicing
|
||||
}
|
||||
}
|
||||
timerWake(interrupt.Interrupt{}) // clear and disable timer
|
||||
return false
|
||||
}
|
||||
|
||||
func timerWake(interrupt.Interrupt) {
|
||||
pitActive.Set(0)
|
||||
// TFLGn[TIF] are set to 1 when a timeout occurs on the associated timer, and
|
||||
// are cleared to 0 by writing a 1 to the corresponding TFLGn[TIF].
|
||||
nxp.PIT.TIMER[pitSleepTimer].TFLG.Set(nxp.PIT_TIMER_TFLG_TIF) // clear interrupt flag
|
||||
nxp.PIT.TIMER[pitSleepTimer].TCTRL.Set(0) // disable timer/interrupt enable flags
|
||||
}
|
||||
Reference in New Issue
Block a user