Compare commits

...

103 Commits

Author SHA1 Message Date
Jiang Jiang Jian
2bde2d8e30 Merge branch 'fix/usb-cdc-non-blocking-read_v5.2' into 'release/v5.2'
fix(esp_vfs_console): USB CDC read when non blocking (backport v5.2)

See merge request espressif/esp-idf!36748
2025-03-04 11:01:27 +08:00
Jiang Jiang Jian
33a97b8ea1 Merge branch 'fix/esp-event-profiling_v5.2' into 'release/v5.2'
fix(esp_event): Fix event loop profiling in handler_execute function (backport v5.2)

See merge request espressif/esp-idf!36691
2025-03-04 11:01:02 +08:00
Jiang Jiang Jian
4e30b88527 Merge branch 'fix/esp-log-put-function-in-iram_v5.2' into 'release/v5.2'
fix(log): Modified linker script to move functions from flash to iram (backport v5.2)

See merge request espressif/esp-idf!36668
2025-03-04 11:00:37 +08:00
Jiang Jiang Jian
511423cd2e Merge branch 'bugfix/storage_generic_pytests_v5.2' into 'release/v5.2'
fix(ci): Removed storage related entries in known generate test child pipeline warnings (v5.2)

See merge request espressif/esp-idf!36686
2025-03-04 11:00:24 +08:00
Alexey Gerenkov
f038c00a5b Merge branch 'fix/coredump_note_section_alignment_v5.2' into 'release/v5.2'
Fix/coredump note section headers and alignments (v5.2)

See merge request espressif/esp-idf!36882
2025-03-04 00:12:41 +08:00
Alexey Gerenkov
12901ff20b Merge branch 'fix/coredump_test_uart_data_missing_v5.2' into 'release/v5.2'
Fix missing coredump uart data in tests (v5.2)

See merge request espressif/esp-idf!36713
2025-03-04 00:12:14 +08:00
Jiang Jiang Jian
1e6a700601 Merge branch 'bugfix/check_ssid_before_sa_query_v5.2' into 'release/v5.2'
fix(esp_wifi): Check SSID from Assoc Req before starting SA Query (Backport v5.2)

See merge request espressif/esp-idf!37196
2025-03-03 17:14:34 +08:00
Sajia
f70b9ed99e fix(esp_wifi): Check SSID from Assoc Req before starting SA Query 2025-03-03 14:51:24 +08:00
Jiang Jiang Jian
590682f8c5 Merge branch 'fix/incorrect_console_open_and_close_behaviour_v5.2' into 'release/v5.2'
fix(storage/vfs_console): stop new console opens from overwriting existing fds (v5.2)

See merge request espressif/esp-idf!35269
2025-03-03 12:01:32 +08:00
Jiang Jiang Jian
d661664106 Merge branch 'fix/fix_ot_uart_init_bug_v5.2' into 'release/v5.2'
fix(openthread): fix a bug of openthread uart init port (v5.2)

See merge request espressif/esp-idf!37325
2025-03-03 12:00:06 +08:00
Jiang Jiang Jian
8385f47948 Merge branch 'feat/add_ot_br_lib_check_case_v5.2' into 'release/v5.2'
feat(openthread): add br library check case (v5.2)

See merge request espressif/esp-idf!36887
2025-03-03 11:56:46 +08:00
Jiang Jiang Jian
499dd676a9 Merge branch 'bugfix/h2_ble_timer_clk_enable_fix_v5.2' into 'release/v5.2'
fix: H2 ble timer clk enable issue. (v5.2)

See merge request espressif/esp-idf!36543
2025-03-03 11:56:20 +08:00
Jiang Jiang Jian
b60bf2c552 Merge branch 'feature/support_hw_reset_when_handling_rcp_failure_v5.2' into 'release/v5.2'
feat(openthread): support hardware reset RCP while processing RCP failure (v5.2)

See merge request espressif/esp-idf!36555
2025-03-03 11:55:11 +08:00
Jiang Jiang Jian
dc1e3c7265 Merge branch 'feat/add_callback_for_esp_ot_radio_spinel_init_v5.2' into 'release/v5.2'
feat(openthread): add an API to set rcp version string(v5.2)

See merge request espressif/esp-idf!36598
2025-03-03 11:54:20 +08:00
Jiang Jiang Jian
fa7be7cb3d Merge branch 'fix/ci_restart_avahi_daemon_v5.2' into 'release/v5.2'
fix(ci): restart avahi-daemon in otbr service discovery test case (v5.2)

See merge request espressif/esp-idf!36435
2025-03-03 11:54:00 +08:00
Jiang Jiang Jian
bd186a3fb0 Merge branch 'bugfix/ifdef_cplusplus_bracket_v5.2' into 'release/v5.2'
bugfix(wifi): Add missing brackets in the C++ guard (Backport v5.2)

See merge request espressif/esp-idf!36847
2025-03-03 11:52:08 +08:00
Jiang Jiang Jian
07f409ec8a Merge branch 'doc/add_wakeup_source_usage_precautions_v5.2' into 'release/v5.2'
change(doc): added more usage notes & warings about PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP (v5.2)

See merge request espressif/esp-idf!37393
2025-03-03 11:48:22 +08:00
Island
895e05db19 Merge branch 'bugfix/fix_blufi_crash_v5.2' into 'release/v5.2'
fix(blufi): Fixed crash issue during memcpy in example (v5.2)

See merge request espressif/esp-idf!36550
2025-03-03 11:32:06 +08:00
Island
d309e7c38a Merge branch 'feat/support_ble_debug_with_gpio_v5.2' into 'release/v5.2'
Support change HID task size by Kconfig in HID example (v5.2)

See merge request espressif/esp-idf!36997
2025-03-03 11:32:00 +08:00
Island
ba66243885 Merge branch 'bugfix/fix_ble_report_len_v5.2' into 'release/v5.2'
fix(ble/bluedroid): Fix adv data and scan rsp data not reported together in BLE active scan (v5.2)

See merge request espressif/esp-idf!37201
2025-03-03 11:31:56 +08:00
morris
95c55f68b5 Merge branch 'fix/usb_host_enum_unchecked_return_coverity_backport_v5.2' into 'release/v5.2'
fix(usb_host): Fixed unchecked return value in enum driver (coverity) (backport to v5.2)

See merge request espressif/esp-idf!36671
2025-03-03 10:56:01 +08:00
morris
86210328a7 Merge branch 'feat/add_temperature_calib_v5.2' into 'release/v5.2'
feat(temperature_sensor): Add temperature sensor calibration support(backport v5.2)

See merge request espressif/esp-idf!37315
2025-03-03 10:47:19 +08:00
akshat
6312c5eebe bugfix(wifi): Fix header file errors and remove esp_supplicant from check_public_headers_exceptions.txt 2025-03-02 17:07:46 +08:00
akshat
f7c0a60a32 bugfix(wifi): Add missing brackets in the C++ guard
Closes https://github.com/espressif/esp-idf/issues/14991
2025-03-02 17:07:46 +08:00
Rocha Euripedes
37b089ee8d Merge branch 'fix/test_app_certificate_v5.2' into 'release/v5.2'
Regenerate certificates for testing (v5.2)

See merge request espressif/esp-idf!36674
2025-03-02 17:00:35 +08:00
Euripedes Rocha
6e1423736e fix(mqtt): Regenerate certificates for testing
- Previous fix ommited one of the client certificates by mistaque.
- This regenerates all certificates to clean that up.
2025-03-02 16:51:21 +08:00
Rahul Tank
f1b3eab741 Merge branch 'bugfix/deprecate_link_estab_v5.2' into 'release/v5.2'
fix(nimble): Deprecate link_estab event (v5.2)

See merge request espressif/esp-idf!37059
2025-03-01 15:12:28 +08:00
Mahavir Jain
1beb0bcd79 Merge branch 'fix/fetch_image_hdr_v5.2' into 'release/v5.2'
fix(esp_system): Correct address used to fetch application image header (v5.2)

See merge request espressif/esp-idf!34629
2025-02-28 21:34:33 +08:00
morris
e6f49c0480 Merge branch 'feat/spi_std_timing_and_bit_trans_v5.2' into 'release/v5.2'
feat(driver_spi): support adjust master rx to standard timing (v5.2)

See merge request espressif/esp-idf!36401
2025-02-28 18:40:13 +08:00
morris
602fe5b9f4 Merge branch 'fix/spi_master_halt_using_rc_fast_v5.2' into 'release/v5.2'
fix(spi_master): fix spi halt when remove device who using rc_fast (v5.2)

See merge request espressif/esp-idf!37005
2025-02-28 18:37:52 +08:00
morris
2af2884ebd Merge branch 'fix/build_when_rom_patch_disable_v5.2' into 'release/v5.2'
fix(spi_flash): Fix build fail when rom_patch config disabled (backport v5.2)

See merge request espressif/esp-idf!37106
2025-02-28 18:00:23 +08:00
morris
d08c883ec3 Merge branch 'feat/mmu_find_paddr_caps_by_any_offset_v5.2' into 'release/v5.2'
mmu: supported find paddr caps by any paddr offset (v5.2)

See merge request espressif/esp-idf!36840
2025-02-28 17:59:56 +08:00
Roland Dobai
75a735fdc7 Merge branch 'fix/ci_upload_gdbinit_files_v5.2' into 'release/v5.2'
fix(ci): upload generated gdbinit files

See merge request espressif/esp-idf!37374
2025-02-28 17:36:52 +08:00
Wang Meng Yang
5670a06d83 Merge branch 'feat/add_vsc_to_support_test_v5.2' into 'release/v5.2'
feat(bt): add vendor hci command and event to support test (v5.2)

See merge request espressif/esp-idf!36569
2025-02-28 17:35:45 +08:00
Marius Vikhammer
b8e6e5389d Merge branch 'bugfix/remove_wdt_both_cpus_test_v5.2' into 'release/v5.2'
test(panic): remove WDT both CPU test (v5.2)

See merge request espressif/esp-idf!36622
2025-02-28 17:30:53 +08:00
wuzhenghui
7b100e98b7
change(doc): added more usage notes & warings about PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP 2025-02-28 16:47:40 +08:00
Roland Dobai
5e577dcd5a Merge branch 'fix/ldgen_interm_no_secs_v5.2' into 'release/v5.2'
fix(ldgen): don't emit intermediate placements without sections (v5.2)

See merge request espressif/esp-idf!36969
2025-02-28 16:08:50 +08:00
Roland Dobai
7de62b3c09 Merge branch 'fix/docker_qemu_seg_v5.2' into 'release/v5.2'
CI: Fixed docker build (v5.2)

See merge request espressif/esp-idf!37368
2025-02-28 16:08:36 +08:00
Mahavir Jain
e2dd6f8a6f Merge branch 'bugfix/memprot_s2_intr_peri1_v5.2' into 'release/v5.2'
fix(security): ESP32S2 memory protection check for Peri1 RTCSLOW interrupt (v5.2)

See merge request espressif/esp-idf!37119
2025-02-28 15:52:29 +08:00
Mahavir Jain
015e4f1b49 Merge branch 'feat/bootloader_nvs_read_encrypted_v5.2' into 'release/v5.2'
fix(esptool_py): NVS partition being incorrectly marked as encrypted by the build system (v5.2)

See merge request espressif/esp-idf!36681
2025-02-28 15:51:39 +08:00
Mahavir Jain
c1ef20b7f4 Merge branch 'bugfix/http_client_select_read_error_v5.2' into 'release/v5.2'
fix(tcp_tranport): Fix handling of select() return value (v5.2)

See merge request espressif/esp-idf!37256
2025-02-28 15:51:31 +08:00
Rahul Tank
172e5a317a fix(nimble): Keep only BLE_GAP_EVENT_CONNECT gap event 2025-02-28 13:14:41 +05:30
Rahul Tank
4459b5f44a Merge branch 'bugfix/fix_issues_18022005' into 'release/v5.2'
fix(nimble) : Fix few nimble issues v5.2

See merge request espressif/esp-idf!37071
2025-02-28 15:40:51 +08:00
Jiang Jiang Jian
11686940ae Merge branch 'bugfix/fix_cache_count_flash_pages_patchs_return_wrong_value_v5.2' into 'release/v5.2'
fix(rom): Fix s2 and s3 Cache_Count_Flash_Pages rom function wrapper (v5.2)

See merge request espressif/esp-idf!37157
2025-02-28 15:30:09 +08:00
Jiang Jiang Jian
28ebdd472d Merge branch 'fix/fix_bad_dslp_param_after_lightsleep_v5.2' into 'release/v5.2'
fix(esp_hw_support): Fixed the issue that light sleep destroyed the parameters of subsequent deep sleep (v5.2)

See merge request espressif/esp-idf!37304
2025-02-28 15:25:33 +08:00
Jiang Jiang Jian
d6c2868bcd Merge branch 'fix/add_sleep_duration_check_for_timer_wakeup_v5.2' into 'release/v5.2'
fix(esp_hw_support): add timer wakeup sleep duration check (v5.2)

See merge request espressif/esp-idf!37012
2025-02-28 15:24:54 +08:00
Jiang Jiang Jian
2dd257d162 Merge branch 'fix/fix_s2_s3_rtc_iomux_clock_management_v5.2' into 'release/v5.2'
fix(esp_hw_support): fix esp32s2/esp32s3 RTC IOMUX clock management (v5.2)

See merge request espressif/esp-idf!37168
2025-02-28 15:24:28 +08:00
Alexey Lapshin
90120f30e1 fix(ci): upload generated gdbinit files 2025-02-28 10:27:31 +07:00
Roland Dobai
548c6a2f38 ci(github): Fixed docker build caused by Qemu segmentation fault
Works around issue from
https://github.com/espressif/esp-idf/actions/runs/13531037397/job/37813060700
caused by Qemu segmentation fault.

    Errors were encountered while processing: libc-bin

