Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sw/bootloader] add TWI boot option #1108

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ for **custom RISC-V instructions**;
caches ([iCACHE](https://stnolting.github.io/neorv32/#_processor_internal_instruction_cache_icache) and
[dCACHE](https://stnolting.github.io/neorv32/#_processor_internal_data_cache_dcache))
* pre-installed bootloader ([BOOTLDROM](https://stnolting.github.io/neorv32/#_bootloader_rom_bootrom)) with serial user interface;
allows booting application code via UART or from external SPI flash
allows booting application code via UART, TWI or from external SPI flash

**Timers and Counters**

Expand Down
18 changes: 17 additions & 1 deletion docs/datasheet/software_bootloader.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The bootloader requires certain CPU and SoC extensions and modules to be enabled
| _RECOMMENDED_ | The machine timer of the <<_core_local_interruptor_clint>> is used to control blinking of the status LED and also to automatically trigger the <<_auto_boot_sequence>>.
| OPTIONAL | The SPI controller (<<_serial_peripheral_interface_controller_spi>>) is needed to store/load executable from external flash using the <<_auto_boot_sequence>>.
| OPTIONAL | The XIP controller (<<_execute_in_place_module_xip>>) is needed to boot/execute code directly from a pre-programmed SPI flash.
| OPTIONAL | The TWI controller (<<_two_wire_serial_interface_controller_twi>>) is needed to boot/execute code directly from pre-programmed TWI memory.
|=======================


Expand All @@ -70,6 +71,17 @@ Most properties (like chip select line, flash address width, SPI clock frequency
without the need to change the source code. Custom configuration can be made using command line switches (defines) when recompiling
the bootloader. See the User Guide https://stnolting.github.io/neorv32/ug/#_customizing_the_internal_bootloader for more information.

:sectnums:
==== Bootloader TWI memory Requirements

The bootloader can access an TWI-compatible memory via the processor's top entity TWI port. Single- and dual address memory is supported, and reading is done in the following pattern
`Slave Address + Enabled Read | Memory Address Byte 0 | Memory Address 1 (optional) | Read Byte 0 | Read Byte 1 | Read Byte 2 | Read Byte 3`.
The addresses are incremented until the end of the program binary is reached.

A python upload script for uploading is provided in the `sw/eeprom_upload` folder. Currently only for the https://www.robot-electronics.co.uk/htm/usb_iss_tech.htm[USB-ISS] module.


Clock speed information can be read here: <<_two_wire_serial_interface_controller_twi>>.

:sectnums:
==== Bootloader Console
Expand Down Expand Up @@ -154,6 +166,7 @@ Available CMDs:
u: Upload
s: Store to flash
l: Load from flash
t: Load from TWI Slave
x: Boot from flash (XIP)
e: Execute
CMD:>
Expand All @@ -167,6 +180,7 @@ The auto boot countdown is stopped and the bootloader's user console is ready to
* `u`: Upload new program executable (`neorv32_exe.bin`) via UART into the instruction memory
* `s`: Store executable to SPI flash at `spi_csn_o(0)` (little-endian byte order)
* `l`: Load executable from SPI flash at `spi_csn_o(0)` (little-endian byte order)
* `t`: Load executable from TWI memory at `0x50` (little-endian byte order) (disabled by default)
* `x`: Boot program directly from flash via XIP (requires a pre-programmed image)
* `e`: Start the application, which is currently stored in the instruction memory (IMEM)

Expand Down Expand Up @@ -206,7 +220,8 @@ https://stnolting.github.io/neorv32/ug/#_programming_an_external_spi_flash_via_t

When you reset the NEORV32 processor, the bootloader waits 8 seconds for a UART console input before it
starts the automatic boot sequence. This sequence tries to fetch a valid boot image from the external SPI
flash, connected to SPI chip select `spi_csn_o(0)`. If a valid boot image is found that can be successfully
flash, connected to SPI chip select `spi_csn_o(0)` or from external TWI memory. If both are enabled, the bootloader
will select SPI. If a valid boot image is found that can be successfully
transferred into the instruction memory, it is automatically started. If no SPI flash is detected or if there
is no valid boot image found, and error code will be shown.

Expand All @@ -228,6 +243,7 @@ In many cases the error source is just _temporary_ (like some HF spike during an
| **`ERR_CHKS`** | This indicates a checksum error. Something went wrong during the transfer of the program image (upload via UART or loading from the external SPI flash). If the error was caused by a UART upload, just try it again. When the error was generated during a flash access, the stored image might be corrupted.
| **`ERR_FLSH`** | This error occurs if the attached SPI flash cannot be accessed. Make sure you have the right type of flash and that it is properly connected to the NEORV32 SPI port using chip select #0.
| **`ERR_EXC`** | The bootloader encountered an unexpected exception during operation. This might be caused when it tries to access peripherals that were not implemented during synthesis. Example: executing commands `l` or `s` (SPI flash operations) without the SPI module being implemented.
| **`ERR_TWI`** | The TWI received an unexpected NACK while reading the external memory. Are the address and speed settings correct?
|=======================

[TIP]
Expand Down
11 changes: 10 additions & 1 deletion docs/userguide/customizing_the_bootloader.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,23 @@ minimal base & privileged ISA `rv32e_zicsr_zifencei` only to ensure it can work
| `SPI_BOOT_BASE_ADDR` | `0x00400000` | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
4+^| XIP configuration
| `XIP_EN` | `0` | `0`, `1` | Set `1` to enable the XIP options
4+^| TWI configuration
| `TWI_EN` | `0` | `0`, `1` | Set `1` to enable the usage of the SPI module (including load/store executables from/to SPI flash options)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description should be "Set 1 to enable the usage of the TWI module (including loade executables from TWI flash option)" I think.

| `TWI_CLK_PRSC` | `CLK_PRSC_64` | `CLK_PRSC_2` `CLK_PRSC_4` `CLK_PRSC_8` `CLK_PRSC_64` `CLK_PRSC_128` `CLK_PRSC_1024` `CLK_PRSC_2024` `CLK_PRSC_4096` | TWI clock pre-scaler (dividing main processor clock)
| `TWI_CLK_DIV` | `3` | `0` ... `15` | TWI clock divider (dividing twi clock)
| `TWI_SLAVE_ID` | `0x50` | `0x00` ... `0x7F` | First TWI slave ID to start. Is incremented until the end of the program is reached, when `TWI_ADDR_BYTES` is `1`.
| `TWI_ADDR_BYTES` | `1` | `1`, `2` | TWI memory address size in number of bytes. When `TWI_ADDR_BYTES` is `1`, `TWI_SLAVE_ID` the gets incremented as well.
|=======================

[IMPORTANT]
Enabling all features while sticking to the minimal RISC-V ISA will result in a too-large binary!

[NOTE]
The XIP options re-use the "SPI configuration" options for configuring the XIP's SPI connection.

Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
(using `+=`) to the makefile `USER_FLAGS` variable. Make sure to use the `-D` prefix here.
(using `+=`) to the makefile `USER_FLAGS` variable. Make sure to use the `-D` prefix here. The configuration is also listed in the makefile of the bootloader.

For example, to configure a UART Baud rate of 57600 and redirecting the status LED to GPIO output pin 20
use the following command:
Expand Down
3 changes: 3 additions & 0 deletions docs/userguide/executable_upload.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ See section https://stnolting.github.io/neorv32/#_bootloader[Bootloader] of the
See section <<_programming_an_external_spi_flash_via_the_bootloader>> to learn how to use an external SPI
flash for nonvolatile program storage.
[TIP]
The bootloader also supports booting from external TWI memory. Enable it in the bootloader makefile, but be caution, enabling all features might result in a too-big binary.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "but be careful"

[TIP]
Executables can also be uploaded via the **on-chip debugger**.
See section <<_debugging_with_gdb>> for more information.
Loading
Loading