Assembly examples for Red-V Thing Plus (SiFive FE310-G002)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flabbergast f8018cf163 Add top-of-file comments. 8 months ago
01-blink Add top-of-file comments. 8 months ago
02-chase Add top-of-file comments. 8 months ago
03-clock Add top-of-file comments. 8 months ago
04-uart Add top-of-file comments. 8 months ago
05-write Add top-of-file comments. 8 months ago
06-irq-delay Add top-of-file comments. 8 months ago
07-uart0irq Add top-of-file comments. 8 months ago
bootloader Shave 2 bytes from bootloader. 8 months ago
.gitignore Add bootloader.hex and gitignore. 8 months ago
02-chase.gif Add 03-clock. 9 months ago Add bootloader. 8 months ago
memmap Add top-of-file comments. 8 months ago Add top-of-file comments. 8 months ago

A bit of assembly on RED-V Thing Plus

This repo contains a progression of example programs written in RISC-V assembly, to run on Sparkfun's RED-V Thing Plus. It's a result of my attempt to learn a bit of RISC-V assembly.



You'll need a compiler capable of compiling for (bare metal) rv32imac architecture. There are precompiled toolchains available from SiFive. The Makefiles are set to use riscv32-elf-as by default, but riscv64-unknown-elf-as and variations should be also fine (you'll need to adjust PREFIX in the Makefiles).

Another piece of software that you may want to use is JLinkExe from Segger, for flashing via make flash. You'll also need to adjust the JLINKEXE path in the Makefiles. This is avoidable; you can also just copy the resulting .hex file(s) onto the virtual "drive" that the onboard JLink emulates for the PC; JLink will then automatically flash it.


The examples are in the numbered subdirectories; they get progressively more complicated. Most of the code is carried over from the earlier to the later ones.

Two files in the main directory are reused (via symlinks) in all the examples: memmap (which tell the linker addresses for flash and RAM), and which have definitions for some of the MCU memory-mapped registers, from the manual.

The filenames in the examples follow the convention that main.s is the main file, which includes various other .s files. The p_*.s contain the MCU-specific code.


Commentary about the board

The RED-V Thing board carries SiFive's FE310-G002 RV32IMAC microcontroller (with supporting crystals and flash), as well as a JLink debugger (actually licensed from Segger). This is very nice - no external hardware needed for flashing, and debugging via JTAG, and a convenient access to UART0. (Most conveniently used using the non-open-source JLink software; but openocd also works.) The board is roughly compatible with SiFive's Hifive1 RevB board, to the point that Hifive1B firmware runs fine on the RED-V, except the RED-V is missing the LEDs and the (imo pointless) ESP32 wifi.

Commentary about the MCU

To do anything with the onboard FE310-G002, one will need FE310 datasheet and most importantly FE310 manual. These are refreshingly short and to the point. They sort of reinforce that FE310-G002 isn't really meant (I guess) to be used in real-world embedded applications: only the basic peripherals (exactly those that I use the most), with just the basic features. On the other hand, this makes it superb to play around with - they are really dead simple and straightforward; one doesn't have to read through hundreds of pages of descriptions of tens of registers that allow (somewhat) obscure features. Just a RISC-V core with basic UART, SPI, I2C, PWM, timer, interrupts. These are designed quite well to go with a RISC-V core: tricks like error flags in bit31 for easy sign tests, etc. There seems to be also a reasonably good attempt at a "sleep" solution (Always-On domain), but I am not that sure about the low power requirements - there are a bunch of extra parts (crystals, flash) that would need to be taken care of in sleep.

Anyway, the MCU is a good demonstration that SiFive digital designers know what they're doing.


On reset, FE310-G002 jumps to 0x20000000 (usually, this is to some extent configurable), which is mapped to the beginning of the onboard flash. From factory, this contains SiFive's bootloader (which they didn't release sources for). In any case, the RED-V board uses the exact same bootloader as the HiFive1B board. Its function is to

a) guard against the scenario when the MCU makes itself inaccessible to JTAG (e.g. sleep without wake sources) - this is done by blinking a LED after 1 second, if RESET is pressed again just after that, then the bootloader does not jump to user code, but just stalls. This allows the JLink to connect to the chip and so reprogram the flash.

b) initialise the ESP32 on the HiFive1B board.

It emits some text over UART (115200 baud); e.g. the result of b).

Now on RED-V: For a), the LED that's blinked on HiFive1B does not exist on RED-V, so that's not visible; but otherwise the mechanism works. For b), there is no ESP32, so it just errors out.

The user code (where the bootloader jumps if it's happy) is at 0x20010000. Most of the sample code that's around (e.g. riscv-rust-quickstart or platformio) does have this set up automatically.

Someone disassebled the original bootloader and also rewrote it into C here. It turns out that it does a few other things, so that more of the MCU peripherals are not in their reset states:

  • it seems to use PMU/sleep mechanism on power-up-reset to reset(?) the ESP32, so it clobbers the PMUSLEEPn registers and triggers sleep once. It uses another "magic value" in AON_BACKUP15 do that it isn't done on subsequent boots - but if the user application uses AON_BACKUP15 for something else, it will happen again.
  • it sets up UART, switches the clock to external crystal (!), and does a "bench clock reset", which seems to only do some computation with numbers of cycles?
  • leaves the SPI peripheral and SPI pins enabled - makes sense on HiFive1b board, but the LED on the RED-V Thing uses one of those pins...

Anyway, I wrote a simple alternative one which just does a) above. It's in the bootloader directory.