#include "gpio.h" #include "ssi_reg.h" void __attribute__((section(".text.boot2_pre"))) boot2_copy_self(void) { #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) { return 0; }