rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit a30b22d7fb523247f4c577ddf427381a903813b4
parent d804058a7c6fbd4bd6f23a2eeda4d2995da8d0ab
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed, 12 Apr 2023 09:00:18 +0900

try to embed boot2

Diffstat:
MMakefile | 13++++---------
Aboot2.s | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmach.s | 35++++-------------------------------
Mmemmap.ld | 1-
4 files changed, 175 insertions(+), 41 deletions(-)

diff --git a/Makefile b/Makefile @@ -19,11 +19,8 @@ clean: rm -f boot2/*.bin rm -f boot2/boot2_crc.s -boot2_crc.o: boot2/boot2.s bincrc - $(AS) $(ASFLAGS) -o boot2/boot2.o boot2/boot2.s - $(OBJCOPY) -O binary boot2/boot2.o boot2/boot2.bin - ./bincrc boot2/boot2.bin boot2/boot2_crc.s - $(AS) $(ASFLAGS) -o boot2_crc.o boot2/boot2_crc.s +boot2.o: boot2.s + $(AS) $(ASFLAGS) -o boot2.o boot2.s main.o: main.c $(CC) $(CFLAGS) -o main.o main.c @@ -31,13 +28,11 @@ main.o: main.c mach.o: mach.s $(AS) $(ASFLAGS) -o mach.o mach.s -led.elf: boot2_crc.o main.o mach.o memmap.ld - $(LD) $(LDFLAGS) -o led.elf -T memmap.ld boot2_crc.o mach.o main.o +led.elf: boot2.o main.o mach.o memmap.ld + $(LD) $(LDFLAGS) -o led.elf -T memmap.ld boot2.o mach.o main.o led.bin: led.elf $(OBJCOPY) -O binary led.elf led.bin -#led.uf2: led.elf -# $(ELF2UF2) led.elf led.uf2 led.uf2: led.bin bin2uf2 ./bin2uf2 led.bin led.uf2 diff --git a/boot2.s b/boot2.s @@ -0,0 +1,167 @@ +.cpu cortex-m0plus +.thumb + + .section boot2 + .global setup_xip + .thumb_func +setup_xip: + push {r4, lr} + + // setup QSPI pad + ldr r4, pads_qspi_base + ldr r1, =(0 << 4 | 0 << 1 | 1) // 2mA, schmitt off, slew fast + str r1, [r4, #0x4] // PADS_QSPI: GPIO_QSPI_SCLK + + // r4 should not be changed from this point on + ldr r4, xip_ssi_base + + // set SSI standard SPI + // disable SSI + mov r1, #0 + str r1, [r4, #0x8] // SSI: SSIENR + //set divider + mov r1, #0x2 + str r1, [r4, #0x14] // SSI: BAUDR + // set 1-cycle sample delay. + mov r1, #1 + mov r2, #0xf0 + str r1, [r4, r2] // SSI: RX_SAMPLE_DLY + // setup SSI + ldr r1, =(7 << 16 | 3 << 8) // 8bit data frame size, eeprom + str r1, [r4, #0] // SSI: CTRLR0 + mov r1, #0 // NDF = 0 + str r1, [r4, #0x4] // SSI: CTRLR1 + // enable SSI + mov r1, #1 + str r1, [r4, #0x8] // SSI: SSIENR + + // set flash QSPI + // write enable + mov r1, #0x06 // write enable + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + // enable QSPI + mov r1, #0x31 // write status register-2 + str r1, [r4, #0x60] // SSI: DR0 + mov r1, #0x2 // quad enable + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + ldr r1, [r4, #0x60] // SSI: DR0 + +wait_sreg: + mov r1, #0x5 // read status register-1 + // This str is required twice if TMOD = 0. + // In this case, /CS signal is set to high just + // after the first str instruction and the flash + // doesn't shift out the status register. + // On the other hand, If TMOD = 3 (eeprom), + // then the /CS is kept to low until NDF + 1 + // data frames are captured. + // Shiran Kedo. + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + mov r2, #1 // BUSY flag + tst r1, r2 + bne wait_sreg + + // set SSI QSPI and XIP + // disable SSI + mov r1, #0 + str r1, [r4, #0x8] // SSI: SSIENR + // set up QSPI + // DFS is said to be the number of clocks of a data frame - 1. + // But in QSPI mode, a frame is 32 bits and is transfered in 8 clocks. + // However, if DFS is set to 7, It doesn't work. + // Maybe this is a bug of the documentation. + ldr r1, =(2 << 21 | 31 << 16 | 3 << 8) // quad, 32bit data frame, eeprom + str r1, [r4, #0] // SSI: CTRLR0 + // setup xip + ldr r1, =(4 << 11 | 2 << 8 | 8 << 2 | 1 << 0) + mov r2, #0xf4 + str r1, [r4, r2] // SSI: SPI_CTRLR0 + // re-enable SSI + mov r1, #1 + str r1, [r4, #0x8] // SSI: SSIENR + + // first read from flash + // set flash continuous read + mov r1, #0xeb // fast read quad i/o + str r1, [r4, #0x60] // SSI: DR0 + // continuous read is not documented in w25q16j datasheet... + // it says mode bits should be Fxh (x: don't care)... + // in w2580bv datasheet, these bits are said to be 0bxx10xxxx. + // why w25q16j lacks the description? + mov r1, #0x20 + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + + // set SIP continuous read + // disable SSI + mov r1, #0 + str r1, [r4, #0x8] // SSI: SSIENR + // the command bit is not documented. + ldr r1, =(0x20 << 24 | 4 << 11 | 0 << 8 | 8 << 2 | 2 << 0) + mov r2, #0xf4 + str r1, [r4, r2] // SSI: SPI_CTRLR0 + // re-enable SSI + mov r1, #1 + str r1, [r4, #0x8] // SSI: SSIENR + + // this code should be rewritten using dma. + ldr r2, boot2_end + ldr r3, sram_base + ldr r0, etext + lsr r0, #2 +sram_cpy: + ldr r1, [r2, #0] + str r1, [r3, #0] + add r2, r2, #0x4 + add r3, r3, #0x4 + sub r0, r0, #0x1 + bne sram_cpy + + // exit from boot2 + pop {r4} + pop {r0} + cmp r0, #0 + beq initial_boot + bx r0 +initial_boot: + ldr r0, sram_base + ldr r1, m0plus_vtor + str r0, [r1, #0] // M0PLUS: VTOR + ldr r1, [r0, #4] // entry point + ldr r0, [r0, #0] // stack pointer + mov sp, r0 + bx r1 + +wait_ssi: + // asumes that r4 is xip_ssi_base + ldr r1, [r4, #0x28] // SSI: SR + mov r2, #4 // TFE + tst r1, r2 + beq wait_ssi + mov r2, #1 // BUSY + tst r1, r2 + bne wait_ssi + bx lr + + .align 2 +boot2_end: + .word 0x10000000 + 0x100 +xip_ssi_base: + .word 0x18000000 +sram_base: + .word 0x20000000 +pads_qspi_base: + .word 0x40020000 +m0plus_vtor: + .word 0xe0000000 + 0xed08 +etext: + .word _etext +literals: + .ltorg + diff --git a/mach.s b/mach.s @@ -6,43 +6,18 @@ vectors: .word 0x20040000 // initial SP .word (reset+1) // entry point - .section .sram_cpy + .section .text .thumb_func reset: - ldr r0, init_sp +/* + ldr r0, sram_base ldr r0, [r0, #0] // initial SP mov sp, r0 - - ldr r2, xip_copy_base - ldr r3, sram_copy_base - ldr r0, etext - sub r0, r0, r3 - add r0, r0, #2 -sram_cpy: - ldr r1, [r2, #0] - str r1, [r3, #0] - add r2, r2, #0x4 - add r3, r3, #0x4 - sub r0, r0, #0x4 - bne sram_cpy - +*/ bl main hang: b hang - .align 2 -init_sp: - .word 0x20000000 -xip_copy_base: - .word 0x10000200 -sram_copy_base: - .word 0x20000100 -etext: - .word _etext -.ltorg - - - .section .text .global init .thumb_func init: @@ -380,7 +355,6 @@ del_loop: pop {r0} bx lr - // data .align 2 @@ -412,4 +386,3 @@ rosc_base: .word 0x40060000 sio_base: .word 0xd0000000 - diff --git a/memmap.ld b/memmap.ld @@ -12,7 +12,6 @@ SECTIONS .text 0x20000000 : AT (0x10000100) { *(.vectors) - *(.sram_cpy) *(.text) _etext = .; }