Line 66... |
Line 66... |
/** UART BAUD rate */
|
/** UART BAUD rate */
|
#define BAUD_RATE (19200)
|
#define BAUD_RATE (19200)
|
/** Enable auto-boot sequence if != 0 */
|
/** Enable auto-boot sequence if != 0 */
|
#define AUTOBOOT_EN (1)
|
#define AUTOBOOT_EN (1)
|
/** Time until the auto-boot sequence starts (in seconds) */
|
/** Time until the auto-boot sequence starts (in seconds) */
|
#define AUTOBOOT_TIMEOUT 8
|
#define AUTOBOOT_TIMEOUT (8)
|
/** Set to 0 to disable bootloader status LED */
|
/** Set to 0 to disable bootloader status LED */
|
#define STATUS_LED_EN (1)
|
#define STATUS_LED_EN (1)
|
/** SPI_DIRECT_BOOT_EN: Define/uncomment to enable SPI direct boot (disables the entire user console!) */
|
/** Set to 1 to enable SPI direct boot (disables the entire user console!) */
|
//#define SPI_DIRECT_BOOT_EN
|
#define SPI_DIRECT_BOOT_EN (0)
|
/** Bootloader status LED at GPIO output port */
|
/** Bootloader status LED at GPIO output port */
|
#define STATUS_LED (0)
|
#define STATUS_LED (0)
|
/** SPI flash boot image base address (warning! address might wrap-around!) */
|
/** SPI flash boot image base address (warning! address might wrap-around!) */
|
#define SPI_FLASH_BOOT_ADR (0x00800000)
|
#define SPI_FLASH_BOOT_ADR (0x00800000)
|
/** SPI flash chip select line at spi_csn_o */
|
/** SPI flash chip select line at spi_csn_o */
|
Line 82... |
Line 82... |
/** Default SPI flash clock prescaler */
|
/** Default SPI flash clock prescaler */
|
#define SPI_FLASH_CLK_PRSC (CLK_PRSC_8)
|
#define SPI_FLASH_CLK_PRSC (CLK_PRSC_8)
|
/** SPI flash sector size in bytes (default = 64kb) */
|
/** SPI flash sector size in bytes (default = 64kb) */
|
#define SPI_FLASH_SECTOR_SIZE (64*1024)
|
#define SPI_FLASH_SECTOR_SIZE (64*1024)
|
/** ASCII char to start fast executable upload process (for use with automatic upload scripts) */
|
/** ASCII char to start fast executable upload process (for use with automatic upload scripts) */
|
#define FAST_UPLOAD_CMD '#'
|
#define FAST_UPLOAD_CMD ('#')
|
/**@}*/
|
/**@}*/
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
Executable stream source select
|
Executable stream source select
|
Line 189... |
Line 189... |
/**********************************************************************//**
|
/**********************************************************************//**
|
* Bootloader main.
|
* Bootloader main.
|
**************************************************************************/
|
**************************************************************************/
|
int main(void) {
|
int main(void) {
|
|
|
#ifdef __riscv_compressed
|
// check ISA
|
#warning In order to allow the bootloader to run on any CPU configuration it should be compiled using the base ISA (rv32i/e) only.
|
#if defined __riscv_atomic || defined __riscv_a || __riscv_b || __riscv_compressed || defined __riscv_c || defined __riscv_mul || defined __riscv_m
|
|
#warning In order to allow the bootloader to run on *ANY* CPU configuration it should be compiled using the base ISA (rv32i/e) only.
|
#endif
|
#endif
|
|
|
exe_available = 0; // global variable for executable size; 0 means there is no exe available
|
exe_available = 0; // global variable for executable size; 0 means there is no exe available
|
getting_exe = 0; // we are not trying to get an executable yet
|
getting_exe = 0; // we are not trying to get an executable yet
|
|
|
Line 212... |
Line 213... |
}
|
}
|
else {
|
else {
|
neorv32_spi_setup(CLK_PRSC_128, 0, 0);
|
neorv32_spi_setup(CLK_PRSC_128, 0, 0);
|
}
|
}
|
|
|
if (STATUS_LED_EN == 1) {
|
#if (STATUS_LED_EN != 0)
|
// activate status LED, clear all others
|
// activate status LED, clear all others
|
neorv32_gpio_port_set(1 << STATUS_LED);
|
neorv32_gpio_port_set(1 << STATUS_LED);
|
}
|
#endif
|
|
|
// init UART (no parity bit, no hardware flow control)
|
// init UART (no parity bit, no hardware flow control)
|
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
|
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
|
|
|
// Configure machine system timer interrupt for ~2Hz
|
// Configure machine system timer interrupt for ~2Hz
|
Line 236... |
Line 237... |
// ------------------------------------------------
|
// ------------------------------------------------
|
// Fast boot mode: Direct SPI boot
|
// Fast boot mode: Direct SPI boot
|
// Bootloader will directly boot and execute image from SPI memory.
|
// Bootloader will directly boot and execute image from SPI memory.
|
// No user UART console is available in this mode!
|
// No user UART console is available in this mode!
|
// ------------------------------------------------
|
// ------------------------------------------------
|
#ifdef SPI_DIRECT_BOOT_EN
|
#if (SPI_DIRECT_BOOT_EN != 0)
|
#warning Compiling bootloader in 'SPI direct boot mode'. Bootloader will directly boot from SPI memory. No user UART console will be available.
|
#warning Compiling bootloader in 'SPI direct boot mode'. Bootloader will directly boot from SPI memory. No user UART console will be available.
|
|
|
neorv32_uart_print("\nNEORV32 bootloader\nAccessing SPI flash at ");
|
neorv32_uart_print("\nNEORV32 bootloader\nAccessing SPI flash at ");
|
print_hex_word((uint32_t)SPI_FLASH_BOOT_ADR);
|
print_hex_word((uint32_t)SPI_FLASH_BOOT_ADR);
|
neorv32_uart_print("\n");
|
neorv32_uart_print("\n");
|
Line 416... |
Line 417... |
|
|
uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
|
|
// make sure this was caused by MTIME IRQ
|
// make sure this was caused by MTIME IRQ
|
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
|
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
|
if (STATUS_LED_EN == 1) {
|
#if (STATUS_LED_EN != 0)
|
// toggle status LED
|
// toggle status LED
|
neorv32_gpio_pin_toggle(STATUS_LED);
|
neorv32_gpio_pin_toggle(STATUS_LED);
|
}
|
#endif
|
// set time for next IRQ
|
// set time for next IRQ
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
|
}
|
}
|
else {
|
else {
|
// store bus access error during get_exe
|
// store bus access error during get_exe
|
Line 431... |
Line 432... |
if ((cause == TRAP_CODE_S_ACCESS) && (getting_exe)) {
|
if ((cause == TRAP_CODE_S_ACCESS) && (getting_exe)) {
|
system_error(ERROR_SIZE);
|
system_error(ERROR_SIZE);
|
}
|
}
|
// unknown error
|
// unknown error
|
else {
|
else {
|
neorv32_uart_print("\n\nEXC (");
|
neorv32_uart_print("\n\nEXCEPTION mcause=");
|
print_hex_word(cause);
|
print_hex_word(cause);
|
neorv32_uart_print(") @ 0x");
|
neorv32_uart_print(" @ pc=");
|
print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
|
print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
|
system_error(ERROR_SYSTEM);
|
system_error(ERROR_SYSTEM);
|
}
|
}
|
}
|
}
|
}
|
}
|
Line 631... |
Line 632... |
*
|
*
|
* @param[in] num Number to print as hexadecimal.
|
* @param[in] num Number to print as hexadecimal.
|
**************************************************************************/
|
**************************************************************************/
|
void print_hex_word(uint32_t num) {
|
void print_hex_word(uint32_t num) {
|
|
|
static const char hex_symbols[16] = "0123456789ABCDEF";
|
static const char hex_symbols[16] = "0123456789abcdef";
|
|
|
neorv32_uart_print("0x");
|
neorv32_uart_print("0x");
|
|
|
int i;
|
int i;
|
for (i=0; i<8; i++) {
|
for (i=0; i<8; i++) {
|