Line 286... |
Line 286... |
#warning Custom boot configuration: Auto boot from external SPI flash.
|
#warning Custom boot configuration: Auto boot from external SPI flash.
|
|
|
// setup UART0 (primary UART, no parity bit, no hardware flow control)
|
// setup UART0 (primary UART, no parity bit, no hardware flow control)
|
neorv32_uart0_setup(UART_BAUD, PARITY_NONE, FLOW_CONTROL_NONE);
|
neorv32_uart0_setup(UART_BAUD, PARITY_NONE, FLOW_CONTROL_NONE);
|
// SPI setup
|
// SPI setup
|
neorv32_spi_setup(SPI_FLASH_CLK_PRSC, 0, 0);
|
neorv32_spi_setup(SPI_FLASH_CLK_PRSC, 0, 0, 0);
|
|
|
PRINT_TEXT("\nNEORV32 bootloader\nLoading from SPI flash at ");
|
PRINT_TEXT("\nNEORV32 bootloader\nLoading from SPI flash at ");
|
PRINT_XNUM((uint32_t)SPI_BOOT_BASE_ADDR);
|
PRINT_XNUM((uint32_t)SPI_BOOT_BASE_ADDR);
|
PRINT_TEXT("...\n");
|
PRINT_TEXT("...\n");
|
|
|
Line 314... |
Line 314... |
// configure trap handler (bare-metal, no neorv32 rte available)
|
// configure trap handler (bare-metal, no neorv32 rte available)
|
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
|
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
|
|
|
#if (SPI_EN != 0)
|
#if (SPI_EN != 0)
|
// setup SPI for 8-bit, clock-mode 0
|
// setup SPI for 8-bit, clock-mode 0
|
neorv32_spi_setup(SPI_FLASH_CLK_PRSC, 0, 0);
|
neorv32_spi_setup(SPI_FLASH_CLK_PRSC, 0, 0, 0);
|
#endif
|
#endif
|
|
|
#if (STATUS_LED_EN != 0)
|
#if (STATUS_LED_EN != 0)
|
if (neorv32_gpio_available()) {
|
if (neorv32_gpio_available()) {
|
// activate status LED, clear all others
|
// activate status LED, clear all others
|
Line 331... |
Line 331... |
neorv32_uart0_setup(UART_BAUD, PARITY_NONE, FLOW_CONTROL_NONE);
|
neorv32_uart0_setup(UART_BAUD, PARITY_NONE, FLOW_CONTROL_NONE);
|
#endif
|
#endif
|
|
|
// Configure machine system timer interrupt for ~2Hz
|
// Configure machine system timer interrupt for ~2Hz
|
if (neorv32_mtime_available()) {
|
if (neorv32_mtime_available()) {
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (NEORV32_SYSINFO.CLK/4));
|
neorv32_mtime_set_timecmp(neorv32_cpu_get_systime() + (NEORV32_SYSINFO.CLK/4));
|
// active timer IRQ
|
// active timer IRQ
|
neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source only!
|
neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source only!
|
neorv32_cpu_eint(); // enable global interrupts
|
neorv32_cpu_eint(); // enable global interrupts
|
}
|
}
|
|
|
Line 370... |
Line 370... |
#if (SPI_EN != 0)
|
#if (SPI_EN != 0)
|
#if (AUTO_BOOT_TIMEOUT != 0)
|
#if (AUTO_BOOT_TIMEOUT != 0)
|
if (neorv32_mtime_available()) {
|
if (neorv32_mtime_available()) {
|
|
|
PRINT_TEXT("\n\nAutoboot in "xstr(AUTO_BOOT_TIMEOUT)"s. Press key to abort.\n");
|
PRINT_TEXT("\n\nAutoboot in "xstr(AUTO_BOOT_TIMEOUT)"s. Press key to abort.\n");
|
uint64_t timeout_time = neorv32_mtime_get_time() + (uint64_t)(AUTO_BOOT_TIMEOUT * NEORV32_SYSINFO.CLK);
|
uint64_t timeout_time = neorv32_cpu_get_systime() + (uint64_t)(AUTO_BOOT_TIMEOUT * NEORV32_SYSINFO.CLK);
|
|
|
while(1){
|
while(1){
|
|
|
if (neorv32_uart0_available()) { // wait for any key to be pressed
|
if (neorv32_uart0_available()) { // wait for any key to be pressed
|
if (neorv32_uart0_char_received()) {
|
if (neorv32_uart0_char_received()) {
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
if (neorv32_mtime_get_time() >= timeout_time) { // timeout? start auto boot sequence
|
if (neorv32_cpu_get_systime() >= timeout_time) { // timeout? start auto boot sequence
|
get_exe(EXE_STREAM_FLASH); // try booting from flash
|
get_exe(EXE_STREAM_FLASH); // try booting from flash
|
PRINT_TEXT("\n");
|
PRINT_TEXT("\n");
|
start_app();
|
start_app();
|
while(1);
|
while(1);
|
}
|
}
|
Line 501... |
Line 501... |
neorv32_gpio_pin_toggle(STATUS_LED_PIN); // toggle status LED
|
neorv32_gpio_pin_toggle(STATUS_LED_PIN); // toggle status LED
|
}
|
}
|
#endif
|
#endif
|
// set time for next IRQ
|
// set time for next IRQ
|
if (neorv32_mtime_available()) {
|
if (neorv32_mtime_available()) {
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (NEORV32_SYSINFO.CLK/4));
|
neorv32_mtime_set_timecmp(neorv32_cpu_get_systime() + (NEORV32_SYSINFO.CLK/4));
|
}
|
}
|
}
|
}
|
|
|
// Bus store access error during get_exe
|
// Bus store access error during get_exe
|
else if ((cause == TRAP_CODE_S_ACCESS) && (getting_exe)) {
|
else if ((cause == TRAP_CODE_S_ACCESS) && (getting_exe)) {
|