The workaround is from https://github.com/docker/setup-qemu-action/issues/198.
2025-02-27 13:05:19 +01:00
C.S.M
9c4b822ab1 feat(temperature_sensor): Add temperature sensor calibration support 2025-02-27 18:31:05 +08:00
Xu Si Yu
dc00dd37dc fix(openthread): fix a bug of openthread uart init port 2025-02-27 15:43:29 +08:00
zhanghaipeng
0efea66c6d fix(ble): Update bt lib for ESP32(2a2631f)
- Support ESP32 BLE GPIO DEBUG
2025-02-27 14:56:58 +08:00
wuzhenghui
b2c8dcacb0
fix(esp_hw_support): fix lightsleep destroys deepsleep rtc parameters 2025-02-26 16:57:41 +08:00
nilesh.kale
d09f48c97b fix(tcp_tranport): Fix handling of select() return value
When both readset/writeset and errset are set for a single socket,
the HTTP client incorrectly handled the condition, causing premature termination.
Added a check to ensure readset/writeset is prioritized before errset.

Closes https://github.com/espressif/esp-idf/issues/14673
2025-02-25 13:29:40 +05:30
zhanghaipeng
0fcca4ec3c fix(ble): Update bt lib for ESP32(194dd63)
- Fix the issue where disconnection events were not reported as a slave.
- Enhance Access Address validation in compatibility mode.
2025-02-23 17:44:29 +08:00
gongyantao
4f8f92aa2d feat(bt): add vendor hci command and event to support test
- add afh related vendor hci command and event
- add vendor event mask command
2025-02-23 17:44:29 +08:00
linruihao
6eaf8815db feat(bt): add coexist scheme status support for bt page 2025-02-23 17:44:29 +08:00
Zhang Hai Peng
339b829126 fix(ble/bluedroid): Fix adv data and scan rsp data not reported together in BLE active scan
(cherry picked from commit 7f2cedc0488fe30316b7c6a45be1c8933ad36952)

Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
2025-02-21 16:13:40 +08:00
wuzhenghui
aff8ad355b
fix(esp_hw_support): fix esp32s2/esp32s3 RTC IOMUX clock management 2025-02-21 10:18:27 +08:00
wuzhenghui
6ed9e39ffa
fix(esp_driver_gpio): manage lp_io module clock by driver
Closes https://github.com/espressif/esp-idf/issues/13683
2025-02-20 19:46:22 +08:00
Tomasz Kramkowski
84a162aba7 fix(rom): Fix s2 and s3 Cache_Count_Flash_Pages rom function wrapper
The rom function on the s2 and s3 only counts one page for any pages
which are mapped to page 0 of flash as the Cache_Flash_To_SPIRAM_Copy
function attempts to map all flash page 0 mapped pages to one PSRAM
page.

As this function can be called for multiple regions, it needs to track
if a page mapped to page 0 has previously been accounted for by a
previous call. It does this using the page0_mapped in-out parameter.
This logic contains an error:

```
if (*page0_mapped == 0) {
    // BUG: If page0_count is 0, 1 is still added
    count = valid_flash_count + 1 - page0_count;
} else {
    count = valid_flash_count - page0_count;
}
*page0_mapped += page0_count;
return count;
```

The current Cache_Count_Flash_Pages wrapper in the idf attempts to
compensate for this bug by checking if the page0_mapped parameter was
changed by a call to the function and reducing the count if it has not.

This, however, will incorrectly over-compensate in situations where the
initial value of page0_mapped was not zero as the code above only
miscounts when it was zero.

This patch addresses the issue in this wrapper function by correctly
compensating for the bug only in cases where the final page0_mapped
value is 0.
2025-02-20 16:11:08 +08:00
Martin Vychodil
671dc31a32 fix(security): Fixed ESP32S2 memory protection check for Peri1 RTCSLOW interrupt
- fixes the issue found in https://github.com/espressif/esp-idf/issues/15359
- extends debug printouts in the related tests
2025-02-19 19:26:21 +01:00
C.S.M
084cb924f2 refactor(spi_flash): remove redundent flash suspend check 2025-02-19 16:59:30 +08:00
C.S.M
60b8013bc3 fix(spi_flash): Fix build fail when rom_patch config disabled,
Closes https://github.com/espressif/esp-idf/issues/15229
2025-02-19 16:58:59 +08:00
Abhinav Kudnar
475ef1bb53 fix(nimble): Save the gatt context in case of preemption 2025-02-18 17:04:34 +05:30
wanlei
1c93d41325 fix(spi_master): fix spi halt when remove device who using rc_fast 2025-02-18 11:29:04 +08:00
wuzhenghui
5e81eb6cf7
fix(esp_hw_support): add timer wakeup sleep duration check
Closes https://github.com/espressif/esp-idf/issues/15255
2025-02-17 19:57:11 +08:00
Mitch Cairns
72c86ba35c feat(ble/bluedroid): Support change HID task size by Kconfig in HID example 2025-02-17 11:28:48 +08:00
Zhang Hai Peng
691f9131fc docs(ble/bluedroid): Optimize doc for implementation of a characteristic with 128 bit UUID
(cherry picked from commit fa40d971a52e9eb66686ac3ae645fca2589f0807)

Co-authored-by: Erast  <78802792+MatoiDev@users.noreply.github.com>
2025-02-17 11:15:03 +08:00
Zhang Hai Peng
72527f85ea fix(ble/bluedroid): Don't log error on 16/128-bit UUID mixed descriptors
(cherry picked from commit fed1d41aa7170d8418dd126dd8e3b47a977b4aca)

Co-authored-by: Nebojša Cvetković <nebkat@gmail.com>
2025-02-17 11:15:01 +08:00
Zhang Hai Peng
af002606a7 refactor(ble/bluedroid): Fix typos in gatt_sr.c
(cherry picked from commit 63b2dcc3a7b4b56486a7ef82050d8a43dd2bb4af)

Co-authored-by: Nebojsa Cvetkovic <nebkat@gmail.com>
2025-02-17 11:14:58 +08:00
Zhang Hai Peng
be13df1104 fix(ble/bluedroid): Allow 0 length indications
(cherry picked from commit 9b5a52e2f784a50c0e4c1a422a2b3d22ce5e9998)

Co-authored-by: Nebojsa Cvetkovic <nebkat@gmail.com>
2025-02-17 11:14:54 +08:00
Zhang Hai Peng
d096dc7cbe refactor(ble/bluedroid): Fix typos in bta_gatts_act.c
(cherry picked from commit a8041a99533628b044a8158bcc4410404f83ea63)

Co-authored-by: Nebojsa Cvetkovic <nebkat@gmail.com>
2025-02-17 11:14:51 +08:00
Zhang Hai Peng
bdef0e0cb4 fix(coredump): only clear high bit in PC when set
(cherry picked from commit eaefd0bd25862fcc7d98c95fbc1f1f0c6a48dca7)

Co-authored-by: Erhan Kurubas <erhan.kurubas@espressif.com>
2025-02-17 11:14:48 +08:00
Frantisek Hrbata
9a1eef2ccc fix(ldgen): don't emit intermediate placements without sections
When a symbol needs to be placed to a different target than the one
designated for the object file, the object file is expanded, which
includes the following steps:

1. Creating a new placement for the symbol's input section with the
   specified target.
2. Excluding the object placement from the orignal target.
3. Creating a new intermediate placement for the object for the original
   target, where its input sections are expanded, excluding the input
   section for the symbol.

Let's illustrate the object expansion process with the following example:

[sections:rodata]
entries:
    .rodata+
    .sdata2+
    .srodata+

[scheme:default]
entries:
    text -> flash_text
    rodata -> flash_rodata

[scheme:noflash]
entries:
    text -> iram0_text
    rodata -> dram0_data

[mapping:soc_pm]
archive: libsoc.a
entries:
    gpio_periph: GPIO_HOLD_MASK (noflash)

gpio_periph section headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000000 00  AX  0   0  2
  [ 2] .data             PROGBITS        00000000 000034 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 000034 000000 00  WA  0   0  1
  [ 4] .rodata.GPIO_HOLD_MASK PROGBITS        00000000 000034 000058 00   A  0   0  4
  [ 5] .rodata.GPIO_PIN_MUX_REG PROGBITS        00000000 00008c 000058 00   A  0   0  4
  [ 6] .debug_info       PROGBITS        00000000 0000e4 0000d8 00      0   0  1
  [ 7] .rela.debug_info  RELA            00000000 0009d4 000108 0c   I 16   6  4
  [ 8] .debug_abbrev     PROGBITS        00000000 0001bc 000070 00      0   0  1
  [ 9] .debug_aranges    PROGBITS        00000000 00022c 000018 00      0   0  1
  [10] .rela.debug_aranges RELA            00000000 000adc 00000c 0c   I 16   9  4
  [11] .debug_line       PROGBITS        00000000 000244 0001ab 00      0   0  1
  [12] .debug_str        PROGBITS        00000000 0003ef 00022d 01  MS  0   0  1
  [13] .comment          PROGBITS        00000000 00061c 000030 01  MS  0   0  1
  [14] .note.GNU-stack   PROGBITS        00000000 00064c 000000 00      0   0  1
  [15] .riscv.attributes RISCV_ATTRIBUTES 00000000 00064c 000044 00      0   0  1
  [16] .symtab           SYMTAB          00000000 000690 000260 10     17  36  4
  [17] .strtab           STRTAB          00000000 0008f0 0000e1 00      0   0  1
  [18] .shstrtab         STRTAB          00000000 000ae8 0000d1 00      0   0  1

1. Creating a new placement
.dram0.data :
{
    *libsoc.a:gpio_periph.*(.rodata.GPIO_HOLD_MASK .sdata2.GPIO_HOLD_MASK .srodata.GPIO_HOLD_MASK)
}

2. Excluding the object placement
.flash.rodata :
{
    *(EXCLUDE_FILE(*libsoc.a:gpio_periph.*) .rodata.* ...)
}

3. Creating a new intermediate placement
.flash.rodata :
{
    *libsoc.a:gpio_periph.*(.rodata.GPIO_PIN_MUX_REG)
}

Now, let's do the same, but also move GPIO_PIN_MUX_REG to noflash with an updated mapping.

[mapping:soc_pm]
archive: libsoc.a
entries:
    gpio_periph: GPIO_HOLD_MASK (noflash)
    gpio_periph: GPIO_PIN_MUX_REG (noflash)

1. Creating a new placement
.dram0.data :
{
    *libsoc.a:gpio_periph.*(.rodata.GPIO_HOLD_MASK .sdata2.GPIO_HOLD_MASK .srodata.GPIO_HOLD_MASK)
    *libsoc.a:gpio_periph.*(.rodata.GPIO_PIN_MUX_REG .sdata2.GPIO_PIN_MUX_REG
                            .srodata.GPIO_PIN_MUX_REG)
}

2. Excluding the object placement
.flash.rodata :
{
    *(EXCLUDE_FILE(*libsoc.a:gpio_periph.*) .rodata.* ...)
}

3. Creating a new intermediate placement
.flash.rodata :
{
    *libsoc.a:gpio_periph.*
}

The *libsoc.a:gpio_periph.* entity in step 3 no longer has input
sections, as there are no remaining .rodata input sections in the object
file. The linker behavior for this mapping is to include all object
input sections that have not yet been placed as described in
https://sourceware.org/binutils/docs/ld.html#Input-Section-Basics
"If you use a file name without a list of sections, then all sections in
the input file will be included in the output section. This is not
commonly done, but it may by useful on occasion."

The map file for such mapping now contains following input sections

 .flash.rodata   0x3c0a0120    0x19b34
     *libsoc.a:gpio_periph.*()
     .debug_info    0x3c0b95bf       0xd8 esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .debug_abbrev  0x3c0b9697       0x70 esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .debug_aranges
                    0x3c0b9707       0x18 esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .debug_line    0x3c0b971f      0x1ab esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .debug_str     0x3c0b98ca      0x21a esp-idf/soc/libsoc.a(gpio_periph.c.obj)
                                    0x22d (size before relaxing)
     .comment       0x3c0b9ae4       0x30 esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .note.GNU-stack
                    0x3c0b9ae4        0x0 esp-idf/soc/libsoc.a(gpio_periph.c.obj)
     .riscv.attributes
                    0x3c0b9ae4       0x44 esp-idf/soc/libsoc.a(gpio_periph.c.obj)

This is incorrect, and such intermediate placement should not be
generated. This type of placement can be recognized because it is not
explicitly defined in the mapping and lacks input sections. We can
identify this in the significant function and prevent issuing commands
for such placement.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2025-02-14 12:18:23 +01:00
Laukik Hase
b216535f73
fix(esp_system): Correct address used to fetch application image header 2025-02-14 16:38:56 +05:30
yiwenxiu
19531e2166 feat(openthread): add br library check case 2025-02-12 09:34:02 +08:00
Erhan Kurubas
7aa691aaff fix(coredump): fix note section alignments 2025-02-11 17:00:12 +01:00
Erhan Kurubas
f5363a3f7a fix(coredump): only clear high bit in PC when set 2025-02-11 16:53:56 +01:00
Armando
771bbf2f63 test(mmu): test can find paddr caps by any paddr offset 2025-02-11 15:57:25 +08:00
zhanghaipeng
bf50c0c197 fix(blufi): Enhance security in BLUFI example 2025-02-11 15:25:08 +08:00
Armando
caca62543b feat(mmu): supported find paddr caps by any paddr offset
Closes https://github.com/espressif/esp-idf/issues/14988
2025-02-11 10:04:34 +08:00
David Cermak
fddc0baced fix(esp_eth): Fix test code to unregister event correctly 2025-02-10 09:47:01 +01:00
David Cermak
bcf635dcd5 fix(esp_event): Fix minor no-ISR post regression
from 15f6775f5d5bd9ee73072e914118024d15b685eb
2025-02-10 09:47:00 +01:00
Geng Yuchao
55f1ac37cc fix(esp32h2): H2 ble timer clk enable issue 2025-02-07 11:46:01 +08:00
radek.tandler
791003ea7f fix(nvs_partition_gen): Fixed sporadic failure of encryption keys 2025-02-06 15:22:38 +01:00
radek.tandler
91e0e36ffe fix(storage/nvs): Fixed failing test cases in example folder 2025-02-06 15:22:38 +01:00
radek.tandler
cacc13873d fix(storage/vfs): Fixed failing test cases in test_apps 2025-02-06 15:22:33 +01:00
Guillaume Souchere
567469dd27 fix(esp_vfs_console): USB CDC read when non blocking
In non blocking mode, the read function is expected
to return weather data is available for reading or not.

In case data are available but the size does not match
the expected size, the function read should return whatever
data is available.

Previously, the function was returning -1 with errno set
to EWOULDBLOCK even if the size of data in the buffer was
less than the requested size. It would only return the
available data if the size in the buffer was greater or equal
to the requested size.

The implementation of cdcacm_read is modified to return the avilable
data from the buffer even is the size is lesser than the requested
size.
2025-02-06 08:57:38 +01:00
Erhan Kurubas
6465aef894 ci(coredump): collect all expected uart data first, then process lazily 2025-02-03 15:18:19 +01:00
Guillaume Souchere
0938688e9b fix(esp_event): Handler unregistration by itself issue
when esp_event_handler_unregister_with_internal cannot take
the loop mutex (e.g., when the handler unregisters itself),
create an event with a special base identifier and add it to
the queue of the corresponding loop to postpone the removal
of the handler from the list at a time when the loop mutex can be
successfully taken.
2025-01-30 10:52:30 +01:00
Guillaume Souchere
d1a02e1854 fix(esp_event): Fix event loop profiling in handler_execute function
handler_execute function is looking to match the handler only in the
list of loop events but does not look in the base event handler list
nor the id event handler list. So unless the event handler is
registered to be triggered for all event bases and all event ids of
an event loop, its profiling fields (invoked and time) are not updated
when it is called.

This commit updates the search for the matching handler to also look
in base event list and ID event list.

Closes https://github.com/espressif/esp-idf/issues/15041
2025-01-30 10:51:38 +01:00
radek.tandler
0c69545f30 fix(ci): Removed storage related ignore warnings 2025-01-30 09:42:26 +01:00
harshal.patil
98285d819b
fix(esptool_py): Fix NVS partition being incorrectly marked as encrypted
- The CMake function esptool_py_partition_needs_encryption() in the esptool_py
component used to mark NVS partition as encrypted, instead it should have marked
the NVS keys partition as encrypted.
2025-01-30 12:03:18 +05:30
Roman Leonov
44f09c470b fix(usb_host): Fixed unchecked return value in enum driver (coverity) 2025-01-29 12:56:02 +01:00
Cristian Funes
c11e4ad3c4 fix(log): Modified linker script to move functions from flash to iram 2025-01-29 10:44:57 +01:00
Marius Vikhammer
d9c471d054 test(panic): remove WDT both CPU test
Test never worked on S3/P4 and was flakey on ESP32. Hard to design a reliable test
case that triggers both WDT at the exact same time.
2025-01-24 13:29:45 +01:00
Tomáš Rohlínek
0214e29fc3 fix(storage/vfs_console): stop new console opens from overwriting existing fds 2025-01-24 14:58:15 +08:00
Xu Si Yu
b83535a889 feat(openthread): add an API to set rcp version string 2025-01-24 10:51:30 +08:00
zwx
07425e242c feat(openthread): support hardware reset RCP while processing RCP failure 2025-01-22 17:12:33 +08:00
Zhang Hai Peng
e65cf7ea2a fix(blufi): Fixed some security issue in blufi example
(cherry picked from commit abc18e93eb3500dbec74c3e589671ef82c8b3919)

Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
2025-01-22 16:34:30 +08:00
wanckl
65a616197f feat(driver_spi): support using SPI_DEVICE_STD_TIMING to adjust master rx in standard timing 2025-01-22 11:11:47 +08:00
zwx
333d4fee6f fix(ci): restart avahi-daemon in otbr service discovery test case 2025-01-21 11:25:21 +08:00
193 changed files with 2919 additions and 935 deletions

View File

@ -60,7 +60,9 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU for multiarch builds
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
with:
image: tonistiigi/binfmt:qemu-v7.0.0-28
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push

View File

@ -76,4 +76,8 @@ void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -490,6 +490,15 @@ config BTDM_BLE_VS_QA_SUPPORT
help
This enables BLE vendor HCI command and event for QA.
config BTDM_CTRL_CONTROLLER_DEBUG_MODE_1
bool "Enable Bluetooth controller debugging mode 1 (for internal use only)" if n
default n
depends on BT_ENABLED
help
Enables specific debugging features for the Bluetooth controller.
This option is strictly for internal debugging purposes and should not be enabled in production environments,
as it may impact performance and stability.
config BTDM_RESERVE_DRAM
hex
default 0xdb5c if BT_ENABLED

@ -1 +1 @@
Subproject commit 35fb599d3733f50254c056171edebcaa3c57d06b
Subproject commit 6093909e01930f8cda6f60510f8a412c6d1814e8

View File

@ -723,8 +723,6 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
} else {
APPL_TRACE_ERROR("%s, malloc failed", __func__);
}
} else {
APPL_TRACE_ERROR("%s, incorrect length", __func__);
}
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
if (cb_data.req_data.value != NULL) {
@ -733,7 +731,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
}
}
} else {
APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
APPL_TRACE_ERROR("Not a registered service attribute ID: 0x%04x",
p_msg->api_indicate.attr_id);
}
}
@ -923,7 +921,7 @@ void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
**
** Function bta_gatts_show_local_database
**
** Description print loacl service database
** Description print local service database
**
** Returns none.
**

View File

@ -18,7 +18,7 @@
/******************************************************************************
*
* This is the public interface file for the simulatenous advanced
* This is the public interface file for the simultaneous advanced
* audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth
* application layer for mobile phones.
*
@ -35,6 +35,10 @@
#if (BTA_AR_INCLUDED == TRUE)
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
** Constants and data types
*****************************************************************************/

View File

@ -23,6 +23,9 @@
#include "stack/a2d_sbc.h"
#if (BTC_AV_INCLUDED == TRUE)
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
** Constants and data types
*****************************************************************************/

View File

@ -4003,7 +4003,6 @@ static void btm_ble_stop_discover(void)
if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
/* Clear the inquiry callback if set */
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
btm_cb.ble_ctr_cb.inq_var.state &= ~BTM_BLE_SCANNING;
/* stop discovery now */
if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) {

View File

@ -200,7 +200,7 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status,
*p++ = GATT_RSP_READ_MULTI;
p_buf->len = 1;
/* Now walk through the buffers puting the data into the response in order */
/* Now walk through the buffers putting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@ -321,7 +321,7 @@ static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS sta
*p++ = GATT_RSP_READ_MULTI_VAR;
p_buf->len = 1;
/* Now walk through the buffers puting the data into the response in order */
/* Now walk through the buffers putting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@ -735,7 +735,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
handle_len = 4 + p_uuid->len;
}
/* get the length byte in the repsonse */
/* get the length byte in the response */
if (p_msg->offset == 0) {
*p ++ = op_code + 1;
p_msg->len ++;
@ -788,7 +788,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
** buffer.
**
** Returns TRUE: if data filled successfully.
** FALSE: packet full, or format mismatch.
** FALSE: packet full.
**
*******************************************************************************/
static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len,
@ -831,10 +831,9 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg,
gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid);
p += LEN_UUID_128;
} else {
GATT_TRACE_ERROR("format mismatch");
status = GATT_NO_RESOURCES;
// UUID format mismatch in sequential attributes
// A new request will be sent with the starting handle of the next attribute
break;
/* format mismatch */
}
p_msg->len += info_pair_len[p_msg->offset - 1];
len -= info_pair_len[p_msg->offset - 1];
@ -889,7 +888,7 @@ static tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len,
/* parse uuid now */
if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE ||
p_uuid_filter->len == 0) {
GATT_TRACE_DEBUG("UUID filter does not exsit");
GATT_TRACE_DEBUG("UUID filter does not exist");
reason = GATT_INVALID_PDU;
} else {
len -= p_uuid_filter->len;
@ -1042,7 +1041,7 @@ static void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
**
** Function gatts_process_mtu_req
**
** Description This function is called to process excahnge MTU request.
** Description This function is called to process exchange MTU request.
** Only used on LE.
**
** Returns void
@ -1055,7 +1054,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
BT_HDR *p_buf;
UINT16 conn_id;
/* BR/EDR conenction, send error response */
/* BR/EDR connection, send error response */
if (p_tcb->att_lcid != L2CAP_ATT_CID) {
gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE);
} else if (len < GATT_MTU_REQ_MIN_LEN) {
@ -1081,7 +1080,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
attp_send_sr_msg (p_tcb, p_buf);
/* Notify all registered application with new MTU size. Us a transaction ID */
/* of 0, as no response is allowed from applcations */
/* of 0, as no response is allowed from applications */
for (i = 0; i < GATT_MAX_APPS; i ++) {
if (gatt_cb.cl_rcb[i].in_use ) {
@ -1448,7 +1447,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand
}
if ((prepare_record->error_code_app == GATT_SUCCESS)
// update prepare write status for excute write request
// update prepare write status for execute write request
&& (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) {
prepare_record->error_code_app = status;
}
@ -1855,7 +1854,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
break;
case GATT_REQ_FIND_INFO: /* discover char descrptor */
case GATT_REQ_FIND_INFO: /* discover char descriptor */
gatts_process_find_info(p_tcb, op_code, len, p_data);
break;

View File

@ -1058,6 +1058,15 @@ config BT_NIMBLE_HOST_QUEUE_CONG_CHECK
or application layer handling adv packets is slow, it will cause the controller memory
to run out. if enabled, adv packets will be lost when host queue is congested.
config BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
bool "Gatt-proc preemption protect check"
depends on BT_NIMBLE_ENABLED
default n
help
When BLE and Wireless protocol/IEEE 802.15.4 operate in coexistence, BLE preemption
can disrupt the GATT context,causing the service discovery callback to not be invoked.
A temporary list is maintained to preserve the GATT context and use it in case of preemption.
menu "Host-controller Transport"
config BT_NIMBLE_TRANSPORT_UART
bool "Enable Uart Transport"

@ -1 +1 @@
Subproject commit c42b505ac5442da027d0cb7738a4a1850a09edc7
Subproject commit 553fe4598c6585b2288e6b255604a63b1e6f8485

View File

@ -1942,6 +1942,14 @@
#endif
#endif
#ifndef MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT
#ifdef CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT
#else
#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT (0)
#endif
#endif
#ifndef MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN
#ifdef CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN
#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN

View File

@ -205,6 +205,16 @@ the adv packet will be discarded until the memory is restored. */
#define BTDM_BLE_CHAN_ASS_EN (0)
#endif
#if CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1
#define BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 (1 << 1)
#else
#define BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 0
#endif
#ifndef BTDM_CTRL_CONTROLLER_DEBUG_FLAG
#define BTDM_CTRL_CONTROLLER_DEBUG_FLAG (BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 | CONTROLLER_ADV_LOST_DEBUG_BIT)
#endif
#if defined(CONFIG_BTDM_BLE_PING_EN)
#define BTDM_BLE_PING_EN (CONFIG_BTDM_BLE_PING_EN)
#else
@ -224,7 +234,7 @@ the adv packet will be discarded until the memory is restored. */
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
.controller_debug_flag = BTDM_CTRL_CONTROLLER_DEBUG_FLAG, \
.mode = BTDM_CONTROLLER_MODE_EFF, \
.ble_max_conn = CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF, \
.bt_max_acl_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF, \

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -23,6 +23,7 @@
#include "hal/gpio_hal.h"
#include "esp_rom_gpio.h"
#include "esp_private/esp_gpio_reserve.h"
#include "esp_private/io_mux.h"
#if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h"
@ -632,6 +633,11 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
#if SOC_RTCIO_WAKE_SUPPORTED
if (rtc_gpio_is_valid_gpio(gpio_num)) {
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
// LP_IO Wake-up function does not depend on LP_IO Matrix, but uses its clock to
// sample the wake-up signal, we need to enable the LP_IO clock here.
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
ret = rtc_gpio_wakeup_enable(gpio_num, intr_type);
}
#endif
@ -657,6 +663,9 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num)
#if SOC_RTCIO_WAKE_SUPPORTED
if (rtc_gpio_is_valid_gpio(gpio_num)) {
ret = rtc_gpio_wakeup_disable(gpio_num);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, false);
#endif
}
#endif
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
@ -984,6 +993,9 @@ esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t int
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type);
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
@ -1002,6 +1014,9 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)
gpio_hal_deepsleep_wakeup_disable(gpio_context.gpio_hal, gpio_num);
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
#endif
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, false);
#endif
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
return ESP_OK;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,6 +8,8 @@
#include "esp_log.h"
#include "esp_err.h"
#include "esp_check.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/io_mux.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
@ -45,6 +47,9 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
RTCIO_ENTER_CRITICAL();
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_enable_lp_io_clock(gpio_num, true);
#endif
rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC);
RTCIO_EXIT_CRITICAL();
@ -57,6 +62,10 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
RTCIO_ENTER_CRITICAL();
// Select Gpio as Digital Gpio
rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
io_mux_force_disable_lp_io_clock(gpio_num);
#endif
RTCIO_EXIT_CRITICAL();
return ESP_OK;

