github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_mimxrt1062.go (about) 1 //go:build mimxrt1062 2 3 package runtime 4 5 import ( 6 "device/arm" 7 "device/nxp" 8 "machine" 9 "math/bits" 10 "unsafe" 11 ) 12 13 //go:extern _svectors 14 var _svectors [0]byte 15 16 //go:extern _flexram_cfg 17 var _flexram_cfg [0]byte 18 19 //export Reset_Handler 20 func main() { 21 22 // disable interrupts 23 irq := arm.DisableInterrupts() 24 25 // initialize FPU and VTOR, reset watchdogs 26 initSystem() 27 28 // configure core and peripheral clocks/PLLs/PFDs 29 initClocks() 30 31 // copy data/bss sections from flash to RAM 32 preinit() 33 34 // initialize cache and MPU 35 initCache() 36 37 // enable SysTick, GPIO, and peripherals 38 initPeripherals() 39 40 // reenable interrupts 41 arm.EnableInterrupts(irq) 42 43 run() 44 exit(0) 45 } 46 47 func getRamSizeConfig(itcmKB, dtcmKB uint32) uint32 { 48 const minKB, disabled = uint32(4), uint32(0) 49 if itcmKB < minKB { 50 itcmKB = disabled 51 } 52 if dtcmKB < minKB { 53 dtcmKB = disabled 54 } 55 itcmKB = uint32(bits.Len(uint(itcmKB))) << nxp.IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_Pos 56 dtcmKB = uint32(bits.Len(uint(dtcmKB))) << nxp.IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_Pos 57 return (itcmKB & nxp.IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_Msk) | 58 (dtcmKB & nxp.IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_Msk) 59 } 60 61 func initSystem() { 62 63 // configure SRAM capacity (512K for both ITCM and DTCM) 64 ramc := uintptr(unsafe.Pointer(&_flexram_cfg)) 65 nxp.IOMUXC_GPR.GPR17.Set(uint32(ramc)) 66 nxp.IOMUXC_GPR.GPR16.Set(0x00200007) 67 nxp.IOMUXC_GPR.GPR14.Set(getRamSizeConfig(512, 512)) 68 69 // from Teensyduino 70 nxp.PMU.MISC0_SET.Set(nxp.PMU_MISC0_REFTOP_SELFBIASOFF) 71 72 // install vector table (TODO: initialize interrupt/exception table?) 73 vtor := uintptr(unsafe.Pointer(&_svectors)) 74 nxp.SystemControl.VTOR.Set(uint32(vtor)) 75 76 const wdogUpdateKey = 0xD928C520 77 78 // disable watchdog powerdown counter 79 nxp.WDOG1.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk) 80 nxp.WDOG2.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk) 81 82 // disable watchdog 83 if nxp.WDOG1.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) { 84 nxp.WDOG1.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk) 85 } 86 if nxp.WDOG2.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) { 87 nxp.WDOG2.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk) 88 } 89 if nxp.RTWDOG.CS.HasBits(nxp.RTWDOG_CS_CMD32EN_Msk) { 90 nxp.RTWDOG.CNT.Set(wdogUpdateKey) 91 } else { 92 nxp.RTWDOG.CNT.Set((wdogUpdateKey >> 0) & 0xFFFF) 93 nxp.RTWDOG.CNT.Set((wdogUpdateKey >> 16) & 0xFFFF) 94 } 95 nxp.RTWDOG.TOVAL.Set(0xFFFF) 96 nxp.RTWDOG.CS.Set((nxp.RTWDOG.CS.Get() & ^uint32(nxp.RTWDOG_CS_EN_Msk)) | nxp.RTWDOG_CS_UPDATE_Msk) 97 } 98 99 func initPeripherals() { 100 101 enableTimerClocks() // activate GPT/PIT clock gates 102 initSysTick() // enable SysTick 103 initRTC() // enable real-time clock 104 105 enablePinClocks() // activate IOMUXC(_GPR)/GPIO clock gates 106 initPins() // configure GPIO 107 108 enablePeripheralClocks() // activate peripheral clock gates 109 initUART() // configure UART (initialized first for debugging) 110 } 111 112 func initPins() { 113 // use fast GPIO for all pins (GPIO6-9) 114 nxp.IOMUXC_GPR.GPR26.Set(0xFFFFFFFF) 115 nxp.IOMUXC_GPR.GPR27.Set(0xFFFFFFFF) 116 nxp.IOMUXC_GPR.GPR28.Set(0xFFFFFFFF) 117 nxp.IOMUXC_GPR.GPR29.Set(0xFFFFFFFF) 118 } 119 120 func initUART() { 121 machine.InitSerial() 122 } 123 124 func putchar(c byte) { 125 machine.Serial.WriteByte(c) 126 } 127 128 func getchar() byte { 129 for machine.UART1.Buffered() == 0 { 130 Gosched() 131 } 132 v, _ := machine.UART1.ReadByte() 133 return v 134 } 135 136 func buffered() int { 137 return machine.UART1.Buffered() 138 } 139 140 func exit(code int) { 141 abort() 142 } 143 144 func abort() { 145 for { 146 arm.Asm("wfe") 147 } 148 } 149 150 func waitForEvents() { 151 arm.Asm("wfe") 152 }