start.s (6712B)
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 bl main 57 loop: 58 wfe 59 b loop 60 61 // void init_clock(void); 62 // init_clock initialize xosc and set it as the system clock 63 // clock freq is 133MHz. 64 .global init_xosc 65 init_xosc: 66 // setup xosc 67 ldr r3, xosc_base 68 mov r0, #47 // start up delay for 12MHz rosc (xosc?) 69 str r0, [r3, #0xc] // XOSC: STARTUP 70 ldr r0, =(0xfab << 12 | 0xaa0) 71 str r0, [r3, #0] // XOSC: CTRL 72 wait_xosc: 73 ldr r0, [r3, #0x4] // XOSC: STATUS 74 lsr r0, r0, #31 // STABLE bit 75 beq wait_xosc 76 bx lr 77 78 // void init_pll(void); 79 // init_pll setups pll_sys in 133MHz. 80 .global init_pll 81 init_pll: 82 ldr r3, pll_sys_base 83 // set feedback divider 84 mov r0, #133 85 str r0, [r3, #0x8] // PLL: FBDIV_INT 86 // power on pll and vco 87 ldr r0, =(1 << 5 | 1) // VCOPD | PD 88 ldr r1, atomic_clr 89 add r1, r1, #0x4 90 str r0, [r3, r1] // PLL: PWR 91 // wait vco to lock 92 wait_vco: 93 ldr r0, [r3, #0] // PLL: CS 94 lsl r0, r0, #31 95 beq wait_vco 96 // setup post dividers 97 ldr r0, =(4 << 16 | 3 << 12) 98 str r0, [r3, #0xc] // PLL: PRIM 99 // power on post divider 100 mov r0, #8 // POSTDIVPD 101 str r0, [r3, r1] // PLL: PWR 102 bx lr 103 104 // void set_system_clock_to_pll_sys(void); 105 // set_system_clock_to_pll_sys sets system clock to pll_sys 106 .global set_system_clock_to_pll_sys 107 set_system_clock_to_pll_sys: 108 // set system clock clksrc_pll_sys 109 ldr r3, clocks_base 110 ldr r0, =(0x0 << 5 | 0x1) 111 str r0, [r3, #0x3c] // CLOCKS: CLK_SYS_CTRL 112 bx lr 113 114 // void enable_clock_peri(void); 115 // enable_clock_peri enables clk_peri and set it to clk_sys 116 .global enable_clock_peri 117 enable_clock_peri: 118 mov r0, #1 119 lsl r0, r0, #11 120 ldr r3, clocks_base 121 str r0, [r3, #0x48] // CLOCKS: CLK_PERI_CTRL 122 bx lr 123 124 // void unreset(reset_bit subsystems); 125 // unreset unresets subsystems. 126 // subsystems is bitwise or. 127 // To unreset uart, clk_peri must be enabled beforehand. 128 .global unreset 129 unreset: 130 ldr r3, resets_base 131 ldr r1, atomic_clr 132 str r0, [r3, r1] // RESETS: RESET 133 unreset_chk: 134 ldr r1, [r3, #0x8] // RESETS: RESET_DONE 135 bic r0, r1 136 bne unreset_chk 137 bx lr 138 139 .global mains 140 mains: 141 push {lr} 142 143 // set gpio functions 144 ldr r3, io_bank0_base 145 // set pins 0 and 1 for uart 146 mov r0, #2 // uart0 147 mov r1, #0x4 148 str r0, [r3, r1] // IO_BANK0: GPIO0_CTRL 149 mov r1, #0xc 150 str r0, [r3, r1] // IO_BANK0: GPIO1_CTRL 151 // set pins 24 and 25 to SIO for led blink. 152 mov r0, #5 // sio 153 mov r1, #0xc4 154 str r0, [r3, r1] // IO_BANK0: GPIO24_CTRL 155 mov r1, #0xcc 156 str r0, [r3, r1] // IO_BANK0: GPIO24_CTRL 157 158 // enable sio output 159 ldr r3, sio_base 160 mov r0, #0b11 161 lsl r0, r0, #24 162 str r0, [r3, #0x24] // SIO: GPIO_OE 163 164 // setup uart0 165 ldr r3, uart0_base 166 // set baudrate 115200 167 // BDRI = 72, BDRF = 0.157 (10 / 64) 168 mov r0, #72 169 str r0, [r3, #0x24] // UART: UARTIBRD 170 mov r0, #10 171 str r0, [r3, #0x28] // UART: UARTFBRD 172 // enable uart0 173 mov r0, #1 // UARTEN 174 ldr r1, atomic_set 175 add r1, r1, #0x30 176 str r0, [r3, r1] // UART: UARTCR 177 // enable FIFO and set format 178 ldr r0, =(3 << 5 | 1 << 4) // WLEN = 8, FEN = 1 179 str r0, [r3, #0x2c] // UART: UARTLCR_H 180 181 // enable uart interrupt in cpu 182 ldr r4, ppb_base 183 mov r5, #0xe1 184 lsl r5, #8 185 mov r0, #1 186 lsl r0, #20 187 str r0, [r4, r5] // M0PLUS: NVIC_ISER 188 189 // enable uart interrupt in uart0 subsystem 190 ldr r1, uart0_base 191 mov r2, #(1 << 6 | 1 << 4) // RTIM | RXIM 192 str r2, [r1, #0x38] // UART: UARTIMSC 193 // set fifo level to 0 194 mov r2, #0 195 str r2, [r1, #0x34] // UART: UARTIFLS 196 197 pop {pc} 198 199 // functions 200 201 // print r0 in hex for debugging. 202 printh: 203 push {r4, r5, r6, r7, lr} 204 mov r4, r0 205 mov r5, #28 206 mov r6, #0xf 207 mov r7, #10 208 printh_loop: 209 mov r0, r4 210 lsr r0, r0, r5 211 and r0, r0, r6 212 sub r1, r0, r7 213 blt digi 214 add r0, r0, #('a' - 10) 215 b alpha 216 digi: 217 add r0, r0, #'0' 218 alpha: 219 bl putbyte 220 sub r5, r5, #4 221 bge printh_loop 222 pop {r4, r5, r6, r7, pc} 223 224 // putbyte sends a byte specified by r0 to uart0. 225 // It busy-waits for the buffer to become available. 226 putbyte: 227 ldr r3, uart0_base 228 mov r1, #1 229 lsl r1, r1, #5 // TXFF 230 txff: 231 ldr r2, [r3, #0x18] // UART: UARTFR 232 tst r1, r2 233 bne txff 234 mov r1, #0xff 235 and r0, r0, r1 236 str r0, [r3, #0] // UART: UARTDR 237 bx lr 238 239 // getbyte reads a byte from uart0 and returns it on r0 240 // It busy-waits for a data. 241 getbyte: 242 ldr r3, uart0_base 243 mov r1, #1 244 lsl r1, r1, #4 // RXFE 245 rxfe: 246 ldr r2, [r3, #0x18] // UART: UARTFR 247 tst r1, r2 248 bne rxfe 249 ldr r0, [r3, #0] // UART: UARTDR 250 mov r1, #0xff 251 and r0, r0, r1 252 bx lr 253 254 // The following functions make no side effects and 255 // can be used anywhare without pushing and popping 256 // registers. 257 258 // pled prints register content with 2 leds on the pins 24 and 25, lsb first. 259 pled: 260 push {r0, r1, r2, r3, r4, r5, r6, lr} 261 mov r4, r0 262 mov r5, #32 263 mov r6, #1 264 pled_loop: 265 tst r4, r6 266 beq pled0 267 bl bled1 268 b pled1 269 pled0: 270 bl bled0 271 pled1: 272 lsr r4, r4, #1 273 sub r5, r5, #1 274 bne pled_loop 275 pop {r0, r1, r2, r3, r4, r5, r6, pc} 276 277 // bled0 blinks the led on the pin 24 once. 278 .global bled0 279 bled0: 280 push {r0, r1, r2, r3, lr} 281 mov r0, #1 282 lsl r0, r0, #24 283 bl bled 284 pop {r0, r1, r2, r3, pc} 285 286 // bled1 blinks the led on the pin 25 once. 287 bled1: 288 push {r0, r1, r2, r3, lr} 289 mov r0, #1 290 lsl r0, r0, #25 291 bl bled 292 pop {r0, r1, r2, r3, pc} 293 294 // bled blinks the led on the pin specified by r0 once. 295 bled: 296 push {r0, r1, r2, r3, r4, r5, lr} 297 ldr r4, sio_base 298 mov r5, r0 299 str r5, [r4, #0x10] // SIO: GPIO_OUT_XOR 300 bl delay 301 str r5, [r4, #0x18] // SIO: GPIO_OUT_XOR 302 bl delay 303 pop {r0, r1, r2, r3, r4, r5, pc} 304 305 // delay delays for a moment by counting down a register. 306 delay: 307 push {r0} 308 mov r0, #1 309 lsl r0, r0, #24 310 delay_loop: 311 sub r0, r0, #1 312 bne delay_loop 313 pop {r0} 314 bx lr 315 316 // uart_interrupt_handler echos the data arrived at uart0 317 uart_interrupt_handler: 318 push {lr} 319 bl getbyte 320 bl putbyte 321 pop {pc} 322 323 .align 2 324 literals: 325 .ltorg 326 atomic_set: 327 .word 0x00002000 328 atomic_clr: 329 .word 0x00003000 330 clocks_base: 331 .word 0x40008000 332 resets_base: 333 .word 0x4000c000 334 io_bank0_base: 335 .word 0x40014000 336 xosc_base: 337 .word 0x40024000 338 pll_sys_base: 339 .word 0x40028000 340 uart0_base: 341 .word 0x40034000 342 sio_base: 343 .word 0xd0000000 344 ppb_base: 345 .word 0xe0000000