Skip to content

Commit deba6f1

Browse files
committed
esp32: ULP and ADC improvements.
esp32/adc: Updated the module to use new driver (esp_adc). Tested and confired working on: - esp32 - esp32 C3 - esp32 S2 - esp32 S3 esp32/ulp: Enable RISCV ULP by default on targets which support it esp32 S2 & S3 have an option of reverting back to using the FSM in a custom build. Signed-off-by: Damian Nowacki (purewack) bobimaster15@gmail.com
1 parent 13a7877 commit deba6f1

File tree

10 files changed

+254
-114
lines changed

10 files changed

+254
-114
lines changed

docs/library/esp32.rst

Lines changed: 124 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ with each number, the bitstream is ``0101`` with durations of [100ns, 2000ns,
204204
For more details see Espressif's `ESP-IDF RMT documentation.
205205
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html>`_.
206206

207-
.. Warning::
207+
.. warning::
208208
The current MicroPython RMT implementation lacks some features, most notably
209209
receiving pulses. RMT should be considered a
210210
*beta feature* and the interface may change in the future.
@@ -300,34 +300,147 @@ Constants
300300
Ultra-Low-Power co-processor
301301
----------------------------
302302

303-
This class gives access to the Ultra Low Power (ULP) co-processor on the ESP32,
304-
ESP32-S2 and ESP32-S3 chips.
303+
This class gives access to the Finite State Machine (FSM) Ultra Low Power (ULP)
304+
co-processor on the ESP32, ESP32-S2 and ESP32-S3 chips. In addition the ESP32-S2
305+
and ESP32-S3 chips contain a RISCV co-processor which can be accessed through this
306+
class.
305307

306-
.. warning::
308+
.. note::
309+
By default RISCV is preferred on supported chips, however, you can configure a custom build
310+
of micropython to revert back to using the FSM ULP.
311+
Modify your mpconfigboard.cmake by specifying::
312+
313+
set(PREFER_FSM_ULP ON)
314+
315+
You can compile a custom board definition which uses the ULP and embeds the app image into the firmware.
316+
To do this, edit or create a board definition in the ports/esp32/boards folder.
317+
Make sure the mpconfigboard.cmake file has the following definition::
318+
319+
set(ulp_embedded_sources ${MICROPY_BOARD_DIR}/ulp/main_pin.c)
320+
# and optionally
321+
set(ulp_embedded_sources ${MICROPY_BOARD_DIR}/cmodules/somemodule.c)
322+
323+
When any sources are defined like this, the ULP code will be automatically added the the firmware.
324+
Any variables prefixed with *var_* will be automatically added to the ULP class and you can use them to reference a memory location for reading and writing
325+
326+
Example usage with embedded code::
327+
328+
import esp32
329+
u = esp32.ULP()
330+
u.run_embedded()
331+
print(u.read(u.VAR_TEST))
332+
333+
334+
Example usage with external code::
335+
336+
import esp32
337+
u = esp32.ULP()
338+
339+
with open("test.bin","rb") as file:
340+
buf = file.read()
341+
342+
u.run(buf)
343+
print(u.read(0x500000dc))
344+
345+
Example usage with external code (FSM)::
346+
347+
import esp32
348+
u = esp32.ULP()
349+
350+
with open("fsm.bin","rb") as file:
351+
buf = file.read()
352+
353+
u.run(0x1c,buf)
354+
print(u.write(0x500000dc, 42))
355+
356+
Example usage with embedded code using ADC1 channel 1 on ESP32 S3 (GPIO_2)::
357+
358+
import esp32
359+
u = esp32.ULP()
360+
361+
u.adc_init(1)
362+
u.set_wakeup_period(100)
363+
u.run_embedded()
364+
print(u.write(u.VAR_DO_ADC_SAMPLING, 1))
307365

308-
This class does not provide access to the RISCV ULP co-processor available
309-
on the ESP32-S2 and ESP32-S3 chips.
366+
.. note::
367+
Exposed variables are relative address offsets from RTC_SLOW_MEM address,
368+
369+
however you can use full address values also, if loading ULP code from outside the compilation process.
310370

311371
.. class:: ULP()
312372

313373
This class provides access to the Ultra-Low-Power co-processor.
314374

315375
.. method:: ULP.set_wakeup_period(period_index, period_us)
376+
ULP.set_wakeup_period(period_us)
316377

317-
Set the wake-up period.
378+
Set the wake-up period. Time specified in micro-seconds.
379+
*period_index* only on FSM.
380+
Since only one slot is used by the RISCV ULP, you only provide the time period in this function.
318381

319-
.. method:: ULP.load_binary(load_addr, program_binary)
382+
.. method:: ULP.run(entry_point, program_binary)
383+
ULP.run(program_binary)
320384

321-
Load a *program_binary* into the ULP at the given *load_addr*.
385+
Load a *program_binary* into the ULP and start from the beginning.
386+
*program_binary* should be a bytearray.
322387

323-
.. method:: ULP.run(entry_point)
388+
*entry_point is only used for FSM*
389+
Start the ULP running at the given *entry_point*, if applicable.
390+
391+
.. method:: ULP.pause()
392+
393+
Stop the ULP wakeup timer from triggering. On RISCV, the ULP will also be halted.
394+
395+
.. method:: ULP.resume()
396+
397+
Resume the ULP wakeup timer. On RISCV, the ULP will also be restarted.
398+
399+
.. method:: ULP.read(address)
400+
401+
Read the contents of RTC memory, specifying either an absolute address within the RTC range
402+
or use embedded variable constants, defined during compilation of firmware.
403+
404+
.. method:: ULP.write(address, value)
405+
406+
Write to the contents of RTC memory, specifying either an absolute address within the RTC range
407+
or use embedded variable constants, defined during compilation of firmware.
408+
409+
The function automatically prevents writing to any other location other than the RTC memory.
410+
411+
.. warning:: **Be careful** as you can overwrite the running ULP program instructions, requiring a reload.
412+
413+
414+
.. method:: ULP.rtc_init(pin_number)
415+
416+
Initialize the give GPIO pin number (different RTC_IO number on ESP32).
417+
418+
.. method:: ULP.rtc_deinit(pin_number)
419+
420+
Un-initialize the give GPIO pin number (different RTC_IO number on ESP32).
421+
422+
.. method:: ULP.adc_init(channel)
423+
424+
Prepare the ADC for use by the ULP on the specified RTC_IO *channel*.
425+
426+
.. note:: Only ADC1 is working with the current ESP-IDF used by MicroPython
427+
428+
.. method:: ULP.run_embedded()
429+
430+
This will load and run the embedded binary, exposing any variables onto the class, for reading and writing.
431+
432+
.. note:: Only available if firmware has compiled with a ULP program image
433+
Start the ULP running the embedded ULP app image.
324434

325-
Start the ULP running at the given *entry_point*.
326435

327436

328437
Constants
329438
---------
330439

440+
.. data:: ULP.RESERVE_MEM
441+
442+
The amount of reserved RTC_SLOW_MEM in bytes.
443+
331444
.. data:: esp32.WAKEUP_ALL_LOW
332445
esp32.WAKEUP_ANY_HIGH
333446

ports/esp32/adc.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
static esp_err_t ensure_adc_calibration(machine_adc_block_obj_t *self, adc_atten_t atten);
3535

3636

37-
esp_err_t apply_self_adc_channel_atten(const machine_adc_obj_t *self, uint8_t atten){
37+
esp_err_t apply_self_adc_channel_atten(const machine_adc_obj_t *self, uint8_t atten) {
3838
adc_oneshot_chan_cfg_t config = {
3939
.atten = atten,
4040
.bitwidth = self->block->bitwidth,
@@ -50,15 +50,15 @@ mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t chan
5050
}
5151

5252
/*
53-
During testing, it turned out that the function `adc_cali_raw_to_voltage` does not account for the lower resolution,
53+
During testing, it turned out that the function `adc_cali_raw_to_voltage` does not account for the lower resolution,
5454
instead it expects the full resolution value as an argument, hence the scaling applied here
5555
*/
5656
mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) {
5757
int raw = madcblock_read_helper(self, channel_id);
5858
int uv = 0;
5959

60-
check_esp_err(ensure_adc_calibration(self, atten));
61-
check_esp_err(adc_cali_raw_to_voltage(self->calib[atten], (raw << (ADC_WIDTH_MAX-self->bitwidth)), &uv));
60+
check_esp_err(ensure_adc_calibration(self, atten));
61+
check_esp_err(adc_cali_raw_to_voltage(self->calib[atten], (raw << (ADC_WIDTH_MAX - self->bitwidth)), &uv));
6262
return (mp_int_t)uv * 1000;
6363
}
6464

@@ -85,7 +85,6 @@ static esp_err_t ensure_adc_calibration(machine_adc_block_obj_t *self, adc_atten
8585
ret = adc_cali_create_scheme_line_fitting(&cali_config, &self->calib[atten]);
8686
#endif
8787

88-
88+
8989
return ret;
9090
}
91-

ports/esp32/adc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ typedef struct _machine_adc_obj_t {
7474
mp_obj_base_t base;
7575
machine_adc_block_obj_t *block;
7676
adc_channel_t channel_id;
77-
gpio_num_t gpio_id;
77+
gpio_num_t gpio_id;
7878
} machine_adc_obj_t;
7979

8080
extern machine_adc_block_obj_t madcblock_obj[];

ports/esp32/esp32_common.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ if(DEFINED ulp_embedded_sources)
217217
${ulp_depentants}
218218
"esp32_ulp.c"
219219
)
220-
message("embedded ULP App sources: " ${ulp_sources} ", deps: " ${ulp_depentants})
220+
message("embedded ULP App sources: " ${ulp_embedded_sources} ", deps: " ${ulp_depentants})
221221
ulp_embed_binary(${ulp_app_name} ${ulp_embedded_sources} ${ulp_depentants})
222222

223223
set(ULP_LD_DIR ${CMAKE_BINARY_DIR}/esp-idf/main_${IDF_TARGET}/ulp_embedded)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy