Porównaj commity

...

103 Commity

Autor SHA1 Wiadomość Data
mitchellcairns 4b192ddb00
Merge 45729f0897 into 9b3ae86417 2024-04-26 13:43:20 -07:00
morris 9b3ae86417 Merge branch 'bugfix/fix_gpio_etm_multi_task_v5.2' into 'release/v5.2'
fix(gpio_etm): allow one GPIO binds to multiple ETM tasks (v5.2)

See merge request espressif/esp-idf!30456
2024-04-25 16:31:22 +08:00
Marius Vikhammer eb7c381761 Merge branch 'fix/vTaskList_backports_v5.2' into 'release/v5.2'
FreeRTOS: vTaskList backports to v5.2

See merge request espressif/esp-idf!30478
2024-04-25 14:45:20 +08:00
Jiang Jiang Jian d82d7039fc Merge branch 'contrib/github_pr_13560_v5.2' into 'release/v5.2'
esp_eth: DP83848: correct link detection to use BMSR (GitHub PR) (v5.2)

See merge request espressif/esp-idf!30451
2024-04-25 11:20:37 +08:00
Jiang Jiang Jian 3d56f1b1b9 Merge branch 'feature/update-gdb-to-14.2_20240403_v5.2' into 'release/v5.2'
feat(tools): update gdb version to 14.2_20240403 (v5.2)

See merge request espressif/esp-idf!30437
2024-04-25 11:19:51 +08:00
Wang Meng Yang dc3e9531c0 Merge branch 'bugfix/bt_bss_in_extram_v5.2' into 'release/v5.2'
fix(bt): Fix missing linker symbol when ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY enabled(backport v5.2)

See merge request espressif/esp-idf!30378
2024-04-25 10:45:54 +08:00
morris 4cf7387e14 Merge branch 'fix/uart_wakeup_threshold_v5.2' into 'release/v5.2'
fix(uart): Fix mismatch wakeup rising edges required with the threshold configured (v5.2)

See merge request espressif/esp-idf!30462
2024-04-25 10:36:42 +08:00
morris bc4c826ff1 Merge branch 'bugfix/uart_bitrate_max_value_c2_v5.2' into 'release/v5.2'
fix(uart): correct C2 UART_BITRATE_MAX value (v5.2)

See merge request espressif/esp-idf!30459
2024-04-25 10:36:36 +08:00
morris 8374791fd4 Merge branch 'bugfix/gpio_drive_cap_v5.2' into 'release/v5.2'
fix(gpio): add workaround to ensure correct IO drive strength for C3 and S3 (v5.2)

See merge request espressif/esp-idf!30466
2024-04-25 10:36:31 +08:00
Michael (XIAO Xufeng) 78b6d515bb Merge branch 'bugfix/i2c_timeout_issue_v5.2' into 'release/v5.2'
fix(i2c): fix issues related to timeout and alive interval tick (backport v5.2)

See merge request espressif/esp-idf!29979
2024-04-24 23:48:32 +08:00
Darian Leung 27e8db2ae9
fix(freertos): Fix vTaskList() parameter print order
xCoreID was previously printed as the last parameter priority to IDF v5.1, but
was changed to the third paramtere from v5.2 onwards. This commit restores the
correct ordering.

Closes https://github.com/espressif/esp-idf/issues/13675
2024-04-24 17:56:59 +08:00
Omar Chebib 70fc931dd2
fix(freertos): display tasks with no affinity as -1 during tracing
Closes https://github.com/espressif/esp-idf/issues/12858
2024-04-24 17:51:11 +08:00
Wang Mengyang 4d7f9c5d88 change(bt): Add a test for release bt .bss and .data memory to heap
1. use nimble host, initialize and then deinitialize bt stack in the test
2. support tests for different SoC targets and multiple configuration options
2024-04-24 17:24:02 +08:00
Wang Mengyang c136089f4e change(bt): Modify test_app directory layout
- Existing test app is put in a new subdirectory "basic_unit_test"
2024-04-24 17:24:02 +08:00
Wang Mengyang bb6cf16177 change(bt): Rename linker script file names and symbol names
1. rename linker files
2. support memory release in case that ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY is enabled
3. improve the implementation of memory release
2024-04-24 17:24:02 +08:00
Wang Mengyang a06844d9b1 fix(bt): Fix missing linker symbol when ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY enabled
1. Closes https://github.com/espressif/esp-idf/issues/10427
2. add two linker script to unify linker script symbols for BT libraries
3. The memory release functions have also been simplified
2024-04-24 17:24:02 +08:00
Jiang Jiang Jian 5ec51688a6 Merge branch 'fix/fix_some_esp32c6_twt_bugs_v5.2' into 'release/v5.2'
fix(wifi): fix some esp32c6 twt bugs (Backport v5.2)

See merge request espressif/esp-idf!30401
2024-04-24 17:23:05 +08:00
Song Ruo Jing 64984b7b71 fix(gpio): add workaround to ensure correct IO drive strength for C3 and S3 2024-04-24 16:58:06 +08:00
Song Ruo Jing 15962a953a fix(uart): Fix mismatch wakeup rising edges required with the threshold configured
Closes https://github.com/espressif/esp-idf/issues/12586
2024-04-24 16:25:54 +08:00
Song Ruo Jing 1ed2f223fb fix(uart): correct C2 UART_BITRATE_MAX value 2024-04-24 16:19:41 +08:00
Song Ruo Jing 373e585bb7 fix(gpio_etm): allow one GPIO binds to multiple ETM tasks 2024-04-24 16:01:34 +08:00
Karl Palsson 52702cf886 fix(esp_eth): dp83848: correct link detection to use BMSR
Reading the link state via PHYSTS was incorrect, as it only reflects the
link state bit from BMSR.  BMSR latches link down events, and are not
cleared without being read.  (See 802.3-2008 section 2, section 22.2.4.2.13)
This leads to the original DP828xx code only supporting link up, then a
single link down event.

Switch to reading the link state via BMSR, but continuing to read the
negotiation results via PHYSTS and ANLPAR.  This is inline with
LAN8720x, RTL8201, KSZ80xx phy drivers, and other opensource drivers for
the DP838xx family of devices.

Tested on a private board with a DP83825i PHY.  No publically available
boards using the original DP83848 are known of for testing.

Signed-off-by: Karl Palsson <karl.palsson@marel.com>
2024-04-24 09:48:18 +02:00
Island 5fa34283c0 Merge branch 'feat/optimzie_ble_ctrl_memory_v5.2' into 'release/v5.2'
ble: support only legacy adv and slave function on esp32c2 (v5.2)

See merge request espressif/esp-idf!30334
2024-04-24 14:18:19 +08:00
xuxiao 9897fd9c87 fix(wifi): fix some esp32c6 wifi bugs (Backport v5.2) 2024-04-24 14:15:04 +08:00
Jiang Jiang Jian 8b4177f148 Merge branch 'bugfix/mgmt_gcmp_issue_v5.2' into 'release/v5.2'
fix(wifi): Fix GCMP encryption for mgmt packets and other bugfixes (Backport v5.2)

See merge request espressif/esp-idf!30439
2024-04-24 11:06:54 +08:00
zwl 275eab4f5d ble: update sdkconfig.defaults.esp32c6 file for blufi example 2024-04-24 10:50:40 +08:00
zwl 05521c918d ble: update sdkconfig.defaults.esp32c2 file for blufi example 2024-04-24 10:50:40 +08:00
zwl e99f45b4c6 ble: optimize bt cmakelists.txt file 2024-04-24 10:50:40 +08:00
zwl a64a528cb8 ble: support only legacy adv and slave function on esp32c2 2024-04-24 10:50:40 +08:00
Shu Chen 66c164b90b Merge branch 'backport/openthread_mtd_joiner_config_52' into 'release/v5.2'
fix(openthread): backport some openthread features(backportv5.2)

See merge request espressif/esp-idf!30419
2024-04-24 10:40:17 +08:00
Jiang Jiang Jian d4e32532df Merge branch 'bugfix/optimize_hidh_connection_v5.2' into 'release/v5.2'
fix(bt/bluedroid): Fix HID Host connection bugs[backport 5.2]

See merge request espressif/esp-idf!30425
2024-04-24 10:23:45 +08:00
Jiang Jiang Jian 5aad8507cb Merge branch 'bugfix/add_workaround_for_ble_rtc_hw_issue_backport_v5.2' into 'release/v5.2'
fix(ble): add workaround for ble RTC not enabled issue (v5.2)

See merge request espressif/esp-idf!30132
2024-04-24 10:16:49 +08:00
Jiang Jiang Jian 1c09bc1675 Merge branch 'bugfix/hf_local_param_null_v5.2' into 'release/v5.2'
fix(bt/bluedroid): allocate memory for control block of HFP Audio Gateway (v5.2)

See merge request espressif/esp-idf!30440
2024-04-24 10:15:47 +08:00
Jin Cheng 89dbe5f6dc fix(bt/bluedroid): allocate memory for control block of HFP Audio Gateway in its initialization when dynamic memory is wnabled 2024-04-24 08:25:24 +08:00
Kapil Gupta 5ce43f68f3 fix(esp_wifi): Correct action frame type in send_mgmt_frame API 2024-04-24 01:52:35 +05:30
Sarvesh Bodakhe 3ba5cb9687 fix(wifi): Add bugfix to avoid RSNXE and KDE mismatch during 4-way-handshake 2024-04-24 01:48:16 +05:30
Kapil Gupta 280ec09b03 fix(wifi): Fix encryption/decryption issue for mgmt packets
* Fix issues related to mgmt packets encryption in GCMP
* Fix issue of wrong decryption of mgmt packets when PMF is enabled
* Fix softAP bug in handling of SAE Reauthentication
2024-04-24 01:48:06 +05:30
Alexey Lapshin d2e5b33e2c feat(tools): update gdb version to 14.2_20240403 2024-04-23 22:32:39 +04:00
liqigan 98b744c85b fix(bt/bluedroid): Fix HID Host connection bugs
1. Fix is_orig value inconsistency for HIDH open event
2. Fix the error state for repeat connection of the same device
2024-04-23 21:04:50 +08:00
cjin ca79a7d878 bugfix(ble): workaround to avoid ble rtc not work when power up 2024-04-23 20:55:13 +08:00
Xu Si Yu d4a361bb71 feat(openthread): support openthread ephemeral key 2024-04-23 20:26:56 +08:00
Dávid Fehér d574cea5e5 fix(openthread): Fix openthread mtd joiner config
* Fix openthread-core-esp32x-mtd-config.h: OPENTHREAD_CONFIG_JOINER_ENABLE macro value

* On ESP32 MTD devices Joiner role functionality was not working even if 'Joiner enable' was checked in SDK config because 0 was defined in OPENTHREAD_CONFIG_JOINER_ENABLE macro. Value modified to 1 to resolve the issue. Tested and working on ESP32 H2 MTD device.

* Closes: https://github.com/espressif/esp-idf/pull/13473
2024-04-23 20:22:35 +08:00
Rahul Tank 2ba5320112 Merge branch 'bugfix/rpa_timeout_api_v5.2' into 'release/v5.2'
fix(nimble): Expose API to set RPA Timeout (v5.2)

See merge request espressif/esp-idf!30408
2024-04-23 20:08:21 +08:00
Jiang Jiang Jian 85e5f0e546 Merge branch 'bugfix/directed_bssid_probe_req_v52' into 'release/v5.2'
Send unicast probe requests if bssid is known during scan(v5.2)

See merge request espressif/esp-idf!30297
2024-04-23 17:14:48 +08:00
Roland Dobai f0e5c92516 Merge branch 'fix/exit_asyncio_gracefully_v5.2' into 'release/v5.2'
fix: exit gracefully when process started via asyncio is terminated (v5.2)

See merge request espressif/esp-idf!30383
2024-04-23 14:46:02 +08:00
Rahul Tank 28157cf1e2 fix(nimble): Expose API to set RPA Timeout 2024-04-23 11:24:10 +05:30
jgujarathi 0a13c60466 fix(esp_wifi): Send unicast probe requests if bssid is known during scan 2024-04-23 11:18:24 +05:30
Shu Chen 1b9597f961 Merge branch 'fix/make_eventfd_case_exit_normally_5_2' into 'release/v5.2'
fix(vfs): make case eventfd_select_block exit normally

See merge request espressif/esp-idf!29928
2024-04-23 10:07:18 +08:00
Xu Si Yu fd36f6fcac fix(ci): fix wrong path of ot sleep case 2024-04-22 20:24:05 +08:00
Xu Si Yu cea24c7137 feat(openthread): add max csmabackoffs for transmission 2024-04-22 20:24:05 +08:00
Xu Si Yu c3398f3373 fix(vfs): make case eventfd_select_block exit normally 2024-04-22 20:24:05 +08:00
Shu Chen 85315941e3 Merge branch 'fix/ieee802154_include_header_issue_v5.2' into 'release/v5.2'
Fix/ieee802154 include header issue (backport v5.2)

See merge request espressif/esp-idf!30332
2024-04-22 20:03:10 +08:00
xiaqilin 9e9aeb64be fix(ieee802154): fix ieee802154 include header file issue and unused value issue 2024-04-22 19:15:48 +08:00
xiaqilin b89f08a615 fix(ieee802154): fix ieee802154 next operation acquire lock in interrupt 2024-04-22 19:15:48 +08:00
Jiang Jiang Jian 470d5406ec Merge branch 'feat/sleep_retention_depends_power_state_management_v5.2' into 'release/v5.2'
backport v5.2: sleep retention multiple modules initialization and dependency management

See merge request espressif/esp-idf!30344
2024-04-22 19:14:10 +08:00
Frantisek Hrbata 4bc2985aa3 fix: exit gracefully when process started via asyncio is terminated
Currently when process is started through asyncio Runner and it is termited
e.g. with SIGINT(ctrl+c) a traceback is printed instead of gracefully
exit.

Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x7fe980970900>
Traceback (most recent call last):
  File "/usr/lib64/python3.12/asyncio/base_subprocess.py", line 129, in __del__
    self.close()
  File "/usr/lib64/python3.12/asyncio/base_subprocess.py", line 107, in close
    proto.pipe.close()
  File "/usr/lib64/python3.12/asyncio/unix_events.py", line 568, in close
    self._close(None)
  File "/usr/lib64/python3.12/asyncio/unix_events.py", line 592, in _close
    self._loop.call_soon(self._call_connection_lost, exc)
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 793, in call_soon
    self._check_closed()
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 540, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

This is caused because asyncio Runner context in asyncio.run is closing the event
loop and if exception is unhandled in coroutine(run_command) the transport is not
closed before the even loop is closed and we get RuntimeError: Event loop is closed
in the transport __del__ function because it's trying to use the closed
even loop.

Let's catch asyncio.CancelledError in case the process we are trying to
read from is terminated, print message, let the asyncio finish and exit
gracefully.

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

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-04-22 11:25:51 +02:00
Wang Meng Yang b0eef7f889 Merge branch 'bugfix/crash_after_bluedroid_deinit_v5.2' into 'release/v5.2'
fix(bt/bluedroid): Fixed controller using null pointer after bluedroid deinit(v5.2)

See merge request espressif/esp-idf!30327
2024-04-22 15:25:59 +08:00
Li Shuai f20186fe02 fix: modify some typos to ensure CI pipeline run pass 2024-04-22 12:49:34 +08:00
Li Shuai 4066844908 fix(example): fixed app partition is too small for binary size 2024-04-22 12:49:34 +08:00
xiaqilin ea3094a9a6 change(ieee802154): add sleep deinit API 2024-04-22 12:49:34 +08:00
Li Shuai 71d37432da change(esp_hw_support): use power down peripheral in light sleep option to determine TOP to off 2024-04-22 12:49:34 +08:00
Li Shuai 8f9090b351 change(esp_hw_support): add adc retention module and it is dependencies on the clock modem 2024-04-22 12:49:34 +08:00
Li Shuai 0e28063291 change(esp_hw_support): dump sleep retention context to io stream 2024-04-22 12:49:34 +08:00
Li Shuai 376b2f74ed change(ieee802154): use new sleep retention api to implement ieee802154 mac retention 2024-04-22 12:49:33 +08:00
Li Shuai 9f52809629 change(bt): use new retention api to implement BT mac and bb retention 2024-04-22 12:49:33 +08:00
Li Shuai 9c8b54b886 change(esp_hw_support): use new retention api to implement gdma retention 2024-04-22 12:49:33 +08:00
Li Shuai 4faf042c21 change(wifi): use new retention api to implement wifi mac and bb retention 2024-04-22 12:49:31 +08:00
Li Shuai 9a51752d4d change(esp_hw_support): modify system and modem clock to support modem domain power down 2024-04-19 14:08:15 +08:00
Li Shuai e7d6748aec change(esp_hw_support): some system peripherals to use a retention module number 2024-04-18 19:26:30 +08:00
Li Shuai a2cbe3f0a3 feat(esp_hw_support): implement of sleep retention module initialize and dependency management 2024-04-18 19:26:30 +08:00
Li Shuai f66e3f031d change(esp_hw_support): modify the style of module argument from bitmap to number 2024-04-18 19:26:28 +08:00
Jiang Jiang Jian 9efa26a23f Merge branch 'feature/disable_pmk_caching_v5.2' into 'release/v5.2'
feat(esp_wifi): Provide API to disable PMK caching (v5.2)

See merge request espressif/esp-idf!30289
2024-04-18 16:58:19 +08:00
Jiang Jiang Jian 3b9d5e120e Merge branch 'doc/update_espnow_example_v5.2' into 'release/v5.2'
docs(wifi): change the magic varible from int to uint32_t on the receiving side (v5.2)

See merge request espressif/esp-idf!30307
2024-04-18 14:47:19 +08:00
Marius Vikhammer aaf3f4a7c3 Merge branch 'contrib/github_pr_13022_v5.2' into 'release/v5.2'
fix(freertos): Fix broken portable macro portTRY_ENTER_CRITICAL_SAFE() (v5.2)

See merge request espressif/esp-idf!30314
2024-04-18 11:56:33 +08:00
Mahavir Jain 082c713069 Merge branch 'fix/incorrect_connection_closure_parttool_test_v5.2' into 'release/v5.2'
ci(otatool): fix test failure caused due to closing connection incorrectly (v5.2)

See merge request espressif/esp-idf!30291
2024-04-18 11:55:17 +08:00
Li Shuai f5c8cc2bef change(esp_hw_support): rename interface name of get modules bitmap to get created modules 2024-04-18 11:41:17 +08:00
Li Shuai fd47ea34bb change(esp_hw_support): rename sleep retention module to created module 2024-04-18 11:32:04 +08:00
Island b19e27dd48 Merge branch 'bugfix/fixed_coex_asset_on_esp32c2_v5.2' into 'release/v5.2'
Bugfix/fixed coex asset on esp32c2 v5.2

See merge request espressif/esp-idf!30302
2024-04-18 10:54:20 +08:00
Jiang Jiang Jian 22fbaf65fd Merge branch 'bugfix/fixed_some_wifi_bugs_240417_v5.2' into 'release/v5.2'
fix(wifi): fixed some wifi issues 240417(Backport v5.2)

See merge request espressif/esp-idf!30315
2024-04-18 10:46:24 +08:00
Island e362358ea3 Merge branch 'bugfix/fix_ble_appearance_v5.2' into 'release/v5.2'
Fixed BLE appearance category ranges (v5.2)

See merge request espressif/esp-idf!30285
2024-04-18 10:44:18 +08:00
xiongweichao 47d542acaa fix(bt/bluedroid): Fixed crash after bluedroid deinit
hci_host_env.downstream_data_ready is set to NULL during bluedroid deinit,
causing the controller to use a null pointer when calling callback.
2024-04-18 10:27:45 +08:00
zhanghaipeng c079772799 fix(ble/bluedroid): Fixed set BLE appearance value 2024-04-17 20:41:14 +08:00
muhaidong a07bce4fcc fix(wifi): fixed lmacEndFrameExchangeSequence assert issue 2024-04-17 19:16:55 +08:00
muhaidong 0e34a993d0 fix(wifi): fixed some wifi issue
1. sync multi antenna gpio register from IDF
2. fixed multicast address qos frames issue
3. fixed task watchdog got triggered by esp_wifi_stop issue
2024-04-17 19:16:24 +08:00
muhaidong 458ce7d4cf fix(wifi): fix multicast address qos frames issue 2024-04-17 19:15:46 +08:00
Andy Lin 6bcf47386d fix(freertos): Fix broken portable macro portTRY_ENTER_CRITICAL_SAFE()
This commit fixes a bug where the portTRY_ENTER_CRITICAL_SAFE() for the
Xtensa and RISC-V FreeRTOS ports were broken as it did not correctly use
the timeout parameter.

Merges: https://github.com/espressif/esp-idf/pull/13022
2024-04-17 12:26:50 +02:00
zhangyanjiao 830464eee7 docs(wifi): update the docmentation for sniffer API
Closes https://github.com/espressif/esp-idf/issues/10740
2024-04-17 16:17:00 +08:00
zhangyanjiao 83f272ca4f docs(wifi): change the magic varible from int to uint32_t on the receiving side
Closes https://github.com/espressif/esp-idf/issues/10912
2024-04-17 16:16:49 +08:00
Omar Chebib dcc7a41ad8 fix(i2c): fix issues related to timeout and alive interval tick
Fixes https://github.com/espressif/esp-idf/issues/4999

Former usage of I2C_CMD_ALIVE_INTERVAL_TICK macro overrode the ticks_to_wait
parameter when the latter was too big
2024-04-17 15:52:56 +08:00
zwl 73f6ca8ebf ble: fixed an occasional assertion issue in coexistence scenarios on ESP32C2 2024-04-17 14:59:31 +08:00
zwl cc213b7c61 ble: fixed the bt cmakelist error when use nimble host only 2024-04-17 14:59:21 +08:00
harshal.patil 42f244ae61
ci(otatool): fix test failure caused due to closing connection incorrectly 2024-04-17 10:13:35 +05:30
Kapil Gupta f9feb970b9 feat(esp_wifi): Provide API to disable PMK caching 2024-04-17 09:40:22 +05:30
Mitch Cairns 45729f0897 Merge branch 'release/v5.2' of https://github.com/mitchellcairns/esp-idf into release/v5.2 2023-12-28 13:34:22 -08:00
Mitch Cairns 151ac2efbf Update Kconfig.in
Add BT HID task size config option
Update esp_hid_common.h

add #ifndef BT_HID_DEVICE_TASK_SIZE to set a default
Update ble_hidd.c

add defined BT_HID_DEVICE_TASK_SIZE
Update bt_hidd.c

Add defined BT_HID_DEVICE_TASK_SIZE
Update esp_hid_common.h

Increase default to 4096
Update Kconfig.in

Update default HID task size to 4096 bytes
Implement DID for Bluetooth Classic HID Device

- Add necessary attributes that get passed along from the esp_hidd component

Remove unneeded comment
2023-12-28 13:34:04 -08:00
Mitch Cairns db15af1aa8 Remove unneeded comment 2023-12-28 13:25:22 -08:00
Mitch Cairns 795edfdbf5 Implement DID for Bluetooth Classic HID Device
- Add necessary attributes that get passed along from the esp_hidd component
2023-12-28 12:20:33 -08:00
mitchellcairns 73616f8aab
Update Kconfig.in
Update default HID task size to 4096 bytes
2023-12-28 00:07:23 -08:00
mitchellcairns 35021387d2
Update esp_hid_common.h
Increase default to 4096
2023-12-28 00:03:49 -08:00
mitchellcairns 730919f274
Update bt_hidd.c
Add defined BT_HID_DEVICE_TASK_SIZE
2023-12-28 00:03:12 -08:00
mitchellcairns b86d322c3d
Update ble_hidd.c
add defined BT_HID_DEVICE_TASK_SIZE
2023-12-28 00:02:49 -08:00
mitchellcairns 3ccbb041e3
Update esp_hid_common.h
add #ifndef BT_HID_DEVICE_TASK_SIZE to set a default
2023-12-28 00:01:58 -08:00
mitchellcairns 9a36745d25
Update Kconfig.in
Add BT HID task size config option
2023-12-27 23:58:59 -08:00
164 zmienionych plików z 2866 dodań i 1190 usunięć

Wyświetl plik

@ -67,37 +67,40 @@ if(CONFIG_IDF_DOC_BUILD)
${nimble_hci_include_dirs})
endif()
if(CONFIG_BT_ENABLED)
set(srcs "")
set(include_dirs "")
set(ldfragments "linker.lf")
set(ldscripts "linker_common.lf")
if(CONFIG_BT_CONTROLLER_ENABLED)
if(CONFIG_IDF_TARGET_ESP32)
list(APPEND srcs "controller/esp32/bt.c"
"controller/esp32/hli_api.c"
"controller/esp32/hli_vectors.S")
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C3)
list(APPEND srcs "controller/esp32c3/bt.c")
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32S3)
list(APPEND srcs "controller/esp32c3/bt.c")
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C2)
set(ldfragments "linker.lf.esp32c2")
list(APPEND srcs "controller/esp32c2/bt.c")
set(ldscripts "linker_esp32c2.lf")
elseif(CONFIG_IDF_TARGET_ESP32C6)
list(APPEND srcs "controller/esp32c6/bt.c")
list(APPEND ldscripts "linker_esp_ble_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32H2)
list(APPEND srcs "controller/esp32h2/bt.c")
list(APPEND ldscripts "linker_esp_ble_controller.lf")
endif()
list(APPEND include_dirs ${target_specific_include_dirs})
endif()
# Common
@ -820,7 +823,7 @@ idf_component_register(SRCS "${srcs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES esp_timer esp_wifi
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs
LDFRAGMENTS "${ldfragments}")
LDFRAGMENTS "${ldscripts}")
if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
@ -837,14 +840,8 @@ if(CONFIG_BT_ENABLED)
target_link_directories(${COMPONENT_LIB} INTERFACE
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
elseif(CONFIG_IDF_TARGET_ESP32C2)
add_prebuilt_library(libble_app "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
elseif(CONFIG_IDF_TARGET_ESP32C6)
add_prebuilt_library(libble_app "controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
elseif(CONFIG_IDF_TARGET_ESP32H2)
add_prebuilt_library(libble_app "controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a")
elseif(CONFIG_BT_CONTROLLER_ENABLED)
add_prebuilt_library(libble_app "controller/lib_${target}/${target}-bt-lib/libble_app.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
endif()

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -233,16 +233,12 @@ extern uint32_t _data_end_btdm_rom;
extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end;
extern uint32_t _nimble_bss_start;
extern uint32_t _nimble_bss_end;
extern uint32_t _btdm_bss_start;
extern uint32_t _btdm_bss_end;
extern uint32_t _bt_controller_bss_start;
extern uint32_t _bt_controller_bss_end;
extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end;
extern uint32_t _nimble_data_start;
extern uint32_t _nimble_data_end;
extern uint32_t _btdm_data_start;
extern uint32_t _btdm_data_end;
extern uint32_t _bt_controller_data_start;
extern uint32_t _bt_controller_data_end;
extern void config_bt_funcs_reset(void);
extern void config_ble_funcs_reset(void);
@ -760,7 +756,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block
* @param item The message which will be send
* @param hptw need do task yield or not
* @return send success or not
* There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes.
* There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes.
* But in Bluetooth controller's isr, We don't care about the return value.
* It only required tp send success when the queue is empty all the time.
* So, this function meets the requirement.
@ -1281,7 +1277,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret;
}
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
{
bool update = true;
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
@ -1332,61 +1366,86 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
}
}
if (mode == ESP_BT_MODE_BTDM) {
mem_start = (intptr_t)&_btdm_bss_start;
mem_end = (intptr_t)&_btdm_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_btdm_data_start;
mem_end = (intptr_t)&_btdm_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
return ESP_OK;
}
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
{
esp_err_t ret = ESP_OK;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
if (mode == ESP_BT_MODE_BTDM) {
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
}
if (ret == ESP_OK) {
ret = esp_bt_controller_rom_mem_release(mode);
}
return ret;
}
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
int ret;
intptr_t mem_start, mem_end;
esp_err_t ret = ESP_OK;
ret = esp_bt_controller_mem_release(mode);
if (ret != ESP_OK) {
return ret;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
bt_area_t bss = {
.start = (intptr_t)&_bt_bss_start,
.end = (intptr_t)&_bt_bss_end,
.name = "BT BSS",
};
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t data = {
.start = (intptr_t)&_bt_data_start,
.end = (intptr_t)&_bt_data_end,
.name = "BT Data",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
if (mode == ESP_BT_MODE_BTDM) {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
/* Start by freeing Bluetooth BSS section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
mem_start = (intptr_t)&_nimble_bss_start;
mem_end = (intptr_t)&_nimble_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_nimble_data_start;
mem_end = (intptr_t)&_nimble_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
/* Do the same thing with the Bluetooth data section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&data, &cont_data);
}
}
return ESP_OK;
/* free data and BSS section for Bluetooth controller ROM code */
if (ret == ESP_OK) {
ret = esp_bt_controller_rom_mem_release(mode);
}
return ret;
}
#if CONFIG_BTDM_CTRL_HLI
@ -1695,7 +1754,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
sdk_config_set_bt_pll_track_enable(true);
// inititalize bluetooth baseband
// initialize bluetooth baseband
btdm_check_and_init_bb();
ret = btdm_controller_enable(mode);
@ -1858,7 +1917,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void)
/**
* This function re-write controller's function,
* As coredump can not show paramerters in function which is in a .a file.
* As coredump can not show parameters in function which is in a .a file.
*
* After coredump fixing this issue, just delete this function.
*/

Wyświetl plik

@ -450,6 +450,7 @@ config BT_LE_USE_ESP_TIMER
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
bool "BLE adv report flow control supported"
depends on BT_LE_ROLE_OBSERVER_ENABLE
default y
help
The function is mainly used to enable flow control for advertising reports. When it is enabled,
@ -498,3 +499,31 @@ config BT_LE_CCA_RSSI_THRESH
default 20
help
Power threshold of CCA in unit of -1 dBm.
config BT_LE_ROLE_CENTROL_ENABLE
bool "Enable BLE Centrol role function"
depends on !BT_NIMBLE_ENABLED
default y
help
Enable centrol role function.
config BT_LE_ROLE_PERIPHERAL_ENABLE
bool "Enable BLE Peripheral role function"
depends on !BT_NIMBLE_ENABLED
default y
help
Enable Peripheral role function.
config BT_LE_ROLE_BROADCASTER_ENABLE
bool "Enable BLE Broadcaster role function"
depends on !BT_NIMBLE_ENABLED
default y
help
Enable broadcaster role function.
config BT_LE_ROLE_OBSERVER_ENABLE
bool "Enable BLE Observer role function"
depends on !BT_NIMBLE_ENABLED
default y
help
Enable observer role function.

Wyświetl plik

@ -168,11 +168,17 @@ extern const char *r_ble_controller_get_rom_compile_version(void);
#if CONFIG_BT_RELEASE_IRAM
extern uint32_t _iram_bt_text_start;
extern uint32_t _bss_bt_end;
#else
extern uint32_t _bt_bss_end;
extern uint32_t _bt_controller_data_start;
#endif
extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end;
extern uint32_t _bt_controller_bss_start;
extern uint32_t _bt_controller_bss_end;
extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end;
extern uint32_t _bt_controller_data_start;
extern uint32_t _bt_controller_data_end;
/* Local Function Declaration
*********************************************************************
*/
@ -644,6 +650,15 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
return ret;
}
#if DEFAULT_BT_LE_50_FEATURE_SUPPORT || DEFAULT_BT_LE_ROLE_CENTROL || DEFAULT_BT_LE_ROLE_OBSERVER
extern int esp_ble_rom_func_ptr_init_all(void);
esp_ble_rom_func_ptr_init_all();
#else
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Init only legacy adv and slave function");
extern int esp_ble_rom_func_ptr_init_legacy_adv_and_slave(void);
esp_ble_rom_func_ptr_init_legacy_adv_and_slave();
#endif
/* Initialize the function pointers for OS porting */
npl_freertos_funcs_init();
struct npl_funcs_t *p_npl_funcs = npl_freertos_funcs_get();
@ -891,9 +906,48 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret;
}
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
#ifndef CONFIG_BT_RELEASE_IRAM
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if(area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
#endif
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
intptr_t mem_start, mem_end;
esp_err_t ret = ESP_OK;
#if CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
/* Release Bluetooth text section and merge Bluetooth data, bss & text into a large free heap
@ -902,26 +956,58 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
* memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs
* to be disabled.
*/
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "`ESP_SYSTEM_PMP_IDRAM_SPLIT` should be disabled!");
assert(0);
#error "ESP_SYSTEM_PMP_IDRAM_SPLIT should be disabled to allow BT to be released"
#endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
if (mode & ESP_BT_MODE_BLE) {
#if CONFIG_BT_RELEASE_IRAM
mem_start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start);
mem_end = (intptr_t)&_bss_bt_end;
#else
mem_start = (intptr_t)&_bt_controller_data_start;
mem_end = (intptr_t)&_bt_bss_end;
#endif // CONFIG_BT_RELEASE_IRAM
if (mem_start != mem_end) {
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Release BLE [0x%08x] - [0x%08x], len %d", mem_start,
mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
if ((mode & ESP_BT_MODE_BLE) == 0) {
return ret;
}
#if CONFIG_BT_RELEASE_IRAM
bt_area_t merged_region = {
.start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start),
.end = (intptr_t)&_bss_bt_end,
.name = "BT Text, BSS and Data"
};
ret = esp_bt_mem_release_area(&merged_region);
#else
bt_area_t bss = {
.start = (intptr_t)&_bt_bss_start,
.end = (intptr_t)&_bt_bss_end,
.name = "BT BSS",
};
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t data = {
.start = (intptr_t)&_bt_data_start,
.end = (intptr_t)&_bt_data_end,
.name = "BT Data",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
/* Start by freeing Bluetooth BSS section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
/* Do the same thing with the Bluetooth data section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&data, &cont_data);
}
#endif
return ret;
}

Wyświetl plik

@ -46,6 +46,10 @@ extern "C" {
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
#endif
#define DEFAULT_BT_LE_ROLE_OBSERVER MYNEWT_VAL(BLE_ROLE_OBSERVER)
#define DEFAULT_BT_LE_ROLE_CENTROL MYNEWT_VAL(BLE_ROLE_CENTRAL)
#define DEFAULT_BT_LE_ROLE_PERIPHERAL MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
#define DEFAULT_BT_LE_ROLE_BROADCASTER MYNEWT_VAL(BLE_ROLE_BROADCASTER)
#else
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
@ -57,13 +61,13 @@ extern "C" {
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
#else
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5)
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (0)
#endif
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
#else
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1)
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (0)
#endif
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS)
@ -125,6 +129,29 @@ extern "C" {
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
#endif
#if defined(CONFIG_BT_LE_ROLE_CENTROL_ENABLE)
#define DEFAULT_BT_LE_ROLE_CENTROL (1)
#else
#define DEFAULT_BT_LE_ROLE_CENTROL (0)
#endif
#if defined(CONFIG_BT_LE_ROLE_PERIPHERAL_ENABLE)
#define DEFAULT_BT_LE_ROLE_PERIPHERAL (1)
#else
#define DEFAULT_BT_LE_ROLE_PERIPHERAL (0)
#endif
#if defined(CONFIG_BT_LE_ROLE_BROADCASTER_ENABLE)
#define DEFAULT_BT_LE_ROLE_BROADCASTER (1)
#else
#define DEFAULT_BT_LE_ROLE_BROADCASTER (0)
#endif
#if defined(CONFIG_BT_LE_ROLE_OBSERVER_ENABLE)
#define DEFAULT_BT_LE_ROLE_OBSERVER (1)
#else
#define DEFAULT_BT_LE_ROLE_OBSERVER (0)
#endif
#endif
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF

Wyświetl plik

@ -263,16 +263,12 @@ extern void btdm_cca_feature_enable(void);
extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end;
extern uint32_t _btdm_bss_start;
extern uint32_t _btdm_bss_end;
extern uint32_t _nimble_bss_start;
extern uint32_t _nimble_bss_end;
extern uint32_t _bt_controller_bss_start;
extern uint32_t _bt_controller_bss_end;
extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end;
extern uint32_t _btdm_data_start;
extern uint32_t _btdm_data_end;
extern uint32_t _nimble_data_start;
extern uint32_t _nimble_data_end;
extern uint32_t _bt_controller_data_start;
extern uint32_t _bt_controller_data_end;
/* Local Function Declare
*********************************************************************
@ -984,145 +980,175 @@ static void btdm_controller_mem_init(void)
btdm_controller_rom_data_init();
}
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
/**
* Release two memory areas to the heap. If both areas are consecutive, they will be released as
* a single area.
*/
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
{
esp_err_t ret = ESP_OK;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
if (mode & ESP_BT_MODE_BLE) {
/* if the addresses of rom btdm .data and .bss are consecutive,
they are registered in the system heap as a piece of memory
*/
if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) {
mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm;
mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
/* if the addresses of rom interface btdm .data and .bss are consecutive,
they are registered in the system heap as a piece of memory
*/
if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) {
mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
bt_area_t rom_btdm_data = {
.start = (intptr_t) ets_rom_layout_p->data_start_btdm,
.end = (intptr_t) ets_rom_layout_p->data_end_btdm,
.name = "ROM btdm data",
};
bt_area_t rom_btdm_bss = {
.start = (intptr_t)ets_rom_layout_p->bss_start_btdm,
.end = (intptr_t)ets_rom_layout_p->bss_end_btdm,
.name = "ROM btdm BSS",
};
bt_area_t rom_btdm_inter_data = {
.start = (intptr_t) ets_rom_layout_p->data_start_interface_btdm,
.end = (intptr_t) ets_rom_layout_p->data_end_interface_btdm,
.name = "ROM interface btdm data",
};
bt_area_t rom_btdm_inter_bss = {
.start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm,
.end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm,
.name = "ROM interface btdm BSS",
};
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
ret = ESP_ERR_INVALID_STATE;
}
return ESP_OK;
if (mode & ESP_BT_MODE_BLE) {
/* Free BTDM memory used by the ROM */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&rom_btdm_data, &rom_btdm_bss);
}
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&rom_btdm_inter_data, &rom_btdm_inter_bss);
}
}
return ret;
}
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
{
esp_err_t ret = ESP_OK;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
if (mode & ESP_BT_MODE_BLE) {
/* free data and BSS section for libbtdm_app.a */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
}
/* free data and BSS section for Bluetooth controller ROM code */
if (ret == ESP_OK) {
ret = esp_bt_controller_rom_mem_release(mode);
}
}
return ret;
}
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
int ret;
intptr_t mem_start, mem_end;
esp_err_t ret = ESP_OK;
ret = esp_bt_controller_mem_release(mode);
if (ret != ESP_OK) {
return ret;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
bt_area_t bss = {
.start = (intptr_t)&_bt_bss_start,
.end = (intptr_t)&_bt_bss_end,
.name = "BT BSS",
};
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t data = {
.start = (intptr_t)&_bt_data_start,
.end = (intptr_t)&_bt_data_end,
.name = "BT Data",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
if (mode & ESP_BT_MODE_BLE) {
/* if the addresses of btdm .bss and bt .bss are consecutive,
they are registered in the system heap as a piece of memory
*/
if(_bt_bss_end == _btdm_bss_start) {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_btdm_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_btdm_bss_start;
mem_end = (intptr_t)&_btdm_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
/* if the addresses of btdm .data and bt .data are consecutive,
they are registered in the system heap as a piece of memory
*/
if(_bt_data_end == _btdm_data_start) {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_btdm_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_btdm_data_start;
mem_end = (intptr_t)&_btdm_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
/* Start by freeing Bluetooth BSS section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
mem_start = (intptr_t)&_nimble_bss_start;
mem_end = (intptr_t)&_nimble_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
/* Do the same thing with the Bluetooth data section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&data, &cont_data);
}
mem_start = (intptr_t)&_nimble_data_start;
mem_end = (intptr_t)&_nimble_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
/* free data and BSS section for Bluetooth controller ROM code */
if (ret == ESP_OK) {
ret = esp_bt_controller_rom_mem_release(mode);
}
}
return ESP_OK;
return ret;
}
static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)

Wyświetl plik

@ -512,9 +512,10 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
}
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
{
uint8_t size;
int extra = *(int *)arg;
const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra);
esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
@ -523,9 +524,27 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
return err;
}
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
{
int retention_args = extra;
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
.depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
}
return err;
}
static void sleep_modem_ble_mac_modem_state_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC);
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
assert(err == ESP_OK);
}
}
void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
@ -984,70 +1003,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret;
}
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
intptr_t mem_start, mem_end;
esp_err_t ret = ESP_OK;
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
bt_area_t bss = {
.start = (intptr_t)&_bt_bss_start,
.end = (intptr_t)&_bt_bss_end,
.name = "BT BSS",
};
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t data = {
.start = (intptr_t)&_bt_data_start,
.end = (intptr_t)&_bt_data_end,
.name = "BT Data",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
if (mode & ESP_BT_MODE_BLE) {
/* If the addresses of btdm .bss and bt .bss are consecutive,
* they are registered in the system heap as a piece of memory
*/
if(_bt_bss_end == _bt_controller_bss_start) {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_controller_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_bt_controller_bss_start;
mem_end = (intptr_t)&_bt_controller_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
/* Start by freeing Bluetooth BSS section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
/* If the addresses of btdm .data and bt .data are consecutive,
* they are registered in the system heap as a piece of memory
*/
if(_bt_data_end == _bt_controller_data_start) {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_controller_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_bt_controller_data_start;
mem_end = (intptr_t)&_bt_controller_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
/* Do the same thing with the Bluetooth data section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&data, &cont_data);
}
}
return ESP_OK;
return ret;
}

Wyświetl plik

@ -501,9 +501,10 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
}
#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
{
uint8_t size;
int extra = *(int *)arg;
const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra);
esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
@ -512,9 +513,27 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
return err;
}
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
{
int retention_args = extra;
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
.depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
}
return err;
}
static void sleep_modem_ble_mac_modem_state_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC);
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
assert(err == ESP_OK);
}
}
void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
@ -957,70 +976,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret;
}
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
intptr_t mem_start, mem_end;
esp_err_t ret = ESP_OK;
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
bt_area_t bss = {
.start = (intptr_t)&_bt_bss_start,
.end = (intptr_t)&_bt_bss_end,
.name = "BT BSS",
};
bt_area_t cont_bss = {
.start = (intptr_t)&_bt_controller_bss_start,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t data = {
.start = (intptr_t)&_bt_data_start,
.end = (intptr_t)&_bt_data_end,
.name = "BT Data",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
if (mode & ESP_BT_MODE_BLE) {
/* If the addresses of btdm .bss and bt .bss are consecutive,
* they are registered in the system heap as a piece of memory
*/
if(_bt_bss_end == _bt_controller_bss_start) {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_controller_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_bss_start;
mem_end = (intptr_t)&_bt_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_bt_controller_bss_start;
mem_end = (intptr_t)&_bt_controller_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
/* Start by freeing Bluetooth BSS section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
/* If the addresses of btdm .data and bt .data are consecutive,
* they are registered in the system heap as a piece of memory
*/
if(_bt_data_end == _bt_controller_data_start) {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_controller_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)&_bt_data_start;
mem_end = (intptr_t)&_bt_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_bt_controller_data_start;
mem_end = (intptr_t)&_bt_controller_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d",
mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
/* Do the same thing with the Bluetooth data section */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&data, &cont_data);
}
}
return ESP_OK;
return ret;
}

@ -1 +1 @@
Subproject commit 05fa7ad7edc0fda255e353880bbd38263bc08b9b
Subproject commit b9a902c3551ef4a2032b6662a4cbb018125ddfda

Wyświetl plik

@ -144,6 +144,13 @@ config BT_HID_DEVICE_ENABLED
help
This enables the BT HID Device
config BT_HID_DEVICE_TASK_SIZE
int "Bluetooth HID event (callback to application) task stack size"
depends on BT_HID_DEVICE_ENABLED
default 4096
help
This selects the esp_hid task size
config BT_BLE_ENABLED
bool "Bluetooth Low Energy"
depends on BT_BLUEDROID_ENABLED

Wyświetl plik

@ -299,6 +299,7 @@ esp_err_t esp_ble_gap_config_local_icon (uint16_t icon)
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV:
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD:
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV:
case ESP_BLE_APPEARANCE_STANDALONE_SPEAKER:
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON;

Wyświetl plik

@ -104,6 +104,7 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit
#define ESP_BLE_APPEARANCE_CYCLING_CADENCE 0x0483 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_CADENCE in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_CYCLING_POWER 0x0484 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_POWER in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_STANDALONE_SPEAKER 0x0841 /*!< relate to BTM_BLE_APPEARANCE_STANDALONE_SPEAKER in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP in stack/btm_ble_api.h */
#define ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST in stack/btm_ble_api.h */

Wyświetl plik

@ -98,6 +98,12 @@ typedef struct {
uint8_t subclass; /*!< HID device subclass */
uint8_t *desc_list; /*!< HID descriptor list */
int desc_list_len; /*!< size in bytes of HID descriptor list */
// DID Profile SDP
uint16_t vendor_id; /*!< HID Vendor ID */
uint16_t product_id; /*!< HID Product ID */
uint16_t version; /*!< HID Product Version */
uint8_t vendor_id_source; /*!< HID Country Code */
} esp_hidd_app_param_t;
/**

Wyświetl plik

@ -175,6 +175,16 @@ void bta_hd_register_act(tBTA_HD_DATA *p_data)
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
// Set DID Profile SDP Record
tBTA_DI_RECORD bqb_device_info;
bqb_device_info.vendor = p_app_data->vendor_id;
bqb_device_info.vendor_id_source = p_app_data->vendor_id_source;
bqb_device_info.product = p_app_data->product_id;
bqb_device_info.version = p_app_data->version;
bqb_device_info.primary_record = TRUE;
BTA_DmSetLocalDiRecord(&bqb_device_info, &bta_hd_cb.sdp_handle);
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);

Wyświetl plik

@ -114,6 +114,13 @@ extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_
p_buf->subclass = p_app_info->subclass;
p_buf->d_len = p_app_info->descriptor.dl_len;
memcpy(p_buf->d_data, p_app_info->descriptor.dsc_list, p_app_info->descriptor.dl_len);
// copy DID profile SDP info
p_buf->vendor_id = p_app_info->vendor_id;
p_buf->product_id = p_app_info->product_id;
p_buf->version = p_app_info->version;
p_buf->vendor_id_source = p_app_info->vendor_id_source;
// copy qos data as-is
memcpy(&p_buf->in_qos, p_in_qos, sizeof(tBTA_HD_QOS_INFO));
memcpy(&p_buf->out_qos, p_out_qos, sizeof(tBTA_HD_QOS_INFO));

Wyświetl plik

@ -75,6 +75,13 @@ typedef struct {
uint8_t subclass;
uint16_t d_len;
uint8_t d_data[BTA_HD_APP_DESCRIPTOR_LEN];
// DID SDP Information (Device Information)
uint16_t vendor_id;
uint16_t product_id;
uint16_t version;
uint8_t vendor_id_source;
tBTA_HD_QOS_INFO in_qos;
tBTA_HD_QOS_INFO out_qos;
} tBTA_HD_REGISTER_APP;

Wyświetl plik

@ -276,7 +276,7 @@ static void bta_hh_di_sdp_cback(UINT16 result)
bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version, 0);
}
} else { /* no DI recrod available */
} else { /* no DI record available */
bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0);
}
@ -358,7 +358,7 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
return;
}
/* GetSDPRecord. at one time only one SDP precedure can be active */
/* GetSDPRecord. at one time only one SDP procedure can be active */
else if (!bta_hh_cb.p_disc_db) {
bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(p_bta_hh_cfg->sdp_db_size);
@ -429,6 +429,7 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
APPL_TRACE_DEBUG ("bta_hh_sdp_cmpl: HID_HostOpenDev failed: \
Status 0x%2X", ret);
#endif
conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle);
/* open fail, remove device from management device list */
HID_HostRemoveDev( p_cb->hid_handle);
status = BTA_HH_ERR;
@ -452,8 +453,6 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
HID_HostRemoveDev( p_cb->incoming_hid_handle);
}
conn_dat.status = status;
/* check if host initiate the connection*/
conn_dat.is_orig = !p_cb->incoming_conn;
(* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat);
/* move state machine W4_CONN ->IDLE */
@ -523,8 +522,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
memset((void *)&conn, 0, sizeof (tBTA_HH_CONN));
conn.handle = dev_handle;
/* check if host initiate the connection*/
conn.is_orig = !p_cb->incoming_conn;
conn.is_orig = HID_HostConnectOrig(dev_handle);
bdcpy(conn.bda, p_cb->addr);
/* increase connection number */
@ -596,7 +594,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
if (p_cb->app_id != 0) {
bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
} else
/* app_id == 0 indicates an incoming conenction request arrives without SDP
/* app_id == 0 indicates an incoming connection request arrives without SDP
performed, do it first */
{
/* store the handle here in case sdp fails - need to disconnect */
@ -637,7 +635,7 @@ void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
**
** Function bta_hh_handsk_act
**
** Description HID Host process a handshake acknoledgement.
** Description HID Host process a handshake acknowledgement.
**
**
** Returns void
@ -674,7 +672,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
p_cb->w4_evt = 0;
break;
/* acknoledgement from HID device for SET_ transaction */
/* acknowledgement from HID device for SET_ transaction */
case BTA_HH_SET_RPT_EVT:
case BTA_HH_SET_PROTO_EVT:
case BTA_HH_SET_IDLE_EVT :
@ -693,8 +691,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
case BTA_HH_OPEN_EVT:
conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK;
conn.handle = p_cb->hid_handle;
/* check if host initiate the connection*/
conn.is_orig = !p_cb->incoming_conn;
conn.is_orig = HID_HostConnectOrig(p_cb->hid_handle);
bdcpy(conn.bda, p_cb->addr);
(* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&conn);
#if BTA_HH_DEBUG
@ -704,12 +701,12 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
break;
default:
/* unknow transaction handshake response */
/* unknown transaction handshake response */
APPL_TRACE_DEBUG("unknown transaction type");
break;
}
/* transaction achknoledgement received, inform PM for mode change */
/* transaction acknowledgement received, inform PM for mode change */
bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr);
return;
}
@ -799,7 +796,7 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ?
BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
/* check if host initiate the connection*/
conn_dat.is_orig = !p_cb->incoming_conn;
conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle);
bdcpy(conn_dat.bda, p_cb->addr);
HID_HostCloseDev(p_cb->hid_handle);
@ -844,13 +841,13 @@ void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
/* Check reason for closing */
if ((reason & (HID_L2CAP_CONN_FAIL | HID_L2CAP_REQ_FAIL)) || /* Failure to initialize connection (page timeout or l2cap error) */
(reason == HID_ERR_AUTH_FAILED) || /* Authenication error (while initiating) */
(reason == HID_ERR_AUTH_FAILED) || /* Authentication error (while initiating) */
(reason == HID_ERR_L2CAP_FAILED)) { /* Failure creating l2cap connection */
/* Failure in opening connection */
conn_dat.handle = p_cb->hid_handle;
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
/* check if host initiate the connection*/
conn_dat.is_orig = !p_cb->incoming_conn;
conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle);
bdcpy(conn_dat.bda, p_cb->addr);
HID_HostCloseDev(p_cb->hid_handle);

Wyświetl plik

@ -293,7 +293,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data)
cback_data.conn.status = BTA_HH_ERR_DB_FULL;
cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
/* check if host initiate the connection*/
cback_data.conn.is_orig = !p_cb->incoming_conn;
cback_data.conn.is_orig = TRUE;
break;
/* DB full, BTA_HhAddDev */
case BTA_HH_API_MAINT_DEV_EVT:

Wyświetl plik

@ -69,6 +69,13 @@ typedef struct {
char *p_description;
char *p_provider;
uint8_t subclass;
// SDP Idenification info
uint16_t vendor_id; // 0x0201
uint16_t product_id; // 0x0202
uint16_t version; // 0x0203
uint8_t vendor_id_source; // 0x0205
tBTA_HD_DEV_DESCR descriptor;
} tBTA_HD_APP_INFO;

Wyświetl plik

@ -318,9 +318,19 @@ bt_status_t btc_hf_init(void)
BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients);
#if HFP_DYNAMIC_MEMORY == TRUE
if (hf_local_param == NULL) {
if ((hf_local_param = (hf_local_param_t *)osi_malloc(BTC_HF_NUM_CB * sizeof(hf_local_param_t))) == NULL) {
BTC_TRACE_ERROR("%s malloc failed!", __func__);
return BT_STATUS_NOMEM;
}
}
memset((void *)hf_local_param, 0, BTC_HF_NUM_CB * sizeof(hf_local_param_t));
#endif
/* Invoke the enable service API to the core to set the appropriate service_id
* Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
* othwerwise only HSP is enabled (tablet)*/
* otherwise only HSP is enabled (tablet)*/
#if (defined(BTC_HF_SERVICES) && (BTC_HF_SERVICES & BTA_HFP_SERVICE_MASK))
btc_dm_enable_service(BTA_HFP_SERVICE_ID);
#else
@ -747,7 +757,7 @@ static bt_status_t btc_hf_phone_state_update(bt_bdaddr_t *bd_addr,int num_active
}
/* CIND response should have been updated. */
BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
/* Just open SCO conenction. */
/* Just open SCO connection. */
BTA_AgAudioOpen(ag_res.audio_handle);
activeCallUpdated = TRUE;
}
@ -1560,7 +1570,7 @@ void btc_hf_cb_handler(btc_msg_t *msg)
CHECK_HF_IDX(idx);
BTC_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
#if (BTM_WBS_INCLUDED == TRUE)
/* If the peer supports mSBC and the BTC prefferred codec is also mSBC, then
/* If the peer supports mSBC and the BTC preferred codec is also mSBC, then
** we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time
** of SCO connection establishment */
if ((btc_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC)) {
@ -1596,7 +1606,7 @@ void btc_hf_cb_handler(btc_msg_t *msg)
BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
memcpy(param.bcs_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
param.bcs_rep.mode = p_data->val.num;
/* No ESP_HF_WBS_NONE case, becuase HFP 1.6 supported device can send BCS */
/* No ESP_HF_WBS_NONE case, because HFP 1.6 supported device can send BCS */
btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, &param);
} while (0);
break;

Wyświetl plik

@ -341,6 +341,13 @@ static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_
btc_hd_cb.out_qos.access_latency = p_out_qos->access_latency;
btc_hd_cb.out_qos.delay_variation = p_out_qos->delay_variation;
// Copy SDP record information for DID (Device Identification Profile)
btc_hd_cb.app_info.vendor_id = p_app_param->vendor_id;
btc_hd_cb.app_info.product_id = p_app_param->product_id;
btc_hd_cb.app_info.version = p_app_param->version;
btc_hd_cb.app_info.vendor_id_source = p_app_param->vendor_id_source;
BTA_HdRegisterApp(&btc_hd_cb.app_info, &btc_hd_cb.in_qos, &btc_hd_cb.out_qos);
} while(0);

Wyświetl plik

@ -189,7 +189,7 @@ static btc_hh_device_t *btc_hh_find_connected_dev_by_bda(BD_ADDR bd_addr)
*
* Function btc_hh_stop_vup_timer
*
* Description stop vitual unplug timer
* Description stop virtual unplug timer
*
* Returns void
******************************************************************************/
@ -316,7 +316,7 @@ void btc_hh_remove_device(BD_ADDR bd_addr)
for (i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
p_added_dev = &btc_hh_cb.added_devices[i];
if (p_added_dev->bd_addr == bd_addr) {
if (memcmp(p_added_dev->bd_addr, bd_addr, BD_ADDR_LEN) == 0) {
BTA_HhRemoveDev(p_added_dev->dev_handle);
btc_storage_remove_hid_info((bt_bdaddr_t *)p_added_dev->bd_addr);
memset(p_added_dev->bd_addr, 0, 6);
@ -544,6 +544,11 @@ static void btc_hh_connect(btc_hidh_args_t *arg)
BTC_TRACE_ERROR("%s exceeded the maximum supported HID device number %d!", __func__, BTC_HH_MAX_HID);
ret = ESP_HIDH_ERR_NO_RES;
break;
} else if (dev && dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED) {
BTC_TRACE_WARNING("%s Device[%s] already connected", __func__,
bdaddr_to_string((const bt_bdaddr_t *)arg->connect.bd_addr, bdstr, sizeof(bdstr)));
param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTED;
break;
}
for (int i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
@ -662,7 +667,7 @@ static void btc_hh_virtual_unplug(btc_hidh_args_t *arg)
param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTING;
param.unplug.handle = p_dev->dev_handle;
} else if ((p_dev != NULL) && (p_dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED)) {
BTC_TRACE_WARNING("%s: Virtual unplug not suported, disconnecting device", __func__);
BTC_TRACE_WARNING("%s: Virtual unplug not supported, disconnecting device", __func__);
/* start the timer */
btc_hh_start_vup_timer(arg->unplug.bd_addr);
p_dev->local_vup = true;

Wyświetl plik

@ -144,6 +144,10 @@ void hci_shut_down(void)
bool hci_downstream_data_post(uint32_t timeout)
{
if (hci_host_env.downstream_data_ready == NULL) {
HCI_TRACE_WARNING("%s downstream_data_ready event not created", __func__);
return false;
}
return osi_thread_post_event(hci_host_env.downstream_data_ready, timeout);
}
@ -263,7 +267,7 @@ static void transmit_command(
// in case the upper layer didn't already
command->event = MSG_STACK_TO_HC_HCI_CMD;
HCI_TRACE_DEBUG("HCI Enqueue Comamnd opcode=0x%x\n", metadata->opcode);
HCI_TRACE_DEBUG("HCI Enqueue Command opcode=0x%x\n", metadata->opcode);
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
fixed_pkt_queue_enqueue(hci_host_env.command_queue, linked_pkt, FIXED_PKT_QUEUE_MAX_TIMEOUT);

Wyświetl plik

@ -3291,6 +3291,7 @@ static void btm_ble_appearance_to_cod(UINT16 appearance, UINT8 *dev_class)
case BTM_BLE_APPEARANCE_CYCLING_CADENCE:
case BTM_BLE_APPEARANCE_CYCLING_POWER:
case BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE:
case BTM_BLE_APPEARANCE_STANDALONE_SPEAKER:
case BTM_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS:
case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION:
case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV:

Wyświetl plik

@ -379,6 +379,7 @@ tHID_STATUS HID_HostAddDev ( BD_ADDR addr, UINT16 attr_mask, UINT8 *handle )
if (!hh_cb.devices[i].in_use) {
hh_cb.devices[i].in_use = TRUE;
hh_cb.devices[i].delay_remove = FALSE;
hh_cb.devices[i].is_orig = FALSE;
memcpy( hh_cb.devices[i].addr, addr, sizeof( BD_ADDR ) ) ;
hh_cb.devices[i].state = HID_DEV_NO_CONN;
hh_cb.devices[i].conn_tries = 0 ;
@ -486,6 +487,7 @@ tHID_STATUS HID_HostOpenDev ( UINT8 dev_handle )
}
hh_cb.devices[dev_handle].conn_tries = 1;
hh_cb.devices[dev_handle].is_orig = TRUE;
return hidh_conn_initiate( dev_handle );
}
@ -651,4 +653,23 @@ BOOLEAN hid_known_hid_device (BD_ADDR bd_addr)
return FALSE;
}
BOOLEAN HID_HostConnectOrig(UINT8 dev_handle)
{
BOOLEAN ret = FALSE;
do {
if (!hh_cb.reg_flag) {
break;
}
if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) {
break;
}
ret = hh_cb.devices[dev_handle].is_orig;
} while (0);
return ret;
}
#endif //HID_HOST_INCLUDED

Wyświetl plik

@ -35,11 +35,11 @@ enum { HID_DEV_NO_CONN, HID_DEV_CONNECTED };
typedef struct per_device_ctb {
BOOLEAN in_use;
BOOLEAN delay_remove;
BOOLEAN is_orig;
BD_ADDR addr; /* BD-Addr of the host device */
UINT16 attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03- reconn_initiate;
0x04- sdp_disable; */
UINT8 state; /* Device state if in HOST-KNOWN mode */
UINT8 conn_substate;
UINT8 conn_tries; /* Remembers to the number of connection attempts while CONNECTING */
tHID_CONN conn; /* L2CAP channel info */

Wyświetl plik

@ -254,6 +254,7 @@ typedef UINT8 BLE_SIGNATURE[BTM_BLE_AUTH_SIGN_LEN]; /* Device address */
#define BTM_BLE_APPEARANCE_CYCLING_CADENCE 0x0483
#define BTM_BLE_APPEARANCE_CYCLING_POWER 0x0484
#define BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485
#define BTM_BLE_APPEARANCE_STANDALONE_SPEAKER 0x0841
#define BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40
#define BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41
#define BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42

Wyświetl plik

@ -249,6 +249,17 @@ BOOLEAN hid_known_hid_device (BD_ADDR bd_addr);
*******************************************************************************/
extern UINT8 HID_HostSetTraceLevel (UINT8 new_level);
/*******************************************************************************
**
** Function HID_HostConnectOrig
**
** Description Check if the HID Host initiates the connection
**
** Returns TRUE if the HID Host initiates the connection else FALSE
**
*******************************************************************************/
extern BOOLEAN HID_HostConnectOrig(UINT8 dev_handle);
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit acbe4fe3219cb7ce677be1aa2c4142f308ea4958
Subproject commit a2acac3e14bb7810783ac5089ccf8229a2dd2f70

Wyświetl plik

@ -1,57 +0,0 @@
[sections:bt_bss]
entries:
.bss+
[sections:bt_common]
entries:
COMMON
[scheme:bt_start_end]
entries:
bt_bss -> dram0_bss
bt_common -> dram0_bss
data -> dram0_data
# For the following fragments, order matters for
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
#
# . = ALIGN(4)
# _sym_start
# ...
# . = ALIGN(4)
# _sym_end
[mapping:bt]
archive: libbt.a
entries:
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (extram_bss)
else:
* (bt_start_end);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
[mapping:btdm]
archive: libbtdm_app.a
entries:
* (bt_start_end);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data)
[mapping:bt_controller]
archive: libble_app.a
entries:
* (bt_start_end);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
[mapping:nimble]
archive: libnimble.a
entries:
* (bt_start_end);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(nimble_data)

Wyświetl plik

@ -0,0 +1,42 @@
[sections:bt_bss]
entries:
.bss+
[sections:bt_common]
entries:
COMMON
[scheme:bt_default]
entries:
bt_bss -> dram0_bss
bt_common -> dram0_bss
data -> dram0_data
[scheme:bt_extram_bss]
entries:
bt_bss -> extern_ram
bt_common -> extern_ram
data -> dram0_data
# For the following fragments, order matters for
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
#
# . = ALIGN(4)
# _sym_start
# ...
# . = ALIGN(4)
# _sym_end
[mapping:bt]
archive: libbt.a
entries:
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (bt_extram_bss);
bt_bss -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
else:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)

Wyświetl plik

@ -1,4 +1,4 @@
[sections:bt_text]
[sections:bt_iram_text]
entries:
.iram1+
@ -17,9 +17,9 @@ entries:
entries:
COMMON
[scheme:bt_start_end]
[scheme:bt_default]
entries:
bt_text -> iram0_bt_text
bt_iram_text -> iram0_bt_text
bt_bss -> dram0_bt_bss
bt_common -> dram0_bt_bss
bt_data -> dram0_bt_data
@ -36,25 +36,15 @@ entries:
[mapping:bt]
archive: libbt.a
entries:
* (bt_start_end);
* (bt_default);
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (extram_bss)
[mapping:btdm]
archive: libbtdm_app.a
entries:
* (bt_start_end);
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss),
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common),
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data)
[mapping:bt_controller]
[mapping:ble_app]
archive: libble_app.a
entries:
* (bt_start_end);
* (bt_default);
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)

Wyświetl plik

@ -0,0 +1,7 @@
[mapping:ble_app]
archive: libble_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)

Wyświetl plik

@ -0,0 +1,7 @@
[mapping:btdm]
archive: libbtdm_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)

Wyświetl plik

@ -1,8 +1,17 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/bt/test_apps:
components/bt/test_apps/basic_unit_test:
disable:
- if: IDF_TARGET not in ["esp32", "esp32c3"]
reason: Sufficient to run the tests on one chip of each architecture
depends_components:
- bt
components/bt/test_apps/memory_release:
disable:
- if: IDF_TARGET not in ["esp32", "esp32c2"]
- if: CONFIG_NAME == "iram" and IDF_TARGET != "esp32c2"
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
reason: Sufficient to run the tests on one chip of each architecture
depends_components:
- bt

Wyświetl plik

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut

Wyświetl plik

@ -1,3 +1,2 @@
CONFIG_BT_ENABLED=y
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n

Wyświetl plik

@ -0,0 +1,5 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_bt_memory_release)

Wyświetl plik

@ -0,0 +1,4 @@
| Supported Targets | ESP32 | ESP32-C2 |
| ----------------- | ----- | -------- |
This test app is used to test esp_bt_memory_release function

Wyświetl plik

@ -0,0 +1,3 @@
idf_component_register(SRCS "test_app_main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES bt nvs_flash)

Wyświetl plik

@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include "esp_log.h"
#include "nvs_flash.h"
#include "multi_heap.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_bt.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "host/util/util.h"
#include "services/gap/ble_svc_gap.h"
#define FAIL() do { printf("FAILURE\n"); return; } while(0)
extern uint8_t _bt_bss_start;
extern uint8_t _bt_bss_end;
extern uint8_t _bt_controller_bss_start;
extern uint8_t _bt_controller_bss_end;
extern void ble_store_config_init(void);
static const char *tag = "MEM_RELEASE_APP";
static void nimble_host_on_reset(int reason)
{
ESP_LOGI(tag, "Resetting state; reason=%d", reason);
}
static void nimble_host_on_sync(void)
{
ESP_LOGI(tag, "NimBLE host synchronized");
}
static void nimble_host_task_fn(void *param)
{
ESP_LOGI(tag, "BLE Host Task Started");
/* This function will return only when nimble_port_stop() is executed */
nimble_port_run();
nimble_port_freertos_deinit();
}
static void bt_stack_init(void)
{
esp_err_t ret = nimble_port_init();
ESP_ERROR_CHECK(ret);
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = nimble_host_on_reset;
ble_hs_cfg.sync_cb = nimble_host_on_sync;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
/* Set the default device name. */
int rc = ble_svc_gap_device_name_set(tag);
assert(rc == 0);
/* XXX Need to have template for store */
ble_store_config_init();
nimble_port_freertos_init(nimble_host_task_fn);
}
static void bt_stack_deinit(void)
{
int rc = nimble_port_stop();
assert(rc == 0);
nimble_port_deinit();
ESP_LOGI(tag, "BLE Host Task Stopped");
}
void app_main(void)
{
esp_err_t ret = ESP_OK;
/* Initialize NVS — it is used to store PHY calibration data */
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
/* initialize and then deinitialize bluetooth stack */
bt_stack_init();
vTaskDelay(pdMS_TO_TICKS(200));
bt_stack_deinit();
/* Get the size of heap located in external RAM */
const uint32_t free_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
ESP_LOGI(tag, "Free size in external RAM heap: %"PRIu32, free_before);
/* Make sure at least one of the Bluetooth BSS section that can be used as a heap */
const uint32_t heap_size = sizeof(multi_heap_info_t);
const uint32_t bt_bss_size = &_bt_bss_end - &_bt_bss_start;
const uint32_t bt_ctrl_bss_size = &_bt_controller_bss_end - &_bt_controller_bss_start;
ESP_LOGI(tag, "bt_bss_size %"PRIu32", bt_ctrl_bss_size %"PRIu32, bt_bss_size, bt_ctrl_bss_size);
if (bt_bss_size < heap_size && bt_ctrl_bss_size < heap_size)
{
ESP_LOGW(tag, "Bluetooth BSS sections are too small!");
FAIL();
}
/* Release the BSS sections to use them as heap */
ret = esp_bt_mem_release(ESP_BT_MODE_BTDM);
ESP_ERROR_CHECK(ret);
/* Check that we have more available memory in the external RAM heap */
const uint32_t free_after = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
ESP_LOGI(tag, "Free size in external RAM after releasing: %"PRIu32, free_after);
if (free_after <= free_before) {
FAIL();
}
ESP_LOGI(tag, "Free heap size increased by %"PRIu32" bytes", free_after - free_before);
ESP_LOGI(tag, "SUCCESS");
}

Wyświetl plik

@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@pytest.mark.parametrize('config', [
pytest.param('default', marks=[pytest.mark.esp32, pytest.mark.esp32c2, pytest.mark.generic]),
pytest.param('iram', marks=[pytest.mark.esp32c2, pytest.mark.generic]),
pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.psram]),
], indirect=True)
def test_bt_memory_release(dut: Dut) -> None:
dut.expect_exact('BLE Host Task Started', timeout=6)
dut.expect_exact('BLE Host Task Stopped', timeout=8)
dut.expect_exact('SUCCESS', timeout=10)

Wyświetl plik

@ -0,0 +1,2 @@
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n
CONFIG_BT_RELEASE_IRAM=y

Wyświetl plik

@ -0,0 +1,2 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y

Wyświetl plik

@ -0,0 +1,2 @@
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -34,19 +34,23 @@ typedef struct gpio_etm_event_t gpio_etm_event_t;
typedef struct gpio_etm_group_t {
portMUX_TYPE spinlock;
gpio_etm_dev_t *dev;
gpio_etm_task_t *tasks[SOC_GPIO_ETM_TASKS_PER_GROUP];
gpio_etm_event_t *events[SOC_GPIO_ETM_EVENTS_PER_GROUP];
uint8_t tasks[GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP]; // Array of the acquired action masks in each GPIO ETM task channel
uint8_t events[GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP]; // Array of the acquired event masks in each GPIO ETM event channel
uint8_t actions[SOC_GPIO_PIN_COUNT]; // Array of the masks of the added actions to each GPIO
uint8_t edges[GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP]; // Array of the masks of the bound event edges in each GPIO ETM event channel
} gpio_etm_group_t;
struct gpio_etm_event_t {
esp_etm_event_t base;
int chan_id;
gpio_etm_event_edge_t edge_id;
gpio_etm_group_t *group;
};
struct gpio_etm_task_t {
esp_etm_task_t base;
int chan_id;
gpio_etm_task_action_t action_id;
gpio_etm_group_t *group;
size_t num_of_gpios; // record the number of GPIOs that are bound to the etm task
};
@ -56,81 +60,65 @@ static gpio_etm_group_t s_gpio_etm_group = {
.spinlock = portMUX_INITIALIZER_UNLOCKED,
};
static esp_err_t gpio_etm_event_register_to_group(gpio_etm_event_t *event)
static esp_err_t gpio_etm_acquire_event_channel(uint8_t event_mask, int *chan_id)
{
assert(chan_id);
gpio_etm_group_t *group = &s_gpio_etm_group;
int chan_id = -1;
// loop to search free one in the group
int free_chan_id = -1;
// loop to search free event channel in the group
portENTER_CRITICAL(&group->spinlock);
for (int j = 0; j < SOC_GPIO_ETM_EVENTS_PER_GROUP; j++) {
for (int j = 0; j < GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP; j++) {
if (!group->events[j]) {
chan_id = j;
group->events[j] = event;
free_chan_id = j;
group->events[j] = event_mask;
break;
}
}
portEXIT_CRITICAL(&group->spinlock);
ESP_RETURN_ON_FALSE(chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free event channel");
event->group = group;
event->chan_id = chan_id;
ESP_RETURN_ON_FALSE(free_chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free event channel");
*chan_id = free_chan_id;
return ESP_OK;
}
static esp_err_t gpio_etm_task_register_to_group(gpio_etm_task_t *task)
static esp_err_t gpio_etm_release_event_channel(int chan_id, uint8_t event_mask)
{
gpio_etm_group_t *group = &s_gpio_etm_group;
int chan_id = -1;
// loop to search free one in the group
portENTER_CRITICAL(&group->spinlock);
for (int j = 0; j < SOC_GPIO_ETM_TASKS_PER_GROUP; j++) {
group->events[chan_id] &= ~event_mask;
portEXIT_CRITICAL(&group->spinlock);
return ESP_OK;
}
static esp_err_t gpio_etm_acquire_task_channel(uint8_t task_mask, int *chan_id)
{
assert(chan_id);
gpio_etm_group_t *group = &s_gpio_etm_group;
int free_chan_id = -1;
// loop to search free task channel in the group
portENTER_CRITICAL(&group->spinlock);
for (int j = 0; j < GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP; j++) {
if (!group->tasks[j]) {
chan_id = j;
group->tasks[j] = task;
free_chan_id = j;
group->tasks[j] = task_mask;
break;
}
}
portEXIT_CRITICAL(&group->spinlock);
ESP_RETURN_ON_FALSE(chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free task channel");
task->group = group;
task->chan_id = chan_id;
ESP_RETURN_ON_FALSE(free_chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free task channel");
*chan_id = free_chan_id;
return ESP_OK;
}
static void gpio_etm_event_unregister_from_group(gpio_etm_event_t *event)
static esp_err_t gpio_etm_release_task_channel(int chan_id, uint8_t task_mask)
{
gpio_etm_group_t *group = event->group;
int chan_id = event->chan_id;
gpio_etm_group_t *group = &s_gpio_etm_group;
portENTER_CRITICAL(&group->spinlock);
group->events[chan_id] = NULL;
group->tasks[chan_id] &= ~task_mask;
portEXIT_CRITICAL(&group->spinlock);
}
static void gpio_etm_task_unregister_from_group(gpio_etm_task_t *task)
{
gpio_etm_group_t *group = task->group;
int chan_id = task->chan_id;
portENTER_CRITICAL(&group->spinlock);
group->tasks[chan_id] = NULL;
portEXIT_CRITICAL(&group->spinlock);
}
static esp_err_t gpio_etm_event_destroy(gpio_etm_event_t *event)
{
if (event->group) {
gpio_etm_event_unregister_from_group(event);
}
free(event);
return ESP_OK;
}
static esp_err_t gpio_etm_task_destroy(gpio_etm_task_t *task)
{
if (task->group) {
gpio_etm_task_unregister_from_group(task);
}
free(task);
return ESP_OK;
}
@ -138,9 +126,16 @@ static esp_err_t gpio_del_etm_event(esp_etm_event_t *event)
{
gpio_etm_event_t *gpio_event = __containerof(event, gpio_etm_event_t, base);
gpio_etm_group_t *group = gpio_event->group;
// disable event channel
gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false);
gpio_etm_event_destroy(gpio_event);
// unbind it from the GPIO and check if the GPIO ETM event channel can be disabled
portENTER_CRITICAL(&group->spinlock);
group->edges[gpio_event->chan_id] &= ~(1 << gpio_event->edge_id);
if (!group->edges[gpio_event->chan_id]) {
gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false);
}
portEXIT_CRITICAL(&group->spinlock);
gpio_etm_release_event_channel(gpio_event->chan_id, 1 << gpio_event->edge_id);
free(gpio_event);
return ESP_OK;
}
@ -149,95 +144,192 @@ static esp_err_t gpio_del_etm_task(esp_etm_task_t *task)
gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base);
// make sure user has called `gpio_etm_task_rm_gpio` to clean the etm task channel
ESP_RETURN_ON_FALSE(gpio_task->num_of_gpios == 0, ESP_ERR_INVALID_STATE, TAG, "some GPIO till bounded to the etm task");
gpio_etm_task_destroy(gpio_task);
gpio_etm_release_task_channel(gpio_task->chan_id, 1 << gpio_task->action_id);
free(gpio_task);
return ESP_OK;
}
esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event)
esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event, ...)
{
#if CONFIG_ETM_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK;
gpio_etm_event_t *event = NULL;
ESP_GOTO_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
int chan_id = -1;
uint8_t event_mask = 0;
esp_etm_event_handle_t *ret_event_itor = ret_event;
va_list args;
ESP_RETURN_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
for (int i = 0; i < GPIO_ETM_EVENT_EDGE_TYPES; i++) {
if (config->edges[i]) {
uint8_t msk = (1 << config->edges[i]);
ESP_RETURN_ON_FALSE(!(msk & event_mask), ESP_ERR_INVALID_ARG, TAG, "no identical edge event allowed in one call");
event_mask |= msk;
}
}
ESP_RETURN_ON_FALSE(event_mask, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
uint32_t event_num = __builtin_popcount(event_mask);
gpio_etm_event_t *events[event_num];
event = heap_caps_calloc(1, sizeof(gpio_etm_event_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no mem for event channel");
// register the event channel to the group
ESP_GOTO_ON_ERROR(gpio_etm_event_register_to_group(event), err, TAG, "register event channel to group failed");
int chan_id = event->chan_id;
uint32_t event_id = 0;
switch (config->edge) {
case GPIO_ETM_EVENT_EDGE_ANY:
event_id = GPIO_LL_ETM_EVENT_ID_ANY_EDGE(chan_id);
break;
case GPIO_ETM_EVENT_EDGE_POS:
event_id = GPIO_LL_ETM_EVENT_ID_POS_EDGE(chan_id);
break;
case GPIO_ETM_EVENT_EDGE_NEG:
event_id = GPIO_LL_ETM_EVENT_ID_NEG_EDGE(chan_id);
break;
default:
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid edge");
for (int i = 0; i < event_num; i++) {
events[i] = (gpio_etm_event_t *)heap_caps_calloc(1, sizeof(gpio_etm_event_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(events[i], ESP_ERR_NO_MEM, err, TAG, "no mem for event channel(s)");
}
event->base.del = gpio_del_etm_event;
event->base.event_id = event_id;
event->base.trig_periph = ETM_TRIG_PERIPH_GPIO;
ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", chan_id=%d", event, event_id, chan_id);
*ret_event = &event->base;
// register the event channel to the group
ESP_GOTO_ON_ERROR(gpio_etm_acquire_event_channel(event_mask, &chan_id), err, TAG, "register event channel to group failed");
bool no_avail_ret_arg = false;
va_start(args, ret_event);
for (int i = 0, j = 0; i < event_num; i++, j++) {
if (!ret_event_itor) {
no_avail_ret_arg = true;
break;
}
// assign to the ret_event handles in the configuration order
gpio_etm_event_edge_t event_edge;
do {
event_edge = config->edges[j];
} while (!event_edge && ++j);
uint32_t event_id = 0;
switch (event_edge) {
case GPIO_ETM_EVENT_EDGE_ANY:
event_id = GPIO_LL_ETM_EVENT_ID_ANY_EDGE(chan_id);
break;
case GPIO_ETM_EVENT_EDGE_POS:
event_id = GPIO_LL_ETM_EVENT_ID_POS_EDGE(chan_id);
break;
case GPIO_ETM_EVENT_EDGE_NEG:
event_id = GPIO_LL_ETM_EVENT_ID_NEG_EDGE(chan_id);
break;
default:
va_end(args);
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid edge");
}
gpio_etm_event_t *event = events[i];
event->base.del = gpio_del_etm_event;
event->base.event_id = event_id;
event->base.trig_periph = ETM_TRIG_PERIPH_GPIO;
event->group = &s_gpio_etm_group;
event->chan_id = chan_id;
event->edge_id = event_edge;
ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", chan_id=%d", event, event_id, chan_id);
*ret_event_itor = &event->base;
ret_event_itor = va_arg(args, esp_etm_event_handle_t *);
}
va_end(args);
ESP_GOTO_ON_FALSE(!no_avail_ret_arg, ESP_ERR_INVALID_ARG, err, TAG, "mismatch number of events with number of pointers to store event handles");
return ESP_OK;
err:
if (event) {
gpio_etm_event_destroy(event);
if (chan_id != -1) {
gpio_etm_release_event_channel(chan_id, event_mask);
}
for (int i = 0; i < event_num; i++) {
if (events[i]) {
free(events[i]);
}
}
ret_event_itor = ret_event;
va_start(args, ret_event);
while (ret_event_itor) {
*ret_event_itor = NULL;
ret_event_itor = va_arg(args, esp_etm_event_handle_t *);
}
va_end(args);
return ret;
}
esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task)
esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task, ...)
{
#if CONFIG_ETM_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK;
gpio_etm_task_t *task = NULL;
ESP_GOTO_ON_FALSE(config && ret_task, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
int chan_id = -1;
uint8_t task_mask = 0;
esp_etm_task_handle_t *ret_task_itor = ret_task;
va_list args;
ESP_RETURN_ON_FALSE(config && ret_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
for (int i = 0; i < GPIO_ETM_TASK_ACTION_TYPES; i++) {
if (config->actions[i]) {
uint8_t msk = (1 << config->actions[i]);
ESP_RETURN_ON_FALSE(!(msk & task_mask), ESP_ERR_INVALID_ARG, TAG, "no identical action allowed in one call");
task_mask |= msk;
}
}
ESP_RETURN_ON_FALSE(task_mask, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
uint32_t task_num = __builtin_popcount(task_mask);
gpio_etm_task_t *tasks[task_num];
task = heap_caps_calloc(1, sizeof(gpio_etm_task_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(task, ESP_ERR_NO_MEM, err, TAG, "no mem for task channel");
// register the task channel to the group
ESP_GOTO_ON_ERROR(gpio_etm_task_register_to_group(task), err, TAG, "register task channel to group failed");
int chan_id = task->chan_id;
uint32_t task_id = 0;
switch (config->action) {
case GPIO_ETM_TASK_ACTION_SET:
task_id = GPIO_LL_ETM_TASK_ID_SET(chan_id);
break;
case GPIO_ETM_TASK_ACTION_CLR:
task_id = GPIO_LL_ETM_TASK_ID_CLR(chan_id);
break;
case GPIO_ETM_TASK_ACTION_TOG:
task_id = GPIO_LL_ETM_TASK_ID_TOG(chan_id);
break;
default:
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid action");
for (int i = 0; i < task_num; i++) {
tasks[i] = (gpio_etm_task_t *)heap_caps_calloc(1, sizeof(gpio_etm_task_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(tasks[i], ESP_ERR_NO_MEM, err, TAG, "no mem for task channel(s)");
}
task->base.del = gpio_del_etm_task;
task->base.task_id = task_id;
task->base.trig_periph = ETM_TRIG_PERIPH_GPIO;
ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32", chan_id=%d", task, task_id, chan_id);
*ret_task = &task->base;
// register the task channel to the group
ESP_GOTO_ON_ERROR(gpio_etm_acquire_task_channel(task_mask, &chan_id), err, TAG, "register task channel to group failed");
bool no_avail_ret_arg = false;
va_start(args, ret_task);
for (int i = 0, j = 0; i < task_num; i++, j++) {
if (!ret_task_itor) {
no_avail_ret_arg = true;
break;
}
// assign to the ret_task handles in the configuration order
gpio_etm_task_action_t action;
do {
action = config->actions[i];
} while (!action && ++j);
uint32_t task_id = 0;
switch (action) {
case GPIO_ETM_TASK_ACTION_SET:
task_id = GPIO_LL_ETM_TASK_ID_SET(chan_id);
break;
case GPIO_ETM_TASK_ACTION_CLR:
task_id = GPIO_LL_ETM_TASK_ID_CLR(chan_id);
break;
case GPIO_ETM_TASK_ACTION_TOG:
task_id = GPIO_LL_ETM_TASK_ID_TOG(chan_id);
break;
default:
va_end(args);
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid action");
}
gpio_etm_task_t *task = tasks[i];
task->base.del = gpio_del_etm_task;
task->base.task_id = task_id;
task->base.trig_periph = ETM_TRIG_PERIPH_GPIO;
task->group = &s_gpio_etm_group;
task->chan_id = chan_id;
task->action_id = action;
ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32", gpio_etm_task_chan_id=%d", task, task_id, chan_id);
*ret_task_itor = &task->base;
ret_task_itor = va_arg(args, esp_etm_task_handle_t *);
}
va_end(args);
ESP_GOTO_ON_FALSE(!no_avail_ret_arg, ESP_ERR_INVALID_ARG, err, TAG, "mismatch number of tasks with number of pointers to store task handles");
return ESP_OK;
err:
if (task) {
gpio_etm_task_destroy(task);
if (chan_id != -1) {
gpio_etm_release_task_channel(chan_id, task_mask);
}
for (int i = 0; i < task_num; i++) {
if (tasks[i]) {
free(tasks[i]);
}
}
ret_task_itor = ret_task;
va_start(args, ret_task);
while (ret_task_itor) {
*ret_task_itor = NULL;
ret_task_itor = va_arg(args, esp_etm_task_handle_t *);
}
va_end(args);
return ret;
}
@ -248,12 +340,27 @@ esp_err_t gpio_etm_event_bind_gpio(esp_etm_event_handle_t event, int gpio_num)
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not input capable");
gpio_etm_event_t *gpio_event = __containerof(event, gpio_etm_event_t, base);
gpio_etm_group_t *group = gpio_event->group;
// disable gpio etm event channel first
gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false);
// then set the gpio number
gpio_ll_etm_event_channel_set_gpio(group->dev, gpio_event->chan_id, gpio_num);
// enable gpio etm event channel again
gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, true);
bool allowed = true;
portENTER_CRITICAL(&group->spinlock);
// check if the GPIO ETM event channel where the new event belongs to has previously been bound to another GPIO
// one GPIO ETM event channel can only be bound to one GPIO
if (group->edges[gpio_event->chan_id]) {
if (gpio_ll_etm_event_channel_get_gpio(group->dev, gpio_event->chan_id) != gpio_num) {
allowed = false;
}
} else {
// set the GPIO number
gpio_ll_etm_event_channel_set_gpio(group->dev, gpio_event->chan_id, gpio_num);
// enable GPIO ETM event channel
gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, true);
}
if (allowed) {
group->edges[gpio_event->chan_id] |= (1 << gpio_event->edge_id);
}
portEXIT_CRITICAL(&group->spinlock);
ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the GPIO ETM event channel where the event belongs to has already been bound to another GPIO");
return ESP_OK;
}
@ -264,19 +371,28 @@ esp_err_t gpio_etm_task_add_gpio(esp_etm_task_handle_t task, int gpio_num)
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not output capable");
gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base);
gpio_etm_group_t *group = gpio_task->group;
bool gpio_not_enabled = true;
bool allowed = true;
// use spinlock as this function may be called with different task object in different threads
// and the gpio_num might reside in the same register
portENTER_CRITICAL(&group->spinlock);
// check if the gpio has been enabled
if (!gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num)) {
// check if the new task is compatible with the tasks that has previously been added to the GPIO
// the tasks have to be from the same GPIO ETM task channel
if (group->actions[gpio_num]) {
if (gpio_ll_etm_gpio_get_task_channel(group->dev, gpio_num) != gpio_task->chan_id) {
allowed = false;
}
} else {
// first action added to the GPIO
gpio_ll_etm_gpio_set_task_channel(group->dev, gpio_num, gpio_task->chan_id);
gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, true);
} else {
gpio_not_enabled = false;
}
if (allowed) {
group->actions[gpio_num] |= (1 << gpio_task->action_id);
}
portEXIT_CRITICAL(&group->spinlock);
ESP_RETURN_ON_FALSE(gpio_not_enabled, ESP_ERR_INVALID_STATE, TAG, "gpio already enabled by other task channel");
ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the task does not belong to the GPIO ETM task channel that the GPIO has already binded to");
gpio_task->num_of_gpios++;
return ESP_OK;
}
@ -287,19 +403,24 @@ esp_err_t gpio_etm_task_rm_gpio(esp_etm_task_handle_t task, int gpio_num)
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not output capable");
gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base);
gpio_etm_group_t *group = gpio_task->group;
bool gpio_enabled_by_this_task = true;
bool allowed = true;
// use spinlock as this function may be called with different task object in different threads
// and the gpio_num might reside in the same register
portENTER_CRITICAL(&group->spinlock);
// check if the gpio is managed by this etm task channel
if (gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num) &&
if ((group->actions[gpio_num] & (1 << gpio_task->action_id)) &&
gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num) &&
(gpio_ll_etm_gpio_get_task_channel(group->dev, gpio_num) == gpio_task->chan_id)) {
gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, false);
group->actions[gpio_num] &= ~(1 << gpio_task->action_id);
if (!group->actions[gpio_num]) {
// all actions removed from the GPIO
gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, false);
}
} else {
gpio_enabled_by_this_task = false;
allowed = false;
}
portEXIT_CRITICAL(&group->spinlock);
ESP_RETURN_ON_FALSE(gpio_enabled_by_this_task, ESP_ERR_INVALID_STATE, TAG, "gpio is not enabled by this task channel");
ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the task was not added to the GPIO");
gpio_task->num_of_gpios--;
return ESP_OK;
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,20 +13,29 @@
extern "C" {
#endif
#define GPIO_ETM_EVENT_EDGE_TYPES 3 /*!< GPIO ETM edge events are POS/NEG/ANY */
#define GPIO_ETM_TASK_ACTION_TYPES 3 /*!< GPIO ETM action tasks are SET/CLEAR/TOGGLE */
/**
* @brief GPIO edges that can be used as ETM event
*/
typedef enum {
GPIO_ETM_EVENT_EDGE_POS, /*!< A rising edge on the GPIO will generate an ETM event signal */
GPIO_ETM_EVENT_EDGE_NEG, /*!< A falling edge on the GPIO will generate an ETM event signal */
GPIO_ETM_EVENT_EDGE_ANY, /*!< Any edge on the GPIO can generate an ETM event signal */
GPIO_ETM_EVENT_EDGE_POS = 1, /*!< A rising edge on the GPIO will generate an ETM event signal */
GPIO_ETM_EVENT_EDGE_NEG, /*!< A falling edge on the GPIO will generate an ETM event signal */
GPIO_ETM_EVENT_EDGE_ANY, /*!< Any edge on the GPIO can generate an ETM event signal */
} gpio_etm_event_edge_t;
/**
* @brief GPIO ETM event configuration
*
* If more than one kind of ETM edge event want to be triggered on the same GPIO pin, you can configure them together.
* It helps to save GPIO ETM event channel resources for other GPIOs.
*/
typedef struct {
gpio_etm_event_edge_t edge; /*!< Which kind of edge can trigger the ETM event module */
union {
gpio_etm_event_edge_t edge; /*!< Which kind of edge can trigger the ETM event module */
gpio_etm_event_edge_t edges[GPIO_ETM_EVENT_EDGE_TYPES]; /*!< Array of kinds of edges to trigger the ETM event module on the same GPIO */
};
} gpio_etm_event_config_t;
/**
@ -34,9 +43,11 @@ typedef struct {
*
* @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
* @note The newly created ETM event object is not bind to any GPIO, you need to call `gpio_etm_event_bind_gpio` to bind the wanted GPIO
* @note Every success call to this function will acquire a free GPIO ETM event channel
*
* @param[in] config GPIO ETM event configuration
* @param[out] ret_event Returned ETM event handle
* @param[out] ... Other returned ETM event handles if any (the order of the returned event handles is aligned with the array order in field `edges` in `gpio_etm_event_config_t`)
* @return
* - ESP_OK: Create ETM event successfully
* - ESP_ERR_INVALID_ARG: Create ETM event failed because of invalid argument
@ -44,7 +55,7 @@ typedef struct {
* - ESP_ERR_NOT_FOUND: Create ETM event failed because all events are used up and no more free one
* - ESP_FAIL: Create ETM event failed because of other reasons
*/
esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event);
esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event, ...);
/**
* @brief Bind the GPIO with the ETM event
@ -65,16 +76,21 @@ esp_err_t gpio_etm_event_bind_gpio(esp_etm_event_handle_t event, int gpio_num);
* @brief GPIO actions that can be taken by the ETM task
*/
typedef enum {
GPIO_ETM_TASK_ACTION_SET, /*!< Set the GPIO level to high */
GPIO_ETM_TASK_ACTION_CLR, /*!< Clear the GPIO level to low */
GPIO_ETM_TASK_ACTION_TOG, /*!< Toggle the GPIO level */
GPIO_ETM_TASK_ACTION_SET = 1, /*!< Set the GPIO level to high */
GPIO_ETM_TASK_ACTION_CLR, /*!< Clear the GPIO level to low */
GPIO_ETM_TASK_ACTION_TOG, /*!< Toggle the GPIO level */
} gpio_etm_task_action_t;
/**
* @brief GPIO ETM task configuration
*
* If multiple actions wants to be added to the same GPIO pin, you have to configure all the GPIO ETM tasks together.
*/
typedef struct {
gpio_etm_task_action_t action; /*!< Which action to take by the ETM task module */
union {
gpio_etm_task_action_t action; /*!< Action to take by the ETM task module */
gpio_etm_task_action_t actions[GPIO_ETM_TASK_ACTION_TYPES]; /*!< Array of actions to take by the ETM task module on the same GPIO */
};
} gpio_etm_task_config_t;
/**
@ -83,9 +99,11 @@ typedef struct {
* @note The created ETM task object can be deleted later by calling `esp_etm_del_task`
* @note The GPIO ETM task works like a container, a newly created ETM task object doesn't have GPIO members to be managed.
* You need to call `gpio_etm_task_add_gpio` to put one or more GPIOs to the container.
* @note Every success call to this function will acquire a free GPIO ETM task channel
*
* @param[in] config GPIO ETM task configuration
* @param[out] ret_task Returned ETM task handle
* @param[out] ... Other returned ETM task handles if any (the order of the returned task handles is aligned with the array order in field `actions` in `gpio_etm_task_config_t`)
* @return
* - ESP_OK: Create ETM task successfully
* - ESP_ERR_INVALID_ARG: Create ETM task failed because of invalid argument
@ -93,7 +111,7 @@ typedef struct {
* - ESP_ERR_NOT_FOUND: Create ETM task failed because all tasks are used up and no more free one
* - ESP_FAIL: Create ETM task failed because of other reasons
*/
esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task);
esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task, ...);
/**
* @brief Add GPIO to the ETM task.

Wyświetl plik

@ -1488,7 +1488,7 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
// Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
esp_err_t ret = ESP_FAIL;
i2c_obj_t *p_i2c = p_i2c_obj[i2c_num];
TickType_t ticks_start = xTaskGetTickCount();
const TickType_t ticks_start = xTaskGetTickCount();
BaseType_t res = xSemaphoreTake(p_i2c->cmd_mux, ticks_to_wait);
if (res == pdFALSE) {
return ESP_ERR_TIMEOUT;
@ -1528,13 +1528,15 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
i2c_cmd_evt_t evt;
while (1) {
TickType_t wait_time = xTaskGetTickCount();
if (wait_time - ticks_start > ticks_to_wait) { // out of time
wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
const TickType_t elapsed = wait_time - ticks_start;
if (elapsed >= ticks_to_wait) { // out of time
/* Before triggering a timeout, empty the queue by giving a wait_time of 0:
* - if the queue is empty, `pdFALSE` will be returned and the loop will be exited
* - if the queue is not empty, we will pop an element and come back here again
*/
wait_time = 0;
} else {
wait_time = ticks_to_wait - (wait_time - ticks_start);
if (wait_time < I2C_CMD_ALIVE_INTERVAL_TICK) {
wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
}
wait_time = MIN(ticks_to_wait - elapsed, I2C_CMD_ALIVE_INTERVAL_TICK);
}
// In master mode, since we don't have an interrupt to detective bus error or FSM state, what we do here is to make
// sure the interrupt mechanism for master mode is still working.

Wyświetl plik

@ -1794,7 +1794,7 @@ esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool *collision_flag)
esp_err_t uart_set_wakeup_threshold(uart_port_t uart_num, int wakeup_threshold)
{
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_THRESHOLD_NUM(uart_num, UART_ACTIVE_THRESHOLD_V) && wakeup_threshold > UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_THRESHOLD_NUM(uart_num, UART_ACTIVE_THRESHOLD_V) && wakeup_threshold >= UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
"wakeup_threshold out of bounds");
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold);

Wyświetl plik

@ -77,13 +77,15 @@ static esp_err_t dp83848_update_link_duplex_speed(phy_dp83848_t *dp83848)
uint32_t peer_pause_ability = false;
anlpar_reg_t anlpar;
physts_reg_t physts;
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed");
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_STS_REG_ADDR, &(physts.val)), err, TAG, "read PHYSTS failed");
eth_link_t link = physts.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
bmsr_reg_t bmsr;
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed");
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
/* check if link status changed */
if (dp83848->phy_802_3.link_status != link) {
/* when link up, read negotiation result */
if (link == ETH_LINK_UP) {
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed");
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_STS_REG_ADDR, &(physts.val)), err, TAG, "read PHYSTS failed");
if (physts.speed_status) {
speed = ETH_SPEED_10M;
} else {

Wyświetl plik

@ -23,6 +23,11 @@ extern "C" {
#include <stdbool.h>
#include <stdio.h>
/* HID BT Task Size Def */
#ifndef BT_HID_DEVICE_TASK_SIZE
#define BT_HID_DEVICE_TASK_SIZE 4096
#endif
/* HID Report Map Values */
#define HID_RM_INPUT 0x80
#define HID_RM_OUTPUT 0x90

Wyświetl plik

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

Wyświetl plik

@ -282,6 +282,12 @@ static void bt_hidd_init_app(void)
s_hidd_param.app_param.subclass = get_subclass_by_appearance(s_hidd_param.dev->appearance);
s_hidd_param.app_param.desc_list = (uint8_t *)s_hidd_param.dev->devices[0].reports_map.data;
s_hidd_param.app_param.desc_list_len = s_hidd_param.dev->devices[0].reports_map.len;
// Information SDP
s_hidd_param.app_param.vendor_id = p_config->vendor_id;
s_hidd_param.app_param.product_id = p_config->product_id;
s_hidd_param.app_param.version = p_config->version;
s_hidd_param.app_param.vendor_id_source = s_hidd_param.app_param.vendor_id_source;
}
static void bt_hidd_init_qos(void)
@ -812,7 +818,7 @@ esp_err_t esp_bt_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_confi
.queue_size = 5,
.task_name = "bt_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = 2048,
.task_stack_size = BT_HID_DEVICE_TASK_SIZE,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_hidd_param.dev->event_loop_handle);

Wyświetl plik

@ -10,39 +10,75 @@
#include "soc/soc_caps.h"
#include "esp_err.h"
#include "esp_check.h"
#if CONFIG_GDMA_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 "esp_log.h"
#include "esp_check.h"
#include "esp_private/sleep_retention.h"
#include "esp_private/esp_regdma.h"
#include "sleep_gdma_retention_context.inc"
#include "hal/gdma_ll.h"
static const char *TAG = "gdma";
#define SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id)
typedef struct {
int group_id;
int pair_id;
} gdma_channel_retention_arg_t;
static esp_err_t sleep_modem_gdma_channel_retention_init(sleep_retention_module_bitmap_t module)
typedef struct gdma_chx_reg_ctx_link {
const sleep_retention_entries_config_t *link_list;
uint32_t link_num;
} gdma_chx_reg_ctx_link_t;
#include "sleep_gdma_retention_context.inc"
static esp_err_t sleep_gdma_channel_retention_init(void *arg)
{
uint32_t id = __builtin_ctz(module / SLEEP_RETENTION_MODULE_GDMA_CH0);
esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[id].link_list, gdma_chx_regs_retention[id].link_num, REGDMA_LINK_PRI_7, module);
gdma_channel_retention_arg_t *parg = (gdma_channel_retention_arg_t *)arg;
int group_id = parg->group_id;
int pair_id = parg->pair_id;
sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id);
esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[group_id][pair_id].link_list, gdma_chx_regs_retention[group_id][pair_id].link_num, REGDMA_LINK_PRI_7, module);
if (err == ESP_OK) {
int group_id = id / SOC_GDMA_PAIRS_PER_GROUP_MAX;
int pair_id = id % SOC_GDMA_PAIRS_PER_GROUP_MAX;
ESP_LOGI(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id);
ESP_LOGD(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id);
}
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id);
return err;
}
esp_err_t gdma_sleep_retention_init(int group_id, int pair_id)
{
esp_err_t err = ESP_OK;
err = sleep_modem_gdma_channel_retention_init(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id));
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id);
gdma_channel_retention_arg_t arg = { .group_id = group_id, .pair_id = pair_id };
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_gdma_channel_retention_init, .arg = &arg } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
};
sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id);
esp_err_t err = sleep_retention_module_init(module, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(module);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for GDMA retention");
}
}
return err;
}
esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id));
return ESP_OK;;
esp_err_t err = sleep_retention_module_free(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id));
if (err != ESP_OK) {
ESP_LOGW(TAG, "GDMA pair (%d, %d) retention destroy failed", group_id, pair_id);
}
err = sleep_retention_module_deinit(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id));
if (err != ESP_OK) {
ESP_LOGW(TAG, "GDMA pair (%d, %d) retention deinit failed", group_id, pair_id);
}
return err;
}

Wyświetl plik

@ -578,11 +578,11 @@ void regdma_link_stats(void *link, int entry);
void regdma_link_set_write_wait_content(void *link, uint32_t value, uint32_t mask);
/**
* @brief Print all node information of the REGDMA linked list indicated by the entry argument
* @brief Dump all node information of the REGDMA linked list indicated by the entry argument
* @param link The REGDMA linkded list head pointer
* @param entry For nodes that support branching, use the branch specified by entry argument recursively
*/
void regdma_link_show_memories(void *link, int entry);
void regdma_link_dump(FILE *out, void *link, int entry);
/**
* @brief Update REGDMA linked list node next pointers
@ -625,7 +625,7 @@ void *regdma_find_module_link_tail(void *link, void *tail, int entry, uint32_t m
/**
* @brief Find the tail node of the previous module of the specified module in the REGDMA linked list
* indicated by the entry argument starting from the link argment to the end of the tail argument
* indicated by the entry argument starting from the link argument to the end of the tail argument
* @param link The REGDMA linkded list head pointer
* @param tail The REGDMA linkded list tail pointer
* @param entry For nodes that support branching, use the branch specified by entry argument recursively
@ -636,7 +636,7 @@ void *regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint3
/**
* @brief Find the head node of the next module of the specified module in the REGDMA linked list
* indicated by the entry argument starting from the link argment to the end of the tail argument
* indicated by the entry argument starting from the link argument to the end of the tail argument
* @param link The REGDMA linkded list head pointer
* @param tail The REGDMA linkded list tail pointer
* @param entry For nodes that support branching, use the branch specified by entry argument recursively

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -31,34 +31,6 @@ extern "C" {
*/
bool clock_domain_pd_allowed(void);
/**
* @brief PCR module power down initialize
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args
* No memory for the retention link
*/
esp_err_t sleep_clock_system_retention_init(void);
/**
* @brief PCR module power down deinitialize
*/
void sleep_clock_system_retention_deinit(void);
/**
* @brief Modem syscon module power down initialize
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args
* No memory for the retention link
*/
esp_err_t sleep_clock_modem_retention_init(void);
/**
* @brief Modem syscon module power down deinitialize
*/
void sleep_clock_modem_retention_deinit(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -23,34 +23,55 @@ extern "C" {
* includes sleep retention list creation, destruction and debugging interfaces.
*/
typedef enum sleep_retention_module_bitmap {
typedef enum sleep_retention_module {
SLEEP_RETENTION_MODULE_MIN = 0,
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1),
SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2),
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2,
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10),
SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11),
SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12),
SLEEP_RETENTION_MODULE_BT_BB = BIT(13),
SLEEP_RETENTION_MODULE_802154_MAC = BIT(14),
SLEEP_RETENTION_MODULE_WIFI_MAC = 10,
SLEEP_RETENTION_MODULE_WIFI_BB = 11,
SLEEP_RETENTION_MODULE_BLE_MAC = 12,
SLEEP_RETENTION_MODULE_BT_BB = 13,
SLEEP_RETENTION_MODULE_802154_MAC = 14,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16),
SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17),
SLEEP_RETENTION_MODULE_TEE_APM = BIT(18),
SLEEP_RETENTION_MODULE_UART0 = BIT(19),
SLEEP_RETENTION_MODULE_TG0 = BIT(20),
SLEEP_RETENTION_MODULE_IOMUX = BIT(21),
SLEEP_RETENTION_MODULE_SPIMEM = BIT(22),
SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23),
SLEEP_RETENTION_MODULE_GDMA_CH0 = BIT(24),
SLEEP_RETENTION_MODULE_GDMA_CH1 = BIT(25),
SLEEP_RETENTION_MODULE_GDMA_CH2 = BIT(26),
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_ADC = 17,
SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
SLEEP_RETENTION_MODULE_MAX = 31
} sleep_retention_module_t;
typedef enum sleep_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} sleep_retention_module_bitmap_t;
typedef regdma_entry_buf_t sleep_retention_entries_t;
@ -60,6 +81,21 @@ typedef struct {
uint32_t owner; /**< Indicates which regdma entries the current node will insert into */
} sleep_retention_entries_config_t;
typedef esp_err_t (*sleep_retention_callback_t)(void *args);
typedef struct {
sleep_retention_callback_t handle;
void *arg;
} sleep_retention_create_callback_t;
typedef struct {
sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */
} sleep_retention_module_callbacks_t;
typedef enum {
SLEEP_RETENTION_MODULE_ATTR_PASSIVE = 0x1
} sleep_retention_module_attribute_t;
/**
* @brief Create a runtime sleep retention linked list
*
@ -67,26 +103,19 @@ typedef struct {
* @param num the total number of sleep retention linked list configuration
* items
* @param priority the priority of the created sleep retention linked list
* @param module the bitmap of the module to which the created sleep retention
* @param module the number of the module to which the created sleep retention
* linked list belongs
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM not enough memory for sleep retention
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module);
esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module);
/**
* @brief Destroy a runtime sleep retention linked list
*
* @param module the bitmap of the module to be destroyed
* @brief Dump all runtime sleep retention linked lists
*/
void sleep_retention_entries_destroy(int module);
/**
* @brief Print all runtime sleep retention linked lists
*/
void sleep_retention_entries_show_memories(void);
void sleep_retention_dump_entries(FILE *out);
/**
* @brief Find the linked list node with the unique id
@ -104,6 +133,90 @@ void * sleep_retention_find_link_by_id(int id);
*/
void sleep_retention_entries_get(sleep_retention_entries_t *entries);
typedef struct sleep_retention_module_init_param {
sleep_retention_module_callbacks_t cbs; /*!< The callbacks list of the initialize module */
sleep_retention_module_attribute_t attribute; /*!< A bitmap indicating attribute of the initialize module */
sleep_retention_module_bitmap_t depends; /*!< A bitmap identifying all modules that the current module depends on */
} sleep_retention_module_init_param_t;
/**
* @brief sleep retention initialization for the module
*
* @param module the module number that needs initialization
* @param param the initialize parameters for module sleep retention initialization
*
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM not enough memory for sleep retention
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
* - ESP_ERR_INVALID_STATE if the retention context of module already been allocated
*/
esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param);
/**
* @brief sleep retention de-initialization for the module
*
* @param module the module number that needs de-initialization
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
* - ESP_ERR_INVALID_STATE if the retention context of module already been allocated
*/
esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module);
/**
* @brief Allocate the sleep retention context for the module
*
* @param module the module number that need to allocating sleep retention context
*
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM not enough memory for sleep retention
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
* - ESP_ERR_INVALID_STATE if the module is de-initialized
* - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE
*/
esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module);
/**
* @brief Free the sleep retention context for the module
*
* @param module the module number that need to free sleep retention context
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
* - ESP_ERR_INVALID_STATE if the module is de-initialized
* - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE
*/
esp_err_t sleep_retention_module_free(sleep_retention_module_t module);
/**
* @brief Get all initialized modules that require sleep retention
*
* This is an unprotected interface for getting a bitmap of all modules that
* require sleep retention.
*
* It can only be called by the sleep procedure.
*
* @return the bitmap for all modules that require sleep retention
*/
uint32_t sleep_retention_get_inited_modules(void);
/**
* @brief Get all created modules that require sleep retention
*
* This is an unprotected interface for getting a bitmap of all modules that
* require sleep retention.
*
* It can only be called by the sleep procedure.
*
* @return the bitmap for all modules that have successfully created a sleep
* retention context
*/
uint32_t sleep_retention_get_created_modules(void);
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
/**
* @brief Software trigger REGDMA to do extra linked list retention
@ -114,18 +227,6 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries);
void sleep_retention_do_extra_retention(bool backup_or_restore);
#endif
/**
* @brief Get all registered modules that require sleep retention
*
* This is an unprotected interface for getting a bitmap of all modules that
* require sleep retention.
*
* It can only be called by the sleep procedure.
*
* @return the bitmap of all modules requiring sleep retention
*/
uint32_t sleep_retention_get_modules(void);
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
/**
* @brief Software trigger REGDMA to do system linked list retention

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -29,15 +29,6 @@ extern "C" {
*/
bool peripheral_domain_pd_allowed(void);
/**
* @brief Digital peripheral power down initialize
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args
* No memory for the retention link
*/
void sleep_sys_periph_retention_init(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -17,6 +17,7 @@
#include "esp_private/esp_pmu.h"
#include "esp_sleep.h"
#include "hal/efuse_hal.h"
#include "hal/clk_tree_ll.h"
// Please define the frequently called modules in the low bit,
// which will improve the execution efficiency
@ -354,10 +355,29 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
#if SOC_BT_SUPPORTED
case PERIPH_BT_MODULE:
#if CONFIG_IDF_TARGET_ESP32H2
bool rc_clk_en = true;
bool selected = (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ||
(src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW);
if (selected) {
rc_clk_en = clk_ll_rc32k_is_enabled();
if (!rc_clk_en) {
clk_ll_rc32k_enable();
}
modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, MODEM_CLOCK_LPCLK_SRC_RC32K);
}
#endif // CONFIG_IDF_TARGET_ESP32H2
modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal);
modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, src);
modem_clock_hal_set_ble_rtc_timer_divisor_value(MODEM_CLOCK_instance()->hal, divider);
modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true);
#if CONFIG_IDF_TARGET_ESP32H2
if (!rc_clk_en) {
extern void esp_ble_rtc_ticks_delay(uint32_t ticks);
esp_ble_rtc_ticks_delay(2);
clk_ll_rc32k_disable();
}
#endif // CONFIG_IDF_TARGET_ESP32H2
#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
if (efuse_hal_chip_revision() != 0) {
if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {

Wyświetl plik

@ -50,32 +50,31 @@ static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = {
GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG
GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG
*/
#define G0P1_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG
#define G0P1_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG
static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000};
static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \
G0P1_RETENTION_REGS_CNT_0, 0, 0, \
G0P2_RETENTION_REGS_CNT_0, 0, 0, \
g0p2_regs_map0[0], g0p2_regs_map0[1], \
g0p2_regs_map0[2], g0p2_regs_map0[3]), \
.owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \
G0P1_RETENTION_REGS_CNT_1, 0, 0, \
G0P2_RETENTION_REGS_CNT_1, 0, 0, \
g0p2_regs_map1[0], g0p2_regs_map1[1], \
g0p2_regs_map1[2], g0p2_regs_map1[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};
static const struct {
const sleep_retention_entries_config_t *link_list;
uint32_t link_num;
} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
}
};

Wyświetl plik

@ -50,32 +50,31 @@ static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = {
GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG
GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG
*/
#define G0P1_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG
#define G0P1_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG
static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000};
static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \
G0P1_RETENTION_REGS_CNT_0, 0, 0, \
G0P2_RETENTION_REGS_CNT_0, 0, 0, \
g0p2_regs_map0[0], g0p2_regs_map0[1], \
g0p2_regs_map0[2], g0p2_regs_map0[3]), \
.owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \
G0P1_RETENTION_REGS_CNT_1, 0, 0, \
G0P2_RETENTION_REGS_CNT_1, 0, 0, \
g0p2_regs_map1[0], g0p2_regs_map1[1], \
g0p2_regs_map1[2], g0p2_regs_map1[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};
static const struct {
const sleep_retention_entries_config_t *link_list;
uint32_t link_num;
} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
}
};

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -698,71 +698,81 @@ void * regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint
}
#if REGDMA_LINK_DBG
static const char *TAG = "regdma_link";
static __attribute__((unused)) const char *TAG = "regdma_link";
static void print_info_continuous_wrapper(void *link)
static void print_info_link_data(FILE *out, const uint32_t buf[], int len)
{
for (int i = 0; i < len; i++) {
fprintf(out, ((i + 1) % 8) ? "%08lx " : "%08lx\n", buf[i]);
}
if (len % 8) {
fprintf(out, "\n");
}
}
static void print_info_continuous_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_continuous_t *cons = __containerof(link, regdma_link_continuous_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x",
cons->stat.module, cons->stat.id, link, cons->head, cons->body.next,
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p\n",
cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next,
cons->body.backup, cons->body.restore, cons->body.mem);
ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length);
print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length);
}
static void print_info_addr_map_wrapper(void *link)
static void print_info_addr_map_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_addr_map_t *map = __containerof(link, regdma_link_addr_map_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}",
map->stat.module, map->stat.id, link, map->head, map->body.next, map->body.backup,
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n",
map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next, map->body.backup,
map->body.restore, map->body.mem, map->body.map[0], map->body.map[1],
map->body.map[2], map->body.map[3]);
ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length);
print_info_link_data(out, (const uint32_t *)map->body.mem, head.length);
}
static void print_info_write_wait_wrapper(void *link)
static void print_info_write_wait_wrapper(FILE *out, void *link)
{
regdma_link_write_wait_t *ww = __containerof(link, regdma_link_write_wait_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, value:%x, mask:%x",
ww->stat.module, ww->stat.id, link, ww->head, ww->body.next,
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, value:%lx, mask:%lx\n",
ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next,
ww->body.backup, ww->body.value, ww->body.mask);
}
static void print_info_branch_continuous_wrapper(void *link)
static void print_info_branch_continuous_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x",
cons->stat.module, cons->stat.id, link, cons->head, cons->body.next[0], cons->body.next[1],
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p\n",
cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next[0], cons->body.next[1],
cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore,
cons->body.mem);
ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length);
print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length);
}
static void print_info_branch_addr_map_wrapper(void *link)
static void print_info_branch_addr_map_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}",
map->stat.module, map->stat.id, link, map->head, map->body.next[0], map->body.next[1], map->body.next[2],
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n",
map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next[0], map->body.next[1], map->body.next[2],
map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0],
map->body.map[1], map->body.map[2], map->body.map[3]);
ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length);
print_info_link_data(out, (const uint32_t *)map->body.mem, head.length);
}
static void print_info_branch_write_wait_wrapper(void *link)
static void print_info_branch_write_wait_wrapper(FILE *out, void *link)
{
regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head);
ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, value:%x, mask:%x",
ww->stat.module, ww->stat.id, link, ww->head, ww->body.next[0], ww->body.next[1],
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, value:%lx, mask:%lx\n",
ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next[0], ww->body.next[1],
ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value,
ww->body.mask);
}
static void print_link_info(void *args, int entry, int depth)
static void print_link_info(FILE *out, void *args, int entry, int depth)
{
typedef void (*prinf_fn_t)(void *);
typedef void (*prinf_fn_t)(FILE *, void *);
const static prinf_fn_t prinf_fn[] = {
[0] = (prinf_fn_t)print_info_continuous_wrapper,
@ -779,20 +789,20 @@ static void print_link_info(void *args, int entry, int depth)
int it = (head.branch << 2) | head.mode;
assert(it < ARRAY_SIZE(prinf_fn));
(*prinf_fn[it])(args);
(*prinf_fn[it])(out, args);
}
void regdma_link_show_memories(void *link, int entry)
void regdma_link_dump(FILE *out, void *link, int entry)
{
assert(entry < REGDMA_LINK_ENTRY_NUM);
void *next = link;
if (link) {
do {
print_link_info(next, entry, 0);
print_link_info(out, next, entry, 0);
} while ((next = regdma_link_get_next(next, entry)) != NULL);
} else {
ESP_EARLY_LOGW(TAG, "This REGDMA linked list is empty!\n");
fprintf(out, "This REGDMA linked list is empty!\n");
}
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -29,7 +29,7 @@
static __attribute__((unused)) const char *TAG = "sleep_clock";
esp_err_t sleep_clock_system_retention_init(void)
static esp_err_t sleep_clock_system_retention_init(void *arg)
{
#if CONFIG_IDF_TARGET_ESP32C6
#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
@ -46,12 +46,8 @@ esp_err_t sleep_clock_system_retention_init(void)
return ESP_OK;
}
void sleep_clock_system_retention_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
}
esp_err_t sleep_clock_modem_retention_init(void)
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
static esp_err_t sleep_clock_modem_retention_init(void *arg)
{
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
@ -70,34 +66,56 @@ esp_err_t sleep_clock_modem_retention_init(void)
ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization");
return ESP_OK;
}
void sleep_clock_modem_retention_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM);
}
#endif
bool clock_domain_pd_allowed(void)
{
const uint32_t modules = sleep_retention_get_modules();
const uint32_t mask = (const uint32_t) (
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
| SLEEP_RETENTION_MODULE_CLOCK_MODEM
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
/* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed
* through MODEM_SYSCON, when one or more MODEMs are initialized, it is
* necessary to check the state of CLOCK_MODEM to determine MODEM domain on
* or off. The clock and reset of digital peripherals are managed through
* PCR, with TOP domain similar to MODEM domain. */
uint32_t modem_clk_dep_modules = 0;
#if SOC_WIFI_SUPPORTED
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB);
#endif
);
return ((modules & mask) == mask);
#if SOC_BT_SUPPORTED
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
#if SOC_IEEE802154_SUPPORTED
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
uint32_t mask = 0;
if (inited_modules & sys_clk_dep_modules) {
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
}
if (inited_modules & modem_clk_dep_modules) {
#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM);
#endif
}
return ((inited_modules & mask) == (created_modules & mask));
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, BIT(0), 106)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
sleep_clock_system_retention_init();
#endif
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } },
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
};
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param);
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
sleep_clock_modem_retention_init();
init_param = (sleep_retention_module_init_param_t) {
.cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } },
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
};
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param);
#endif
return ESP_OK;
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -285,16 +285,20 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void
bool modem_domain_pd_allowed(void)
{
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
const uint32_t modules = sleep_retention_get_modules();
const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC |
SLEEP_RETENTION_MODULE_WIFI_BB);
const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC |
SLEEP_RETENTION_MODULE_BT_BB);
const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC |
SLEEP_RETENTION_MODULE_BT_BB);
return (((modules & mask_wifi) == mask_wifi) ||
((modules & mask_ble) == mask_ble) ||
((modules & mask_154) == mask_154));
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
uint32_t mask = 0;
#if SOC_WIFI_SUPPORTED
mask |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB);
#endif
#if SOC_BT_SUPPORTED
mask |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
#if SOC_IEEE802154_SUPPORTED
mask |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
return ((inited_modules & mask) == (created_modules & mask));
#else
return false; /* MODEM power domain is controlled by each module (WiFi, Bluetooth or 15.4) of modem */
#endif

Wyświetl plik

@ -2084,7 +2084,11 @@ static uint32_t get_power_down_flags(void)
#endif
#if SOC_PM_SUPPORT_MODEM_PD
if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed()) {
if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed()
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
&& clock_domain_pd_allowed()
#endif
) {
pd_flags |= RTC_SLEEP_PD_MODEM;
}
#endif

Wyświetl plik

@ -23,6 +23,92 @@
static __attribute__((unused)) const char *TAG = "sleep";
struct sleep_retention_module_object {
sleep_retention_module_callbacks_t cbs; /* A callback list that can extend more sleep retention event callbacks */
sleep_retention_module_bitmap_t dependents; /* A bitmap identifying all modules that the current module depends on */
sleep_retention_module_bitmap_t references; /* A bitmap indicating all other modules that depend on (or reference) the current module,
* It will update at runtime based on whether the module is referenced by other modules */
sleep_retention_module_attribute_t attributes; /* A bitmap indicating attribute of the current module */
};
static inline void sleep_retention_module_object_ctor(struct sleep_retention_module_object * const self, sleep_retention_module_callbacks_t *cbs)
{
self->cbs = *cbs;
self->dependents = 0;
self->references = 0;
self->attributes = 0;
}
static inline void sleep_retention_module_object_dtor(struct sleep_retention_module_object * const self)
{
self->cbs = (sleep_retention_module_callbacks_t) { .create = { .handle = NULL, .arg = NULL } };
}
static inline void set_dependencies(struct sleep_retention_module_object * const self, sleep_retention_module_bitmap_t depends)
{
self->dependents = depends;
}
static inline void clr_dependencies(struct sleep_retention_module_object * const self)
{
self->dependents = 0;
}
static inline sleep_retention_module_bitmap_t get_dependencies(struct sleep_retention_module_object * const self)
{
return self->dependents;
}
static inline void set_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module)
{
self->references |= BIT(module);
}
static inline void clr_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module)
{
self->references &= ~BIT(module);
}
static inline sleep_retention_module_bitmap_t get_references(struct sleep_retention_module_object * const self)
{
return self->references;
}
static inline bool references_exist(struct sleep_retention_module_object * const self)
{
return (get_references(self) != 0);
}
static inline void set_attributes(struct sleep_retention_module_object * const self, sleep_retention_module_attribute_t attributes)
{
self->attributes = attributes;
}
static inline void clr_attributes(struct sleep_retention_module_object * const self)
{
self->attributes = 0;
}
static inline sleep_retention_module_attribute_t get_attributes(struct sleep_retention_module_object * const self)
{
return self->attributes;
}
static inline bool module_is_passive(struct sleep_retention_module_object * const self)
{
return (get_attributes(self) & SLEEP_RETENTION_MODULE_ATTR_PASSIVE) ? true : false;
}
static inline bool module_is_inited(sleep_retention_module_t module)
{
return (sleep_retention_get_inited_modules() & BIT(module)) ? true : false;
}
static inline bool module_is_created(sleep_retention_module_t module)
{
return (sleep_retention_get_created_modules() & BIT(module)) ? true : false;
}
/**
* Internal structure which holds all requested sleep retention parameters
*/
@ -38,7 +124,7 @@ typedef struct {
* information according to the configuration information of the linked list
* nodes.
* The PMU module triggers REGDMA to use the corresponding linked list when
* swtiching between different power states. For example:
* switching between different power states. For example:
*
* +---------------+---------------+-------------------+-----------+
* | Current | The next | The entry will be | Retention |
@ -82,6 +168,7 @@ typedef struct {
#define SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES (8u)
#define SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY (0)
#define SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY (SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES - 1)
#define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(-1)) /* the final node does not belong to any module */
struct {
sleep_retention_entries_t entries;
uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM,
@ -91,22 +178,31 @@ typedef struct {
} lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES];
_lock_t lock;
regdma_link_priority_t highpri;
uint32_t modules;
uint32_t inited_modules;
uint32_t created_modules;
struct sleep_retention_module_object instance[32];
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
#define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1)
#endif
} sleep_retention_t;
static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = {
.highpri = (uint8_t)-1, .modules = 0
.highpri = (uint8_t)-1, .inited_modules = 0, .created_modules = 0
};
#define SLEEP_RETENTION_ENTRY_BITMAP_MASK (BIT(REGDMA_LINK_ENTRY_NUM) - 1)
#define SLEEP_RETENTION_ENTRY_BITMAP(bitmap) ((bitmap) & SLEEP_RETENTION_ENTRY_BITMAP_MASK)
static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module);
static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module);
static void sleep_retention_entries_join(void);
static inline sleep_retention_module_bitmap_t module_num2map(sleep_retention_module_t module)
{
return (module == SLEEP_RETENTION_MODULE_INVALID) ? 0 : BIT(module);
}
static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32_t runtime_bitmap)
{
bool use_new_entry = SLEEP_RETENTION_ENTRY_BITMAP(owner & ~runtime_bitmap) ? true : false;
@ -114,7 +210,7 @@ static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32
return use_new_entry && intersection_exist;
}
static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, uint32_t module)
static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, sleep_retention_module_t module)
{
assert(sleep_retention_entries_require_branch(owner, runtime_bitmap));
@ -133,7 +229,7 @@ static esp_err_t sleep_retention_entries_check_and_create_final_default(void)
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries_bitmap == 0) {
err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, 0);
err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, SLEEP_RETENTION_MODULE_INVALID);
}
_lock_release_recursive(&s_retention.lock);
return err;
@ -157,7 +253,7 @@ static void sleep_retention_entries_update(uint32_t owner, void *new_link, regdm
_lock_release_recursive(&s_retention.lock);
}
static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module)
static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module)
{
void *link = NULL;
assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM));
@ -165,9 +261,9 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con
_lock_acquire_recursive(&s_retention.lock);
if (sleep_retention_entries_require_branch(owner, s_retention.lists[priority].runtime_bitmap)) {
if (sleep_retention_entries_check_and_create_default(owner, s_retention.lists[priority].runtime_bitmap,
s_retention.lists[priority].entries_bitmap, priority, module) == ESP_OK) { /* branch node can't as tail node */
s_retention.lists[priority].entries_bitmap, priority, module_num2map(module)) == ESP_OK) { /* branch node can't as tail node */
link = regdma_link_init_safe(
config, true, module,
config, true, module_num2map(module),
(owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL,
(owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL,
(owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL,
@ -175,18 +271,18 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con
);
}
} else {
link = regdma_link_init_safe(config, false, module, s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]);
link = regdma_link_init_safe(config, false, module_num2map(module), s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]);
}
_lock_release_recursive(&s_retention.lock);
return link;
}
static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module)
static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module)
{
assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM));
_lock_acquire_recursive(&s_retention.lock);
void *link = regdma_link_init_safe(
config, true, module,
config, true, module_num2map(module),
(owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL,
(owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL,
(owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL,
@ -208,13 +304,13 @@ static void sleep_retention_entries_stats(void)
}
#if REGDMA_LINK_DBG
void sleep_retention_entries_show_memories(void)
void sleep_retention_dump_entries(FILE *out)
{
_lock_acquire_recursive(&s_retention.lock);
if (s_retention.highpri >= SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY && s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) {
for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[s_retention.highpri].entries); entry++) {
ESP_LOGW(TAG, "Print sleep retention entries[%d] memories:", entry);
regdma_link_show_memories(s_retention.lists[s_retention.highpri].entries[entry], entry);
fprintf(out, "\nsleep retention entries[%d] context:\n", entry);
regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry);
}
}
_lock_release_recursive(&s_retention.lock);
@ -246,7 +342,7 @@ static uint32_t sleep_retention_entries_owner_bitmap(sleep_retention_entries_t *
return owner;
}
static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, uint32_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail)
static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, sleep_retention_module_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail)
{
bool exist = false;
sleep_retention_entries_t destroy_tails, prev_tails;
@ -257,13 +353,13 @@ static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t p
_lock_acquire_recursive(&s_retention.lock);
for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[priority].entries); entry++) {
(*destroy_entries)[entry] = regdma_find_module_link_head(
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module);
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module));
destroy_tails [entry] = regdma_find_module_link_tail(
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module);
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module));
(*next_entries) [entry] = regdma_find_next_module_link_head(
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module);
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module));
prev_tails [entry] = regdma_find_prev_module_link_tail(
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module);
s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module));
if ((*destroy_entries)[entry] && destroy_tails[entry]) {
exist = true;
}
@ -322,12 +418,12 @@ static void sleep_retention_entries_check_and_distroy_final_default(void)
{
_lock_acquire_recursive(&s_retention.lock);
assert(s_retention.highpri == SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY);
assert(s_retention.modules == 0);
assert(s_retention.created_modules == 0);
sleep_retention_entries_destroy_wrapper(&s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries);
_lock_release_recursive(&s_retention.lock);
}
static void sleep_retention_entries_all_destroy_wrapper(uint32_t module)
static void sleep_retention_entries_all_destroy_wrapper(sleep_retention_module_t module)
{
void *destroy_tail = NULL, *prev_tail = NULL;
sleep_retention_entries_t destroy_entries, next_entries;
@ -348,13 +444,13 @@ static void sleep_retention_entries_all_destroy_wrapper(uint32_t module)
priority++;
}
} while (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES);
s_retention.modules &= ~module;
s_retention.created_modules &= ~module_num2map(module);
_lock_release_recursive(&s_retention.lock);
}
static void sleep_retention_entries_do_destroy(int module)
static void sleep_retention_entries_do_destroy(sleep_retention_module_t module)
{
assert(module != 0);
assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX);
_lock_acquire_recursive(&s_retention.lock);
sleep_retention_entries_join();
sleep_retention_entries_stats();
@ -362,25 +458,21 @@ static void sleep_retention_entries_do_destroy(int module)
_lock_release_recursive(&s_retention.lock);
}
void sleep_retention_entries_destroy(int module)
static void sleep_retention_entries_destroy(sleep_retention_module_t module)
{
assert(module != 0);
assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX);
_lock_acquire_recursive(&s_retention.lock);
sleep_retention_entries_do_destroy(module);
if (s_retention.modules == 0) {
if (s_retention.created_modules == 0) {
sleep_retention_entries_check_and_distroy_final_default();
pmu_sleep_disable_regdma_backup();
memset((void *)s_retention.lists, 0, sizeof(s_retention.lists));
s_retention.highpri = (uint8_t)-1;
_lock_release_recursive(&s_retention.lock);
_lock_close_recursive(&s_retention.lock);
s_retention.lock = NULL;
return;
}
_lock_release_recursive(&s_retention.lock);
}
static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module)
static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module)
{
_lock_acquire_recursive(&s_retention.lock);
for (int i = num - 1; i >= 0; i--) {
@ -403,7 +495,7 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri
return ESP_OK;
}
static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, uint32_t module)
static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module)
{
static const sleep_retention_entries_config_t bonding_dummy = { REGDMA_LINK_WAIT_INIT(0xffff, 0, 0, 0, 1, 1), SLEEP_RETENTION_ENTRY_BITMAP_MASK };
@ -442,7 +534,7 @@ static void sleep_retention_entries_join(void)
_lock_release_recursive(&s_retention.lock);
}
static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, uint32_t module)
static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module)
{
_lock_acquire_recursive(&s_retention.lock);
esp_err_t err = sleep_retention_entries_create_bonding(priority, module);
@ -451,7 +543,7 @@ static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_en
if(err) goto error;
err = sleep_retention_entries_create_bonding(priority, module);
if(err) goto error;
s_retention.modules |= module;
s_retention.created_modules |= module_num2map(module);
sleep_retention_entries_join();
error:
@ -459,17 +551,16 @@ error:
return err;
}
esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module)
esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module)
{
if (!(retent && num > 0 && (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) && (module != 0))) {
if (retent == NULL || num <= 0) {
return ESP_ERR_INVALID_ARG;
}
if (s_retention.lock == NULL) {
_lock_init_recursive(&s_retention.lock);
if (s_retention.lock == NULL) {
ESP_LOGE(TAG, "Create sleep retention lock failed");
return ESP_ERR_NO_MEM;
}
if (priority >= SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) {
return ESP_ERR_INVALID_ARG;
}
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = sleep_retention_entries_check_and_create_final_default();
if (err) goto error;
@ -493,9 +584,192 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries)
_lock_release_recursive(&s_retention.lock);
}
uint32_t IRAM_ATTR sleep_retention_get_modules(void)
uint32_t IRAM_ATTR sleep_retention_get_inited_modules(void)
{
return s_retention.modules;
return s_retention.inited_modules;
}
uint32_t IRAM_ATTR sleep_retention_get_created_modules(void)
{
return s_retention.created_modules;
}
esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (param == NULL || param->cbs.create.handle == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (s_retention.lock == NULL) {
/* Passive modules will be initialized during the system startup, with the
* operating system scheduler not yet enabled. There is no risk of contention
* for lock initialization here. */
_lock_init_recursive(&s_retention.lock);
if (s_retention.lock == NULL) {
ESP_LOGE(TAG, "Create sleep retention lock failed");
return ESP_ERR_NO_MEM;
}
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (module_is_created(module) || module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
sleep_retention_module_object_ctor(&s_retention.instance[module], &param->cbs);
set_dependencies(&s_retention.instance[module], param->depends);
set_attributes(&s_retention.instance[module], param->attribute);
s_retention.inited_modules |= module_num2map(module);
}
_lock_release_recursive(&s_retention.lock);
return err;
}
esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
bool do_lock_release = false;
_lock_acquire_recursive(&s_retention.lock);
if (module_is_created(module) || !module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
clr_attributes(&s_retention.instance[module]);
clr_dependencies(&s_retention.instance[module]);
sleep_retention_module_object_dtor(&s_retention.instance[module]);
s_retention.inited_modules &= ~module_num2map(module);
do_lock_release = (sleep_retention_get_inited_modules() == 0);
}
_lock_release_recursive(&s_retention.lock);
if (do_lock_release) {
_lock_close_recursive(&s_retention.lock);
s_retention.lock = NULL;
}
return err;
}
static esp_err_t sleep_retention_passive_module_allocate(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency");
assert(module_is_inited(module) && "All passive module must be inited first!");
if (!module_is_created(module)) {
sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]);
for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) {
if (depends & BIT(0)) {
set_reference(&s_retention.instance[i], module);
err = sleep_retention_passive_module_allocate(i);
}
}
if (err == ESP_OK) {
sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle;
if (fn) {
err = (*fn)(s_retention.instance[module].cbs.create.arg);
}
}
}
_lock_release_recursive(&s_retention.lock);
return err;
}
esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(&s_retention.instance[module])) {
if (module_is_inited(module) && !module_is_created(module)) {
sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]);
for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) {
if (depends & BIT(0)) {
set_reference(&s_retention.instance[i], module);
if (module_is_passive(&s_retention.instance[i])) { /* the callee ensures this module is inited */
err = sleep_retention_passive_module_allocate(i);
}
}
}
if (err == ESP_OK) {
sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle;
if (fn) {
err = (*fn)(s_retention.instance[module].cbs.create.arg);
}
}
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;
}
static esp_err_t sleep_retention_passive_module_free(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency");
assert(module_is_inited(module) && "All passive module must be inited first!");
if (module_is_created(module)) {
if (!references_exist(&s_retention.instance[module])) {
sleep_retention_entries_destroy(module);
sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]);
for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) {
if (depends & BIT(0)) {
clr_reference(&s_retention.instance[i], module);
err = sleep_retention_passive_module_free(i);
}
}
}
}
_lock_release_recursive(&s_retention.lock);
return err;
}
esp_err_t sleep_retention_module_free(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(&s_retention.instance[module])) {
if (module_is_inited(module) && module_is_created(module)) {
sleep_retention_entries_destroy(module);
sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]);
for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) {
if (depends & BIT(0)) {
clr_reference(&s_retention.instance[i], module);
if (module_is_passive(&s_retention.instance[i])) {
err = sleep_retention_passive_module_free(i);
}
}
}
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;
}
#if SOC_PM_RETENTION_HAS_CLOCK_BUG

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -34,7 +34,7 @@ static __attribute__((unused)) const char *TAG = "sleep_sys_periph";
#define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6)
esp_err_t sleep_sys_periph_intr_matrix_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_intr_matrix_retention_init(void *arg)
{
#define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1)
@ -42,13 +42,13 @@ esp_err_t sleep_sys_periph_intr_matrix_retention_init(void)
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */
};
esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention");
ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Interrupt matrix");
ESP_LOGD(TAG, "Interrupt Matrix sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_hp_system_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_init(void *arg)
{
#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1)
@ -56,13 +56,13 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void)
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */
};
esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention");
ESP_LOGI(TAG, "HP System sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "HP system");
ESP_LOGD(TAG, "HP System sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_tee_apm_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg)
{
#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1)
#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1)
@ -72,36 +72,36 @@ esp_err_t sleep_sys_periph_tee_apm_retention_init(void)
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */
};
esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_TEE_APM);
esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_SYS_PERIPH);
if (err == ESP_OK) {
const static sleep_retention_entries_config_t regs_highpri_retention[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) }
};
err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_TEE_APM);
err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_SYS_PERIPH);
}
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (TEE/APM) retention");
ESP_LOGI(TAG, "TEE/APM sleep retention initialization");
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM");
ESP_LOGD(TAG, "TEE/APM sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_uart0_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg)
{
#define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1)
const static sleep_retention_entries_config_t uart_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */
/* Note: uart register should set update reg to make the configuration take effect */
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
};
esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention");
ESP_LOGI(TAG, "UART sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "UART");
ESP_LOGD(TAG, "UART sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_tg0_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg)
{
#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1)
@ -117,13 +117,13 @@ esp_err_t sleep_sys_periph_tg0_retention_init(void)
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
};
esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group) retention");
ESP_LOGI(TAG, "Timer Group sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group");
ESP_LOGD(TAG, "Timer Group sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_iomux_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg)
{
#if CONFIG_IDF_TARGET_ESP32C6
#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1)
@ -143,13 +143,13 @@ esp_err_t sleep_sys_periph_iomux_retention_init(void)
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }
};
esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention");
ESP_LOGI(TAG, "IO Matrix sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "IO Matrix");
ESP_LOGD(TAG, "IO Matrix sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_spimem_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg)
{
#define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1)
#define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1)
@ -175,13 +175,13 @@ esp_err_t sleep_sys_periph_spimem_retention_init(void)
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }
};
esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention");
ESP_LOGI(TAG, "SPI Mem sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem");
ESP_LOGD(TAG, "SPI Mem sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_systimer_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg)
{
#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1)
@ -214,30 +214,30 @@ esp_err_t sleep_sys_periph_systimer_retention_init(void)
[18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */
};
esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention");
ESP_LOGI(TAG, "SysTimer sleep retention initialization");
esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SysTimer");
ESP_LOGD(TAG, "SysTimer sleep retention initialization");
return ESP_OK;
}
esp_err_t sleep_sys_periph_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *arg)
{
esp_err_t err;
err = sleep_sys_periph_intr_matrix_retention_init();
err = sleep_sys_periph_intr_matrix_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_hp_system_retention_init();
err = sleep_sys_periph_hp_system_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_tee_apm_retention_init();
err = sleep_sys_periph_tee_apm_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_uart0_retention_init();
err = sleep_sys_periph_uart0_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_tg0_retention_init();
err = sleep_sys_periph_tg0_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_iomux_retention_init();
err = sleep_sys_periph_iomux_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_spimem_retention_init();
err = sleep_sys_periph_spimem_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_systimer_retention_init();
err = sleep_sys_periph_systimer_retention_init(arg);
error:
return err;
@ -245,23 +245,31 @@ error:
bool peripheral_domain_pd_allowed(void)
{
const uint32_t modules = sleep_retention_get_modules();
const uint32_t mask = (const uint32_t) (
SLEEP_RETENTION_MODULE_INTR_MATRIX | \
SLEEP_RETENTION_MODULE_HP_SYSTEM | \
SLEEP_RETENTION_MODULE_TEE_APM | \
SLEEP_RETENTION_MODULE_UART0 | \
SLEEP_RETENTION_MODULE_TG0 | \
SLEEP_RETENTION_MODULE_IOMUX | \
SLEEP_RETENTION_MODULE_SPIMEM | \
SLEEP_RETENTION_MODULE_SYSTIMER);
return ((modules & mask) == mask);
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
return ((inited_modules & mask) == (created_modules & mask));
#else
return false;
#endif
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, BIT(0), 107)
{
sleep_sys_periph_retention_init();
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_sys_periph_retention_init, .arg = NULL } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_SYS_PERIPH, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_SYS_PERIPH);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to allocate sleep retention linked list for system peripherals retention");
}
}
return ESP_OK;
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -81,7 +81,7 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]")
// delete gpio etm task without remove all bounded GPIOs should fail
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_etm_del_task(gpio_task));
// remove unrelated GPIO from the task should fail
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gpio_etm_task_rm_gpio(gpio_task, 10));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_rm_gpio(gpio_task, 10));
// delete etm primitives
TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task, output_gpio));
@ -90,3 +90,118 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]")
TEST_ESP_OK(esp_etm_del_event(gpio_event));
TEST_ESP_OK(esp_etm_del_channel(etm_channel_a));
}
TEST_CASE("gpio_etm_self_trigger_multi_action", "[etm]")
{
// GPIO 0 pos edge event ---> GPIO 1 set level task
// GPIO 22 pos edge event ---> GPIO 1 clear level task
const uint32_t input_gpio1 = 0;
const uint32_t input_gpio2 = 22;
const uint32_t output_gpio = 1;
printf("allocate etm channels\r\n");
esp_etm_channel_config_t etm_config = {};
esp_etm_channel_handle_t etm_channel_a = NULL;
esp_etm_channel_handle_t etm_channel_b = NULL;
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a));
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_b));
printf("allocate GPIO etm event and task\r\n");
esp_etm_task_handle_t gpio_task_a = NULL;
esp_etm_event_handle_t gpio_event_a = NULL;
esp_etm_task_handle_t gpio_task_b = NULL;
esp_etm_event_handle_t gpio_event_b = NULL;
gpio_etm_event_config_t gpio_event_config = {};
gpio_event_config.edges[0] = GPIO_ETM_EVENT_EDGE_POS;
TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_a));
esp_etm_event_handle_t gpio_event_c = NULL; // an extra event only used for testing binding
gpio_event_config.edges[1] = GPIO_ETM_EVENT_EDGE_ANY;
TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_b, &gpio_event_c));
gpio_etm_task_config_t gpio_task_config = {};
gpio_task_config.actions[0] = GPIO_ETM_TASK_ACTION_CLR;
gpio_task_config.actions[1] = GPIO_ETM_TASK_ACTION_SET;
TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task_b, &gpio_task_a));
// bind GPIO to the event and task
TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_a, input_gpio1));
TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_b, input_gpio2));
TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_a, output_gpio));
TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_b, output_gpio));
// try an infeasible bind of second event to a GPIO
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_event_bind_gpio(gpio_event_c, input_gpio1));
// try a feasible bind of second event to a GPIO
TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_c, input_gpio2));
// delete the event to unbind it from the GPIO
TEST_ESP_OK(esp_etm_del_event(gpio_event_c));
printf("initialize gpio\r\n");
gpio_config_t task_gpio_config = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_INPUT_OUTPUT, // we want to read the GPIO value, so it should be input and output
.pin_bit_mask = 1ULL << output_gpio,
};
TEST_ESP_OK(gpio_config(&task_gpio_config));
// set the initial level
TEST_ESP_OK(gpio_set_level(output_gpio, 0));
gpio_config_t event_gpio_config = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_INPUT_OUTPUT, // we want to simulate the edge signal by software, so it should be input and output
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pin_bit_mask = (1ULL << input_gpio1) | (1ULL << input_gpio2),
};
TEST_ESP_OK(gpio_config(&event_gpio_config));
// set the initial level
TEST_ESP_OK(gpio_set_level(input_gpio1, 0));
TEST_ESP_OK(gpio_set_level(input_gpio2, 0));
printf("connect event and task to the channel\r\n");
TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, gpio_event_a, gpio_task_a));
TEST_ESP_OK(esp_etm_channel_connect(etm_channel_b, gpio_event_b, gpio_task_b));
TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a));
TEST_ESP_OK(esp_etm_channel_enable(etm_channel_b));
// input_gpio1 pos edge ---> output_gpio level being set
TEST_ESP_OK(gpio_set_level(input_gpio1, 1));
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio));
// input_gpio1 neg edge does not affect output_gpio level
TEST_ESP_OK(gpio_set_level(input_gpio1, 0));
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio));
// input_gpio2 pos edge ---> output_gpio level being cleared
TEST_ESP_OK(gpio_set_level(input_gpio2, 1));
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio));
// input_gpio2 neg edge does not affect output_gpio level
TEST_ESP_OK(gpio_set_level(input_gpio2, 0));
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio));
// Create a new gpio etm task separately, and add it to the output_gpio should fail (the task does not belong to the same GPIO ETM task channel as gpio_task_a and gpio_task_b)
esp_etm_task_handle_t gpio_task_c = NULL;
gpio_etm_task_config_t gpio_task_config_2 = {
.action = GPIO_ETM_TASK_ACTION_TOG,
};
TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config_2, &gpio_task_c));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_add_gpio(gpio_task_c, output_gpio));
// delete etm primitives
TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_a, output_gpio));
TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_b, output_gpio));
TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a));
TEST_ESP_OK(esp_etm_channel_disable(etm_channel_b));
TEST_ESP_OK(esp_etm_del_task(gpio_task_a));
TEST_ESP_OK(esp_etm_del_task(gpio_task_b));
TEST_ESP_OK(esp_etm_del_task(gpio_task_c));
TEST_ESP_OK(esp_etm_del_event(gpio_event_a));
TEST_ESP_OK(esp_etm_del_event(gpio_event_b));
TEST_ESP_OK(esp_etm_del_channel(etm_channel_a));
TEST_ESP_OK(esp_etm_del_channel(etm_channel_b));
}

Wyświetl plik

@ -28,7 +28,7 @@ static const char* TAG = "btbb_init";
#define BTBB_LINK_OWNER ENTRY(0) | ENTRY(2)
#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG
static esp_err_t btbb_sleep_retention_init(void)
static esp_err_t btbb_sleep_retention_init(void *arg)
{
const static sleep_retention_entries_config_t btbb_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x00), BB_PART_0_ADDR, BB_PART_0_ADDR, BB_PART_0_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
@ -37,13 +37,20 @@ static esp_err_t btbb_sleep_retention_init(void)
};
esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BT_BB);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention");
ESP_LOGI(TAG, "btbb sleep retention initialization");
ESP_LOGD(TAG, "btbb sleep retention initialization");
return ESP_OK;
}
static void btbb_sleep_retention_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BT_BB);
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BT_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to destroy sleep retention linked list for btbb retention");
}
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BT_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Modem BT BB retention callback unregister failed");
}
}
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
@ -54,7 +61,19 @@ void esp_btbb_enable(void)
if (s_btbb_access_ref == 0) {
bt_bb_v2_init_cmplx(BTBB_ENABLE_VERSION_PRINT);
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
btbb_sleep_retention_init();
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = btbb_sleep_retention_init, .arg = NULL } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BT_BB, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BT_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to allocate sleep retention linked list for btbb retention");
}
} else {
ESP_LOGW(TAG, "Modem BT BB retention callback register failed");
}
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
}
s_btbb_access_ref++;

Wyświetl plik

@ -21,6 +21,7 @@
#include "esp_efuse.h"
#include "esp_timer.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
@ -313,7 +314,7 @@ void esp_phy_disable(esp_phy_modem_t modem)
#endif
}
#if CONFIG_IDF_TARGET_ESP32
// Update WiFi MAC time before disalbe WiFi/BT common peripheral clock
// Update WiFi MAC time before disable WiFi/BT common peripheral clock
phy_update_wifi_mac_time(true, esp_timer_get_time());
#endif
// Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG
@ -412,7 +413,20 @@ static uint8_t s_macbb_backup_mem_ref = 0;
/* Reference of powering down MAC and BB */
static bool s_mac_bb_pu = true;
#elif SOC_PM_MODEM_RETENTION_BY_REGDMA
static void *s_mac_bb_tx_base = NULL;
static esp_err_t sleep_retention_wifi_bb_init(void *arg)
{
const static sleep_retention_entries_config_t bb_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */
};
esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi BB");
ESP_LOGD(TAG, "WiFi BB sleep retention initialization");
return ESP_OK;
}
#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA
void esp_mac_bb_pd_mem_init(void)
@ -425,22 +439,18 @@ void esp_mac_bb_pd_mem_init(void)
}
_lock_release(&s_phy_access_lock);
#elif SOC_PM_MODEM_RETENTION_BY_REGDMA
const static sleep_retention_entries_config_t bb_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_retention_wifi_bb_init, .arg = NULL } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM)
};
esp_err_t err = ESP_OK;
_lock_acquire(&s_phy_access_lock);
s_mac_bb_tx_base = sleep_retention_find_link_by_id(0x0b01);
if (s_mac_bb_tx_base == NULL) {
err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB);
}
_lock_release(&s_phy_access_lock);
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_BB, &init_param);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to allocate memory for WiFi baseband retention");
ESP_LOGW(TAG, "WiFi BB sleep retention init failed");
return;
}
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi bb retention");
}
#endif
}
@ -456,10 +466,15 @@ void esp_mac_bb_pd_mem_deinit(void)
}
_lock_release(&s_phy_access_lock);
#elif SOC_PM_MODEM_RETENTION_BY_REGDMA
_lock_acquire(&s_phy_access_lock);
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_WIFI_BB);
s_mac_bb_tx_base = NULL;
_lock_release(&s_phy_access_lock);
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi bb retention");
return;
}
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_BB);
if (err != ESP_OK) {
ESP_LOGW(TAG, "WiFi BB sleep retention deinit failed");
}
#endif
}
@ -903,7 +918,7 @@ static uint8_t phy_find_bin_type_according_country(const char* country)
if (i == sizeof(s_country_code_map_type_table)/sizeof(phy_country_to_bin_type_t)) {
phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
ESP_LOGW(TAG, "Use the default certification code beacuse %c%c doesn't have a certificate", country[0], country[1]);
ESP_LOGW(TAG, "Use the default certification code because %c%c doesn't have a certificate", country[0], country[1]);
}
return phy_init_data_type;

Wyświetl plik

@ -1093,7 +1093,6 @@ r_ble_lll_conn_coex_dpc_update_on_event_scheduled = 0x400014e4;
r_ble_lll_conn_coex_dpc_update_on_event_started = 0x400014e8;
r_ble_lll_conn_cth_flow_alloc_credit = 0x400014ec;
r_ble_lll_conn_current_sm_over = 0x400014f4;
r_ble_lll_conn_event_end_timer_cb = 0x40001508;
r_ble_lll_conn_event_is_over = 0x40001510;
r_ble_lll_conn_event_start_cb = 0x40001514;
r_ble_lll_conn_free_rx_mbuf = 0x40001518;
@ -1483,7 +1482,7 @@ is_lmac_idle = 0x40001b0c;
/*lmacAdjustTimestamp = 0x40001b10;*/
lmacDiscardAgedMSDU = 0x40001b14;
/*lmacDiscardMSDU = 0x40001b18;*/
lmacEndFrameExchangeSequence = 0x40001b1c;
/*lmacEndFrameExchangeSequence = 0x40001b1c;*/
lmacIsIdle = 0x40001b20;
lmacIsLongFrame = 0x40001b24;
/*lmacMSDUAged = 0x40001b28;*/
@ -1845,7 +1844,7 @@ ic_ebuf_recycle_rx = 0x40001fa0;
ic_ebuf_recycle_tx = 0x40001fa4;
ic_reset_rx_ba = 0x40001fa8;
ieee80211_align_eb = 0x40001fac;
ieee80211_ampdu_reorder = 0x40001fb0;
/*ieee80211_ampdu_reorder = 0x40001fb0;*/
ieee80211_ampdu_start_age_timer = 0x40001fb4;
/*ieee80211_encap_esfbuf = 0x40001fb8;*/
ieee80211_is_tx_allowed = 0x40001fbc;
@ -1868,8 +1867,8 @@ ieee80211_decap = 0x40001ffc;
ieee80211_set_tx_pti = 0x40002000;
wifi_is_started = 0x40002004;
ieee80211_gettid = 0x40002008;
ieee80211_ccmp_decrypt = 0x4000200c;
ieee80211_ccmp_encrypt = 0x40002010;
/* ieee80211_ccmp_decrypt = 0x4000200c; */
/* ieee80211_ccmp_encrypt = 0x40002010; */
ccmp_encap = 0x40002014;
ccmp_decap = 0x40002018;
tkip_encap = 0x4000201c;
@ -1923,7 +1922,7 @@ ieee80211_crypto_aes_128_cmac_encrypt = 0x40002100;
ieee80211_alloc_tx_buf = 0x40002108;
/* ieee80211_output_do = 0x4000210c; */
/* ieee80211_send_nulldata = 0x40002110; */
ieee80211_setup_robust_mgmtframe = 0x40002114;
/* ieee80211_setup_robust_mgmtframe = 0x40002114; */
ieee80211_encap_null_data = 0x4000211c;
ieee80211_send_deauth = 0x40002120;
ieee80211_alloc_deauth = 0x40002124;

Wyświetl plik

@ -1516,7 +1516,7 @@ is_lmac_idle = 0x400015e8;
/*lmacAdjustTimestamp = 0x400015ec;*/
lmacDiscardAgedMSDU = 0x400015f0;
/*lmacDiscardMSDU = 0x400015f4;*/
lmacEndFrameExchangeSequence = 0x400015f8;
/*lmacEndFrameExchangeSequence = 0x400015f8;*/
lmacIsIdle = 0x400015fc;
lmacIsLongFrame = 0x40001600;
/*lmacMSDUAged = 0x40001604;*/
@ -1717,7 +1717,7 @@ ic_ebuf_recycle_rx = 0x40001844;
ic_ebuf_recycle_tx = 0x40001848;
ic_reset_rx_ba = 0x4000184c;
ieee80211_align_eb = 0x40001850;
ieee80211_ampdu_reorder = 0x40001854;
/*ieee80211_ampdu_reorder = 0x40001854;*/
ieee80211_ampdu_start_age_timer = 0x40001858;
/*ieee80211_encap_esfbuf = 0x4000185c;*/
ieee80211_is_tx_allowed = 0x40001860;

Wyświetl plik

@ -31,7 +31,7 @@ ic_ebuf_recycle_rx = 0x40000b70;
ic_ebuf_recycle_tx = 0x40000b74;
ic_reset_rx_ba = 0x40000b78;
ieee80211_align_eb = 0x40000b7c;
ieee80211_ampdu_reorder = 0x40000b80;
/*ieee80211_ampdu_reorder = 0x40000b80;*/
ieee80211_ampdu_start_age_timer = 0x40000b84;
/*ieee80211_encap_esfbuf = 0x40000b88;*/
ieee80211_is_tx_allowed = 0x40000b8c;

Wyświetl plik

@ -37,7 +37,7 @@ is_lmac_idle = 0x40000c14;
/*lmacAdjustTimestamp = 0x40000c18;*/
lmacDiscardAgedMSDU = 0x40000c1c;
/*lmacDiscardMSDU = 0x40000c20;*/
lmacEndFrameExchangeSequence = 0x40000c24;
/*lmacEndFrameExchangeSequence = 0x40000c24;*/
lmacIsIdle = 0x40000c28;
lmacIsLongFrame = 0x40000c2c;
/*lmacMSDUAged = 0x40000c30;*/
@ -80,7 +80,7 @@ pm_on_data_rx = 0x40000ca8;
pm_sleep_for = 0x40000cc4;
//pm_tbtt_process = 0x40000cc8;
ppAMPDU2Normal = 0x40000ccc;
ppAssembleAMPDU = 0x40000cd0;
/* ppAssembleAMPDU = 0x40000cd0; */
ppCalFrameTimes = 0x40000cd4;
ppCalSubFrameLength = 0x40000cd8;
//ppCalTxAMPDULength = 0x40000cdc;

Wyświetl plik

@ -1816,7 +1816,7 @@ is_lmac_idle = 0x400052f8;
/*lmacAdjustTimestamp = 0x40005304;*/
lmacDiscardAgedMSDU = 0x40005310;
/*lmacDiscardMSDU = 0x4000531c;*/
lmacEndFrameExchangeSequence = 0x40005328;
/*lmacEndFrameExchangeSequence = 0x40005328;*/
lmacIsIdle = 0x40005334;
lmacIsLongFrame = 0x40005340;
/*lmacMSDUAged = 0x4000534c;*/
@ -2024,7 +2024,7 @@ ic_ebuf_recycle_rx = 0x40005a24;
ic_ebuf_recycle_tx = 0x40005a30;
ic_reset_rx_ba = 0x40005a3c;
ieee80211_align_eb = 0x40005a48;
ieee80211_ampdu_reorder = 0x40005a54;
/* ieee80211_ampdu_reorder = 0x40005a54; */
ieee80211_ampdu_start_age_timer = 0x40005a60;
/* ieee80211_encap_esfbuf = 0x40005a6c; */
ieee80211_is_tx_allowed = 0x40005a78;

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -535,6 +535,18 @@ static void esp_phy_disable_wrapper(void)
esp_phy_disable(PHY_MODEM_WIFI);
}
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
static void regdma_link_set_write_wait_content_wrapper(void *addr, uint32_t value, uint32_t mask)
{
regdma_link_set_write_wait_content(addr, value, mask);
}
static void *sleep_retention_find_link_by_id_wrapper(int id)
{
return sleep_retention_find_link_by_id(id);
}
#endif
wifi_osi_funcs_t g_wifi_osi_funcs = {
._version = ESP_WIFI_OS_ADAPTER_VERSION,
._env_is_chip = esp_coex_common_env_is_chip_wrapper,
@ -650,10 +662,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
._coex_register_start_cb = coex_register_start_cb_wrapper,
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content,
._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id,
._sleep_retention_entries_create = (int (*)(const void *, int, int, int))sleep_retention_entries_create,
._sleep_retention_entries_destroy = sleep_retention_entries_destroy,
._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content_wrapper,
._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id_wrapper,
#endif
._coex_schm_process_restart = coex_schm_process_restart_wrapper,
._coex_schm_register_cb = coex_schm_register_cb_wrapper,

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -72,7 +72,7 @@ typedef enum {
#define WIFI_LOG_SUBMODULE_INIT (1) /*logs related to initialization*/
#define WIFI_LOG_SUBMODULE_IOCTL (1<<1) /*logs related to API calling*/
#define WIFI_LOG_SUBMODULE_CONN (1<<2) /*logs related to connecting*/
#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scaning*/
#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scanning*/
/**
@ -164,9 +164,9 @@ typedef void (*wifi_netstack_buf_free_cb_t)(void *netstack_buf);
* supports reference counter.
*
* @param wifi_if : wifi interface id
* @param buffer : the buffer to be tansmit
* @param buffer : the buffer to be transmit
* @param len : the length of buffer
* @param netstack_buf : the netstack buffer related to bufffer
* @param netstack_buf : the netstack buffer related to buffer
*
* @return
* - ESP_OK : Successfully transmit the buffer to wifi driver
@ -539,6 +539,18 @@ void esp_wifi_power_domain_on(void);
*/
void esp_wifi_power_domain_off(void);
#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA)
/**
* @brief Get wifi mac sleep retention hardware context configuration and size
*
* @param config_size: the wifi mac hardware context configuration size
*
* @return A pointer that point to wifi mac sleep renteiton hardware context configuration table
*/
void * esp_wifi_internal_mac_retention_context_get(int *config_size);
#endif
#if CONFIG_MAC_BB_PD
/**
* @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping.
@ -562,12 +574,12 @@ void pm_mac_wakeup(void);
#endif
/**
* @breif TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb()
* @brief TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb()
*
* @param ifidx The interface id that the tx callback has been triggered from
* @param data Pointer to the data transmitted
* @param data_len Length of the data transmitted
* @param txStatus True:if the data was transmitted sucessfully False: if data transmission failed
* @param txStatus True:if the data was transmitted successfully False: if data transmission failed
*/
typedef void (* wifi_tx_done_cb_t)(uint8_t ifidx, uint8_t *data, uint16_t *data_len, bool txStatus);

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -152,8 +152,6 @@ typedef struct {
#if CONFIG_IDF_TARGET_ESP32C6
void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t);
void * (* _sleep_retention_find_link_by_id)(int);
int (* _sleep_retention_entries_create)(const void *, int, int, int);
void (* _sleep_retention_entries_destroy)(int);
#endif
int32_t _magic;
} wifi_osi_funcs_t;

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -240,6 +240,26 @@ typedef struct {
uint32_t actual_suspend_time_ms[8]; /**< the actual suspend time for each flow id, unit: ms */
} wifi_event_sta_itwt_suspend_t;
/**
* @brief TWT types
*/
typedef enum {
TWT_TYPE_INDIVIDUAL, /**< individual twt */
TWT_TYPE_BROADCAST, /**< broadcast twt */
TWT_TYPE_MAX, /**< the max value */
} wifi_twt_type_t;
/** Argument structure for twt configuration */
typedef struct {
bool post_wakeup_event; /**< post twt wakeup event */
} wifi_twt_config_t;
/** Argument structure for WIFI_EVENT_TWT_WAKEUP event */
typedef struct {
wifi_twt_type_t twt_type; /**< twt type */
uint8_t flow_id; /**< flow id */
} wifi_event_sta_twt_wakeup_t;
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -583,6 +583,7 @@ typedef struct {
uint8_t *hdr; /**< header of the wifi packet */
uint8_t *payload; /**< payload of the wifi packet */
uint16_t payload_len; /**< payload len of the wifi packet */
uint16_t rx_seq; /**< rx sequence number of the wifi packet */
} wifi_csi_info_t;
/**
@ -895,6 +896,7 @@ typedef enum {
WIFI_EVENT_ITWT_TEARDOWN, /**< iTWT teardown */
WIFI_EVENT_ITWT_PROBE, /**< iTWT probe */
WIFI_EVENT_ITWT_SUSPEND, /**< iTWT suspend */
WIFI_EVENT_TWT_WAKEUP, /**< TWT wakeup */
WIFI_EVENT_NAN_STARTED, /**< NAN Discovery has started */
WIFI_EVENT_NAN_STOPPED, /**< NAN Discovery has stopped */

@ -1 +1 @@
Subproject commit 39926ae1f56bd2de3d0c7fb875d5d301c4bf4467
Subproject commit 4fba9c81baa3baf0996a8697127aca176a89e350

Wyświetl plik

@ -12,6 +12,7 @@
#include "esp_private/sleep_modem.h"
#include "esp_pm.h"
#include "esp_sleep.h"
#include "esp_check.h"
#include "esp_private/pm_impl.h"
#include "esp_private/esp_clk.h"
#include "esp_wpa.h"
@ -29,6 +30,10 @@
#include "esp_chip_info.h"
#endif
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
#include "esp_private/sleep_retention.h"
#endif
static bool s_wifi_inited = false;
#if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM)
@ -108,6 +113,41 @@ static void esp_wifi_set_log_level(void)
esp_wifi_internal_set_log_level(wifi_log_level);
}
#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA)
static esp_err_t init_wifi_mac_sleep_retention(void *arg)
{
int config_size;
sleep_retention_entries_config_t *config = esp_wifi_internal_mac_retention_context_get(&config_size);
esp_err_t err = sleep_retention_entries_create(config, config_size, 3, SLEEP_RETENTION_MODULE_WIFI_MAC);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi MAC");
ESP_LOGD(TAG, "WiFi MAC sleep retention initialization");
return ESP_OK;
}
#endif
#if CONFIG_MAC_BB_PD
static void esp_wifi_mac_pd_mem_init(void)
{
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
esp_err_t err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_MAC);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi mac retention");
}
#endif
esp_wifi_internal_set_mac_sleep(true);
}
static void esp_wifi_mac_pd_mem_deinit(void)
{
esp_wifi_internal_set_mac_sleep(false);
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_MAC);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi mac retention");
}
#endif
}
#endif
static esp_err_t wifi_deinit_internal(void)
{
esp_err_t err = ESP_OK;
@ -126,6 +166,11 @@ static esp_err_t wifi_deinit_internal(void)
esp_nan_app_deinit();
#endif
#if CONFIG_MAC_BB_PD
esp_wifi_mac_pd_mem_deinit();
esp_mac_bb_pd_mem_deinit();
#endif
esp_supplicant_deinit();
err = esp_wifi_deinit_internal();
if (err != ESP_OK) {
@ -157,15 +202,17 @@ static esp_err_t wifi_deinit_internal(void)
esp_sleep_disable_wifi_beacon_wakeup();
# endif
#endif /* SOC_WIFI_HW_TSF */
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_MAC);
if (err != ESP_OK) {
ESP_LOGW(TAG, "WiFi MAC sleep retention deinit failed");
}
#endif /* SOC_PM_MODEM_RETENTION_BY_REGDMA */
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
#if CONFIG_MAC_BB_PD
esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
#endif
#if CONFIG_MAC_BB_PD
esp_wifi_internal_set_mac_sleep(false);
esp_mac_bb_pd_mem_deinit();
#endif
#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
esp_wifi_internal_modem_state_configure(false);
esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep);
@ -281,6 +328,17 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
#endif
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = init_wifi_mac_sleep_retention, .arg = NULL } },
.depends = BIT(SLEEP_RETENTION_MODULE_WIFI_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_MAC, &init_param);
if (err != ESP_OK) {
ESP_LOGW(TAG, "WiFi MAC sleep retention init failed");
}
#endif
#if CONFIG_MAC_BB_PD
if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK
|| esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) {
@ -332,7 +390,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
if (result == ESP_OK) {
#if CONFIG_MAC_BB_PD
esp_mac_bb_pd_mem_init();
esp_wifi_internal_set_mac_sleep(true);
esp_wifi_mac_pd_mem_init();
#endif
esp_phy_modem_init();
#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP

Wyświetl plik

@ -142,7 +142,7 @@ typedef uint32_t TickType_t;
UBaseType_t xPortSetInterruptMaskFromISR(void);
/**
* @brief Reenable interrupts in a nested manner (meant to be called from ISRs)
* @brief Re-enable interrupts in a nested manner (meant to be called from ISRs)
*
* @warning Only applies to current CPU.
* @param prev_int_level Previous interrupt level
@ -502,7 +502,7 @@ void vPortTCBPreDeleteHook( void *pxTCB );
#define portENTER_CRITICAL_ISR(mux) vPortEnterCriticalMultiCore(mux)
#define portEXIT_CRITICAL_ISR(mux) vPortExitCriticalMultiCore(mux)
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) xPortEnterCriticalTimeoutSafe(mux)
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) xPortEnterCriticalTimeoutSafe(mux, timeout)
#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux)
#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux)
#else
@ -536,7 +536,12 @@ void vPortTCBPreDeleteHook( void *pxTCB );
portEXIT_CRITICAL(mux); \
} \
})
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) portENTER_CRITICAL_SAFE(mux, timeout)
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) ({ \
(void)timeout; \
portENTER_CRITICAL_SAFE(mux); \
BaseType_t ret = pdPASS; \
ret; \
})
#endif /* (configNUM_CORES > 1) */

Wyświetl plik

@ -172,7 +172,7 @@ BaseType_t xPortInterruptedFromISRContext(void);
static inline UBaseType_t xPortSetInterruptMaskFromISR(void);
/**
* @brief Reenable interrupts in a nested manner (meant to be called from ISRs)
* @brief Re-enable interrupts in a nested manner (meant to be called from ISRs)
*
* @warning Only applies to current CPU.
* @param prev_level Previous interrupt level
@ -460,7 +460,7 @@ void vPortTCBPreDeleteHook( void *pxTCB );
#define portENTER_CRITICAL_ISR(mux) vPortEnterCritical(mux)
#define portEXIT_CRITICAL_ISR(mux) vPortExitCritical(mux)
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) xPortEnterCriticalTimeoutSafe(mux)
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) xPortEnterCriticalTimeoutSafe(mux, timeout)
#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux)
#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux)

Wyświetl plik

@ -5440,7 +5440,8 @@ static void prvResetNextTaskUnblockTime( void )
/* Write the rest of the string. */
#if ( configTASKLIST_INCLUDE_COREID == 1 )
{
sprintf( pcWriteBuffer, "\t%c\t%u\t%d\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].xCoreID, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
const BaseType_t xCoreID = ( pxTaskStatusArray[ x ].xCoreID == tskNO_AFFINITY ) ? -1 : pxTaskStatusArray[ x ].xCoreID;
sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\t%d\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber, ( int ) xCoreID ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
}
#else /* configTASKLIST_INCLUDE_COREID == 1 */
{

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -30,7 +30,7 @@ extern "C" {
// The timeout calibration factor when using ref_tick
#define UART_LL_TOUT_REF_FACTOR_DEFAULT (8)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define UART interrupts
@ -692,7 +692,9 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+2)
// Note: On ESP32, the minimum UART wakeup threshold is 2 + 1 = 3 (UART_ACTIVE_THRESHOLD set to 0 leads to consecutive triggering wakeup)
hw->sleep_conf.active_threshold = wakeup_thrd - (UART_LL_MIN_WAKEUP_THRESH - 1);
}
/**
@ -834,7 +836,7 @@ FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char
*/
FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
{
return hw->sleep_conf.active_threshold + UART_LL_MIN_WAKEUP_THRESH;
return hw->sleep_conf.active_threshold + (UART_LL_MIN_WAKEUP_THRESH - 1);
}
/**

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -672,6 +672,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -380,7 +380,12 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
*/
static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength)
{
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S);
uint32_t drv_cap = (uint32_t)strength;
// DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target
if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) {
drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1
}
SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S);
}
/**
@ -392,7 +397,12 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
*/
static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength)
{
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S);
uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
// DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target
if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) {
drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1
}
*strength = (gpio_drive_cap_t)drv_cap;
}
/**

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -675,6 +675,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -18,6 +18,8 @@
extern "C" {
#endif
#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) + pair_id)
#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL)
#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5]

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,15 +22,20 @@
#define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch))
#define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch))
#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8
#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set which GPIO to be bounded to the event channel
* @brief Set which GPIO to be bound to the event channel
*
* @note Different channels can be bound to one GPIO
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num)
@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3
}
/**
* @brief Wether to enable the event channel
* @brief Whether to enable the event channel
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @param enable True to enable, false to disable
*/
static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable)
@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_
}
/**
* @brief Set which GPIO to be bounded to the task channel
*
* @note One channel can be bounded to multiple different GPIOs
* @brief Get which GPIO is bound to the event channel
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @return GPIO number
*/
static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan)
{
return dev->event_chn_cfg[chan].etm_chn_event_sel;
}
/**
* @brief Set which GPIO to be bound to the task channel
*
* @note One channel can be bound to multiple different GPIOs
*
* @param dev Register base address
* @param chan GPIO ETM Task channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan)
@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32
}
/**
* @brief Wether to enable the GPIO to be managed by the task channel
* @brief Whether to enable the GPIO to be managed by the task channel
*
* @param dev Register base address
* @param gpio_num GPIO number
@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_
}
/**
* @brief Get the channel number that the GPIO is bounded to
* @brief Get the channel number that the GPIO is bound to
*
* @param dev Register base address
* @param gpio_num GPIO number

Wyświetl plik

@ -33,7 +33,7 @@ extern "C" {
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -864,6 +864,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -18,6 +18,8 @@
extern "C" {
#endif
#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) + pair_id)
#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL)
#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5]

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,15 +22,20 @@
#define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch))
#define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch))
#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8
#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set which GPIO to be bounded to the event channel
* @brief Set which GPIO to be bound to the event channel
*
* @note Different channels can be bound to one GPIO
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num)
@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3
}
/**
* @brief Wether to enable the event channel
* @brief Whether to enable the event channel
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @param enable True to enable, false to disable
*/
static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable)
@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_
}
/**
* @brief Set which GPIO to be bounded to the task channel
*
* @note One channel can be bounded to multiple different GPIOs
* @brief Get which GPIO is bound to the event channel
*
* @param dev Register base address
* @param chan Channel number
* @param chan GPIO ETM Event channel number
* @return GPIO number
*/
static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan)
{
return dev->etm_event_chn_cfg[chan].etm_chn_event_sel;
}
/**
* @brief Set which GPIO to be bound to the task channel
*
* @note One channel can be bound to multiple different GPIOs
*
* @param dev Register base address
* @param chan GPIO ETM Task channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan)
@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32
}
/**
* @brief Wether to enable the GPIO to be managed by the task channel
* @brief Whether to enable the GPIO to be managed by the task channel
*
* @param dev Register base address
* @param gpio_num GPIO number
@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_
}
/**
* @brief Get the channel number that the GPIO is bounded to
* @brief Get the channel number that the GPIO is bound to
*
* @param dev Register base address
* @param gpio_num GPIO number

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