main.s (5459B)
1 .cpu cortex-m0plus 2 .thumb 3 4 .global vectors 5 vectors: 6 .word 0x20040000 // initial SP 7 .word (reset+1) // entry point 8 .word 0xdeadbeef 9 .word 0xdeadbeef 10 11 .word 0xdeadbeef 12 .word 0xdeadbeef 13 .word 0xdeadbeef 14 .word 0xdeadbeef 15 16 .word 0xdeadbeef 17 .word 0xdeadbeef 18 .word 0xdeadbeef 19 .word 0xdeadbeef 20 21 .word 0xdeadbeef 22 .word 0xdeadbeef 23 .word 0xdeadbeef 24 .word 0xdeadbeef 25 26 27 .word 0xdeadbeef 28 .word 0xdeadbeef 29 .word 0xdeadbeef 30 .word 0xdeadbeef 31 32 .word 0xdeadbeef 33 .word 0xdeadbeef 34 .word 0xdeadbeef 35 .word 0xdeadbeef 36 37 .word 0xdeadbeef 38 .word 0xdeadbeef 39 .word 0xdeadbeef 40 .word 0xdeadbeef 41 42 .word 0xdeadbeef 43 .word 0xdeadbeef 44 .word 0xdeadbeef 45 .word 0xdeadbeef 46 47 .word 0xdeadbeef 48 .word 0xdeadbeef 49 .word 0xdeadbeef 50 .word 0xdeadbeef 51 52 .word (uart_interrupt_handler+1) // UART0_IRQ 53 54 .section .text 55 reset: 56 // unreset gpio, pll_sys, uart0 57 ldr r0, =(1 << 22 | 1 << 12 | 1 << 5) // uart0 | pll_sys | io_bank0 58 ldr r3, resets_base 59 ldr r1, atomic_clr 60 str r0, [r3, r1] // RESETS: RESET 61 mov r1, #1 62 lsl r1, #22 63 bic r0, r1 // uart stays in reset state until clock_peri is enabled 64 unreset_chk: 65 ldr r1, [r3, #0x8] // RESETS: RESET_DONE 66 bic r0, r1 67 bne unreset_chk 68 69 // set gpio functions 70 ldr r3, io_bank0_base 71 mov r0, #2 // uart0 72 mov r1, #0x4 73 str r0, [r3, r1] // IO_BANK0: GPIO0_CTRL 74 mov r1, #0xc 75 str r0, [r3, r1] // IO_BANK0: GPIO1_CTRL 76 77 // setup xosc 78 ldr r3, xosc_base 79 mov r0, #47 // start up delay for 12MHz rosc (xosc?) 80 str r0, [r3, #0xc] // XOSC: STARTUP 81 ldr r0, =(0xfab << 12 | 0xaa0) 82 str r0, [r3, #0] // XOSC: CTRL 83 wait_xosc: 84 ldr r0, [r3, #0x4] // XOSC: STATUS 85 lsr r0, r0, #31 // STABLE bit 86 beq wait_xosc 87 88 // setup pll_sys 133MHz 89 ldr r3, pll_sys_base 90 // set feedback divider 91 mov r0, #133 92 str r0, [r3, #0x8] // PLL: FBDIV_INT 93 // power on pll and vco 94 ldr r0, =(1 << 5 | 1) // VCOPD | PD 95 ldr r1, atomic_clr 96 add r1, r1, #0x4 97 str r0, [r3, r1] // PLL: PWR 98 // wait vco to lock 99 wait_vco: 100 ldr r0, [r3, #0] // PLL: CS 101 lsl r0, r0, #31 102 beq wait_vco 103 // setup post dividers 104 ldr r0, =(4 << 16 | 3 << 12) 105 str r0, [r3, #0xc] // PLL: PRIM 106 // power on post divider 107 mov r0, #8 // POSTDIVPD 108 str r0, [r3, r1] // PLL: PWR 109 110 // set system clock clksrc_pll_sys 111 ldr r3, clocks_base 112 ldr r0, =(0x0 << 5 | 0x1) 113 str r0, [r3, #0x3c] // CLOCKS: CLK_SYS_CTRL 114 // enable clk_peri 115 mov r0, #1 116 lsl r0, r0, #11 117 str r0, [r3, #0x48] // CLOCKS: CLK_PERI_CTRL 118 119 // setup uart0 120 ldr r3, uart0_base 121 // set baudrate 115200 122 // BDRI = 72, BDRF = 0.157 (10 / 64) 123 mov r0, #72 124 str r0, [r3, #0x24] // UART: UARTIBRD 125 mov r0, #10 126 str r0, [r3, #0x28] // UART: UARTFBRD 127 // enable uart0 128 mov r0, #1 // UARTEN 129 ldr r1, atomic_set 130 add r1, r1, #0x30 131 str r0, [r3, r1] // UART: UARTCR 132 // enable FIFO and set format 133 ldr r0, =(3 << 5 | 1 << 4) // WLEN = 8, FEN = 1 134 str r0, [r3, #0x2c] // UART: UARTLCR_H 135 136 // enable uart interrupt in cpu 137 ldr r4, ppb_base 138 mov r5, #0xe1 139 lsl r5, #8 140 mov r0, #1 141 lsl r0, #20 142 str r0, [r4, r5] // M0PLUS: NVIC_ISER 143 144 // enable uart interrupt in uart0 subsystem 145 ldr r1, uart0_base 146 // according to sdk's src/rp2_common/hardware_uart/include/hardware/uart.h 147 // receive interrupt needs RTIM bit masked 148 mov r2, #(1<<6|1<<4) // RTIM | RXIM 149 str r2, [r1, #0x38] // UART: UARTIMSC 150 // set fifo level to 0 151 mov r2, #0 152 str r2, [r1, #0x34] // UART: UARTIFLS 153 bl delay 154 ldr r0, [r1, #0x3c] // UART: UARTRIS 155 bl printh 156 157 loop: 158 wfe 159 b loop 160 161 // functions 162 163 // print r0 in hex for debugging. 164 printh: 165 push {r4, r5, r6, r7, lr} 166 mov r4, r0 167 mov r5, #28 168 mov r6, #0xf 169 mov r7, #10 170 printh_loop: 171 mov r0, r4 172 lsr r0, r0, r5 173 and r0, r0, r6 174 sub r1, r0, r7 175 blt digi 176 add r0, r0, #('a' - 10) 177 b alpha 178 digi: 179 add r0, r0, #'0' 180 alpha: 181 bl putbyte 182 sub r5, r5, #4 183 bge printh_loop 184 pop {r4, r5, r6, r7, pc} 185 186 putbyte: 187 ldr r3, uart0_base 188 mov r1, #1 189 lsl r1, r1, #5 // TXFF 190 txff: 191 ldr r2, [r3, #0x18] // UART: UARTFR 192 tst r1, r2 193 bne txff 194 mov r1, #0xff 195 and r0, r0, r1 196 str r0, [r3, #0] // UART: UARTDR 197 bx lr 198 199 getbyte: 200 ldr r3, uart0_base 201 mov r1, #1 202 lsl r1, r1, #4 // RXFE 203 rxfe: 204 ldr r2, [r3, #0x18] // UART: UARTFR 205 tst r1, r2 206 bne rxfe 207 ldr r0, [r3, #0] // UART: UARTDR 208 mov r1, #0xff 209 and r0, r0, r1 210 bx lr 211 212 // The following functions make no side effects and 213 // can be used anywhare without pushing and popping 214 // registers. 215 216 // Print register content with 2 leds, lsb first. 217 pled: 218 push {r0, r1, r2, r3, r4, r5, r6, lr} 219 mov r4, r0 220 mov r5, #32 221 mov r6, #1 222 pled_loop: 223 tst r4, r6 224 beq pled0 225 bl bled1 226 b pled1 227 pled0: 228 bl bled0 229 pled1: 230 lsr r4, r4, #1 231 sub r5, r5, #1 232 bne pled_loop 233 pop {r0, r1, r2, r3, r4, r5, r6, pc} 234 235 bled0: 236 push {r0, r1, r2, r3, lr} 237 mov r0, #1 238 lsl r0, r0, #24 239 bl bled 240 pop {r0, r1, r2, r3, pc} 241 242 bled1: 243 push {r0, r1, r2, r3, lr} 244 mov r0, #1 245 lsl r0, r0, #25 246 bl bled 247 pop {r0, r1, r2, r3, pc} 248 249 bled: 250 push {r0, r1, r2, r3, r4, r5, lr} 251 ldr r4, sio_base 252 mov r5, r0 253 str r5, [r4, #0x10] // SIO: GPIO_OUT_XOR 254 bl delay 255 str r5, [r4, #0x18] // SIO: GPIO_OUT_XOR 256 bl delay 257 pop {r0, r1, r2, r3, r4, r5, pc} 258 259 delay: 260 push {r0} 261 mov r0, #1 262 lsl r0, r0, #24 263 delay_loop: 264 sub r0, r0, #1 265 bne delay_loop 266 pop {r0} 267 bx lr 268 269 uart_interrupt_handler: 270 push {lr} 271 bl getbyte 272 bl putbyte 273 pop {pc} 274 275 .align 2 276 literals: 277 .ltorg 278 atomic_set: 279 .word 0x00002000 280 atomic_clr: 281 .word 0x00003000 282 clocks_base: 283 .word 0x40008000 284 resets_base: 285 .word 0x4000c000 286 io_bank0_base: 287 .word 0x40014000 288 xosc_base: 289 .word 0x40024000 290 pll_sys_base: 291 .word 0x40028000 292 uart0_base: 293 .word 0x40034000 294 sio_base: 295 .word 0xd0000000 296 ppb_base: 297 .word 0xe0000000