commit f54b95e177d885028b09e1ab7ce368f6db3240c5
parent e99f7a9bb0e1fe65bb38f0061b2e2c6fb81b7299
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 3 Apr 2023 18:45:31 +0900
trying to compile original code from sdk
Diffstat:
2 files changed, 126 insertions(+), 93 deletions(-)
diff --git a/Makefile b/Makefile
@@ -30,8 +30,8 @@ start.o: start.s
# ./bincrc boot2/bs2_default.bin boot2/boot2_crc.S
boot2_crc.o: boot2/boot2_crc.S
$(AS) $(ASFLAGS) -o boot2_crc.o boot2/boot2_crc.S
-boot2/boot2_crc.S: boot2/boot2.S bincrc
- $(AS) $(ASFLAGS) -o boot2/boot2.o boot2/boot2.S
+boot2/boot2_crc.S: boot2/boot2_w25q.S bincrc
+ $(AS) $(ASFLAGS) -o boot2/boot2.o boot2/boot2_w25q.S
$(OBJCOPY) -O binary boot2/boot2.o boot2/boot2.bin
./bincrc boot2/boot2.bin boot2/boot2_crc.S
diff --git a/boot2/boot2_w25q.S b/boot2/boot2_w25q.S
@@ -1,15 +1,6 @@
-#define PICO_FLASH_SPI_CLKDIV 4
-#define FRAME_FORMAT 0x2
-#define CMD_READ 0xeb
-#define MODE_CONTINUOUS_READ 0xa0
-#define ADDR_L 8
-#define WAIT_CYCLES 4
-
-#define CMD_WRITE_ENABLE 0x06
-#define CMD_READ_STATUS 0x05
-#define CMD_READ_STATUS2 0x35
-#define CMD_WRITE_STATUS 0x01
-#define SREG_DATA 0x02 // Enable quad-SPI mode
+.equ XIP_SSI_BASE, 0x18000000
+.equ PADS_QSPI_BASE, 0x40020000
+.equ PPB_BASE, 0xe0000000
.syntax unified
.cpu cortex-m0plus
@@ -24,82 +15,82 @@ _stage2_boot:
push {lr}
ldr r3, =PADS_QSPI_BASE
- movs r0, #(2 << PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_LSB | PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_BITS)
- str r0, [r3, #PADS_QSPI_GPIO_QSPI_SCLK_OFFSET]
- ldr r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
- movs r1, #PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_BITS
+ movs r0, #(2 << 4 | 1)
+ str r0, [r3, #0x4]
+ ldr r0, [r3, #0x8]
+ movs r1, #2
bics r0, r1
- str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
- str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD1_OFFSET]
- str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD2_OFFSET]
- str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD3_OFFSET]
+ str r0, [r3, #0x8]
+ str r0, [r3, #0xc]
+ str r0, [r3, #0x10]
+ str r0, [r3, #0x14]
ldr r3, =XIP_SSI_BASE
// Disable SSI to allow further config
movs r1, #0
- str r1, [r3, #SSI_SSIENR_OFFSET]
+ str r1, [r3, #0x8]
// Set baud rate
- movs r1, #PICO_FLASH_SPI_CLKDIV
- str r1, [r3, #SSI_BAUDR_OFFSET]
+ movs r1, #4
+ str r1, [r3, #0x14]
- // Set 1-cycle sample delay. If PICO_FLASH_SPI_CLKDIV == 2 then this means,
+ // Set 1-cycle sample delay. If 4 == 2 then this means,
// if the flash launches data on SCLK posedge, we capture it at the time that
// the next SCLK posedge is launched. This is shortly before that posedge
// arrives at the flash, so data hold time should be ok. For
- // PICO_FLASH_SPI_CLKDIV > 2 this pretty much has no effect.
+ // 4 > 2 this pretty much has no effect.
movs r1, #1
- movs r2, #SSI_RX_SAMPLE_DLY_OFFSET // == 0xf0 so need 8 bits of offset significance
+ ldr r2, =0xf0 // == 0xf0 so need 8 bits of offset significance
str r1, [r3, r2]
// On QSPI parts we usually need a 01h SR-write command to enable QSPI mode
// (i.e. turn WPn and HOLDn into IO2/IO3)
-#ifdef PROGRAM_STATUS_REG
program_sregs:
-#define CTRL0_SPI_TXRX \
- (7 << SSI_CTRLR0_DFS_32_LSB) | /* 8 bits per data frame */ \
- (SSI_CTRLR0_TMOD_VALUE_TX_AND_RX << SSI_CTRLR0_TMOD_LSB)
+ movs r1, #7
+ lsls r1, r1, #16
+ movs r2, #0
+ lsls r2, r2, #8
+ adds r1, r1, r2
- ldr r1, =(CTRL0_SPI_TXRX)
- str r1, [r3, #SSI_CTRLR0_OFFSET]
+ str r1, [r3, #0]
// Enable SSI and select slave 0
movs r1, #1
- str r1, [r3, #SSI_SSIENR_OFFSET]
+ str r1, [r3, #0x8]
// Check whether SR needs updating
- movs r0, #CMD_READ_STATUS2
+ movs r0, #0x35
bl read_flash_sreg
- movs r2, #SREG_DATA
+ movs r2, #0x02
cmp r0, r2
beq skip_sreg_programming
// Send write enable command
- movs r1, #CMD_WRITE_ENABLE
- str r1, [r3, #SSI_DR0_OFFSET]
+ movs r1, #0x06
+ str r1, [r3, #0x60]
// Poll for completion and discard RX
bl wait_ssi_ready
- ldr r1, [r3, #SSI_DR0_OFFSET]
+ ldr r1, [r3, #0x60]
// Send status write command followed by data bytes
- movs r1, #CMD_WRITE_STATUS
- str r1, [r3, #SSI_DR0_OFFSET]
+ movs r1, #0x01
+ str r1, [r3, #0x60]
movs r0, #0
- str r0, [r3, #SSI_DR0_OFFSET]
- str r2, [r3, #SSI_DR0_OFFSET]
+ str r0, [r3, #0x60]
+ str r2, [r3, #0x60]
bl wait_ssi_ready
- ldr r1, [r3, #SSI_DR0_OFFSET]
- ldr r1, [r3, #SSI_DR0_OFFSET]
- ldr r1, [r3, #SSI_DR0_OFFSET]
+ ldr r1, [r3, #0x60]
+ ldr r1, [r3, #0x60]
+ ldr r1, [r3, #0x60]
// Poll status register for write completion
1:
- movs r0, #CMD_READ_STATUS
+ movs r0, #0x05
bl read_flash_sreg
movs r1, #1
tst r0, r1
@@ -109,8 +100,7 @@ skip_sreg_programming:
// Disable SSI again so that it can be reconfigured
movs r1, #0
- str r1, [r3, #SSI_SSIENR_OFFSET]
-#endif
+ str r1, [r3, #0x8]
// Currently the flash expects an 8 bit serial command prefix on every
// transfer, which is a waste of cycles. Perform a dummy Fast Read Quad I/O
@@ -119,38 +109,40 @@ skip_sreg_programming:
// of the read, the important part is the mode bits.
dummy_read:
-#define CTRLR0_ENTER_XIP \
- (FRAME_FORMAT /* Quad I/O mode */ \
- << SSI_CTRLR0_SPI_FRF_LSB) | \
- (31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 data bits */ \
- (SSI_CTRLR0_TMOD_VALUE_EEPROM_READ /* Send INST/ADDR, Receive Data */ \
- << SSI_CTRLR0_TMOD_LSB)
+ movs r1, #0x2
+ lsls r1, r1, #21
+ movs r2, #31
+ lsls r2, r2, #16
+ adds r1, r1, r2
+ movs r2, #3
+ lsls r2, r2, #8
+ adds r1, r1, r2
- ldr r1, =(CTRLR0_ENTER_XIP)
- str r1, [r3, #SSI_CTRLR0_OFFSET]
+ str r1, [r3, #0x0]
movs r1, #0x0 // NDF=0 (single 32b read)
- str r1, [r3, #SSI_CTRLR1_OFFSET]
-
-#define SPI_CTRLR0_ENTER_XIP \
- (ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Address + mode bits */ \
- (WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
- (SSI_SPI_CTRLR0_INST_L_VALUE_8B \
- << SSI_SPI_CTRLR0_INST_L_LSB) | /* 8-bit instruction */ \
- (SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A /* Send Command in serial mode then address in Quad I/O mode */ \
- << SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
-
- ldr r1, =(SPI_CTRLR0_ENTER_XIP)
- ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) // SPI_CTRL0 Register
+ str r1, [r3, #0x4]
+
+ movs r1, #8
+ lsls r1, r1, #2
+ movs r2, #4
+ lsls r2, r2, #11
+ adds r1, r1, r2
+ movs r2, #2
+ lsls r2, r2, #8
+ adds r1, r1, r2
+ adds r1, #1
+
+ ldr r0, =(XIP_SSI_BASE + 0xf4) // SPI_CTRL0 Register
str r1, [r0]
movs r1, #1 // Re-enable SSI
- str r1, [r3, #SSI_SSIENR_OFFSET]
+ str r1, [r3, #0x8]
- movs r1, #CMD_READ
- str r1, [r3, #SSI_DR0_OFFSET] // Push SPI command into TX FIFO
- movs r1, #MODE_CONTINUOUS_READ // 32-bit: 24 address bits (we don't care, so 0) and M[7:4]=1010
- str r1, [r3, #SSI_DR0_OFFSET] // Push Address into TX FIFO - this will trigger the transaction
+ movs r1, #0xeb
+ str r1, [r3, #0x60] // Push SPI command into TX FIFO
+ movs r1, #0xa0 // 32-bit: 24 address bits (we don't care, so 0) and M[7:4]=1010
+ str r1, [r3, #0x60] // Push Address into TX FIFO - this will trigger the transaction
// Poll for completion
bl wait_ssi_ready
@@ -160,41 +152,82 @@ dummy_read:
// into QSPI transfers of this form.
movs r1, #0
- str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
+ str r1, [r3, #0x8] // Disable SSI (and clear FIFO) to allow further config
// Note that the INST_L field is used to select what XIP data gets pushed into
// the TX FIFO:
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
configure_ssi:
-#define SPI_CTRLR0_XIP \
- (MODE_CONTINUOUS_READ /* Mode bits to keep flash in continuous read mode */ \
- << SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
- (ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
- (WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
- (SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
- << SSI_SPI_CTRLR0_INST_L_LSB) | \
- (SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
- << SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
+ movs r1, #0xa0
+ lsls r1, r1, #24
+ movs r2, #8
+ lsls r2, #2
+ adds r1, r1, r2
+ movs r2, #4
+ lsls r2, r2, #11
+ adds r1, r1, r2
+ movs r2, #0
+ lsls r2, r2, #8
+ adds r1, r1, r2
+ adds r1, #2
ldr r1, =(SPI_CTRLR0_XIP)
- ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
+ ldr r0, =(XIP_SSI_BASE + 0xf4)
str r1, [r0]
movs r1, #1
- str r1, [r3, #SSI_SSIENR_OFFSET] // Re-enable SSI
+ str r1, [r3, #0x8] // Re-enable SSI
// Bus accesses to the XIP window will now be transparently serviced by the
// external flash on cache miss. We are ready to run code from flash.
// Pull in standard exit routine
-#include "boot2_helpers/exit_from_boot2.S"
+check_return:
+ pop {r0}
+ cmp r0, #0
+ beq vector_into_flash
+ bx r0
+vector_into_flash:
+ ldr r0, =XIP_BASE
+ ldr r1, =0x100
+ adds r0, r0, r1
+ ldr r1, =PPB_BASE
+ ldr r2, =0xed08
+ adds r1, r1, r2
+ str r0, [r1]
+ ldmia r0, {r0, r1}
+ msr msp, r0
+ bx r1
+
+wait_ssi_ready:
+ push {r0, r1, lr}
+
+ // Command is complete when there is nothing left to send
+ // (TX FIFO empty) and SSI is no longer busy (CSn deasserted)
+1:
+ ldr r1, [r3, #0x28]
+ movs r0, #4
+ tst r1, r0
+ beq 1b
+ movs r0, #1
+ tst r1, r0
+ bne 1b
+
+ pop {r0, r1, pc}
+
+read_flash_sreg:
+ push {r1, lr}
+ str r0, [r3, #0x60]
+ // Dummy byte:
+ str r0, [r3, #0x60]
+
+ bl wait_ssi_ready
+ // Discard first byte and combine the next two
+ ldr r0, [r3, #0x60]
+ ldr r0, [r3, #0x60]
-// Common functions
-#include "boot2_helpers/wait_ssi_ready.S"
-#ifdef PROGRAM_STATUS_REG
-#include "boot2_helpers/read_flash_sreg.S"
-#endif
+ pop {r1, pc}
.global literals
literals: