Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit25bf34e

Browse files
authored
Merge pull request#91 from wnienhaus/s2s3_support
ESP32-S2/S3 support
2 parents5c4d016 +debff30 commit25bf34e

File tree

44 files changed

+3414
-344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3414
-344
lines changed

‎.gitignore‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
tests/compat/*.bin
2-
tests/compat/*.elf
3-
tests/compat/*.o
4-
tests/compat/*.ulp
5-
tests/compat/*.log
1+
tests/binutils-gdb
2+
tests/esp-idf
3+
tests/ulptool
4+
tests/**/*.bin
5+
tests/**/*.elf
6+
tests/**/*.o
7+
tests/**/*.ulp
8+
tests/**/*.log
9+
tests/**/*.pre
10+
tests/log
11+
tests/*.lst
12+
tests/*.log
13+
tests/defines*.db
614
demo.ulp
715
*.pyc
816
*.pyo

‎README.rst‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ micropython-esp32-ulp is an assembler toolchain for the ESP32 ULP (Ultra Low-Pow
1515
Co-Processor, written in MicroPython.
1616

1717
It can translate small assembly language programs to a loadable/executable
18-
ULPmachine code binary, directly onthe ESP32 microcontroller.
18+
ULP-FSM (not RISC-V)machine code binary, directly ona ESP32 microcontroller.
1919

2020
This is intended as an alternative approach to assembling such programs using
2121
the `binutils-gdb toolchain<https://github.com/espressif/binutils-gdb/tree/esp32ulp-elf-2.35>`_
@@ -30,13 +30,30 @@ Features
3030
The following features are supported:
3131

3232
* the entire `ESP32 ULP instruction set<https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ulp_instruction_set.html>`_
33+
* the entire `ESP32-S2 ULP instruction set<https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/ulp_instruction_set.html>`_
34+
(this also covers the ESP32-S3) [#f1]_ [#f2]_
3335
* constants defined with ``.set``
3436
* constants defined with ``#define``
3537
* expressions in assembly code and constant definitions
3638
* RTC convenience macros (e.g. ``WRITE_RTC_REG``)
3739
* many ESP32 ULP code examples found on the web will work unmodified
3840
* a simple disassembler is also provided
3941

42+
.. [#f1]Note: the ESP32-S2 and ESP32-S3 have the same ULP binary format between each other
43+
but the binary format is different than that of the original ESP32 ULP. You need to
44+
select the ``esp32s2`` cpu (`see docs</docs/index.rst>`_) when assembling code for
45+
use on an ESP32-S2/S3.
46+
47+
.. [#f2]Note: The ESP32-S2 and ESP32-S3 have the same ULP binary format, but the peripheral
48+
register addresses (those accessed with REG_RD and REG_WR) are different. For best
49+
results, use the correct peripheral register addresses for the specific variant you
50+
are working with. The assembler (when used with ``cpu=esp32s2``) will accept
51+
addresses for any of the 3 variants, because they are translated into relative
52+
offsets anyway and many registers live at the same relative offset on all 3 variants.
53+
This conveniently means that the same assembly code can assembled unmodified for each
54+
variant and produce a correctly working binary - as long as only peripheral registers
55+
are used, which have the same relative offset across the variants. Use with care!
56+
4057
4158
Quick start
4259
-----------
@@ -66,10 +83,12 @@ See `docs/index.rst </docs/index.rst>`_.
6683
Requirements
6784
------------
6885

69-
The minimum supported version of MicroPython is v1.12.
86+
The minimum supported version of MicroPython is v1.12. (For ESP32-S2 and S3
87+
devices, a version greater than v1.20 is required as versions before that
88+
did not enable the ``esp32.ULP`` class).
7089

71-
An ESP32 is required to run the ULP machine code binary produced by micropython-esp32-ulp
72-
(the ESP32-S2 will not work as it is not binary compatible with the ESP32).
90+
An ESP32deviceis required to run the ULP machine code binary produced by
91+
micropython-esp32-ulp.
7392

7493

7594
License

‎docs/disassembler.rst‎

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ You can also specify additional options to ``disassemble.py`` as follows:
2525
+--------------------------+----------------------------------------------------------------+
2626
| Option| Description|
2727
+==========================+================================================================+
28+
| ``-c`` or ``--mcpu``| Choose ULP variant: either esp32 or esp32s2|
29+
+--------------------------+----------------------------------------------------------------+
2830
| ``-h``| Show help text|
2931
+--------------------------+----------------------------------------------------------------+
3032
|| ``-m <bytes sequence>`` || Disassemble a provided sequence of hex bytes|
@@ -43,18 +45,31 @@ specified file.
4345
Note that the ULP header is validates and files with unknown magic bytes will be
4446
rejected. The correct 4 magic bytes at the start of a ULP binary are ``ulp\x00``.
4547

46-
Example:
48+
Example disassembling an ESP32 ULP binary:
4749

4850
..code-block::shell
4951
5052
$ micropython -m tools.disassemble path/to/binary.ulp
5153
.text
5254
0000 040000d0 LD r0, r1, 0
53-
0004 0e0400d0 LD r2, r3, 1
55+
0004 0e0000d0 LD r2, r3, 0
56+
0008 04000068 ST r0, r1, 0
57+
000c 0b000068 ST r3, r2, 0
58+
.data
59+
0010 00000000<empty>
60+
61+
Example disassembling an ESP32-S2 ULP binary:
62+
63+
..code-block::shell
64+
65+
$ micropython -m tools.disassemble -c esp32s2 path/to/binary.ulp
66+
.text
67+
0000 040000d0 LD r0, r1, 0
68+
0004 0e0000d0 LD r2, r3, 0
5469
0008 84010068 ST r0, r1, 0
55-
000c8b090068 ST r3, r2,2
70+
000c8b010068 ST r3, r2,0
5671
.data
57-
0000 00000000<empty>
72+
0010 00000000<empty>
5873
5974
6075
Disassembling a byte sequence
@@ -129,18 +144,20 @@ For example:
129144
Disassembling on device
130145
-----------------------------
131146

132-
The disassembler also works when used on an ESP32.
147+
The disassembler also works when used on an ESP32 device.
133148

134149
To use the disassembler on a real device:
135150

136151
* ensure ``micropython-esp32-ulp`` is installed on the device (see `docs/index.rst</docs/index.rst>`_).
137-
* upload ``tools/disassemble.py`` to the device (any directory will do)
138-
* run the following:
152+
* upload ``tools/disassemble.py`` ``tools/decode.py`` and ``tools/decode_s2.py`` to the device
153+
(any directory will do, as long as those 3 files are in the same directory)
154+
* the following example code assumes you placed the 3 files into the device's "root" directory
155+
* run the following (note, we must specify which the cpu the binary is for):
139156

140157
..code-block::python
141158
142159
from disassembleimport disassemble_file
143160
# then either:
144-
disassemble_file('path/to/file.ulp')# normal mode
161+
disassemble_file('path/to/file.ulp',cpu='esp32s2')# normal mode
145162
# or:
146-
disassemble_file('path/to/file.ulp',True)# verbose mode
163+
disassemble_file('path/to/file.ulp',cpu='esp32s2',verbose=True)# verbose mode

‎docs/index.rst‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ follows:
5858
cd micropython-esp32-ulp
5959
micropython -m esp32_ulp path/to/code.S# this results in path/to/code.ulp
6060
61+
The assembler supports selecting a CPU to assemble for using the ``-c`` option
62+
(valid cpu's are ``esp32`` and ``esp32s2``):
63+
64+
..code-block::shell
65+
66+
micropython -m esp32_ulp -c esp32s2 path/to/code.S# assemble for an ESP32-S2
67+
6168
6269
More examples
6370
+++++++++++++
@@ -86,12 +93,13 @@ assembly source file into a machine code binary file with a ``.ulp`` extension.
8693
That file can then be loaded directly without assembling the source again.
8794

8895
1. Create/upload an assembly source file and run the following to get a
89-
loadable ULP binary as a ``.ulp`` file:
96+
loadable ULP binary as a ``.ulp`` file (specify ``cpu='esp32s2'`` if you
97+
have an ESP32-S2 or ESP32-S3 device):
9098

9199
..code-block::python
92100
93101
import esp32_ulp
94-
esp32_ulp.assemble_file('code.S')# this results in code.ulp
102+
esp32_ulp.assemble_file('code.S',cpu='esp32')# this results in code.ulp
95103
96104
2. The above prints out the offsets of all global symbols/labels. For the next
97105
step, you will need to note down the offset of the label, which represents
@@ -153,7 +161,6 @@ Currently the following are not supported:
153161
* assembler macros using ``.macro``
154162
* preprocessor macros using ``#define A(x,y) ...``
155163
* including files using ``#include``
156-
* ESP32-S2 (not binary compatible with the ESP32)
157164

158165

159166
Testing
@@ -164,7 +171,8 @@ output is identical with what Espressif's esp32-elf-as (from their `binutils-gdb
164171
<https://github.com/espressif/binutils-gdb/tree/esp32ulp-elf-2.35>`_) produces.
165172

166173
micropython-esp32-ulp has been tested on the Unix port of MicroPython and on real ESP32
167-
devices with the chip type ESP32D0WDQ6 (revision 1) without SPIRAM.
174+
devices with the chip type ESP32D0WDQ6 (revision 1) without SPIRAM as well as ESP32-S2
175+
(ESP32-S2FH4) and ESP32-S3 (ESP32-S3R8) devices.
168176

169177
Consult the Github Actions `workflow definition file</.github/workflows/run_tests.yaml>`_
170178
for how to run the different tests.

‎docs/preprocess.rst‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,21 @@ are not needed on the device either.)
9595
micropython -m esp32_ulp.parse_to_db \
9696
esp-idf/components/soc/esp32/include/soc/{soc,soc_ulp,rtc_cntl_reg,rtc_io_reg,sens_reg}.h
9797
98+
99+
..warning::
100+
101+
`:warning:` Ensure that you include the header files for the correct
102+
variant you are working with. In the example code above, simply switch
103+
``esp32`` to ``esp32s2`` or ``esp32s3`` in the path to the include files.
104+
105+
There are subtle differences across the ESP32 variants such as which
106+
constants are available or the value of certain constants. For example,
107+
peripheral register addresses differ between the 3 variants even though
108+
many constants for peripheral registers are available on all 3 variants.
109+
Other constants such as those relating to the HOLD functionality of touch
110+
pads are only available on the original ESP32.
111+
112+
98113
2. Using the defines database during preprocessing
99114

100115
The preprocessor will automatically use a defines database, when using the
@@ -108,6 +123,7 @@ are not needed on the device either.)
108123
or instantiate the ``Preprocessor`` class directly, without passing it a
109124
DefinesDB instance via ``use_db``.
110125

126+
111127
Design choices
112128
--------------
113129

‎esp32_ulp/__init__.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
garbage_collect('after import')
77

88

9-
defsrc_to_binary(src):
10-
assembler=Assembler()
9+
defsrc_to_binary(src,cpu):
10+
assembler=Assembler(cpu)
1111
src=preprocess(src)
1212
assembler.assemble(src,remove_comments=False)# comments already removed by preprocessor
1313
garbage_collect('before symbols export')
@@ -19,11 +19,11 @@ def src_to_binary(src):
1919
returnmake_binary(text,data,bss_len)
2020

2121

22-
defassemble_file(filename):
22+
defassemble_file(filename,cpu):
2323
withopen(filename)asf:
2424
src=f.read()
2525

26-
binary=src_to_binary(src)
26+
binary=src_to_binary(src,cpu)
2727

2828
iffilename.endswith('.s')orfilename.endswith('.S'):
2929
filename=filename[:-2]

‎esp32_ulp/__main__.py‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@
22
from .importassemble_file
33

44

5-
defmain(fn):
6-
assemble_file(fn)
5+
defmain(fn,cpu):
6+
assemble_file(fn,cpu)
77

88

99
if__name__=='__main__':
10-
main(sys.argv[1])
10+
cpu='esp32'
11+
filename=sys.argv[1]
12+
iflen(sys.argv)>3:
13+
ifsys.argv[1]in ('-c','--mcpu'):
14+
cpu=sys.argv[2].lower()
15+
ifcpunotin ('esp32','esp32s2'):
16+
raiseValueError('Invalid cpu')
17+
filename=sys.argv[3]
18+
main(filename,cpu)
1119

‎esp32_ulp/assemble.py‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""
44

55
importre
6-
from .importopcodes
76
from .nocommentimportremove_commentsasdo_remove_comments
87
from .utilimportgarbage_collect
98

@@ -88,9 +87,19 @@ def set_global(self, symbol):
8887

8988
classAssembler:
9089

91-
def__init__(self,symbols=None,bases=None,globals=None):
90+
def__init__(self,cpu='esp32',symbols=None,bases=None,globals=None):
91+
ifcpu=='esp32':
92+
opcode_module='opcodes'
93+
elifcpu=='esp32s2':
94+
opcode_module='opcodes_s2'
95+
else:
96+
raiseValueError('Invalid cpu')
97+
98+
relative_import=1if'/'in__file__else0
99+
self.opcodes=__import__(opcode_module,None,None, [],relative_import)
100+
92101
self.symbols=SymbolTable(symbolsor {},basesor {},globalsor {})
93-
opcodes.symbols=self.symbols# XXX dirty hack
102+
self.opcodes.symbols=self.symbols# XXX dirty hack
94103

95104
# regex for parsing assembly lines
96105
# format: [[whitespace]label:][whitespace][opcode[whitespace arg[,arg...]]]
@@ -223,7 +232,7 @@ def d_align(self, align=4, fill=None):
223232
self.fill(self.section,amount,fill)
224233

225234
defd_set(self,symbol,expr):
226-
value=int(opcodes.eval_arg(expr))
235+
value=int(self.opcodes.eval_arg(expr))
227236
self.symbols.set_sym(symbol,ABS,None,value)
228237

229238
defd_global(self,symbol):
@@ -264,13 +273,13 @@ def assembler_pass(self, lines):
264273
else:
265274
# machine instruction
266275
opcode_lower=opcode.lower()
267-
func=getattr(opcodes,'i_'+opcode_lower,None)
276+
func=getattr(self.opcodes,'i_'+opcode_lower,None)
268277
iffuncisnotNone:
269278
ifself.a_pass==1:
270279
# during the first pass, symbols are not all known yet.
271280
# so we add empty instructions to the section, to determine
272281
# section sizes and symbol offsets for pass 2.
273-
result= (0,)*opcodes.no_of_instr(opcode_lower,args)
282+
result= (0,)*self.opcodes.no_of_instr(opcode_lower,args)
274283
else:
275284
result=func(*args)
276285

‎esp32_ulp/opcodes.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ def i_reg_wr(reg, high_bit, low_bit, val):
379379
_wr_reg.addr=reg&0xff
380380
_wr_reg.periph_sel= (reg&0x300)>>8
381381
else:
382-
_wr_reg.addr= (reg&0xff)>>2
382+
_wr_reg.addr= (reg>>2)&0xff
383383
_wr_reg.periph_sel=_soc_reg_to_ulp_periph_sel(reg)
384384
_wr_reg.data=get_imm(val)
385385
_wr_reg.low=get_imm(low_bit)
@@ -394,7 +394,7 @@ def i_reg_rd(reg, high_bit, low_bit):
394394
_rd_reg.addr=reg&0xff
395395
_rd_reg.periph_sel= (reg&0x300)>>8
396396
else:
397-
_rd_reg.addr= (reg&0xff)>>2
397+
_rd_reg.addr= (reg>>2)&0xff
398398
_rd_reg.periph_sel=_soc_reg_to_ulp_periph_sel(reg)
399399
_rd_reg.unused=0
400400
_rd_reg.low=get_imm(low_bit)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp