rp2040

RP2040 Programming without SDK
Log | Files | Refs

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