Line 409... |
Line 409... |
|
|
PRINT_TEXT("\nCMD:> ");
|
PRINT_TEXT("\nCMD:> ");
|
char c = PRINT_GETC();
|
char c = PRINT_GETC();
|
PRINT_PUTC(c); // echo
|
PRINT_PUTC(c); // echo
|
PRINT_TEXT("\n");
|
PRINT_TEXT("\n");
|
|
while (neorv32_uart0_tx_busy());
|
|
|
if (c == 'r') { // restart bootloader
|
if (c == 'r') { // restart bootloader
|
asm volatile ("li t0, %[input_i]; jr t0" : : [input_i] "i" (BOOTLOADER_BASE_ADDRESS)); // jump to beginning of boot ROM
|
asm volatile ("li t0, %[input_i]; jr t0" : : [input_i] "i" (BOOTLOADER_BASE_ADDRESS)); // jump to beginning of boot ROM
|
}
|
}
|
else if (c == 'h') { // help menu
|
else if (c == 'h') { // help menu
|
Line 490... |
Line 491... |
*
|
*
|
* @note Since we have no runtime environment, we have to use the interrupt attribute here. Here and only here!
|
* @note Since we have no runtime environment, we have to use the interrupt attribute here. Here and only here!
|
**************************************************************************/
|
**************************************************************************/
|
void __attribute__((__interrupt__)) bootloader_trap_handler(void) {
|
void __attribute__((__interrupt__)) bootloader_trap_handler(void) {
|
|
|
uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
register uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
|
|
// Machine timer interrupt
|
// Machine timer interrupt
|
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
|
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
|
#if (STATUS_LED_EN != 0)
|
#if (STATUS_LED_EN != 0)
|
if (neorv32_gpio_available()) {
|
if (neorv32_gpio_available()) {
|
Line 512... |
Line 513... |
system_error(ERROR_SIZE); // -> seems like executable is too large
|
system_error(ERROR_SIZE); // -> seems like executable is too large
|
}
|
}
|
|
|
// Anything else (that was not expected); output exception notifier and try to resume
|
// Anything else (that was not expected); output exception notifier and try to resume
|
else {
|
else {
|
uint32_t epc = neorv32_cpu_csr_read(CSR_MEPC);
|
register uint32_t epc = neorv32_cpu_csr_read(CSR_MEPC);
|
#if (UART_EN != 0)
|
#if (UART_EN != 0)
|
if (neorv32_uart0_available()) {
|
if (neorv32_uart0_available()) {
|
PRINT_TEXT("\n[EXC ");
|
PRINT_TEXT("\n[ERR ");
|
PRINT_XNUM(cause); // MCAUSE
|
PRINT_XNUM(cause); // MCAUSE
|
PRINT_PUTC(' ');
|
PRINT_PUTC(' ');
|
PRINT_XNUM(epc); // MEPC
|
PRINT_XNUM(epc); // MEPC
|
PRINT_PUTC(' ');
|
PRINT_PUTC(' ');
|
PRINT_XNUM(neorv32_cpu_csr_read(CSR_MTVAL)); // MTVAL
|
PRINT_XNUM(neorv32_cpu_csr_read(CSR_MTVAL)); // MTVAL
|
Line 550... |
Line 551... |
#if (SPI_EN != 0)
|
#if (SPI_EN != 0)
|
else {
|
else {
|
PRINT_TEXT("Loading... ");
|
PRINT_TEXT("Loading... ");
|
|
|
// flash checks
|
// flash checks
|
if ((neorv32_spi_available() == 0) || // check if SPI is available at all
|
if (spi_flash_read_1st_id() == 0x00) { // check if flash ready (or available at all)
|
(spi_flash_read_1st_id() == 0x00)) { // check if flash ready (or available at all)
|
|
system_error(ERROR_FLASH);
|
system_error(ERROR_FLASH);
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
|
|
Line 611... |
Line 611... |
uint32_t addr = (uint32_t)SPI_BOOT_BASE_ADDR;
|
uint32_t addr = (uint32_t)SPI_BOOT_BASE_ADDR;
|
|
|
// info and prompt
|
// info and prompt
|
PRINT_TEXT("Write ");
|
PRINT_TEXT("Write ");
|
PRINT_XNUM(size);
|
PRINT_XNUM(size);
|
PRINT_TEXT(" bytes to SPI flash @ ");
|
PRINT_TEXT(" bytes to SPI flash @0x");
|
PRINT_XNUM(addr);
|
PRINT_XNUM(addr);
|
PRINT_TEXT("? (y/n) ");
|
PRINT_TEXT("? (y/n) ");
|
|
|
char c = PRINT_GETC();
|
char c = PRINT_GETC();
|
PRINT_PUTC(c);
|
PRINT_PUTC(c);
|