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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [bootloader/] [bootloader.c] - Diff between revs 37 and 39

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

Rev 37 Rev 39
Line 67... Line 67...
#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!) */
 
//#define SPI_DIRECT_BOOT_EN
/** 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 179... Line 181...
/**********************************************************************//**
/**********************************************************************//**
 * Bootloader main.
 * Bootloader main.
 **************************************************************************/
 **************************************************************************/
int main(void) {
int main(void) {
 
 
 
#ifdef __riscv_compressed
 
  #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
 
 
 
  // global variable for executable size; 0 means there is no exe available
 
  exe_available = 0;
 
 
 
  // ------------------------------------------------
 
  // Minimal CPU hardware initialization
 
  // - all IO devices are reset and disabled by the crt0 code
 
  // ------------------------------------------------
 
 
 
  // confiure trap handler (bare-metal, no neorv32 rte available)
 
  neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
 
 
 
 
  // ------------------------------------------------
  // ------------------------------------------------
  // Processor hardware initialization
  // Minimal processor hardware initialization
  // - all IO devices are reset and disabled by the crt0 code
  // - all IO devices are reset and disabled by the crt0 code
  // ------------------------------------------------
  // ------------------------------------------------
 
 
  // get clock speed (in Hz)
  // get clock speed (in Hz)
  uint32_t clock_speed = SYSINFO_CLK;
  uint32_t clock_speed = SYSINFO_CLK;
Line 195... Line 213...
  }
  }
  else {
  else {
    neorv32_spi_setup(CLK_PRSC_128, 0, 0, 0);
    neorv32_spi_setup(CLK_PRSC_128, 0, 0, 0);
  }
  }
 
 
 
  if (STATUS_LED_EN == 1) {
 
    // activate status LED, clear all others
 
    neorv32_gpio_port_set(1 << STATUS_LED);
 
  }
 
 
  // init UART (no interrupts)
  // init UART (no interrupts)
  neorv32_uart_setup(BAUD_RATE, 0, 0);
  neorv32_uart_setup(BAUD_RATE, 0, 0);
 
 
  // 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)
 
  neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
 
 
 
  neorv32_cpu_csr_write(CSR_MIE, 1 << CPU_MIE_MTIE); // activate MTIME IRQ source
  neorv32_cpu_csr_write(CSR_MIE, 1 << CPU_MIE_MTIE); // activate MTIME IRQ source
  neorv32_cpu_eint(); // enable global interrupts
  neorv32_cpu_eint(); // enable global interrupts
 
 
  if (STATUS_LED_EN == 1) {
 
    // activate status LED, clear all others
 
    neorv32_gpio_port_set(1 << STATUS_LED);
 
  }
 
 
 
  // global variable to executable size; 0 means there is no exe available
  // ------------------------------------------------
  exe_available = 0;
  // Fast boot mode: Direct SPI boot
 
  // Bootloader will directly boot and execute image from SPI memory.
 
  // No user UART console is available in this mode!
 
  // ------------------------------------------------
 
#ifdef SPI_DIRECT_BOOT_EN
 
  #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 ");
 
  print_hex_word((uint32_t)SPI_FLASH_BOOT_ADR);
 
  neorv32_uart_print("\n");
 
 
 
  get_exe(EXE_STREAM_FLASH);
 
  neorv32_uart_print("\n");
 
  start_app();
 
 
 
  return 0;
 
#endif
 
 
 
 
  // ------------------------------------------------
  // ------------------------------------------------
  // Show bootloader intro and system info
  // Show bootloader intro and system info
  // ------------------------------------------------
  // ------------------------------------------------
Line 350... Line 382...
  if (exe_available == 0) {
  if (exe_available == 0) {
    neorv32_uart_print("No executable available.");
    neorv32_uart_print("No executable available.");
    return;
    return;
  }
  }
 
 
  // no need to shut down or reset the used peripherals
  // no need to shut down/reset the used peripherals
  // no need to disable interrupt sources
  // no need to disable interrupt sources
  // -> this will be done by application's crt0
  // -> crt0 will do a clean CPU/processor reset/setup
 
 
  // deactivate global IRQs
  // deactivate global IRQs
  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 ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0);
 
 
  // reset performance counters (to benchmark actual application)
 
  asm volatile ("csrw mcycle,    zero"); // also clears 'cycle'
 
  asm volatile ("csrw mcycleh,   zero"); // also clears 'cycleh'
 
  asm volatile ("csrw minstret,  zero"); // also clears 'instret'
 
  asm volatile ("csrw minstreth, zero"); // also clears 'instreth'
 
 
 
  // 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);
}
}
Line 666... Line 692...
    uint8_t  uint8[sizeof(uint32_t)];
    uint8_t  uint8[sizeof(uint32_t)];
  } data;
  } data;
 
 
  data.uint32 = wdata;
  data.uint32 = wdata;
 
 
  uint32_t 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[3-i]);
  }
  }
}
}
 
 
Line 759... Line 785...
    uint8_t  uint8[sizeof(uint32_t)];
    uint8_t  uint8[sizeof(uint32_t)];
  } address;
  } address;
 
 
  address.uint32 = addr;
  address.uint32 = addr;
 
 
  neorv32_spi_trans(address.uint8[2]);
  int i;
  neorv32_spi_trans(address.uint8[1]);
  for (i=2; i>=0; i--) {
  neorv32_spi_trans(address.uint8[0]);
    neorv32_spi_trans(address.uint8[i]);
 
  }
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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