NEORV32 - Software Framework Documentation
Macros | Enumerations | Functions | Variables
bootloader.c File Reference

Default NEORV32 bootloader. More...

#include <stdint.h>
#include <neorv32.h>

Macros

#define EXE_SIGNATURE   0x4788CAFE
 
Bootloader configuration (override via console to customize)

default values are used if not explicitly customized

#define UART_EN   1
 
#define UART_BAUD   19200
 
#define STATUS_LED_EN   1
 
#define STATUS_LED_PIN   0
 
#define AUTO_BOOT_SPI_EN   0
 
#define AUTO_BOOT_OCD_EN   0
 
#define AUTO_BOOT_SIMPLE_UART_EN   0
 
#define AUTO_BOOT_TIMEOUT   8
 
#define SPI_EN   1
 
#define SPI_FLASH_CS   0
 
#define SPI_FLASH_ADDR_BYTES   3
 
#define SPI_FLASH_SECTOR_SIZE   65536
 
#define SPI_FLASH_CLK_PRSC   CLK_PRSC_8
 
#define SPI_BOOT_BASE_ADDR   0x08000000
 
#define xstr(a)   str(a)
 
#define str(a)   #a
 
#define PRINT_TEXT(...)   neorv32_uart0_print(__VA_ARGS__)
 
#define PRINT_XNUM(a)   print_hex_word(a)
 
#define PRINT_GETC(a)   neorv32_uart0_getc()
 
#define PRINT_PUTC(a)   neorv32_uart0_putc(a)
 

Enumerations

enum  EXE_STREAM_SOURCE { EXE_STREAM_UART = 0 , EXE_STREAM_FLASH = 1 }
 
enum  ERROR_CODES { ERROR_SIGNATURE = 0 , ERROR_SIZE = 1 , ERROR_CHECKSUM = 2 , ERROR_FLASH = 3 }
 
enum  SPI_FLASH_CMD {
  SPI_FLASH_CMD_PAGE_PROGRAM = 0x02 , SPI_FLASH_CMD_READ = 0x03 , SPI_FLASH_CMD_WRITE_DISABLE = 0x04 , SPI_FLASH_CMD_READ_STATUS = 0x05 ,
  SPI_FLASH_CMD_WRITE_ENABLE = 0x06 , SPI_FLASH_CMD_SECTOR_ERASE = 0xD8
}
 
enum  SPI_FLASH_SREG { FLASH_SREG_BUSY = 0 , FLASH_SREG_WEL = 1 }
 
enum  NEORV32_EXECUTABLE { EXE_OFFSET_SIGNATURE = 0 , EXE_OFFSET_SIZE = 4 , EXE_OFFSET_CHECKSUM = 8 , EXE_OFFSET_DATA = 12 }
 

Functions

void bootloader_trap_handler (void)
 
void print_help (void)
 
void start_app (void)
 
void get_exe (int src)
 
void save_exe (void)
 
uint32_t get_exe_word (int src, uint32_t addr)
 
void system_error (uint8_t err_code)
 
void print_hex_word (uint32_t num)
 
int spi_flash_check (void)
 
uint8_t spi_flash_read_byte (uint32_t addr)
 
void spi_flash_write_byte (uint32_t addr, uint8_t wdata)
 
void spi_flash_write_word (uint32_t addr, uint32_t wdata)
 
void spi_flash_erase_sector (uint32_t addr)
 
void spi_flash_write_enable (void)
 
void spi_flash_write_disable (void)
 
uint32_t spi_flash_read_status (void)
 
void spi_flash_write_addr (uint32_t addr)
 
int main (void)
 

Variables

const char error_message [4][24]
 
volatile uint32_t exe_available
 
volatile uint32_t getting_exe
 

Detailed Description

Default NEORV32 bootloader.

Author
Stephan Nolting

Macro Definition Documentation

◆ AUTO_BOOT_OCD_EN

#define AUTO_BOOT_OCD_EN   0

Set to 1 to enable boot only via on-chip debugger (keep CPU in halt loop until OCD takes over control)

◆ AUTO_BOOT_SIMPLE_UART_EN

