Skip to content

Commit 7eb2a80

Browse files
Merge pull request #73 from wnienhaus/readgpio_example
add example: reading a GPIO input with the ULP coprocessor
2 parents 97ad8e0 + d53326d commit 7eb2a80

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

examples/readgpio.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
Very basic example showing how to read a GPIO pin from the ULP and access
3+
that data from the main CPU.
4+
5+
In this case GPIO4 is being read. Note that the ULP needs to refer to GPIOs
6+
via their RTC channel number. You can see the mapping in this file:
7+
https://github.com/espressif/esp-idf/blob/v4.4.1/components/soc/esp32/include/soc/rtc_io_channel.h#L51
8+
9+
If you change to a different GPIO number, make sure to modify both the channel
10+
number and also the RTC_IO_TOUCH_PAD0_* references appropriately. The best place
11+
to see the mappings might be this table here (notice the "real GPIO numbers" as
12+
comments to each line):
13+
https://github.com/espressif/esp-idf/blob/v4.4.1/components/soc/esp32/rtc_io_periph.c#L61
14+
15+
The timer is set to a rather long period, so you can watch the data value
16+
change as you change the GPIO input (see loop at the end).
17+
"""
18+
19+
from esp32 import ULP
20+
from machine import mem32
21+
22+
from esp32_ulp import src_to_binary
23+
24+
source = """\
25+
#define DR_REG_RTCIO_BASE 0x3ff48400
26+
#define RTC_IO_TOUCH_PAD0_REG (DR_REG_RTCIO_BASE + 0x94)
27+
#define RTC_IO_TOUCH_PAD0_MUX_SEL_M (BIT(19))
28+
#define RTC_IO_TOUCH_PAD0_FUN_IE_M (BIT(13))
29+
#define RTC_GPIO_IN_REG (DR_REG_RTCIO_BASE + 0x24)
30+
#define RTC_GPIO_IN_NEXT_S 14
31+
.set channel, 10 # 10 is the channel no. of gpio4
32+
33+
state: .long 0
34+
35+
entry:
36+
# connect GPIO to the RTC subsystem so the ULP can read it
37+
WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, 1, 1)
38+
39+
# switch the GPIO into input mode
40+
WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_FUN_IE_M, 1, 1)
41+
42+
# read the GPIO's current state into r0
43+
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + channel, 1)
44+
45+
# set r3 to the memory address of "state"
46+
move r3, state
47+
48+
# store what was read into r0 into the "state" variable
49+
st r0, r3, 0
50+
51+
# halt ULP co-processor (until it gets woken up again)
52+
halt
53+
"""
54+
55+
binary = src_to_binary(source)
56+
57+
load_addr, entry_addr = 0, 4
58+
59+
ULP_MEM_BASE = 0x50000000
60+
ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits
61+
62+
ulp = ULP()
63+
ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles
64+
ulp.load_binary(load_addr, binary)
65+
66+
mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialise state to 0
67+
ulp.run(entry_addr)
68+
69+
while True:
70+
print(hex(mem32[ULP_MEM_BASE + load_addr] & ULP_DATA_MASK))
71+

0 commit comments

Comments
 (0)