OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [bootloader/] [bootloader.c] - Diff between revs 69 and 72

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 69 Rev 72
Line 1... Line 1...
// #################################################################################################
// #################################################################################################
// # << NEORV32 - Bootloader >>                                                                    #
// # << NEORV32 - Bootloader >>                                                                    #
// # ********************************************************************************************* #
// # ********************************************************************************************* #
// # BSD 3-Clause License                                                                          #
// # BSD 3-Clause License                                                                          #
// #                                                                                               #
// #                                                                                               #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
// #                                                                                               #
// #                                                                                               #
// # Redistribution and use in source and binary forms, with or without modification, are          #
// # Redistribution and use in source and binary forms, with or without modification, are          #
// # permitted provided that the following conditions are met:                                     #
// # permitted provided that the following conditions are met:                                     #
// #                                                                                               #
// #                                                                                               #
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
Line 142... Line 142...
  ERROR_SIZE      = 1, /**< 1: Insufficient instruction memory capacity */
  ERROR_SIZE      = 1, /**< 1: Insufficient instruction memory capacity */
  ERROR_CHECKSUM  = 2, /**< 2: Checksum error in executable */
  ERROR_CHECKSUM  = 2, /**< 2: Checksum error in executable */
  ERROR_FLASH     = 3  /**< 3: SPI flash access error */
  ERROR_FLASH     = 3  /**< 3: SPI flash access error */
};
};
 
 
 
/**********************************************************************//**
 
 * Error messages
 
 **************************************************************************/
 
const char error_message[4][24] = {
 
  "exe signature fail",
 
  "exceeding IMEM capacity",
 
  "checksum fail",
 
  "SPI flash access failed"
 
};
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * SPI flash commands
 * SPI flash commands
 **************************************************************************/
 **************************************************************************/
enum SPI_FLASH_CMD {
enum SPI_FLASH_CMD {
Line 168... Line 178...
  EXE_OFFSET_DATA      = 12, /**< Offset in bytes from start to data (32-bit) */
  EXE_OFFSET_DATA      = 12, /**< Offset in bytes from start to data (32-bit) */
};
};
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Valid executable identification signature.
 * Valid executable identification signature
 **************************************************************************/
 **************************************************************************/
#define EXE_SIGNATURE 0x4788CAFE
#define EXE_SIGNATURE 0x4788CAFE
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
Line 329... Line 339...
#if (UART_EN != 0)
#if (UART_EN != 0)
  // 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);
#endif
#endif
 
 
  // Configure machine system timer interrupt for ~2Hz
  // Configure machine system timer interrupt
  if (neorv32_mtime_available()) {
  if (neorv32_mtime_available()) {
    neorv32_mtime_set_timecmp(neorv32_cpu_get_systime() + (NEORV32_SYSINFO.CLK/4));
    neorv32_mtime_set_timecmp(0 + (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 346... Line 356...
  PRINT_TEXT("\n\n\n<< NEORV32 Bootloader >>\n\n"
  PRINT_TEXT("\n\n\n<< NEORV32 Bootloader >>\n\n"
                     "BLDV: "__DATE__"\nHWV:  ");
                     "BLDV: "__DATE__"\nHWV:  ");
  PRINT_XNUM(neorv32_cpu_csr_read(CSR_MIMPID));
  PRINT_XNUM(neorv32_cpu_csr_read(CSR_MIMPID));
  PRINT_TEXT("\nCLK:  ");
  PRINT_TEXT("\nCLK:  ");
  PRINT_XNUM(NEORV32_SYSINFO.CLK);
  PRINT_XNUM(NEORV32_SYSINFO.CLK);
  PRINT_TEXT("\nMISA: ");
  PRINT_TEXT("\nISA:  ");
  PRINT_XNUM(neorv32_cpu_csr_read(CSR_MISA));
  PRINT_XNUM(neorv32_cpu_csr_read(CSR_MISA));
  PRINT_TEXT("\nCPU:  ");
  PRINT_TEXT(" + ");
  PRINT_XNUM(NEORV32_SYSINFO.CPU);
  PRINT_XNUM(neorv32_cpu_csr_read(CSR_MXISA));
  PRINT_TEXT("\nSOC:  ");
  PRINT_TEXT("\nSOC:  ");
  PRINT_XNUM(NEORV32_SYSINFO.SOC);
  PRINT_XNUM(NEORV32_SYSINFO.SOC);
  PRINT_TEXT("\nIMEM: ");
  PRINT_TEXT("\nIMEM: ");
  PRINT_XNUM(NEORV32_SYSINFO.IMEM_SIZE);
  PRINT_XNUM(NEORV32_SYSINFO.IMEM_SIZE); PRINT_TEXT(" bytes @");
  PRINT_TEXT(" bytes @");
 
  PRINT_XNUM(NEORV32_SYSINFO.ISPACE_BASE);
  PRINT_XNUM(NEORV32_SYSINFO.ISPACE_BASE);
  PRINT_TEXT("\nDMEM: ");
  PRINT_TEXT("\nDMEM: ");
  PRINT_XNUM(NEORV32_SYSINFO.DMEM_SIZE);
  PRINT_XNUM(NEORV32_SYSINFO.DMEM_SIZE);
  PRINT_TEXT(" bytes @");
  PRINT_TEXT(" bytes @");
  PRINT_XNUM(NEORV32_SYSINFO.DSPACE_BASE);
  PRINT_XNUM(NEORV32_SYSINFO.DSPACE_BASE);
Line 369... Line 378...
  // ------------------------------------------------
  // ------------------------------------------------
#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 any key to abort.\n");
    uint64_t timeout_time = neorv32_cpu_get_systime() + (uint64_t)(AUTO_BOOT_TIMEOUT * NEORV32_SYSINFO.CLK);
    uint64_t timeout_time = neorv32_mtime_get_time() + (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_cpu_get_systime() >= timeout_time) { // timeout? start auto boot sequence
      if (neorv32_mtime_get_time() >= 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 436... Line 445...
      }
      }
      else {
      else {
        start_app();
        start_app();
      }
      }
    }
    }
 
    else if (c == '?') {
 
      PRINT_TEXT("(c) by Stephan Nolting\nhttps://github.com/stnolting/neorv32");
 
    }
    else { // unknown command
    else { // unknown command
      PRINT_TEXT("Invalid CMD");
      PRINT_TEXT("Invalid CMD");
    }
    }
  }
  }
 
 