#define AUTO_BOOT_SIMPLE_UART_EN   0

Set to 1 to enable simple UART executable upload (no console, no SPI flash)

◆ AUTO_BOOT_SPI_EN

#define AUTO_BOOT_SPI_EN   0

Set to 1 to enable automatic (after reset) only boot from external SPI flash at address SPI_BOOT_BASE_ADDR

◆ AUTO_BOOT_TIMEOUT

#define AUTO_BOOT_TIMEOUT   8

Time until the auto-boot sequence starts (in seconds); 0 = disabled

◆ EXE_SIGNATURE

#define EXE_SIGNATURE   0x4788CAFE

Valid executable identification signature

◆ PRINT_GETC

#define PRINT_GETC (   a)    neorv32_uart0_getc()

Helper macros Actual define-to-string helper

◆ PRINT_PUTC

#define PRINT_PUTC (   a)    neorv32_uart0_putc(a)

Helper macros Actual define-to-string helper

◆ PRINT_TEXT

#define PRINT_TEXT (   ...)    neorv32_uart0_print(__VA_ARGS__)

Print to UART 0

◆ PRINT_XNUM

#define PRINT_XNUM (   a)    print_hex_word(a)

Helper macros Actual define-to-string helper

◆ SPI_BOOT_BASE_ADDR

#define SPI_BOOT_BASE_ADDR   0x08000000

SPI flash boot base address

◆ SPI_EN

#define SPI_EN   1

Enable SPI module (default) including SPI flash boot options

◆ SPI_FLASH_ADDR_BYTES

#define SPI_FLASH_ADDR_BYTES   3

SPI flash address width (in numbers of bytes; 2,3,4)

◆ SPI_FLASH_CLK_PRSC

#define SPI_FLASH_CLK_PRSC   CLK_PRSC_8

SPI flash clock pre-scaler; see NEORV32_SPI_CTRL_enum

◆ SPI_FLASH_CS

#define SPI_FLASH_CS   0

SPI flash chip select (low-active) at SPI.spi_csn_o(SPI_FLASH_CS)

◆ SPI_FLASH_SECTOR_SIZE

#define SPI_FLASH_SECTOR_SIZE   65536

SPI flash sector size in bytes

◆ STATUS_LED_EN

#define STATUS_LED_EN   1

Set to 0 to disable bootloader status LED (heart beat) at GPIO.gpio_o(STATUS_LED_PIN)

◆ STATUS_LED_PIN

#define STATUS_LED_PIN   0

GPIO output pin for high-active bootloader status LED (heart beat)

◆ str

#define str (   a)    #a

Internal helper macro

◆ UART_BAUD

#define UART_BAUD   19200

UART BAUD rate for serial interface

◆ UART_EN

#define UART_EN   1

Set to 0 to disable UART interface

◆ xstr

#define xstr (   a)    str(a)

Helper macros Actual define-to-string helper

Enumeration Type Documentation

◆ ERROR_CODES

Error codes

Enumerator
ERROR_SIGNATURE 

0: Wrong signature in executable

ERROR_SIZE 

1: Insufficient instruction memory capacity

ERROR_CHECKSUM 

2: Checksum error in executable

ERROR_FLASH 

3: SPI flash access error

◆ EXE_STREAM_SOURCE

Executable stream source select

Enumerator
EXE_STREAM_UART 

Get executable via UART

EXE_STREAM_FLASH 

Get executable via SPI flash

◆ NEORV32_EXECUTABLE

NEORV32 executable

Enumerator
EXE_OFFSET_SIGNATURE 

Offset in bytes from start to signature (32-bit)

EXE_OFFSET_SIZE 

Offset in bytes from start to size (32-bit)

EXE_OFFSET_CHECKSUM 

Offset in bytes from start to checksum (32-bit)

EXE_OFFSET_DATA 

Offset in bytes from start to data (32-bit)

◆ SPI_FLASH_CMD

SPI flash commands

Enumerator
SPI_FLASH_CMD_PAGE_PROGRAM 

Program page

SPI_FLASH_CMD_READ 

Read data

SPI_FLASH_CMD_WRITE_DISABLE 

