75 lines
1.8 KiB
C
75 lines
1.8 KiB
C
#include "clock_config.h"
|
|
#include "peripherals.h"
|
|
#include "pin_mux.h"
|
|
|
|
#define APP_BASE (0x90000000)
|
|
#define APP_MAX_SIZE (256 * 1024 * 1024) /* Maximum Quad SPI address space */
|
|
|
|
typedef void (*app_entry_t)(void);
|
|
|
|
static int app_map_qspi(void);
|
|
static int app_boot_xip(void);
|
|
|
|
int main(void) {
|
|
HAL_Init();
|
|
|
|
BOARD_InitBootClocks();
|
|
BOARD_InitBootPins();
|
|
BOARD_InitBootPeripherals();
|
|
|
|
if (app_map_qspi() != 0) {
|
|
goto boot_fail_loop;
|
|
}
|
|
|
|
if (app_boot_xip() != 0) {
|
|
goto boot_fail_loop;
|
|
}
|
|
|
|
boot_fail_loop:
|
|
for (;;) {
|
|
HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
|
|
HAL_Delay(500);
|
|
}
|
|
}
|
|
|
|
static int app_map_qspi(void) {
|
|
QSPI_CommandTypeDef cmd = {
|
|
.Instruction = 0xEC, /* Fast read quad IO with 4 byte address <1-4-4> */
|
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
|
.AddressMode = QSPI_ADDRESS_4_LINES,
|
|
.AddressSize = QSPI_ADDRESS_32_BITS,
|
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES,
|
|
.DataMode = QSPI_DATA_4_LINES,
|
|
.DummyCycles = 4U,
|
|
};
|
|
|
|
QSPI_MemoryMappedTypeDef mmap = {
|
|
.TimeOutPeriod = 0xFFFFU,
|
|
.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE,
|
|
};
|
|
|
|
if (HAL_QSPI_MemoryMapped(&hqspi, &cmd, &mmap) != HAL_OK) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int app_boot_xip(void) {
|
|
uint32_t initial_sp = *(uint32_t *)APP_BASE;
|
|
uint32_t reset_vect = *(uint32_t *)(APP_BASE + 4);
|
|
|
|
if ((reset_vect < APP_BASE) || (reset_vect > (APP_BASE + APP_MAX_SIZE))) {
|
|
/* PC is invalid */
|
|
return -1;
|
|
}
|
|
|
|
app_entry_t entry = (app_entry_t)reset_vect;
|
|
|
|
SysTick->CTRL = 0U; /* Disable SysTick interrupt */
|
|
SCB->VTOR = APP_BASE; /* Initialize */
|
|
__set_MSP(initial_sp);
|
|
entry();
|
|
|
|
return 0; /* Useless. */
|
|
} |