Compare commits

...

112 Commits

Author SHA1 Message Date
Nebojša Cvetković
4c5d9743a4
Merge 7dbf96baaddd52bd3b897e706787b4d8b280f532 into 83e8f70ee4f7ddb6b874bdb81a1f75ceeeba58e4 2025-03-01 10:11:34 +05:30
Abhik Roy
83e8f70ee4 Merge branch 'lwip/ip_napt_enable_fix' into 'master'
fix(lwip): Fixed NULL pointer dereference in ip_napt_enable; add unit tests

Closes IDFGH-12823 and IDF-8155

See merge request espressif/esp-idf!36810
2025-02-27 20:09:10 +08:00
Wang Meng Yang
9f68b151db Merge branch 'bugfix/bt_ctrl_issues' into 'master'
fix(bt/controller): fixed some controller bugs on ESP32.

Closes IDFGH-14343, IDFGH-14392, and IDFGH-12607

See merge request espressif/esp-idf!37180
2025-02-27 19:39:46 +08:00
Chen Ji Chang
de853be81e Merge branch 'feat/h4_introduce_step4_rom_support' into 'master'
feat(esp32h4): add esp_rom and efuse files (stage4)

See merge request espressif/esp-idf!37160
2025-02-27 18:11:44 +08:00
Wu Zheng Hui
2d1c99e74f Merge branch 'fix/fix_bad_dslp_param_after_lightsleep' into 'master'
fix(esp_hw_support): Fixed the issue that light sleep destroyed the parameters of subsequent deep sleep

Closes PM-366 and BLERP-1602

See merge request espressif/esp-idf!37276
2025-02-27 15:51:55 +08:00
Frantisek Hrbata
4f968c3fc5 Merge branch 'contrib/github_pr_15401' into 'master'
Fix idf_as_lib example (GitHub PR)

Closes IDFGH-14655

See merge request espressif/esp-idf!37127
2025-02-27 15:00:12 +08:00
Song Ruo Jing
ce3d603e05 Merge branch 'feature/esp32h21_gdma_support' into 'master'
feat(gdma): add GDMA support for ESP32H21

Closes IDF-11603 and IDF-11604

See merge request espressif/esp-idf!37063
2025-02-27 14:07:52 +08:00
Chen Ji Chang
f02812544e Merge branch 'fix/fix_parlio_test_case' into 'master'
fix(parlio): increase test case success rate

See merge request espressif/esp-idf!37307
2025-02-27 14:04:38 +08:00
Mahavir Jain
e81a9285fe Merge branch 'bugfix/esp32s2_memprot_clear' into 'master'
fix(esp_hw_support): clear the memory protection interrupt status on boot

Closes IDFGH-5968 and IDFGH-14602

See merge request espressif/esp-idf!36801
2025-02-27 12:54:06 +08:00
Chen Jichang
a07e67893b fix(parlio): increase test case success ratio 2025-02-27 11:58:52 +08:00
C.S.M
dbd2aa8c54 Merge branch 'refactor/optimize_flash_iram_usage' into 'master'
refactor(spi_flash): optimize flash functions to save IRAM memory

See merge request espressif/esp-idf!36902
2025-02-27 11:26:23 +08:00
Michael (XIAO Xufeng)
80bc9d8828 Merge branch 'feat/h2_v1.2_compatibility' into 'master'
doc(compatibility): add compatibility info for h2 v1.2

See merge request espressif/esp-idf!37174
2025-02-27 09:03:07 +08:00
Jaroslav Burian
1f08a8c67e Merge branch 'fix/flush_esptool_output' into 'master'
fix(esptool): Fix flush output while flashing

Closes ESPTOOL-1014

See merge request espressif/esp-idf!37243
2025-02-27 06:34:45 +08:00
Island
371c7edb22 Merge branch 'dev/ble_log_spi_output' into 'master'
fix(ble): fix flushout and sync issues

See merge request espressif/esp-idf!37282
2025-02-26 23:00:40 +08:00
Martin Vychodil
8606eb43f7 Merge branch 'feat/optimize_vfs_mountpoint_table' into 'master'
feat(storage/vfs): improve mountpoint table memory usage

Closes IDF-12560

See merge request espressif/esp-idf!36613
2025-02-26 22:08:15 +08:00
Martin Vychodil
fec59ecb42 Merge branch 'docs/fatfs_unlink_discrepancy' into 'master'
docs(storage/fatfs): discrepancies between FATFS and POSIX

Closes IDFGH-14405 and DOC-10313

See merge request espressif/esp-idf!36941
2025-02-26 21:40:29 +08:00
Igor Masar
d53b0a9111 Merge branch 'fix/usb-hal-dwc-host-channel-num' into 'master'
fix(usb/hal/dwc): Correct host channel number calculation

See merge request espressif/esp-idf!37173
2025-02-26 21:19:51 +08:00
Tomas Rezucha
51fd02dd83 Merge branch 'fix/usb_phy_set_speed' into 'master'
fix(usb/phy): Fixed crash on external PHY init with speed != UNDEFINED

See merge request espressif/esp-idf!37218
2025-02-26 19:50:23 +08:00
C.S.M
8f371a5004 docs(spi_flash): Add docs for spi_flash IRAM usage 2025-02-26 18:29:35 +08:00
C.S.M
b66e140fbc refactor(spi_flash): optimize flash functions to save iram memory 2025-02-26 18:28:49 +08:00
Mahavir Jain
8014ffa225 Merge branch 'fix/esp_tee_aes_sha_prot' into 'master'
fix(esp_tee): Protect the AES/SHA clock registers from REE access

Closes IDF-8954 and IDF-7188

See merge request espressif/esp-idf!36783
2025-02-26 18:06:44 +08:00
Zhang Shu Xian
656415b8aa Merge branch 'docs/update_cn_translation_for_storage_fatfs' into 'docs/fatfs_unlink_discrepancy'
docs: Update CN translation for fatfs

See merge request espressif/esp-idf!37155
2025-02-26 17:50:42 +08:00
igor.masar
dfd8098716 fix(usb/hal/dwc): Correct host channel number calculation
The hardware field `ghwcfg2.numhstchnl` is zero-based, meaning the actual
number of available host channels is `numhstchnl + 1`. This off-by-one
error caused the USB Host controller to report N-1 channels instead of N,
leading to premature "No more HCD channels available" errors when
connecting multiple devices.

This issue affects ESP32-S2, ESP32-S3, and ESP32-P4.
2025-02-26 17:29:06 +08:00
Jaroslav Burian
64f4956d4f fix(esptool): Fix flush output while flashing
With the new esptool v5.0 the output is not flushed while flashing
the firmware. This commit fixes the issue by using python unbuffered mode.
2025-02-26 10:04:16 +01:00
Shu Chen
aa424235e2 Merge branch 'fix/fix_ot_uart_init_bug' into 'master'
fix(openthread): fix a bug of openthread uart init port

Closes TZ-1564

See merge request espressif/esp-idf!37284
2025-02-26 16:46:27 +08:00
Jin Cheng
309747bf9a fix(bt/controller): fixed some controller bugs on ESP32.
1. added a VSC to control whether to initiate lmp_auto_rate
        - Closes https://github.com/espressif/esp-idf/issues/15133
    2. fixed EA resource cleanup error after SNIFF negotiation failure
        - Closes https://github.com/espressif/esp-idf/issues/13605
    3. removed an assertion in SCO data TX handler after disconnection
        - Closes https://github.com/espressif/esp-idf/issues/15176
2025-02-26 16:31:06 +08:00
Michael (XIAO Xufeng)
70b474a08a Merge branch 'feat/c2_v2.0_compatibility' into 'master'
hw_support: Add compatibility information and Kconfig option for c2 v2.0

See merge request espressif/esp-idf!35831
2025-02-26 16:01:58 +08:00
Konstantin Kondrashov
8778ed2812 Merge branch 'feature/update_ring_buffer_doc' into 'master'
feat(esp_ringbuf): Update ring buffer doc

Closes IDFGH-14536

See merge request espressif/esp-idf!36760
2025-02-26 15:58:36 +08:00
Konstantin Kondrashov
038d99f3c5 feat(efuse): Generate efuse source files for ESP32-H4 2025-02-26 09:50:11 +02:00
Island
6aa557c845 Merge branch 'feat/add_save_debug_context_250226' into 'master'
Feat/add save debug context 250226

Closes BLERP-1561 and BLERP-1604

See merge request espressif/esp-idf!37281
2025-02-26 14:45:33 +08:00
Zhou Xiao
b144337020 fix(ble): fix flushout and sync issues 2025-02-26 12:27:22 +08:00
Wu Zheng Hui
132444cd08 Merge branch 'feat/support_esp32h21_modem_clock' into 'master'
feat(esp_hw_support): support esp32h21 modem clock

Closes PM-348

See merge request espressif/esp-idf!37082
2025-02-26 12:02:43 +08:00
Xu Si Yu
76c207250d fix(openthread): fix a bug of openthread uart init port 2025-02-26 11:53:55 +08:00
morris
548caad60b Merge branch 'doc/wrong_info_about_psram_support' into 'master'
docs(gpio): fix wrong psram support information

See merge request espressif/esp-idf!37280
2025-02-26 11:48:21 +08:00
zwl
da07b1fabe feat(ble): add a debug way to retain scene on ESP32-C5 2025-02-26 11:02:56 +08:00
zwl
bc299e784c feat(ble): add a debug way to retain scene on ESP32-C6 2025-02-26 11:00:12 +08:00
Island
efdce75bb1 Merge branch 'fix/feed_wdts_during_ble_log_dump_c2' into 'master'
fix(ble): add feed wdts during ble log dump for ESP32-C2

Closes BLERP-1598

See merge request espressif/esp-idf!37265
2025-02-26 10:42:59 +08:00
zwl
5b8ac71ace fix(ble): fixed common kconfig error when controller enable only 2025-02-26 10:37:35 +08:00
morris
3dc8c0f3cb docs(gpio): fix wrong psram support information
PSRAM is NOT supported on esp32c3, but IS supported on esp32c5 and
esp32c61
2025-02-26 10:23:18 +08:00
wuzhenghui
dd2bde0847
fix(esp_hw_support): fix lightsleep destroys deepsleep rtc parameters 2025-02-26 10:13:07 +08:00
Zhang Shuxian
26078bbf9a docs: Update CN translation for fatfs 2025-02-26 10:04:26 +08:00
Abhik Roy
c264d8c580 fix(lwip): Fixed NULL pointer dereference in ip_napt_enable; add unit tests
[LWIP submodule changes]: git log --oneline fa4dffdf..0a44efa1

Detailed description of the changes:
  - napt: Fixed NULL pointer dereference in ip_napt_enable (espressif/esp-lwip@0a44efa1)
  - napt: Added unit tests for napt (espressif/esp-lwip@865d7d0c)

Closes https://github.com/espressif/esp-lwip/issues/69
2025-02-26 00:24:10 +11:00
Island
0461e2ff88 Merge branch 'feat/add_ble_ctrl_log_module_on_esp32c3' into 'master'
feat(bt): Added BLE log module on ESP32-C3 and ESP32-S3(723439d)

Closes BLERP-1590 and BLERP-1591

See merge request espressif/esp-idf!37220
2025-02-25 20:40:41 +08:00
Laukik Hase
873409da6b
refactor(esp_tee): Simplify service call ASM routine
- Remove `mret` for jumping to the service call dispatcher; instead, enable
  interrupts and execute directly
- Fix potential corruption of the `t3` register when returning from a service
  call
- Simplify the secure service dispatcher function
2025-02-25 17:18:08 +05:30
Wang Meng Yang
909d81283d Merge branch 'docs/fix_some_coexist_doc_issue' into 'master'
docs(coex): update rf coexistence documents

See merge request espressif/esp-idf!36974
2025-02-25 19:33:14 +08:00
Chen Jichang
a74f9cbe63 feat(esp32h4): add esp_rom and efuse files (stage4) 2025-02-25 19:30:03 +08:00
Laukik Hase
5c4a527750
refactor(esp_tee): Remove explicit setting of the HP_CPU APM/TEE security mode 2025-02-25 16:49:08 +05:30
Laukik Hase
26fa7109f3
fix(esp_tee): Protect the AES/SHA clock registers from REE access 2025-02-25 16:49:08 +05:30
Omar Chebib
a99753d293 fix(esp_hw_support): clear the memory protection interrupt status on boot
Fixes https://github.com/espressif/esp-idf/issues/15359
2025-02-25 18:06:38 +08:00
Zhou Xiao
e2e8e7dce1 fix(ble): add feed wdts during ble log dump for ESP32-C2 2025-02-25 17:57:15 +08:00
Roman Leonov
d7222cc89e Merge branch 'feature/usb_host_ext_hub_error_handle' into 'master'
feat(ext_hub): Added device error handling

Closes IDF-10057

Closes https://github.com/espressif/esp-idf/issues/15437

See merge request espressif/esp-idf!33956
2025-02-25 17:18:46 +08:00
Song Ruo Jing
a4a28b57a3 feat(gdma): add GDMA support for ESP32H21 2025-02-25 17:05:48 +08:00
linruihao
9f0c8e7bfc docs(coex): update rf coexistence documents
- remove BLE connecting state in coexistence scenario
- remove WIFI section in H2 docs
2025-02-25 17:05:34 +08:00
Frantisek Hrbata
54cb6636ec ci: add idf_as_lib to patterns-build_system rules
The `idf_as_lib` example is used and tested in
`tools/test_build_system/test_cmake.py`. Include `idf_as_lib` in the
build_system rules to ensure the tests are executed whenever there is a
modification in the `idf_as_lib` example.

Expand the `test_build_custom_cmake_project` test to cover all supported
targets, including host build.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2025-02-25 08:54:02 +01:00
chenjianhua
d4c15e2cb6 feat(bt): Update bt lib for ESP32-C3 and ESP32-S3(723439d)
- Added BLE controller debug log trace
- Added BLE controller log module
2025-02-25 15:18:58 +08:00
Aditya Patwardhan
61f992a061 Merge branch 'contrib/github_pr_15291' into 'master'
fix(esp_http_client): Fix invalid content length header (GitHub PR)

Closes IDFGH-14528

See merge request espressif/esp-idf!37036
2025-02-25 13:03:12 +08:00
Chen Ji Chang
e7088bbd07 Merge branch 'feat/add_uart_support_on_h21' into 'master'
feat(uart): support uart on esp32h21

Closes IDF-11618, IDF-11620, and IDF-12143

See merge request espressif/esp-idf!37197
2025-02-25 11:26:09 +08:00
Gao Xu
d17b0ed4fe Merge branch 'feature/esp32h21_gpio_support' into 'master'
feat(esp32h21): support GPIO on esp32h21

Closes IDF-11611

See merge request espressif/esp-idf!36781
2025-02-25 11:12:54 +08:00
Igor Udot
13188dc33b Merge branch 'ci/update_patterns-build_check' into 'master'
ci: add build_system example to patterns-build_check

See merge request espressif/esp-idf!37191
2025-02-25 10:34:39 +08:00
Erhan Kurubas
e405583bae Merge branch 'update_usb_jtag_doc' into 'master'
docs(jtag): add esp32p4 usb jtag pin numbers

Closes DOC-10317

See merge request espressif/esp-idf!36698
2025-02-24 21:12:34 +08:00
morris
e964cc3ad5 Merge branch 'refactor/gptimer_isr_logs_opt_int' into 'master'
feat(gptimer): make start and stop function idempotent, also refactored the doc structure

Closes IDFGH-11157, IDFGH-12474, IDF-12513, and IDFCI-2734

See merge request espressif/esp-idf!36983
2025-02-24 20:51:42 +08:00
Roman Leonov
e815f68a50 docs(usb_host): Removed the limitation for Low-speed device connected via hub 2025-02-24 19:39:53 +08:00
Roman Leonov
858947e461 feat(ext_hub): Added support for low-speed devices, connected via hubs 2025-02-24 19:39:53 +08:00
Jiang Jiang Jian
837311c0ff Merge branch 'bugfix/pmkid_password_mismatch' into 'master'
fix(wifi): Fix wrong PMKSA cache entry being used when wifi password is changed

Closes WIFIBUG-622, WIFIBUG-648, and WIFIBUG-702

See merge request espressif/esp-idf!33285
2025-02-24 19:37:49 +08:00
Wan Lei
73eb376eb1 Merge branch 'feat/h21_gptimer_support' into 'master'
feat(driver_gptimer): esp32h21 add basic gptimer support

Closes IDF-11594

See merge request espressif/esp-idf!37028
2025-02-24 19:32:11 +08:00
Chen Jichang
028a16c01c feat(uart): support uart on esp32h21 2025-02-24 17:49:45 +08:00
gaoxu
7e54886a4e feat(esp32h21): move gpio intr source to gpio_ll.h 2025-02-24 17:32:01 +08:00
gaoxu
51ad6cfab0 feat(esp32h21): support RTC_IO and hysteresis on ESP32H21 2025-02-24 17:31:55 +08:00
gaoxu
d3acbe15aa feat(esp32h21): refactor gpio_ll to use io_mux_struct 2025-02-24 17:25:58 +08:00
gaoxu
760f134d84 feat(esp32h21): support GPIO on esp32h21 2025-02-24 17:24:16 +08:00
morris
046279155d Merge branch 'fix/spi_device_dynamic_freq_bug' into 'master'
fix(driver_spi): fixed wrong condition check in master driver device override_freq_hz feature

Closes IDF-12525

See merge request espressif/esp-idf!37222
2025-02-24 16:40:47 +08:00
Mahavir Jain
18c09cfe64 Merge branch 'fix/fix_security_app_readme' into 'master'
fix(security): Fixed README for security features app

See merge request espressif/esp-idf!37140
2025-02-24 16:08:39 +08:00
Mahavir Jain
e2fc36349a Merge branch 'contrib/github_pr_15388' into 'master'
fix(esp_http_client): Fix host header for IPv6 address literal (GitHub PR)

Closes IDFGH-14640

See merge request espressif/esp-idf!37035
2025-02-24 16:02:27 +08:00
Song Ruo Jing
c9dff55c9f Merge branch 'bugfix/gpio_standardization_fix' into 'master'
fix(gpio): minor improvement to output/input configuration step

Closes IDF-12240

See merge request espressif/esp-idf!36973
2025-02-24 15:56:59 +08:00
Armando (Dou Yiwen)
97b7b880c7 Merge branch 'refactor/rng_ll_c61' into 'master'
rng: refactor to use hal/ll apis for esp32c61

Closes IDF-12467

See merge request espressif/esp-idf!37019
2025-02-24 15:47:38 +08:00
Chen Ji Chang
33e81e572b Merge branch 'feat/h4_introduce_step2_3' into 'master'
feat(esp32h4): add soc register header files (stage 3/8, part 3/3)

See merge request espressif/esp-idf!37092
2025-02-24 15:39:11 +08:00
morris
5f70a525f0 doc(gptimer): refactor doc structure
Split into two parts: quick start and advanced usage
2025-02-24 15:04:19 +08:00
morris
9822433957 feat(gptimer): make start and stop function idempotent
Closes https://github.com/espressif/esp-idf/issues/12325
Closes https://github.com/espressif/esp-idf/issues/13486
2025-02-24 14:53:34 +08:00
Island
5f2a7f4d29 Merge branch 'feat/add_ble_spi_log' into 'master'
fix(ble/bluedroid): Support SPI log output options for HCI

Closes BLERP-1585 and BLERP-1586

See merge request espressif/esp-idf!37207
2025-02-24 14:37:41 +08:00
Mahavir Jain
37a4de8a71 Merge branch 'fix/incorrect_calculation_of_used_xip_pages' into 'master'
fix(esp_psram): Fix incorrect calculation of used XIP PSRAM pages

See merge request espressif/esp-idf!37069
2025-02-24 13:54:53 +08:00
morris
0d6b29c369 Merge branch 'chor/update_etm_register_esp32c61' into 'master'
change(etm): update soc register files for esp32c61

See merge request espressif/esp-idf!37152
2025-02-24 13:22:23 +08:00
Chen Jichang
62700fa36f feat(esp32h4): add soc register header files (stage2_3)
add soc headers made by hand
2025-02-24 12:20:27 +08:00
wanckl
90728ade83 fix(driver_spi): fixed wrong condition check in master driver device override_freq_hz feature 2025-02-24 11:50:42 +08:00
Armando
c7ee2d7157 refactor(pmu): replace regi2c registers with LL APIs 2025-02-24 11:16:48 +08:00
Armando
d598c9db7c refactor(rng): refactor to use hal/ll apis for c61 2025-02-24 11:16:48 +08:00
zhanghaipeng
b6903296ad fix(ble/bluedroid): Added SPI output support for Bluedroid host log 2025-02-23 17:23:54 +08:00
zhanghaipeng
e00ba3cbd1 fix(ble/bluedroid): Support SPI log output options for HCI 2025-02-23 11:46:47 +08:00
Tomas Rezucha
ca24a117c7 fix(usb/phy): Fixed crash on external PHY init with speed != UNDEFINED
Also deprecated usb_phy_otg_dev_set_speed()
and usb_phy_action() which are no longer used in esp-idf
2025-02-21 14:11:51 +01:00
wanckl
cfe4bf339f feat(driver_gptimer): esp32h21 add basic gptimer support 2025-02-21 20:22:41 +08:00
Erhan Kurubas
93b4ef13ae docs(jtag): add esp32p4 usb jtag pin numbers 2025-02-21 10:32:43 +01:00
harshal.patil
a1e6387c16
fix(esp_psram): Fix incorrect calculation of used XIP PSRAM pages
The functions mmu_config_psram_text_segment() and mmu_config_psram_rodata_segment()
used to return the value of next start page in *out_page instead of the number
of pages used as mentioned in the documentation
2025-02-21 11:07:39 +05:30
Sarvesh Bodakhe
3d5bf355c3 fix(wifi): Fix wrong PMKSA cache entry being used when wifi password is changed 2025-02-21 10:54:57 +05:30
igor.udot
7bc8938469 ci: add build_system example to patterns-build_check 2025-02-21 12:25:45 +08:00
Aditya Patwardhan
786dcacd8b
fix(security): Fixed README for security features app 2025-02-20 22:05:48 +05:30
Michael (XIAO Xufeng)
1aae76f524 doc(compatibility): add compatibility info for h2 v1.2 2025-02-20 22:10:01 +08:00
Xiao Xufeng
7361aca98b doc(compatibility): add compatibility info for c2 v2.0 2025-02-20 21:56:25 +08:00
Song Ruo Jing
53d8b70e8b fix(gpio): fix IO output enable control
oen_sel and oen_inv_sel fields from func_out_sel_cfg register
2025-02-20 19:49:28 +08:00
Song Ruo Jing
1d6bcb86ba fix(gpio): removed unnecessary step when routing input signal to a pin 2025-02-20 18:54:19 +08:00
Song Ruo Jing
a88bd155cd fix(ledc): overflowed integer argument in ledc_hal_clear_left_off_fade_param 2025-02-20 18:54:19 +08:00
wuzhenghui
d305628c25
feat(hal): add esp32h21 modem_clock hal layer 2025-02-20 15:18:13 +08:00
wuzhenghui
88a3a6c58d
feat(soc): add esp32h21 modem_clock registers 2025-02-20 15:16:12 +08:00
morris
90d59288b1 change(etm): update soc register files for esp32c1
removed unavailable fields
2025-02-20 14:20:05 +08:00
Darian Leung
3b28818ba4
fix(examples): idf_as_lib linux build
The Linux build was broken after IDF flash API was updated without updating
the Linux stub library in the example. This commit updates the spi_flash stub
library such that:

- The API now matches same API as IDF's spi_flash component
- Links the stub_esp32 library to pull in basic types and defines
2025-02-19 18:41:05 +08:00
Darian Leung
0b6922405d
fix(examples): idf_as_lib move flash_ops.c to spi_flash stub library
Example linux build of the example demonstrates "esp32" and "spi_flash" stub
libraries (roughly analogous to "esp_system" and "spi_flash" components).

This commit moves the "flash_ops.c" file to the "spi_flash" stub library as it
is a flash related funciton.

Also renamed the header to "esp_flash.h" (in order to match current header name
in IDF). This is a prerequisite to fixing the linux build of this example.
2025-02-19 18:41:05 +08:00
Darian Leung
5301eaf0d8
fix(examples): Fix idf_as_lib for esp32p4
The build-esp32p4.sh and run-esp32p4.sh scripts are not symbolic links to the
base scripts, leading to a "permission denied" error. This commit changes their
types to symbolic links, in line with the other targets.
2025-02-19 18:39:18 +08:00
Bernhard Heinloth
f31a0f7f61 fix(esp_http_client): Fix host header for IPv6 address literal
An IPv6 IP that occurs in the 'Host:' header of an HTTP request must be enclosed
in square brackets (RFC3986 section 3.2.2).

Searches for ':' in the host string to efficiently determine if the host is an
IPv6 IP address.
2025-02-19 10:41:05 +01:00
Nebojsa Cvetkovic
7dbf96baad fix(esp_netif): Free allocation if pppos_create fails 2025-02-13 12:49:29 +00:00
Tomáš Rohlínek
09aae72bfa
docs(storage/fatfs): discrepancies between FATFS and POSIX
Closes https://github.com/espressif/esp-idf/issues/15187
2025-02-13 10:15:52 +01:00
Tomáš Rohlínek
67638981ec
feat(storage/vfs): cleanup path prefix handling 2025-02-07 10:34:24 +01:00
Konstantin Kondrashov
8155e60edf feat(esp_ringbuf): Update ring buffer doc
Closes https://github.com/espressif/esp-idf/issues/15298
2025-02-06 17:44:14 +02:00
Tomáš Rohlínek
a45b12a68b
feat(storage/vfs): improve mountpoint table memory usage 2025-01-30 09:07:51 +01:00
Christopher Durand
c0590f5b50 fix(esp_http_client): Fix invalid content length header
In case a request with no content is sent after one with the content
length header set the header of the previous request is sent with the
subsequent one.
For instance, an empty GET request after a PUT request will still
indicate the non-zero content length of the previous request.

This is fixed by clearing the content length header when it shouldn't be
set.
2025-01-27 12:09:23 +01:00
334 changed files with 20301 additions and 5430 deletions

View File

@ -68,6 +68,7 @@
- "tools/ci/check_public_headers.py" - "tools/ci/check_public_headers.py"
- "tools/ci/check_register_rw_half_word.cmake" - "tools/ci/check_register_rw_half_word.cmake"
- "tools/ci/check_register_rw_half_word.py" - "tools/ci/check_register_rw_half_word.py"
- "examples/build_system/**/*"
.patterns-host_test: &patterns-host_test .patterns-host_test: &patterns-host_test
- ".gitlab/ci/host-test.yml" - ".gitlab/ci/host-test.yml"

View File

@ -97,6 +97,18 @@ Supported since ESP-IDF v5.0.
| release/v5.2 | v5.2.2+ | v5.2 | | release/v5.2 | v5.2.2+ | v5.2 |
| release/v5.3 and above | v5.3+ | v5.3 | | release/v5.3 and above | v5.3+ | v5.3 |
#### v2.0
| Release branch | Recommended | Required |
|------------------------|-------------|----------|
| release/v5.0 | v5.0.8+ | v5.0.8 |
| release/v5.1 | v5.1.5+ | v5.1.5* |
| release/v5.2 | v5.2.4+ | v5.2.4 |
| release/v5.3 | v5.3.2+ | v5.3.2* |
| release/v5.4 and above | v5.4+ | v5.4 |
Note: IDF v5.1.5 and v5.3.2 are compatible with C2 v2.0. However the chip revision check hasn't been updated on these releases. Enable `ESP32C2_REV2_DEVELOPMENT` config to bypass the outdated check.
### ESP32-C6 ### ESP32-C6
#### v0.0, v0.1 #### v0.0, v0.1
@ -109,6 +121,16 @@ Supported since ESP-IDF v5.1.
Supported since ESP-IDF v5.1. Supported since ESP-IDF v5.1.
#### v1.2
| Release branch | Recommended | Required |
|------------------------|-------------|----------|
| release/v5.1 | v5.1.6+ | v5.1.6 |
| release/v5.2 | v5.2.5+ | v5.2.5 |
| release/v5.3 | v5.3.3+ | v5.3.3 |
| release/v5.4 | v5.4.1+ | v5.4.1 |
| release/v5.5 and above | v5.5+ | v5.5 |
## What If the ESP-IDF Version Is Lower than the `Required` Version? ## What If the ESP-IDF Version Is Lower than the `Required` Version?
Latest ESP-IDF versions can prevent from downloading to, or even execute binaries on unsupported chips. ESP-IDF of versions v4.4.5+, v5.0.1+, v5.1 and above have both esptool download check and bootloader loading check against the chip revision. While ESP-IDF v4.3.5 has only esptool downloading check. Latest ESP-IDF versions can prevent from downloading to, or even execute binaries on unsupported chips. ESP-IDF of versions v4.4.5+, v5.0.1+, v5.1 and above have both esptool download check and bootloader loading check against the chip revision. While ESP-IDF v4.3.5 has only esptool downloading check.

View File

@ -97,6 +97,18 @@
| release/v5.2 | v5.2.2+ | v5.1 | | release/v5.2 | v5.2.2+ | v5.1 |
| release/v5.3 及以上 | v5.3+ | v5.3 | | release/v5.3 及以上 | v5.3+ | v5.3 |
#### v2.0
| 发布分支 | 推荐版本 | 需求版本 |
|------------------------|-------------|----------|
| release/v5.0 | v5.0.8+ | v5.0.8 |
| release/v5.1 | v5.1.5+ | v5.1.5* |
| release/v5.2 | v5.2.4+ | v5.2.4 |
| release/v5.3 | v5.3.2+ | v5.3.2* |
| release/v5.4 及以上 | v5.4+ | v5.4 |
提示: IDF v5.1.5 及 v5.3.2 与 C2 v2.0 兼容,但芯片版本检查尚未在这些发布版本更新。使能 `ESP32C2_REV2_DEVELOPMENT` 选项来跳过这些过时的检查。
### ESP32-C6 ### ESP32-C6
#### v0.0, v0.1 #### v0.0, v0.1
@ -109,6 +121,16 @@
从 ESP-IDF v5.1 开始支持。 从 ESP-IDF v5.1 开始支持。
#### v1.2
| 发布分支 | 推荐版本 | 需求版本 |
|------------------------|-------------|----------|
| release/v5.1 | v5.1.6+ | v5.1.6 |
| release/v5.2 | v5.2.5+ | v5.2.5 |
| release/v5.3 | v5.3.3+ | v5.3.3 |
| release/v5.4 | v5.4.1+ | v5.4.1 |
| release/v5.5 及以上 | v5.5+ | v5.5 |
## 如果 ESP-IDF 版本低于 `需求版本` 会出现什么情况? ## 如果 ESP-IDF 版本低于 `需求版本` 会出现什么情况?

View File

@ -702,6 +702,5 @@ mainmenu "Espressif IoT Development Framework Configuration"
- CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH - CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
- CONFIG_ESP_WIFI_EAP_TLS1_3 - CONFIG_ESP_WIFI_EAP_TLS1_3
- CONFIG_ESP_WIFI_ENABLE_ROAMING_APP - CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
- CONFIG_USB_HOST_EXT_PORT_SUPPORT_LS
- CONFIG_USB_HOST_EXT_PORT_RESET_ATTEMPTS - CONFIG_USB_HOST_EXT_PORT_RESET_ATTEMPTS
- CONFIG_LIBC_PICOLIBC - CONFIG_LIBC_PICOLIBC

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -12,14 +12,12 @@
#include "bootloader_mem.h" #include "bootloader_mem.h"
#include "esp_cpu.h" #include "esp_cpu.h"
#if SOC_APM_SUPPORTED
#include "hal/apm_hal.h" #include "hal/apm_hal.h"
#endif
void bootloader_init_mem(void) void bootloader_init_mem(void)
{ {
#if !defined(BOOTLOADER_BUILD) && defined(SOC_APM_SUPPORTED) #if !defined(BOOTLOADER_BUILD)
/* By default, these access path filters are enable and allow the /* By default, these access path filters are enable and allow the
* access to masters only if they are in TEE mode. Since all masters * access to masters only if they are in TEE mode. Since all masters
* except HP CPU boots in REE mode, default setting of these filters * except HP CPU boots in REE mode, default setting of these filters

View File

@ -1,107 +1,58 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "soc/soc.h" #include "hal/regi2c_ctrl_ll.h"
#include "soc/pcr_reg.h" #include "hal/adc_ll.h"
#include "soc/apb_saradc_reg.h" #include "hal/adc_types.h"
#include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_saradc.h"
#include "esp_log.h"
static const uint32_t SAR2_CHANNEL = 9;
static const uint32_t SAR1_CHANNEL = 7;
static const uint32_t PATTERN_BIT_WIDTH = 6;
static const uint32_t SAR1_ATTEN = 3;
static const uint32_t SAR2_ATTEN = 3;
void bootloader_random_enable(void) void bootloader_random_enable(void)
{ {
// pull SAR ADC out of reset adc_ll_reset_register();
REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); adc_ll_enable_bus_clock(true);
REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); adc_ll_enable_func_clock(true);
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL);
// enable SAR ADC APB clock adc_ll_digi_controller_clk_div(0, 0, 0);
REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN);
// pull APB register out of reset
REG_SET_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_RST_EN);
REG_CLR_BIT(PCR_SARADC_CONF_REG, PCR_SARADC_REG_RST_EN);
// enable ADC_CTRL_CLK (SAR ADC function clock)
REG_SET_BIT(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN);
// select XTAL clock (40 MHz) source for ADC_CTRL_CLK
REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_SEL, 0);
// set the clock divider for ADC_CTRL_CLK to default value (in case it has been changed)
REG_SET_FIELD(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_DIV_NUM, 0);
// some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU // some ADC sensor registers are in power group PERIF_I2C and need to be enabled via PMU
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); regi2c_ctrl_ll_i2c_reset_set();
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); regi2c_ctrl_ll_i2c_periph_enable();
// enable analog i2c master clock for RNG runtime // enable analog i2c master clock for RNG runtime
ANALOG_CLOCK_ENABLE(); ANALOG_CLOCK_ENABLE();
// Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal voltage as sampling source adc_ll_regi2c_adc_init();
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR , 0); adc_ll_set_calibration_param(ADC_UNIT_1, 0x866);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR , 1); adc_ll_set_calibration_param(ADC_UNIT_2, 0x866);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x08); adc_digi_pattern_config_t pattern_config = {};
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x66); pattern_config.unit = ADC_UNIT_1;
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x08); pattern_config.atten = ADC_ATTEN_DB_12;
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x66); pattern_config.channel = ADC_CHANNEL_7;
adc_ll_digi_set_pattern_table(ADC_UNIT_1, 0, pattern_config);
pattern_config.unit = ADC_UNIT_2;
pattern_config.atten = ADC_ATTEN_DB_12;
pattern_config.channel = ADC_CHANNEL_1;
adc_ll_digi_set_pattern_table(ADC_UNIT_2, 1, pattern_config);
adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, 2);
// create patterns and set them in pattern table adc_ll_digi_set_clk_div(15);
uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation adc_ll_digi_set_trigger_interval(200);
uint32_t pattern_two = (SAR1_CHANNEL << 2) | SAR1_ATTEN; // we want channel 7 with max attenuation adc_ll_digi_trigger_enable();
uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH;
REG_WRITE(SARADC_SAR_PATT_TAB1_REG, pattern_table);
// set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0)
REG_SET_FIELD(SARADC_CTRL_REG, SARADC_SAR_PATT_LEN, 1);
// Same as in C3
REG_SET_FIELD(SARADC_CTRL_REG, SARADC_SAR_CLK_DIV, 15);
// set timer expiry (timer is ADC_CTRL_CLK)
REG_SET_FIELD(SARADC_CTRL2_REG, SARADC_TIMER_TARGET, 200);
// enable timer
REG_SET_BIT(SARADC_CTRL2_REG, SARADC_TIMER_EN);
} }
void bootloader_random_disable(void) void bootloader_random_disable(void)
{ {
// disable timer adc_ll_digi_trigger_disable();
REG_CLR_BIT(SARADC_CTRL2_REG, SARADC_TIMER_EN); adc_ll_digi_reset_pattern_table();
adc_ll_set_calibration_param(ADC_UNIT_1, 0x0);
// Write reset value of this register adc_ll_set_calibration_param(ADC_UNIT_2, 0x0);
REG_WRITE(SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); adc_ll_regi2c_adc_deinit();
// Revert ADC I2C configuration and initial voltage source setting
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, 0x60);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, 0x0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0x60);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0x0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
// disable analog i2c master clock // disable analog i2c master clock
ANALOG_CLOCK_DISABLE(); ANALOG_CLOCK_DISABLE();
adc_ll_digi_controller_clk_div(4, 0, 0);
// disable ADC_CTRL_CLK (SAR ADC function clock) adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_XTAL);
REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000);
// Set PCR_SARADC_CONF_REG to initial state
REG_WRITE(PCR_SARADC_CONF_REG, 0x5);
} }

View File

@ -4,7 +4,6 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_log.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "hal/regi2c_ctrl_ll.h" #include "hal/regi2c_ctrl_ll.h"
#include "hal/adc_ll.h" #include "hal/adc_ll.h"
@ -23,9 +22,7 @@ void bootloader_random_enable(void)
// enable analog i2c master clock for RNG runtime // enable analog i2c master clock for RNG runtime
ANALOG_CLOCK_ENABLE(); ANALOG_CLOCK_ENABLE();
adc_ll_set_dtest_param(0); adc_ll_regi2c_adc_init();
adc_ll_set_ent_param(1);
adc_ll_enable_tout_bus(ADC_UNIT_1, true);
adc_ll_set_calibration_param(ADC_UNIT_1, 0x866); adc_ll_set_calibration_param(ADC_UNIT_1, 0x866);
adc_ll_set_calibration_param(ADC_UNIT_2, 0x866); adc_ll_set_calibration_param(ADC_UNIT_2, 0x866);
@ -49,9 +46,7 @@ void bootloader_random_disable(void)
adc_ll_digi_reset_pattern_table(); adc_ll_digi_reset_pattern_table();
adc_ll_set_calibration_param(ADC_UNIT_1, 0x0); adc_ll_set_calibration_param(ADC_UNIT_1, 0x0);
adc_ll_set_calibration_param(ADC_UNIT_2, 0x0); adc_ll_set_calibration_param(ADC_UNIT_2, 0x0);
adc_ll_set_dtest_param(0); adc_ll_regi2c_adc_deinit();
adc_ll_set_ent_param(0);
adc_ll_enable_tout_bus(ADC_UNIT_1, false);
// disable analog i2c master clock // disable analog i2c master clock
ANALOG_CLOCK_DISABLE(); ANALOG_CLOCK_DISABLE();

View File

@ -870,12 +870,27 @@ if(CONFIG_BT_ENABLED)
endif() endif()
set(bt_priv_requires
nvs_flash
soc
esp_pm
esp_phy
esp_coex
mbedtls
esp_driver_uart
vfs
esp_ringbuf
esp_driver_spi
esp_driver_gpio
esp_gdbstub
)
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}" INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES esp_timer esp_wifi REQUIRES esp_timer esp_wifi
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls esp_driver_uart vfs esp_ringbuf PRIV_REQUIRES "${bt_priv_requires}"
esp_driver_spi esp_driver_gpio
LDFRAGMENTS "${ldscripts}") LDFRAGMENTS "${ldscripts}")
if(CONFIG_BT_ENABLED) if(CONFIG_BT_ENABLED)

View File

@ -81,8 +81,6 @@ menu "Bluetooth"
So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT) So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT)
menu "Common Options" menu "Common Options"
visible if (BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED)
source "$IDF_PATH/components/bt/common/Kconfig.in" source "$IDF_PATH/components/bt/common/Kconfig.in"
endmenu endmenu

View File

@ -1,6 +1,7 @@
config BT_ALARM_MAX_NUM config BT_ALARM_MAX_NUM
int "Maximum number of Bluetooth alarms" int "Maximum number of Bluetooth alarms"
default 50 default 50
depends on (BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED)
help help
This option decides the maximum number of alarms which This option decides the maximum number of alarms which
could be used by Bluetooth host. could be used by Bluetooth host.
@ -11,6 +12,21 @@ config BT_BLE_LOG_SPI_OUT_ENABLED
help help
Output ble logs to SPI bus Output ble logs to SPI bus
config BT_BLE_LOG_SPI_OUT_HCI_ENABLED
bool "Enable HCI log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled.
config BT_BLE_LOG_SPI_OUT_HOST_ENABLED
bool "Enable Host log output to SPI"
depends on BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
This configuration applies to the logs of both Bluedroid Host and NimBLE Host.
When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI.
config BT_BLE_LOG_SPI_OUT_QUEUE_SIZE config BT_BLE_LOG_SPI_OUT_QUEUE_SIZE
int "Number of ble log async SPI output queues" int "Number of ble log async SPI output queues"
depends on BT_BLE_LOG_SPI_OUT_ENABLED depends on BT_BLE_LOG_SPI_OUT_ENABLED

View File

@ -176,8 +176,10 @@ IRAM_ATTR static void esp_timer_cb_flushout(void)
if (trans_head->trans.length) { if (trans_head->trans.length) {
spi_out_append_trans(); spi_out_append_trans();
} }
} else { }
// Restart flushout timer
// Restart flushout timer if not active
if (!esp_timer_is_active(flushout_timer_handle)) {
esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT);
} }
@ -193,6 +195,9 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void)
uint32_t lc_ts = 0; uint32_t lc_ts = 0;
uint32_t esp_ts = 0; uint32_t esp_ts = 0;
// Toggle sync IO
sync_io_level = !sync_io_level;
// Enter critical // Enter critical
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock); portENTER_CRITICAL_SAFE(&spinlock);
@ -205,7 +210,7 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void)
lc_ts = r_os_cputime_get32(); lc_ts = r_os_cputime_get32();
#endif // CONFIG_IDF_TARGET_ESP32C2 #endif // CONFIG_IDF_TARGET_ESP32C2
// Toggle Sync IO // Set sync IO level
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level); gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
// Get ESP timestamp // Get ESP timestamp
@ -219,9 +224,6 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void)
memcpy(sync_frame + 1, &lc_ts, sizeof(lc_ts)); memcpy(sync_frame + 1, &lc_ts, sizeof(lc_ts));
memcpy(sync_frame + 5, &esp_ts, sizeof(esp_ts)); memcpy(sync_frame + 5, &esp_ts, sizeof(esp_ts));
ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, sync_frame, 9); ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, sync_frame, 9);
// Update IO level
sync_io_level = !sync_io_level;
} }
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
@ -351,6 +353,10 @@ void ble_log_spi_out_ts_sync_stop(void)
if (esp_timer_is_active(ts_sync_timer_handle)) { if (esp_timer_is_active(ts_sync_timer_handle)) {
esp_timer_stop(ts_sync_timer_handle); esp_timer_stop(ts_sync_timer_handle);
} }
// Set sync IO to low level
sync_io_level = 0;
gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level);
} }
} }
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED
@ -437,6 +443,53 @@ IRAM_ATTR int ble_log_spi_out_printf(uint8_t source, const char *format, ...)
return 0; return 0;
} }
IRAM_ATTR int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...)
{
// Get ESP timestamp
uint32_t esp_ts = esp_timer_get_time();
// Create log prefix in the format: "[level][tag] "
char prefix[32];
int prefix_len = snprintf(prefix, sizeof(prefix), "[%d][%s] ", level, tag ? tag : "NULL");
// Compute the length of the formatted log message
va_list args;
va_start(args, format);
va_list args_copy;
va_copy(args_copy, args);
int log_len = vsnprintf(NULL, 0, format, args_copy);
va_end(args_copy);
// Validate length
if (log_len < 0 || log_len > 0xFFFF) {
va_end(args);
return -1;
}
// Compute total log length (prefix + formatted message)
int total_len = prefix_len + log_len;
// Allocate memory for the complete log message
uint8_t *buffer = malloc(total_len + 1);
if (!buffer) {
va_end(args);
return -1;
}
// Construct the final log message
memcpy(buffer, prefix, prefix_len); // Copy the prefix
vsnprintf((char *)(buffer + prefix_len), log_len + 1, format, args);
va_end(args);
// Transmit log data via SPI
ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4);
ble_log_spi_out_write(source, buffer, total_len);
// Free allocated memory
free(buffer);
return 0;
}
IRAM_ATTR void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len) IRAM_ATTR void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len)
{ {
// Get esp timestamp // Get esp timestamp

View File

@ -6,6 +6,7 @@
#ifndef __BT_SPI_OUT_H__ #ifndef __BT_SPI_OUT_H__
#define __BT_SPI_OUT_H__ #define __BT_SPI_OUT_H__
#include <stdarg.h>
#include <string.h> #include <string.h>
#include "driver/spi_master.h" #include "driver/spi_master.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@ -19,9 +20,19 @@
#define BLE_LOG_SPI_OUT_SOURCE_NIMBLE 3 #define BLE_LOG_SPI_OUT_SOURCE_NIMBLE 3
#define BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM 4 #define BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM 4
#define BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM 5 #define BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM 5
#define BLE_LOG_SPI_OUT_SOURCE_USER 0x10
#define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE #define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE
#define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF #define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF
// SPI Log Level Definitions
#define BLE_LOG_SPI_OUT_LEVEL_NONE 0 /*!< No log output */
#define BLE_LOG_SPI_OUT_LEVEL_ERROR 1 /*!< Critical errors that SPI driver cannot recover from */
#define BLE_LOG_SPI_OUT_LEVEL_WARN 2 /*!< Recoverable error conditions in SPI communication */
#define BLE_LOG_SPI_OUT_LEVEL_INFO 3 /*!< Informational messages about SPI transactions */
#define BLE_LOG_SPI_OUT_LEVEL_DEBUG 4 /*!< Detailed debug information, such as SPI register values */
#define BLE_LOG_SPI_OUT_LEVEL_VERBOSE 5 /*!< Very detailed debugging logs, potentially flooding output */
#define BLE_LOG_SPI_OUT_LEVEL_MAX 6 /*!< Number of SPI log levels supported */
// Public functions // Public functions
void ble_log_spi_out_init(void); void ble_log_spi_out_init(void);
void ble_log_spi_out_deinit(void); void ble_log_spi_out_deinit(void);
@ -30,6 +41,7 @@ void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end);
void ble_log_spi_out_ts_sync_start(void); void ble_log_spi_out_ts_sync_start(void);
void ble_log_spi_out_ts_sync_stop(void); void ble_log_spi_out_ts_sync_stop(void);
int ble_log_spi_out_printf(uint8_t source, const char *format, ...); int ble_log_spi_out_printf(uint8_t source, const char *format, ...);
int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...);
void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len); void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len);
#endif // __BT_SPI_OUT_H__ #endif // __BT_SPI_OUT_H__

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -84,6 +84,20 @@
#define BT_HCI_LOG_INCLUDED FALSE #define BT_HCI_LOG_INCLUDED FALSE
#endif #endif
// HCI LOG TO SPI
#if UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#else
#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE
#endif
// BLURDROID LOG TO SPI
#if UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED
#define BT_BLE_LOG_SPI_OUT_HOST_ENABLED UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED
#else
#define BT_BLE_LOG_SPI_OUT_HOST_ENABLED FALSE
#endif
#if UC_BT_HCI_LOG_DATA_BUFFER_SIZE #if UC_BT_HCI_LOG_DATA_BUFFER_SIZE
#define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE #define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE
#else #else

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -126,6 +126,20 @@
#define UC_BT_HCI_LOG_DEBUG_EN FALSE #define UC_BT_HCI_LOG_DEBUG_EN FALSE
#endif #endif
//HCI LOG TO SPI
#ifdef CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#define UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED TRUE
#else
#define UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE
#endif
//BLUEDROID LOG TO SPI
#ifdef CONFIG_BT_BLE_LOG_SPI_OUT_HOST_ENABLED
#define UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED TRUE
#else
#define UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED FALSE
#endif
#ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE
#define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE
#else #else

View File

@ -393,11 +393,11 @@ void esp_bt_read_ctrl_log_from_flash(bool output)
portENTER_CRITICAL_SAFE(&spinlock); portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts(); esp_panic_handler_feed_wdts();
ble_log_async_output_dump_all(true); ble_log_async_output_dump_all(true);
stop_write = true;
esp_bt_ontroller_log_deinit(); esp_bt_ontroller_log_deinit();
portEXIT_CRITICAL_SAFE(&spinlock); stop_write = true;
buffer = (const uint8_t *)mapped_ptr; buffer = (const uint8_t *)mapped_ptr;
esp_panic_handler_feed_wdts();
if (is_filled) { if (is_filled) {
read_index = next_erase_index; read_index = next_erase_index;
} else { } else {
@ -409,7 +409,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output)
while (read_index != write_index) { while (read_index != write_index) {
esp_rom_printf("%02x ", buffer[read_index]); esp_rom_printf("%02x ", buffer[read_index]);
if (print_len > max_print_len) { if (print_len > max_print_len) {
vTaskDelay(2); esp_panic_handler_feed_wdts();
print_len = 0; print_len = 0;
} }
@ -417,6 +417,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output)
read_index = (read_index + 1) % MAX_STORAGE_SIZE; read_index = (read_index + 1) % MAX_STORAGE_SIZE;
} }
esp_rom_printf(":DUMP_END]\r\n"); esp_rom_printf(":DUMP_END]\r\n");
portEXIT_CRITICAL_SAFE(&spinlock);
esp_partition_munmap(mmap_handle); esp_partition_munmap(mmap_handle);
err = esp_bt_controller_log_init(log_output_mode); err = esp_bt_controller_log_init(log_output_mode);
assert(err == ESP_OK); assert(err == ESP_OK);
@ -430,6 +431,9 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, b
esp_bt_controller_log_storage(len, addr, end); esp_bt_controller_log_storage(len, addr, end);
#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
} else { } else {
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
esp_rom_printf("%02x ", addr[i]); esp_rom_printf("%02x ", addr[i]);
} }
@ -437,6 +441,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, b
if (end) { if (end) {
esp_rom_printf("\n"); esp_rom_printf("\n");
} }
portEXIT_CRITICAL_SAFE(&spinlock);
} }
} }

View File

@ -550,6 +550,7 @@ config BT_CTRL_BLE_SECURITY_ENABLE
depends on BT_CTRL_RUN_IN_FLASH_ONLY && BT_CONTROLLER_ONLY depends on BT_CTRL_RUN_IN_FLASH_ONLY && BT_CONTROLLER_ONLY
bool "Enable BLE security feature" bool "Enable BLE security feature"
default y default y
config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS
bool "Enable enhanced Access Address check in CONNECT_IND" bool "Enable enhanced Access Address check in CONNECT_IND"
default n default n
@ -557,3 +558,71 @@ config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS
Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU.
This improves security by ensuring that only connection requests with valid Access Addresses are accepted. This improves security by ensuring that only connection requests with valid Access Addresses are accepted.
If disabled, only basic checks are applied, improving compatibility. If disabled, only basic checks are applied, improving compatibility.
menu "Controller debug log Options (Experimental)"
config BT_CTRL_LE_LOG_EN
depends on BT_CTRL_RUN_IN_FLASH_ONLY
bool "Enable BLE debug log"
default n
config BT_CTRL_LE_HCI_LOG_EN
depends on BT_CTRL_LE_LOG_EN
bool "Enable BLE HCI log"
default n
config BT_CTRL_LE_LOG_DUMP_ONLY
depends on BT_CTRL_LE_LOG_EN
bool "Enable BLE log dump only"
default n
config BT_CTRL_LE_LOG_STORAGE_EN
depends on BT_CTRL_LE_LOG_EN
bool "Enable BLE log storage to flash"
default n
config BT_CTRL_LE_LOG_PARTITION_SIZE
int "The size of ble controller log partition(Multiples of 4K)"
depends on BT_CTRL_LE_LOG_STORAGE_EN
default 65536
help
The size of ble controller log partition shall be a multiples of 4K.
The name of log partition shall be "bt_ctrl_log".
The partition type shall be ESP_PARTITION_TYPE_DATA.
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
config BT_CTRL_LE_LOG_SPI_OUT_EN
bool "Output ble controller logs to SPI bus"
depends on BT_CTRL_LE_LOG_EN
depends on !BT_CTRL_LE_LOG_DUMP_ONLY
select BT_BLE_LOG_SPI_OUT_ENABLED
default n
help
Output ble controller logs to SPI bus
config BT_CTRL_LE_LOG_MODE_EN
depends on BT_CTRL_LE_LOG_EN
int "Enable log for specified BLE mode"
range 0 4095
default 4093
config BT_CTRL_LE_LOG_LEVEL
depends on BT_CTRL_LE_LOG_EN
int "The level of BLE log"
range 0 5
default 2
config BT_CTRL_LE_LOG_BUF1_SIZE
depends on BT_CTRL_LE_LOG_EN
int "The size of BLE log buffer1"
default 1024
config BT_CTRL_LE_LOG_HCI_BUF_SIZE
depends on BT_CTRL_LE_LOG_EN
int "The size of BLE log HCI buffer"
default 1024
config BT_CTRL_LE_LOG_BUF2_SIZE
depends on BT_CTRL_LE_LOG_EN
int "The size of BLE log buffer2"
default 1024
endmenu

View File

@ -52,6 +52,10 @@
#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED #if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#include "ble_log/ble_log_spi_out.h" #include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED #endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#include "esp_partition.h"
#include "hal/wdt_hal.h"
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#if CONFIG_BT_ENABLED #if CONFIG_BT_ENABLED
/* Macro definition /* Macro definition
@ -118,12 +122,20 @@ do{\
} while(0) } while(0)
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff #define OSI_FUNCS_TIME_BLOCKING 0xffffffff
#define OSI_VERSION 0x00010009 #define OSI_VERSION 0x0001000A
#define OSI_MAGIC_VALUE 0xFADEBEAD #define OSI_MAGIC_VALUE 0xFADEBEAD
#define BLE_PWR_HDL_INVL 0xFFFF #define BLE_PWR_HDL_INVL 0xFFFF
#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA) #define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA)
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#define MAX_STORAGE_SIZE (CONFIG_BT_CTRL_LE_LOG_PARTITION_SIZE)
#define BLOCK_SIZE (4096)
#define THRESHOLD (3072)
#define PARTITION_NAME "bt_ctrl_log"
#endif
/* Types definition /* Types definition
************************************************************************ ************************************************************************
*/ */
@ -219,8 +231,13 @@ struct osi_funcs_t {
void (* _btdm_rom_table_ready)(void); void (* _btdm_rom_table_ready)(void);
bool (* _coex_bt_wakeup_request)(void); bool (* _coex_bt_wakeup_request)(void);
void (* _coex_bt_wakeup_request_end)(void); void (* _coex_bt_wakeup_request_end)(void);
int64_t (*_get_time_us)(void);
void (* _assert)(void);
}; };
#if CONFIG_BT_CTRL_LE_LOG_EN
typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end);
#endif // CONFIG_BT_CTRL_LE_LOG_EN
/* External functions or values /* External functions or values
************************************************************************ ************************************************************************
@ -280,6 +297,15 @@ extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, b
extern void btdm_cca_feature_enable(void); extern void btdm_cca_feature_enable(void);
extern void btdm_aa_check_enhance_enable(void); extern void btdm_aa_check_enhance_enable(void);
/* BLE Log module */
#if CONFIG_BT_CTRL_LE_LOG_EN
extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size);
extern int r_ble_log_deinit_async(void);
extern void r_ble_log_async_select_dump_buffers(uint8_t buffers);
extern void r_ble_log_async_output_dump_all(bool output);
extern void esp_panic_handler_feed_wdts(void);
#endif // CONFIG_BT_CTRL_LE_LOG_EN
extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end; extern uint32_t _bt_bss_end;
extern uint32_t _bt_controller_bss_start; extern uint32_t _bt_controller_bss_start;
@ -341,6 +367,8 @@ static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32
static void btdm_funcs_table_ready_wrapper(void); static void btdm_funcs_table_ready_wrapper(void);
static bool coex_bt_wakeup_request(void); static bool coex_bt_wakeup_request(void);
static void coex_bt_wakeup_request_end(void); static void coex_bt_wakeup_request_end(void);
static int64_t get_time_us_wrapper(void);
static void assert_wrapper(void);
static void btdm_slp_tmr_callback(void *arg); static void btdm_slp_tmr_callback(void *arg);
@ -348,6 +376,15 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end);
static void bt_controller_deinit_internal(void); static void bt_controller_deinit_internal(void);
#if CONFIG_BT_CTRL_LE_LOG_EN
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end);
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
void esp_bt_read_ctrl_log_from_flash(bool output);
static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end);
static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void);
#endif // #if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#endif // CONFIG_BT_CTRL_LE_LOG_EN
/* Local variable definition /* Local variable definition
*************************************************************************** ***************************************************************************
*/ */
@ -413,6 +450,8 @@ static const struct osi_funcs_t osi_funcs_ro = {
._btdm_rom_table_ready = btdm_funcs_table_ready_wrapper, ._btdm_rom_table_ready = btdm_funcs_table_ready_wrapper,
._coex_bt_wakeup_request = coex_bt_wakeup_request, ._coex_bt_wakeup_request = coex_bt_wakeup_request,
._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end, ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end,
._get_time_us = get_time_us_wrapper,
._assert = assert_wrapper,
}; };
static DRAM_ATTR struct osi_funcs_t *osi_funcs_p; static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
@ -441,6 +480,255 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
#endif #endif
#if CONFIG_BT_CTRL_LE_LOG_EN
enum log_out_mode {
LOG_DUMP_MEMORY,
LOG_ASYNC_OUT,
LOG_STORAGE_TO_FLASH,
LOG_SPI_OUT,
};
const static uint32_t log_bufs_size[] = {CONFIG_BT_CTRL_LE_LOG_BUF1_SIZE, CONFIG_BT_CTRL_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_CTRL_LE_LOG_BUF2_SIZE};
bool log_is_inited = false;
#if CONFIG_BT_CTRL_LE_LOG_DUMP_ONLY
uint8_t log_output_mode = LOG_DUMP_MEMORY;
#else
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
uint8_t log_output_mode = LOG_STORAGE_TO_FLASH;
#elif CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN
uint8_t log_output_mode = LOG_SPI_OUT;
#else
uint8_t log_output_mode = LOG_ASYNC_OUT;
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#endif // CONFIG_BT_CTRL_LE_LOG_DUMP_ONLY
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
static const esp_partition_t *log_partition;
static uint32_t write_index = 0;
static uint32_t next_erase_index = BLOCK_SIZE;
static bool block_erased = false;
static bool stop_write = false;
static bool is_filled = false;
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end)
{
if (log_output_mode == LOG_STORAGE_TO_FLASH) {
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
esp_bt_controller_log_storage(len, addr, end);
#endif //CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
} else {
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
for (int i = 0; i < len; i++) {
esp_rom_printf("%02x ", addr[i]);
}
if (end) {
esp_rom_printf("\n");
}
portEXIT_CRITICAL_SAFE(&spinlock);
}
}
#if CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN
static IRAM_ATTR void esp_bt_controller_spi_log_interface(uint32_t len, const uint8_t *addr, bool end)
{
return ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY, addr, len);
}
#endif // CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN
void esp_ble_controller_log_dump_all(bool output)
{
if (log_output_mode == LOG_STORAGE_TO_FLASH) {
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
esp_bt_read_ctrl_log_from_flash(output);
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
} else {
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
esp_rom_printf("\r\n[DUMP_START:");
r_ble_log_async_output_dump_all(output);
esp_rom_printf(":DUMP_END]\r\n");
portEXIT_CRITICAL_SAFE(&spinlock);
}
}
void esp_bt_log_output_mode_set(uint8_t output_mode)
{
log_output_mode = output_mode;
}
uint8_t esp_bt_log_output_mode_get(void)
{
return log_output_mode;
}
esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode)
{
esp_err_t ret = ESP_OK;
interface_func_t bt_controller_log_interface;
bt_controller_log_interface = esp_bt_controller_log_interface;
bool task_create;
uint8_t buffers = 0;
if (log_is_inited) {
return ret;
}
#if CONFIG_BT_CTRL_LE_LOG_EN
buffers |= ESP_BLE_LOG_BUF_CONTROLLER;
#endif // CONFIG_BT_CTRL_LE_LOG_EN
#if CONFIG_BT_CTRL_LE_HCI_LOG_EN
buffers |= ESP_BLE_LOG_BUF_HCI;
#endif // CONFIG_BT_CTRL_LE_HCI_LOG_EN
switch (log_output_mode) {
case LOG_DUMP_MEMORY:
task_create = false;
break;
case LOG_ASYNC_OUT:
case LOG_STORAGE_TO_FLASH:
task_create = true;
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
if (log_output_mode == LOG_STORAGE_TO_FLASH) {
esp_bt_ctrl_log_partition_get_and_erase_first_block();
}
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
break;
case LOG_SPI_OUT:
task_create = true;
#if CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN
bt_controller_log_interface = esp_bt_controller_spi_log_interface;
#endif // CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN
break;
default:
assert(0);
}
ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size);
if (ret == ESP_OK) {
log_is_inited = true;
}
return ret;
}
void esp_bt_ontroller_log_deinit(void)
{
r_ble_log_deinit_async();
log_is_inited = false;
}
#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void)
{
log_partition = NULL;
assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0);
// Find the partition map in the partition table
log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME);
assert(log_partition != NULL);
// Prepare data to be read later using the mapped address
ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE));
write_index = 0;
next_erase_index = BLOCK_SIZE;
block_erased = false;
is_filled = false;
stop_write = false;
}
static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end)
{
if (len > MAX_STORAGE_SIZE) {
return -1;
}
if (stop_write) {
return 0;
}
if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) {
// esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index);
esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE);
next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE;
block_erased = true;
}
if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) {
block_erased = false;
}
if (write_index + len <= MAX_STORAGE_SIZE) {
esp_partition_write(log_partition, write_index, addr, len);
write_index = (write_index + len) % MAX_STORAGE_SIZE;
} else {
uint32_t first_part_len = MAX_STORAGE_SIZE - write_index;
esp_partition_write(log_partition, write_index, addr, first_part_len);
esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len);
write_index = len - first_part_len;
is_filled = true;
// esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index);
}
return 0;
}
void esp_bt_read_ctrl_log_from_flash(bool output)
{
esp_partition_mmap_handle_t mmap_handle;
uint32_t read_index;
const void *mapped_ptr;
const uint8_t *buffer;
uint32_t print_len;
uint32_t max_print_len;
esp_err_t err;
print_len = 0;
max_print_len = 4096;
err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle);
if (err != ESP_OK) {
ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err));
return;
}
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_SAFE(&spinlock);
esp_panic_handler_feed_wdts();
r_ble_log_async_output_dump_all(true);
esp_bt_ontroller_log_deinit();
stop_write = true;
buffer = (const uint8_t *)mapped_ptr;
esp_panic_handler_feed_wdts();
if (is_filled) {
read_index = next_erase_index;
} else {
read_index = 0;
}
esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled);
esp_rom_printf("\r\n[DUMP_START:");
while (read_index != write_index) {
esp_rom_printf("%02x ", buffer[read_index]);
if (print_len > max_print_len) {
esp_panic_handler_feed_wdts();
print_len = 0;
}
print_len++;
read_index = (read_index + 1) % MAX_STORAGE_SIZE;
}
esp_rom_printf(":DUMP_END]\r\n");
portEXIT_CRITICAL_SAFE(&spinlock);
esp_partition_munmap(mmap_handle);
err = esp_bt_controller_log_init(log_output_mode);
assert(err == ESP_OK);
}
#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN
#endif // CONFIG_BT_CTRL_LE_LOG_EN
void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void) void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void)
{ {
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
@ -994,6 +1282,18 @@ static void coex_bt_wakeup_request_end(void)
return; return;
} }
static IRAM_ATTR int64_t get_time_us_wrapper(void)
{
return esp_timer_get_time();
}
static IRAM_ATTR void assert_wrapper(void)
{
#if CONFIG_BT_CTRL_LE_LOG_EN
esp_ble_controller_log_dump_all(true);
#endif // CONFIG_BT_CTRL_LE_LOG_EN
}
bool esp_vhci_host_check_send_available(void) bool esp_vhci_host_check_send_available(void)
{ {
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
@ -1456,6 +1756,14 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
periph_module_enable(PERIPH_BT_MODULE); periph_module_enable(PERIPH_BT_MODULE);
periph_module_reset(PERIPH_BT_MODULE); periph_module_reset(PERIPH_BT_MODULE);
#if CONFIG_BT_CTRL_LE_LOG_EN
err = esp_bt_controller_log_init(log_output_mode);
if (err != ESP_OK) {
ESP_LOGW(BT_LOG_TAG, "ble_controller_log_init failed %d", err);
goto error;
}
#endif // CONFIG_BT_CTRL_LE_LOG_EN
err = btdm_controller_init(cfg); err = btdm_controller_init(cfg);
if (err != 0) { if (err != 0) {
@ -1563,6 +1871,10 @@ static void bt_controller_deinit_internal(void)
#endif #endif
esp_phy_modem_deinit(); esp_phy_modem_deinit();
#if CONFIG_BT_CTRL_LE_LOG_EN
esp_bt_ontroller_log_deinit();
#endif // CONFIG_BT_CTRL_LE_LOG_EN
if (osi_funcs_p != NULL) { if (osi_funcs_p != NULL) {
free(osi_funcs_p); free(osi_funcs_p);
osi_funcs_p = NULL; osi_funcs_p = NULL;

View File

@ -396,6 +396,12 @@ menu "Controller debug features"
config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)"
default n default n
config BT_LE_DEBUG_REMAIN_SCENE_ENABLED
bool "Remain scene with GDB to capture relevant status info(Experimental)"
default n
help
Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN).
endmenu endmenu
config BT_LE_LL_RESOLV_LIST_SIZE config BT_LE_LL_RESOLV_LIST_SIZE

View File

@ -1640,6 +1640,10 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv)
#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC
#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED)
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
#include "esp_gdbstub.h"
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
int IRAM_ATTR int IRAM_ATTR
ble_capture_info_user_handler(uint8_t type, uint32_t reason) ble_capture_info_user_handler(uint8_t type, uint32_t reason)
{ {
@ -1650,12 +1654,16 @@ ble_capture_info_user_handler(uint8_t type, uint32_t reason)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
esp_ble_controller_info_capture(0x010101); esp_ble_controller_info_capture(0x010101);
} }
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
uintptr_t sp;
__asm__ volatile ("mv %0, sp" : "=r" (sp));
esp_gdbstub_panic_handler(&sp);
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
break; break;
#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
case 1: case 1:
if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) {
osi_assert_wrapper(__LINE__,__func__, type reason); osi_assert_wrapper(__LINE__,__func__, type, reason);
} }
break; break;
#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED

View File

@ -428,6 +428,12 @@ menu "Controller debug features"
config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)"
default n default n
config BT_LE_DEBUG_REMAIN_SCENE_ENABLED
bool "Remain scene with GDB to capture relevant status info(Experimental)"
default n
help
Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN).
endmenu endmenu
config BT_LE_LL_RESOLV_LIST_SIZE config BT_LE_LL_RESOLV_LIST_SIZE

View File

@ -1661,6 +1661,10 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv)
#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC
#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED)
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
#include "esp_gdbstub.h"
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
int IRAM_ATTR int IRAM_ATTR
ble_capture_info_user_handler(uint8_t type, uint32_t reason) ble_capture_info_user_handler(uint8_t type, uint32_t reason)
{ {
@ -1671,12 +1675,16 @@ ble_capture_info_user_handler(uint8_t type, uint32_t reason)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
esp_ble_controller_info_capture(0x010101); esp_ble_controller_info_capture(0x010101);
} }
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
uintptr_t sp;
__asm__ volatile ("mv %0, sp" : "=r" (sp));
esp_gdbstub_panic_handler(&sp);
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
break; break;
#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
case 1: case 1:
if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) {
osi_assert_wrapper(__LINE__,__func__, type reason); osi_assert_wrapper(__LINE__,__func__, type, reason);
} }
break; break;
#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED

View File

@ -419,6 +419,12 @@ menu "Controller debug features"
config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)"
default n default n
config BT_LE_DEBUG_REMAIN_SCENE_ENABLED
bool "Remain scene with GDB to capture relevant status info(Experimental)"
default n
help
Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN).
endmenu endmenu
config BT_LE_LL_RESOLV_LIST_SIZE config BT_LE_LL_RESOLV_LIST_SIZE

View File

@ -1633,6 +1633,9 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv)
#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC
#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED)
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
#include "esp_gdbstub.h"
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
int IRAM_ATTR int IRAM_ATTR
ble_capture_info_user_handler(uint8_t type, uint32_t reason) ble_capture_info_user_handler(uint8_t type, uint32_t reason)
@ -1644,12 +1647,16 @@ ble_capture_info_user_handler(uint8_t type, uint32_t reason)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
esp_ble_controller_info_capture(0x010101); esp_ble_controller_info_capture(0x010101);
} }
#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
uintptr_t sp;
__asm__ volatile ("mv %0, sp" : "=r" (sp));
esp_gdbstub_panic_handler(&sp);
#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED
break; break;
#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
case 1: case 1:
if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) {
osi_assert_wrapper(__LINE__,__func__, type reason); osi_assert_wrapper(__LINE__,__func__, type, reason);
} }
break; break;
#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED #endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED

@ -1 +1 @@
Subproject commit 6093909e01930f8cda6f60510f8a412c6d1814e8 Subproject commit fbbb054cbc5c8b5aa466208dc8d12ccc10d7e08c

@ -1 +1 @@
Subproject commit ed99228396aaa18935b575d600bc19da38dc4746 Subproject commit 2ce747aec8008d008fe34fa375a2aea3e7e48e9a

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -16,6 +16,10 @@
#define LOG_TAG "HCI_API" #define LOG_TAG "HCI_API"
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 }; static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 };
esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops) esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops)
@ -63,6 +67,9 @@ void hci_host_send_packet(uint8_t *data, uint16_t len)
#if (BT_HCI_LOG_INCLUDED == TRUE) #if (BT_HCI_LOG_INCLUDED == TRUE)
bt_hci_log_record_hci_data(data[0], &data[1], len - 1); bt_hci_log_record_hci_data(data[0], &data[1], len - 1);
#endif #endif
#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len);
#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
#if (BT_CONTROLLER_INCLUDED == TRUE) #if (BT_CONTROLLER_INCLUDED == TRUE)
esp_vhci_host_send_packet(data, len); esp_vhci_host_send_packet(data, len);
#else /* BT_CONTROLLER_INCLUDED == TRUE */ #else /* BT_CONTROLLER_INCLUDED == TRUE */

View File

@ -25,6 +25,9 @@
#include "stack/bt_types.h" #include "stack/bt_types.h"
#include "bt_common.h" #include "bt_common.h"
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#include "ble_log/ble_log_spi_out.h"
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t len) static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t len)
{ {
uint16_t i; uint16_t i;
@ -217,20 +220,83 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
/* Define tracing for BTM /* Define tracing for BTM
*/ */
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#define BTM_TRACE_ERROR(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_BTM", fmt, ## args); \
if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args); \
}
#define BTM_TRACE_WARNING(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_BTM", fmt, ## args); \
if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args); \
}
#define BTM_TRACE_API(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_BTM", fmt, ## args); \
if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM, API)) BT_PRINT_I("BT_BTM", fmt, ## args); \
}
#define BTM_TRACE_EVENT(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_BTM", fmt, ## args); \
if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM, EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args); \
}
#define BTM_TRACE_DEBUG(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_BTM", fmt, ## args); \
if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM, DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args); \
}
#else
#define BTM_TRACE_ERROR(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args);} #define BTM_TRACE_ERROR(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args);}
#define BTM_TRACE_WARNING(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args);} #define BTM_TRACE_WARNING(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args);}
#define BTM_TRACE_API(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM,API)) BT_PRINT_I("BT_BTM", fmt, ## args);} #define BTM_TRACE_API(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM,API)) BT_PRINT_I("BT_BTM", fmt, ## args);}
#define BTM_TRACE_EVENT(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM,EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args);} #define BTM_TRACE_EVENT(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM,EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args);}
#define BTM_TRACE_DEBUG(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM,DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args);} #define BTM_TRACE_DEBUG(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM,DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args);}
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
/* Define tracing for the L2CAP unit /* Define tracing for the L2CAP unit
*/ */
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#define L2CAP_TRACE_ERROR(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_L2CAP", fmt, ## args); \
if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args); \
}
#define L2CAP_TRACE_WARNING(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_L2CAP", fmt, ## args); \
if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args); \
}
#define L2CAP_TRACE_API(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_L2CAP", fmt, ## args); \
if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP, API)) BT_PRINT_I("BT_L2CAP", fmt, ## args); \
}
#define L2CAP_TRACE_EVENT(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_L2CAP", fmt, ## args); \
if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP, EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \
}
#define L2CAP_TRACE_DEBUG(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_L2CAP", fmt, ## args); \
if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP, DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \
}
#else
#define L2CAP_TRACE_ERROR(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_ERROR(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_WARNING(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_WARNING(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_API(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP,API)) BT_PRINT_I("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_API(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP,API)) BT_PRINT_I("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_EVENT(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP,EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_EVENT(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP,EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_DEBUG(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP,DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_DEBUG(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP,DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args);}
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
/* Define tracing for the SDP unit /* Define tracing for the SDP unit
*/ */
#define SDP_TRACE_ERROR(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SDP, ERROR)) BT_PRINT_E("BT_SDP", fmt, ## args);} #define SDP_TRACE_ERROR(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SDP, ERROR)) BT_PRINT_E("BT_SDP", fmt, ## args);}
@ -248,11 +314,38 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
#define RFCOMM_TRACE_DEBUG(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(RFCOMM,DEBUG)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);} #define RFCOMM_TRACE_DEBUG(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(RFCOMM,DEBUG)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);}
/* Generic Access Profile traces */ /* Generic Access Profile traces */
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#define GAP_TRACE_ERROR(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_GAP", fmt, ## args); \
if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args); \
}
#define GAP_TRACE_WARNING(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_GAP", fmt, ## args); \
if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args); \
}
#define GAP_TRACE_API(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GAP", fmt, ## args); \
if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP, API)) BT_PRINT_I("BT_GAP", fmt, ## args); \
}
#define GAP_TRACE_EVENT(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GAP", fmt, ## args); \
if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP, EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args); \
}
#else
#define GAP_TRACE_ERROR(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args);} #define GAP_TRACE_ERROR(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args);}
#define GAP_TRACE_API(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP,API)) BT_PRINT_I("BT_GAP", fmt, ## args);} #define GAP_TRACE_API(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP,API)) BT_PRINT_I("BT_GAP", fmt, ## args);}
#define GAP_TRACE_EVENT(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP,EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args);} #define GAP_TRACE_EVENT(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP,EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args);}
#define GAP_TRACE_WARNING(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args);} #define GAP_TRACE_WARNING(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args);}
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
/* define traces for HID Host */ /* define traces for HID Host */
#define HIDH_TRACE_ERROR(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDH, ERROR)) BT_PRINT_E("BT_HIDH", fmt, ## args);} #define HIDH_TRACE_ERROR(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDH, ERROR)) BT_PRINT_E("BT_HIDH", fmt, ## args);}
#define HIDH_TRACE_WARNING(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDH, WARNING)) BT_PRINT_W("BT_HIDH", fmt, ## args);} #define HIDH_TRACE_WARNING(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDH, WARNING)) BT_PRINT_W("BT_HIDH", fmt, ## args);}
@ -354,20 +447,81 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
/* Define tracing for the ATT/GATT unit /* Define tracing for the ATT/GATT unit
*/ */
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#define GATT_TRACE_ERROR(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_GATT", fmt, ## args); \
if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args); \
}
#define GATT_TRACE_WARNING(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_GATT", fmt, ## args); \
if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args); \
}
#define GATT_TRACE_API(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GATT", fmt, ## args); \
if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT, API)) BT_PRINT_I("BT_GATT", fmt, ## args); \
}
#define GATT_TRACE_EVENT(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GATT", fmt, ## args); \
if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT, EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args); \
}
#define GATT_TRACE_DEBUG(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GATT", fmt, ## args); \
if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT, DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args); \
}
#else
#define GATT_TRACE_ERROR(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args);} #define GATT_TRACE_ERROR(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args);}
#define GATT_TRACE_WARNING(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args);} #define GATT_TRACE_WARNING(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args);}
#define GATT_TRACE_API(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT,API)) BT_PRINT_I("BT_GATT", fmt, ## args);} #define GATT_TRACE_API(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT,API)) BT_PRINT_I("BT_GATT", fmt, ## args);}
#define GATT_TRACE_EVENT(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT,EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args);} #define GATT_TRACE_EVENT(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT,EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args);}
#define GATT_TRACE_DEBUG(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT,DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args);} #define GATT_TRACE_DEBUG(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT,DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args);}
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
/* Define tracing for the SMP unit /* Define tracing for the SMP unit
*/ */
#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
#define SMP_TRACE_ERROR(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_SMP", fmt, ## args); \
if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args); \
}
#define SMP_TRACE_WARNING(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_SMP", fmt, ## args); \
if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args); \
}
#define SMP_TRACE_API(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_SMP", fmt, ## args); \
if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP, API)) BT_PRINT_I("BT_SMP", fmt, ## args); \
}
#define SMP_TRACE_EVENT(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_SMP", fmt, ## args); \
if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP, EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args); \
}
#define SMP_TRACE_DEBUG(fmt, args...) { \
ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_SMP", fmt, ## args); \
if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP, DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args); \
}
#else
#define SMP_TRACE_ERROR(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args);} #define SMP_TRACE_ERROR(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args);}
#define SMP_TRACE_WARNING(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args);} #define SMP_TRACE_WARNING(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args);}
#define SMP_TRACE_API(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP,API)) BT_PRINT_I("BT_SMP", fmt, ## args);} #define SMP_TRACE_API(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP,API)) BT_PRINT_I("BT_SMP", fmt, ## args);}
#define SMP_TRACE_EVENT(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP,EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args);} #define SMP_TRACE_EVENT(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP,EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args);}
#define SMP_TRACE_DEBUG(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP,DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args);} #define SMP_TRACE_DEBUG(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP,DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args);}
#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
extern UINT8 btif_trace_level; extern UINT8 btif_trace_level;

View File

@ -41,6 +41,10 @@
#include "stack/hcimsgs.h" #include "stack/hcimsgs.h"
#include "hci_log/bt_hci_log.h" #include "hci_log/bt_hci_log.h"
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#define HCI_BLE_EVENT 0x3e #define HCI_BLE_EVENT 0x3e
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
#define PACKET_TYPE_TO_INDEX(type) ((type) - 1) #define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
@ -567,6 +571,9 @@ void bt_record_hci_data(uint8_t *data, uint16_t len)
static int host_recv_pkt_cb(uint8_t *data, uint16_t len) static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
{ {
#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len);
#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
//Target has packet to host, malloc new buffer for packet //Target has packet to host, malloc new buffer for packet
BT_HDR *pkt = NULL; BT_HDR *pkt = NULL;
#if (BLE_42_SCAN_EN == TRUE) #if (BLE_42_SCAN_EN == TRUE)

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -24,6 +24,10 @@
#include "bt_common.h" #include "bt_common.h"
#include "hci_log/bt_hci_log.h" #include "hci_log/bt_hci_log.h"
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#include "ble_log/ble_log_spi_out.h"
#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#define NIMBLE_VHCI_TIMEOUT_MS 2000 #define NIMBLE_VHCI_TIMEOUT_MS 2000
#define BLE_HCI_EVENT_HDR_LEN (2) #define BLE_HCI_EVENT_HDR_LEN (2)
#define BLE_HCI_CMD_HDR_LEN (3) #define BLE_HCI_CMD_HDR_LEN (3)
@ -68,6 +72,9 @@ void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len)
#if (BT_HCI_LOG_INCLUDED == TRUE) #if (BT_HCI_LOG_INCLUDED == TRUE)
bt_hci_log_record_hci_data(data[0], &data[1], len - 1); bt_hci_log_record_hci_data(data[0], &data[1], len - 1);
#endif #endif
#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len);
#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
esp_vhci_host_send_packet(data, len); esp_vhci_host_send_packet(data, len);
} }
@ -219,6 +226,10 @@ static int dummy_host_rcv_pkt(uint8_t *data, uint16_t len)
*/ */
static int host_rcv_pkt(uint8_t *data, uint16_t len) static int host_rcv_pkt(uint8_t *data, uint16_t len)
{ {
#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len);
#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
bt_record_hci_data(data, len); bt_record_hci_data(data, len);
if(!ble_hs_enabled_state) { if(!ble_hs_enabled_state) {

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -30,7 +30,7 @@ extern "C" {
* *
* @note Please do not modify this value * @note Please do not modify this value
*/ */
#define ESP_BT_CTRL_CONFIG_VERSION 0x02410230 #define ESP_BT_CTRL_CONFIG_VERSION 0x02502230
/** /**
* @brief Internal use only * @brief Internal use only
@ -323,6 +323,24 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
#define BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED 0 #define BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED 0
#endif #endif
#if defined(CONFIG_BT_CTRL_LE_LOG_EN)
#define BT_BLE_LOG_EN CONFIG_BT_CTRL_LE_LOG_EN
#else
#define BT_BLE_LOG_EN (0)
#endif
#if defined(CONFIG_BT_CTRL_LE_LOG_MODE_EN)
#define BLE_LOG_MODE_EN CONFIG_BT_CTRL_LE_LOG_MODE_EN
#else
#define BLE_LOG_MODE_EN (0)
#endif
#if defined(CONFIG_BT_CTRL_LE_LOG_LEVEL)
#define BLE_LOG_LEVEL CONFIG_BT_CTRL_LE_LOG_LEVEL
#else
#define BLE_LOG_LEVEL (0)
#endif
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL, \ .magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL, \
.version = ESP_BT_CTRL_CONFIG_VERSION, \ .version = ESP_BT_CTRL_CONFIG_VERSION, \
@ -369,6 +387,8 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
.master_en = BT_CTRL_BLE_MASTER, \ .master_en = BT_CTRL_BLE_MASTER, \
.scan_en = BT_CTRL_BLE_SCAN, \ .scan_en = BT_CTRL_BLE_SCAN, \
.ble_aa_check = BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED, \ .ble_aa_check = BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED, \
.ble_log_mode_en = BLE_LOG_MODE_EN, \
.ble_log_level = BLE_LOG_LEVEL, \
} }
#else #else
@ -494,6 +514,8 @@ typedef struct {
bool master_en; /*!< In the flash mode, True if the master feature is enabled (default); false otherwise. Configurable in menuconfig.*/ bool master_en; /*!< In the flash mode, True if the master feature is enabled (default); false otherwise. Configurable in menuconfig.*/
bool scan_en; /*!< In the flash mode, True if the scan feature is enabled (default); false otherwise. Configurable in menuconfig.*/ bool scan_en; /*!< In the flash mode, True if the scan feature is enabled (default); false otherwise. Configurable in menuconfig.*/
bool ble_aa_check; /*!< True if adds a verification step for the Access Address within the CONNECT_IND PDU; false otherwise. Configurable in menuconfig */ bool ble_aa_check; /*!< True if adds a verification step for the Access Address within the CONNECT_IND PDU; false otherwise. Configurable in menuconfig */
uint32_t ble_log_mode_en; /*!< BLE log mode enable */
uint8_t ble_log_level; /*!< BLE log level */
} esp_bt_controller_config_t; } esp_bt_controller_config_t;
/** /**
@ -904,6 +926,16 @@ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
*/ */
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
/**
* @brief Select buffers
*/
typedef enum {
ESP_BLE_LOG_BUF_HCI = 0x02,
ESP_BLE_LOG_BUF_CONTROLLER = 0x05,
} esp_ble_log_buf_t;
void esp_ble_controller_log_dump_all(bool output);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -495,8 +495,7 @@ def main():
global idf_target global idf_target
parser = argparse.ArgumentParser(description='ESP32 eFuse Manager') parser = argparse.ArgumentParser(description='ESP32 eFuse Manager')
parser.add_argument('--idf_target', '-t', help='Target chip type', choices=['esp32', 'esp32s2', 'esp32s3', 'esp32c3', parser.add_argument('--idf_target', '-t', help='Target chip type', default='esp32')
'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], default='esp32')
parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true') parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true')
parser.add_argument('--debug', help='Create header file with debug info', default=False, action='store_false') parser.add_argument('--debug', help='Create header file with debug info', default=False, action='store_false')
parser.add_argument('--info', help='Print info about range of used bits', default=False, action='store_true') parser.add_argument('--info', help='Print info about range of used bits', default=False, action='store_true')

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_efuse.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_table.h"
#include "stdlib.h"
#include "esp_types.h"
#include "assert.h"
#include "esp_err.h"
#include "esp_log.h"
#include "soc/efuse_periph.h"
#include "sys/param.h"
static __attribute__((unused)) const char *TAG = "efuse";
// Contains functions that provide access to efuse fields which are often used in IDF.
// Returns chip package from efuse
uint32_t esp_efuse_get_pkg_ver(void)
{
uint32_t pkg_ver = 0;
#ifdef EFUSE_PKG_VERSION
esp_efuse_read_field_blob(ESP_EFUSE_PKG_VERSION, &pkg_ver, ESP_EFUSE_PKG_VERSION[0]->bit_count);
#endif
return pkg_ver;
}
esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme)
{
int cur_log_scheme = 0;
esp_efuse_read_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &cur_log_scheme, 2);
if (!cur_log_scheme) { // not burned yet
return esp_efuse_write_field_blob(ESP_EFUSE_UART_PRINT_CONTROL, &log_scheme, 2);
} else {
return ESP_ERR_INVALID_STATE;
}
}
esp_err_t esp_efuse_disable_rom_download_mode(void)
{
return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE);
}
esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
{
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) {
return ESP_ERR_INVALID_STATE;
}
return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,162 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1-256) | #
# | EFUSE_BLK1 | | | #
# | ...) | | | #
##########################################################################
# !!!!!!!!!!! #
# After editing this file, run the command manually "idf.py efuse-common-table"
# this will generate new source files, next rebuild all the sources.
# !!!!!!!!!!! #
# This file was generated by regtools.py based on the efuses.yaml file with the version: 7bc342bad0952907e1db21112d258c6b
WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses
WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS
WR_DIS.KM_DISABLE_DEPLOY_MODE, EFUSE_BLK0, 1, 1, [] wr_dis of KM_DISABLE_DEPLOY_MODE
WR_DIS.KM_RND_SWITCH_CYCLE, EFUSE_BLK0, 1, 1, [] wr_dis of KM_RND_SWITCH_CYCLE
WR_DIS.KM_DEPLOY_ONLY_ONCE, EFUSE_BLK0, 1, 1, [] wr_dis of KM_DEPLOY_ONLY_ONCE
WR_DIS.FORCE_USE_KEY_MANAGER_KEY, EFUSE_BLK0, 1, 1, [] wr_dis of FORCE_USE_KEY_MANAGER_KEY
WR_DIS.FORCE_DISABLE_SW_INIT_KEY, EFUSE_BLK0, 1, 1, [] wr_dis of FORCE_DISABLE_SW_INIT_KEY
WR_DIS.KM_XTS_KEY_LENGTH_256, EFUSE_BLK0, 1, 1, [] wr_dis of KM_XTS_KEY_LENGTH_256
WR_DIS.LOCK_KM_KEY, EFUSE_BLK0, 1, 1, [] wr_dis of LOCK_KM_KEY
WR_DIS.DIS_USB_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_USB_JTAG
WR_DIS.DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_FORCE_DOWNLOAD
WR_DIS.SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 2, 1, [] wr_dis of SPI_DOWNLOAD_MSPI_DIS
WR_DIS.DIS_TWAI, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_TWAI
WR_DIS.JTAG_SEL_ENABLE, EFUSE_BLK0, 2, 1, [] wr_dis of JTAG_SEL_ENABLE
WR_DIS.DIS_PAD_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_PAD_JTAG
WR_DIS.DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT
WR_DIS.SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 4, 1, [] wr_dis of SPI_BOOT_CRYPT_CNT
WR_DIS.SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 5, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE0
WR_DIS.SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 6, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE1
WR_DIS.SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 7, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE2
WR_DIS.KEY_PURPOSE_0, EFUSE_BLK0, 8, 1, [WR_DIS.KEY0_PURPOSE] wr_dis of KEY_PURPOSE_0
WR_DIS.KEY_PURPOSE_1, EFUSE_BLK0, 9, 1, [WR_DIS.KEY1_PURPOSE] wr_dis of KEY_PURPOSE_1
WR_DIS.KEY_PURPOSE_2, EFUSE_BLK0, 10, 1, [WR_DIS.KEY2_PURPOSE] wr_dis of KEY_PURPOSE_2
WR_DIS.KEY_PURPOSE_3, EFUSE_BLK0, 11, 1, [WR_DIS.KEY3_PURPOSE] wr_dis of KEY_PURPOSE_3
WR_DIS.KEY_PURPOSE_4, EFUSE_BLK0, 12, 1, [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4
WR_DIS.KEY_PURPOSE_5, EFUSE_BLK0, 13, 1, [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5
WR_DIS.SEC_DPA_LEVEL, EFUSE_BLK0, 14, 1, [] wr_dis of SEC_DPA_LEVEL
WR_DIS.XTS_DPA_PSEUDO_LEVEL, EFUSE_BLK0, 14, 1, [] wr_dis of XTS_DPA_PSEUDO_LEVEL
WR_DIS.XTS_DPA_CLK_ENABLE, EFUSE_BLK0, 14, 1, [] wr_dis of XTS_DPA_CLK_ENABLE
WR_DIS.ECC_FORCE_CONST_TIME, EFUSE_BLK0, 14, 1, [] wr_dis of ECC_FORCE_CONST_TIME
WR_DIS.SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, [] wr_dis of SECURE_BOOT_EN
WR_DIS.SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 16, 1, [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE
WR_DIS.FLASH_TPUW, EFUSE_BLK0, 18, 1, [] wr_dis of FLASH_TPUW
WR_DIS.DIS_DOWNLOAD_MODE, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DOWNLOAD_MODE
WR_DIS.DIS_DIRECT_BOOT, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DIRECT_BOOT
WR_DIS.DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_USB_SERIAL_JTAG_ROM_PRINT
WR_DIS.DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE
WR_DIS.ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 18, 1, [] wr_dis of ENABLE_SECURITY_DOWNLOAD
WR_DIS.UART_PRINT_CONTROL, EFUSE_BLK0, 18, 1, [] wr_dis of UART_PRINT_CONTROL
WR_DIS.FORCE_SEND_RESUME, EFUSE_BLK0, 18, 1, [] wr_dis of FORCE_SEND_RESUME
WR_DIS.SECURE_VERSION, EFUSE_BLK0, 18, 1, [] wr_dis of SECURE_VERSION
WR_DIS.HUK_GEN_STATE, EFUSE_BLK0, 19, 1, [] wr_dis of HUK_GEN_STATE
WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC
WR_DIS.MAC_EXT, EFUSE_BLK0, 20, 1, [] wr_dis of MAC_EXT
WR_DIS.PVT_LIMIT, EFUSE_BLK0, 20, 1, [] wr_dis of PVT_LIMIT
WR_DIS.PVT_CELL_SELECT, EFUSE_BLK0, 20, 1, [] wr_dis of PVT_CELL_SELECT
WR_DIS.PVT_PUMP_LIMIT, EFUSE_BLK0, 20, 1, [] wr_dis of PVT_PUMP_LIMIT
WR_DIS.PUMP_DRV, EFUSE_BLK0, 20, 1, [] wr_dis of PUMP_DRV
WR_DIS.WDT_DELAY_SEL, EFUSE_BLK0, 20, 1, [] wr_dis of WDT_DELAY_SEL
WR_DIS.HYS_EN_PAD, EFUSE_BLK0, 20, 1, [] wr_dis of HYS_EN_PAD
WR_DIS.PVT_GLITCH_CHARGE_RESET, EFUSE_BLK0, 20, 1, [] wr_dis of PVT_GLITCH_CHARGE_RESET
WR_DIS.VDD_SPI_LDO_ADJUST, EFUSE_BLK0, 20, 1, [] wr_dis of VDD_SPI_LDO_ADJUST
WR_DIS.FLASH_LDO_POWER_SEL, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_LDO_POWER_SEL
WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA
WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC
WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0
WR_DIS.BLOCK_KEY1, EFUSE_BLK0, 24, 1, [WR_DIS.KEY1] wr_dis of BLOCK_KEY1
WR_DIS.BLOCK_KEY2, EFUSE_BLK0, 25, 1, [WR_DIS.KEY2] wr_dis of BLOCK_KEY2
WR_DIS.BLOCK_KEY3, EFUSE_BLK0, 26, 1, [WR_DIS.KEY3] wr_dis of BLOCK_KEY3
WR_DIS.BLOCK_KEY4, EFUSE_BLK0, 27, 1, [WR_DIS.KEY4] wr_dis of BLOCK_KEY4
WR_DIS.BLOCK_KEY5, EFUSE_BLK0, 28, 1, [WR_DIS.KEY5] wr_dis of BLOCK_KEY5
WR_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 29, 1, [WR_DIS.SYS_DATA_PART2] wr_dis of BLOCK_SYS_DATA2
WR_DIS.USB_EXCHG_PINS, EFUSE_BLK0, 30, 1, [] wr_dis of USB_EXCHG_PINS
WR_DIS.SOFT_DIS_JTAG, EFUSE_BLK0, 31, 1, [] wr_dis of SOFT_DIS_JTAG
RD_DIS, EFUSE_BLK0, 32, 7, [] Disable reading from BlOCK4-10
RD_DIS.BLOCK_KEY0, EFUSE_BLK0, 32, 1, [RD_DIS.KEY0] rd_dis of BLOCK_KEY0
RD_DIS.BLOCK_KEY1, EFUSE_BLK0, 33, 1, [RD_DIS.KEY1] rd_dis of BLOCK_KEY1
RD_DIS.BLOCK_KEY2, EFUSE_BLK0, 34, 1, [RD_DIS.KEY2] rd_dis of BLOCK_KEY2
RD_DIS.BLOCK_KEY3, EFUSE_BLK0, 35, 1, [RD_DIS.KEY3] rd_dis of BLOCK_KEY3
RD_DIS.BLOCK_KEY4, EFUSE_BLK0, 36, 1, [RD_DIS.KEY4] rd_dis of BLOCK_KEY4
RD_DIS.BLOCK_KEY5, EFUSE_BLK0, 37, 1, [RD_DIS.KEY5] rd_dis of BLOCK_KEY5
RD_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 38, 1, [RD_DIS.SYS_DATA_PART2] rd_dis of BLOCK_SYS_DATA2
DIS_USB_JTAG, EFUSE_BLK0, 39, 1, [] Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled 0: enabled
DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 41, 1, [] Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled 0: enabled
SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 42, 1, [] Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled 0: enabled
DIS_TWAI, EFUSE_BLK0, 43, 1, [] Represents whether TWAI function is disabled or enabled. 1: disabled 0: enabled
JTAG_SEL_ENABLE, EFUSE_BLK0, 44, 1, [] Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled 0: disabled
DIS_PAD_JTAG, EFUSE_BLK0, 45, 1, [] Represents whether JTAG is disabled in the hard way(permanently). 1: disabled 0: enabled
DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 46, 1, [] Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled 0: enabled
PVT_GLITCH_EN, EFUSE_BLK0, 50, 1, [] Represents whether to enable PVT power glitch monitor function.1:Enable. 0:Disable
PVT_GLITCH_MODE, EFUSE_BLK0, 52, 2, [] Use to configure glitch mode
DIS_CORE1, EFUSE_BLK0, 54, 1, [] Represents whether the CPU-Core1 is disabled. 1: Disabled. 0: Not disable
SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 55, 3, [] Enables flash encryption when 1 or 3 bits are set and disables otherwise {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"}
SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 58, 1, [] Revoke 1st secure boot key
SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 59, 1, [] Revoke 2nd secure boot key
SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 60, 1, [] Revoke 3rd secure boot key
KEY_PURPOSE_0, EFUSE_BLK0, 64, 5, [KEY0_PURPOSE] Represents the purpose of Key0
KEY_PURPOSE_1, EFUSE_BLK0, 69, 5, [KEY1_PURPOSE] Represents the purpose of Key1
KEY_PURPOSE_2, EFUSE_BLK0, 74, 5, [KEY2_PURPOSE] Represents the purpose of Key2
KEY_PURPOSE_3, EFUSE_BLK0, 79, 5, [KEY3_PURPOSE] Represents the purpose of Key3
KEY_PURPOSE_4, EFUSE_BLK0, 84, 5, [KEY4_PURPOSE] Represents the purpose of Key4
KEY_PURPOSE_5, EFUSE_BLK0, 89, 5, [KEY5_PURPOSE] Represents the purpose of Key5
SEC_DPA_LEVEL, EFUSE_BLK0, 94, 2, [] Represents the spa secure level by configuring the clock random divide mode
XTS_DPA_PSEUDO_LEVEL, EFUSE_BLK0, 96, 2, [] Represents the pseudo round level of xts-aes anti-dpa attack. 3: High. 2: Moderate 1. Low 0: Disabled
XTS_DPA_CLK_ENABLE, EFUSE_BLK0, 98, 1, [] Represents whether xts-aes anti-dpa attack clock is enabled. 1. Enable. 0: Disable.
ECC_FORCE_CONST_TIME, EFUSE_BLK0, 99, 1, [] Represents whether to force ecc to use const-time calculation mode. 1: Enable. 0: Disable
ECDSA_P384_ENABLE, EFUSE_BLK0, 100, 1, [] Represents if the chip supports ECDSA P384
SECURE_BOOT_EN, EFUSE_BLK0, 101, 1, [] Represents whether secure boot is enabled or disabled. 1: enabled 0: disabled
SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 102, 1, [] Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled
KM_DISABLE_DEPLOY_MODE, EFUSE_BLK0, 103, 5, [] Represents whether the new key deployment of key manager is disabled. Bit0: Represents whether the new ECDSA key deployment is disabled0: Enabled1: DisabledBit1: Represents whether the new XTS-AES (flash and PSRAM) key deployment is disabled0: Enabled1: DisabledBit2: Represents whether the new HMAC key deployment is disabled0: Enabled1: DisabledBit3: Represents whether the new DS key deployment is disabled0: Enabled1: Disabled
KM_RND_SWITCH_CYCLE, EFUSE_BLK0, 108, 2, [] Represents the cycle at which the Key Manager switches random numbers.0: Controlled by the \hyperref[fielddesc:KEYMNGRNDSWITCHCYCLE]{KEYMNG\_RND\_SWITCH\_CYCLE} register. For more information; please refer to Chapter \ref{mod:keymng} \textit{\nameref{mod:keymng}}1: 8 Key Manager clock cycles2: 16 Key Manager clock cycles3: 32 Key Manager clock cycles
KM_DEPLOY_ONLY_ONCE, EFUSE_BLK0, 110, 5, [] Represents whether the corresponding key can be deployed only once.Bit0: Represents whether the ECDSA key can be deployed only once0: The key can be deployed multiple times1: The key can be deployed only onceBit1: Represents whether the XTS-AES (flash and PSRAM) key can be deployed only once0: The key can be deployed multiple times1: The key can be deployed only onceBit2: Represents whether the HMAC key can be deployed only once0: The key can be deployed multiple times1: The key can be deployed only onceBit3: Represents whether the DS key can be deployed only once0: The key can be deployed multiple times1: The key can be deployed only once
FORCE_USE_KEY_MANAGER_KEY, EFUSE_BLK0, 115, 5, [] Represents whether the corresponding key must come from Key Manager. Bit0: Represents whether the ECDSA key must come from Key Manager.0: The key does not need to come from Key Manager1: The key must come from Key ManagerBit1: Represents whether the XTS-AES (flash and PSRAM) key must come from Key Manager.0: The key does not need to come from Key Manager1: The key must come from Key ManagerBit2: Represents whether the HMAC key must come from Key Manager.0: The key does not need to come from Key Manager1: The key must come from Key ManagerBit3: Represents whether the DS key must come from Key Manager.0: The key does not need to come from Key Manager1: The key must come from Key Manager
FORCE_DISABLE_SW_INIT_KEY, EFUSE_BLK0, 120, 1, [] Represents whether to disable the use of the initialization key written by software and instead force use efuse\_init\_key.0: Enable1: Disable
KM_XTS_KEY_LENGTH_256, EFUSE_BLK0, 121, 1, [] Represents which key flash encryption uses.0: XTS-AES-256 key1: XTS-AES-128 key
LOCK_KM_KEY, EFUSE_BLK0, 122, 1, [] Represents whether the keys in the Key Manager are locked after deployment.0: Not locked1: Locked
FLASH_TPUW, EFUSE_BLK0, 123, 3, [] Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value
DIS_DOWNLOAD_MODE, EFUSE_BLK0, 127, 1, [] Represents whether Download mode is disabled or enabled. 1: disabled 0: enabled
DIS_DIRECT_BOOT, EFUSE_BLK0, 128, 1, [] Represents whether direct boot mode is disabled or enabled. 1: disabled 0: enabled
DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 129, 1, [] Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled 0: enabled
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 130, 1, [] Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: Disable 0: Enable
ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 131, 1, [] Represents whether security download is enabled or disabled. 1: enabled 0: disabled
UART_PRINT_CONTROL, EFUSE_BLK0, 132, 2, [] Represents the type of UART printing. 00: force enable printing 01: enable printing when GPIO8 is reset at low level 10: enable printing when GPIO8 is reset at high level 11: force disable printing
FORCE_SEND_RESUME, EFUSE_BLK0, 134, 1, [] Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced 0:not forced
SECURE_VERSION, EFUSE_BLK0, 135, 16, [] Represents the version used by ESP-IDF anti-rollback feature
HUK_GEN_STATE, EFUSE_BLK0, 151, 5, [] Represents whether the HUK generate mode is valid.Odd count of bits with a value of 1: InvalidEven count of bits with a value of 1: Valid
FLASH_LDO_EFUSE_SEL, EFUSE_BLK0, 156, 1, [] Represents whether to select efuse control flash ldo default voltage. 1 : efuse 0 : strapping
USB_EXCHG_PINS, EFUSE_BLK0, 168, 1, [] Represents whether the D+ and D- pins of USB_SERIAL_JTAG PHY is exchanged. 1: exchanged 0: not exchanged
USB_OTG_FS_EXCHG_PINS, EFUSE_BLK0, 169, 1, [] Represents whether the D+ and D- pins of USB_OTG_FS PHY is exchanged. 1: exchanged 0: not exchanged
USB_PHY_SEL, EFUSE_BLK0, 170, 1, [] Represents whether to exchange the USB_SERIAL_JTAG PHY with USB_OTG_FS PHY. 1: exchanged. 0: not exchanged
SOFT_DIS_JTAG, EFUSE_BLK0, 171, 3, [] Represents whether JTAG is disabled in soft way. Odd number: disabled Even number: enabled
IO_LDO_ADJUST, EFUSE_BLK0, 174, 8, [] Represents configuration of IO LDO mode and voltage.
IO_LDO_1P8, EFUSE_BLK0, 182, 1, [] Represents select IO LDO voltage to 1.8V or 3.3V. 1: 1.8V 0: 3.3V
DCDC_CCM_EN, EFUSE_BLK0, 183, 1, [] Represents whether change DCDC to CCM mode
MAC, EFUSE_BLK1, 40, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 32, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 24, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 16, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 8, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address
MAC_EXT, EFUSE_BLK1, 48, 16, [] Represents the extended bits of MAC address
PVT_LIMIT, EFUSE_BLK1, 64, 16, [] Power glitch monitor threthold
PVT_CELL_SELECT, EFUSE_BLK1, 80, 7, [] Power glitch monitor PVT cell select
PVT_PUMP_LIMIT, EFUSE_BLK1, 87, 8, [] Use to configure voltage monitor limit for charge pump
PUMP_DRV, EFUSE_BLK1, 96, 4, [] Use to configure charge pump voltage gain
WDT_DELAY_SEL, EFUSE_BLK1, 100, 2, [] Represents the threshold level of the RTC watchdog STG0 timeout. 0: Original threshold configuration value of STG0 *2 1: Original threshold configuration value of STG0 *4 2: Original threshold configuration value of STG0 *8 3: Original threshold configuration value of STG0 *16
HYS_EN_PAD, EFUSE_BLK1, 102, 1, [] Represents whether the hysteresis function of corresponding PAD is enabled. 1: enabled 0:disabled
PVT_GLITCH_CHARGE_RESET, EFUSE_BLK1, 103, 1, [] Represents whether to trigger reset or charge pump when PVT power glitch happened.1:Trigger charge pump. 0:Trigger reset
VDD_SPI_LDO_ADJUST, EFUSE_BLK1, 105, 8, [] Represents configuration of FLASH LDO mode and voltage.
FLASH_LDO_POWER_SEL, EFUSE_BLK1, 113, 1, [] Represents which flash ldo be select: 1: FLASH LDO 1P2 0 : FLASH LDO 1P8
USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data
USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC
KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data
KEY1, EFUSE_BLK5, 0, 256, [BLOCK_KEY1] Key1 or user data
KEY2, EFUSE_BLK6, 0, 256, [BLOCK_KEY2] Key2 or user data
KEY3, EFUSE_BLK7, 0, 256, [BLOCK_KEY3] Key3 or user data
KEY4, EFUSE_BLK8, 0, 256, [BLOCK_KEY4] Key4 or user data
KEY5, EFUSE_BLK9, 0, 256, [BLOCK_KEY5] Key5 or user data
SYS_DATA_PART2, EFUSE_BLK10, 0, 256, [BLOCK_SYS_DATA2] System data part 2 (reserved)
Can't render this file because it contains an unexpected character in line 8 and column 53.

View File

@ -0,0 +1,208 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "assert.h"
#include "esp_efuse_utility.h"
#include "soc/efuse_periph.h"
#include "hal/efuse_hal.h"
static const char *TAG = "efuse";
#ifdef CONFIG_EFUSE_VIRTUAL
extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
#endif // CONFIG_EFUSE_VIRTUAL
/*Range addresses to read blocks*/
const esp_efuse_range_addr_t range_read_addr_blocks[] = {
{EFUSE_RD_WR_DIS0_REG, EFUSE_RD_REPEAT_DATA4_REG}, // range address of EFUSE_BLK0 REPEAT
{EFUSE_RD_MAC_SYS0_REG, EFUSE_RD_MAC_SYS5_REG}, // range address of EFUSE_BLK1 MAC_SPI_8M
{EFUSE_RD_SYS_PART1_DATA0_REG, EFUSE_RD_SYS_PART1_DATA7_REG}, // range address of EFUSE_BLK2 SYS_DATA
{EFUSE_RD_USR_DATA0_REG, EFUSE_RD_USR_DATA7_REG}, // range address of EFUSE_BLK3 USR_DATA
{EFUSE_RD_KEY0_DATA0_REG, EFUSE_RD_KEY0_DATA7_REG}, // range address of EFUSE_BLK4 KEY0
{EFUSE_RD_KEY1_DATA0_REG, EFUSE_RD_KEY1_DATA7_REG}, // range address of EFUSE_BLK5 KEY1
{EFUSE_RD_KEY2_DATA0_REG, EFUSE_RD_KEY2_DATA7_REG}, // range address of EFUSE_BLK6 KEY2
{EFUSE_RD_KEY3_DATA0_REG, EFUSE_RD_KEY3_DATA7_REG}, // range address of EFUSE_BLK7 KEY3
{EFUSE_RD_KEY4_DATA0_REG, EFUSE_RD_KEY4_DATA7_REG}, // range address of EFUSE_BLK8 KEY4
{EFUSE_RD_KEY5_DATA0_REG, EFUSE_RD_KEY5_DATA7_REG}, // range address of EFUSE_BLK9 KEY5
{EFUSE_RD_SYS_PART2_DATA0_REG, EFUSE_RD_SYS_PART2_DATA7_REG} // range address of EFUSE_BLK10 KEY6
};
static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
/*Range addresses to write blocks (it is not real regs, it is buffer) */
const esp_efuse_range_addr_t range_write_addr_blocks[] = {
{(uint32_t) &write_mass_blocks[EFUSE_BLK0][0], (uint32_t) &write_mass_blocks[EFUSE_BLK0][5]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK1][0], (uint32_t) &write_mass_blocks[EFUSE_BLK1][5]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK2][0], (uint32_t) &write_mass_blocks[EFUSE_BLK2][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK3][0], (uint32_t) &write_mass_blocks[EFUSE_BLK3][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK4][0], (uint32_t) &write_mass_blocks[EFUSE_BLK4][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK5][0], (uint32_t) &write_mass_blocks[EFUSE_BLK5][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK6][0], (uint32_t) &write_mass_blocks[EFUSE_BLK6][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK7][0], (uint32_t) &write_mass_blocks[EFUSE_BLK7][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK8][0], (uint32_t) &write_mass_blocks[EFUSE_BLK8][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK9][0], (uint32_t) &write_mass_blocks[EFUSE_BLK9][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK10][0], (uint32_t) &write_mass_blocks[EFUSE_BLK10][7]},
};
#ifndef CONFIG_EFUSE_VIRTUAL
// Update Efuse timing configuration
static esp_err_t esp_efuse_set_timing(void)
{
// efuse clock is fixed.
// An argument (0) is for compatibility and will be ignored.
efuse_hal_set_timing(0);
return ESP_OK;
}
#endif // ifndef CONFIG_EFUSE_VIRTUAL
// Efuse read operation: copies data from physical efuses to efuse read registers.
void esp_efuse_utility_clear_program_registers(void)
{
efuse_hal_read();
efuse_hal_clear_program_registers();
}
esp_err_t esp_efuse_utility_check_errors(void)
{
return ESP_OK;
}
// Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void)
{
return esp_efuse_utility_burn_chip_opt(false, true);
}
esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data)
{
esp_err_t error = ESP_OK;
#ifdef CONFIG_EFUSE_VIRTUAL
(void) ignore_coding_errors;
(void) verify_written_data;
ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
int subblock = 0;
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block);
}
}
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
esp_efuse_utility_write_efuses_to_flash();
#endif
#else // CONFIG_EFUSE_VIRTUAL
if (esp_efuse_set_timing() != ESP_OK) {
ESP_LOGE(TAG, "Efuse fields are not burnt");
} else {
// Permanently update values written to the efuse write registers
// It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks.
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
bool need_burn_block = false;
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
if (REG_READ(addr_wr_block) != 0) {
need_burn_block = true;
break;
}
}
if (!need_burn_block) {
continue;
}
if (error) {
// It is done for a use case: BLOCK2 (Flash encryption key) could have an error (incorrect written data)
// in this case we can not burn any data into BLOCK0 because it might set read/write protections of BLOCK2.
ESP_LOGE(TAG, "BLOCK%d can not be burned because a previous block got an error, skipped.", num_block);
continue;
}
efuse_hal_clear_program_registers();
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
hal_memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
}
unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t);
unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t);
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len);
uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data
hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data));
int repeat_burn_op = 1;
bool correct_written_data;
bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block);
if (coding_error_before) {
ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block);
}
bool coding_error_occurred;
do {
ESP_LOGI(TAG, "BURN BLOCK%d", num_block);
efuse_hal_program(num_block); // BURN a block
bool coding_error_after;
for (unsigned i = 0; i < 5; i++) {
efuse_hal_read();
coding_error_after = efuse_hal_is_coding_error_in_block(num_block);
if (coding_error_after == true) {
break;
}
}
coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before;
if (coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block);
}
correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true;
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
}
} while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3);
if (coding_error_occurred) {
ESP_LOGW(TAG, "Coding error was not fixed");
if (num_block == 0) {
ESP_LOGE(TAG, "BLOCK0 got a coding error, which might be critical for security");
error = ESP_FAIL;
}
}
if (!correct_written_data) {
ESP_LOGE(TAG, "Written data are incorrect");
error = ESP_FAIL;
}
}
}
#endif // CONFIG_EFUSE_VIRTUAL
esp_efuse_utility_reset();
return error;
}
// After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values.
// This function reads EFUSE_BLKx_WDATAx_REG registers, and checks possible to write these data with RS coding scheme.
// The RS coding scheme does not require data changes for the encoded data. esp32s2 has special registers for this.
// They will be filled during the burn operation.
esp_err_t esp_efuse_utility_apply_new_coding_scheme()
{
// start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
if (REG_READ(addr_wr_block)) {
int num_reg = 0;
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, ++num_reg) {
if (esp_efuse_utility_read_reg(num_block, num_reg)) {
ESP_LOGE(TAG, "Bits are not empty. Write operation is forbidden.");
return ESP_ERR_CODING;
}
}
break;
}
}
}
}
return ESP_OK;
}

View File

@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of eFuse blocks ESP32H4
*/
typedef enum {
EFUSE_BLK0 = 0, /**< Number of eFuse BLOCK0. REPEAT_DATA */
EFUSE_BLK1 = 1, /**< Number of eFuse BLOCK1. MAC_SPI_8M_SYS */
EFUSE_BLK2 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
EFUSE_BLK_SYS_DATA_PART1 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
EFUSE_BLK3 = 3, /**< Number of eFuse BLOCK3. USER_DATA*/
EFUSE_BLK_USER_DATA = 3, /**< Number of eFuse BLOCK3. USER_DATA*/
EFUSE_BLK4 = 4, /**< Number of eFuse BLOCK4. KEY0 */
EFUSE_BLK_KEY0 = 4, /**< Number of eFuse BLOCK4. KEY0 */
EFUSE_BLK5 = 5, /**< Number of eFuse BLOCK5. KEY1 */
EFUSE_BLK_KEY1 = 5, /**< Number of eFuse BLOCK5. KEY1 */
EFUSE_BLK6 = 6, /**< Number of eFuse BLOCK6. KEY2 */
EFUSE_BLK_KEY2 = 6, /**< Number of eFuse BLOCK6. KEY2 */
EFUSE_BLK7 = 7, /**< Number of eFuse BLOCK7. KEY3 */
EFUSE_BLK_KEY3 = 7, /**< Number of eFuse BLOCK7. KEY3 */
EFUSE_BLK8 = 8, /**< Number of eFuse BLOCK8. KEY4 */
EFUSE_BLK_KEY4 = 8, /**< Number of eFuse BLOCK8. KEY4 */
EFUSE_BLK9 = 9, /**< Number of eFuse BLOCK9. KEY5 */
EFUSE_BLK_KEY5 = 9, /**< Number of eFuse BLOCK9. KEY5 */
EFUSE_BLK_KEY_MAX = 10,
EFUSE_BLK10 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */
EFUSE_BLK_SYS_DATA_PART2 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */
EFUSE_BLK_MAX
} esp_efuse_block_t;
/**
* @brief Type of coding scheme
*/
typedef enum {
EFUSE_CODING_SCHEME_NONE = 0, /**< None */
EFUSE_CODING_SCHEME_RS = 3, /**< Reed-Solomon coding */
} esp_efuse_coding_scheme_t;
/**
* @brief Type of key purpose
*/
typedef enum {
ESP_EFUSE_KEY_PURPOSE_USER = 0, /**< User purposes (software-only use) */
ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY = 1, /**< ECDSA private key (Expected in little endian order)*/
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4, /**< XTS_AES_128_KEY (flash/PSRAM encryption) */
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5, /**< HMAC Downstream mode */
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6, /**< JTAG soft enable key (uses HMAC Downstream mode) */
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7, /**< Digital Signature peripheral key (uses HMAC Downstream mode) */
ESP_EFUSE_KEY_PURPOSE_HMAC_UP = 8, /**< HMAC Upstream mode */
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9, /**< SECURE_BOOT_DIGEST0 (Secure Boot key digest) */
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10, /**< SECURE_BOOT_DIGEST1 (Secure Boot key digest) */
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11, /**< SECURE_BOOT_DIGEST2 (Secure Boot key digest) */
ESP_EFUSE_KEY_PURPOSE_MAX, /**< MAX PURPOSE */
} esp_efuse_purpose_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,208 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_efuse.h"
// md5_digest_table 6bfa2ae917ac6cbce5b70a55ea6a78bd
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
// To show efuse_table run the command 'show_efuse_table'.
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KM_DISABLE_DEPLOY_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KM_RND_SWITCH_CYCLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KM_DEPLOY_ONLY_ONCE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FORCE_USE_KEY_MANAGER_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FORCE_DISABLE_SW_INIT_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KM_XTS_KEY_LENGTH_256[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LOCK_KM_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_TWAI[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_JTAG_SEL_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_PAD_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_0[];
#define ESP_EFUSE_WR_DIS_KEY0_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_0
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_1[];
#define ESP_EFUSE_WR_DIS_KEY1_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_1
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_2[];
#define ESP_EFUSE_WR_DIS_KEY2_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_2
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_3[];
#define ESP_EFUSE_WR_DIS_KEY3_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_3
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_4[];
#define ESP_EFUSE_WR_DIS_KEY4_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_4
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_5[];
#define ESP_EFUSE_WR_DIS_KEY5_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_5
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_PSEUDO_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_CLK_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ECC_FORCE_CONST_TIME[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TPUW[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DIRECT_BOOT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_ROM_PRINT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ENABLE_SECURITY_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_UART_PRINT_CONTROL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FORCE_SEND_RESUME[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_HUK_GEN_STATE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[];
#define ESP_EFUSE_WR_DIS_MAC_FACTORY ESP_EFUSE_WR_DIS_MAC
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PVT_LIMIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PVT_CELL_SELECT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PVT_PUMP_LIMIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PUMP_DRV[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WDT_DELAY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_HYS_EN_PAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PVT_GLITCH_CHARGE_RESET[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_VDD_SPI_LDO_ADJUST[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_LDO_POWER_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[];
#define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[];
#define ESP_EFUSE_WR_DIS_MAC_CUSTOM ESP_EFUSE_WR_DIS_CUSTOM_MAC
#define ESP_EFUSE_WR_DIS_USER_DATA_MAC_CUSTOM ESP_EFUSE_WR_DIS_CUSTOM_MAC
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY0[];
#define ESP_EFUSE_WR_DIS_KEY0 ESP_EFUSE_WR_DIS_BLOCK_KEY0
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY1[];
#define ESP_EFUSE_WR_DIS_KEY1 ESP_EFUSE_WR_DIS_BLOCK_KEY1
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY2[];
#define ESP_EFUSE_WR_DIS_KEY2 ESP_EFUSE_WR_DIS_BLOCK_KEY2
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY3[];
#define ESP_EFUSE_WR_DIS_KEY3 ESP_EFUSE_WR_DIS_BLOCK_KEY3
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY4[];
#define ESP_EFUSE_WR_DIS_KEY4 ESP_EFUSE_WR_DIS_BLOCK_KEY4
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_KEY5[];
#define ESP_EFUSE_WR_DIS_KEY5 ESP_EFUSE_WR_DIS_BLOCK_KEY5
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA2[];
#define ESP_EFUSE_WR_DIS_SYS_DATA_PART2 ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA2
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_USB_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SOFT_DIS_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY0[];
#define ESP_EFUSE_RD_DIS_KEY0 ESP_EFUSE_RD_DIS_BLOCK_KEY0
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY1[];
#define ESP_EFUSE_RD_DIS_KEY1 ESP_EFUSE_RD_DIS_BLOCK_KEY1
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY2[];
#define ESP_EFUSE_RD_DIS_KEY2 ESP_EFUSE_RD_DIS_BLOCK_KEY2
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY3[];
#define ESP_EFUSE_RD_DIS_KEY3 ESP_EFUSE_RD_DIS_BLOCK_KEY3
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY4[];
#define ESP_EFUSE_RD_DIS_KEY4 ESP_EFUSE_RD_DIS_BLOCK_KEY4
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_KEY5[];
#define ESP_EFUSE_RD_DIS_KEY5 ESP_EFUSE_RD_DIS_BLOCK_KEY5
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_BLOCK_SYS_DATA2[];
#define ESP_EFUSE_RD_DIS_SYS_DATA_PART2 ESP_EFUSE_RD_DIS_BLOCK_SYS_DATA2
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_TWAI[];
extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_GLITCH_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_GLITCH_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_CORE1[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_BOOT_CRYPT_CNT[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_0[];
#define ESP_EFUSE_KEY0_PURPOSE ESP_EFUSE_KEY_PURPOSE_0
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_1[];
#define ESP_EFUSE_KEY1_PURPOSE ESP_EFUSE_KEY_PURPOSE_1
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_2[];
#define ESP_EFUSE_KEY2_PURPOSE ESP_EFUSE_KEY_PURPOSE_2
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_3[];
#define ESP_EFUSE_KEY3_PURPOSE ESP_EFUSE_KEY_PURPOSE_3
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_4[];
#define ESP_EFUSE_KEY4_PURPOSE ESP_EFUSE_KEY_PURPOSE_4
extern const esp_efuse_desc_t* ESP_EFUSE_KEY_PURPOSE_5[];
#define ESP_EFUSE_KEY5_PURPOSE ESP_EFUSE_KEY_PURPOSE_5
extern const esp_efuse_desc_t* ESP_EFUSE_SEC_DPA_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_XTS_DPA_CLK_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_ECC_FORCE_CONST_TIME[];
extern const esp_efuse_desc_t* ESP_EFUSE_ECDSA_P384_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_DISABLE_DEPLOY_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_RND_SWITCH_CYCLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_DEPLOY_ONLY_ONCE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_USE_KEY_MANAGER_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_DISABLE_SW_INIT_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_XTS_KEY_LENGTH_256[];
extern const esp_efuse_desc_t* ESP_EFUSE_LOCK_KM_KEY[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TPUW[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DIRECT_BOOT[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[];
extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[];
extern const esp_efuse_desc_t* ESP_EFUSE_SECURE_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_HUK_GEN_STATE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_LDO_EFUSE_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_OTG_FS_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_PHY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_IO_LDO_ADJUST[];
extern const esp_efuse_desc_t* ESP_EFUSE_IO_LDO_1P8[];
extern const esp_efuse_desc_t* ESP_EFUSE_DCDC_CCM_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_MAC[];
#define ESP_EFUSE_MAC_FACTORY ESP_EFUSE_MAC
extern const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_LIMIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_CELL_SELECT[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_PUMP_LIMIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_PUMP_DRV[];
extern const esp_efuse_desc_t* ESP_EFUSE_WDT_DELAY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_HYS_EN_PAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_GLITCH_CHARGE_RESET[];
extern const esp_efuse_desc_t* ESP_EFUSE_VDD_SPI_LDO_ADJUST[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_LDO_POWER_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
#define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];
#define ESP_EFUSE_MAC_CUSTOM ESP_EFUSE_USER_DATA_MAC_CUSTOM
#define ESP_EFUSE_CUSTOM_MAC ESP_EFUSE_USER_DATA_MAC_CUSTOM
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
#define ESP_EFUSE_BLOCK_KEY0 ESP_EFUSE_KEY0
extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
#define ESP_EFUSE_BLOCK_KEY1 ESP_EFUSE_KEY1
extern const esp_efuse_desc_t* ESP_EFUSE_KEY2[];
#define ESP_EFUSE_BLOCK_KEY2 ESP_EFUSE_KEY2
extern const esp_efuse_desc_t* ESP_EFUSE_KEY3[];
#define ESP_EFUSE_BLOCK_KEY3 ESP_EFUSE_KEY3
extern const esp_efuse_desc_t* ESP_EFUSE_KEY4[];
#define ESP_EFUSE_BLOCK_KEY4 ESP_EFUSE_KEY4
extern const esp_efuse_desc_t* ESP_EFUSE_KEY5[];
#define ESP_EFUSE_BLOCK_KEY5 ESP_EFUSE_KEY5
extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART2[];
#define ESP_EFUSE_BLOCK_SYS_DATA2 ESP_EFUSE_SYS_DATA_PART2
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0
#define ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(scheme, max_num_bit)
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
"esp_efuse_fields.c"
"esp_efuse_utility.c")

View File

@ -43,7 +43,7 @@ extern void spi_flash_enable_interrupts_caches_and_other_cpu(void);
__attribute__((unused)) __attribute__((unused))
static void s_test_cache_disable_period_us(test_adc_iram_ctx_t *ctx, uint32_t period_us); static void s_test_cache_disable_period_us(test_adc_iram_ctx_t *ctx, uint32_t period_us);
#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_IRAM_SAFE #if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_CACHE_SAFE
/*--------------------------------------------------------------- /*---------------------------------------------------------------
ADC oneshot work with cache safe ISR ADC oneshot work with cache safe ISR
---------------------------------------------------------------*/ ---------------------------------------------------------------*/
@ -140,7 +140,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]")
TEST_ESP_OK(gptimer_del_timer(timer)); TEST_ESP_OK(gptimer_del_timer(timer));
TEST_ESP_OK(adc_oneshot_del_unit(oneshot_handle)); TEST_ESP_OK(adc_oneshot_del_unit(oneshot_handle));
} }
#endif //#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_IRAM_SAFE #endif //#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_CACHE_SAFE
#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE #if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE
#include "esp_adc/adc_continuous.h" #include "esp_adc/adc_continuous.h"

View File

@ -3,7 +3,7 @@ CONFIG_XTAL_FREQ_26=y
CONFIG_COMPILER_DUMP_RTL_FILES=y CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y CONFIG_GPTIMER_ISR_CACHE_SAFE=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y

View File

@ -1,6 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y CONFIG_GPTIMER_ISR_CACHE_SAFE=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y

View File

@ -1,6 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y CONFIG_GPTIMER_ISR_CACHE_SAFE=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y

View File

@ -20,7 +20,7 @@ When a peripheral driver does de-initialization, to de-configure the pin as the
If the signal is routed through IO MUX to the pin, then only needs to call `gpio_iomux_input` to select the IO MUX function index and direct the signal to IO MUX. Input will be enabled for the IO internally. If the signal is routed through IO MUX to the pin, then only needs to call `gpio_iomux_input` to select the IO MUX function index and direct the signal to IO MUX. Input will be enabled for the IO internally.
If the signal is routed through GPIO Matrix to the pin, then first call `gpio_func_sel` to let the pin use `PIN_FUNC_GPIO` function, follow by calling `gpio_input_enable` and `esp_rom_gpio_connect_in_signal` to enable the input and connect the signal to the pin. If the signal is routed through GPIO Matrix to the pin, then call `gpio_input_enable` and `esp_rom_gpio_connect_in_signal` to enable the input and connect the signal to the pin.
When a peripheral driver does de-initialization, to de-configure the pin as the peripheral signal input, use `esp_rom_gpio_connect_in_signal` to connect the signal to CONST_ONE or CONST_ZERO, so that it is disconnected from the pin. It is not desired to call `gpio_input_disable`, because there might be other drivers still using this pin as an input. When a peripheral driver does de-initialization, to de-configure the pin as the peripheral signal input, use `esp_rom_gpio_connect_in_signal` to connect the signal to CONST_ONE or CONST_ZERO, so that it is disconnected from the pin. It is not desired to call `gpio_input_disable`, because there might be other drivers still using this pin as an input.

View File

@ -53,7 +53,7 @@ esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num);
esp_err_t gpio_func_sel(gpio_num_t gpio_num, uint32_t func); esp_err_t gpio_func_sel(gpio_num_t gpio_num, uint32_t func);
/** /**
* @brief Enable output for an IO * @brief Enable output for an IO (as a simple GPIO output)
* *
* @param gpio_num GPIO number * @param gpio_num GPIO number
* *
@ -126,13 +126,12 @@ esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx);
* @param gpio_num GPIO number of the pad. * @param gpio_num GPIO number of the pad.
* @param func The index number of the IOMUX function to be selected for the pin. * @param func The index number of the IOMUX function to be selected for the pin.
* One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``. * One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
* @param out_en_inv Whether the output enable control is inverted or not.
* *
* @return * @return
* - ESP_OK Success * - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO number error * - ESP_ERR_INVALID_ARG GPIO number error
*/ */
esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func, bool out_en_inv); esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -207,7 +207,7 @@ esp_err_t gpio_output_disable(gpio_num_t gpio_num)
{ {
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
gpio_hal_output_disable(gpio_context.gpio_hal, gpio_num); gpio_hal_output_disable(gpio_context.gpio_hal, gpio_num);
gpio_hal_matrix_out_default(gpio_context.gpio_hal, gpio_num); // Ensure no other output signal is routed via GPIO matrix to this pin gpio_hal_set_output_enable_ctrl(gpio_context.gpio_hal, gpio_num, false, false); // so that output disable could take effect
return ESP_OK; return ESP_OK;
} }
@ -604,13 +604,7 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags,
{ {
GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG); GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
gpio_isr_alloc_t p; gpio_isr_alloc_t p;
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7995 p.source = GPIO_LL_INTR_SOURCE0;
p.source = ETS_GPIO_INTR0_SOURCE;
#elif CONFIG_IDF_TARGET_ESP32H21 // TODO: IDF-11611
p.source = ETS_GPIO_INTERRUPT_PRO_SOURCE;
#else
p.source = ETS_GPIO_INTR_SOURCE;
#endif
p.intr_alloc_flags = intr_alloc_flags; p.intr_alloc_flags = intr_alloc_flags;
#if SOC_ANA_CMPR_INTR_SHARE_WITH_GPIO #if SOC_ANA_CMPR_INTR_SHARE_WITH_GPIO
p.intr_alloc_flags |= ESP_INTR_FLAG_SHARED; p.intr_alloc_flags |= ESP_INTR_FLAG_SHARED;
@ -836,15 +830,16 @@ esp_err_t gpio_iomux_input(gpio_num_t gpio_num, int func, uint32_t signal_idx)
// Deprecated function // Deprecated function
void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv) void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv)
{ {
gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, out_en_inv); (void)out_en_inv; // out_en_inv only takes effect when signal goes through gpio matrix to the IO
gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func);
} }
esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func, bool out_en_inv) esp_err_t gpio_iomux_output(gpio_num_t gpio_num, int func)
{ {
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, out_en_inv); gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func);
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
return ESP_OK; return ESP_OK;
@ -1094,11 +1089,18 @@ esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask)
gpio_io_config_t io_config = {}; gpio_io_config_t io_config = {};
gpio_get_io_config(gpio_num, &io_config); gpio_get_io_config(gpio_num, &io_config);
// When the IO is used as a simple GPIO output, oe signal can only be controlled by the oe register
// When the IO is not used as a simple GPIO output, oe signal could be controlled by the peripheral
const char *oe_str = io_config.oe ? "1" : "0";
if (io_config.sig_out != SIG_GPIO_OUT_IDX && io_config.oe_ctrl_by_periph) {
oe_str = "[periph_sig_ctrl]";
}
fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_reserved(BIT64(gpio_num)) ? " **RESERVED**" : ""); fprintf(out_stream, "IO[%"PRIu32"]%s -\n", gpio_num, esp_gpio_is_reserved(BIT64(gpio_num)) ? " **RESERVED**" : "");
fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", io_config.pu, io_config.pd, (uint32_t)io_config.drv); fprintf(out_stream, " Pullup: %d, Pulldown: %d, DriveCap: %"PRIu32"\n", io_config.pu, io_config.pd, (uint32_t)io_config.drv);
fprintf(out_stream, " InputEn: %d, OutputEn: %d, OpenDrain: %d\n", io_config.ie, io_config.oe, io_config.od); fprintf(out_stream, " InputEn: %d, OutputEn: %s%s, OpenDrain: %d\n", io_config.ie, oe_str, ((io_config.fun_sel == PIN_FUNC_GPIO) && (io_config.oe_inv)) ? " (inversed)" : "", io_config.od);
fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", io_config.fun_sel, (io_config.fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX"); fprintf(out_stream, " FuncSel: %"PRIu32" (%s)\n", io_config.fun_sel, (io_config.fun_sel == PIN_FUNC_GPIO) ? "GPIO" : "IOMUX");
if (io_config.oe && io_config.fun_sel == PIN_FUNC_GPIO) { if (io_config.fun_sel == PIN_FUNC_GPIO) {
fprintf(out_stream, " GPIO Matrix SigOut ID: %"PRIu32"%s\n", io_config.sig_out, (io_config.sig_out == SIG_GPIO_OUT_IDX) ? " (simple GPIO output)" : ""); fprintf(out_stream, " GPIO Matrix SigOut ID: %"PRIu32"%s\n", io_config.sig_out, (io_config.sig_out == SIG_GPIO_OUT_IDX) ? " (simple GPIO output)" : "");
} }
if (io_config.ie && io_config.fun_sel == PIN_FUNC_GPIO) { if (io_config.ie && io_config.fun_sel == PIN_FUNC_GPIO) {

View File

@ -3,11 +3,6 @@
components/esp_driver_gpio/test_apps: components/esp_driver_gpio/test_apps:
depends_components: depends_components:
- esp_driver_gpio - esp_driver_gpio
disable:
- if: IDF_TARGET in ["esp32h21"]
temporary: true
reason: not support yet # TODO: [esp32h21] IDF-11611
components/esp_driver_gpio/test_apps/gpio_extensions: components/esp_driver_gpio/test_apps/gpio_extensions:
enable: enable:
- if: SOC_DEDICATED_GPIO_SUPPORTED == 1 - if: SOC_DEDICATED_GPIO_SUPPORTED == 1

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -561,6 +561,9 @@ TEST_CASE("GPIO_get_level_from_fixed_voltage_test", "[gpio]")
TEST_ASSERT_EQUAL_INT_MESSAGE(0, level2, "get level error! the level should be low!"); TEST_ASSERT_EQUAL_INT_MESSAGE(0, level2, "get level error! the level should be low!");
} }
#if !CONFIG_IDF_ENV_FPGA
// On FPGA do not support GPIO pull down
TEST_CASE("GPIO_io_pull_up/down_function", "[gpio]") TEST_CASE("GPIO_io_pull_up/down_function", "[gpio]")
{ {
// First, ensure that the output IO will not affect the level // First, ensure that the output IO will not affect the level
@ -662,6 +665,8 @@ TEST_CASE("GPIO_mode_test", "[gpio]")
TEST_ASSERT_EQUAL_INT_MESSAGE(!level, gpio_get_level(TEST_GPIO_EXT_IN_IO), "direction GPIO_MODE_INPUT_OUTPUT set error, it gives incorrect output"); TEST_ASSERT_EQUAL_INT_MESSAGE(!level, gpio_get_level(TEST_GPIO_EXT_IN_IO), "direction GPIO_MODE_INPUT_OUTPUT set error, it gives incorrect output");
} }
#endif //!CONFIG_IDF_ENV_FPGA
static void prompt_to_continue(const char *str) static void prompt_to_continue(const char *str)
{ {
printf("%s , please press \"Enter\" to go on!\n", str); printf("%s , please press \"Enter\" to go on!\n", str);

View File

@ -1,31 +1,45 @@
menu "ESP-Driver:GPTimer Configurations" menu "ESP-Driver:GPTimer Configurations"
depends on SOC_GPTIMER_SUPPORTED depends on SOC_GPTIMER_SUPPORTED
config GPTIMER_ISR_HANDLER_IN_IRAM config GPTIMER_ISR_HANDLER_IN_IRAM
bool "Place GPTimer ISR handler into IRAM" bool "Place GPTimer ISR handler in IRAM to reduce latency"
default y default y
select GPTIMER_OBJ_CACHE_SAFE
help help
Place GPTimer ISR handler into IRAM for better performance and fewer cache misses. Place GPTimer ISR handler in IRAM to reduce latency caused by cache miss.
config GPTIMER_CTRL_FUNC_IN_IRAM config GPTIMER_CTRL_FUNC_IN_IRAM
bool "Place GPTimer control functions into IRAM" bool "Place GPTimer control functions in IRAM"
default n default n
select GPTIMER_OBJ_CACHE_SAFE
help help
Place GPTimer control functions (like start/stop) into IRAM, Place GPTimer control functions (like start/stop) in IRAM, to reduce latency caused by cache miss.
so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. If enabled, these functions can also be called when cache is disabled.
Enabling this option can improve driver performance as well.
config GPTIMER_ISR_IRAM_SAFE config GPTIMER_ISR_CACHE_SAFE
bool "GPTimer ISR IRAM-Safe" bool "Allow GPTimer ISR to execute when cache is disabled"
select GPTIMER_ISR_HANDLER_IN_IRAM select GPTIMER_ISR_HANDLER_IN_IRAM
default n default n
help help
Ensure the GPTimer interrupt is IRAM-Safe by allowing the interrupt handler to be Enable this option to allow the GPTimer Interrupt Service Routine (ISR)
executable when the cache is disabled (e.g. SPI Flash write). to execute even when the cache is disabled. This can be useful in scenarios where the cache
might be turned off, but the GPTimer functionality is still required to operate correctly.
config GPTIMER_ENABLE_DEBUG_LOG config GPTIMER_OBJ_CACHE_SAFE
bool "Enable debug log" bool
default n default n
help help
whether to enable the debug log message for GPTimer driver. This will ensure the GPTimer object will not be allocated from a memory region
Note that, this option only controls the GPTimer driver log, won't affect other drivers. where its cache can be disabled.
config GPTIMER_ENABLE_DEBUG_LOG
bool "Force enable debug log"
default n
help
If enabled, GPTimer component will:
1. ignore the global logging settings
2. compile all log messages into the binary
3. set the runtime log level to VERBOSE
Please enable this option by caution, as it will increase the binary size.
endmenu endmenu

View File

@ -135,7 +135,7 @@ esp_err_t gptimer_get_captured_count(gptimer_handle_t timer, uint64_t *value);
/** /**
* @brief Group of supported GPTimer callbacks * @brief Group of supported GPTimer callbacks
* @note The callbacks are all running under ISR environment * @note The callbacks are all running under ISR environment
* @note When CONFIG_GPTIMER_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. * @note When CONFIG_GPTIMER_ISR_CACHE_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
*/ */
typedef struct { typedef struct {
gptimer_alarm_cb_t on_alarm; /*!< Timer alarm callback */ gptimer_alarm_cb_t on_alarm; /*!< Timer alarm callback */

View File

@ -0,0 +1,4 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
CONFIG_GPTIMER_ISR_IRAM_SAFE CONFIG_GPTIMER_ISR_CACHE_SAFE

View File

@ -1,27 +1,14 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <sys/lock.h> #include <sys/lock.h>
#include "sdkconfig.h"
#if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "freertos/FreeRTOS.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/gptimer.h" #include "driver/gptimer.h"
#include "esp_memory_utils.h"
#include "gptimer_priv.h" #include "gptimer_priv.h"
#include "esp_memory_utils.h"
static const char *TAG = "gptimer";
static void gptimer_default_isr(void *args); static void gptimer_default_isr(void *args);
@ -136,9 +123,6 @@ static esp_err_t gptimer_destroy(gptimer_t *timer)
esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *ret_timer) esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *ret_timer)
{ {
#if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
gptimer_t *timer = NULL; gptimer_t *timer = NULL;
ESP_RETURN_ON_FALSE(config && ret_timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(config && ret_timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
@ -188,7 +172,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
timer->direction = config->direction; timer->direction = config->direction;
timer->intr_priority = config->intr_priority; timer->intr_priority = config->intr_priority;
timer->flags.intr_shared = config->flags.intr_shared; timer->flags.intr_shared = config->flags.intr_shared;
ESP_LOGD(TAG, "new gptimer (%d,%d) at %p, resolution=%"PRIu32"Hz", group_id, timer_id, timer, timer->resolution_hz); ESP_LOGD(TAG, "new gptimer (%d,%d) at %p, %zu bytes used", group_id, timer_id, timer, heap_caps_get_allocated_size(timer));
*ret_timer = timer; *ret_timer = timer;
return ESP_OK; return ESP_OK;
@ -231,7 +215,9 @@ esp_err_t gptimer_del_timer(gptimer_handle_t timer)
esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, unsigned long long value) esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, unsigned long long value)
{ {
ESP_RETURN_ON_FALSE_ISR(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&timer->spinlock); portENTER_CRITICAL_SAFE(&timer->spinlock);
timer_hal_set_counter_value(&timer->hal, value); timer_hal_set_counter_value(&timer->hal, value);
@ -241,7 +227,9 @@ esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, unsigned long long value
esp_err_t gptimer_get_raw_count(gptimer_handle_t timer, unsigned long long *value) esp_err_t gptimer_get_raw_count(gptimer_handle_t timer, unsigned long long *value)
{ {
ESP_RETURN_ON_FALSE_ISR(timer && value, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL || value == NULL) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&timer->spinlock); portENTER_CRITICAL_SAFE(&timer->spinlock);
*value = timer_hal_capture_and_get_counter_value(&timer->hal); *value = timer_hal_capture_and_get_counter_value(&timer->hal);
@ -258,7 +246,9 @@ esp_err_t gptimer_get_resolution(gptimer_handle_t timer, uint32_t *out_resolutio
esp_err_t gptimer_get_captured_count(gptimer_handle_t timer, uint64_t *value) esp_err_t gptimer_get_captured_count(gptimer_handle_t timer, uint64_t *value)
{ {
ESP_RETURN_ON_FALSE_ISR(timer && value, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL || value == NULL) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&timer->spinlock); portENTER_CRITICAL_SAFE(&timer->spinlock);
*value = timer_ll_get_counter_value(timer->hal.dev, timer->timer_id); *value = timer_ll_get_counter_value(timer->hal.dev, timer->timer_id);
@ -274,7 +264,7 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer
int group_id = group->group_id; int group_id = group->group_id;
int timer_id = timer->timer_id; int timer_id = timer->timer_id;
#if CONFIG_GPTIMER_ISR_IRAM_SAFE #if CONFIG_GPTIMER_ISR_CACHE_SAFE
if (cbs->on_alarm) { if (cbs->on_alarm) {
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_alarm), ESP_ERR_INVALID_ARG, TAG, "on_alarm callback not in IRAM"); ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_alarm), ESP_ERR_INVALID_ARG, TAG, "on_alarm callback not in IRAM");
} }
@ -308,14 +298,22 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer
esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_config_t *config) esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_config_t *config)
{ {
ESP_RETURN_ON_FALSE_ISR(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (config) { if (config) {
#if CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM #if CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
ESP_RETURN_ON_FALSE_ISR(esp_ptr_internal(config), ESP_ERR_INVALID_ARG, TAG, "alarm config struct not in internal RAM"); // when the function is placed in IRAM, we expect the config struct is also placed in internal RAM
// if the cache is disabled, the function can still access the config struct
if (esp_ptr_internal(config) == false) {
return ESP_ERR_INVALID_ARG;
}
#endif #endif
// When auto_reload is enabled, alarm_count should not be equal to reload_count // When auto_reload is enabled, alarm_count should not be equal to reload_count
bool valid_auto_reload = !config->flags.auto_reload_on_alarm || config->alarm_count != config->reload_count; bool valid_auto_reload = !config->flags.auto_reload_on_alarm || config->alarm_count != config->reload_count;
ESP_RETURN_ON_FALSE_ISR(valid_auto_reload, ESP_ERR_INVALID_ARG, TAG, "reload count can't equal to alarm count"); if (valid_auto_reload == false) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&timer->spinlock); portENTER_CRITICAL_SAFE(&timer->spinlock);
timer->reload_count = config->reload_count; timer->reload_count = config->reload_count;
@ -343,6 +341,7 @@ esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_c
esp_err_t gptimer_enable(gptimer_handle_t timer) esp_err_t gptimer_enable(gptimer_handle_t timer)
{ {
ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
// the only acceptable FSM change: init->enable
gptimer_fsm_t expected_fsm = GPTIMER_FSM_INIT; gptimer_fsm_t expected_fsm = GPTIMER_FSM_INIT;
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_ENABLE), ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_ENABLE),
ESP_ERR_INVALID_STATE, TAG, "timer not in init state"); ESP_ERR_INVALID_STATE, TAG, "timer not in init state");
@ -363,6 +362,7 @@ esp_err_t gptimer_enable(gptimer_handle_t timer)
esp_err_t gptimer_disable(gptimer_handle_t timer) esp_err_t gptimer_disable(gptimer_handle_t timer)
{ {
ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
// the only acceptable FSM change: enable->init
gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE; gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE;
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_INIT), ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_INIT),
ESP_ERR_INVALID_STATE, TAG, "timer not in enable state"); ESP_ERR_INVALID_STATE, TAG, "timer not in enable state");
@ -382,7 +382,14 @@ esp_err_t gptimer_disable(gptimer_handle_t timer)
esp_err_t gptimer_start(gptimer_handle_t timer) esp_err_t gptimer_start(gptimer_handle_t timer)
{ {
ESP_RETURN_ON_FALSE_ISR(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
}
// if the timer is already started, do nothing
if (atomic_load(&timer->fsm) == GPTIMER_FSM_RUN) {
return ESP_OK;
}
gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE; gptimer_fsm_t expected_fsm = GPTIMER_FSM_ENABLE;
if (atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_RUN_WAIT)) { if (atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_RUN_WAIT)) {
@ -396,7 +403,8 @@ esp_err_t gptimer_start(gptimer_handle_t timer)
atomic_store(&timer->fsm, GPTIMER_FSM_RUN); atomic_store(&timer->fsm, GPTIMER_FSM_RUN);
portEXIT_CRITICAL_SAFE(&timer->spinlock); portEXIT_CRITICAL_SAFE(&timer->spinlock);
} else { } else {
ESP_RETURN_ON_FALSE_ISR(false, ESP_ERR_INVALID_STATE, TAG, "timer is not ready for a new start"); // return error if the timer is not in the expected state
return ESP_ERR_INVALID_STATE;
} }
return ESP_OK; return ESP_OK;
@ -404,7 +412,15 @@ esp_err_t gptimer_start(gptimer_handle_t timer)
esp_err_t gptimer_stop(gptimer_handle_t timer) esp_err_t gptimer_stop(gptimer_handle_t timer)
{ {
ESP_RETURN_ON_FALSE_ISR(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); if (timer == NULL) {
// not printing error message here because the return value already indicates the error well
return ESP_ERR_INVALID_ARG;
}
// if the timer is not started, do nothing
if (atomic_load(&timer->fsm) == GPTIMER_FSM_ENABLE) {
return ESP_OK;
}
gptimer_fsm_t expected_fsm = GPTIMER_FSM_RUN; gptimer_fsm_t expected_fsm = GPTIMER_FSM_RUN;
if (atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_ENABLE_WAIT)) { if (atomic_compare_exchange_strong(&timer->fsm, &expected_fsm, GPTIMER_FSM_ENABLE_WAIT)) {
@ -415,7 +431,8 @@ esp_err_t gptimer_stop(gptimer_handle_t timer)
atomic_store(&timer->fsm, GPTIMER_FSM_ENABLE); atomic_store(&timer->fsm, GPTIMER_FSM_ENABLE);
portEXIT_CRITICAL_SAFE(&timer->spinlock); portEXIT_CRITICAL_SAFE(&timer->spinlock);
} else { } else {
ESP_RETURN_ON_FALSE_ISR(false, ESP_ERR_INVALID_STATE, TAG, "timer is not running"); // return error if the timer is not in the expected state
return ESP_ERR_INVALID_STATE;
} }
return ESP_OK; return ESP_OK;

View File

@ -1,18 +1,14 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <sys/lock.h> #include <sys/lock.h>
#include "esp_check.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/gptimer.h" #include "esp_private/gptimer.h"
#include "gptimer_priv.h" #include "gptimer_priv.h"
#include "soc/soc_caps.h" #include "esp_private/esp_clk_tree_common.h"
static const char *TAG = "gptimer";
typedef struct gptimer_platform_t { typedef struct gptimer_platform_t {
_lock_t mutex; // platform level mutex lock _lock_t mutex; // platform level mutex lock
@ -182,3 +178,11 @@ int gptimer_get_group_id(gptimer_handle_t timer, int *group_id)
*group_id = timer->group->group_id; *group_id = timer->group->group_id;
return ESP_OK; return ESP_OK;
} }
#if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
__attribute__((constructor))
static void gptimer_override_default_log_level(void)
{
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
}
#endif

View File

@ -1,26 +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 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <sys/lock.h> #include <sys/lock.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_heap_caps.h"
#include "driver/gptimer.h" #include "driver/gptimer.h"
#include "gptimer_priv.h" #include "gptimer_priv.h"
#include "hal/timer_ll.h"
#include "esp_private/etm_interface.h" #include "esp_private/etm_interface.h"
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
static const char *TAG = "gptimer-etm";
static esp_err_t gptimer_del_etm_event(esp_etm_event_t *event) static esp_err_t gptimer_del_etm_event(esp_etm_event_t *event)
{ {
free(event); free(event);
@ -36,17 +27,16 @@ static esp_err_t gptimer_del_etm_task(esp_etm_task_t *task)
esp_err_t gptimer_new_etm_event(gptimer_handle_t timer, const gptimer_etm_event_config_t *config, esp_etm_event_handle_t *out_event) esp_err_t gptimer_new_etm_event(gptimer_handle_t timer, const gptimer_etm_event_config_t *config, esp_etm_event_handle_t *out_event)
{ {
esp_etm_event_t *event = NULL; esp_etm_event_t *event = NULL;
esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(timer && config && out_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(timer && config && out_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(config->event_type < GPTIMER_ETM_EVENT_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid event type");
ESP_GOTO_ON_FALSE(config->event_type < GPTIMER_ETM_EVENT_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid event type");
event = heap_caps_calloc(1, sizeof(esp_etm_event_t), ETM_MEM_ALLOC_CAPS); event = heap_caps_calloc(1, sizeof(esp_etm_event_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM event"); ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no memory for ETM event");
// get the event ID that can be recognized by ETM hardware
gptimer_group_t *group = timer->group; gptimer_group_t *group = timer->group;
int group_id = group->group_id; int group_id = group->group_id;
int timer_id = timer->timer_id; int timer_id = timer->timer_id;
uint32_t event_id = TIMER_LL_ETM_EVENT_TABLE(group_id, timer_id, config->event_type); uint32_t event_id = TIMER_LL_ETM_EVENT_TABLE(group_id, timer_id, config->event_type);
ESP_GOTO_ON_FALSE(event_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported event type");
// fill the ETM event object // fill the ETM event object
event->event_id = event_id; event->event_id = event_id;
@ -54,28 +44,21 @@ esp_err_t gptimer_new_etm_event(gptimer_handle_t timer, const gptimer_etm_event_
event->del = gptimer_del_etm_event; event->del = gptimer_del_etm_event;
*out_event = event; *out_event = event;
return ESP_OK; return ESP_OK;
err:
if (event) {
gptimer_del_etm_event(event);
}
return ret;
} }
esp_err_t gptimer_new_etm_task(gptimer_handle_t timer, const gptimer_etm_task_config_t *config, esp_etm_task_handle_t *out_task) esp_err_t gptimer_new_etm_task(gptimer_handle_t timer, const gptimer_etm_task_config_t *config, esp_etm_task_handle_t *out_task)
{ {
esp_etm_task_t *task = NULL; esp_etm_task_t *task = NULL;
esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(timer && config && out_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(timer && config && out_task, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(config->task_type < GPTIMER_ETM_TASK_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid task type");
ESP_GOTO_ON_FALSE(config->task_type < GPTIMER_ETM_TASK_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid task type");
task = heap_caps_calloc(1, sizeof(esp_etm_task_t), ETM_MEM_ALLOC_CAPS); task = heap_caps_calloc(1, sizeof(esp_etm_task_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(task, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM task"); ESP_RETURN_ON_FALSE(task, ESP_ERR_NO_MEM, TAG, "no memory for ETM task");
// get the task ID that can be recognized by ETM hardware
gptimer_group_t *group = timer->group; gptimer_group_t *group = timer->group;
int group_id = group->group_id; int group_id = group->group_id;
int timer_id = timer->timer_id; int timer_id = timer->timer_id;
uint32_t task_id = TIMER_LL_ETM_TASK_TABLE(group_id, timer_id, config->task_type); uint32_t task_id = TIMER_LL_ETM_TASK_TABLE(group_id, timer_id, config->task_type);
ESP_GOTO_ON_FALSE(task_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported task type");
// fill the ETM task object // fill the ETM task object
task->task_id = task_id; task->task_id = task_id;
@ -83,10 +66,4 @@ esp_err_t gptimer_new_etm_task(gptimer_handle_t timer, const gptimer_etm_task_co
task->del = gptimer_del_etm_task; task->del = gptimer_del_etm_task;
*out_task = task; *out_task = task;
return ESP_OK; return ESP_OK;
err:
if (task) {
gptimer_del_etm_task(task);
}
return ret;
} }

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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -9,17 +9,25 @@
#include <stdint.h> #include <stdint.h>
#include <stdatomic.h> #include <stdatomic.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#if CONFIG_GPTIMER_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for gptimer driver
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#endif
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "clk_ctrl_os.h"
#include "esp_pm.h" #include "esp_pm.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "hal/timer_types.h" #include "hal/timer_types.h"
#include "hal/timer_hal.h" #include "hal/timer_hal.h"
#include "hal/timer_ll.h" #include "hal/timer_ll.h"
#include "clk_ctrl_os.h"
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
@ -29,13 +37,13 @@ extern "C" {
// If ISR handler is allowed to run whilst cache is disabled, // If ISR handler is allowed to run whilst cache is disabled,
// Make sure all the code and related variables used by the handler are in the SRAM // Make sure all the code and related variables used by the handler are in the SRAM
#if CONFIG_GPTIMER_ISR_IRAM_SAFE || CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM #if CONFIG_GPTIMER_OBJ_CACHE_SAFE
#define GPTIMER_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #define GPTIMER_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else #else
#define GPTIMER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #define GPTIMER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif #endif
#if CONFIG_GPTIMER_ISR_IRAM_SAFE #if CONFIG_GPTIMER_ISR_CACHE_SAFE
#define GPTIMER_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) #define GPTIMER_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED)
#else #else
#define GPTIMER_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED #define GPTIMER_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED
@ -53,6 +61,10 @@ extern "C" {
#define GPTIMER_CLOCK_SRC_ATOMIC() #define GPTIMER_CLOCK_SRC_ATOMIC()
#endif #endif
///!< Logging settings
#define TAG "gptimer"
///!< Forward declaration
typedef struct gptimer_t gptimer_t; typedef struct gptimer_t gptimer_t;
typedef struct gptimer_group_t { typedef struct gptimer_group_t {

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -1,7 +1,7 @@
set(srcs "test_app_main.c" set(srcs "test_app_main.c"
"test_gptimer.c") "test_gptimer.c")
if(CONFIG_GPTIMER_ISR_IRAM_SAFE) if(CONFIG_GPTIMER_ISR_CACHE_SAFE)
list(APPEND srcs "test_gptimer_iram.c") list(APPEND srcs "test_gptimer_iram.c")
endif() endif()
@ -15,6 +15,8 @@ endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs} idf_component_register(
PRIV_REQUIRES unity esp_driver_gptimer esp_driver_gpio SRCS ${srcs}
WHOLE_ARCHIVE) PRIV_REQUIRES unity esp_driver_gptimer esp_driver_gpio
WHOLE_ARCHIVE
)

View File

@ -13,11 +13,11 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_attr.h" #include "esp_attr.h"
#if CONFIG_GPTIMER_ISR_IRAM_SAFE #if CONFIG_GPTIMER_ISR_CACHE_SAFE
#define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR #define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
#else #else
#define TEST_ALARM_CALLBACK_ATTR #define TEST_ALARM_CALLBACK_ATTR
#endif // CONFIG_GPTIMER_ISR_IRAM_SAFE #endif // CONFIG_GPTIMER_ISR_CACHE_SAFE
TEST_CASE("gptimer_set_get_raw_count", "[gptimer]") TEST_CASE("gptimer_set_get_raw_count", "[gptimer]")
{ {
@ -103,7 +103,7 @@ TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
printf("get raw count of gptimer %d: %llu\r\n", i, value); printf("get raw count of gptimer %d: %llu\r\n", i, value);
// convert the raw count to us // convert the raw count to us
value = value * 1000000 / timer_resolution_hz[i]; value = value * 1000000 / timer_resolution_hz[i];
TEST_ASSERT_UINT_WITHIN(200, 20000, value); TEST_ASSERT_UINT_WITHIN(400, 20000, value); //200 more threshold for cpu on stop process
} }
printf("restart timers\r\n"); printf("restart timers\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
@ -121,7 +121,7 @@ TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
printf("get raw count of gptimer %d: %llu\r\n", i, value); printf("get raw count of gptimer %d: %llu\r\n", i, value);
// convert the raw count to us // convert the raw count to us
value = value * 1000000 / timer_resolution_hz[i]; value = value * 1000000 / timer_resolution_hz[i];
TEST_ASSERT_UINT_WITHIN(400, 40000, value); TEST_ASSERT_UINT_WITHIN(600, 40000, value); //same 200 for cpu time
} }
printf("disable timers\r\n"); printf("disable timers\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
@ -299,7 +299,7 @@ TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_normal_callback(gptimer_
* Also should account for the inaccuracy of the systick during DFS. * Also should account for the inaccuracy of the systick during DFS.
*/ */
#if CONFIG_PM_ENABLE #if CONFIG_PM_ENABLE
#define GPTIMER_ONE_SHOT_ALARM_COUNT_DELTA 15000 #define GPTIMER_ONE_SHOT_ALARM_COUNT_DELTA 50000
#else #else
#define GPTIMER_ONE_SHOT_ALARM_COUNT_DELTA 1000 #define GPTIMER_ONE_SHOT_ALARM_COUNT_DELTA 1000
#endif // CONFIG_PM_ENABLE #endif // CONFIG_PM_ENABLE

View File

@ -13,11 +13,11 @@
#include "driver/gpio_etm.h" #include "driver/gpio_etm.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#if CONFIG_GPTIMER_ISR_IRAM_SAFE #if CONFIG_GPTIMER_ISR_CACHE_SAFE
#define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR #define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
#else #else
#define TEST_ALARM_CALLBACK_ATTR #define TEST_ALARM_CALLBACK_ATTR
#endif // CONFIG_GPTIMER_ISR_IRAM_SAFE #endif // CONFIG_GPTIMER_ISR_CACHE_SAFE
TEST_ALARM_CALLBACK_ATTR TEST_ALARM_CALLBACK_ATTR
static bool on_gptimer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) static bool on_gptimer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)

View File

@ -23,7 +23,7 @@ static void IRAM_ATTR test_delay_post_cache_disable(void *args)
esp_rom_delay_us(1000); esp_rom_delay_us(1000);
} }
TEST_CASE("gptimer_interrupt_iram_safe", "[gptimer]") TEST_CASE("gptimer works with cache disabled", "[gptimer]")
{ {
gptimer_handle_t gptimer = NULL; gptimer_handle_t gptimer = NULL;
gptimer_config_t timer_config = { gptimer_config_t timer_config = {

View File

@ -1,6 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y CONFIG_GPTIMER_ISR_CACHE_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y CONFIG_COMPILER_OPTIMIZATION_NONE=y
# place non-ISR FreeRTOS functions in Flash # place non-ISR FreeRTOS functions in Flash
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y

View File

@ -258,7 +258,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
if (config->clk_src == PARLIO_CLK_SRC_EXTERNAL) { if (config->clk_src == PARLIO_CLK_SRC_EXTERNAL) {
ESP_RETURN_ON_FALSE(config->clk_in_gpio_num >= 0, ESP_ERR_INVALID_ARG, TAG, "clk_in_gpio_num must be set while the clock input from external"); ESP_RETURN_ON_FALSE(config->clk_in_gpio_num >= 0, ESP_ERR_INVALID_ARG, TAG, "clk_in_gpio_num must be set while the clock input from external");
/* Connect the clock in signal to the GPIO matrix if it is set */ /* Connect the clock in signal to the GPIO matrix if it is set */
gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->clk_in_gpio_num); gpio_input_enable(config->clk_in_gpio_num);
// deprecated, to be removed in in esp-idf v6.0 // deprecated, to be removed in in esp-idf v6.0
@ -290,7 +289,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
/* Initialize the valid GPIO as input */ /* Initialize the valid GPIO as input */
if (config->valid_gpio_num >= 0) { if (config->valid_gpio_num >= 0) {
gpio_func_sel(config->valid_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->valid_gpio_num); gpio_input_enable(config->valid_gpio_num);
// deprecated, to be removed in in esp-idf v6.0 // deprecated, to be removed in in esp-idf v6.0
@ -305,7 +303,6 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
for (int i = 0; i < config->data_width; i++) { for (int i = 0; i < config->data_width; i++) {
/* Loop the data_gpio_nums to connect data and valid signals via GPIO matrix */ /* Loop the data_gpio_nums to connect data and valid signals via GPIO matrix */
if (config->data_gpio_nums[i] >= 0) { if (config->data_gpio_nums[i] >= 0) {
gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO);
gpio_input_enable(config->data_gpio_nums[i]); gpio_input_enable(config->data_gpio_nums[i]);
// deprecated, to be removed in in esp-idf v6.0 // deprecated, to be removed in in esp-idf v6.0

View File

@ -183,7 +183,6 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const
parlio_periph_signals.groups[group_id].tx_units[unit_id].clk_out_sig, false, false); parlio_periph_signals.groups[group_id].tx_units[unit_id].clk_out_sig, false, false);
} }
if (config->clk_in_gpio_num >= 0) { if (config->clk_in_gpio_num >= 0) {
gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->clk_in_gpio_num); gpio_input_enable(config->clk_in_gpio_num);
// deprecated, to be removed in in esp-idf v6.0 // deprecated, to be removed in in esp-idf v6.0

View File

@ -366,7 +366,7 @@ static void test_use_external_non_free_running_clock(parlio_tx_unit_handle_t tx_
TEST_ESP_OK(parlio_new_tx_unit(&config, &tx_unit)); TEST_ESP_OK(parlio_new_tx_unit(&config, &tx_unit));
TEST_ESP_OK(parlio_tx_unit_enable(tx_unit)); TEST_ESP_OK(parlio_tx_unit_enable(tx_unit));
// let core clock running for a while to update the clock divider threshold // let core clock running for a while to update the clock divider threshold
esp_rom_delay_us(100); esp_rom_delay_us(100 * 1000);
parlio_transmit_config_t transmit_config = { parlio_transmit_config_t transmit_config = {
.idle_value = 0xAA, .idle_value = 0xAA,
}; };

View File

@ -562,7 +562,7 @@ static void configure_pin_iomux(uint8_t gpio_num)
gpio_pulldown_dis(gpio_num); gpio_pulldown_dis(gpio_num);
gpio_input_enable(gpio_num); gpio_input_enable(gpio_num);
gpio_iomux_output(gpio_num, SDMMC_LL_IOMUX_FUNC, false); gpio_iomux_output(gpio_num, SDMMC_LL_IOMUX_FUNC);
gpio_set_drive_capability(gpio_num, 3); gpio_set_drive_capability(gpio_num, 3);
} }

View File

@ -445,7 +445,7 @@ static void bus_iomux_pins_set_oct(spi_host_device_t host, const spi_bus_config_
if (io_nums[i] > 0) { if (io_nums[i] > 0) {
// In Octal mode use function channel 2 // In Octal mode use function channel 2
gpio_iomux_input(io_nums[i], SPI2_FUNC_NUM_OCT, io_signals[i]); gpio_iomux_input(io_nums[i], SPI2_FUNC_NUM_OCT, io_signals[i]);
gpio_iomux_output(io_nums[i], SPI2_FUNC_NUM_OCT, false); gpio_iomux_output(io_nums[i], SPI2_FUNC_NUM_OCT);
} }
} }
} }
@ -455,23 +455,23 @@ static void bus_iomux_pins_set_quad(spi_host_device_t host, const spi_bus_config
{ {
if (bus_config->mosi_io_num >= 0) { if (bus_config->mosi_io_num >= 0) {
gpio_iomux_input(bus_config->mosi_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spid_in); gpio_iomux_input(bus_config->mosi_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spid_in);
gpio_iomux_output(bus_config->mosi_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(bus_config->mosi_io_num, spi_periph_signal[host].func);
} }
if (bus_config->miso_io_num >= 0) { if (bus_config->miso_io_num >= 0) {
gpio_iomux_input(bus_config->miso_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiq_in); gpio_iomux_input(bus_config->miso_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiq_in);
gpio_iomux_output(bus_config->miso_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(bus_config->miso_io_num, spi_periph_signal[host].func);
} }
if (bus_config->quadwp_io_num >= 0) { if (bus_config->quadwp_io_num >= 0) {
gpio_iomux_input(bus_config->quadwp_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiwp_in); gpio_iomux_input(bus_config->quadwp_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiwp_in);
gpio_iomux_output(bus_config->quadwp_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(bus_config->quadwp_io_num, spi_periph_signal[host].func);
} }
if (bus_config->quadhd_io_num >= 0) { if (bus_config->quadhd_io_num >= 0) {
gpio_iomux_input(bus_config->quadhd_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spihd_in); gpio_iomux_input(bus_config->quadhd_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spihd_in);
gpio_iomux_output(bus_config->quadhd_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(bus_config->quadhd_io_num, spi_periph_signal[host].func);
} }
if (bus_config->sclk_io_num >= 0) { if (bus_config->sclk_io_num >= 0) {
gpio_iomux_input(bus_config->sclk_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiclk_in); gpio_iomux_input(bus_config->sclk_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spiclk_in);
gpio_iomux_output(bus_config->sclk_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(bus_config->sclk_io_num, spi_periph_signal[host].func);
} }
} }
@ -733,7 +733,7 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) { if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define. //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
gpio_iomux_input(cs_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spics_in); gpio_iomux_input(cs_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spics_in);
gpio_iomux_output(cs_io_num, spi_periph_signal[host].func, false); gpio_iomux_output(cs_io_num, spi_periph_signal[host].func);
} else { } else {
//Use GPIO matrix //Use GPIO matrix
if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) { if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) {

View File

@ -652,7 +652,7 @@ static SPI_MASTER_ISR_ATTR void spi_setup_device(spi_device_t *dev, spi_trans_pr
.duty_cycle = dev->cfg.duty_cycle_pos, .duty_cycle = dev->cfg.duty_cycle_pos,
.input_delay_ns = dev->cfg.input_delay_ns, .input_delay_ns = dev->cfg.input_delay_ns,
.half_duplex = dev->hal_dev.half_duplex, .half_duplex = dev->hal_dev.half_duplex,
.use_gpio = !(dev->host->bus_attr->flags | SPICOMMON_BUSFLAG_IOMUX_PINS), .use_gpio = !(dev->host->bus_attr->flags & SPICOMMON_BUSFLAG_IOMUX_PINS),
}; };
if (ESP_OK == spi_hal_cal_clock_conf(&timing_param, &dev->hal_dev.timing_conf)) { if (ESP_OK == spi_hal_cal_clock_conf(&timing_param, &dev->hal_dev.timing_conf)) {

View File

@ -686,7 +686,7 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
if (upin->input) { if (upin->input) {
gpio_iomux_input(io_num, upin->iomux_func, upin->signal); gpio_iomux_input(io_num, upin->iomux_func, upin->signal);
} else { } else {
gpio_iomux_output(io_num, upin->iomux_func, false); gpio_iomux_output(io_num, upin->iomux_func);
} }
} }
#if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1) #if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1)
@ -768,7 +768,6 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) { if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) {
io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(rx_io_num, PIN_FUNC_GPIO);
gpio_input_enable(rx_io_num); gpio_input_enable(rx_io_num);
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0); esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
} }
@ -803,7 +802,6 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) { if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(cts_io_num, PIN_FUNC_GPIO);
gpio_pullup_en(cts_io_num); gpio_pullup_en(cts_io_num);
gpio_input_enable(cts_io_num); gpio_input_enable(cts_io_num);
esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0); esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);

View File

@ -3,9 +3,6 @@
components/esp_driver_uart/test_apps/rs485: components/esp_driver_uart/test_apps/rs485:
disable: disable:
- if: SOC_UART_SUPPORTED != 1 - if: SOC_UART_SUPPORTED != 1
- if: IDF_TARGET in ["esp32h21"]
temporary: true
reason: not support yet # TODO: [esp32h21] IDF-11618
disable_test: disable_test:
- if: IDF_TARGET != "esp32" - if: IDF_TARGET != "esp32"
temporary: true temporary: true
@ -17,9 +14,6 @@ components/esp_driver_uart/test_apps/rs485:
components/esp_driver_uart/test_apps/uart: components/esp_driver_uart/test_apps/uart:
disable: disable:
- if: SOC_UART_SUPPORTED != 1 - if: SOC_UART_SUPPORTED != 1
- if: IDF_TARGET in ["esp32h21"]
temporary: true
reason: not support yet # TODO: [esp32h21] IDF-11618
depends_components: depends_components:
- esp_driver_uart - esp_driver_uart
- esp_driver_gpio - esp_driver_gpio

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -10,6 +10,7 @@
#include "driver/uart.h" #include "driver/uart.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_private/gpio.h"
#if SOC_LP_GPIO_MATRIX_SUPPORTED #if SOC_LP_GPIO_MATRIX_SUPPORTED
#include "driver/lp_io.h" #include "driver/lp_io.h"
#include "driver/rtc_io.h" #include "driver/rtc_io.h"
@ -463,6 +464,7 @@ TEST_CASE("uart int state restored after flush", "[uart]")
/* Make sure UART's TX signal is connected to RX pin /* Make sure UART's TX signal is connected to RX pin
* This creates a loop that lets us receive anything we send on the UART */ * This creates a loop that lets us receive anything we send on the UART */
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(uart_rx, PIN_FUNC_GPIO);
esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false); esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false);
#if SOC_UART_LP_NUM > 0 #if SOC_UART_LP_NUM > 0
} else { } else {

View File

@ -90,7 +90,7 @@ static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_
if (is_input) { if (is_input) {
ESP_RETURN_ON_ERROR(gpio_iomux_input(iomux_info->gpio_num, iomux_info->func, signal_idx), TAG, "failed to set perip. input via IOMUX"); ESP_RETURN_ON_ERROR(gpio_iomux_input(iomux_info->gpio_num, iomux_info->func, signal_idx), TAG, "failed to set perip. input via IOMUX");
} else { } else {
ESP_RETURN_ON_ERROR(gpio_iomux_output(iomux_info->gpio_num, iomux_info->func, false), TAG, "failed to set perip. output via IOMUX"); ESP_RETURN_ON_ERROR(gpio_iomux_output(iomux_info->gpio_num, iomux_info->func), TAG, "failed to set perip. output via IOMUX");
} }
ESP_RETURN_ON_ERROR(gpio_set_pull_mode(iomux_info->gpio_num, GPIO_FLOATING), ESP_RETURN_ON_ERROR(gpio_set_pull_mode(iomux_info->gpio_num, GPIO_FLOATING),
TAG, "failed to set pull mode at GPIO %i", iomux_info->gpio_num); TAG, "failed to set pull mode at GPIO %i", iomux_info->gpio_num);

View File

@ -703,10 +703,13 @@ static char *_get_host_header(char *host, int port)
{ {
int err = 0; int err = 0;
char *host_name; char *host_name;
assert(host != NULL);
// Check if host is an IPv6 address literal that needs square brackets according to RFC3986
bool is_ipv6 = (host[0] != '[' && strchr(host, ':') != NULL);
if (port != DEFAULT_HTTP_PORT && port != DEFAULT_HTTPS_PORT) { if (port != DEFAULT_HTTP_PORT && port != DEFAULT_HTTPS_PORT) {
err = asprintf(&host_name, "%s:%d", host, port); err = asprintf(&host_name, is_ipv6 ? "[%s]:%d" : "%s:%d", host, port);
} else { } else {
err = asprintf(&host_name, "%s", host); err = asprintf(&host_name, is_ipv6 ? "[%s]" : "%s", host);
} }
if (err == -1) { if (err == -1) {
return NULL; return NULL;
@ -1587,6 +1590,8 @@ static int http_client_prepare_first_line(esp_http_client_handle_t client, int w
client->connection_info.method != HTTP_METHOD_DELETE); client->connection_info.method != HTTP_METHOD_DELETE);
if (write_len != 0 || length_required) { if (write_len != 0 || length_required) {
http_header_set_format(client->request->headers, "Content-Length", "%d", write_len); http_header_set_format(client->request->headers, "Content-Length", "%d", write_len);
} else {
http_header_delete(client->request->headers, "Content-Length");
} }
} else { } else {
esp_http_client_set_header(client, "Transfer-Encoding", "chunked"); esp_http_client_set_header(client, "Transfer-Encoding", "chunked");

View File

@ -141,7 +141,7 @@ static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t*
allocated_mapping->ref_cnt++; allocated_mapping->ref_cnt++;
if (allocated_mapping->ref_cnt == 1) { if (allocated_mapping->ref_cnt == 1) {
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX #if SOC_GPIO_CLOCKOUT_BY_IO_MUX
gpio_iomux_output(gpio_num, CLKOUT_CHANNEL_TO_IOMUX_FUNC(allocated_mapping->clkout_channel_hdl->channel_id), false); gpio_iomux_output(gpio_num, CLKOUT_CHANNEL_TO_IOMUX_FUNC(allocated_mapping->clkout_channel_hdl->channel_id));
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
gpio_set_pull_mode(gpio_num, GPIO_FLOATING); gpio_set_pull_mode(gpio_num, GPIO_FLOATING);
gpio_func_sel(gpio_num, PIN_FUNC_GPIO); gpio_func_sel(gpio_num, PIN_FUNC_GPIO);

View File

@ -564,8 +564,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode. * used in lightsleep mode.
* *
* @param slowclk_period re-calibrated slow clock period * @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_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup #define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup

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 * 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); 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 // 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_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, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period)); 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, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); 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 */ /* Read back 'reject' status when waking from light or deep sleep */

View File

@ -598,8 +598,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode. * used in lightsleep mode.
* *
* @param slowclk_period re-calibrated slow clock period * @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_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

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 * 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); 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 // 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_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, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period)); 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, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); 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); static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -644,8 +644,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode. * used in lightsleep mode.
* *
* @param slowclk_period re-calibrated slow clock period * @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_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup

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 * 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); 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 // 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_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, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period)); 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, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); 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); static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -12,6 +12,7 @@
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
#include "hal/pmu_hal.h" #include "hal/pmu_hal.h"
#include "hal/regi2c_ctrl_ll.h"
#include "pmu_param.h" #include "pmu_param.h"
#include "esp_private/esp_pmu.h" #include "esp_private/esp_pmu.h"
#include "soc/regi2c_dig_reg.h" #include "soc/regi2c_dig_reg.h"
@ -209,8 +210,8 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx)
void pmu_init(void) void pmu_init(void)
{ {
/* Peripheral reg i2c power up */ /* Peripheral reg i2c power up */
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); regi2c_ctrl_ll_i2c_reset_set();
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); regi2c_ctrl_ll_i2c_periph_enable();
pmu_hp_system_init_default(PMU_instance()); pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance());

View File

@ -24,8 +24,15 @@ uint32_t *freq_value)
ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision");
ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer");
#if !SOC_CLK_TREE_SUPPORTED
// Have only XTAL 32M before clock tree supported
assert(clk_src == SOC_MOD_CLK_XTAL);
#endif
uint32_t clk_src_freq = 0; uint32_t clk_src_freq = 0;
switch (clk_src) { switch (clk_src) {
case SOC_MOD_CLK_XTAL:
clk_src_freq = SOC_XTAL_FREQ_32M * MHZ;
break;
case SOC_MOD_CLK_PLL_F48M: case SOC_MOD_CLK_PLL_F48M:
clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ; clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ;
break; break;
@ -39,8 +46,7 @@ uint32_t *freq_value)
break; break;
} }
ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG, ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG, "freq shouldn't be 0, calibration failed");
"freq shouldn't be 0, calibration failed");
*freq_value = clk_src_freq; *freq_value = clk_src_freq;
return ESP_OK; return ESP_OK;
} }

View File

@ -1,8 +1,77 @@
/* /*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
//TODO: [ESP32H21] IDF-11611 #include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
static uint8_t s_rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM] = { 0 };
static uint32_t s_rtc_io_using_mask = 0;
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
bool clk_conflict = false;
// check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true;
} else {
s_io_mux_clk_src = clk_src;
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
if (clk_conflict) {
return ESP_ERR_INVALID_STATE;
}
gpio_ll_iomux_set_clk_src(clk_src);
return ESP_OK;
}
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_enabled_cnt[gpio_num] == 0) {
s_rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_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_enabled_cnt[gpio_num] = 0;
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

View File

@ -669,8 +669,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode. * used in lightsleep mode.
* *
* @param slowclk_period re-calibrated slow clock period * @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_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup #define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -787,6 +787,13 @@ esp_err_t esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uin
bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW; bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW;
bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1; bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1;
// make sure there is no pending interrupt, this may be the case if the target just rebooted
// after a memory protection fault.
memprot_ll_iram0_clear_intr();
memprot_ll_dram0_clear_intr();
memprot_ll_peri1_clear_intr();
memprot_ll_peri2_clear_intr();
//disable protection //disable protection
if (use_iram0 && (ret = esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false)) != ESP_OK) { if (use_iram0 && (ret = esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false)) != ESP_OK) {
return ret; return ret;
@ -865,7 +872,7 @@ esp_err_t esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uin
} }
} }
//reenable protection (bus based) //re-enable protection (bus based)
if (use_iram0 && (ret = esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, true)) != ESP_OK) { if (use_iram0 && (ret = esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, true)) != ESP_OK) {
return ret; return ret;
} }

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 * 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); 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_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_CK8M_WAIT, RTC_CNTL_CK8M_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_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, dslp ? RTC_CNTL_CK8M_WAIT_DEFAULT : RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
} }
/* Read back 'reject' status when waking from light or deep sleep */ /* Read back 'reject' status when waking from light or deep sleep */

View File

@ -655,8 +655,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg);
* used in lightsleep mode. * used in lightsleep mode.
* *
* @param slowclk_period re-calibrated slow clock period * @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_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup
#define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup #define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup

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 * 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); 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 // 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_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, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period)); 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, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); 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); static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);

View File

@ -956,9 +956,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, esp_sleep_mode_
rtc_sleep_init(config); rtc_sleep_init(config);
// Set state machine time for light sleep // Set state machine time for light sleep
if (!deep_sleep) { rtc_sleep_low_init(s_config.rtc_clk_cal_period, deep_sleep);
rtc_sleep_low_init(s_config.rtc_clk_cal_period);
}
#endif #endif
// Configure timer wakeup // Configure timer wakeup

View File

@ -21,7 +21,7 @@ if(CONFIG_SOC_ETM_SUPPORTED)
list(APPEND srcs "test_etm_core.c") list(APPEND srcs "test_etm_core.c")
endif() endif()
if(CONFIG_SOC_GPTIMER_SUPPORTED) if(CONFIG_SOC_GPTIMER_SUPPORTED AND CONFIG_SOC_GPSPI_SUPPORTED)
list(APPEND srcs "test_intr_alloc.c") list(APPEND srcs "test_intr_alloc.c")
endif() endif()

View File

@ -99,8 +99,8 @@ TEST_CASE("GPIO output internal clock", "[gpio_output_clock][ignore]")
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
/* ESP32 clock out channel pin reuses UART TX/RX pin, restore its default /* ESP32 clock out channel pin reuses UART TX/RX pin, restore its default
configuration at the end of the test */ configuration at the end of the test */
gpio_iomux_output(U0RXD_GPIO_NUM, FUNC_U0RXD_U0RXD, false); gpio_iomux_output(U0RXD_GPIO_NUM, FUNC_U0RXD_U0RXD);
gpio_iomux_output(U0TXD_GPIO_NUM, FUNC_U0TXD_U0TXD, false); gpio_iomux_output(U0TXD_GPIO_NUM, FUNC_U0TXD_U0TXD);
#endif #endif
} }

View File

@ -223,6 +223,7 @@ netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif
ESP_LOGD(TAG, "%s: PPP connection created: %p", __func__, ppp_obj->ppp); ESP_LOGD(TAG, "%s: PPP connection created: %p", __func__, ppp_obj->ppp);
if (!ppp_obj->ppp) { if (!ppp_obj->ppp) {
ESP_LOGE(TAG, "%s: lwIP PPP connection cannot be created", __func__); ESP_LOGE(TAG, "%s: lwIP PPP connection cannot be created", __func__);
free(ppp_obj);
return NULL; return NULL;
} }

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -111,8 +111,7 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size
ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), irom_load_addr_aligned, mapped_size); ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), irom_load_addr_aligned, mapped_size);
start_page += BYTES_TO_MMU_PAGE(irom_size); *out_page = BYTES_TO_MMU_PAGE(irom_size);
*out_page = start_page;
ESP_EARLY_LOGI(TAG, ".text xip on psram"); ESP_EARLY_LOGI(TAG, ".text xip on psram");
return ESP_OK; return ESP_OK;
@ -147,8 +146,7 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si
ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), drom_load_addr_aligned, mapped_size); ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), drom_load_addr_aligned, mapped_size);
start_page += BYTES_TO_MMU_PAGE(drom_size); *out_page = BYTES_TO_MMU_PAGE(drom_size);
*out_page = start_page;
ESP_EARLY_LOGI(TAG, ".rodata xip on psram"); ESP_EARLY_LOGI(TAG, ".rodata xip on psram");
return ESP_OK; return ESP_OK;

View File

@ -420,10 +420,6 @@ size_t xRingbufferGetMaxItemSize(RingbufHandle_t xRingbuffer);
* buffer. This represents the maximum size an item/data can have if it was * buffer. This represents the maximum size an item/data can have if it was
* currently sent to the ring buffer. * currently sent to the ring buffer.
* *
* @warning This API is not thread safe. So, if multiple threads are accessing
* the same ring buffer, it is the application's responsibility to
* ensure atomic access to this API and the subsequent Send
*
* @note An empty no-split buffer has a max current free size for an item * @note An empty no-split buffer has a max current free size for an item
* that is limited to ((buffer_size/2)-header_size). See API reference * that is limited to ((buffer_size/2)-header_size). See API reference
* for xRingbufferGetMaxItemSize(). * for xRingbufferGetMaxItemSize().

View File

@ -27,7 +27,7 @@ else()
# Override regi2c implementation in ROM # Override regi2c implementation in ROM
if(CONFIG_ESP_ROM_HAS_REGI2C_BUG OR CONFIG_ESP_ROM_WITHOUT_REGI2C) if(CONFIG_ESP_ROM_HAS_REGI2C_BUG OR CONFIG_ESP_ROM_WITHOUT_REGI2C)
if(target STREQUAL "esp32c6" OR target STREQUAL "esp32c5") if(target STREQUAL "esp32c6" OR target STREQUAL "esp32c5" OR target STREQUAL "esp32h4")
list(APPEND sources "patches/esp_rom_hp_regi2c_${target}.c") list(APPEND sources "patches/esp_rom_hp_regi2c_${target}.c")
else() else()
list(APPEND sources "patches/esp_rom_regi2c_${target}.c") list(APPEND sources "patches/esp_rom_regi2c_${target}.c")

View File

@ -663,6 +663,7 @@ PROVIDE ( ld_acl_rsw_frm_cbk = 0x40033bb0 );
PROVIDE ( ld_sco_modify = 0x40031778 ); PROVIDE ( ld_sco_modify = 0x40031778 );
PROVIDE ( lm_cmd_cmp_send = 0x40051838 ); PROVIDE ( lm_cmd_cmp_send = 0x40051838 );
PROVIDE ( ld_sco_frm_cbk = 0x400349dc ); PROVIDE ( ld_sco_frm_cbk = 0x400349dc );
PROVIDE ( ld_sco_evt_start_cbk = 0x40031afc );
PROVIDE ( ld_sco_evt_stop_cbk = 0x40031d78 ); PROVIDE ( ld_sco_evt_stop_cbk = 0x40031d78 );
PROVIDE ( ld_acl_rsw_evt_start_cbk = 0x40031154 ); PROVIDE ( ld_acl_rsw_evt_start_cbk = 0x40031154 );
PROVIDE ( ld_acl_sco_rsvd_check = 0x4002fa94 ); PROVIDE ( ld_acl_sco_rsvd_check = 0x4002fa94 );

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -10,8 +10,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "soc/gpio_reg.h" #include "soc/gpio_reg.h"
//TODO: [ESP32H21] IDF-11611
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -30,7 +28,6 @@ extern "C" {
#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n)) #define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4) #define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4)
//TODO: [ESP32H21] IDF-11611, need check
#define GPIO_FUNC_IN_HIGH 0x20 #define GPIO_FUNC_IN_HIGH 0x20
#define GPIO_FUNC_IN_LOW 0x30 #define GPIO_FUNC_IN_LOW 0x30
@ -50,7 +47,7 @@ typedef enum {
/** /**
* @brief Change GPIO(0-27) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0). * @brief Change GPIO(0-25) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
* There is no particular ordering guaranteed; so if the order of writes is significant, * There is no particular ordering guaranteed; so if the order of writes is significant,
* calling code should divide a single call into multiple calls. * calling code should divide a single call into multiple calls.
* *
@ -67,7 +64,7 @@ typedef enum {
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask); void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
/** /**
* @brief Sample the value of GPIO input pins(0-27) and returns a bitmask. * @brief Sample the value of GPIO input pins(0-25) and returns a bitmask.
* *
* @param None * @param None
* *
@ -76,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
uint32_t gpio_input_get(void); uint32_t gpio_input_get(void);
/** /**
* @brief Set GPIO to wakeup the ESP32. * @brief Set GPIO to wakeup the ESP32H21.
* Please do not call this function in SDK. * Please do not call this function in SDK.
* *
* @param uint32_t i: gpio number. * @param uint32_t i: gpio number.
@ -88,7 +85,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state); void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/** /**
* @brief disable GPIOs to wakeup the ESP32. * @brief disable GPIOs to wakeup the ESP32H21.
* Please do not call this function in SDK. * Please do not call this function in SDK.
* *
* @param None * @param None
@ -100,10 +97,9 @@ void gpio_pin_wakeup_disable(void);
/** /**
* @brief set gpio input to a signal, one gpio can input to several signals. * @brief set gpio input to a signal, one gpio can input to several signals.
* *
* @param uint32_t gpio : gpio number, 0~27 * @param uint32_t gpio : gpio number, 0~25
* gpio == 0x3C, input 0 to signal * gpio == 0x30, input 0 to signal
* gpio == 0x3A, input nothing to signal * gpio == 0x20, input 1 to signal
* gpio == 0x38, input 1 to signal
* *
* @param uint32_t signal_idx : signal index. * @param uint32_t signal_idx : signal index.
* *
@ -116,7 +112,7 @@ void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv);
/** /**
* @brief set signal output to gpio, one signal can output to several gpios. * @brief set signal output to gpio, one signal can output to several gpios.
* *
* @param uint32_t gpio : gpio number, 0~27 * @param uint32_t gpio : gpio number, 0~25
* *
* @param uint32_t signal_idx : signal index. * @param uint32_t signal_idx : signal index.
* signal_idx == 0x80, cancel output put to the gpio * signal_idx == 0x80, cancel output put to the gpio
@ -132,7 +128,7 @@ void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_
/** /**
* @brief Select pad as a gpio function from IOMUX. * @brief Select pad as a gpio function from IOMUX.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -141,7 +137,7 @@ void gpio_pad_select_gpio(uint32_t gpio_num);
/** /**
* @brief Set pad driver capability. * @brief Set pad driver capability.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @param uint32_t drv : 0-3 * @param uint32_t drv : 0-3
* *
@ -152,7 +148,7 @@ void gpio_pad_set_drv(uint32_t gpio_num, uint32_t drv);
/** /**
* @brief Pull up the pad from gpio number. * @brief Pull up the pad from gpio number.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -161,7 +157,7 @@ void gpio_pad_pullup(uint32_t gpio_num);
/** /**
* @brief Pull down the pad from gpio number. * @brief Pull down the pad from gpio number.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -170,7 +166,7 @@ void gpio_pad_pulldown(uint32_t gpio_num);
/** /**
* @brief Unhold the pad from gpio number. * @brief Unhold the pad from gpio number.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -179,7 +175,7 @@ void gpio_pad_unhold(uint32_t gpio_num);
/** /**
* @brief Hold the pad from gpio number. * @brief Hold the pad from gpio number.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -188,7 +184,7 @@ void gpio_pad_hold(uint32_t gpio_num);
/** /**
* @brief enable gpio pad input. * @brief enable gpio pad input.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */
@ -197,7 +193,7 @@ void gpio_pad_input_enable(uint32_t gpio_num);
/** /**
* @brief disable gpio pad input. * @brief disable gpio pad input.
* *
* @param uint32_t gpio_num : gpio number, 0~27 * @param uint32_t gpio_num : gpio number, 0~25
* *
* @return None * @return None
*/ */

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