View File

@ -423,8 +423,12 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
spi_hal_timing_conf_t temp_timing_conf;
int freq;
esp_err_t ret = spi_hal_cal_clock_conf(&timing_param, &freq, &temp_timing_conf);
temp_timing_conf.clock_source = clk_src;
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
temp_timing_conf.clock_source = clk_src;
temp_timing_conf.rx_sample_point = dev_config->sample_point;
if (temp_timing_conf.rx_sample_point == SPI_SAMPLING_POINT_PHASE_1) {
SPI_CHECK(spi_ll_master_is_rx_std_sample_supported(), "SPI_SAMPLING_POINT_PHASE_1 is not supported on this chip", ESP_ERR_NOT_SUPPORTED);
}
//Allocate memory for device
dev = malloc(sizeof(spi_device_t));
@ -513,6 +517,15 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
#if SOC_SPI_SUPPORT_CLK_RC_FAST
if (handle->cfg.clock_source == SPI_CLK_SRC_RC_FAST) {
// If no transactions from other device, acquire the bus to switch module clock to `SPI_CLK_SRC_DEFAULT`
// because `SPI_CLK_SRC_RC_FAST` will be disabled then, which block following transactions
if (handle->host->cur_cs == DEV_NUM_MAX) {
spi_device_acquire_bus(handle, portMAX_DELAY);
SPI_MASTER_PERI_CLOCK_ATOMIC() {
spi_ll_set_clk_source(handle->host->hal.hw, SPI_CLK_SRC_DEFAULT);
}
spi_device_release_bus(handle);
}
periph_rtc_dig_clk8m_disable();
}
#endif

View File

@ -77,6 +77,7 @@ typedef struct {
delay before the MISO is ready on the line. Leave at 0 unless you know you need a delay. For better timing
performance at high frequency (over 8MHz), it's suggest to have the right value.
*/
spi_sampling_point_t sample_point; ///< Sample point tuning of spi master receiving bit.
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time

View File

@ -1,5 +1,5 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -111,7 +111,18 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
// Currently calibration is not supported on ESP32-C2, IDF-5236
*tsens_cal = 0.0;
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -132,7 +132,18 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
// Currently calibration is not supported on ESP32-C6, IDF-5236
*tsens_cal = 0;
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -124,7 +124,18 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
// Currently calibration is not supported on ESP32-H2, IDF-5236
*tsens_cal = 0;
const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
assert(cal_temp_size == 9);
uint32_t cal_temp = 0;
esp_err_t err = esp_efuse_read_field_blob(cal_temp_efuse, &cal_temp, cal_temp_size);
if (err != ESP_OK) {
*tsens_cal = 0.0;
return err;
}
// BIT(8) stands for sign: 1: negative, 0: positive
*tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
return ESP_OK;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -35,7 +35,6 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
//TODO: IDF-7482
*tsens_cal = 0;
return ESP_ERR_NOT_SUPPORTED;
}

View File

@ -434,7 +434,10 @@ cleanup:
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
#ifndef CONFIG_TARGET_ETH_PHY_DEVICE_W5500
// only unregister events if the device != W5500, since w5500 doesn't support loopback and we don't register the event
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
#endif
TEST_ESP_OK(esp_event_loop_delete_default());
extra_cleanup();
vEventGroupDelete(eth_event_group);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,7 +22,7 @@
/* ---------------------------- Definitions --------------------------------- */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
// LOOP @<address, name> rx:<recieved events no.> dr:<dropped events no.>
// LOOP @<address, name> rx:<received events no.> dr:<dropped events no.>
#define LOOP_DUMP_FORMAT "LOOP @%p,%s rx:%" PRIu32 " dr:%" PRIu32 "\n"
// handler @<address> ev:<base, id> inv:<times invoked> time:<runtime>
#define HANDLER_DUMP_FORMAT " HANDLER @%p ev:%s,%s inv:%" PRIu32 " time:%lld us\n"
@ -38,6 +38,7 @@
static const char* TAG = "event";
static const char* esp_event_any_base = "any";
static const char* esp_event_handler_cleanup = "cleanup";
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
static SLIST_HEAD(esp_event_loop_instance_list_t, esp_event_loop_instance) s_event_loops =
@ -136,29 +137,14 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_n
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, data_ptr);
#else
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data);
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data.ptr);
#endif
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
diff = esp_timer_get_time() - start;
xSemaphoreTake(loop->profiling_mutex, portMAX_DELAY);
// At this point handler may be already unregistered.
// This happens in "handler instance can unregister itself" test case.
// To prevent memory corruption error it's necessary to check if pointer is still valid.
esp_event_loop_node_t* loop_node;
esp_event_handler_node_t* handler_node;
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
SLIST_FOREACH(handler_node, &(loop_node->handlers), next) {
if(handler_node == handler) {
handler->invoked++;
handler->time += diff;
}
}
}
xSemaphoreGive(loop->profiling_mutex);
handler->invoked++;
handler->time += diff;
#endif
}
@ -363,8 +349,8 @@ static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int3
if (SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(base_node->id_nodes), it, esp_event_id_node, next);
free(it);
return ESP_OK;
}
return ESP_OK;
}
}
}
@ -388,8 +374,8 @@ static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_
if (SLIST_EMPTY(&(it->handlers)) && SLIST_EMPTY(&(it->id_nodes))) {
SLIST_REMOVE(&(loop_node->base_nodes), it, esp_event_base_node, next);
free(it);
return ESP_OK;
}
return ESP_OK;
}
}
}
@ -398,6 +384,23 @@ static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_
return ESP_ERR_NOT_FOUND;
}
static esp_err_t loop_remove_handler(esp_event_remove_handler_context_t* ctx)
{
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(ctx->loop->loop_nodes), next, temp) {
esp_err_t res = loop_node_remove_handler(it, ctx->event_base, ctx->event_id, ctx->handler_ctx, ctx->legacy);
if (res == ESP_OK) {
if (SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(ctx->loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
}
return ESP_OK;
}
}
return ESP_ERR_NOT_FOUND;
}
static void handler_instances_remove_all(esp_event_handler_nodes_t* handlers)
{
esp_event_handler_node_t *it, *temp;
@ -435,17 +438,112 @@ static void loop_node_remove_all_handler(esp_event_loop_node_t* loop_node)
static void inline __attribute__((always_inline)) post_instance_delete(esp_event_post_instance_t* post)
{
#if CONFIG_ESP_EVENT_POST_FROM_ISR
if (post->data_allocated && post->data.ptr) {
if (post->data_allocated)
#endif
{
free(post->data.ptr);
}
#else
if (post->data) {
free(post->data);
}
#endif
memset(post, 0, sizeof(*post));
}
static esp_err_t find_and_unregister_handler(esp_event_remove_handler_context_t* ctx)
{
esp_event_handler_node_t *handler_to_unregister = NULL;
esp_event_handler_node_t *handler;
esp_event_loop_node_t *loop_node;
esp_event_base_node_t *base_node;
esp_event_id_node_t *id_node;
SLIST_FOREACH(loop_node, &(ctx->loop->loop_nodes), next) {
// Execute loop level handlers
SLIST_FOREACH(handler, &(loop_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
if (handler_to_unregister != NULL) {
break;
}
SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) {
if (base_node->base == ctx->event_base) {
// Execute base level handlers
SLIST_FOREACH(handler, &(base_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
if (handler_to_unregister != NULL) {
break;
}
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
if (id_node->id == ctx->event_id) {
// Execute id level handlers
SLIST_FOREACH(handler, &(id_node->handlers), next) {
if (ctx->legacy) {
if (handler->handler_ctx->handler == ctx->handler_ctx->handler) {
handler_to_unregister = handler;
break;
}
} else {
if (handler->handler_ctx == ctx->handler_ctx) {
handler_to_unregister = handler;
break;
}
}
}
}
}
}
}
}
if (handler_to_unregister == NULL) {
/* handler not found in the lists, return */
return ESP_ERR_NOT_FOUND;
}
if (handler_to_unregister->unregistered) {
/* the handler was found in a list but has already be marked
* as unregistered. It means an event was already created to
* remove from the list. return OK but do nothing */
return ESP_OK;
}
/* handler found in the lists and not already marked as unregistered. Mark it as unregistered
* and post an event to remove it from the lists */
handler_to_unregister->unregistered = true;
if (ctx->legacy) {
/* in case of legacy code, we have to copy the handler_ctx content since it was created in the calling function */
esp_event_handler_instance_context_t *handler_ctx_copy = calloc(1, sizeof(esp_event_handler_instance_context_t));
if (!handler_ctx_copy) {
return ESP_ERR_NO_MEM;
}
handler_ctx_copy->arg = ctx->handler_ctx->arg;
handler_ctx_copy->handler = ctx->handler_ctx->handler;
ctx->handler_ctx = handler_ctx_copy;
}
return esp_event_post_to(ctx->loop, esp_event_handler_cleanup, 0, ctx, sizeof(esp_event_remove_handler_context_t), portMAX_DELAY);
}
/* ---------------------------- Public API --------------------------------- */
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop)
@ -481,14 +579,6 @@ esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, es
goto on_err;
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
loop->profiling_mutex = xSemaphoreCreateMutex();
if (loop->profiling_mutex == NULL) {
ESP_LOGE(TAG, "create event loop profiling mutex failed");
goto on_err;
}
#endif
SLIST_INIT(&(loop->loop_nodes));
// Create the loop task if requested
@ -534,12 +624,6 @@ on_err:
vSemaphoreDelete(loop->mutex);
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
if (loop->profiling_mutex != NULL) {
vSemaphoreDelete(loop->profiling_mutex);
}
#endif
free(loop);
return err;
@ -566,10 +650,25 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
int64_t remaining_ticks = ticks_to_run;
#endif
while(xQueueReceive(loop->queue, &post, ticks_to_run) == pdTRUE) {
while (xQueueReceive(loop->queue, &post, remaining_ticks) == pdTRUE) {
// The event has already been unqueued, so ensure it gets executed.
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
// check if the event retrieve from the queue is the internal event that is
// triggered when a handler needs to be removed..
if (post.base == esp_event_handler_cleanup) {
assert(post.data.ptr != NULL);
esp_event_remove_handler_context_t* ctx = (esp_event_remove_handler_context_t*)post.data.ptr;
loop_remove_handler(ctx);
// if the handler unregistration request came from legacy code,
// we have to free handler_ctx pointer since it points to memory
// allocated by esp_event_handler_unregister_with_internal
if (ctx->legacy) {
free(ctx->handler_ctx);
}
}
loop->running_task = xTaskGetCurrentTaskHandle();
bool exec = false;
@ -582,24 +681,30 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
SLIST_FOREACH_SAFE(loop_node, &(loop->loop_nodes), next, temp_node) {
// Execute loop level handlers
SLIST_FOREACH_SAFE(handler, &(loop_node->handlers), next, temp_handler) {
handler_execute(loop, handler, post);
exec |= true;
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
}
SLIST_FOREACH_SAFE(base_node, &(loop_node->base_nodes), next, temp_base) {
if (base_node->base == post.base) {
// Execute base level handlers
SLIST_FOREACH_SAFE(handler, &(base_node->handlers), next, temp_handler) {
handler_execute(loop, handler, post);
exec |= true;
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
}
SLIST_FOREACH_SAFE(id_node, &(base_node->id_nodes), next, temp_id_node) {
if (id_node->id == post.id) {
// Execute id level handlers
SLIST_FOREACH_SAFE(handler, &(id_node->handlers), next, temp_handler) {
handler_execute(loop, handler, post);
exec |= true;
if (!handler->unregistered) {
handler_execute(loop, handler, post);
exec |= true;
}
}
// Skip to next base node
break;
@ -646,14 +751,10 @@ esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
SemaphoreHandle_t loop_mutex = loop->mutex;
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
SemaphoreHandle_t loop_profiling_mutex = loop->profiling_mutex;
#endif
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreTake(loop->profiling_mutex, portMAX_DELAY);
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_REMOVE(&s_event_loops, loop, esp_event_loop_instance, next);
portEXIT_CRITICAL(&s_event_loops_spinlock);
@ -683,10 +784,6 @@ esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
free(loop);
// Free loop mutex before deleting
xSemaphoreGiveRecursive(loop_mutex);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreGive(loop_profiling_mutex);
vSemaphoreDelete(loop_profiling_mutex);
#endif
vSemaphoreDelete(loop_mutex);
return ESP_OK;
@ -786,24 +883,21 @@ esp_err_t esp_event_handler_unregister_with_internal(esp_event_loop_handle_t eve
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_remove_handler_context_t remove_handler_ctx = {loop, event_base, event_id, handler_ctx, legacy};
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop->loop_nodes), next, temp) {
esp_err_t res = loop_node_remove_handler(it, event_base, event_id, handler_ctx, legacy);
if (res == ESP_OK && SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
break;
}
/* remove the handler if the mutex is taken successfully.
* otherwise it will be removed from the list later */
esp_err_t res = ESP_FAIL;
if (xSemaphoreTake(loop->mutex, 0) == pdTRUE) {
res = loop_remove_handler(&remove_handler_ctx);
xSemaphoreGive(loop->mutex);
} else {
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
res = find_and_unregister_handler(&remove_handler_ctx);
xSemaphoreGiveRecursive(loop->mutex);
}
xSemaphoreGiveRecursive(loop->mutex);
return ESP_OK;
return res;
}
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
@ -847,12 +941,10 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
}
memcpy(event_data_copy, event_data, event_data_size);
#if CONFIG_ESP_EVENT_POST_FROM_ISR
post.data.ptr = event_data_copy;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
post.data_allocated = true;
post.data_set = true;
#else
post.data = event_data_copy;
#endif
}
post.base = event_base;
@ -894,7 +986,7 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_recieved, 1);
atomic_fetch_add(&loop->events_received, 1);
#endif
return ESP_OK;
@ -942,7 +1034,7 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_recieved, 1);
atomic_fetch_add(&loop->events_received, 1);
#endif
return ESP_OK;
@ -971,13 +1063,13 @@ esp_err_t esp_event_dump(FILE* file)
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_FOREACH(loop_it, &s_event_loops, next) {
uint32_t events_recieved, events_dropped;
uint32_t events_received, events_dropped;
events_recieved = atomic_load(&loop_it->events_recieved);
events_received = atomic_load(&loop_it->events_received);
events_dropped = atomic_load(&loop_it->events_dropped);
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none" ,
events_recieved, events_dropped);
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none",
events_received, events_dropped);
int sz_bak = sz;

View File

@ -1,16 +1,8 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_EVENT_INTERNAL_H_
#define ESP_EVENT_INTERNAL_H_
@ -39,6 +31,7 @@ typedef struct esp_event_handler_node {
int64_t time; /**< total runtime of this handler across all calls */
#endif
SLIST_ENTRY(esp_event_handler_node) next; /**< next event handler in the list */
bool unregistered;
} esp_event_handler_node_t;
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_node) esp_event_handler_nodes_t;
@ -84,21 +77,24 @@ typedef struct esp_event_loop_instance {
esp_event_loop_nodes_t loop_nodes; /**< set of linked lists containing the
registered handlers for the loop */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_uint_least32_t events_recieved; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_received; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_dropped; /**< number of events dropped due to queue being full */
SemaphoreHandle_t profiling_mutex; /**< mutex used for profiliing */
SLIST_ENTRY(esp_event_loop_instance) next; /**< next event loop in the list */
#endif
} esp_event_loop_instance_t;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
typedef struct esp_event_remove_handler_context_t {
esp_event_loop_instance_t* loop; /**< Instance of the event loop from which the handler has to be removed */
esp_event_base_t event_base; /**< The event base identification of the handler that has to be removed */
int32_t event_id; /**< The event identification value of the handler that has to be removed */
esp_event_handler_instance_context_t* handler_ctx; /**< The handler context of the handler that has to be removed */
bool legacy; /**< Set to true when the handler unregistration request was made from legacy code */
} esp_event_remove_handler_context_t;
typedef union esp_event_post_data {
uint32_t val;
void *ptr;
} esp_event_post_data_t;
#else
typedef void* esp_event_post_data_t;
#endif
/// Event posted to the event queue
typedef struct esp_event_post_instance {

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -8,6 +8,7 @@
#include <stdio.h>
#include <string.h>
#include "inttypes.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -1571,3 +1572,167 @@ TEST_CASE("default event loop: registering event handler instance without instan
TEST_ESP_OK(esp_event_loop_delete_default());
}
#if CONFIG_ESP_EVENT_LOOP_PROFILING
static void handler_all(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
static void handler_base(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
static void handler_id(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
}
/* This test executes the following steps:
* 1) register handler_id for a event id A and event base B,
* 2) register handler_base for a given event base,
* 3) register handler_all for on the loop level,
* 4) post an event (A, B),
* 5) call esp_event_dump and make sure by parsing the string IN PYTEST ENVIRONMENT that
* all handlers profiling data is printed
* 6) unregister the handlers successfully */
TEST_CASE("profiling reports valid values", "[event][default]")
{
TEST_ESP_OK(esp_event_loop_create_default());
/* register handler for event base 1 and event id 1 */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id, NULL));
/* register handler for event base 1 and all event ids */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, ESP_EVENT_ANY_ID, handler_base, NULL));
/* register handler for all event bases and all event ids */
TEST_ESP_OK(esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, handler_all, NULL));
/* post an event on event base 1, event id 1 */
TEST_ESP_OK(esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000)));
/* post an event 1 from base 1 and check the dump.
* - 3 handlers invoked, exec time is not 0 */
esp_event_dump(stdout);
/* unregister handlers */
TEST_ESP_OK(esp_event_handler_unregister(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, handler_all));
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, ESP_EVENT_ANY_ID, handler_base));
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id));
/* delete loop */
TEST_ESP_OK(esp_event_loop_delete_default());
}
static void handler_id2(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
printf("event received: base=%s, id=%" PRId32 ", data=%p\n", event_base, event_id, data);
/* self unregistering handler */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id2));
/* register a new handler on id level */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id, NULL));
}
/* This test executes the following steps:
* 1) register handler_id2 for a given event id and event base,
* 2) post an event to trigger the handler_id2,
* 3) unregister the handler_id2 during the execution of the handler_id2 and register
* handler_id instead.
* 4) call esp_event_dump and make sure by parsing the string IN PYTEST ENVIRONMENT that
* 1 handler profiling data is printed
* 5) unregister the handler_id successfully */
TEST_CASE("esp_event_dump does not show self unregistered handler", "[event][default]")
{
TEST_ESP_OK(esp_event_loop_create_default());
/* register handler for event base 1 and event id 1 */
TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id2, NULL));
/* post an event on event base 1, event id 1 */
TEST_ESP_OK(esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000)));
/* post an event 1 from base 1 and check the dump.
* - 1 handler invoked 0 times, exec time is 0 us */
esp_event_dump(stdout);
/* unregister handler id */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, handler_id));
/* delete loop */
TEST_ESP_OK(esp_event_loop_delete_default());
}
static SemaphoreHandle_t s_event_mutex;
static StaticSemaphore_t s_event_mutex_buf;
static size_t s_handler_triggered = 0;
static void self_unregistering_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* data)
{
xSemaphoreTake(s_event_mutex, portMAX_DELAY);
/* self unregistering handler */
TEST_ESP_OK(esp_event_handler_unregister(s_test_base1, TEST_EVENT_BASE1_EV1, self_unregistering_handler));
s_handler_triggered++;
xSemaphoreGive(s_event_mutex);
}
/* This test makes sure that once a handler is unregistered, it is never called again.
* This test follows the update in esp event unregistration process where a handler can
* be marked as unregistered but not removed directly from the list it belongs to.
* The test creates a handler triggered by a specific combination of event base / event id
* and generates 2 consecutive events that should trigger the handler. The handler unregisters
* itself. Make sure that the second event does not trigger the handler again.
*
* Both event posts need to be queued before the unregistration happens, to make sure that event if
* the handler is still present in the handlers lists when the second event triggers, it will not
* be called. To make sure of that, the execution of the handler is blocked by a mutex released from
* test after the 2 events are posted. */
TEST_CASE("self unregistered handlers are never called again after they return", "[event][default]")
{
s_event_mutex = xSemaphoreCreateMutexStatic(&s_event_mutex_buf);
TEST_ASSERT_NOT_NULL(s_event_mutex);
esp_err_t ret = esp_event_loop_create_default();
printf("esp_event_loop_create_default %d\n", ret);
TEST_ESP_OK(ret);
/* register handler for event base 1 and event id 1 */
ret = esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, self_unregistering_handler, NULL);
printf("esp_event_handler_register %d\n", ret);
TEST_ESP_OK(ret);
/* take the mutex to block the execution of the self_unregistering_handler */
xSemaphoreTake(s_event_mutex, portMAX_DELAY);
/* post 2 times the event on event base 1, event id 1 */
ret = esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000));
printf("esp_event_post %d\n", ret);
TEST_ESP_OK(ret);
ret = esp_event_post(s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(1000));
printf("esp_event_post %d\n", ret);
TEST_ESP_OK(ret);
/* release the mutex to execute the self_unregistering_handler */
xSemaphoreGive(s_event_mutex);
/* make sure the handler was called only once */
TEST_ASSERT(s_handler_triggered == 1);
/* delete mutex */
vSemaphoreDelete(s_event_mutex);
/* reset the static variable in case the test gets called once more */
s_handler_triggered = 0;
/* delete loop */
ret = esp_event_loop_delete_default();
printf("esp_event_loop_delete_default %d\n", ret);
TEST_ESP_OK(ret);
}
#endif // CONFIG_ESP_EVENT_LOOP_PROFILING

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -43,3 +42,28 @@ def test_esp_event_posix_simulator(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests.')
dut.write('*')
dut.expect(r'\d{2} Tests 0 Failures 0 Ignored', timeout=120)
@pytest.mark.esp32
@pytest.mark.generic
def test_esp_event_profiling(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests.')
dut.write('"profiling reports valid values"')
# look for all references of handlers invoked at least 1 time
# with an execution time superior to 0 us
matches = dut.expect(r'HANDLER .+ inv:[1-9][0-9]{0,} time:[1-9][0-9]{0,} us', timeout=2)
matches_arr = matches.group().split(b'\r\n')
assert (len(matches_arr) == 3)
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)
dut.expect_exact("Enter next test, or 'enter' to see menu")
dut.write('"esp_event_dump does not show self unregistered handler"')
# look for 1 handlers never invoked
matches = dut.expect(r'HANDLER .+ inv:0 time:0 us', timeout=2)
matches_arr = matches.group().split(b'\r\n')
assert (len(matches_arr) == 1)
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)
dut.expect_exact("Enter next test, or 'enter' to see menu")
dut.write('"self unregistered handlers are never called again after they return"')
dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120)

