rp2040

RP2040 Programming without SDK
Log | Files | Refs

main.s (4173B)


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