Line 111... |
Line 111... |
/** SPI flash sector size in bytes */
|
/** SPI flash sector size in bytes */
|
#ifndef SPI_FLASH_SECTOR_SIZE
|
#ifndef SPI_FLASH_SECTOR_SIZE
|
#define SPI_FLASH_SECTOR_SIZE 65536 // default = 64kB
|
#define SPI_FLASH_SECTOR_SIZE 65536 // default = 64kB
|
#endif
|
#endif
|
|
|
/** SPI flash clock pre-scaler; see #NEORV32_TWI_CT_enum */
|
/** SPI flash clock pre-scaler; see #NEORV32_SPI_CTRL_enum */
|
#ifndef SPI_FLASH_CLK_PRSC
|
#ifndef SPI_FLASH_CLK_PRSC
|
#define SPI_FLASH_CLK_PRSC CLK_PRSC_8
|
#define SPI_FLASH_CLK_PRSC CLK_PRSC_8
|
#endif
|
#endif
|
|
|
/** SPI flash boot base address */
|
/** SPI flash boot base address */
|
Line 331... |
Line 331... |
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 for ~2Hz
|
if (neorv32_mtime_available()) {
|
if (neorv32_mtime_available()) {
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (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 345... |
Line 345... |
// ------------------------------------------------
|
// ------------------------------------------------
|
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(SYSINFO_CLK);
|
PRINT_XNUM(NEORV32_SYSINFO.CLK);
|
PRINT_TEXT("\nMISA: ");
|
PRINT_TEXT("\nMISA: ");
|
PRINT_XNUM(neorv32_cpu_csr_read(CSR_MISA));
|
PRINT_XNUM(neorv32_cpu_csr_read(CSR_MISA));
|
PRINT_TEXT("\nZEXT: ");
|
PRINT_TEXT("\nCPU: ");
|
PRINT_XNUM(SYSINFO_CPU);
|
PRINT_XNUM(NEORV32_SYSINFO.CPU);
|
PRINT_TEXT("\nPROC: ");
|
PRINT_TEXT("\nSOC: ");
|
PRINT_XNUM(SYSINFO_FEATURES);
|
PRINT_XNUM(NEORV32_SYSINFO.SOC);
|
PRINT_TEXT("\nIMEM: ");
|
PRINT_TEXT("\nIMEM: ");
|
PRINT_XNUM(SYSINFO_IMEM_SIZE);
|
PRINT_XNUM(NEORV32_SYSINFO.IMEM_SIZE);
|
PRINT_TEXT(" bytes @");
|
PRINT_TEXT(" bytes @");
|
PRINT_XNUM(SYSINFO_ISPACE_BASE);
|
PRINT_XNUM(NEORV32_SYSINFO.ISPACE_BASE);
|
PRINT_TEXT("\nDMEM: ");
|
PRINT_TEXT("\nDMEM: ");
|
PRINT_XNUM(SYSINFO_DMEM_SIZE);
|
PRINT_XNUM(NEORV32_SYSINFO.DMEM_SIZE);
|
PRINT_TEXT(" bytes @");
|
PRINT_TEXT(" bytes @");
|
PRINT_XNUM(SYSINFO_DSPACE_BASE);
|
PRINT_XNUM(NEORV32_SYSINFO.DSPACE_BASE);
|
|
|
|
|
// ------------------------------------------------
|
// ------------------------------------------------
|
// Auto boot sequence
|
// Auto boot sequence
|
// ------------------------------------------------
|
// ------------------------------------------------
|
#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 key to abort.\n");
|
uint64_t timeout_time = neorv32_mtime_get_time() + (uint64_t)(AUTO_BOOT_TIMEOUT * 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()) {
|
Line 475... |
Line 475... |
|
|
// wait for UART to finish transmitting
|
// wait for UART to finish transmitting
|
while (neorv32_uart0_tx_busy());
|
while (neorv32_uart0_tx_busy());
|
|
|
// 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 = NEORV32_SYSINFO.ISPACE_BASE;
|
asm volatile ("jalr zero, %0" : : "r" (app_base));
|
asm volatile ("jalr zero, %0" : : "r" (app_base));
|
while (1);
|
while (1);
|
}
|
}
|
|
|
|
|
Line 501... |
Line 501... |
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_mtime_get_time() + (SYSINFO_CLK/4));
|
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (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 568... |
Line 568... |
// image size and checksum
|
// image size and checksum
|
uint32_t size = get_exe_word(src, addr + EXE_OFFSET_SIZE); // size in bytes
|
uint32_t size = get_exe_word(src, addr + EXE_OFFSET_SIZE); // size in bytes
|
uint32_t check = get_exe_word(src, addr + EXE_OFFSET_CHECKSUM); // complement sum checksum
|
uint32_t check = get_exe_word(src, addr + EXE_OFFSET_CHECKSUM); // complement sum checksum
|
|
|
// transfer program data
|
// transfer program data
|
uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE;
|
uint32_t *pnt = (uint32_t*)NEORV32_SYSINFO.ISPACE_BASE;
|
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
uint32_t d = 0, i = 0;
|
uint32_t d = 0, i = 0;
|
addr = addr + EXE_OFFSET_DATA;
|
addr = addr + EXE_OFFSET_DATA;
|
while (i < (size/4)) { // in words
|
while (i < (size/4)) { // in words
|
d = get_exe_word(src, addr);
|
d = get_exe_word(src, addr);
|
Line 644... |
Line 644... |
// write size
|
// write size
|
spi_flash_write_word(addr + EXE_OFFSET_SIZE, size);
|
spi_flash_write_word(addr + EXE_OFFSET_SIZE, size);
|
|
|
// store data from instruction memory and update checksum
|
// store data from instruction memory and update checksum
|
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE;
|
uint32_t *pnt = (uint32_t*)NEORV32_SYSINFO.ISPACE_BASE;
|
addr = addr + EXE_OFFSET_DATA;
|
addr = addr + EXE_OFFSET_DATA;
|
uint32_t i = 0;
|
uint32_t i = 0;
|
while (i < (size/4)) { // in words
|
while (i < (size/4)) { // in words
|
uint32_t d = (uint32_t)*pnt++;
|
uint32_t d = (uint32_t)*pnt++;
|
checksum += d;
|
checksum += d;
|