Lab13_RISCV_ICT

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Hanoi University of Science and Technology

School of Information and Communications Technology

Lab 13. Assembly Programming with ESP32-C3 –


Simulation Using Wokwi

Goal
In this lab, students will become familiar with the ESP32-C3 kit, which is based on the
RISC-V architecture. Students will use RISC-V assembly language to program simple
applications that control the input/output ports of the kit and run simulations using the
Wokwi emulator tool.

Materials
• ESP32-C3 Technical Reference Manual

Preparation

Introduction to the ESP32-C3 MCU


ESP32-C3 is a System on Chip (SoC) by Espressif, integrating a microcontroller based
on the open-source RISC-V architecture. It balances performance, peripheral
connectivity, and security, providing an optimal low-cost solution for connected
devices. The 32-bit RISC-V microcontroller operates at a maximum clock speed of 160
MHz. With 22 configurable General-Purpose Input/Output (GPIO) pins, 400 KB RAM,
and support for low-power modes, it can be used in various connected device scenarios.
Electronics manufacturers typically produce
development boards (or kits). These kits, besides the
primary microcontroller module, integrate additional
electronic circuits for ease of use, such as
programming circuits via USB, voltage control
circuits, status LEDs, etc. An example is the ESP32-
C3-DevKitM-1 manufactured by Espressif. Other
manufacturers also produce various versions.

When working with these development boards,


students should consult the datasheet to understand
usage, pin configuration, operation modes, etc.

Simulating the ESP32-C3 Kit Using Wokwi


Wokwi is a web-based application for simulating embedded system development boards
like Arduino, STM32, and ESP32. The platform provides an interface for programmers
to write and test code on simulated embedded systems. It also includes basic electronic
components such as LEDs, 7-segment LEDs, LCD screens, buttons, switches, resistors,
etc., to simulate simple embedded applications.

1
Hanoi University of Science and Technology
School of Information and Communications Technology

User interface of Wokwi

Assembly Programming on ESP32-C3 Using Wokwi


Steps to create and simulate a project on Wokwi:
1. Create a new project using the ESP32-C3 template.
a. Navigate to the Wokwi homepage at https://wokwi.com
b. Select ESP32
c. Select ESP32-C3
2. Rename the default source file if necessary (click the arrow next to the Library
Manager and select Rename). Change the contents of the source file (.ino
extension) to the following:
void setup() {}
void loop() {}

3. Add a new assembly source file (.S extension). Click the arrow next to the
Library Manager, select New file..., and name the file the same as the source
file (.ino extention) but with the .S extension. For example, if the source file is
sketch.ino, the assembly file should be sketch.S.
4. Edit the assembly source file. Use the following skeleton for the program:
# Define the init function for Wokwi to execute the assembly program
.global init

# (Optional) Use the .eqv directive to define constants


.eqv CONST1, 0x0001

# (Optional) Use the .data directive to declare data in memory


.data

# The .text directive marks the start of code


# If there’s no .data, the .text directive is not required
.text
init:
# The assembly program starts here!!!
2
Hanoi University of Science and Technology
School of Information and Communications Technology

5. Add the necessary electronic components, connect their pins to the ESP32-C3 kit
pins as per the schematic.
6. Click Start to compile and run the simulation.

GPIO Control Registers on ESP32-C3


ESP32-C3 has 22 multi-functional GPIO pins. These can be configured as either output
or input. Each pin can also perform other functions (e.g., interfacing with peripherals
using the I2C protocol). ESP32-C3 provides registers for configuring GPIO
functionality, typically done during initialization.

• GPIO_ENABLE_REG (GPIO output enable register), address 0x60004020:


