Skip to content

Commit 4b370ec

Browse files
authored
Add LED Fade Example
An example that uses ULP self-modifying code to create a PWM-like LED dimming effect on GPIO 15.
1 parent f77a321 commit 4b370ec

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

examples/fade_s2.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#
2+
# This file is part of the micropython-esp32-ulp project,
3+
# https://github.com/micropython/micropython-esp32-ulp
4+
#
5+
# SPDX-FileCopyrightText: 2018-2023, the micropython-esp32-ulp authors, see AUTHORS file.
6+
# SPDX-License-Identifier: MIT
7+
8+
"""
9+
Example for: ESP32-S2 Wemos mini development board V1.0.0 with led on pin 15
10+
11+
This example creates a PWM-like dimming effect using self-modifying ULP code.
12+
The ULP program rewrites the `WAIT` instructions to control on/off LED durations,
13+
simulating a variable duty cycle.
14+
15+
Note:
16+
The `WAIT` instruction uses an immediate operand (fixed value) for delay cycles. However, we can change the lower half of memory
17+
to modify these values at runtime, simulating variable wait times via registers.
18+
"""
19+
20+
from esp32 import ULP
21+
from machine import mem32
22+
from esp32_ulp import src_to_binary
23+
from time import sleep
24+
25+
source = """\
26+
# constants from:
27+
# https://github.com/espressif/esp-idf/blob/v5.0.2/components/soc/esp32s2/include/soc/reg_base.h
28+
#define DR_REG_RTCIO_BASE 0x3f408400
29+
30+
# constants from:
31+
# https://github.com/espressif/esp-idf/blob/v5.0.2/components/soc/esp32s2/include/soc/rtc_io_reg.h
32+
#define RTC_IO_XTAL_32P_PAD_REG (DR_REG_RTCIO_BASE + 0xC0)
33+
#define RTC_IO_X32P_MUX_SEL_M (BIT(19))
34+
#define RTC_GPIO_OUT_REG (DR_REG_RTCIO_BASE + 0x0)
35+
#define RTC_GPIO_ENABLE_REG (DR_REG_RTCIO_BASE + 0xc)
36+
#define RTC_GPIO_ENABLE_S 10
37+
#define RTC_GPIO_OUT_DATA_S 10
38+
39+
# constants from:
40+
# https://github.com/espressif/esp-idf/blob/v5.0.2/components/soc/esp32s2/include/soc/rtc_io_channel.h
41+
#define RTCIO_GPIO15_CHANNEL 15
42+
43+
.global entry
44+
program_init:
45+
# connect GPIO to ULP (0: GPIO connected to digital GPIO module, 1: GPIO connected to analog RTC module)
46+
WRITE_RTC_REG(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL_M, 1, 1);
47+
48+
# enable GPIO as output, not input (this also enables a pull-down by default)
49+
WRITE_RTC_REG(RTC_GPIO_ENABLE_REG, RTC_GPIO_ENABLE_S + RTCIO_GPIO15_CHANNEL, 1, 1)
50+
51+
set_waits: add r0, r0, 0xFF # Increase r0 (delay time)
52+
move r3, wait_off
53+
st r0, r3, 0 # Overwrite wait_off with new delay value
54+
55+
move r2, 0xFFFF
56+
sub r1, r2, r0 # Calculate complementary delay time
57+
move r3, wait_on
58+
st r1, r3, 0 # Overwrite wait_on with new value
59+
60+
WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + RTCIO_GPIO15_CHANNEL, 1, 0) # turn off led
61+
wait_off: wait 0 # Placeholder; value overwritten dynamically
62+
WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + RTCIO_GPIO15_CHANNEL, 1, 1) # turn on led
63+
wait_on: wait 0 # Placeholder; value overwritten dynamically
64+
65+
jump set_waits # Loop program
66+
67+
"""
68+
69+
binary = src_to_binary(source, cpu="esp32s2") # cpu is esp32 or esp32s2
70+
71+
load_addr, entry_addr = 0, 0
72+
73+
ULP_MEM_BASE = 0x50000000
74+
75+
ulp = ULP()
76+
ulp.load_binary(load_addr, binary)
77+
78+
ulp.run(entry_addr)
79+
80+
while True:
81+
print(hex(mem32[ULP_MEM_BASE + 40])) # show that the WAIT cycles are changing
82+
sleep(0.5)

0 commit comments

Comments
 (0)