From ec54eb19e394552fbe26c4593878f81811c98fb8 Mon Sep 17 00:00:00 2001 From: zhji Date: Sat, 19 Apr 2025 21:07:29 +0800 Subject: [PATCH] [feat] add boot2_copy_self --- driver/inc/reg/ssi_reg.h | 50 +++++++++++++++++++++++++++++++++++++ example/boot2/boot2.ld | 3 +++ example/boot2/boot2_pre.S | 1 + example/boot2/main.c | 52 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 driver/inc/reg/ssi_reg.h diff --git a/driver/inc/reg/ssi_reg.h b/driver/inc/reg/ssi_reg.h new file mode 100644 index 0000000..d649088 --- /dev/null +++ b/driver/inc/reg/ssi_reg.h @@ -0,0 +1,50 @@ +#ifndef __HARDWARE_SSI_REG_H__ +#define __HARDWARE_SSI_REG_H__ + +#include "reg.h" + +typedef struct { + io_rw_32 ctrlr0; + io_rw_32 ctrlr1; + io_rw_32 ssienr; + io_rw_32 mwcr; + io_rw_32 ser; + io_rw_32 baudr; + io_rw_32 txftlr; + io_rw_32 rxftlr; + io_rw_32 txflr; + io_rw_32 rxflr; + io_rw_32 sr; + io_rw_32 imr; + io_rw_32 isr; + io_rw_32 risr; + io_rw_32 txoicr; + io_rw_32 rxoicr; + io_rw_32 rxuicr; + io_rw_32 msticr; + io_rw_32 icr; + io_rw_32 dmacr; + io_rw_32 dmatdlr; + io_rw_32 dmardlr; + io_rw_32 idr; + io_rw_32 ssi_version_id; + io_rw_32 dr0; + uint32_t _pad[(0xf0 - 0x60) / 4 - 1]; + io_rw_32 rx_sample_dly; + io_rw_32 spi_ctrlr0; + io_rw_32 txd_drive_edge; +} ssi_hw_t; + +#define ssi_hw ((ssi_hw_t *const)XIP_SSI_BASE) +#define ssi_hw_set ((ssi_hw_t *const)hw_set_alias_untyped(ssi_hw)) +#define ssi_hw_clear ((ssi_hw_t *const)hw_clear_alias_untyped(ssi_hw)) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_SSI_REG_H__ */ diff --git a/example/boot2/boot2.ld b/example/boot2/boot2.ld index 4b0f09e..27a688a 100644 --- a/example/boot2/boot2.ld +++ b/example/boot2/boot2.ld @@ -34,6 +34,7 @@ SECTIONS .text : { . = ALIGN(4); + _boot2_copy_self_start_addr = .; *(.text*) . = ALIGN(4); } >RAM AT > FLASH :text @@ -52,6 +53,8 @@ SECTIONS . = ALIGN(4); } >RAM AT > FLASH :data + _boot2_copy_self_end_addr = .; + .bss (NOLOAD) : { . = ALIGN(4); diff --git a/example/boot2/boot2_pre.S b/example/boot2/boot2_pre.S index 3cf46a1..f9a6f98 100644 --- a/example/boot2/boot2_pre.S +++ b/example/boot2/boot2_pre.S @@ -11,6 +11,7 @@ boot2_pre: msr msp, r0 bl boot2_copy_self bl main + b . .word 0x11223344 .word 0xabcdef58 diff --git a/example/boot2/main.c b/example/boot2/main.c index eef6389..9d367ae 100644 --- a/example/boot2/main.c +++ b/example/boot2/main.c @@ -1,6 +1,56 @@ +#include "gpio.h" +#include "ssi_reg.h" + void __attribute__((section(".text.boot2_pre"))) boot2_copy_self(void) { - return; + #define BOOT2_FLASHCMD_READ_DATA (0x03) + #define BOOT2_FLASH_OFFSET (256) + extern uint32_t _boot2_copy_self_start_addr; + extern uint32_t _boot2_copy_self_end_addr; + + io_rw_32 *reg; + uint32_t cmd; + uint32_t length, tx_count, rx_count, rx_skip; + uint8_t *copy_to_addr; + uint8_t rxbyte; + + /* force QSPI_CS low level as selected */ + reg = (io_rw_32 *)(IO_QSPI_BASE + GPIO_QSPI_CS_CTRL_OFFSET); + *reg = GPIO_OVER_OUT_FORCE_LOW << GPIO_OVER_OUT_POS; + + /* send command and length */ + cmd = (BOOT2_FLASHCMD_READ_DATA << 24) | BOOT2_FLASH_OFFSET; + for (int i = 0; i < 4; ++i) { + ssi_hw->dr0 = cmd >> 24; + cmd <<= 8; + } + /* init parameter */ + length = (uint32_t)&_boot2_copy_self_end_addr - (uint32_t)&_boot2_copy_self_start_addr; + tx_count = length; + rx_count = length; + rx_skip = 4; + copy_to_addr = (uint8_t *)&_boot2_copy_self_start_addr; + /* copy data from flash to ram */ + while (tx_count || rx_skip || rx_count) { + uint32_t tx_level = ssi_hw->txflr; + uint32_t rx_level = ssi_hw->rxflr; + if (tx_count && tx_level + rx_level < 14) { + ssi_hw->dr0 = 0; + tx_count--; + } + if (rx_level) { + rxbyte = ssi_hw->dr0; + if (rx_skip) { + rx_skip--; + } else { + *copy_to_addr++ = rxbyte; + rx_count--; + } + } + } + + /* force QSPI_CS high level as disselected */ + *reg = GPIO_OVER_OUT_FORCE_HIGH << GPIO_OVER_OUT_POS; } int main(void)