commit 7ae0d491ea01a26d60aa461adbb10d35625cfcd2
parent 5e21ef2b45ed4bbf67bae276ecad7d66e9f3a6a8
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Mon, 11 Aug 2025 08:10:30 +0900
copy ex2
Diffstat:
| A | spi/Makefile | | | 36 | ++++++++++++++++++++++++++++++++++++ | 
| A | spi/boot2.s | | | 29 | +++++++++++++++++++++++++++++ | 
| A | spi/main.s | | | 225 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | spi/memmap.ld | | | 18 | ++++++++++++++++++ | 
4 files changed, 308 insertions(+), 0 deletions(-)
diff --git a/spi/Makefile b/spi/Makefile
@@ -0,0 +1,36 @@
+AS = arm-none-eabi-as
+LD = arm-none-eabi-ld
+OBJCOPY = arm-none-eabi-objcopy
+BINCRC = ../tools/bincrc
+BIN2UF2 = ../tools/bin2uf2
+
+MCPU = -mcpu=cortex-m0plus
+ASFLAGS = $(MCPU)
+CFLAGS = $(MCPU) -ffreestanding -nostartfiles -O0 -fpic -mthumb -c
+LDFLAGS = --no-relax -nostdlib
+
+all: tools a.uf2
+
+clean:
+	rm -f *.o *.elf *.uf2 *.bin
+	cd ../tools && make clean
+
+.s.o:
+	$(AS) $(ASFLAGS) -o $@ $<
+
+a.elf: boot2.o main.o memmap.ld
+	$(LD) $(LDFLAGS) -o $@ -T memmap.ld boot2.o main.o 
+
+a.bin: a.elf
+	$(OBJCOPY) -O binary a.elf $@
+
+a.uf2: a.bin
+	$(BINCRC) a.bin a_crc.bin
+	$(BIN2UF2) a_crc.bin $@
+
+flash: all
+	mount /dev/disk/by-label/RPI-RP2 /mnt
+	cp a.uf2 /mnt
+
+tools:
+	cd ../tools && make
diff --git a/spi/boot2.s b/spi/boot2.s
@@ -0,0 +1,29 @@
+.cpu cortex-m0plus
+.thumb
+
+	.section .boot2
+setup_xip:
+	ldr r3, rom_base
+
+	ldrh r0, [r3, #0x14] // rom_func_table
+	ldr r1, =('C' | 'X' << 8) // _flash_enter_cmd_xip()
+	ldrh r2, [r3, #0x18] // rom_table_lookup
+	blx r2
+	blx r0
+
+	ldr r0, =vectors
+	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
+
+	.align 2
+rom_base:
+	.word 0x00000000
+m0plus_vtor:
+	.word 0xe0000000 + 0xed08
+literals:
+	.ltorg
+
diff --git a/spi/main.s b/spi/main.s
@@ -0,0 +1,225 @@
+.cpu cortex-m0plus
+.thumb
+
+	.global vectors
+vectors:
+	.word 0x20040000 // initial SP
+	.word (reset+1)  // entry point
+
+	.section .text
+reset:
+	// unreset gpio, pll_sys, uart0
+	ldr r0, =(1 << 22 | 1 << 12 | 1 << 5) // uart0 | pll_sys | io_bank0
+	ldr r3, resets_base
+	ldr r1, atomic_clr
+	str r0, [r3, r1] // RESETS: RESET
+	mov r1, #1
+	lsl r1, #22
+	bic r0, r1 // uart stays in reset state until clock_peri is enabled
+unreset_chk:
+	ldr r1, [r3, #0x8] // RESETS: RESET_DONE
+	bic r0, r1
+	bne unreset_chk
+
+	// set gpio functions
+	ldr r3, io_bank0_base
+	mov r0, #2 // uart0
+	mov r1, #0x4
+	str r0, [r3, r1] // IO_BANK0: GPIO0_CTRL
+	mov r1, #0xc
+	str r0, [r3, r1] // IO_BANK0: GPIO1_CTRL
+
+	// setup xosc
+	ldr r3, xosc_base
+	mov r0, #47 // start up delay for 12MHz rosc (xosc?)
+	str r0, [r3, #0xc] // XOSC: STARTUP
+	ldr r0, =(0xfab << 12 | 0xaa0)
+	str r0, [r3, #0] // XOSC: CTRL
+wait_xosc:
+	ldr r0, [r3, #0x4] // XOSC: STATUS
+	lsr r0, r0, #31 // STABLE bit
+	beq wait_xosc
+
+	// setup pll_sys 133MHz
+	ldr r3, pll_sys_base
+	// set feedback divider
+	mov r0, #133
+	str r0, [r3, #0x8] // PLL: FBDIV_INT
+	// power on pll and vco
+	ldr r0, =(1 << 5 | 1) // VCOPD | PD
+	ldr r1, atomic_clr
+	add r1, r1, #0x4
+	str r0, [r3, r1] // PLL: PWR
+	// wait vco to lock
+wait_vco:
+	ldr r0, [r3, #0] // PLL: CS
+	lsl r0, r0, #31
+	beq wait_vco
+	// setup post dividers
+	ldr r0, =(4 << 16 | 3 << 12)
+	str r0, [r3, #0xc] // PLL: PRIM
+	// power on post divider
+	mov r0, #8 // POSTDIVPD
+	str r0, [r3, r1] // PLL: PWR
+
+	// set system clock clksrc_pll_sys
+	ldr r3, clocks_base
+	ldr r0, =(0x0 << 5 | 0x1)
+	str r0, [r3, #0x3c] // CLOCKS: CLK_SYS_CTRL
+	// enable clk_peri
+	mov r0, #1
+	lsl r0, r0, #11
+	str r0, [r3, #0x48] // CLOCKS: CLK_PERI_CTRL
+
+	// setup uart0
+	ldr r3, uart0_base
+	// set baudrate 115200
+	// BDRI = 72, BDRF = 0.157 (10 / 64)
+	mov r0, #72
+	str r0, [r3, #0x24] // UART: UARTIBRD
+	mov r0, #10
+	str r0, [r3, #0x28] // UART: UARTFBRD
+	// enable uart0
+	mov r0, #1 // UARTEN
+	ldr r1, atomic_set
+	add r1, r1, #0x30
+	str r0, [r3, r1] // UART: UARTCR
+	// enable FIFO and set format
+	ldr r0, =(3 << 5 | 1 << 4) // WLEN = 8, FEN = 1
+	str r0, [r3, #0x2c] // UART: UARTLCR_H
+
+loop:
+	bl getbyte
+	bl putbyte
+	b loop
+
+// functions
+
+	// print r0 in hex for debugging.
+printh:
+	push {r4, r5, r6, r7, lr}
+	mov r4, r0
+	mov r5, #28
+	mov r6, #0xf
+	mov r7, #10
+printh_loop:
+	mov r0, r4
+	lsr r0, r0, r5
+	and r0, r0, r6
+	sub r1, r0, r7
+	blt digi
+	add r0, r0, #('a' - 10)
+	b alpha
+digi:
+	add r0, r0, #'0'
+alpha:
+	bl putbyte
+	sub r5, r5, #4
+	bge printh_loop
+	pop {r4, r5, r6, r7, pc}
+
+putbyte:
+	ldr r3, uart0_base
+	mov r1, #1
+	lsl r1, r1, #5 // TXFF
+txff:
+	ldr r2, [r3, #0x18] // UART: UARTFR
+	tst r1, r2
+	bne txff
+	mov r1, #0xff
+	and r0, r0, r1
+	str r0, [r3, #0] // UART: UARTDR
+	bx lr
+
+getbyte:
+	ldr r3, uart0_base
+	mov r1, #1
+	lsl r1, r1, #4 // RXFE
+rxfe:
+	ldr r2, [r3, #0x18] // UART: UARTFR
+	tst r1, r2
+	bne rxfe
+	ldr r0, [r3, #0] // UART: UARTDR
+	mov r1, #0xff
+	and r0, r0, r1
+	bx lr
+
+// The following functions make no side effects and
+// can be used anywhare without pushing and popping
+// registers.
+
+	// Print register content with 2 leds, lsb first.
+pled:
+	push {r0, r1, r2, r3, r4, r5, r6, lr}
+	mov r4, r0
+	mov r5, #32
+	mov r6, #1
+pled_loop:
+	tst r4, r6
+	beq pled0
+	bl bled1
+	b pled1
+pled0:
+	bl bled0
+pled1:
+	lsr r4, r4, #1
+	sub r5, r5, #1
+	bne pled_loop
+	pop {r0, r1, r2, r3, r4, r5, r6, pc}
+
+bled0:
+	push {r0, r1, r2, r3, lr}
+	mov r0, #1
+	lsl r0, r0, #24
+	bl bled
+	pop {r0, r1, r2, r3, pc}
+
+bled1:
+	push {r0, r1, r2, r3, lr}
+	mov r0, #1
+	lsl r0, r0, #25
+	bl bled
+	pop {r0, r1, r2, r3, pc}
+
+bled:
+	push {r0, r1, r2, r3, r4, r5, lr}
+	ldr r4, sio_base
+	mov r5, r0
+	str r5, [r4, #0x10] // SIO: GPIO_OUT_XOR
+	bl delay
+	str r5, [r4, #0x18] // SIO: GPIO_OUT_XOR
+	bl delay
+	pop {r0, r1, r2, r3, r4, r5, pc}
+	
+delay:
+	push {r0}
+	mov r0, #1
+	lsl r0, r0, #20
+delay_loop:
+	sub r0, r0, #1
+	bne delay_loop
+	pop {r0}
+	bx lr
+
+	.align 2
+literals:
+	.ltorg
+atomic_set:
+	.word 0x00002000
+atomic_clr:
+	.word 0x00003000
+clocks_base:
+	.word 0x40008000
+resets_base:
+	.word 0x4000c000
+io_bank0_base:
+	.word 0x40014000
+xosc_base:
+	.word 0x40024000
+pll_sys_base:
+	.word 0x40028000
+uart0_base:
+	.word 0x40034000
+sio_base:
+	.word 0xd0000000
+
diff --git a/spi/memmap.ld b/spi/memmap.ld
@@ -0,0 +1,18 @@
+MEMORY
+{
+	FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
+	SRAM(rwx) : ORIGIN = 0x20000000, LENGTH = 264k
+}
+
+SECTIONS
+{
+	.boot2 : {
+		*(.boot2)
+		. = 0x100;
+	} > FLASH
+
+	.text : {
+		*(.text)
+	} > FLASH
+}
+