Line 4... |
Line 4... |
// # In order to run the bootloader on any CPU configuration, the bootloader should be compiled #
|
// # In order to run the bootloader on any CPU configuration, the bootloader should be compiled #
|
// # unsing the base ISA (rv32i/rv32e) only. #
|
// # unsing the base ISA (rv32i/rv32e) only. #
|
// # ********************************************************************************************* #
|
// # ********************************************************************************************* #
|
// # Boot from (internal) instruction memory, UART or SPI Flash. #
|
// # Boot from (internal) instruction memory, UART or SPI Flash. #
|
// # #
|
// # #
|
|
// # The bootloader uses the primary UART (UART0) for user console interface. #
|
|
// # #
|
// # UART configuration: 8 data bits, NO parity bit, 1 stop bit, 19200 baud (19200-8N1) #
|
// # UART configuration: 8 data bits, NO parity bit, 1 stop bit, 19200 baud (19200-8N1) #
|
// # Boot Flash: 8-bit SPI, 24-bit addresses (like Micron N25Q032A) @ neorv32.spi_csn_o(0) #
|
// # Boot Flash: 8-bit SPI, 24-bit addresses (like Micron N25Q032A) @ neorv32.spi_csn_o(0) #
|
// # neorv32.gpio_o(0) is used as high-active status LED (can be disabled via #STATUS_LED_EN). #
|
// # neorv32.gpio_o(0) is used as high-active status LED (can be disabled via #STATUS_LED_EN). #
|
// # #
|
// # #
|
// # Auto boot sequence (can be disabled via #AUTOBOOT_EN) after timeout (via #AUTOBOOT_TIMEOUT): #
|
// # Auto boot sequence (can be disabled via #AUTOBOOT_EN) after timeout (via #AUTOBOOT_TIMEOUT): #
|
Line 281... |
Line 283... |
#if (AUTOBOOT_EN != 0)
|
#if (AUTOBOOT_EN != 0)
|
neorv32_uart_print("\n\nAutoboot in "xstr(AUTOBOOT_TIMEOUT)"s. Press key to abort.\n");
|
neorv32_uart_print("\n\nAutoboot in "xstr(AUTOBOOT_TIMEOUT)"s. Press key to abort.\n");
|
|
|
uint64_t timeout_time = neorv32_mtime_get_time() + (uint64_t)(AUTOBOOT_TIMEOUT * clock_speed);
|
uint64_t timeout_time = neorv32_mtime_get_time() + (uint64_t)(AUTOBOOT_TIMEOUT * clock_speed);
|
|
|
while ((UART_DATA & (1 << UART_DATA_AVAIL)) == 0) { // wait for any key to be pressed
|
while (neorv32_uart_char_received() == 0) { // wait for any key to be pressed
|
|
|
if (neorv32_mtime_get_time() >= timeout_time) { // timeout? start auto boot sequence
|
if (neorv32_mtime_get_time() >= timeout_time) { // timeout? start auto boot sequence
|
fast_upload(EXE_STREAM_FLASH); // try booting from flash
|
fast_upload(EXE_STREAM_FLASH); // try booting from flash
|
}
|
}
|
}
|
}
|
Line 393... |
Line 395... |
neorv32_cpu_dint();
|
neorv32_cpu_dint();
|
|
|
neorv32_uart_print("Booting...\n\n");
|
neorv32_uart_print("Booting...\n\n");
|
|
|
// wait for UART to finish transmitting
|
// wait for UART to finish transmitting
|
while ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0);
|
while (neorv32_uart_tx_busy());
|
|
|
// start app at instruction space base address
|
// start app at instruction space base address
|
register uint32_t app_base = SYSINFO_ISPACE_BASE;
|
register uint32_t app_base = SYSINFO_ISPACE_BASE;
|
asm volatile ("jalr zero, %0" : : "r" (app_base));
|
asm volatile ("jalr zero, %0" : : "r" (app_base));
|
while (1);
|
while (1);
|