60 lines
1.7 KiB
C
60 lines
1.7 KiB
C
#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;
|
|
}
|