View File

@ -0,0 +1,3 @@
# This configuration checks the event loop if posting from ISR is disabled
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_POST_EVENTS_FROM_ISR=n

View File

@ -0,0 +1,17 @@
menu "ESP HID"
config ESPHID_TASK_SIZE_BT
int "Task stack size for ESP HID BR/EDR"
range 2048 10240
default 2048
help
This is the stack size for the BT HID task.
Default is 2048 bytes.
config ESPHID_TASK_SIZE_BLE
int "Task stack size for ESP HID BLE"
range 2048 10240
default 4096
help
This is the stack size for the BLE HID task.
Default is 4096 bytes.
endmenu

View File

@ -1,16 +1,8 @@
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@ -94,6 +86,19 @@ extern "C" {
#define ESP_HID_CCC_NOTIFICATIONS_ENABLED 0x01 // Notifications enabled
#define ESP_HID_CCC_INDICATIONS_ENABLED 0x02 // Indications enabled
/* HID Task Size configuration */
#ifdef CONFIG_ESPHID_TASK_SIZE_BT
#define BT_HID_DEVICE_TASK_SIZE_BT CONFIG_ESPHID_TASK_SIZE_BT
#else
#define BT_HID_DEVICE_TASK_SIZE_BT 2048
#endif
#ifdef CONFIG_ESPHID_TASK_SIZE_BLE
#define BT_HID_DEVICE_TASK_SIZE_BLE CONFIG_ESPHID_TASK_SIZE_BLE
#else
#define BT_HID_DEVICE_TASK_SIZE_BLE 4096
#endif
/* HID Transports */
typedef enum {
ESP_HID_TRANSPORT_BT,
@ -203,8 +208,8 @@ esp_hid_report_map_t *esp_hid_parse_report_map(const uint8_t *hid_rm, size_t hid
void esp_hid_free_report_map(esp_hid_report_map_t *map);
/**
* @brief Calculate the HID Device usage type from the BLE Apperance
* @param appearance : BLE Apperance value
* @brief Calculate the HID Device usage type from the BLE Appearance
* @param appearance : BLE Appearance value
*
* @return: the hid usage type
*/

View File

@ -976,7 +976,7 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf
.queue_size = 5,
.task_name = "ble_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = 4096,
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BLE,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_dev->event_loop_handle);

View File

@ -810,7 +810,7 @@ esp_err_t esp_bt_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_confi
.queue_size = 5,
.task_name = "bt_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = 2048,
.task_stack_size = BT_HID_DEVICE_TASK_SIZE_BT,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_hidd_param.dev->event_loop_handle);

View File

@ -1,13 +1,17 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_err.h"
#include "soc/clk_tree_defs.h"
#include "soc/gpio_num.h"
#include "soc/soc_caps.h"
#include "soc/io_mux_reg.h"
#ifdef __cplusplus
extern "C" {
@ -26,6 +30,26 @@ extern "C" {
*/
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src);
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
typedef struct {
uint8_t rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM];
uint32_t rtc_io_using_mask;
} rtc_io_status_t;
/**
* Enable/Disable LP_IO peripheral clock.
* @param gpio_num GPIO number
* @param enable true to enable the clock / false to disable the clock
*/
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable);
/**
* Force disable one LP_IO to clock dependency
* @param gpio_num GPIO number
*/
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -168,9 +168,13 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void);
/**
* @brief Enable wakeup by timer
* @param time_in_us time before wakeup, in microseconds
* @note The valid `time_in_us` value depends on the bit width of the lp_timer/rtc_timer counter and the
* current slow clock source selection (Refer RTC clock source configuration in menuconfig).
* Valid values should be positive values less than RTC slow clock period * (2 ^ RTC timer bitwidth).
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if value is out of range (TBD)
* - ESP_ERR_INVALID_ARG if value is out of range.
*/
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);
@ -411,8 +415,10 @@ esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_
*
* This function enables an IO pin to wake up the chip from deep sleep.
*
* @note This function does not modify pin configuration. The pins are
* configured inside esp_deep_sleep_start, immediately before entering sleep mode.
* @note 1.This function does not modify pin configuration. The pins are configured
* inside `esp_deep_sleep_start`, immediately before entering sleep mode.
* 2.This function is also applicable to waking up the lightsleep when the peripheral
* power domain is powered off, see PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP in menuconfig.
*
* @note You don't need to worry about pull-up or pull-down resistors before
* using this function because the ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS
@ -447,7 +453,12 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
* wakeup level, for each GPIO which is used for wakeup.
* Then call this function to enable wakeup feature.
*
* @note On ESP32, GPIO wakeup source can not be used together with touch or ULP wakeup sources.
* @note 1. On ESP32, GPIO wakeup source can not be used together with touch or ULP wakeup sources.
* 2. If PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is enabled (if target supported),
* this API is unavailable since the GPIO module is powered down during sleep.
* You can use `esp_deep_sleep_enable_gpio_wakeup` instead, or use EXT1 wakeup source
* by `esp_sleep_enable_ext1_wakeup_io` to achieve the same function.
* (Only GPIOs which have RTC functionality can be used)
*
* @return
* - ESP_OK on success
@ -463,7 +474,9 @@ esp_err_t esp_sleep_enable_gpio_wakeup(void);
* Wakeup from light sleep takes some time, so not every character sent
* to the UART can be received by the application.
*
* @note ESP32 does not support wakeup from UART2.
* @note 1. ESP32 does not support wakeup from UART2.
* 2. If PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is enabled (if target supported),
* this API is unavailable since the UART module is powered down during sleep.
*
* @param uart_num UART port to wake up from
* @return

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -235,12 +235,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
/* Read back 'reject' status when waking from light or deep sleep */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -145,9 +145,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -193,12 +193,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -159,9 +159,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -244,12 +244,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -162,9 +162,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -237,9 +237,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -236,9 +236,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -198,9 +198,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,13 +1,67 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_attr.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
// IO MUX clock source is not selectable
return ESP_OK;
}
extern portMUX_TYPE rtc_spinlock;
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 },
.rtc_io_using_mask = 0
};
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_rtc_io_status.rtc_io_using_mask == 0) {
rtcio_ll_enable_io_clock(false);
} else {
rtcio_ll_enable_io_clock(true);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -249,11 +249,11 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
{
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
/* Read back 'reject' status when waking from light or deep sleep */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -227,9 +227,9 @@ uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -1,13 +1,67 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_attr.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() \
for (int _rc_cnt = 1; \
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
// IO MUX clock source is not selectable
return ESP_OK;
}
extern portMUX_TYPE rtc_spinlock;
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 },
.rtc_io_using_mask = 0
};
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
if (enable) {
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_rtc_io_status.rtc_io_using_mask == 0) {
rtcio_ll_enable_io_clock(false);
} else {
rtcio_ll_enable_io_clock(true);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

View File

@ -19,6 +19,7 @@
#include "esp_hw_log.h"
#include "hal/clk_tree_ll.h"
#include "hal/regi2c_ctrl_ll.h"
#include "hal/rtc_io_ll.h"
#include "esp_private/regi2c_ctrl.h"
#include "soc/regi2c_dig_reg.h"
#include "soc/sens_reg.h"
@ -65,7 +66,7 @@ void rtc_clk_32k_enable(bool enable)
void rtc_clk_32k_enable_external(void)
{
PIN_INPUT_ENABLE(IO_MUX_GPIO15_REG);
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN);
rtcio_ll_enable_io_clock(true);
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_X32P_HOLD);
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -256,12 +256,12 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu);
}
void rtc_sleep_low_init(uint32_t slowclk_period)
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp)
{
// set 5 PWC state machine times to fit in main state machine time
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, dslp ? RTC_CNTL_PLL_BUF_WAIT_DEFAULT : RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, dslp ? RTC_CNTL_XTL_BUF_WAIT_DEFAULT : rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -161,9 +161,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}