This register allows enabling GPIO output. Bits 0 to 21 correspond to GPIO0 to
GPIO21. A bit value of 1 enables the corresponding GPIO pin as an output pin.
• GPIO_ENABLE_W1TS_REG (GPIO output enable set register), address
0x60004024: This register supports setting bits in the GPIO_ENABLE_REG
register. A bit value of 1 sets the corresponding bit in GPIO_ENABLE_REG,
leaving other bits unchanged.
• GPIO_ENABLE_W1TC_REG (GPIO output enable clear register), address
0x60004028: This register supports clearing bits in the GPIO_ENABLE_REG
register. A bit value of 1 clears the corresponding bit in GPIO_ENABLE_REG,
leaving other bits unchanged.
• GPIO_IN_REG (GPIO input register), address 0x6000403C: This register is
used to read the state of GPIO pins configured as input. Bits 0 to 21 correspond
to GPIO0 to GPIO21. A bit value of 1/0 indicates a high/low logic level on the
corresponding GPIO pin.
• GPIO_OUT_REG (GPIO output register), address 0x60004004: This register
controls the output signal. Bits 0 to 21 correspond to GPIO0 to GPIO21. A bit
value of 1/0 indicates a high/low logic level on the corresponding GPIO pin.
• GPIO_OUT_W1TS_REG (GPIO output set register), address 0x60004008:
This register supports setting bits in the GPIO_OUT_REG register. A bit value
of 1 sets the corresponding bit in GPIO_OUT_REG, leaving other bits
unchanged.
• GPIO_OUT_W1TC_REG (GPIO output clear register), address 0x6000400C:
This register supports clearing bits in the GPIO_OUT_REG register. A bit value
of 1 clears the corresponding bit in GPIO_OUT_REG, leaving other bits
unchanged.
• IO_MUX_GPIOn_REG (n from 0 to 21), address 0x60009004 + 4×n: This
register configures the functionality of the GPIOn pin (from GPIO0 to GPIO21).
The pins of ESP32-C3 can be used as GPIO pins or connected to peripheral
signals. These registers are used to select functions and configure the operation
of GPIO pins.
Notes:
• Use GPIO_ENABLE_W1TS_REG and GPIO_ENABLE_W1TC_REG to
configure the necessary bits for the GPIO_ENABLE_REG register, avoiding
changes to unrelated bits.
3
Hanoi University of Science and Technology
School of Information and Communications Technology

• Use GPIO_OUT_W1TS_REG and GPIO_OUT_W1TC_REG to configure


the necessary bits for the GPIO_OUT_REG register, avoiding changes to
unrelated bits.
• Consult documentation to understand GPIO functions and select the appropriate
configuration.

Home Assignment 1 – Turning the LED On/Off


The following example demonstrates a circuit for
controlling an LED to turn on/off.
The schematic includes an LED with its anode
connected to GPIO0 and its cathode connected in series
with a 220-Ohm resistor to the GND pin.
- When GPIO0 is at logic level 0, the LED is off.
- When GPIO0 is at logic level 0, the LED is off.
Steps:
- Use Wokwi to assemble the circuit as illustrated
in the schematic.
- Implement and test the provided assembly
source code.

Source code:
.global init

.eqv GPIO_ENABLE_REG, 0x60004020 # Register for configuring GPIO input/output


pins
.eqv GPIO_OUT_W1TS_REG, 0x60004008 # Register for configuring GPIO pins'
input/output

init:
li a1, GPIO_ENABLE_REG # Configure GPIO0 as an output pin
li a2, 0x01 # Load mask 0x01 into the GPIO_ENABLE_REG
sw a2, 0(a1)

li a1, GPIO_OUT_W1TS_REG # Set GPIO0 to high, turn on the LED


li a2, 0x01 # Load mask 0x01 into the GPIO_OUT_W1TS_REG
sw a2, 0(a1)

Home Assignment 2 – Blinking LED


The following example demonstrates a circuit for controlling a blinking LED. The
circuit is the same as in Home Assignment 1. To create the blinking effect, the program
alternates between turning the LED on and off, with a delay in between.

Source code:
.global init

.eqv GPIO_ENABLE_REG, 0x60004020


.eqv GPIO_OUT_W1TS_REG, 0x60004008

4
Hanoi University of Science and Technology
School of Information and Communications Technology

.eqv GPIO_OUT_W1TC_REG, 0x6000400C

init:
li a1, GPIO_ENABLE_REG # Configure GPIO0 as an output pin
li a2, 0x01
sw a2, 0(a1)

main_loop:
li a1, GPIO_OUT_W1TS_REG # Set GPIO0 to high
li a2, 0x01
sw a2, 0(a1)
call delay_asm # Delay

li a1, GPIO_OUT_W1TC_REG # Clear GPIO0 to low


li a2, 0x01
sw a2, 0(a1)
call delay_asm # Delay

j main_loop # Loop

# Delay subroutine, wait for a specific period


delay_asm:
li a3, 0 # Counter variable value
li a4, 5000000 # Wait time (number of counts)
loop_delay:
addi a3, a3, 1
blt a3, a4, loop_delay
ret

Home Assignment 3 – Displaying numbers on a 7-segment display


The following example demonstrates displaying the digit 0 on a common-anode 7-
segment display.

Circuit Details:
- Pins a, b, c, d, e, f, g of the 7-segment
display are connected to GPIO0,
GPIO1, GPIO2, GPIO3, GPIO4,
GPIO5, GPIO6, respectively. These
GPIO pins must be configured as
output.

Notes:
- GPIO4, GPIO5, GPIO6, and GPIO7
have default functionality for SPI
communication.
- To use them as GPIO output, you need to reconfigure their function using the
IO_MUX_GPIOn_REG registers (n from 4 to 7).
- The IO_MUX_GPIOn_MCU_SEL field (bit 12 – 14) is used to configure the
function for GPIOn pins. If this field is 1, they are input/output pins.

