Use the target RC_FAST approximation for LP core delay conversion.
This prevents ESP32-S31 from under-delaying when running from RC_FAST.
Co-authored-by: Cursor <cursoragent@cursor.com>
On ESP32-S2/S3 the ULP-RISC-V ADC shares the RTC SAR controller with the
main CPU. ulp_adc_init() sets sar1_en_pad_force = 1 so software selects
the channel, but deep-sleep entry resets it to 0 (ULP/HW control). After
that, the per-read channel selection in ulp_riscv_adc_read_channel() is
ignored and every channel returns the same stale value. Single-channel
worked only because the channel never changed.
Re-assert RTC controller (sar1_en_pad_force = 1) before selecting the
channel on each read so multi-channel sampling works after deep sleep.
ulp_adc_init() could only configure a single ADC channel, so monitoring
several channels from the ULP on one ADC unit was not possible. Add
ulp_adc_multi_channel_init() to configure multiple channels with
per-channel attenuation while keeping the existing single-channel API
unchanged.
Closes https://github.com/espressif/esp-idf/issues/11160
Refactor the esp_err_to_name() system to decouple esp_common from
higher-level components. Instead of a monolithic generated table,
each component registers its error codes into a dedicated linker
section (.esp_err_msg_table) via idf_define_esp_err_codes() in its
CMakeLists.txt.
New files:
- tools/err_codes_extract.py: extract ESP_ERR_* defines from headers to CSV
- tools/err_codes_to_c.py: generate C source placing entries into linker section
- tools/err_codes_to_rst.py: generate RST documentation from error codes
- tools/cmake/err_codes.cmake: CMake module providing idf_define_esp_err_codes()
- components/esp_common/include/esp_err_codes.h: esp_err_msg_t typedef
- components/esp_common/src/esp_err_to_name_new.c: new lookup using link-time array
- tools/test_apps/build_system/err_codes_check/: CI test app
Changes:
- Remove all optional component dependencies from esp_common/CMakeLists.txt
- Add .esp_err_msg_table section to all 5 linker scripts
- Register error codes in 18 components via idf_define_esp_err_codes()
- Add new scripts to .gitlab/ci/rules.yml build_check patterns
- use new scripts to generate doc and add CI validation
- Update esp_err.rst to add description of composable code registration
The test was passing without real I2C communication due to a GPIO
mismatch (slave on GPIO 6/7 vs RTC I2C master on GPIO 2/3), single-byte
zero-coincidence, unchecked ULP return values, and an insufficient
RTC I2C timeout.
Fix slave GPIOs, increase test length, check I2C return values, add
proper assertions, and set an adequate RTC I2C timeout.
Co-authored-by: Cursor <cursoragent@cursor.com>
On SOC_LP_GPIO_MATRIX_SUPPORTED targets, use lp_gpio_matrix_input and
lp_gpio_matrix_output instead of lp_gpio_connect_* so matrix outputs use
rtcio_hal_matrix_out (LP GPIO IOMUX applied in HAL).
LP UART remapped pins: drop rtc_gpio_iomux_func_sel(pin, 1); rtc_gpio_init
already selects RTCIO_LL_PIN_FUNC.
Non-matrix LP I2C: select dedicated LP I2C RTC IOMUX via rtc_gpio_iomux_output
(same mux register write as rtc_gpio_iomux_func_sel; matches HAL naming for
peripheral-owned output enable on dedicated mux functions).
The configured maximum should match each target's fixed LP/RTC
reservations so menuconfig does not advertise values that the linker
cannot support.
Keep the linker failure explicit about CONFIG_ULP_COPROC_RESERVE_MEM
because application RTC sections still share the remaining LP/RTC RAM.
This allows rtc_gpio_deinit to always switch the pad back to GPIO,
regardless of lp io clock enabled or not, so that gpio_config can
always switch the IO back to GPIO use after wakeup from deep sleep.
fix(ulp/lp_core): fix LP UART data_bits validation and add full word-length test coverage
Closes PM-715, PM-660, IDFCI-10410, and IDFCI-10464
See merge request espressif/esp-idf!47432
Add LP SPI HAL LL layer for ESP32-S31 and ESP32-P4, enable the
peripheral in soc_caps, and port the HP-side and LP-core-side SPI
drivers to use the new LL abstraction.
The multi-device LP UART tests were failing on esp32p4 due to several
issues in the test harness:
- LP ROM boot banner: On chips with LP ROM (esp32p4), the LP core emits
a ROM banner on LP UART during startup, corrupting the first bytes of
test data. Set skip_lp_rom_boot=true in the ULP config for write, read
and mismatch tests to suppress this.
- Stale FIFO data: The HP UART RX FIFO could accumulate garbage during
pin mux setup. Add uart_flush_input() after HP UART driver installation
and before each read phase. Call lp_core_uart_clear_buf() before LP-side
read tests to flush the LP UART RX FIFO as well.
- Missing synchronization: The HP reader could start listening before
the LP transmitter was ready (or vice versa), causing data loss at
higher baud rates. Add signal exchange (unity_send_signal /
unity_wait_for_signal) to coordinate LP-to-HP data transfers.
- Short read timeout: The uart_read_bytes() timeout of 10 ms was too
aggressive for slower baud rates. Increase to 100 ms.
Made-with: Cursor
Several LP core pytest files were either hardcoded to specific chip lists
or using a less-precise SOC capability filter:
- test_lp_core_multi_device: was locked to ['esp32c6'] pending a workaround
for LP I2C on esp32p4; all three active LP core chips now have
SOC_LP_I2C_SUPPORTED=1, so switch to soc_filtered_targets.
- test_lp_uart_wakeup_modes: was using SOC_LP_CORE_SUPPORTED which is
semantically wrong for a UART test; change to SOC_ULP_LP_UART_SUPPORTED.
- LP core example pytests (build_system, interrupt, gpio_intr_pulse_counter,
lp_timer_interrupt): replace hardcoded ['esp32c5', 'esp32c6', 'esp32p4']
with soc_filtered_targets('SOC_LP_CORE_SUPPORTED == 1') so that new
chips automatically get coverage when their SOC cap is enabled.
Refactor the LP UART multi-device tests to use a single parameterised
helper pair (test_lp_uart_write_cfg / test_lp_uart_read_cfg) instead of
one-off functions per config, and extend coverage to:
- write and read tests for 5-, 6-, 7-bit and even-parity configurations
- negative tests: word-length mismatch (FRAM_ERR recovery on LP side,
garbled receive on HP side)
- LP GPIO Matrix routing tests (SOC_LP_GPIO_MATRIX_SUPPORTED chips only):
swaps the default TX/RX GPIO numbers so both pins go through the LP GPIO
Matrix, covering the lp_gpio_connect_in/out_signal() branch of
lp_uart_config_io() that was previously untested at the data-transfer
level; the same physical cross-wiring as all other LP UART tests is reused
Add rtc_gpio_deinit() cleanup at the end of single-board LP UART tests
so configured pins are returned to HP/digital mode and do not interfere
with subsequent tests that may reuse the same GPIOs.
lp_core_uart_set_pin() unconditionally configured the RTS and CTS GPIO
pins even when flow control was disabled. Only configure the RTS pin
when UART_HW_FLOWCTRL_RTS is set, and the CTS pin when
UART_HW_FLOWCTRL_CTS is set.
On chips with SOC_LP_GPIO_MATRIX_SUPPORTED (esp32p4, esp32s31), when the
default IOMUX pin is used for LP UART, calling rtc_gpio_iomux_func_sel()
alone only selects the IOMUX function on the pad side but does not set
sig_in_sel=0 on the peripheral side. This leaves the LP UART RX input
still reading from the LP GPIO Matrix (where no signal is connected),
causing RX to receive nothing.
Apply the same fix that was already in the HP UART driver: use
rtc_gpio_iomux_input() / rtc_gpio_iomux_output() which additionally
configure the peripheral to bypass the LP GPIO Matrix for IOMUX pins.