Line 1... |
Line 1... |
// #################################################################################################
|
// #################################################################################################
|
// # << NEORV32 - Bootloader >> #
|
// # << NEORV32 - Bootloader >> #
|
// # ********************************************************************************************* #
|
// # ********************************************************************************************* #
|
// # 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. #
|
// # using the base ISA (rv32i/rv32e) only. #
|
// # ********************************************************************************************* #
|
// # ********************************************************************************************* #
|
// # Boot from (internal) instruction memory, UART or SPI Flash. #
|
// # Boot from (internal) instruction memory, UART or SPI Flash. #
|
|
// # Bootloader executables (neorv32_exe.bin) are LITTLE-ENDIAN! #
|
// # #
|
// # #
|
// # The bootloader uses the primary UART (UART0) for user console interface. #
|
// # 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) #
|
Line 224... |
Line 225... |
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
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (clock_speed/4));
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (clock_speed/4));
|
|
|
// confiure 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));
|
|
|
// active timer IRQ
|
// active timer IRQ
|
neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source
|
neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source
|
neorv32_cpu_eint(); // enable global interrupts
|
neorv32_cpu_eint(); // enable global interrupts
|
Line 248... |
Line 249... |
|
|
get_exe(EXE_STREAM_FLASH);
|
get_exe(EXE_STREAM_FLASH);
|
neorv32_uart_print("\n");
|
neorv32_uart_print("\n");
|
start_app();
|
start_app();
|
|
|
return 0;
|
return 1; // bootloader should never return
|
#endif
|
#endif
|
|
|
|
|
// ------------------------------------------------
|
// ------------------------------------------------
|
// Show bootloader intro and system info
|
// Show bootloader intro and system info
|
Line 341... |
Line 342... |
else { // unknown command
|
else { // unknown command
|
neorv32_uart_print("Invalid CMD");
|
neorv32_uart_print("Invalid CMD");
|
}
|
}
|
}
|
}
|
|
|
return 0; // bootloader should never return
|
return 1; // bootloader should never return
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* Get executable stream and execute it.
|
* Get executable stream and execute it.
|
Line 597... |
Line 598... |
} data;
|
} data;
|
|
|
uint32_t i;
|
uint32_t i;
|
for (i=0; i<4; i++) {
|
for (i=0; i<4; i++) {
|
if (src == EXE_STREAM_UART) {
|
if (src == EXE_STREAM_UART) {
|
data.uint8[3-i] = (uint8_t)neorv32_uart_getc();
|
data.uint8[i] = (uint8_t)neorv32_uart_getc();
|
}
|
}
|
else {
|
else {
|
data.uint8[3-i] = spi_flash_read_byte(addr + i);
|
data.uint8[i] = spi_flash_read_byte(addr + i);
|
}
|
}
|
}
|
}
|
|
|
return data.uint32;
|
return data.uint32;
|
}
|
}
|
Line 710... |
Line 711... |
|
|
data.uint32 = wdata;
|
data.uint32 = wdata;
|
|
|
int i;
|
int i;
|
for (i=0; i<4; i++) {
|
for (i=0; i<4; i++) {
|
spi_flash_write_byte(addr + i, data.uint8[3-i]);
|
spi_flash_write_byte(addr + i, data.uint8[i]);
|
}
|
}
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|