5
Hanoi University of Science and Technology
School of Information and Communications Technology

For Wokwi simulations, configuring GPIO functions is optional. However, for actual
development boards, function configuration is required.

Source code:
.global init

.eqv GPIO_ENABLE_REG, 0x60004020 # Enable output signals on GPIO pins


.eqv GPIO_OUT_REG, 0x60004004 # Configure the output logic level

.eqv IO_MUX_GPIO4_REG, 0x60009014 # Configure the functionality of GPIO4


.eqv IO_MUX_GPIO5_REG, 0x60009018 # Configure the functionality of GPIO5
.eqv IO_MUX_GPIO6_REG, 0x6000901C # Configure the functionality of GPIO6
.eqv IO_MUX_GPIO7_REG, 0x60009020 # Configure the functionality of GPIO7

.text

init:
li a1, GPIO_ENABLE_REG
li a2, 0xFF # Output signals on GPIO0 to GPIO7 (set 8 bits)
sw a2, 0(a1) # Configure the bits in GPIO_ENABLE_REG

# Configure the functionality of GPIO4, GPIO5, GPIO6, GPIO7


# By default, these pins are used for the SPI protocol
# Function needs to be switched to GPIO

li a2, 0x1000

li a1, IO_MUX_GPIO4_REG
sw a2, 0(a1)

li a1, IO_MUX_GPIO5_REG
sw a2, 0(a1)

6
Hanoi University of Science and Technology
School of Information and Communications Technology

li a1, IO_MUX_GPIO6_REG
sw a2, 0(a1)

li a1, IO_MUX_GPIO7_REG
sw a2, 0(a1)

# a1 contains the address of the register determining the output logic level of
GPIO pins
li a1, GPIO_OUT_REG
li a2, 0xC0
sw a2, 0(a1) # Output signal to GPIO pins

Home Assignment 4 – Reading Button/Switch Input


The following example demonstrates a circuit to
read an input signal on GPIO0 and control an LED
connected to GPIO1.

Circuit Details:
- A button is connected to GPIO0, and an
LED is connected to GPIO1.
- The GPIO_IN_REG register is used to read
the signal input from GPIO pins.
- By default, GPIO pins are configured as
input to receive signals. However, for
GPIOx to receive signals, you must enable input by setting the
IO_MUX_GPIOx_FUN_IE bit in the IO_MUX_GPIOx_REG register
corresponding to GPIOx.

Source code:
.global init

.eqv GPIO_OUT_W1TS_REG, 0x60004008 # Set register


.eqv GPIO_OUT_W1TC_REG, 0x6000400C # Clear register
.eqv GPIO_ENABLE_REG, 0x60004020 # Register to enable output signals
.eqv GPIO_IN_REG, 0x6000403C # Register to read GPIO states
.eqv IO_MUX_GPIO0_REG, 0x60009004 # Register to configure the
functionality of GPIO0

init:
li a1, GPIO_ENABLE_REG # Configure GPIO1 as an output pin
li a2, 0x02
sw a2, 0(a1)

li a1, IO_MUX_GPIO0_REG # Configure GPIO0 to allow input signals


lw a2, 0(a1)
ori a2, a2, 0x200 # Set the IO_MUX_GPIO0_FUN_IE bit
sw a2, 0(a1)

loop:
li a1, GPIO_IN_REG # Read the state of GPIO pins
lw a2, 0(a1)
7
Hanoi University of Science and Technology
School of Information and Communications Technology

andi a3, a2, 0x01 # Check the signal level of GPIO0


beq a3, zero, clear # If GPIO0 = 0 => Turn off the LED
set:
li a1, GPIO_OUT_W1TS_REG # Turn on the LED: Set GPIO1 = 1
li a2, 0x02
sw a2, 0(a1)
j next
clear:
li a1, GPIO_OUT_W1TC_REG # Turn off the LED: Clear GPIO1 = 0
li a2, 0x02
sw a2, 0(a1)
next:
j loop # Loop

Assignment 1
Create a project to implement and test Home Assignment 1. Update the source code to
test with other GPIO pins (GPIO2, GPIO3, GPIO4).

Assignment 2
Create a project to implement and test Home Assignment 2. Update the source code to
test with other GPIO pins (GPIO2, GPIO3, GPIO4) and change the LED blinking time.

Assignment 3
Create a project to implement and test Home Assignment 3. Update the source code to
display different digits (from 0 to 9).

Assignment 4
Create a project to implement and test Home Assignment 4. Update the source code to
use other GPIO pins as signal-receiving pins (GPIO2, GPIO3, GPIO4).

Assignment 5
Create a project to implement a 0 to 9 counter circuit on a 7-segment display.

You might also like