Disallow write access

SPI_FLASH_CMD_READ_STATUS 

Get status register

SPI_FLASH_CMD_WRITE_ENABLE 

Allow write access

SPI_FLASH_CMD_SECTOR_ERASE 

Erase complete sector

◆ SPI_FLASH_SREG

SPI flash status register bits

Enumerator
FLASH_SREG_BUSY 

Busy, write/erase in progress when set, read-only

FLASH_SREG_WEL 

Write access enabled when set, read-only

Function Documentation

◆ bootloader_trap_handler()

void bootloader_trap_handler ( void  )

Bootloader trap handler. Used for the MTIME tick and to capture any other traps.

Warning
Adapt exception PC only for sync exceptions!
Note
Since we have no runtime environment, we have to use the interrupt attribute here. Here and only here!

◆ get_exe()

void get_exe ( int  src)

Get executable stream.

Parameters
srcSource of executable stream data. See EXE_STREAM_SOURCE.

◆ get_exe_word()

uint32_t get_exe_word ( int  src,
uint32_t  addr 
)

Get word from executable stream

Parameters
srcSource of executable stream data. See EXE_STREAM_SOURCE.
addrAddress when accessing SPI flash.
Returns
32-bit data word from stream.

◆ main()

int main ( void  )

Sanity check: Base ISA only! Bootloader main.

◆ print_help()

void print_help ( void  )

Print help menu.

◆ print_hex_word()

void print_hex_word ( uint32_t  num)

Print 32-bit number as 8-digit hexadecimal value (with "0x" suffix).

Parameters
[in]numNumber to print as hexadecimal.

◆ save_exe()

void save_exe ( void  )

Store content of instruction memory to SPI flash.

◆ spi_flash_check()

int spi_flash_check ( void  )

Check if SPI and flash are available/working by making sure the WEL flag of the flash status register can be set and cleared again.

Returns
0 if success, -1 if error

◆ spi_flash_erase_sector()

void spi_flash_erase_sector ( uint32_t  addr)

Erase sector (64kB) at base address.

Parameters
[in]addrBase address of sector to erase.

◆ spi_flash_read_byte()

uint8_t spi_flash_read_byte ( uint32_t  addr)

Read byte from SPI flash.

Parameters
[in]addrFlash read address.
Returns
Read byte from SPI flash.

◆ spi_flash_read_status()

uint32_t spi_flash_read_status ( void  )

Read flash status register.

Returns
SPI flash status register (32-bit zero-extended).

◆ spi_flash_write_addr()

void spi_flash_write_addr ( uint32_t  addr)

Send address word to flash (16-bit, 24-bit or 32-bit address size).

Parameters
[in]addrAddress word.

◆ spi_flash_write_byte()

void spi_flash_write_byte ( uint32_t  addr,
uint8_t  wdata 
)

Write byte to SPI flash.

Parameters
[in]addrSPI flash read address.
[in]wdataSPI flash read data.

◆ spi_flash_write_disable()

void spi_flash_write_disable ( void  )

Disable flash write access.

◆ spi_flash_write_enable()

void spi_flash_write_enable ( void  )

Enable flash write access.

◆ spi_flash_write_word()

void spi_flash_write_word ( uint32_t  addr,
uint32_t  wdata 
)

Write word to SPI flash.

Parameters
addrSPI flash write address.
wdataSPI flash write data.

◆ start_app()

void start_app ( void  )

Start application program at the beginning of instruction space.

◆ system_error()

void system_error ( uint8_t  err_code)

Output system error ID and stall.

Parameters
[in]err_codeError code. See ERROR_CODES and error_message.

Variable Documentation

◆ error_message

const char error_message[4][24]
Initial value:
= {
"exe signature error",
"exceeding IMEM capacity",
"checksum error",
"SPI flash access error"
}

Error messages

◆ exe_available

volatile uint32_t exe_available

This global variable keeps the size of the available executable in bytes. If =0 no executable is available (yet).

◆ getting_exe

volatile uint32_t getting_exe

Only set during executable fetch (required for capturing STORE BUS-TIMOUT exception).