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