From b737c03bef8f1d52d3bef0c37b9bccd2bf482cb8 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 01:15:48 +0200 Subject: [PATCH 01/11] README: fix typos, grammar, punctuation --- README.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.rst b/README.rst index 6b650fa..462c29b 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ micropython-esp32-ulp is an assembler toolchain for the ESP32 ULP (Ultra Low-Pow Co-Processor, written in MicroPython. It can translate small assembly language programs to a loadable/executable -ULP-FSM (not RISC-V) machine code binary, directly on a ESP32 microcontroller. +ULP-FSM (not RISC-V) machine code binary, directly on an ESP32 microcontroller. This is intended as an alternative approach to assembling such programs using the `binutils-gdb toolchain `_ @@ -39,9 +39,9 @@ The following features are supported: * many ESP32 ULP code examples found on the web will work unmodified * a simple disassembler is also provided -.. [#f1] Note: the ESP32-S2 and ESP32-S3 have the same ULP binary format between each other - but the binary format is different than that of the original ESP32 ULP. You need to - select the ``esp32s2`` cpu (`see docs `_) when assembling code for +.. [#f1] Note: the ESP32-S2 and ESP32-S3 have the same ULP binary format, + but the binary format is different from that of the original ESP32 ULP. You need to + select the ``esp32s2`` CPU (`see docs `_) when assembling code for use on an ESP32-S2/S3. .. [#f2] Note: The ESP32-S2 and ESP32-S3 have the same ULP binary format, but the peripheral @@ -49,8 +49,8 @@ The following features are supported: results, use the correct peripheral register addresses for the specific variant you are working with. The assembler (when used with ``cpu=esp32s2``) will accept addresses for any of the 3 variants, because they are translated into relative - offsets anyway and many registers live at the same relative offset on all 3 variants. - This conveniently means that the same assembly code can assembled unmodified for each + offsets anyway, and many registers live at the same relative offset on all 3 variants. + This conveniently means that the same assembly code can be assembled unmodified for each variant and produce a correctly working binary - as long as only peripheral registers are used, which have the same relative offset across the variants. Use with care! @@ -58,7 +58,7 @@ The following features are supported: Quick start ----------- -To get going run the following directly on the ESP32: +To get going, run the following directly on the ESP32: .. code-block:: python @@ -77,7 +77,7 @@ To get going run the following directly on the ESP32: import counter The `examples/counter.py `_ example shows how to assemble code, -load and run the resulting binary and exchange data between the ULP and the main CPU. +load and run the resulting binary, and exchange data between the ULP and the main CPU. Documentation @@ -88,9 +88,9 @@ See `docs/index.rst `_. Requirements ------------ -The minimum supported version of MicroPython is v1.12. (For ESP32-S2 and S3 -devices, a version greater than v1.20 is required as versions before that -did not enable the ``esp32.ULP`` class). +The minimum supported version of MicroPython is v1.12. (For ESP32-S2 and ESP32-S3 +devices, a version greater than v1.20 is required, as earlier versions did not +enable the ``esp32.ULP`` class). An ESP32 device is required to run the ULP machine code binary produced by micropython-esp32-ulp. From 5980c7a8995811ece529c9d51c2076fad648ccbe Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 01:26:33 +0200 Subject: [PATCH 02/11] docs: fix typos, grammar, punctuation --- docs/disassembler.rst | 14 +++++++------- docs/index.rst | 12 ++++++------ docs/preprocess.rst | 20 ++++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/disassembler.rst b/docs/disassembler.rst index ee733e9..7a0721b 100644 --- a/docs/disassembler.rst +++ b/docs/disassembler.rst @@ -42,7 +42,7 @@ Disassembling a file The simplest and default mode of the disassembler is to disassemble the specified file. -Note that the ULP header is validates and files with unknown magic bytes will be +Note that the ULP header is validated and files with unknown magic bytes will be rejected. The correct 4 magic bytes at the start of a ULP binary are ``ulp\x00``. Example disassembling an ESP32 ULP binary: @@ -75,13 +75,13 @@ Example disassembling an ESP32-S2 ULP binary: Disassembling a byte sequence ----------------------------- -The ``-m`` option allows disassembling a sequences hex letters representing +The ``-m`` option allows disassembling a sequence of hex letters representing ULP instructions. This option expects the actual instructions directly, without any ULP header. The sequence must contain a number of hex letters exactly divisible by 8, i.e. -8, 16, 24, etc, because each 32-bit word is made up of 8 hex letters. Spaces +8, 16, 24, etc., because each 32-bit word is made up of 8 hex letters. Spaces can be included in the sequence and they are ignored. The typical use case for this feature is to copy/paste some instructions from @@ -148,11 +148,11 @@ The disassembler also works when used on an ESP32 device. To use the disassembler on a real device: -* ensure ``micropython-esp32-ulp`` is installed on the device (see `docs/index.rst `_). -* upload ``tools/disassemble.py`` ``tools/decode.py`` and ``tools/decode_s2.py`` to the device +* Ensure ``micropython-esp32-ulp`` is installed on the device (see `docs/index.rst `_). +* Upload ``tools/disassemble.py``, ``tools/decode.py``, and ``tools/decode_s2.py`` to the device (any directory will do, as long as those 3 files are in the same directory) -* the following example code assumes you placed the 3 files into the device's "root" directory -* run the following (note, we must specify which the cpu the binary is for): +* The following example code assumes you placed the 3 files into the device's "root" directory +* Run the following (note, we must specify which CPU the binary is for): .. code-block:: python diff --git a/docs/index.rst b/docs/index.rst index 77906dc..0900573 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,7 +37,7 @@ On the ESP32 ++++++++++++ The simplest example to try on the ESP32 is `counter.py `_. -It shows how to assemble code, load and run the resulting binary and exchange +It shows how to assemble code, load and run the resulting binary, and exchange data between the ULP and the main CPU. Run the ``counter.py`` example: @@ -65,7 +65,7 @@ follows: micropython -m esp32_ulp path/to/code.S # this results in path/to/code.ulp The assembler supports selecting a CPU to assemble for using the ``-c`` option -(valid cpu's are ``esp32`` and ``esp32s2``): +(valid CPUs are ``esp32`` and ``esp32s2``): .. code-block:: shell @@ -91,7 +91,7 @@ This can be useful in battery-powered applications where every second of sleep time matters. Splitting the assembly and load stage can be combined with other techniques, -for example to implement a caching mechansim for the ULP binary that +for example, to implement a caching mechanism for the ULP binary that automatically updates the binary every time the assembly source code changes. The ``esp32_ulp.assemble_file`` function can be used to assemble and link an @@ -128,7 +128,7 @@ That file can then be loaded directly without assembling the source again. # start the ULP # assemble_file printed offsets in number of 32-bit words. # ulp.run() expects an offset in number of bytes. - # Thus, multiply the offset to our entry point by 4. + # Thus, multiply the offset of our entry point by 4. # e.g. for an offset of 2: # 2 words * 4 = 8 bytes ulp.run(2*4) # specify the offset of the entry point label @@ -173,14 +173,14 @@ Testing ------- There are unit tests and also compatibility tests that check whether the binary -output is identical with what Espressif's esp32-elf-as (from their `binutils-gdb fork +output is identical to what Espressif's esp32-elf-as (from their `binutils-gdb fork `_) produces. micropython-esp32-ulp has been tested on the Unix port of MicroPython and on real ESP32 devices with the chip type ESP32D0WDQ6 (revision 1) without SPIRAM as well as ESP32-S2 (ESP32-S2FH4) and ESP32-S3 (ESP32-S3R8) devices. -Consult the Github Actions `workflow definition file `_ +Consult the GitHub Actions `workflow definition file `_ for how to run the different tests. diff --git a/docs/preprocess.rst b/docs/preprocess.rst index 45569a5..da5affa 100644 --- a/docs/preprocess.rst +++ b/docs/preprocess.rst @@ -11,7 +11,7 @@ provided by the ESP-IDF framework, along with constants defined in the framework's include files (such as ``RTC_GPIO_IN_REG``), to make reading and writing from/to peripheral registers much easier. -In order to do this the preprocessor has two capabilities: +In order to do this, the preprocessor has two capabilities: 1. Parse and replace identifiers defined with ``#define`` 2. Recognise the ``WRITE_RTC_*`` and ``READ_RTC_*`` macros and expand @@ -21,7 +21,7 @@ In order to do this the preprocessor has two capabilities: Usage ------------------------ -Normally the assembler is called as follows +Normally the assembler is called as follows: .. code-block:: python @@ -49,8 +49,8 @@ Using a "Defines Database" Because the micropython-esp32-ulp assembler was built for running on the ESP32 microcontroller with limited RAM, the preprocessor aims to work there too. -To handle large number of defined constants (such as the ``RTC_*`` constants from -the ESP-IDF) the preprocessor can use a database (based on BerkleyDB) stored on the +To handle a large number of defined constants (such as the ``RTC_*`` constants from +the ESP-IDF) the preprocessor can use a database (based on Berkeley DB) stored on the device's filesystem for looking up defines. The database needs to be populated before preprocessing. (Usually, when only using @@ -67,7 +67,7 @@ are not needed on the device either.) database from include files. The resulting file will be called ``defines.db``. - (The following assume running on a PC. To do this on device, refer to the + (The following assumes running on a PC. To do this on device, refer to the `esp32_ulp/parse_to_db.py <../esp32_ulp/parse_to_db.py>`_ file.) .. code-block:: bash @@ -83,7 +83,7 @@ are not needed on the device either.) # if file system space is not a concern, the following can be convenient # by including all relevant include files from the ESP-IDF framework. - # This results in an approximately 2MB large database. + # This results in an approximately 2 MB large database. micropython -m esp32_ulp.parse_to_db \ esp-idf/components/soc/esp32/include/soc/*.h \ esp-idf/components/esp_common/include/*.h @@ -91,14 +91,14 @@ are not needed on the device either.) # most ULP code uses only 5 include files. Parsing only those into the # database should thus allow assembling virtually all ULP code one would # find or want to write. - # This results in an approximately 250kB large database. + # This results in an approximately 250 kB large database. micropython -m esp32_ulp.parse_to_db \ esp-idf/components/soc/esp32/include/soc/{soc,soc_ulp,rtc_cntl_reg,rtc_io_reg,sens_reg}.h .. warning:: - `:warning:` Ensure that you include the header files for the correct + Ensure that you include the header files for the correct variant you are working with. In the example code above, simply switch ``esp32`` to ``esp32s2`` or ``esp32s3`` in the path to the include files. @@ -118,7 +118,7 @@ are not needed on the device either.) is taken not to create an empty database file, cluttering up the filesystem, when not needed). - If you do not want the preprocessor use use a DefinesDB, pass ``False`` to + If you do not want the preprocessor to use a DefinesDB, pass ``False`` to the ``use_defines_db`` argument of the ``preprocess`` convenience function, or instantiate the ``Preprocessor`` class directly, without passing it a DefinesDB instance via ``use_db``. @@ -129,7 +129,7 @@ Design choices The preprocessor does not support: -1. Function style macros such as :code:`#define f(a,b) (a+b)` +1. Function-style macros such as :code:`#define f(a,b) (a+b)` This is not important, because there are only few RTC macros that need to be supported and they are simply implemented as Python functions. From 949caad1cd5247efe6af823ef4f15b2e2bc18e3b Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 01:40:32 +0200 Subject: [PATCH 03/11] code: fix typos, grammar, punctuation --- esp32_ulp/__main__.py | 2 +- esp32_ulp/assemble.py | 4 ++-- esp32_ulp/preprocess.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/esp32_ulp/__main__.py b/esp32_ulp/__main__.py index fc14320..b885eb8 100644 --- a/esp32_ulp/__main__.py +++ b/esp32_ulp/__main__.py @@ -20,7 +20,7 @@ def main(fn, cpu): if sys.argv[1] in ('-c', '--mcpu'): cpu = sys.argv[2].lower() if cpu not in ('esp32', 'esp32s2'): - raise ValueError('Invalid cpu') + raise ValueError('Invalid CPU') filename = sys.argv[3] main(filename, cpu) diff --git a/esp32_ulp/assemble.py b/esp32_ulp/assemble.py index 33cec42..2b019c4 100644 --- a/esp32_ulp/assemble.py +++ b/esp32_ulp/assemble.py @@ -100,7 +100,7 @@ def __init__(self, cpu='esp32', symbols=None, bases=None, globals=None): elif cpu == 'esp32s2': opcode_module = 'opcodes_s2' else: - raise ValueError('Invalid cpu') + raise ValueError('Invalid CPU') relative_import = 1 if '/' in __file__ else 0 self.opcodes = __import__(opcode_module, None, None, [], relative_import) @@ -111,7 +111,7 @@ def __init__(self, cpu='esp32', symbols=None, bases=None, globals=None): # regex for parsing assembly lines # format: [[whitespace]label:][whitespace][opcode[whitespace arg[,arg...]]] # where [] means optional - # initialised here once, instead of compiling once per line + # initialized here once, instead of compiling once per line self.line_regex = re.compile(r'^(\s*([a-zA-Z0-9_$.]+):)?\s*((\S*)\s*(.*))$') def init(self, a_pass): diff --git a/esp32_ulp/preprocess.py b/esp32_ulp/preprocess.py index 4b08749..d9161c5 100644 --- a/esp32_ulp/preprocess.py +++ b/esp32_ulp/preprocess.py @@ -55,7 +55,7 @@ def parse_define_line(self, line): identifier, value = parts tmp = identifier.split('(', 1) if len(tmp) == 2: - # skip parameterised defines (macros) + # skip parameterized defines (macros) return {} value = "".join(nocomment.remove_comments(value)).strip() return {identifier: value} @@ -68,7 +68,7 @@ def parse_defines(self, content): def expand_defines(self, line): found = True - while found: # do as many passed as needed, until nothing was replaced anymore + while found: # do as many passes as needed, until nothing is replaced anymore found = False tokens = split_tokens(line) line = "" @@ -115,8 +115,8 @@ def expand_rtc_macros(self, line): if macro_fn is None: return line - macro_args, _ = macro_args.rsplit(')', 1) # trim away right bracket. safe as comments already stripped - macro_args = macro_args.split(',') # not safe when args contain ',' but we should not have those + macro_args, _ = macro_args.rsplit(')', 1) # trim away the right bracket; safe as comments are already stripped + macro_args = macro_args.split(',') # not safe when args contain ','; we should not have those macro_args = [x.strip() for x in macro_args] return macro_fn(*macro_args) From 0efce32ecaf43b7fbddbed5f2adfb49889dc67bc Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 01:52:49 +0200 Subject: [PATCH 04/11] examples: fix typos, grammar, punctuation --- examples/blink.py | 24 ++++++++++++------------ examples/blink_s2.py | 20 ++++++++++---------- examples/counter.py | 10 +++++----- examples/counter_s2.py | 10 +++++----- examples/fade_s2.py | 4 ++-- examples/readgpio.py | 4 ++-- examples/readgpio_s2.py | 4 ++-- examples/readgpio_s3.py | 4 ++-- examples/tsens_s2.py | 10 +++++----- 9 files changed, 45 insertions(+), 45 deletions(-) diff --git a/examples/blink.py b/examples/blink.py index 3c43883..4b36140 100644 --- a/examples/blink.py +++ b/examples/blink.py @@ -8,20 +8,20 @@ """ Example for: ESP32 -Simple example showing how to control a GPIO pin from the ULP coprocessor. +Simple example showing how to control a GPIO pin from the ULP co-processor. The GPIO port is configured to be attached to the RTC module, and then set -to OUTPUT mode. To avoid re-initializing the GPIO on every wakeup, a magic +to OUTPUT mode. To avoid re-initializing the GPIO on every wake-up, a magic token gets set in memory. After every change of state, the ULP is put back to sleep again until the -next wakeup. The ULP wakes up every 500ms to change the state of the GPIO -pin. An LED attached to the GPIO pin would toggle on and off every 500ms. +next wake-up. The ULP wakes up every 500 ms to change the state of the GPIO +pin. An LED attached to the GPIO pin would toggle on and off every 500 ms. -The end of the python script has a loop to show the value of the magic token +The end of the Python script has a loop to show the value of the magic token and the current state, so you can confirm the magic token gets set and watch the state value changing. If the loop is stopped (Ctrl-C), the LED attached -to the GPIO pin continues to blink, because the ULP runs independently from +to the GPIO pin continues to blink, because the ULP runs independently of the main processor. """ @@ -61,7 +61,7 @@ move r0, magic ld r1, r0, 0 - # test if we have initialised already + # test if we have initialized already sub r1, r1, token jump after_init, eq # jump if magic == token (note: "eq" means the last instruction (sub) resulted in 0) @@ -72,7 +72,7 @@ # GPIO shall be output, not input (this also enables a pull-down by default) WRITE_RTC_REG(RTC_GPIO_ENABLE_REG, RTC_GPIO_ENABLE_S + gpio, 1, 1) - # store that we're done with initialisation + # store that we're done with initialization move r0, magic move r1, token st r1, r0, 0 @@ -89,17 +89,17 @@ jump off # else jump to 'off' on: - # turn on led (set GPIO) + # turn on LED (set GPIO) WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + gpio, 1, 1) jump exit off: - # turn off led (clear GPIO) + # turn off LED (clear GPIO) WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + gpio, 1, 0) jump exit exit: - halt # go back to sleep until next wakeup period + halt # go back to sleep until the next wake-up period """ binary = src_to_binary(source, cpu="esp32") # cpu is esp32 or esp32s2 @@ -110,7 +110,7 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 500000) # use timer0, wakeup after 500000usec (0.5s) +ulp.set_wakeup_period(0, 500000) # use timer0; wake up after 500000 usec (0.5 s) ulp.load_binary(load_addr, binary) ulp.run(entry_addr) diff --git a/examples/blink_s2.py b/examples/blink_s2.py index 2bdeccc..88cf46e 100644 --- a/examples/blink_s2.py +++ b/examples/blink_s2.py @@ -9,17 +9,17 @@ Example for: ESP32-S2 and ESP32-S3 The GPIO port is configured to be attached to the RTC module, and then set -to OUTPUT mode. To avoid re-initializing the GPIO on every wakeup, a magic +to OUTPUT mode. To avoid re-initializing the GPIO on every wake-up, a magic token gets set in memory. After every change of state, the ULP is put back to sleep again until the -next wakeup. The ULP wakes up every 500ms to change the state of the GPIO -pin. An LED attached to the GPIO pin would toggle on and off every 500ms. +next wake-up. The ULP wakes up every 500 ms to change the state of the GPIO +pin. An LED attached to the GPIO pin would toggle on and off every 500 ms. -The end of the python script has a loop to show the value of the magic token +The end of the Python script has a loop to show the value of the magic token and the current state, so you can confirm the magic token gets set and watch the state value changing. If the loop is stopped (Ctrl-C), the LED attached -to the GPIO pin continues to blink, because the ULP runs independently from +to the GPIO pin continues to blink, because the ULP runs independently of the main processor. """ @@ -59,7 +59,7 @@ move r0, magic ld r1, r0, 0 - # test if we have initialised already + # test if we have initialized already sub r1, r1, token jump after_init, eq # jump if magic == token (note: "eq" means the last instruction (sub) resulted in 0) @@ -87,17 +87,17 @@ jump off # else jump to 'off' on: - # turn on led (set GPIO) + # turn on LED (set GPIO) WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + gpio, 1, 1) jump exit off: - # turn off led (clear GPIO) + # turn off LED (clear GPIO) WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + gpio, 1, 0) jump exit exit: - halt # go back to sleep until next wakeup period + halt # go back to sleep until the next wake-up period """ binary = src_to_binary(source, cpu="esp32s2") # cpu is esp32 or esp32s2 @@ -108,7 +108,7 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 500000) # use timer0, wakeup after 500000usec (0.5s) +ulp.set_wakeup_period(0, 500000) # use timer0; wake up after 500000 usec (0.5 s) ulp.load_binary(load_addr, binary) ulp.run(entry_addr) diff --git a/examples/counter.py b/examples/counter.py index 6029bbd..b95741d 100644 --- a/examples/counter.py +++ b/examples/counter.py @@ -8,11 +8,11 @@ """ Example for: ESP32 -Very basic example showing data exchange main CPU <--> ULP coprocessor. +Very basic example showing data exchange between the main CPU and the ULP co-processor. To show that the ULP is doing something, it just increments the value . -It does that once per ulp timer wakeup (and then the ULP halts until it gets -waked up via the timer again). +It does that once per ULP timer wake-up (and then the ULP halts until it gets +woken up via the timer again). The timer is set to a rather long period, so you can watch the data value incrementing (see loop at the end). @@ -31,7 +31,7 @@ add r2, r2, 1 # increment r2 st r2, r3, 0 # store r2 contents into data ([r3+0]) - halt # halt ULP co-prozessor (until it gets waked up again) + halt # halt ULP co-processor (until it gets woken up again) """ binary = src_to_binary(source, cpu="esp32") # cpu is esp32 or esp32s2 @@ -42,7 +42,7 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles +ulp.set_wakeup_period(0, 50000) # use timer0; wake up after 50,000 cycles ulp.load_binary(load_addr, binary) mem32[ULP_MEM_BASE + load_addr] = 0x1000 diff --git a/examples/counter_s2.py b/examples/counter_s2.py index a5abbf9..6407000 100644 --- a/examples/counter_s2.py +++ b/examples/counter_s2.py @@ -8,11 +8,11 @@ """ Example for: ESP32-S2 and ESP32-S3 -Very basic example showing data exchange main CPU <--> ULP coprocessor. +Very basic example showing data exchange between the main CPU and the ULP co-processor. To show that the ULP is doing something, it just increments the value . -It does that once per ulp timer wakeup (and then the ULP halts until it gets -waked up via the timer again). +It does that once per ULP timer wake-up (and then the ULP halts until it gets +woken up via the timer again). The timer is set to a rather long period, so you can watch the data value incrementing (see loop at the end). @@ -31,7 +31,7 @@ add r2, r2, 1 # increment r2 st r2, r3, 0 # store r2 contents into data ([r3+0]) - halt # halt ULP co-prozessor (until it gets waked up again) + halt # halt ULP co-processor (until it gets woken up again) """ binary = src_to_binary(source, cpu="esp32s2") # cpu is esp32 or esp32s2 @@ -42,7 +42,7 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles +ulp.set_wakeup_period(0, 50000) # use timer0; wake up after 50,000 cycles ulp.load_binary(load_addr, binary) mem32[ULP_MEM_BASE + load_addr] = 0x1000 diff --git a/examples/fade_s2.py b/examples/fade_s2.py index 5f8d4ca..c887d63 100644 --- a/examples/fade_s2.py +++ b/examples/fade_s2.py @@ -59,9 +59,9 @@ move r3, wait_on st r1, r3, 0 # Overwrite wait_on with new value - WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + led_pin, 1, 0) # turn off led (clear GPIO) + WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + led_pin, 1, 0) # turn off LED (clear GPIO) wait_off: wait 0 # Placeholder; value overwritten dynamically - WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + led_pin, 1, 1) # turn on led (set GPIO) + WRITE_RTC_REG(RTC_GPIO_OUT_REG, RTC_GPIO_OUT_DATA_S + led_pin, 1, 1) # turn on LED (set GPIO) wait_on: wait 0 # Placeholder; value overwritten dynamically jump set_waits # Loop program diff --git a/examples/readgpio.py b/examples/readgpio.py index 944f1c2..f7d8f26 100644 --- a/examples/readgpio.py +++ b/examples/readgpio.py @@ -69,10 +69,10 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles +ulp.set_wakeup_period(0, 50000) # use timer0; wake up after 50,000 cycles ulp.load_binary(load_addr, binary) -mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialise state to 0 +mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialize state to 0 ulp.run(entry_addr) while True: diff --git a/examples/readgpio_s2.py b/examples/readgpio_s2.py index 91614e3..7d1a9ac 100644 --- a/examples/readgpio_s2.py +++ b/examples/readgpio_s2.py @@ -75,10 +75,10 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles +ulp.set_wakeup_period(0, 50000) # use timer0; wake up after 50,000 cycles ulp.load_binary(load_addr, binary) -mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialise state to 0 +mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialize state to 0 ulp.run(entry_addr) while True: diff --git a/examples/readgpio_s3.py b/examples/readgpio_s3.py index d5645cd..66cb76a 100644 --- a/examples/readgpio_s3.py +++ b/examples/readgpio_s3.py @@ -75,10 +75,10 @@ ULP_DATA_MASK = 0xffff # ULP data is only in lower 16 bits ulp = ULP() -ulp.set_wakeup_period(0, 50000) # use timer0, wakeup after 50.000 cycles +ulp.set_wakeup_period(0, 50000) # use timer0; wake up after 50,000 cycles ulp.load_binary(load_addr, binary) -mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialise state to 0 +mem32[ULP_MEM_BASE + load_addr] = 0x0 # initialize state to 0 ulp.run(entry_addr) while True: diff --git a/examples/tsens_s2.py b/examples/tsens_s2.py index 58594e6..9f14610 100644 --- a/examples/tsens_s2.py +++ b/examples/tsens_s2.py @@ -41,7 +41,7 @@ entry: move r3, magic ld r0, r3, 0 - jumpr start, token, eq #check if we have already initialized + jumpr start, token, eq # check if we have already initialized init: # Set SENS_TSENS_CLKGATE_EN to enable temperature sensor clock. @@ -50,14 +50,14 @@ # Store temperature_data memory location in r2 move r2, temperature_data - # store that we're done with initialisation + # store that we're done with initialization move r0, token st r0, r3, 0 start: - tsens r0, 1000 # make measurement for 1000 clock cycles - st r0, r2, 0 # store the temperature in memory to be read by main CPU - halt # go back to sleep until next wakeup period + tsens r0, 1000 # make a measurement for 1000 clock cycles + st r0, r2, 0 # store the temperature in memory to be read by the main CPU + halt # go back to sleep until the next wake-up period """ binary = src_to_binary(source, cpu="esp32s2") # cpu is esp32 or esp32s2 From 88294f9aa71a9e43cc76b863b340f9d773667f85 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:03:07 +0200 Subject: [PATCH 05/11] tests: fix typos, grammar, punctuation --- tests/00_unit_tests.sh | 2 +- tests/01_compat_tests.sh | 2 +- tests/02_compat_rtc_tests.sh | 12 ++++++------ tests/assemble.py | 6 +++--- tests/decode.py | 2 +- tests/decode_s2.py | 2 +- tests/opcodes.py | 2 +- tests/opcodes_s2.py | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/00_unit_tests.sh b/tests/00_unit_tests.sh index 0a01933..c9baf94 100755 --- a/tests/00_unit_tests.sh +++ b/tests/00_unit_tests.sh @@ -13,6 +13,6 @@ set -e LIST=${1:-opcodes opcodes_s2 assemble link util preprocess definesdb decode decode_s2} for file in $LIST; do - echo testing $file... + echo Testing $file... micropython $file.py done diff --git a/tests/01_compat_tests.sh b/tests/01_compat_tests.sh index a6fc2d1..09c4367 100755 --- a/tests/01_compat_tests.sh +++ b/tests/01_compat_tests.sh @@ -36,7 +36,7 @@ run_tests_for_cpu() { for src_file in $(ls -1 compat/*.S fixtures/*.S); do src_name="${src_file%.S}" - # files with a cpu encoded into their name are only run for that cpu + # Files with a CPU encoded into their name are only run for that CPU if [[ $src_file =~ \.esp32\. && $cpu != esp32 ]] || [[ $src_file =~ \.esp32s2?\. && $cpu != esp32s2 ]]; then continue fi diff --git a/tests/02_compat_rtc_tests.sh b/tests/02_compat_rtc_tests.sh index be2a98d..c2896c7 100755 --- a/tests/02_compat_rtc_tests.sh +++ b/tests/02_compat_rtc_tests.sh @@ -130,12 +130,12 @@ run_tests_for_cpu() { LIST=$(echo binutils-gdb/gas/testsuite/gas/esp32ulp/$cpu/*.s) if [ $cpu = esp32 ]; then - # append extra tests to test preprocessor - # examples have constants specific to ESP32 (original) - # so we only run these tests with cpu = esp32 - # these tests primarily test our preprocessor, which is - # cpu independent, so we do not need to run them - # per each cpu. + # Append extra tests to test the preprocessor + # Examples have constants specific to the original ESP32, + # so we only run these tests with CPU = esp32. + # These tests primarily exercise our preprocessor, which is + # CPU-independent, so we do not need to run them + # for each CPU. LIST=$(echo ulptool/src/ulp_examples/*/*.s $LIST) fi diff --git a/tests/assemble.py b/tests/assemble.py index cfd1baa..98822f4 100644 --- a/tests/assemble.py +++ b/tests/assemble.py @@ -62,7 +62,7 @@ def test_parse_line(): def test_parse_labels_correctly(): """ - description of what defines a label + Description of what defines a label https://sourceware.org/binutils/docs/as/Statements.html https://sourceware.org/binutils/docs/as/Labels.html """ @@ -168,7 +168,7 @@ def test_assemble_uppercase_opcode(): assert not raised -def test_assemble_evalulate_expressions(): +def test_assemble_evaluate_expressions(): src_w_expr = """\ .set shft, 2 .set loops, (1 << shft) @@ -300,7 +300,7 @@ def test_support_multiple_statements_per_line(): test_assemble_bss_with_value() test_assemble_global() test_assemble_uppercase_opcode() -test_assemble_evalulate_expressions() +test_assemble_evaluate_expressions() test_assemble_optional_comment_removal() test_assemble_test_regressions_from_evaluation() test_support_multiple_statements_per_line() diff --git a/tests/decode.py b/tests/decode.py index eb74b95..48bfbba 100644 --- a/tests/decode.py +++ b/tests/decode.py @@ -73,7 +73,7 @@ def test_empty_instruction(): # instruction offset encoded in the binary instruction will be in # words (1 word = 4 bytes). # The disassembled instructions would therefore show as "JUMP 1" -# for what was originally "JUMP 4" in the source code.@test +# for what was originally "JUMP 4" in the source code. @test def test_all_instructions(): # OPCODE_WR_REG = 1 diff --git a/tests/decode_s2.py b/tests/decode_s2.py index 52838ca..57617ad 100644 --- a/tests/decode_s2.py +++ b/tests/decode_s2.py @@ -73,7 +73,7 @@ def test_empty_instruction(): # instruction offset encoded in the binary instruction will be in # words (1 word = 4 bytes). # The disassembled instructions would therefore show as "JUMP 1" -# for what was originally "JUMP 4" in the source code.@test +# for what was originally "JUMP 4" in the source code. @test def test_all_instructions(): # OPCODE_WR_REG = 1 diff --git a/tests/opcodes.py b/tests/opcodes.py index f8109b5..eab86a3 100644 --- a/tests/opcodes.py +++ b/tests/opcodes.py @@ -83,7 +83,7 @@ def test_get_cond(): def test_eval_arg(): opcodes.symbols = SymbolTable({}, {}, {}) opcodes.symbols.set_sym('const', ABS, None, 42) # constant - opcodes.symbols.set_sym('raise', ABS, None, 99) # constant using a python keyword as name (is allowed) + opcodes.symbols.set_sym('raise', ABS, None, 99) # constant using a Python keyword as a name (allowed) assert eval_arg('1+1') == 2 assert eval_arg('1+const') == 43 diff --git a/tests/opcodes_s2.py b/tests/opcodes_s2.py index b9d74d3..feb59d9 100644 --- a/tests/opcodes_s2.py +++ b/tests/opcodes_s2.py @@ -83,7 +83,7 @@ def test_get_cond(): def test_eval_arg(): opcodes.symbols = SymbolTable({}, {}, {}) opcodes.symbols.set_sym('const', ABS, None, 42) # constant - opcodes.symbols.set_sym('raise', ABS, None, 99) # constant using a python keyword as name (is allowed) + opcodes.symbols.set_sym('raise', ABS, None, 99) # constant using a Python keyword as a name (allowed) assert eval_arg('1+1') == 2 assert eval_arg('1+const') == 43 From 2721450ea779327dac67f682db30fa0c0266a928 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:10:00 +0200 Subject: [PATCH 06/11] tools: fix typos, grammar, punctuation --- tools/decode_s2.py | 4 ++-- tools/disassemble.py | 6 +++--- tools/genpkgjson.py | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/decode_s2.py b/tools/decode_s2.py index f25c5b0..01aff79 100644 --- a/tools/decode_s2.py +++ b/tools/decode_s2.py @@ -112,8 +112,8 @@ def twos_comp(val, bits): """ - compute the correct value of a 2's complement - based on the number of bits in the source + Compute the correct two's complement value + based on the number of bits in the source. """ if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255 val = val - (1 << bits) # compute negative value diff --git a/tools/disassemble.py b/tools/disassemble.py index 774771f..04d70cf 100644 --- a/tools/disassemble.py +++ b/tools/disassemble.py @@ -10,8 +10,8 @@ import sys -# placeholders: -# these functions will be dynamically loaded later based on the chosen cpu +# Placeholders: +# These functions will be dynamically loaded later based on the chosen CPU decode_instruction, get_instruction_fields = None, None @@ -21,7 +21,7 @@ def load_decoder(cpu): elif cpu == 'esp32s2': mod = 'decode_s2' else: - raise ValueError('Invalid cpu') + raise ValueError('Invalid CPU') relative_import = 1 if '/' in __file__ else 0 decode = __import__(mod, globals(), locals(), [], relative_import) diff --git a/tools/genpkgjson.py b/tools/genpkgjson.py index 7572f85..ceb383b 100644 --- a/tools/genpkgjson.py +++ b/tools/genpkgjson.py @@ -8,12 +8,12 @@ """ Tool for generating package.json for the MIP package manager -Run this tool from the repo root, like: +Run this tool from the repo root like this: python tools/genpkgjson.py > package.json Note: -This tool works with both python3 and micropyton. +This tool works with both Python 3 and MicroPython. """ import os @@ -38,9 +38,9 @@ def print_package_json(urls): """ Custom-formatting JSON output for better readability - json.dumps in MicroPython cannot format the output and python3 - puts each element of each urls' sub-arrays onto a new line. - Here we print each file and its source url onto the same line. + json.dumps in MicroPython cannot format the output, and Python 3 + puts each element of each URLs subarray on a new line. + Here we print each file and its source URL on the same line. """ print('{') print(f' "v":{PACKAGE_JSON_VERSION},') From 6ea30b8dcba3c7609b956ee820dfb5168386d821 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:12:14 +0200 Subject: [PATCH 07/11] CHANGES: fix typos, grammar, punctuation --- CHANGES | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 0d6b2b5..5a9c3f4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,14 +1,13 @@ -ChangeLog +Changelog ========= -1.2.0, release 2022-03-26 +1.2.0, released 2022-03-26 -- project moved to micropython organization -- project renamed from py-esp32-ulp to micropython-esp32-ulp -- (no functional changes) +- Project moved to the MicroPython organization. +- Project renamed from py-esp32-ulp to micropython-esp32-ulp. +- (No functional changes.) +1.1.0, released 2021-12-03 -1.1.0, release 2021-12-03 - -- first pypi release +- First PyPI release. From 6f969cea33fd5610085e95426615b0d6ac0ef09e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:14:36 +0200 Subject: [PATCH 08/11] demo: fix typos, grammar, punctuation --- demo.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demo.S b/demo.S index 0522924..d857870 100644 --- a/demo.S +++ b/demo.S @@ -27,7 +27,7 @@ textstart: ld r0, r1, 0 # a comment! rsh r0, r1, 42 move r0, r1 move r0, 42 - move r0, textstart # moves abs addr of textstart to r0 + move r0, textstart # Move the absolute address of textstart to r0 move r0, constant42 stage_rst stage_inc 42 @@ -70,10 +70,10 @@ data1: .space 4, 0x42 data2: .skip 4 dataw: .word 1, 2, 3, 4 datal: .long 1, 2, 3, 4 -datab: .byte 1, 2, 3 # test alignment / fill up of section +datab: .byte 1, 2, 3 # Test alignment and fill up the section dataend: .bss bss0: .skip 4 -bss1: .skip 2 # test alignment / fill up of section +bss1: .skip 2 # Test alignment and fill up the section bssend: From 64fb9741d2d7b3035ad3c0624f8b359efd1a7cbe Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:16:02 +0200 Subject: [PATCH 09/11] AUTHORS: fix typos, grammar, punctuation --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 15d0749..3ae1236 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -E-mail addresses listed here are not intended for support. +Email addresses listed here are not intended for support requests. micropython-esp32-ulp authors ----------------------------- From 56f50a757c0ea196ef7d83c8b23888c569f0452d Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:18:29 +0200 Subject: [PATCH 10/11] setup.py: fix typos, grammar, punctuation --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4eab8ff..3f268a2 100644 --- a/setup.py +++ b/setup.py @@ -14,10 +14,10 @@ def long_desc_from_readme(): with open('README.rst', 'r') as fd: long_description = fd.read() - # remove badges + # Remove badges. long_description = re.compile(r'^\.\. start-badges.*^\.\. end-badges', re.M | re.S).sub('', long_description) - # strip links. keep link name and use literal text formatting + # Strip links: keep the link text and use literal formatting. long_description = re.sub(r'`([^<`]+) ]+>`_', '``\\1``', long_description) return long_description From 9d137bbaf63d64e662a00f6ee3e6b38aa2633ad9 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 8 Oct 2025 02:23:47 +0200 Subject: [PATCH 11/11] .github: fix typos, grammar, punctuation --- .github/workflows/publish.yml | 8 ++++---- .github/workflows/run_tests.yaml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d541818..2b4ba05 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,11 +8,11 @@ name: Publish Python Package on: - # trigger when publishing a release + # Trigger when publishing a release. release: types: [published] - # also allow triggering this workflow manually for testing + # Also allow triggering this workflow manually for testing. workflow_dispatch: jobs: @@ -24,7 +24,7 @@ jobs: - name: Checkout uses: actions/checkout@v3 with: - # just fetching 1 commit is not enough for setuptools-scm, so we fetch all + # Fetching a single commit is not enough for setuptools-scm, so we fetch all commits. fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 @@ -36,7 +36,7 @@ jobs: - name: Build package run: | python setup.py sdist - rm dist/*.orig # clean sdist_upip noise + rm dist/*.orig # Remove sdist_upip noise. - name: Publish to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index bf54464..647f568 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -32,7 +32,7 @@ jobs: - name: Build MicroPython id: build_micropython run: | - echo "Building micropython" + echo "Building MicroPython" git clone --depth 1 https://github.com/micropython/micropython.git pushd micropython/mpy-cross make @@ -50,8 +50,8 @@ jobs: - name: Fetch binutils-esp32ulp id: fetch_binutils run: | - echo "Fetching URL of pre-built esp32ulp-elf binaries" - ## URL to pre-built binaries is published in esp-idf + echo "Fetching URL of prebuilt esp32ulp-elf binaries" + ## The URL to prebuilt binaries is published in ESP-IDF IDFVER=v5.0.1 curl -s \ -o tools.json \