Line 502... Line 514...
      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_cpu_get_systime() + (NEORV32_SYSINFO.CLK/4));
      neorv32_mtime_set_timecmp(neorv32_mtime_get_timecmp() + (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)) {
Line 516... Line 528...
  // 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 {
    register 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[ERR ");
      PRINT_TEXT("\n[ERROR - Unexpected exception! mcause=");
      PRINT_XNUM(cause); // MCAUSE
      PRINT_XNUM(cause); // MCAUSE
      PRINT_PUTC(' ');
      PRINT_TEXT(" mepc=");
      PRINT_XNUM(epc); // MEPC
      PRINT_XNUM(epc); // MEPC
      PRINT_PUTC(' ');
      PRINT_TEXT(" mtval=");
      PRINT_XNUM(neorv32_cpu_csr_read(CSR_MTVAL)); // MTVAL
      PRINT_XNUM(neorv32_cpu_csr_read(CSR_MTVAL)); // MTVAL
      PRINT_TEXT("]\n");
      PRINT_TEXT("] trying to resume...\n");
    }
    }
#endif
#endif
    neorv32_cpu_csr_write(CSR_MEPC, epc + 4); // advance to next instruction
    neorv32_cpu_csr_write(CSR_MEPC, epc + 4); // advance to next instruction
  }
  }
}
}
Line 697... Line 709...
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Output system error ID and stall.
 * Output system error ID and stall.
 *
 *
 * @param[in] err_code Error code. See #ERROR_CODES.
 * @param[in] err_code Error code. See #ERROR_CODES and #error_message.
 **************************************************************************/
 **************************************************************************/
void system_error(uint8_t err_code) {
void system_error(uint8_t err_code) {
 
 
  PRINT_TEXT("\a\nERROR_"); // output error code with annoying bell sound
  PRINT_TEXT("\a\nERROR_"); // output error code with annoying bell sound
  PRINT_PUTC('0' + ((char)err_code));
  PRINT_PUTC('0' + ((char)err_code));
 
  PRINT_PUTC(':');
 
  PRINT_PUTC(' ');
 
  PRINT_TEXT(error_message[err_code]);
 
 
  neorv32_cpu_dint(); // deactivate IRQs
  neorv32_cpu_dint(); // deactivate IRQs
#if (STATUS_LED_EN != 0)
#if (STATUS_LED_EN != 0)
  if (neorv32_gpio_available()) {
  if (neorv32_gpio_available()) {
    neorv32_gpio_port_set(1 << STATUS_LED_PIN); // permanently light up status LED
    neorv32_gpio_port_set(1 << STATUS_LED_PIN); // permanently light up status LED

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.