rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 6d42e176fafd1b6edfb2bf1c1249d387d9527b39
parent d18d189ee7dfae9421fe63b9a9a166dfc2dad0ff
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 25 Mar 2023 11:27:00 +0900

Use c to print string

Diffstat:
MMakefile | 11+++++++----
Aas.s | 295+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amain.c | 10++++++++++
Dmain.s | 273-------------------------------------------------------------------------------
4 files changed, 312 insertions(+), 277 deletions(-)

diff --git a/Makefile b/Makefile @@ -22,11 +22,14 @@ start.o: start.s boot2.o: boot2/bs2_default_padded_checksummed.S $(AS) $(ASFLAGS) -o boot2.o boot2/bs2_default_padded_checksummed.S -main.o: main.s - $(CC) $(CFLAGS) -o main.o main.s +main.o: main.c + $(CC) $(CFLAGS) -o main.o main.c -led.elf: start.o boot2.o main.o - $(LD) $(LFLAGS) -o led.elf -T memmap.ld start.o boot2.o main.o +as.o: as.s + $(AS) $(ASFLAGS) -o as.o as.s + +led.elf: start.o boot2.o main.o as.o + $(LD) $(LFLAGS) -o led.elf -T memmap.ld start.o boot2.o as.o main.o led.uf2: led.elf $(ELF2UF2) led.elf led.uf2 diff --git a/as.s b/as.s @@ -0,0 +1,295 @@ + .section .text + .global init +init: + push {lr} + // unreset gpio and pll_sys and uart0 + mov r1, #1 + lsl r0, r1, #5 // io_bank0 + lsl r1, r1, #12 // pll_sys + add r0, r0, r1 + lsl r1, r1, #10 // uart0 + add r0, r0, r1 + bl unreset + bl wait_unreset + + // set gpio functions + ldr r0, io_bank0_base + mov r1, #2 // uart0 + mov r2, #5 // sio + add r0, r0, #0x4 // io_bank0_gpio0_ctrl + str r1, [r0, #0] // uart0 + add r0, r0, #0x8 // #0xc io_bank0_gpio1_ctrl + str r1, [r0, #0] // uart0 + add r0, r0, #0xa8 // #0xb4 io_bank0_gpio22_ctrl + str r2, [r0, #0] // sio + add r0, r0, #0x10 // #0xc4 io_bank0_gpio24_ctrl + str r2, [r0, #0] // sio + + // enable gpio output + ldr r0, sio_base + mov r1, #5 + lsl r1, r1, #22 // gpio22 and gpio24 + str r1, [r0, #0x24] + + // enable xosc + ldr r0, xosc_base + mov r1, #0xf + lsl r1, r1, #8 + add r1, r1, #0xab + lsl r1, r1, #8 + add r1, r1, #0xaa + lsl r1, r1, #4 + str r1, [r0, #0] // XOSC_CTRL + + // set xosc delay + mov r1, #47 + str r1, [r0, #0xc] // XOSC_STARTUP + + // wait for xosc startup +xosc_stable: + ldr r1, [r0, #0x4] // XOSC_STATUS + lsr r1, r1, #31 + beq xosc_stable + + // set pll feedback divider + ldr r0, pll_sys_base + mov r1, #125 + str r1, [r0, #0x8] // PLL_FBDIV_INT + + // power on pll + ldr r1, atomic_clr + add r0, r0, r1 + mov r1, #33 // VCOPD | PD + str r1, [r0, #0x4] // PLL_PWR + + // wait for pll locking + ldr r0, pll_sys_base +pll_lock: + ldr r1, [r0, #0] // PLL_CS + lsr r1, r1, #31 + beq pll_lock + + // set post dividers + ldr r0, pll_sys_base + ldr r1, atomic_clr + add r0, r0, r1 + mov r1, #3 + lsl r1, r1, #4 + add r1, r1, #4 + lsl r1, r1, #12 + str r1, [r0, #0xc] // PLL_PRIM + + // turn on post dividers + ldr r0, pll_sys_base + ldr r1, atomic_clr + add r0, r0, r1 + mov r1, #8 + str r1, [r0, #0x4] // PLL_PWR + + // set sys clock to pll_sys + ldr r0, clocks_base + mov r1, #1 + str r1, [r0, #0x3c] // CLOCKS_CLK_SYS_CTRL + // enable clk_peri + lsl r1, r1, #11 + str r1, [r0, #0x48] + + // enable clk_peri + ldr r0, clocks_base + mov r1, #1 + lsl r1, r1, #11 + str r1, [r0, #0x48] // CLOCKS_CLK_PERI_CTRL + + // enable uart0 + ldr r0, uart0_base + ldr r1, atomic_set + add r0, r0, r1 + mov r1, #1 + str r1, [r0, #0x30] // UART0_UARTCR + // enable FIFO + lsl r1, r1, #4 + str r1, [r0, #0x2c] // UART0_UARTLCR_H + // set baud rate dividers + mov r1, #67 + str r1, [r0, #0x24] // UART0_UARTIBRD + mov r1, #52 + str r1, [r0, #0x28] // UART0_UARTFBRD + // setup uart0 + mov r1, #3 // WLEN = 8 + lsl r1, r1, #5 + str r1, [r0, #0x2c] // UART0_UARTLCR_H + + pop {pc} + +loop: + bl uart0_read + bl uart0_write + b loop + +// functions + +unreset: + // unreset subsystems specified by r0 + // args: bit mask to specify the subsystems to unreset + // return: the bit mask same as the arg + ldr r1, resets_base + ldr r2, atomic_clr + add r1, r1, r2 + str r0, [r1, #0] // RESETS_RESET + bx lr + +wait_unreset: + // wait for subsystems specified by r0 to reset done + // args: bit mask to specify the subsystems to wait for + // return: void + ldr r1, resets_base +reset_chk: + ldr r2, [r1, #0x8] // RESETS_RESET_DONE + and r0, r0, r2 + beq reset_chk + bx lr + +uart0_write: + push {r4, r5, r6, r7, lr} + mov r4, #0xFF + and r4, r4, r0 + ldr r5, uart0_base + mov r6, #32 // TXFF +uart0_txff: + ldr r7, [r5, #0x18] // UART0_UARTFR + and r7, r7, r6 + bne uart0_txff + str r4, [r5, #0] // UART0_UARTDR + pop {r4, r5, r6, r7, pc} + +uart0_read: + push {r4, r5, r6, lr} + ldr r4, uart0_base + mov r5, #16 +uart0_rxfe: + ldr r6, [r4, #0x18] // UART0_UARTFR + and r6, r6, r5 + bne uart0_rxfe + ldr r0, [r4, #0] // UART0_UARTDR + mov r4, #0xFF + and r0, r0, r4 + pop {r4, r5, r6, pc} + + .global print + // void print(char *s); +print: + push {r4, r5, lr} + mov r4, r0 + mov r5, #0xFF +print_loop: + ldrb r1, [r4, #0] + and r1, r1, r5 + beq print_end + mov r0, r1 + bl uart0_write + add r4, r4, #1 + b print_loop +print_end: + pop {r4, r5, pc} + +led_pr: + // print register with 2 leds + push {lr} + mov r1, #32 +led_pr_loop: + push {r0} + mov r2, #1 + and r2, r2, r0 + beq led_pr_0 + bl led_p1 + b led_pr_1 +led_pr_0: + bl led_p0 +led_pr_1: + pop {r0} + lsr r0, r0, #1 + sub r1, #1 + bne led_pr_loop + pop {pc} + +led_p0: + // blink led on gpio22 + push {lr} + mov r0, #1 + lsl r0, r0, #22 + bl led_blink + pop {pc} + +led_p1: + // blink led on gpio24 + push {lr} + mov r0, #1 + lsl r0, r0, #24 + bl led_blink + pop {pc} + + .global led_p2 +led_p2: + // blink led on gpio22 and gpio24 + push {lr} + mov r0, #5 + lsl r0, r0, #22 + bl led_blink + pop {pc} + +led_blink: + push {r4, r5, lr} + ldr r4, sio_base + mov r5, r0 + str r5, [r4, #0x10] // SIO_GPIO_OUT_SET + bl delay + str r5, [r4, #0x18] // SIO_GPIO_OUT_CLR + bl delay + pop {r4, r5, pc} + + .global delay +delay: + mov r0, #1 + lsl r0, r0, #22 +del_loop: + sub r0, r0, #1 + bne del_loop + bx lr + + +// data + + .align 2 + +atomic_set: + .word 0x00002000 + +atomic_clr: + .word 0x00003000 + +clocks_base: + .word 0x40008000 + +resets_base: + .word 0x4000c000 + +reset_done: + .word 0x4000c008 + +io_bank0_base: + .word 0x40014000 + +xosc_base: + .word 0x40024000 + +pll_sys_base: + .word 0x40028000 + +uart0_base: + .word 0x40034000 + +rosc_base: + .word 0x40060000 + +sio_base: + .word 0xd0000000 diff --git a/main.c b/main.c @@ -0,0 +1,10 @@ +void +main(void) +{ + char *s = "unko\n"; + init(); + while(1) { + print(s); + delay(); + } +} diff --git a/main.s b/main.s @@ -1,273 +0,0 @@ - .section .text - .global main -main: - // unreset gpio and pll_sys and uart0 - mov r1, #1 - lsl r0, r1, #5 // io_bank0 - lsl r1, r1, #12 // pll_sys - add r0, r0, r1 - lsl r1, r1, #10 // uart0 - add r0, r0, r1 - bl unreset - bl wait_unreset - - // set gpio functions - ldr r0, io_bank0_base - mov r1, #2 // uart0 - mov r2, #5 // sio - add r0, r0, #0x4 // io_bank0_gpio0_ctrl - str r1, [r0, #0] // uart0 - add r0, r0, #0x8 // #0xc io_bank0_gpio1_ctrl - str r1, [r0, #0] // uart0 - add r0, r0, #0xa8 // #0xb4 io_bank0_gpio22_ctrl - str r2, [r0, #0] // sio - add r0, r0, #0x10 // #0xc4 io_bank0_gpio24_ctrl - str r2, [r0, #0] // sio - - // enable gpio output - ldr r0, sio_base - mov r1, #5 - lsl r1, r1, #22 // gpio22 and gpio24 - str r1, [r0, #0x24] - - // enable xosc - ldr r0, xosc_base - mov r1, #0xf - lsl r1, r1, #8 - add r1, r1, #0xab - lsl r1, r1, #8 - add r1, r1, #0xaa - lsl r1, r1, #4 - str r1, [r0, #0] // XOSC_CTRL - - // set xosc delay - mov r1, #47 - str r1, [r0, #0xc] // XOSC_STARTUP - - // wait for xosc startup -xosc_stable: - ldr r1, [r0, #0x4] // XOSC_STATUS - lsr r1, r1, #31 - beq xosc_stable - - // set pll feedback divider - ldr r0, pll_sys_base - mov r1, #125 - str r1, [r0, #0x8] // PLL_FBDIV_INT - - // power on pll - ldr r1, atomic_clr - add r0, r0, r1 - mov r1, #33 // VCOPD | PD - str r1, [r0, #0x4] // PLL_PWR - - // wait for pll locking - ldr r0, pll_sys_base -pll_lock: - ldr r1, [r0, #0] // PLL_CS - lsr r1, r1, #31 - beq pll_lock - - // set post dividers - ldr r0, pll_sys_base - ldr r1, atomic_clr - add r0, r0, r1 - mov r1, #3 - lsl r1, r1, #4 - add r1, r1, #4 - lsl r1, r1, #12 - str r1, [r0, #0xc] // PLL_PRIM - - // turn on post dividers - ldr r0, pll_sys_base - ldr r1, atomic_clr - add r0, r0, r1 - mov r1, #8 - str r1, [r0, #0x4] // PLL_PWR - - // set sys clock to pll_sys - ldr r0, clocks_base - mov r1, #1 - str r1, [r0, #0x3c] // CLOCKS_CLK_SYS_CTRL - // enable clk_peri - lsl r1, r1, #11 - str r1, [r0, #0x48] - - // enable clk_peri - ldr r0, clocks_base - mov r1, #1 - lsl r1, r1, #11 - str r1, [r0, #0x48] // CLOCKS_CLK_PERI_CTRL - - // enable uart0 - ldr r0, uart0_base - ldr r1, atomic_set - add r0, r0, r1 - mov r1, #1 - str r1, [r0, #0x30] // UART0_UARTCR - // enable FIFO - lsl r1, r1, #4 - str r1, [r0, #0x2c] // UART0_UARTLCR_H - // set baud rate dividers - mov r1, #67 - str r1, [r0, #0x24] // UART0_UARTIBRD - mov r1, #52 - str r1, [r0, #0x28] // UART0_UARTFBRD - // setup uart0 - mov r1, #3 // WLEN = 8 - lsl r1, r1, #5 - str r1, [r0, #0x2c] // UART0_UARTLCR_H - -loop: - bl uart0_read - bl uart0_write - b loop - -// functions - -unreset: - // unreset subsystems specified by r0 - // args: bit mask to specify the subsystems to unreset - // return: the bit mask same as the arg - ldr r1, resets_base - ldr r2, atomic_clr - add r1, r1, r2 - str r0, [r1, #0] // RESETS_RESET - bx lr - -wait_unreset: - // wait for subsystems specified by r0 to reset done - // args: bit mask to specify the subsystems to wait for - // return: void - ldr r1, resets_base -reset_chk: - ldr r2, [r1, #0x8] // RESETS_RESET_DONE - and r0, r0, r2 - beq reset_chk - bx lr - -uart0_write: - push {r4, r5, r6, r7, lr} - mov r4, #0xFF - and r4, r4, r0 - ldr r5, uart0_base - mov r6, #32 // TXFF -uart0_txff: - ldr r7, [r5, #0x18] // UART0_UARTFR - and r7, r7, r6 - bne uart0_txff - str r4, [r5, #0] // UART0_UARTDR - pop {r4, r5, r6, r7, pc} - -uart0_read: - push {r4, r5, r6, lr} - ldr r4, uart0_base - mov r5, #16 -uart0_rxfe: - ldr r6, [r4, #0x18] // UART0_UARTFR - and r6, r6, r5 - bne uart0_rxfe - ldr r0, [r4, #0] // UART0_UARTDR - mov r4, #0xFF - and r0, r0, r4 - pop {r4, r5, r6, pc} - -led_pr: - // print register with 2 leds - push {lr} - mov r1, #32 -led_pr_loop: - push {r0} - mov r2, #1 - and r2, r2, r0 - beq led_pr_0 - bl led_p1 - b led_pr_1 -led_pr_0: - bl led_p0 -led_pr_1: - pop {r0} - lsr r0, r0, #1 - sub r1, #1 - bne led_pr_loop - pop {pc} - -led_p0: - // blink led on gpio22 - push {lr} - mov r0, #1 - lsl r0, r0, #22 - bl led_blink - pop {pc} - -led_p1: - // blink led on gpio24 - push {lr} - mov r0, #1 - lsl r0, r0, #24 - bl led_blink - pop {pc} - -led_p2: - // blink led on gpio22 and gpio24 - push {lr} - mov r0, #5 - lsl r0, r0, #22 - bl led_blink - pop {pc} - -led_blink: - push {r4, r5, lr} - ldr r4, sio_base - mov r5, r0 - str r5, [r4, #0x10] // SIO_GPIO_OUT_SET - bl delay - str r5, [r4, #0x18] // SIO_GPIO_OUT_CLR - bl delay - pop {r4, r5, pc} - -delay: - mov r0, #1 - lsl r0, r0, #22 -del_loop: - sub r0, r0, #1 - bne del_loop - bx lr - - -// data - - .align 2 - -atomic_set: - .word 0x00002000 - -atomic_clr: - .word 0x00003000 - -clocks_base: - .word 0x40008000 - -resets_base: - .word 0x4000c000 - -reset_done: - .word 0x4000c008 - -io_bank0_base: - .word 0x40014000 - -xosc_base: - .word 0x40024000 - -pll_sys_base: - .word 0x40028000 - -uart0_base: - .word 0x40034000 - -rosc_base: - .word 0x40060000 - -sio_base: - .word 0xd0000000