View File

@ -12,10 +12,13 @@
#include "esp_attr.h"
#include "esp_memory_utils.h"
#include "esp_sleep.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_timer_private.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/sleep_event.h"
#include "esp_private/system_internal.h"
#include "esp_private/io_mux.h"
#include "esp_log.h"
#include "esp_newlib.h"
#include "esp_timer.h"
@ -874,9 +877,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
rtc_sleep_init(config);
// Set state machine time for light sleep
if (!deep_sleep) {
rtc_sleep_low_init(s_config.rtc_clk_cal_period);
}
rtc_sleep_low_init(s_config.rtc_clk_cal_period, deep_sleep);
#endif
// Configure timer wakeup
@ -1488,6 +1489,10 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void)
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
if (time_in_us > ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ ) {
return ESP_ERR_INVALID_ARG;
}
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us;
return ESP_OK;
@ -1606,6 +1611,9 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
static void ext0_wakeup_prepare(void)
{
int rtc_gpio_num = s_config.ext0_rtc_gpio_num;
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level);
rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC);
rtcio_hal_input_enable(rtc_gpio_num);
@ -1735,6 +1743,9 @@ static void ext1_wakeup_prepare(void)
if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) {
continue;
}
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
// Route pad to RTC
rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC);
@ -1806,6 +1817,9 @@ static void gpio_deep_sleep_wakeup_prepare(void)
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
continue;
}
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
rtcio_ll_enable_io_clock(true);
#endif
#if CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS
if (s_config.gpio_trigger_mode & BIT(gpio_idx)) {
ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx));
@ -1854,6 +1868,9 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
esp_err_t esp_sleep_enable_gpio_wakeup(void)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_LOGW(TAG, "%s wakeup source is not available if the peripheral power domain is powered down in sleep", "GPIO");
#endif
#if CONFIG_IDF_TARGET_ESP32
if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
@ -1866,6 +1883,9 @@ esp_err_t esp_sleep_enable_gpio_wakeup(void)
esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_LOGW(TAG, "%s wakeup source is not available if the peripheral power domain is powered down in sleep", "UART");
#endif
if (uart_num == UART_NUM_0) {
s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
} else if (uart_num == UART_NUM_1) {

View File

@ -351,7 +351,7 @@ IRAM_ATTR esp_err_t esp_mmu_paddr_find_caps(const esp_paddr_t paddr, mmu_mem_cap
}
//now we are only traversing the actual dynamically allocated blocks, dummy_head and dummy_tail are excluded already
if (mem_block->paddr_start == paddr) {
if (paddr >= mem_block->paddr_start && paddr < mem_block->paddr_end) {
found = true;
found_block = mem_block;
break;

View File

@ -50,3 +50,23 @@ TEST_CASE("Can dump mapped block stats", "[mmu]")
TEST_ESP_OK(esp_mmu_unmap(ptr1));
TEST_ESP_OK(esp_mmu_unmap(ptr2));
}
TEST_CASE("Can find paddr caps by any paddr offset", "[mmu]")
{
const esp_partition_t *part = s_get_partition();
ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size);
void *ptr0 = NULL;
TEST_ESP_OK(esp_mmu_map(part->address, TEST_BLOCK_SIZE, MMU_TARGET_FLASH0, MMU_MEM_CAP_READ, 0, &ptr0));
mmu_mem_caps_t caps = 0;
TEST_ESP_OK(esp_mmu_paddr_find_caps(part->address, &caps));
ESP_LOGI(TAG, "caps: 0x%x", caps);
TEST_ASSERT(caps == MMU_MEM_CAP_READ);
TEST_ESP_OK(esp_mmu_paddr_find_caps(part->address + 0x100, &caps));
ESP_LOGI(TAG, "caps: 0x%x", caps);
TEST_ASSERT(caps == MMU_MEM_CAP_READ);
TEST_ESP_OK(esp_mmu_unmap(ptr0));
}

View File

@ -144,12 +144,17 @@ menu "Power Management"
depends on SOC_PAU_SUPPORTED
default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252)
help
If enabled, digital peripherals will be powered down in light sleep, it will reduce sleep
current consumption by about 100 uA. Chip will save/restore register context at sleep/wake
time to keep the system running. Enabling this option will increase static RAM and heap usage,
the actual cost depends on the peripherals you have initialized. In order to save/restore the
context of the necessary hardware for FreeRTOS to run, it will need at least 4.55 KB free heap
at sleep time. Otherwise sleep will not power down the peripherals.
If enabled, digital peripherals will try to powered down in light sleep, then all related peripherals will
not be available during sleep, including wake-up sources from the peripherals (For detailed availability
information, see the note of the corresponding wakeup source enable function).
The chip will automatically save/restore register context during sleep/wakeup to make the upper layer
user unaware of the peripheral powerdown during sleep. Enabling this option will increase static RAM and
heap usage but will also significantly reduce power.
consumption during lightsleep, the actual memory cost depends on the peripherals you have initialized,
for specific power consumption data in this mode, please refer to Electrical Characteristics section
in the chip datasheet.
(In order to save/restore the context of the necessary hardware for FreeRTOS to run, it will need
at least 4.55 KB free heap at sleep time. Otherwise sleep will not power down the peripherals.)
Note1: Please use this option with caution, the current IDF does not support the retention of
all peripherals. When the digital peripherals are powered off and a sleep and wake-up is completed,
@ -164,6 +169,14 @@ menu "Power Management"
of freertos to not be compensated correctly when returning from sleep and cause the system to crash.
To avoid this, you can increase FREERTOS_IDLE_TIME_BEFORE_SLEEP threshold in menuconfig.
Note3: Enabling this option does not necessarily mean that the peripheral power domain will be
turned down during sleep. The control priority of `esp_sleep_pd_config` is higher than this option,
user code can still prevent the peripheral power domain from powering down during sleep by
`esp_sleep_pd_config(ESP_PD_DOMAIN_TOP, ESP_PD_OPTION_ON)`. In addition, whether the peripheral power
domain is powered down during sleep also depends on the sleep working strategy selected by the driver.
If any module belonging to the peripheral power domain chooses not to be powered down during sleep,
then the peripheral power domain will not be powered off either.
config PM_UPDATE_CCOMPARE_HLI_WORKAROUND
bool
default y if PM_ENABLE && BTDM_CTRL_HLI

View File

@ -21,14 +21,13 @@
extern uint32_t rom_Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped);
uint32_t Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped)
{
uint32_t page0_before_count = *page0_mapped;
uint32_t flash_pages = 0;
flash_pages = rom_Cache_Count_Flash_Pages(bus, page0_mapped);
/* No page mapped to page0, in this condition, the rom api will return
/* No page mapped to page0 yet, in this condition, the rom api will return
* unexpected value + 1.
*/
if (page0_before_count == *page0_mapped) {
if (*page0_mapped == 0) {
flash_pages--;
}
return flash_pages;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,8 +18,6 @@
#define SPI_IDX 1
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
#if CONFIG_IDF_TARGET_ESP32
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
@ -105,6 +103,12 @@ __attribute__((__unused__)) esp_rom_spiflash_result_t esp_rom_spiflash_clear_bp(
}
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) __attribute__((alias("esp_rom_spiflash_clear_bp")));
#endif // CONFIG_IDF_TARGET_ESP32
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
#if CONFIG_IDF_TARGET_ESP32
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi);
//only support spi1

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -92,6 +92,14 @@ bool esp_usb_console_write_available(void);
*/
esp_err_t esp_usb_console_set_cb(esp_usb_console_cb_t rx_cb, esp_usb_console_cb_t tx_cb, void* arg);
/**
* @brief Call the USB interrupt handler while any interrupts
* are pending, but not more than a few times. Non-static to
* allow placement into IRAM by ldgen.
*
*/
void esp_usb_console_poll_interrupts(void); // [refactor-todo] Remove when implementing IDF-12175
#ifdef __cplusplus
}
#endif

View File

@ -13,6 +13,7 @@
#include "esp_log.h"
#include "esp_chip_info.h"
#include "esp_app_format.h"
#include "esp_efuse.h"
#include "esp_private/cache_err_int.h"
@ -751,18 +752,26 @@ void IRAM_ATTR call_start_cpu0(void)
// Read the application binary image header. This will also decrypt the header if the image is encrypted.
__attribute__((unused)) esp_image_header_t fhdr = {0};
#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#if CONFIG_APP_BUILD_TYPE_RAM
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO;
fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2;
fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB;
bootloader_flash_unlock();
#else
// This assumes that DROM is the first segment in the application binary, i.e. that we can read
// the binary header through cache by accessing SOC_DROM_LOW address.
hal_memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr));
#endif // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#endif
#else
// We can access the image header through the cache by reading from the memory-mapped virtual DROM start offset
uint32_t fhdr_src_addr = (uint32_t)(&_rodata_reserved_start) - sizeof(esp_image_header_t) - sizeof(esp_image_segment_header_t);
hal_memcpy(&fhdr, (void *) fhdr_src_addr, sizeof(fhdr));
if (fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
ESP_EARLY_LOGE(TAG, "Invalid app image header");
abort();
}
#endif // CONFIG_APP_BUILD_TYPE_RAM
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#if CONFIG_IDF_TARGET_ESP32

View File

@ -19,6 +19,7 @@
#include "soc/rtc.h" // for wakeup trigger defines
#include "soc/rtc_periph.h" // for read rtc registers directly (cause)
#include "soc/soc.h" // for direct register read macros
#include "esp_clk_tree.h"
#include "esp_newlib.h"
#include "test_utils.h"
#include "sdkconfig.h"
@ -26,6 +27,7 @@
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/uart_private.h"
#include "esp_random.h"
#include "nvs_flash.h"
@ -57,6 +59,10 @@ static void deep_sleep_task(void *arg)
static void do_deep_sleep_from_app_cpu(void)
{
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(UINT64_MAX));
uint64_t lp_timer_max_allowed_time_in_us = ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ;
TEST_ASSERT_EQUAL(ESP_OK, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us + 1));
esp_sleep_enable_timer_wakeup(2000000);
xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1);

View File

@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/errno.h>
#include "unity.h"
#include "esp_private/usb_console.h"
#include "esp_vfs_cdcacm.h"
static void flush_write(void)
{
fflush(stdout);
fsync(fileno(stdout));
}
static void test_setup(const char* func_name, const size_t func_name_size)
{
/* write the name of the test back to the pytest environment to start the test */
write(fileno(stdout), func_name, func_name_size);
write(fileno(stdout), "\n", 1);
flush_write();
}
static bool wait_for_read_ready(FILE *stream)
{
int fd = fileno(stream);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
/* call select to wait for either a read ready or an except to happen */
int nread = select(fd + 1, &read_fds, NULL, NULL, NULL);
if ((nread >= 0) && (FD_ISSET(fd, &read_fds))) {
return true;
} else {
return false;
}
}
static void test_usb_cdc_read_non_blocking(void)
{
test_setup(__func__, sizeof(__func__));
const size_t max_read_bytes = 16;
char read_data_buffer[max_read_bytes];
memset(read_data_buffer, 0x00, max_read_bytes);
/* reset errno to 0 for the purpose of the test to make sure it is no
* longer set to EWOULDBLOCK later in the test. */
errno = 0;
/* make sure to read in non blocking mode */
int stdin_fd = fileno(stdin);
int flags = fcntl(stdin_fd, F_GETFL);
flags |= O_NONBLOCK;
int res = fcntl(stdin_fd, F_SETFL, flags);
TEST_ASSERT(res == 0);
/* call read when no data is available for reading.
* expected result:
* - read returns -1 and errno has been set to EWOULDBLOCK */
int nread = read(stdin_fd, read_data_buffer, max_read_bytes);
TEST_ASSERT(nread == -1);
TEST_ASSERT(errno == EWOULDBLOCK);
/* reset errno to 0 for the purpose of the test to make sure it is no
* longer set to EWOULDBLOCK later in the test. */
errno = 0;
/* call read X number of bytes when less than X number of
* bytes are available for reading (Y bytes).
* expected result:
* - read returns at least 1 bytes errno is not set to EWOULDBLOCK */
char message_8[] = "send_bytes\n";
write(fileno(stdout), message_8, sizeof(message_8));
flush_write();
const bool is_ready = wait_for_read_ready(stdin);
TEST_ASSERT(is_ready);
nread = read(stdin_fd, read_data_buffer, max_read_bytes);
TEST_ASSERT(nread >= 1);
TEST_ASSERT(errno != EWOULDBLOCK);
}
void app_main(void)
{
test_usb_cdc_read_non_blocking();
}

View File

@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.usb_device
@pytest.mark.parametrize(
'port, flash_port, config',
[
pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'release'),
],
indirect=True,)
@pytest.mark.parametrize('test_message', ['test123456789!@#%^&*'])
def test_usb_cdc_vfs_default(dut: Dut, test_message: str) -> None:
# test run: test_usb_cdc_read_non_blocking
dut.expect_exact('test_usb_cdc_read_non_blocking', timeout=2)
dut.expect_exact('send_bytes', timeout=2)
dut.write('abcdefgh')

@ -1 +1 @@
Subproject commit 7d365e96bafc85d2d2a8ddbfe2a022907d81c5fe
Subproject commit 1b54a5565502faaacc257d7d94fcff482bcb6d83

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -200,15 +200,28 @@ static int elf_add_segment(core_dump_elf_t *self,
return data_len;
}
static int elf_write_note_header(core_dump_elf_t *self,
const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type)
/*
* Example Note Segment
* +================================================================+
* | Offset | +0 | +1 | +2 | +3 | Description |
* +----------------------------------------------------------------+
* | 0 | 0x05 | 0x00 | 0x00 | 0x00 | namesz = 5 |
* | 4 | 0x06 | 0x00 | 0x00 | 0x00 | descsz = 6 |
* | 8 | 0x01 | 0x00 | 0x00 | 0x00 | type = 1 |
* | 12 | 'C' | 'O' | 'R' | 'E' | name ("CORE") |
* | 16 | 0x00 | pad | pad | pad | NULL + padding |
* | 20 | 0x1 | 0x2 | 0x3 | 0x4 | desc (6 bytes) |
* | 24 | 0x5 | 0x6 | pad | pad | desc + padding |
* +================================================================+
*/
static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32_t data_sz, uint32_t type)
{
// temporary aligned buffer for note name
static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 };
elf_note note_hdr = { 0 };
memcpy(name_buffer, name, name_len);
note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4);
size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer));
note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */
note_hdr.n_descsz = data_sz;
note_hdr.n_type = type;
// write note header
@ -216,7 +229,7 @@ static int elf_write_note_header(core_dump_elf_t *self,
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
"Write ELF note header failure (%d)", err);
// write note name
err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz);
err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4));
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL,
"Write ELF note name failure (%d)", err);
@ -230,18 +243,17 @@ static int elf_write_note(core_dump_elf_t *self,
uint32_t data_sz)
{
esp_err_t err = ESP_FAIL;
uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator
uint32_t data_len = ALIGN_UP(data_sz, 4);
uint32_t name_len = strlen(name) + 1; // get name length including terminator
ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0,
"Segment note name is too long %d.", name_len);
uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4);
uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note);
// write segment data during second pass
if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data);
err = elf_write_note_header(self, name, strlen(name), data_sz, type);
err = elf_write_note_header(self, name, data_sz, type);
if (err != ESP_OK) {
return err;
}
@ -250,8 +262,8 @@ static int elf_write_note(core_dump_elf_t *self,
// which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary.
err = esp_core_dump_write_data(&self->write_data, data, data_sz);
if (err == ESP_OK) {
int pad_size = data_len - data_sz;
if (pad_size != 0) {
const int pad_size = ALIGN_UP(data_sz, 4) - data_sz;
if (pad_size > 0) {
uint8_t pad_bytes[3] = {0};
ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size);
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
@ -543,7 +555,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data)
static int elf_add_wdt_panic_details(core_dump_elf_t *self)
{
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME) - 1;
uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */
core_dump_elf_opaque_t param = {
.self = self,
.total_size = 0,
@ -557,27 +569,25 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self)
self->note_data_size = param.total_size;
} else if (self->elf_stage == ELF_STAGE_PLACE_DATA) {
esp_err_t err = elf_write_note_header(self,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
name_len,
self->note_data_size,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME,
self->note_data_size,
ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE);
if (err != ESP_OK) {
return err;
}
esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, &param, NULL);
ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err);
const uint32_t mod = self->note_data_size & 3;
if (mod != 0) {
const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size;
if (pad_size > 0) {
uint8_t pad_bytes[3] = {0};
uint32_t pad_size = 4 - mod;
ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size);
err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size);
ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err);
}
}
return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4);
return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note);
}
#endif //CONFIG_ESP_TASK_WDT_EN
@ -839,17 +849,17 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co
size_t consumed_note_sz = 0;
while (consumed_note_sz < ph->p_memsz) {
const elf_note *note = (const elf_note *)(coredump_data + ph->p_offset + consumed_note_sz);
for (size_t idx = 0; idx < size; ++idx) {
if (target_notes[idx].n_type == note->n_type) {
char *nm = (char *)&note[1];
target_notes[idx].n_ptr = nm + note->n_namesz;
for (size_t idx = 0; idx < size; ++idx) {
if (target_notes[idx].n_type == note->n_type) {
char *nm = (char *)&note[1];
target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4);
target_notes[idx].n_descsz = note->n_descsz;
ESP_COREDUMP_LOGD("%d bytes target note (%X) found in the note section",
note->n_descsz, note->n_type);
break;
}
}
consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4);
note->n_descsz, note->n_type);
break;
}
}
consumed_note_sz += ALIGN_UP(note->n_namesz, 4) + ALIGN_UP(note->n_descsz, 4) + sizeof(elf_note);
}
}
}

View File

@ -249,7 +249,7 @@ static esp_err_t esp_core_dump_get_regs_from_stack(void* stack_addr,
for (int i = 0; i < XT_SOL_AR_NUM; i++) {
regs->ar[i] = stack_arr[XT_SOL_AR_START + i];
}
regs->pc = (regs->pc & 0x3fffffff);
if (regs->pc & 0x80000000) {
regs->pc = (regs->pc & 0x3fffffff);
}

View File

@ -251,13 +251,13 @@ function(esptool_py_partition_needs_encryption retencrypted partition_name)
# - DATA 0x01
# Subtypes:
# - ota 0x00
# - nvs 0x02
# If the partition is an app, an OTA or an NVS partition, then it should
# - nvs_keys 0x04
# If the partition is an app, an OTA or an NVS keys partition, then it should
# be encrypted
if(
(${type} EQUAL 0) OR
(${type} EQUAL 1 AND ${subtype} EQUAL 0) OR
(${type} EQUAL 1 AND ${subtype} EQUAL 2)
(${type} EQUAL 1 AND ${subtype} EQUAL 4)
)
set(encrypted TRUE)
endif()

View File

@ -607,6 +607,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -644,7 +663,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(SPI1.clock) reg;
typeof(SPI1.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -696,6 +696,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -733,7 +752,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -698,6 +698,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -735,7 +754,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -690,6 +690,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -727,7 +746,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -60,15 +60,10 @@ static inline void modem_syscon_ll_enable_modem_sec_clock(modem_syscon_dev_t *hw
hw->clk_conf.clk_modem_sec_apb_en = en;
}
__attribute__((always_inline))
static inline void modem_syscon_ll_enable_ble_timer_apb(modem_syscon_dev_t *hw, bool en)
{
hw->clk_conf.clk_ble_timer_apb_en = en;
}
__attribute__((always_inline))
static inline void modem_syscon_ll_enable_ble_timer_clock(modem_syscon_dev_t *hw, bool en)
{
hw->clk_conf.clk_ble_timer_apb_en = en;
hw->clk_conf.clk_ble_timer_en = en;
}

View File

@ -20,11 +20,13 @@
#include "esp_types.h"
#include "soc/spi_periph.h"
#include "soc/spi_struct.h"
#include "soc/chip_revision.h"
#include "soc/pcr_struct.h"
#include "soc/lldesc.h"
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/efuse_hal.h"
#include "hal/spi_types.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
@ -689,6 +691,26 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
* This config take effect only when SPI_CLK (pre-div before periph) div >=2
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
hw->clock.clk_edge_sel = (sample_point == SPI_SAMPLING_POINT_PHASE_1);
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102);
}
/**
* Set the clock for master by stored value.
*
@ -726,7 +748,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -707,6 +707,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -744,7 +763,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -112,7 +112,7 @@ static inline intptr_t memprot_ll_peri1_rtcslow_get_fault_address(void)
static inline bool memprot_ll_peri1_rtcslow_is_intr_mine(void)
{
if (memprot_ll_dram0_is_assoc_intr()) {
if (memprot_ll_peri1_is_assoc_intr()) {
uint32_t faulting_address = (uint32_t)memprot_ll_peri1_rtcslow_get_fault_address();
return faulting_address >= PERI1_RTCSLOW_ADDRESS_LOW && faulting_address <= PERI1_RTCSLOW_ADDRESS_HIGH;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,7 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_io_struct.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_periph.h"
@ -25,7 +26,7 @@ extern "C" {
#endif
typedef enum {
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
} rtcio_ll_func_t;
@ -51,6 +52,16 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, 0x3, func, rtc_io_desc[rtcio_num].func);
}
/**
* @brief Enable/Disable LP IOMUX clock.
*
* @param enable true to enable the clock / false to disable the clock
*/
static inline void rtcio_ll_enable_io_clock(bool enable)
{
SENS.sar_io_mux_conf.iomux_clk_gate_en = enable;
}
/**
* @brief Select the rtcio function.
*
@ -61,14 +72,12 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
{
if (func == RTCIO_LL_FUNC_RTC) {
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
//0:RTC FUNCTION 1,2,3:Reserved
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
SENS.sar_io_mux_conf.iomux_clk_gate_en = 0;
}
}
@ -281,8 +290,7 @@ static inline void rtcio_ll_force_unhold_all(void)
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
{
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
RTCIO.pin[rtcio_num].wakeup_enable = 1;
RTCIO.pin[rtcio_num].int_type = type;
}
@ -293,7 +301,6 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t ty
*/
static inline void rtcio_ll_wakeup_disable(int rtcio_num)
{
SENS.sar_io_mux_conf.iomux_clk_gate_en = 0;
RTCIO.pin[rtcio_num].wakeup_enable = 0;
RTCIO.pin[rtcio_num].int_type = RTCIO_LL_WAKEUP_DISABLE;
}

View File

@ -681,6 +681,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -718,7 +737,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,7 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_io_struct.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_periph.h"
@ -42,6 +43,16 @@ typedef enum {
RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */
} rtcio_ll_out_mode_t;
/**
* @brief Enable/Disable LP IOMUX clock.
*
* @param enable true to enable the clock / false to disable the clock
*/
static inline void rtcio_ll_enable_io_clock(bool enable)
{
SENS.sar_peri_clk_gate_conf.iomux_clk_en = enable;
}
/**
* @brief Select a RTC IOMUX function for the RTC IO
*
@ -67,14 +78,12 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
if (rtcio_num == rtc_io_num_map[USB_INT_PHY0_DM_GPIO_NUM] || rtcio_num == rtc_io_num_map[USB_INT_PHY0_DP_GPIO_NUM]) {
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
}
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 1;
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
//0:RTC FUNCTION 1,2,3:Reserved
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 0;
// USB Serial JTAG pad re-enable won't be done here (it requires both DM and DP pins not in rtc function)
// Instead, USB_SERIAL_JTAG_USB_PAD_ENABLE needs to be guaranteed to be set in usb_serial_jtag driver
}
@ -307,8 +316,7 @@ static inline void rtcio_ll_force_unhold_all(void)
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
{
SENS.sar_peri_clk_gate_conf.iomux_clk_en = 1;
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
RTCIO.pin[rtcio_num].wakeup_enable = 1;
RTCIO.pin[rtcio_num].int_type = type;
}

View File

@ -717,6 +717,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the standard clock mode for master.
*
* @param hw Beginning address of the peripheral registers.
* @param enable_std True for std timing, False for half cycle delay sampling.
*/
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
{
//This is not supported
}
/**
* Get if standard clock mode is supported.
*/
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
{
return false;
}
/**
* Set the clock for master by stored value.
*
@ -754,7 +773,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
typeof(GPSPI2.clock) reg = {.val = 0};
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.

View File

@ -72,6 +72,7 @@ typedef struct {
spi_clock_source_t clock_source; ///< Clock source of each device used by LL layer
int timing_dummy; ///< Extra dummy needed to compensate the timing
int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing
spi_sampling_point_t rx_sample_point;///< Sample data follow standard SPI timing in master mode
} spi_hal_timing_conf_t;
/**

View File

@ -76,8 +76,15 @@ typedef enum {
SPI_CMD_HD_INT2 = BIT(9),
} spi_command_t;
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
/**
* @brief SPI master RX sample point mode configuration
*/
typedef enum {
SPI_SAMPLING_POINT_PHASE_0, ///< Data sampling point at 50% cycle delayed then standard timing, (default).
SPI_SAMPLING_POINT_PHASE_1, ///< Data sampling point follows standard SPI timing in master mode
} spi_sampling_point_t;
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
//alias for different chips, deprecated for the chips after esp32s2
#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_HOST SPI1_HOST
@ -89,7 +96,6 @@ typedef enum {
#define FSPI_HOST SPI2_HOST
#define HSPI_HOST SPI3_HOST
#endif
/** @endcond */
#ifdef __cplusplus

View File

@ -52,6 +52,7 @@ void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
#endif
spi_ll_master_set_pos_cs(hw, dev->cs_pin_id, dev->positive_cs);
spi_ll_master_set_clock_by_reg(hw, &dev->timing_conf.clock_reg);
spi_ll_master_set_rx_timing_mode(hw, dev->timing_conf.rx_sample_point);
//Configure bit order
spi_ll_set_rx_lsbfirst(hw, dev->rx_lsbfirst);
spi_ll_set_tx_lsbfirst(hw, dev->tx_lsbfirst);

View File

@ -2,6 +2,7 @@
archive: liblog.a
entries:
log:esp_log_write (noflash)
log:esp_log_writev (noflash)
log_freertos:esp_log_timestamp (noflash)
log_freertos:esp_log_early_timestamp (noflash)
log_freertos:esp_log_impl_lock (noflash)

View File

@ -1,3 +1,9 @@
components/nvs_flash/host_test:
enable:
- if: IDF_TARGET == "linux"
components/nvs_flash/test_apps:
disable_test:
- if: IDF_TARGET not in ["esp32", "esp32c3"]
temporary: true
reason: NVS flash test on one Xtensa and one RISCV target is enough

View File

@ -3,24 +3,23 @@
# esp-idf NVS partition generation tool. Tool helps in generating NVS-compatible
# partition binary, with key-value pair entries provided via a CSV file.
#
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
#
import argparse
import array
import binascii
import codecs
import csv
import datetime
import distutils.dir_util
import os
import random
import struct
import sys
import textwrap
import zlib
from io import open
import distutils.dir_util
try:
from cryptography.hazmat.backends import default_backend
@ -891,7 +890,7 @@ def generate_key(args):
encr_key_bytes = e_key + t_key
key_len = len(encr_key_bytes)
key = f"{int.from_bytes(encr_key_bytes, 'big'):x}"
key = encr_key_bytes.hex()
keys_buf[0:key_len] = encr_key_bytes
crc_data = keys_buf[0:key_len]

View File

@ -10,7 +10,8 @@ CONFIGS_NVS_ENCR_FLASH_ENC = [
]
@pytest.mark.supported_targets
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.generic
@pytest.mark.parametrize('config', ['default'], indirect=True)
def test_nvs_flash(dut: IdfDut) -> None:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,6 +9,7 @@
#include "esp_netif.h"
#include "esp_netif_types.h"
#include "esp_openthread.h"
#include "esp_openthread_spinel.h"
#include "openthread/instance.h"
#ifdef __cplusplus
@ -60,42 +61,6 @@ esp_err_t esp_openthread_border_router_deinit(void);
*/
esp_netif_t *esp_openthread_get_backbone_netif(void);
/**
* @brief Registers the callback for RCP failure.
*
*/
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
/**
* @brief Registers the callback for spinel compatibility error.
*
* @note This function must be called before esp_openthread_init.
*
* @param[in] callback The callback.
*
*/
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
/**
* @brief Deinitializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
*
*/
esp_err_t esp_openthread_rcp_deinit(void);
/**
* @brief Initializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to initialize RCP
*
*/
esp_err_t esp_openthread_rcp_init(void);
/**
* @brief Sets the meshcop(e) instance name.
*

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "esp_openthread_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Registers the callback for RCP failure.
*
*/
void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler);
/**
* @brief Registers the callback for spinel compatibility error.
*
* @note This function should be called before esp_openthread_init.
*
* @param[in] callback The callback.
*
*/
void esp_openthread_set_compatibility_error_callback(esp_openthread_compatibility_error_callback callback);
/**
* @brief Deinitializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if fail to deinitialize RCP
*
*/
esp_err_t esp_openthread_rcp_deinit(void);
/**
* @brief Initializes the connection to RCP.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to initialize RCP
*
*/
esp_err_t esp_openthread_rcp_init(void);
/**
* @brief Set the RCP version string.
*
* @note This function should be called before esp_openthread_init. When the RCP version string is not an empty string,
* compatibility checks will be performed during the initialization of the ESP OpenThread radio spinel.
* The `esp_openthread_compatibility_error_callback` will be triggered if the desired RCP version does not match
* the actual version running on the RCP. If needed, a NULL parameter can be passed to clear the version string.
*
* @param[in] version_str The pointer to RCP version string.
*
* @return
* - ESP_OK on success
* - ESP_FAIL if fail to set RCP version string
*
*/
esp_err_t esp_openthread_rcp_version_set(const char *version_str);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -198,8 +198,16 @@ typedef struct {
esp_openthread_port_config_t port_config; /*!< The port configuration */
} esp_openthread_platform_config_t;
/**
* @brief The OpenThread rcp failure handler
*
*/
typedef void (*esp_openthread_rcp_failure_handler)(void);
/**
* @brief The OpenThread compatibility error callback
*
*/
typedef void (*esp_openthread_compatibility_error_callback)(void);
#ifdef __cplusplus

View File

@ -494,16 +494,6 @@
#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000)
#endif
#if CONFIG_EXTERNAL_COEX_ENABLE
/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
*
* Enables compilation of vendor specific code for Spinel
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1
#endif
#endif
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
#if CONFIG_OPENTHREAD_LINK_METRICS

View File

@ -25,6 +25,9 @@
#include "openthread/platform/time.h"
#include "platform/exit_code.h"
#include "spinel_driver.hpp"
#include <cstring>
#define OT_SPINEL_RCP_VERSION_MAX_SIZE 100
using ot::Spinel::RadioSpinel;
using esp::openthread::SpinelInterfaceAdapter;
@ -56,34 +59,7 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL
static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL;
#if CONFIG_EXTERNAL_COEX_ENABLE
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
static esp_ieee802154_coex_config_t s_coex_config = {
.idle = IEEE802154_IDLE,
.txrx = IEEE802154_LOW,
.txrx_at = IEEE802154_MIDDLE,
};
static void esp_openthread_restore_coex_config(void *context)
{
esp_openthread_set_coex_config(s_coex_config);
}
static esp_err_t esp_openthread_radio_spinel_coex_config_init(void)
{
s_radio.SetVendorRestorePropertiesCallback(esp_openthread_restore_coex_config, esp_openthread_get_instance());
esp_ieee802154_coex_config_t coex_config;
uint16_t coex_config_len = 0;
ESP_RETURN_ON_ERROR(s_radio.Get(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &coex_config, &coex_config_len),
OT_PLAT_LOG_TAG, "Fail to get coex config");
ESP_RETURN_ON_FALSE(coex_config_len == sizeof(esp_ieee802154_coex_config_t), ESP_FAIL, OT_PLAT_LOG_TAG,
"Fail to get coex config");
s_coex_config = coex_config;
return ESP_OK;
}
#endif
static char s_internal_rcp_version[OT_SPINEL_RCP_VERSION_MAX_SIZE] = {'\0'};
static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config)
{
@ -136,11 +112,18 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf
"Spinel interface init failed");
#endif
s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid);
if (strlen(s_internal_rcp_version) > 0) {
const char *running_rcp_version = s_spinel_driver.GetVersion();
if (strcmp(s_internal_rcp_version, running_rcp_version) != 0) {
if (s_compatibility_error_callback) {
s_compatibility_error_callback();
} else {
ESP_LOGW(OT_PLAT_LOG_TAG, "The running rcp does not match the provided rcp");
}
}
}
s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance());
s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true);
#if CONFIG_EXTERNAL_COEX_ENABLE
ESP_RETURN_ON_ERROR(esp_openthread_radio_spinel_coex_config_init(), OT_PLAT_LOG_TAG, "Coex config init failed");
#endif
#if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed");
#endif
@ -185,12 +168,24 @@ esp_err_t esp_openthread_rcp_init(void)
radiospinel_workflow);
}
esp_err_t esp_openthread_rcp_version_set(const char *version_str)
{
if (version_str == NULL) {
memset(s_internal_rcp_version, 0, OT_SPINEL_RCP_VERSION_MAX_SIZE);
return ESP_OK;
}
ESP_RETURN_ON_FALSE(strlen(version_str) > 0 && strlen(version_str) < OT_SPINEL_RCP_VERSION_MAX_SIZE, ESP_FAIL, OT_PLAT_LOG_TAG, "Invalid rcp version");
strcpy(s_internal_rcp_version, version_str);
return ESP_OK;
}
void esp_openthread_radio_deinit(void)
{
s_radio.Deinit();
s_spinel_driver.Deinit();
s_spinel_interface.GetSpinelInterface().Disable();
esp_openthread_platform_workflow_unregister(radiospinel_workflow);
s_compatibility_error_callback = NULL;
}
esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop)
@ -515,39 +510,3 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
// Refer to `GetRadioChannelMask(bool aPreferred)`: FALSE to get supported channel mask
return s_radio.GetRadioChannelMask(false);
}
#if CONFIG_EXTERNAL_COEX_ENABLE
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config)
{
otError err = s_radio.Set(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &s_coex_config, sizeof(esp_ieee802154_coex_config_t));
ESP_RETURN_ON_FALSE(err == OT_ERROR_NONE, , OT_PLAT_LOG_TAG, "Fail to set coex config");
s_coex_config = config;
}
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void)
{
return s_coex_config;
}
namespace ot {
namespace Spinel {
otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey)
{
otError error = OT_ERROR_NONE;
switch (aPropKey)
{
default:
ESP_LOGW(OT_PLAT_LOG_TAG, "Not Implemented!");
error = OT_ERROR_NOT_FOUND;
break;
}
return error;
}
} // namespace Spinel
} // namespace ot
#endif

View File

@ -63,7 +63,7 @@ static void handle_ot_netdata_change(void)
static void handle_ot_role_change(otInstance* instance)
{
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE && OPENTHREAD_RADIO_NATIVE) || CONFIG_EXTERNAL_COEX_ENABLE)
#if ((CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) && OPENTHREAD_RADIO_NATIVE)
otLinkModeConfig linkmode = otThreadGetLinkMode(instance);
esp_ieee802154_coex_config_t config = esp_openthread_get_coex_config();
config.txrx = (linkmode.mRxOnWhenIdle) ? IEEE802154_LOW : IEEE802154_MIDDLE;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -64,11 +64,12 @@ esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *conf
#ifndef CONFIG_ESP_CONSOLE_UART
// If UART console is used, UART vfs devices should be registered during startup.
// Otherwise we need to register them here.
DIR *uart_dir = opendir("/dev/uart");
if (!uart_dir) {
char uart_path[16];
snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", config->port);
bool is_uart_registered = (access(uart_path, F_OK) == 0);
if (!is_uart_registered) {
// If UART vfs devices are registered, we will failed to open the directory
esp_vfs_dev_uart_register();
} else {
closedir(uart_dir);
}
#endif
ESP_RETURN_ON_ERROR(uart_param_config(config->port, &config->uart_config), OT_PLAT_LOG_TAG,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -266,8 +266,8 @@ otError SpiSpinelInterface::WaitForFrame(uint64_t timeout_us)
otError SpiSpinelInterface::HardwareReset(void)
{
if (mRcpFailureHandler) {
ConductSPITransaction(true, 0, 0); // clear
mRcpFailureHandler();
ConductSPITransaction(true, 0, 0); // clear
}
return OT_ERROR_NONE;
}

View File

@ -667,6 +667,14 @@ config SOC_TIMER_GROUP_SUPPORT_APB
bool
default y
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TOUCH_VERSION_1
bool
default y

View File

@ -571,8 +571,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period);
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
#define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup

View File

@ -317,6 +317,10 @@
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
#define SOC_TIMER_GROUP_SUPPORT_APB (1)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */
#define SOC_TOUCH_SENSOR_NUM (10)

View File

@ -559,6 +559,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 1
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -603,8 +603,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period);
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

View File

@ -265,6 +265,10 @@
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (1U)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -803,6 +803,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -648,8 +648,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode.
*
* @param slowclk_period re-calibrated slow clock period
* @param dslp true if initialize for deepsleep request
*/
void rtc_sleep_low_init(uint32_t slowclk_period);
void rtc_sleep_low_init(uint32_t slowclk_period, bool dslp);
#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

Some files were not shown because too many files have changed in this diff Show More