rp2040

RP2040 Programming without SDK
Log | Files | Refs

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