🛠 Configuring GPIOs and Driving Peripherals on Sapphire RV64

Efinix Sapphire RV64 : Configurable 64-bit RISC-V SoC for FPGAs · intermediaire · Apprenez à configurer les broches GPIO du SoC Sapphire RV64 via Efinity pour interagir avec des composants externes comme des LED ou des capteurs.

Objectives

This tutorial aims to understand the I/O architecture of the Efinix Sapphire RV64 SoC. We will configure the GPIO blocks available in the programmable logic to control a digital output (LED) or read an input (button/sensor). The focus is on hardware configuration via Efinity and memory register access from embedded software.

Required Equipment

Steps

  1. SoC Configuration in Efinity: Open your Efinity project. In the Sapphire SoC configuration, enable the GPIO block. You can allocate up to 32 GPIOs. Ensure selected physical pins do not conflict with other interfaces (UART, SPI).
  2. Bitstream Generation: Compile the project to generate the FPGA configuration file. Upload it to the board.
  3. Memory Address Identification: Check the generation report to find the base address of the GPIO block. By default, control and data registers are mapped in the memory space.
  4. Writing C Code: Use pointers to access registers. For example, to turn on an LED on GPIO 0:
#define GPIO_BASE 0x01000000
#define GPIO_DIR 0x00
#define GPIO_OUT 0x04

void main() {
    // Configure GPIO 0 as output (bit 0 to 1)
    *(volatile unsigned int*)(GPIO_BASE + GPIO_DIR) |= (1 << 0);
    // Set GPIO 0 to high state
    *(volatile unsigned int*)(GPIO_BASE + GPIO_OUT) |= (1 << 0);
    while(1);
}
  1. Compilation and Transfer: Compile the code with the RISC-V toolchain adapted for the VexiiRiscv core. Load the binary via JTAG or UART.

Verification

Observe the LED lighting up after program execution. If using a button, configure the GPIO as input and read the input register to detect state changes. Use the RISC-V debugger to check register values in real-time.

Further Reading

Explore External Peripheral Interrupts (EPI) to react to GPIO state changes without polling. Integrate an I2C sensor to diversify I/O inputs.

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials