mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-19 04:16:01 -04:00
Compare commits
274 Commits
d9334df730
...
0d9edcbfcd
Author | SHA1 | Date | |
---|---|---|---|
|
0d9edcbfcd | ||
|
59e1838270 | ||
|
0c388cf576 | ||
|
ee41fc8a4c | ||
|
5ef55584c1 | ||
|
1d8f1a584c | ||
|
c4d1c046a0 | ||
|
e813b32a3a | ||
|
9c4ae855bb | ||
|
93454579ef | ||
|
a07eed67ef | ||
|
e163941205 | ||
|
1e3c3b8738 | ||
|
5d66e8f729 | ||
|
1337828a0b | ||
|
f1008faa1a | ||
|
e963bff523 | ||
|
5ec3bebf00 | ||
|
83ea37bcfc | ||
|
e43ded7ed5 | ||
|
89712154a8 | ||
|
26c8cae4dd | ||
|
94a915fd5c | ||
|
b9c58c550c | ||
|
98cf50d140 | ||
|
85bc5acfc7 | ||
|
7f0a140f46 | ||
|
3606d9ebf7 | ||
|
82a951447a | ||
|
35c6e44181 | ||
|
625c437412 | ||
|
db6e37c975 | ||
|
6bfa408c7b | ||
|
1611d1344f | ||
|
2726023db4 | ||
|
5214656421 | ||
|
07c3be3398 | ||
|
6ee1c300c2 | ||
|
2b806c9772 | ||
|
c83bf0c3df | ||
|
4f399061e7 | ||
|
5df76105d6 | ||
|
c8de3754df | ||
|
f82c7ee4d1 | ||
|
ef1c62b67d | ||
|
fef76de1ce | ||
|
53272f7d11 | ||
|
7d2752dacd | ||
|
a1da4f8a01 | ||
|
1650681d64 | ||
|
e145e04fca | ||
|
3c30341cfd | ||
|
0878ff90d6 | ||
|
6a29e01a9e | ||
|
7b71d7aaac | ||
|
5a88c4d1ab | ||
|
ec3029ebb3 | ||
|
5be4aca831 | ||
|
60890e9093 | ||
|
19d488370f | ||
|
19c6e77a31 | ||
|
473f39c31f | ||
|
259b7009e9 | ||
|
ae5c7d46d1 | ||
|
f3eec83421 | ||
|
0833cc9bcb | ||
|
f7b31defc9 | ||
|
b6916ca304 | ||
|
81ad0eb544 | ||
|
ba16f50560 | ||
|
21c6c62087 | ||
|
a971ddf17a | ||
|
832e728ac3 | ||
|
f567341168 | ||
|
4e095f4b9f | ||
|
a82b8565b7 | ||
|
cd8009dc5b | ||
|
b9f4822dcb | ||
|
360bbd62b8 | ||
|
9a5a94e75d | ||
|
fe09637123 | ||
|
e1f27d04ed | ||
|
8e53e91ec9 | ||
|
82a4c12817 | ||
|
d3631b3afa | ||
|
3550e36a68 | ||
|
7ac567df96 | ||
|
02da65314b | ||
|
ff3e93af28 | ||
|
8c8e9ae546 | ||
|
d1c47835a2 | ||
|
1011cee7a7 | ||
|
53b7d63ba5 | ||
|
a3274e502e | ||
|
7cf872e610 | ||
|
c68c404cdc | ||
|
8410392567 | ||
|
74ec959b38 | ||
|
9c25d54cb8 | ||
|
a79159f5e1 | ||
|
6673376297 | ||
|
09b53af171 | ||
|
347800bcda | ||
|
05b356f87f | ||
|
7c9109d9e1 | ||
|
24c1f084d0 | ||
|
506bff240b | ||
|
418c856db0 | ||
|
8780375859 | ||
|
bf0eeb633f | ||
|
945ad6ea5d | ||
|
23bc6eac43 | ||
|
e9f4fa08d6 | ||
|
d0be11adfc | ||
|
d91ac9a261 | ||
|
e25e164241 | ||
|
99f0e1b526 | ||
|
b175f84a47 | ||
|
1d0d121861 | ||
|
976066d537 | ||
|
53bb819e88 | ||
|
b71768b742 | ||
|
dfe20e46a1 | ||
|
951d6e44eb | ||
|
3a1c212b41 | ||
|
77c17de379 | ||
|
1157a27964 | ||
|
42e852a165 | ||
|
87859c5629 | ||
|
e9d4e99a2a | ||
|
6e5414b6c4 | ||
|
1fa27cbb0d | ||
|
462698f2de | ||
|
fe80989a17 | ||
|
3937e225ec | ||
|
2526ebdaa9 | ||
|
89c808c26c | ||
|
338d9f40d9 | ||
|
796d40a6a7 | ||
|
d7b701bfa0 | ||
|
7c47596ead | ||
|
bb5f95fcc3 | ||
|
18d545708a | ||
|
4393343ac9 | ||
|
7a5c05e7c0 | ||
|
928859307f | ||
|
966f2c6a5b | ||
|
87d8a5154e | ||
|
2133ca9522 | ||
|
af4315a2b1 | ||
|
29bf116021 | ||
|
c13f35a7cf | ||
|
d215fa6cdb | ||
|
ab53d300d0 | ||
|
8fcc57b12f | ||
|
bde735fe3f | ||
|
66cb82a446 | ||
|
1c319ce9c2 | ||
|
6eb6f9b363 | ||
|
99b89b726d | ||
|
3ef9750005 | ||
|
39cbba3685 | ||
|
51cd6e9291 | ||
|
6c59cda5b1 | ||
|
a56d18383b | ||
|
59066e3edf | ||
|
17f422cc33 | ||
|
b2a3e49635 | ||
|
eec9197d47 | ||
|
dc61456ad8 | ||
|
95f286555a | ||
|
dbcff0e941 | ||
|
315796f96c | ||
|
17ddda01a8 | ||
|
e93e09de3f | ||
|
1cf4becc5f | ||
|
02f5e0f98c | ||
|
debb6ab6a1 | ||
|
d6737c3207 | ||
|
5e82899305 | ||
|
5e5fb89c10 | ||
|
bfba80b778 | ||
|
47a0677525 | ||
|
04485a655f | ||
|
538e3a767b | ||
|
86e384b563 | ||
|
4a124913c4 | ||
|
d891995a7a | ||
|
ef8ff691aa | ||
|
24aa547c80 | ||
|
a0da9ade35 | ||
|
50791931a1 | ||
|
6c9ed891ee | ||
|
8d9b3cfb2f | ||
|
980ec70d0a | ||
|
3e70dafa0b | ||
|
4a72739840 | ||
|
02b2f9a4c4 | ||
|
7f5496de53 | ||
|
2136c072b5 | ||
|
14a2be6eed | ||
|
079df0282a | ||
|
0e4464c363 | ||
|
005844421d | ||
|
c92dfc0f3f | ||
|
b50c2bf195 | ||
|
fc6b33bf3c | ||
|
52059ae507 | ||
|
e6e7b23917 | ||
|
b70f41ca7a | ||
|
350f1410d3 | ||
|
6b6065de50 | ||
|
f49b072ac7 | ||
|
50704ffa70 | ||
|
e5f22521da | ||
|
fc9175d494 | ||
|
c91d481dc9 | ||
|
dbca12721e | ||
|
c3155c39d1 | ||
|
da3b28c29d | ||
|
ba49442683 | ||
|
c94986d793 | ||
|
997512ace2 | ||
|
bd95e6955b | ||
|
e220f1fec6 | ||
|
76102f3b0c | ||
|
5145174858 | ||
|
5d4e5e99c1 | ||
|
1380c0e9ff | ||
|
cd05eea685 | ||
|
b456865c4a | ||
|
913eca40ef | ||
|
f1aa4a5a1c | ||
|
289ceff0e0 | ||
|
2d463ad18b | ||
|
3aac7d2a58 | ||
|
8b1e4d8437 | ||
|
a1e45ac2cc | ||
|
8437262c13 | ||
|
8aacb78ae4 | ||
|
2ca453dab1 | ||
|
8c31479fe5 | ||
|
fb5df708a1 | ||
|
b853ed7aff | ||
|
9960cdd313 | ||
|
6f968394bd | ||
|
385439213a | ||
|
5e50b11232 | ||
|
a11aa9ce10 | ||
|
f62f21dafb | ||
|
f429790e34 | ||
|
86713a6946 | ||
|
4d7489a8ff | ||
|
e03fd702ae | ||
|
97acf99867 | ||
|
f1ea8ca5f0 | ||
|
9c9ae155ba | ||
|
1e6d843e65 | ||
|
1bedadcc17 | ||
|
baf026dcf8 | ||
|
a8bb279dff | ||
|
14cdd8ba2b | ||
|
8aee667873 | ||
|
6cb2080076 | ||
|
4e7d2ec241 | ||
|
f73612d616 | ||
|
03611c121b | ||
|
18e69cab01 | ||
|
47f730645c | ||
|
2f145230b9 | ||
|
891c4d5264 | ||
|
4025f1fc61 | ||
|
c33c8a27c4 | ||
|
3def69642e |
@ -288,8 +288,8 @@ variables:
|
||||
git remote add origin "${CI_REPOSITORY_URL}"
|
||||
fi
|
||||
|
||||
.git_checkout_fetch_head: &git_checkout_fetch_head |
|
||||
git checkout FETCH_HEAD
|
||||
.git_checkout_ci_commit_sha: &git_checkout_ci_commit_sha |
|
||||
git checkout $CI_COMMIT_SHA
|
||||
git clean ${GIT_CLEAN_FLAGS}
|
||||
|
||||
# git diff requires two commits, with different CI env var
|
||||
@ -313,6 +313,7 @@ variables:
|
||||
git fetch origin $CI_MERGE_REQUEST_DIFF_BASE_SHA --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
git fetch origin $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
export GIT_DIFF_OUTPUT=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA)
|
||||
git fetch origin $CI_COMMIT_SHA --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
# merge request pipelines, when the mr got conflicts
|
||||
elif [[ -n $CI_MERGE_REQUEST_DIFF_BASE_SHA ]]; then
|
||||
git fetch origin $CI_MERGE_REQUEST_DIFF_BASE_SHA --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
@ -328,7 +329,7 @@ variables:
|
||||
git fetch origin $CI_COMMIT_SHA --depth=2 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
export GIT_DIFF_OUTPUT=$(git diff --name-only $CI_COMMIT_SHA~1 $CI_COMMIT_SHA)
|
||||
fi
|
||||
- *git_checkout_fetch_head
|
||||
- *git_checkout_ci_commit_sha
|
||||
- *common-before_scripts
|
||||
- *setup_tools_and_idf_python_venv
|
||||
- add_gitlab_ssh_keys
|
||||
@ -342,7 +343,7 @@ variables:
|
||||
- *git_init
|
||||
- *git_fetch_from_mirror_url_if_exists
|
||||
- git fetch origin "${CI_COMMIT_SHA}" --depth=1 ${GIT_FETCH_EXTRA_FLAGS}
|
||||
- *git_checkout_fetch_head
|
||||
- *git_checkout_ci_commit_sha
|
||||
- *common-before_scripts
|
||||
- *setup_tools_and_idf_python_venv
|
||||
- add_gitlab_ssh_keys
|
||||
|
@ -11,7 +11,7 @@ extra_default_build_targets:
|
||||
- esp32c61
|
||||
|
||||
bypass_check_test_targets:
|
||||
- esp32c61
|
||||
|
||||
#
|
||||
# These lines would
|
||||
# - enable the README.md check for esp32c6. Don't forget to add the build jobs in .gitlab/ci/build.yml
|
||||
|
@ -388,3 +388,17 @@ test_idf_build_apps_load_soc_caps:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- python tools/ci/check_soc_headers_load_in_idf_build_apps.py
|
||||
|
||||
test_nvs_gen_check:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
paths:
|
||||
- XUNIT_RESULT.xml
|
||||
- components/nvs_flash/nvs_partition_tool
|
||||
reports:
|
||||
junit: XUNIT_RESULT.xml
|
||||
variables:
|
||||
LC_ALL: C.UTF-8
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/nvs_flash/nvs_partition_tool
|
||||
- pytest --noconftest test_nvs_gen_check.py --junitxml=XUNIT_RESULT.xml
|
||||
|
@ -16,7 +16,11 @@ endif()
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND compile_options "-Oz")
|
||||
else()
|
||||
list(APPEND compile_options "-Os")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
@ -34,7 +38,11 @@ if(NOT BOOTLOADER_BUILD)
|
||||
else() # BOOTLOADER_BUILD
|
||||
|
||||
if(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND compile_options "-Oz")
|
||||
else()
|
||||
list(APPEND compile_options "-Os")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
|
6
Kconfig
6
Kconfig
@ -323,8 +323,8 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
help
|
||||
This option sets compiler optimization level (gcc -O argument) for the app.
|
||||
|
||||
- The "Debug" setting will add the -0g flag to CFLAGS.
|
||||
- The "Size" setting will add the -0s flag to CFLAGS.
|
||||
- The "Debug" setting will add the -Og flag to CFLAGS.
|
||||
- The "Size" setting will add the -Os flag to CFLAGS (-Oz with Clang).
|
||||
- The "Performance" setting will add the -O2 flag to CFLAGS.
|
||||
- The "None" setting will add the -O0 flag to CFLAGS.
|
||||
|
||||
@ -345,7 +345,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
config COMPILER_OPTIMIZATION_DEBUG
|
||||
bool "Debug (-Og)"
|
||||
config COMPILER_OPTIMIZATION_SIZE
|
||||
bool "Optimize for size (-Os)"
|
||||
bool "Optimize for size (-Os with GCC, -Oz with Clang)"
|
||||
config COMPILER_OPTIMIZATION_PERF
|
||||
bool "Optimize for performance (-O2)"
|
||||
config COMPILER_OPTIMIZATION_NONE
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
components/app_update/test_apps:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c5", "esp32c61"]
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: target esp32c5 is not supported yet # TODO: [ESP32C5] IDF-8640, IDF-10317, [ESP32C61] IDF-9245
|
||||
reason: target esp32c61 is not supported yet # TODO: [ESP32C61] IDF-9245
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
@ -19,7 +19,8 @@ def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None:
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317
|
||||
# TODO: [ESP32C61] IDF-9245, IDF-9247, IDF-10983
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C61 has not supported deep sleep')
|
||||
@pytest.mark.generic
|
||||
def test_app_update(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=90)
|
||||
|
@ -20,14 +20,14 @@ menu "Bootloader config"
|
||||
This option sets compiler optimization level (gcc -O argument)
|
||||
for the bootloader.
|
||||
|
||||
- The default "Size" setting will add the -0s flag to CFLAGS.
|
||||
- The default "Size" setting will add the -Os (-Oz with clang) flag to CFLAGS.
|
||||
- The "Debug" setting will add the -Og flag to CFLAGS.
|
||||
- The "Performance" setting will add the -O2 flag to CFLAGS.
|
||||
|
||||
Note that custom optimization levels may be unsupported.
|
||||
|
||||
config BOOTLOADER_COMPILER_OPTIMIZATION_SIZE
|
||||
bool "Size (-Os)"
|
||||
bool "Size (-Os with GCC, -Oz with Clang)"
|
||||
config BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG
|
||||
bool "Debug (-Og)"
|
||||
config BOOTLOADER_COMPILER_OPTIMIZATION_PERF
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -28,12 +28,12 @@
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_init.h"
|
||||
|
||||
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
|
||||
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
|
||||
#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM
|
||||
#define FLASH_SPID_IO SPI_D_GPIO_NUM
|
||||
#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM
|
||||
#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM
|
||||
#define FLASH_CLK_IO MSPI_IOMUX_PIN_NUM_CLK
|
||||
#define FLASH_CS_IO MSPI_IOMUX_PIN_NUM_CS0
|
||||
#define FLASH_SPIQ_IO MSPI_IOMUX_PIN_NUM_MISO
|
||||
#define FLASH_SPID_IO MSPI_IOMUX_PIN_NUM_MOSI
|
||||
#define FLASH_SPIWP_IO MSPI_IOMUX_PIN_NUM_WP
|
||||
#define FLASH_SPIHD_IO MSPI_IOMUX_PIN_NUM_HD
|
||||
|
||||
void bootloader_flash_update_id(void)
|
||||
{
|
||||
@ -98,15 +98,15 @@ void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
|
||||
} else {
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
||||
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_CS, SPICS0_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_MISO, SPIQ_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(SPI_IOMUX_PIN_NUM_MISO, SPIQ_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_MOSI, SPID_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(SPI_IOMUX_PIN_NUM_MOSI, SPID_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_WP, SPIWP_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(SPI_IOMUX_PIN_NUM_WP, SPIWP_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_HD, SPIHD_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(SPI_IOMUX_PIN_NUM_HD, SPIHD_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_out_signal(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||
esp_rom_gpio_connect_out_signal(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
@ -190,7 +190,7 @@ int bootloader_flash_get_wp_pin(void)
|
||||
case EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302:
|
||||
return ESP32_PICO_V3_GPIO;
|
||||
default:
|
||||
return SPI_WP_GPIO_NUM;
|
||||
return MSPI_IOMUX_PIN_NUM_WP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -88,12 +88,12 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
// IDF-4066
|
||||
const uint32_t spiconfig = 0;
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
if (spiconfig == 0) {
|
||||
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
if (spiconfig == 0) {
|
||||
|
||||
} else {
|
||||
|
@ -74,12 +74,12 @@ static const char *TAG = "boot.esp32c5";
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
|
@ -69,12 +69,12 @@ static const char *TAG = "boot.esp32c6";
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
|
@ -70,12 +70,12 @@ void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
|
@ -70,12 +70,12 @@ static const char *TAG = "boot.esp32h2";
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
|
@ -66,12 +66,12 @@ static const char *TAG = "boot.esp32p4";
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -94,12 +94,12 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
if (spiconfig == 0) {
|
||||
|
||||
} else {
|
||||
|
@ -105,12 +105,12 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK;
|
||||
uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO;
|
||||
uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI;
|
||||
uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0;
|
||||
uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD;
|
||||
uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP;
|
||||
if (spiconfig == 0) {
|
||||
|
||||
} else {
|
||||
|
@ -48,8 +48,8 @@ void bootloader_console_init(void)
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
|
||||
const int uart_tx_gpio = (CONFIG_ESP_CONSOLE_UART_TX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_TX_GPIO : UART_NUM_0_TXD_DIRECT_GPIO_NUM;
|
||||
const int uart_rx_gpio = (CONFIG_ESP_CONSOLE_UART_RX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_RX_GPIO : UART_NUM_0_RXD_DIRECT_GPIO_NUM;
|
||||
|
||||
// Switch to the new UART (this just changes UART number used for esp_rom_printf in ROM code).
|
||||
esp_rom_output_set_as_console(uart_num);
|
||||
|
@ -19,6 +19,6 @@ void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
//Not supported but common bootloader calls the function. Do nothing
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8667
|
||||
// TODO: [ESP32C5] IDF-8667, PM-207
|
||||
(void)enable;
|
||||
}
|
||||
|
@ -17,16 +17,15 @@
|
||||
#include "hal/wdt_hal.h"
|
||||
|
||||
// Need to remove check and merge accordingly for ESP32C5 once key manager support added in IDF-8621
|
||||
#if SOC_KEY_MANAGER_SUPPORTED || CONFIG_IDF_TARGET_ESP32C5
|
||||
#if SOC_KEY_MANAGER_FE_KEY_DEPLOY || CONFIG_IDF_TARGET_ESP32C5
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
#include "soc/keymng_reg.h"
|
||||
#include "hal/key_mgr_types.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#else
|
||||
#include "hal/key_mgr_hal.h"
|
||||
#else /* CONFIG_IDF_TARGET_ESP32C5 */
|
||||
#include "hal/key_mgr_ll.h"
|
||||
#include "hal/mspi_timing_tuning_ll.h"
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32C5 */
|
||||
#endif
|
||||
#endif /* !CONFIG_IDF_TARGET_ESP32C5 */
|
||||
#endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY */
|
||||
|
||||
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
#include "soc/sensitive_reg.h"
|
||||
@ -223,17 +222,25 @@ static esp_err_t check_and_generate_encryption_keys(void)
|
||||
ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
|
||||
}
|
||||
// Need to remove check for ESP32C5 and merge accordingly once key manager support added in IDF-8621
|
||||
#if SOC_KEY_MANAGER_SUPPORTED || CONFIG_IDF_TARGET_ESP32C5
|
||||
#if SOC_KEY_MANAGER_FE_KEY_DEPLOY || CONFIG_IDF_TARGET_ESP32C5
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 2);
|
||||
REG_SET_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
REG_CLR_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
#else
|
||||
#else /* CONFIG_IDF_TARGET_ESP32C5 */
|
||||
// Enable and reset key manager
|
||||
// To suppress build errors about spinlock's __DECLARE_RCC_ATOMIC_ENV
|
||||
int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused));
|
||||
key_mgr_ll_enable_bus_clock(true);
|
||||
key_mgr_ll_enable_peripheral_clock(true);
|
||||
key_mgr_ll_reset_register();
|
||||
while (key_mgr_ll_get_state() != ESP_KEY_MGR_STATE_IDLE) {
|
||||
};
|
||||
// Force Key Manager to use eFuse key for XTS-AES operation
|
||||
key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
|
||||
key_mgr_ll_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
|
||||
_mspi_timing_ll_reset_mspi();
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32C5 */
|
||||
#endif
|
||||
#endif /* !CONFIG_IDF_TARGET_ESP32C5 */
|
||||
#endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY */
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/sleep_modem.h"
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -75,11 +76,6 @@
|
||||
#define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5
|
||||
|
||||
#define BT_ASSERT_PRINT ets_printf
|
||||
typedef enum ble_rtc_slow_clk_src {
|
||||
BT_SLOW_CLK_SRC_MAIN_XTAL,
|
||||
BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0,
|
||||
} ble_rtc_slow_clk_src_t;
|
||||
|
||||
/* Types definition
|
||||
************************************************************************
|
||||
*/
|
||||
@ -442,6 +438,7 @@ static bool s_ble_active = false;
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#define BTDM_MIN_TIMER_UNCERTAINTY_US (200)
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
|
||||
#define BLE_RTC_DELAY_US (1800)
|
||||
|
||||
@ -556,6 +553,20 @@ void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
|
||||
{
|
||||
return s_bt_lpclk_src;
|
||||
}
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
|
||||
{
|
||||
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_bt_lpclk_src = clk_src;
|
||||
}
|
||||
|
||||
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
{
|
||||
if (!s_ble_active) {
|
||||
@ -582,7 +593,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
s_ble_active = true;
|
||||
}
|
||||
|
||||
esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src)
|
||||
esp_err_t controller_sleep_init(modem_clock_lpclk_src_t slow_clk_src)
|
||||
{
|
||||
esp_err_t rc = 0;
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
@ -590,7 +601,7 @@ esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src)
|
||||
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, 500 + BLE_RTC_DELAY_US);
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (slow_clk_src == BT_SLOW_CLK_SRC_MAIN_XTAL) {
|
||||
if (slow_clk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
||||
} else {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO);
|
||||
@ -645,11 +656,11 @@ void controller_sleep_deinit(void)
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
}
|
||||
|
||||
static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src)
|
||||
static void esp_bt_rtc_slow_clk_select(modem_clock_lpclk_src_t slow_clk_src)
|
||||
{
|
||||
/* Select slow clock source for BT momdule */
|
||||
switch (slow_clk_src) {
|
||||
case BT_SLOW_CLK_SRC_MAIN_XTAL:
|
||||
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S);
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S);
|
||||
@ -661,7 +672,7 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src)
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
|
||||
#endif // CONFIG_XTAL_FREQ_26
|
||||
break;
|
||||
case BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0:
|
||||
case MODEM_CLOCK_LPCLK_SRC_EXT32K:
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source");
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S);
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S);
|
||||
@ -678,40 +689,39 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src)
|
||||
SET_PERI_REG_BITS(MODEM_CLKRST_ETM_CLK_CONF_REG, 1, 0, MODEM_CLKRST_ETM_CLK_SEL_S);
|
||||
}
|
||||
|
||||
static ble_rtc_slow_clk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
|
||||
static modem_clock_lpclk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
ble_rtc_slow_clk_src_t slow_clk_src;
|
||||
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) {
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
#ifdef CONFIG_XTAL_FREQ_26
|
||||
cfg->rtc_freq = 40000;
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
cfg->rtc_freq = 32000;
|
||||
#endif // CONFIG_XTAL_FREQ_26
|
||||
slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#endif // CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
}
|
||||
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
|
||||
cfg->rtc_freq = 32768;
|
||||
slow_clk_src = BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
#ifdef CONFIG_XTAL_FREQ_26
|
||||
cfg->rtc_freq = 40000;
|
||||
#else
|
||||
cfg->rtc_freq = 32000;
|
||||
#endif // CONFIG_XTAL_FREQ_26
|
||||
slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
esp_bt_rtc_slow_clk_select(slow_clk_src);
|
||||
return slow_clk_src;
|
||||
esp_bt_rtc_slow_clk_select(s_bt_lpclk_src);
|
||||
return s_bt_lpclk_src;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ble_npl_count_info_t npl_info;
|
||||
ble_rtc_slow_clk_src_t rtc_clk_src;
|
||||
modem_clock_lpclk_src_t rtc_clk_src;
|
||||
uint8_t hci_transport_mode;
|
||||
|
||||
memset(&npl_info, 0, sizeof(ble_npl_count_info_t));
|
||||
|
@ -39,11 +39,10 @@
|
||||
#include "esp_pm.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "bt_osi_mem.h"
|
||||
|
||||
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
#include "soc/regdma.h"
|
||||
#include "bt_osi_mem.h"
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/sleep_modem.h"
|
||||
@ -52,9 +51,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "soc/rtc.h"
|
||||
/* Macro definition
|
||||
@ -190,6 +186,7 @@ static bool s_ble_active = false;
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#define BTDM_MIN_TIMER_UNCERTAINTY_US (200)
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
|
||||
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500)
|
||||
#define BLE_RTC_DELAY_US_MODEM_SLEEP (500)
|
||||
@ -333,6 +330,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
|
||||
}
|
||||
}
|
||||
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
|
||||
{
|
||||
return s_bt_lpclk_src;
|
||||
}
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
|
||||
{
|
||||
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_bt_lpclk_src = clk_src;
|
||||
}
|
||||
|
||||
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
{
|
||||
if (!s_ble_active) {
|
||||
@ -362,25 +373,53 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
// TODO: IDF-10765
|
||||
// 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_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// if (err == ESP_OK) {
|
||||
// ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
|
||||
// }
|
||||
// return err;
|
||||
// return ESP_OK;
|
||||
// }
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
|
||||
{
|
||||
uint8_t size;
|
||||
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_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
|
||||
}
|
||||
return err;
|
||||
// TODO: IDF-10765
|
||||
// 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;
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void sleep_modem_ble_mac_modem_state_deinit(void)
|
||||
{
|
||||
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// TODO: IDF-10765
|
||||
// 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);
|
||||
// }
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
}
|
||||
|
||||
void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
|
||||
{
|
||||
esp_ble_set_wakeup_overhead(overhead);
|
||||
// TODO: IDF-10765
|
||||
// esp_ble_set_wakeup_overhead(overhead);
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
|
||||
@ -534,12 +573,51 @@ void ble_controller_scan_duplicate_config(void)
|
||||
ble_vhci_disc_duplicate_set_max_cache_size(cache_size);
|
||||
}
|
||||
|
||||
static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) {
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
}
|
||||
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
cfg->rtc_freq = 100000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
|
||||
cfg->rtc_freq = 32768;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
|
||||
cfg->rtc_freq = 30000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
}
|
||||
esp_bt_rtc_slow_clk_select(s_bt_lpclk_src);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
esp_err_t ret = ESP_OK;
|
||||
ble_npl_count_info_t npl_info;
|
||||
uint32_t slow_clk_freq = 0;
|
||||
uint8_t hci_transport_mode;
|
||||
|
||||
memset(&npl_info, 0, sizeof(ble_npl_count_info_t));
|
||||
@ -592,33 +670,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
modem_clock_module_enable(PERIPH_BT_MODULE);
|
||||
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
|
||||
/* Select slow clock source for BT momdule */
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW);
|
||||
slow_clk_freq = 30000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K);
|
||||
slow_clk_freq = 32768;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K);
|
||||
slow_clk_freq = 32000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K);
|
||||
slow_clk_freq = 32000;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
ble_rtc_clk_init(cfg);
|
||||
esp_phy_modem_init();
|
||||
|
||||
if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) {
|
||||
@ -664,7 +716,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
}
|
||||
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version());
|
||||
r_esp_ble_change_rtc_freq(slow_clk_freq);
|
||||
|
||||
ble_controller_scan_duplicate_config();
|
||||
|
||||
|
@ -393,6 +393,7 @@ static bool s_ble_active = false;
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#define BTDM_MIN_TIMER_UNCERTAINTY_US (200)
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
|
||||
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500)
|
||||
#define BLE_RTC_DELAY_US_MODEM_SLEEP (500)
|
||||
@ -536,6 +537,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
|
||||
}
|
||||
}
|
||||
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
|
||||
{
|
||||
return s_bt_lpclk_src;
|
||||
}
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
|
||||
{
|
||||
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_bt_lpclk_src = clk_src;
|
||||
}
|
||||
|
||||
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
{
|
||||
if (!s_ble_active) {
|
||||
@ -759,12 +774,51 @@ void ble_controller_scan_duplicate_config(void)
|
||||
ble_vhci_disc_duplicate_set_max_cache_size(cache_size);
|
||||
}
|
||||
|
||||
static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) {
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
}
|
||||
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
cfg->rtc_freq = 100000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
|
||||
cfg->rtc_freq = 32768;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
|
||||
cfg->rtc_freq = 30000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
}
|
||||
esp_bt_rtc_slow_clk_select(s_bt_lpclk_src);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
esp_err_t ret = ESP_OK;
|
||||
ble_npl_count_info_t npl_info;
|
||||
uint32_t slow_clk_freq = 0;
|
||||
uint8_t hci_transport_mode;
|
||||
|
||||
memset(&npl_info, 0, sizeof(ble_npl_count_info_t));
|
||||
@ -816,33 +870,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
modem_clock_module_enable(PERIPH_BT_MODULE);
|
||||
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
|
||||
/* Select slow clock source for BT momdule */
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW);
|
||||
slow_clk_freq = 30000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K);
|
||||
slow_clk_freq = 32768;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K);
|
||||
slow_clk_freq = 32000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K);
|
||||
slow_clk_freq = 32000;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
ble_rtc_clk_init(cfg);
|
||||
esp_phy_modem_init();
|
||||
|
||||
if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) {
|
||||
@ -875,7 +903,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
}
|
||||
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version());
|
||||
r_esp_ble_change_rtc_freq(slow_clk_freq);
|
||||
|
||||
ble_controller_scan_duplicate_config();
|
||||
|
||||
|
@ -129,6 +129,9 @@ extern void os_msys_deinit(void);
|
||||
extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
|
||||
extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
#if CONFIG_PM_ENABLE
|
||||
extern void r_esp_ble_stop_wakeup_timing(void);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
extern void r_esp_ble_change_rtc_freq(uint32_t freq);
|
||||
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
|
||||
const uint8_t *peer_pub_key_y,
|
||||
@ -384,6 +387,7 @@ static bool s_ble_active = false;
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#define BTDM_MIN_TIMER_UNCERTAINTY_US (200)
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
|
||||
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (5100)
|
||||
#define BLE_RTC_DELAY_US_MODEM_SLEEP (1500)
|
||||
@ -522,6 +526,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
|
||||
}
|
||||
}
|
||||
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
|
||||
{
|
||||
return s_bt_lpclk_src;
|
||||
}
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
|
||||
{
|
||||
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_bt_lpclk_src = clk_src;
|
||||
}
|
||||
|
||||
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
{
|
||||
if (!s_ble_active) {
|
||||
@ -613,6 +631,9 @@ esp_err_t controller_sleep_init(void)
|
||||
if (rc != ESP_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = esp_deep_sleep_register_hook(&r_esp_ble_stop_wakeup_timing);
|
||||
assert(rc == 0);
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
/* Create a new regdma link for BLE related register restoration */
|
||||
rc = sleep_modem_ble_mac_modem_state_init(0);
|
||||
@ -633,6 +654,7 @@ error:
|
||||
esp_sleep_disable_bt_wakeup();
|
||||
esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing);
|
||||
/*lock should release first and then delete*/
|
||||
if (s_pm_lock != NULL) {
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
@ -652,6 +674,7 @@ void controller_sleep_deinit(void)
|
||||
esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing);
|
||||
/* lock should be released first */
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
@ -729,12 +752,51 @@ void ble_controller_scan_duplicate_config(void)
|
||||
ble_vhci_disc_duplicate_set_max_cache_size(cache_size);
|
||||
}
|
||||
|
||||
static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) {
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
}
|
||||
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
cfg->rtc_freq = 100000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
|
||||
cfg->rtc_freq = 32768;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
|
||||
cfg->rtc_freq = 30000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
|
||||
cfg->rtc_freq = 32000;
|
||||
}
|
||||
esp_bt_rtc_slow_clk_select(s_bt_lpclk_src);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
esp_err_t ret = ESP_OK;
|
||||
ble_npl_count_info_t npl_info;
|
||||
uint32_t slow_clk_freq = 0;
|
||||
uint8_t hci_transport_mode;
|
||||
|
||||
memset(&npl_info, 0, sizeof(ble_npl_count_info_t));
|
||||
@ -786,33 +848,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
modem_clock_module_enable(PERIPH_BT_MODULE);
|
||||
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
|
||||
/* Select slow clock source for BT momdule */
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW);
|
||||
slow_clk_freq = 30000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K);
|
||||
slow_clk_freq = 32768;
|
||||
} else {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL);
|
||||
slow_clk_freq = 100000;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K);
|
||||
slow_clk_freq = 32000;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K);
|
||||
slow_clk_freq = 32000;
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
ble_rtc_clk_init(cfg);
|
||||
|
||||
if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) {
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed");
|
||||
@ -844,7 +880,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
}
|
||||
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version());
|
||||
r_esp_ble_change_rtc_freq(slow_clk_freq);
|
||||
|
||||
ble_controller_scan_duplicate_config();
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 3bb36a79cdfad65c656b9238e0d46b935775ed72
|
||||
Subproject commit 8112ca2c575c6feb32d755623f097f1b66759490
|
@ -1 +1 @@
|
||||
Subproject commit ef1dfc518572e9cda55f13906e32207b40ee280b
|
||||
Subproject commit d874f55e1132416fe18293ae1aa9ac73c40b3261
|
@ -238,3 +238,14 @@ esp_err_t esp_bluedroid_deinit(void)
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_CI_ID) && defined(CONFIG_EXAMPLE_CI_PIPELINE_ID)
|
||||
char *esp_bluedroid_get_example_name(void)
|
||||
{
|
||||
static char example_name[ESP_BLE_ADV_NAME_LEN_MAX];
|
||||
memset(example_name, 0, sizeof(example_name));
|
||||
sprintf(example_name, "BE%02X_%05X_%02X", CONFIG_EXAMPLE_CI_ID & 0xFF,
|
||||
CONFIG_EXAMPLE_CI_PIPELINE_ID & 0xFFFFF, CONFIG_IDF_FIRMWARE_CHIP_ID & 0xFF);
|
||||
return example_name;
|
||||
}
|
||||
#endif
|
||||
|
@ -512,13 +512,17 @@ uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_
|
||||
|
||||
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
|
||||
(type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) {
|
||||
LOG_ERROR("the eir type not define, type = %x\n", type);
|
||||
LOG_ERROR("The advertising data type is not defined, type = %x", type);
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (adv_data == NULL || adv_data_len == 0) {
|
||||
LOG_ERROR("Invalid advertising data.\n");
|
||||
if (adv_data_len == 0) {
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (adv_data == NULL) {
|
||||
LOG_ERROR("Invalid advertising data.");
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ESP_BT_SET_COD_RESERVED_2:
|
||||
case ESP_BT_SET_COD_MAJOR_MINOR:
|
||||
case ESP_BT_SET_COD_SERVICE_CLASS:
|
||||
case ESP_BT_CLR_COD_SERVICE_CLASS:
|
||||
|
@ -209,6 +209,8 @@ typedef uint8_t esp_ble_key_mask_t; /* the key mask type */
|
||||
#define ESP_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define ESP_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
#define ESP_BLE_ADV_NAME_LEN_MAX 29
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -95,6 +95,11 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg);
|
||||
*/
|
||||
esp_err_t esp_bluedroid_deinit(void);
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_CI_ID) && defined(CONFIG_EXAMPLE_CI_PIPELINE_ID)
|
||||
// Only for internal used (CI example test)
|
||||
char *esp_bluedroid_get_example_name(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -33,8 +33,9 @@ typedef enum {
|
||||
ESP_BT_SET_COD_MAJOR_MINOR = 0x01, /*!< overwrite major, minor class */
|
||||
ESP_BT_SET_COD_SERVICE_CLASS = 0x02, /*!< set the bits in the input, the current bit will remain */
|
||||
ESP_BT_CLR_COD_SERVICE_CLASS = 0x04, /*!< clear the bits in the input, others will remain */
|
||||
ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class */
|
||||
ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */
|
||||
ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class, reserved_2 remain unchanged */
|
||||
ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class, reserved_2 remain unchanged */
|
||||
ESP_BT_SET_COD_RESERVED_2 = 0x10, /*!< overwrite the two least significant bits reserved_2 whose default value is 0b00; other values of reserved_2 are invalid according to Bluetooth Core Specification 5.4 */
|
||||
} esp_bt_cod_mode_t;
|
||||
|
||||
#define ESP_BT_GAP_AFH_CHANNELS_LEN 10
|
||||
@ -209,6 +210,28 @@ typedef enum {
|
||||
ESP_BT_COD_MAJOR_DEV_UNCATEGORIZED = 31, /*!< Uncategorized: device not specified */
|
||||
} esp_bt_cod_major_dev_t;
|
||||
|
||||
/// Minor device class field of Class of Device for Peripheral Major Class
|
||||
typedef enum {
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD = 0x10, /*!< Keyboard */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_POINTING = 0x20, /*!< Pointing */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_COMBO = 0x30, /*!< Combo
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD, ESP_BT_COD_MINOR_PERIPHERAL_POINTING
|
||||
and ESP_BT_COD_MINOR_PERIPHERAL_COMBO can be OR'd with one of the
|
||||
following values to identify a multifunctional device. e.g.
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD | ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_POINTING | ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE
|
||||
*/
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_JOYSTICK = 0x01, /*!< Joystick */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD = 0x02, /*!< Gamepad */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_REMOTE_CONTROL = 0x03, /*!< Remote Control */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE = 0x04, /*!< Sensing Device */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_DIGITIZING_TABLET = 0x05, /*!< Digitizing Tablet */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_CARD_READER = 0x06, /*!< Card Reader */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_DIGITAL_PAN = 0x07, /*!< Digital Pan */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_HAND_SCANNER = 0x08, /*!< Hand Scanner */
|
||||
ESP_BT_COD_MINOR_PERIPHERAL_HAND_GESTURAL_INPUT = 0x09, /*!< Hand Gestural Input */
|
||||
} esp_bt_cod_minor_peripheral_t;
|
||||
|
||||
/// Bits of major device class field
|
||||
#define ESP_BT_COD_MAJOR_DEV_BIT_MASK (0x1f00) /*!< Major device bit mask */
|
||||
#define ESP_BT_COD_MAJOR_DEV_BIT_OFFSET (8) /*!< Major device bit offset */
|
||||
|
@ -413,7 +413,11 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
|
||||
|
||||
/* check if mSBC support enabled */
|
||||
if (bta_hf_client_version >= HFP_HF_VERSION_1_6) {
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
bta_hf_client_cb.msbc_enabled = TRUE;
|
||||
#else
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
#endif
|
||||
} else{
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04
|
||||
#define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */
|
||||
#define BTA_UTL_INIT_COD 0x0a
|
||||
#define BTA_UTL_SET_COD_RESERVED_2 0x10 /* overwrite the two least significant bits reserved_2 */
|
||||
|
||||
/*****************************************************************************
|
||||
** Type Definitions
|
||||
@ -43,6 +44,7 @@
|
||||
|
||||
/** for utl_set_device_class() **/
|
||||
typedef struct {
|
||||
UINT8 reserved_2;
|
||||
UINT8 minor;
|
||||
UINT8 major;
|
||||
UINT16 service;
|
||||
@ -125,11 +127,12 @@ extern void utl_freebuf(void **p);
|
||||
** p_cod - Pointer to the device class to set to
|
||||
**
|
||||
** cmd - the fields of the device class to update.
|
||||
** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2
|
||||
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
|
||||
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
|
||||
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
|
@ -170,11 +170,12 @@ void utl_freebuf(void **p)
|
||||
** p_cod - Pointer to the device class to set to
|
||||
**
|
||||
** cmd - the fields of the device class to update.
|
||||
** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2
|
||||
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
|
||||
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
|
||||
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
@ -183,15 +184,19 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd)
|
||||
{
|
||||
UINT8 *dev;
|
||||
UINT16 service;
|
||||
UINT8 minor, major;
|
||||
UINT8 minor, major, reserved_2;
|
||||
DEV_CLASS dev_class;
|
||||
|
||||
dev = BTM_ReadDeviceClass();
|
||||
BTM_COD_SERVICE_CLASS( service, dev );
|
||||
BTM_COD_MINOR_CLASS(minor, dev );
|
||||
BTM_COD_MAJOR_CLASS(major, dev );
|
||||
BTM_COD_RESERVED_2(reserved_2, dev);
|
||||
|
||||
switch (cmd) {
|
||||
case BTA_UTL_SET_COD_RESERVED_2:
|
||||
reserved_2 = p_cod->reserved_2 & BTM_COD_RESERVED_2_MASK;
|
||||
break;
|
||||
case BTA_UTL_SET_COD_MAJOR_MINOR:
|
||||
minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK;
|
||||
major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK;
|
||||
@ -226,7 +231,7 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd)
|
||||
}
|
||||
|
||||
/* convert the fields into the device class type */
|
||||
FIELDS_TO_COD(dev_class, minor, major, service);
|
||||
FIELDS_TO_COD(dev_class, reserved_2, minor, major, service);
|
||||
|
||||
if (BTM_SetDeviceClass(dev_class) == BTM_SUCCESS) {
|
||||
return TRUE;
|
||||
@ -252,16 +257,18 @@ BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod)
|
||||
{
|
||||
UINT8 *dev;
|
||||
UINT16 service;
|
||||
UINT8 minor, major;
|
||||
UINT8 minor, major, reserved_2;
|
||||
|
||||
dev = BTM_ReadDeviceClass();
|
||||
BTM_COD_SERVICE_CLASS( service, dev );
|
||||
BTM_COD_MINOR_CLASS(minor, dev );
|
||||
BTM_COD_MAJOR_CLASS(major, dev );
|
||||
BTM_COD_RESERVED_2(reserved_2, dev );
|
||||
|
||||
p_cod->minor = minor;
|
||||
p_cod->major = major;
|
||||
p_cod->service = service;
|
||||
p_cod->reserved_2 = reserved_2;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -585,6 +585,7 @@ static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg)
|
||||
{
|
||||
tBTA_UTL_COD p_cod;
|
||||
esp_bt_cod_t *cod = &(arg->set_cod.cod);
|
||||
p_cod.reserved_2 = cod->reserved_2;
|
||||
p_cod.minor = cod->minor << 2;
|
||||
p_cod.major = cod->major;
|
||||
p_cod.service = cod->service << 5;
|
||||
@ -602,6 +603,7 @@ esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod)
|
||||
BTC_TRACE_ERROR("%s get class of device failed!",__func__);
|
||||
return ESP_BT_STATUS_FAIL;
|
||||
}
|
||||
cod->reserved_2 = p_cod.reserved_2;
|
||||
cod->minor = p_cod.minor >> 2;
|
||||
cod->major = p_cod.major;
|
||||
cod->service = p_cod.service >> 5;
|
||||
|
@ -163,7 +163,7 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
|
||||
UINT8 scan_mode = 0;
|
||||
UINT16 service_class;
|
||||
UINT8 *p_cod;
|
||||
UINT8 major, minor;
|
||||
UINT8 major, minor, reserved_2;
|
||||
DEV_CLASS cod;
|
||||
LAP temp_lap[2];
|
||||
BOOLEAN is_limited;
|
||||
@ -255,13 +255,14 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
|
||||
if (is_limited ^ cod_limited) {
|
||||
BTM_COD_MINOR_CLASS(minor, p_cod );
|
||||
BTM_COD_MAJOR_CLASS(major, p_cod );
|
||||
BTM_COD_RESERVED_2(reserved_2, p_cod);
|
||||
if (is_limited) {
|
||||
service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
|
||||
} else {
|
||||
service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
|
||||
}
|
||||
|
||||
FIELDS_TO_COD(cod, minor, major, service_class);
|
||||
FIELDS_TO_COD(cod, reserved_2, minor, major, service_class);
|
||||
(void) BTM_SetDeviceClass (cod);
|
||||
}
|
||||
|
||||
@ -515,7 +516,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d
|
||||
|
||||
/* Before beginning the inquiry the current filter must be cleared, so initiate the command */
|
||||
if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED) {
|
||||
/* If set filter command is not succesful reset the state */
|
||||
/* If set filter command is not successful reset the state */
|
||||
p_inq->p_inq_results_cb = NULL;
|
||||
p_inq->state = BTM_INQ_INACTIVE_STATE;
|
||||
|
||||
@ -688,7 +689,7 @@ UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval)
|
||||
** Description This function returns a bit mask of the current inquiry state
|
||||
**
|
||||
** Returns BTM_INQUIRY_INACTIVE if inactive (0)
|
||||
** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active
|
||||
** BTM_LIMITED_INQUIRY_ACTIVE if a limited inquiry is active
|
||||
** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
|
||||
** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active
|
||||
**
|
||||
@ -783,7 +784,7 @@ tBTM_STATUS BTM_CancelInquiry(void)
|
||||
** Description This function is called to start an inquiry.
|
||||
**
|
||||
** Parameters: p_inqparms - pointer to the inquiry information
|
||||
** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately
|
||||
** mode - GENERAL or LIMITED inquiry, BR/LE bit mask separately
|
||||
** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
|
||||
** max_resps - maximum amount of devices to search for before ending the inquiry
|
||||
** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
|
||||
@ -1858,7 +1859,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* new device response */
|
||||
&& ( p_i == NULL ||
|
||||
/* exisiting device with BR/EDR info */
|
||||
/* existing device with BR/EDR info */
|
||||
(p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
|
||||
)
|
||||
#endif
|
||||
|
@ -2162,7 +2162,9 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0};
|
||||
UINT8 num_reports = {0};
|
||||
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
|
||||
UINT8 *pp = p;
|
||||
#endif
|
||||
//UINT8 legacy_event_type = 0;
|
||||
UINT16 evt_type = 0;
|
||||
uint8_t addr_type;
|
||||
|
@ -457,22 +457,22 @@ typedef enum {
|
||||
#define BTM_COD_SERVICE_INFORMATION 0x8000
|
||||
|
||||
/* class of device field macros */
|
||||
#define BTM_COD_FORMAT_TYPE(u8, pd) {u8 = pd[2]&0x03;}
|
||||
#define BTM_COD_RESERVED_2(u8, pd) {u8 = pd[2]&0x03;}
|
||||
#define BTM_COD_MINOR_CLASS(u8, pd) {u8 = pd[2]&0xFC;}
|
||||
#define BTM_COD_MAJOR_CLASS(u8, pd) {u8 = pd[1]&0x1F;}
|
||||
#define BTM_COD_SERVICE_CLASS(u16, pd) {u16 = pd[0]; u16<<=8; u16 += pd[1]&0xE0;}
|
||||
|
||||
/* to set the fields (assumes that format type is always 0) */
|
||||
#define FIELDS_TO_COD(pd, mn, mj, sv) {pd[2] = mn; pd[1] = \
|
||||
mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
|
||||
pd[0] = (sv) >> 8;}
|
||||
#define FIELDS_TO_COD(pd, rs, mn, mj, sv) {pd[2] = (mn & BTM_COD_MINOR_CLASS_MASK) + (rs & BTM_COD_RESERVED_2_MASK); \
|
||||
pd[1] = mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
|
||||
pd[0] = (sv) >> 8;}
|
||||
|
||||
/* the COD masks */
|
||||
#define BTM_COD_FORMAT_TYPE_MASK 0x03
|
||||
#define BTM_COD_MINOR_CLASS_MASK 0xFC
|
||||
#define BTM_COD_MAJOR_CLASS_MASK 0x1F
|
||||
#define BTM_COD_SERVICE_CLASS_LO_B 0x00E0
|
||||
#define BTM_COD_SERVICE_CLASS_MASK 0xFFE0
|
||||
#define BTM_COD_RESERVED_2_MASK 0x03
|
||||
|
||||
/* BTM service definitions
|
||||
** Used for storing EIR data to bit mask
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 071575038c771dedfe177e1c3e0bcf6f83d7094b
|
||||
Subproject commit d1f02191a1b17673ee0f539514f50d2e5fdc7863
|
@ -16,6 +16,7 @@
|
||||
#include "nimble/nimble_npl.h"
|
||||
#include "../../../../controller/esp32c2/esp_bt_cfg.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#include "driver/uart.h"
|
||||
@ -428,6 +429,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
|
||||
void esp_ble_controller_log_dump_all(bool output);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nimble/nimble_npl.h"
|
||||
#include "../../../../controller/esp32c5/esp_bt_cfg.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#include "driver/uart.h"
|
||||
@ -415,6 +416,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
|
||||
void esp_ble_controller_log_dump_all(bool output);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nimble/nimble_npl.h"
|
||||
#include "../../../../controller/esp32c6/esp_bt_cfg.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#include "driver/uart.h"
|
||||
@ -414,6 +415,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
|
||||
void esp_ble_controller_log_dump_all(bool output);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "nimble/nimble_npl.h"
|
||||
#include "../../../../controller/esp32h2/esp_bt_cfg.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#include "driver/uart.h"
|
||||
@ -418,6 +419,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
|
||||
void esp_ble_controller_log_dump_all(bool output);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
|
||||
|
||||
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -444,13 +444,13 @@ static void hci_driver_uart_dma_install(void)
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel));
|
||||
ESP_ERROR_CHECK(gdma_new_ahb_channel(&tx_channel_config, &s_tx_channel));
|
||||
gdma_channel_alloc_config_t rx_channel_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
.sibling_chan = s_tx_channel,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel));
|
||||
ESP_ERROR_CHECK(gdma_new_ahb_channel(&rx_channel_config, &s_rx_channel));
|
||||
gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
||||
gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
||||
gdma_strategy_config_t strategy_config = {
|
||||
|
@ -139,6 +139,10 @@ esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
|
||||
void
|
||||
esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
|
||||
{
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
hci_driver_vhci_tx(data[0], data, len, HCI_DRIVER_DIR_H2C);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ extern "C" {
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "soc/uart_channel.h"
|
||||
|
||||
// Forward declaration. Definition in linenoise/linenoise.h.
|
||||
typedef struct linenoiseCompletions linenoiseCompletions;
|
||||
@ -88,8 +89,8 @@ typedef struct {
|
||||
{ \
|
||||
.channel = CONFIG_ESP_CONSOLE_UART_NUM, \
|
||||
.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE, \
|
||||
.tx_gpio_num = CONFIG_ESP_CONSOLE_UART_TX_GPIO, \
|
||||
.rx_gpio_num = CONFIG_ESP_CONSOLE_UART_RX_GPIO, \
|
||||
.tx_gpio_num = (CONFIG_ESP_CONSOLE_UART_TX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_TX_GPIO : UART_NUM_0_TXD_DIRECT_GPIO_NUM, \
|
||||
.rx_gpio_num = (CONFIG_ESP_CONSOLE_UART_RX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_RX_GPIO : UART_NUM_0_RXD_DIRECT_GPIO_NUM, \
|
||||
}
|
||||
#else
|
||||
#define ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT() \
|
||||
|
@ -290,7 +290,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
|
||||
gdma_channel_alloc_config_t rx_alloc_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
};
|
||||
ret = gdma_new_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel);
|
||||
ret = gdma_new_ahb_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel);
|
||||
if (ret != ESP_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ static esp_err_t i2s_dma_intr_init(i2s_port_t i2s_num, int intr_flag)
|
||||
if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
|
||||
dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX;
|
||||
/* Register a new GDMA tx channel */
|
||||
ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &p_i2s[i2s_num]->tx_dma_chan), TAG, "Register tx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_cfg, &p_i2s[i2s_num]->tx_dma_chan), TAG, "Register tx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_connect(p_i2s[i2s_num]->tx_dma_chan, trig), TAG, "Connect tx dma channel error");
|
||||
gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback};
|
||||
/* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */
|
||||
@ -380,7 +380,7 @@ static esp_err_t i2s_dma_intr_init(i2s_port_t i2s_num, int intr_flag)
|
||||
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
|
||||
dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX;
|
||||
/* Register a new GDMA rx channel */
|
||||
ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &p_i2s[i2s_num]->rx_dma_chan), TAG, "Register rx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_cfg, &p_i2s[i2s_num]->rx_dma_chan), TAG, "Register rx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_connect(p_i2s[i2s_num]->rx_dma_chan, trig), TAG, "Connect rx dma channel error");
|
||||
gdma_rx_event_callbacks_t cb = {.on_recv_eof = i2s_dma_rx_callback};
|
||||
/* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */
|
||||
|
@ -99,7 +99,7 @@
|
||||
#define TEST_DMA_CHAN_MASTER GET_DMA_CHAN(TEST_SPI_HOST)
|
||||
#define TEST_DMA_CHAN_SLAVE GET_DMA_CHAN(TEST_SLAVE_HOST)
|
||||
|
||||
#define FUNC_SPI 1
|
||||
#define FUNC_SPI SPI2_FUNC_NUM
|
||||
#define FUNC_GPIO PIN_FUNC_GPIO
|
||||
|
||||
//Delay information
|
||||
|
@ -126,7 +126,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
|
||||
if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) {
|
||||
sar_periph_ctrl_adc_oneshot_power_acquire();
|
||||
} else {
|
||||
#if !CONFIG_IDF_TARGET_ESP32C5// # TODO: IDF-8638, IDF-8640
|
||||
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
|
||||
esp_sleep_enable_adc_tsens_monitor(true);
|
||||
#endif
|
||||
}
|
||||
@ -229,7 +229,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
|
||||
if (ulp_mode == ADC_ULP_MODE_DISABLE) {
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
} else {
|
||||
#if !CONFIG_IDF_TARGET_ESP32C5// # TODO: IDF-8638, IDF-8640
|
||||
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
|
||||
esp_sleep_enable_adc_tsens_monitor(false);
|
||||
#endif
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ esp_err_t adc_dma_init(adc_dma_t *adc_dma)
|
||||
gdma_channel_alloc_config_t rx_alloc_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
};
|
||||
ret = gdma_new_channel(&rx_alloc_config, &(adc_dma->gdma_chan));
|
||||
ret = gdma_new_ahb_channel(&rx_alloc_config, &(adc_dma->gdma_chan));
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
164
components/esp_coex/esp32c61/esp_coex_adapter.c
Normal file
164
components/esp_coex/esp32c61/esp_coex_adapter.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_timer.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "private/esp_coexist_adapter.h"
|
||||
#include "esp32c61/rom/ets_sys.h"
|
||||
|
||||
#define TAG "esp_coex_adapter"
|
||||
|
||||
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
|
||||
|
||||
bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void)
|
||||
{
|
||||
#ifdef CONFIG_IDF_ENV_FPGA
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *esp_coex_common_spin_lock_create_wrapper(void)
|
||||
{
|
||||
portMUX_TYPE tmp = portMUX_INITIALIZER_UNLOCKED;
|
||||
void *mux = malloc(sizeof(portMUX_TYPE));
|
||||
|
||||
if (mux) {
|
||||
memcpy(mux, &tmp, sizeof(portMUX_TYPE));
|
||||
return mux;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux)
|
||||
{
|
||||
if (xPortInIsrContext()) {
|
||||
portENTER_CRITICAL_ISR(wifi_int_mux);
|
||||
} else {
|
||||
portENTER_CRITICAL(wifi_int_mux);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp)
|
||||
{
|
||||
if (xPortInIsrContext()) {
|
||||
portEXIT_CRITICAL_ISR(wifi_int_mux);
|
||||
} else {
|
||||
portEXIT_CRITICAL(wifi_int_mux);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
{
|
||||
return (void *)xSemaphoreCreateCounting(max, init);
|
||||
}
|
||||
|
||||
void esp_coex_common_semphr_delete_wrapper(void *semphr)
|
||||
{
|
||||
vSemaphoreDelete(semphr);
|
||||
}
|
||||
|
||||
int32_t esp_coex_common_semphr_take_wrapper(void *semphr, uint32_t block_time_tick)
|
||||
{
|
||||
if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) {
|
||||
return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY);
|
||||
} else {
|
||||
return (int32_t)xSemaphoreTake(semphr, block_time_tick);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t esp_coex_common_semphr_give_wrapper(void *semphr)
|
||||
{
|
||||
return (int32_t)xSemaphoreGive(semphr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer)
|
||||
{
|
||||
ets_timer_disarm(timer);
|
||||
}
|
||||
|
||||
void esp_coex_common_timer_done_wrapper(void *ptimer)
|
||||
{
|
||||
ets_timer_done(ptimer);
|
||||
}
|
||||
|
||||
void esp_coex_common_timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg)
|
||||
{
|
||||
ets_timer_setfn(ptimer, pfunction, parg);
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat)
|
||||
{
|
||||
ets_timer_arm_us(ptimer, us, repeat);
|
||||
}
|
||||
|
||||
uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void)
|
||||
{
|
||||
/* The bit width of WiFi light sleep clock calibration is 12 while the one of
|
||||
* system is 19. It should shift 19 - 12 = 7.
|
||||
*/
|
||||
return (esp_clk_slowclk_cal_get() >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH));
|
||||
}
|
||||
|
||||
void *IRAM_ATTR esp_coex_common_malloc_internal_wrapper(size_t size)
|
||||
{
|
||||
return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
}
|
||||
|
||||
/* static wrapper */
|
||||
|
||||
static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, void *hptw)
|
||||
{
|
||||
return (int32_t)xSemaphoreTakeFromISR(semphr, hptw);
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, void *hptw)
|
||||
{
|
||||
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
|
||||
}
|
||||
|
||||
coex_adapter_funcs_t g_coex_adapter_funcs = {
|
||||
._version = COEX_ADAPTER_VERSION,
|
||||
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
|
||||
._semphr_create = esp_coex_common_semphr_create_wrapper,
|
||||
._semphr_delete = esp_coex_common_semphr_delete_wrapper,
|
||||
._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper,
|
||||
._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper,
|
||||
._semphr_take = esp_coex_common_semphr_take_wrapper,
|
||||
._semphr_give = esp_coex_common_semphr_give_wrapper,
|
||||
._is_in_isr = xPortInIsrContext,
|
||||
._malloc_internal = esp_coex_common_malloc_internal_wrapper,
|
||||
._free = free,
|
||||
._esp_timer_get_time = esp_timer_get_time,
|
||||
._env_is_chip = esp_coex_common_env_is_chip_wrapper,
|
||||
._timer_disarm = esp_coex_common_timer_disarm_wrapper,
|
||||
._timer_done = esp_coex_common_timer_done_wrapper,
|
||||
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
|
||||
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
|
||||
._magic = COEX_ADAPTER_MAGIC,
|
||||
};
|
@ -1 +1 @@
|
||||
Subproject commit 3880b604ad7529c91fb4173da479dd9713ce1f66
|
||||
Subproject commit 6a3c4b312155e49593b5df184ffecb54404d295d
|
@ -22,7 +22,7 @@ case $IDF_TARGET in
|
||||
esp32s3)
|
||||
PREFIX=xtensa-esp32s3-elf-
|
||||
;;
|
||||
esp32c2|esp32c3|esp32c6|esp32h2|esp32c5)
|
||||
esp32c2|esp32c3|esp32c6|esp32h2|esp32c5|esp32c61)
|
||||
PREFIX=riscv32-esp-elf-
|
||||
;;
|
||||
*)
|
||||
|
@ -975,7 +975,7 @@ esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num)
|
||||
}
|
||||
#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED
|
||||
esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
if (!GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num)) {
|
||||
@ -1015,7 +1015,7 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num)
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED
|
||||
|
||||
esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ CONFIGS = [
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32c61
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@ -27,6 +28,7 @@ def test_gpio_filter(dut: IdfDut) -> None:
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32c61
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
|
@ -351,8 +351,8 @@ static esp_err_t s_lp_i2c_pins_config(i2c_bus_handle_t handle)
|
||||
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
rtc_gpio_iomux_func_sel(handle->sda_num, i2c_periph_signal[port_id].iomux_func);
|
||||
#else
|
||||
lp_gpio_connect_out_signal(handle->sda_num, i2c_periph_signal[port_id].scl_out_sig, 0, 0);
|
||||
lp_gpio_connect_in_signal(handle->sda_num, i2c_periph_signal[port_id].scl_in_sig, 0);
|
||||
lp_gpio_connect_out_signal(handle->sda_num, i2c_periph_signal[port_id].sda_out_sig, 0, 0);
|
||||
lp_gpio_connect_in_signal(handle->sda_num, i2c_periph_signal[port_id].sda_in_sig, 0);
|
||||
#endif
|
||||
|
||||
rtc_gpio_init(handle->scl_num);
|
||||
@ -366,8 +366,8 @@ static esp_err_t s_lp_i2c_pins_config(i2c_bus_handle_t handle)
|
||||
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
rtc_gpio_iomux_func_sel(handle->scl_num, i2c_periph_signal[port_id].iomux_func);
|
||||
#else
|
||||
lp_gpio_connect_out_signal(handle->scl_num, i2c_periph_signal[port_id].sda_out_sig, 0, 0);
|
||||
lp_gpio_connect_in_signal(handle->scl_num, i2c_periph_signal[port_id].sda_in_sig, 0);
|
||||
lp_gpio_connect_out_signal(handle->scl_num, i2c_periph_signal[port_id].scl_out_sig, 0, 0);
|
||||
lp_gpio_connect_in_signal(handle->scl_num, i2c_periph_signal[port_id].scl_in_sig, 0);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -586,23 +586,13 @@ static esp_err_t s_i2c_transaction_start(i2c_master_dev_handle_t i2c_dev, int xf
|
||||
i2c_master->rx_cnt = 0;
|
||||
i2c_master->read_len_static = 0;
|
||||
|
||||
i2c_hal_master_set_scl_timeout_val(hal, i2c_dev->scl_wait_us, i2c_master->base->clk_src_freq_hz);
|
||||
|
||||
if (!i2c_master->base->is_lp_i2c) {
|
||||
I2C_CLOCK_SRC_ATOMIC() {
|
||||
i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
}
|
||||
}
|
||||
#if SOC_LP_I2C_SUPPORTED
|
||||
else {
|
||||
LP_I2C_SRC_CLK_ATOMIC() {
|
||||
lp_i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
I2C_CLOCK_SRC_ATOMIC() {
|
||||
i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz);
|
||||
}
|
||||
|
||||
// Set the timeout value
|
||||
i2c_hal_master_set_scl_timeout_val(hal, i2c_dev->scl_wait_us, i2c_master->base->clk_src_freq_hz);
|
||||
|
||||
i2c_ll_master_set_fractional_divider(hal->dev, 0, 0);
|
||||
i2c_ll_update(hal->dev);
|
||||
|
||||
@ -941,6 +931,19 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(i2c_param_master_config(i2c_master->base, bus_config), err, TAG, "i2c configure parameter failed");
|
||||
|
||||
if (!i2c_master->base->is_lp_i2c) {
|
||||
I2C_CLOCK_SRC_ATOMIC() {
|
||||
i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
}
|
||||
}
|
||||
#if SOC_LP_I2C_SUPPORTED
|
||||
else {
|
||||
LP_I2C_SRC_CLK_ATOMIC() {
|
||||
lp_i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
i2c_master->bus_lock_mux = xSemaphoreCreateBinaryWithCaps(I2C_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(i2c_master->bus_lock_mux, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore");
|
||||
xSemaphoreGive(i2c_master->bus_lock_mux);
|
||||
|
@ -26,9 +26,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_LP_I2C_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#define LP_I2C_SCL_IO 4
|
||||
#define LP_I2C_SDA_IO 5
|
||||
#else
|
||||
#define LP_I2C_SCL_IO 7
|
||||
#define LP_I2C_SDA_IO 6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ESP_SLAVE_ADDR 0x28 /*!< ESP_I2C slave address, you can set any 7bit value */
|
||||
#define TEST_I2C_PORT 0
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/i2s_hal.h"
|
||||
#include "hal/dma_types.h"
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
@ -63,8 +64,12 @@
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
/* The actual max size of DMA buffer is 4095
|
||||
* Set 4092 here to align with 4-byte, so that the position of the slot data in the buffer will be relatively fixed */
|
||||
#define I2S_DMA_BUFFER_MAX_SIZE (4092)
|
||||
* Reserve several bytes for alignment, so that the position of the slot data in the buffer will be relatively fixed */
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#define I2S_DMA_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED
|
||||
#else
|
||||
#define I2S_DMA_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED
|
||||
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
|
||||
static const char *TAG = "i2s_common";
|
||||
|
||||
@ -366,7 +371,7 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin
|
||||
for (int sign = 1; bufsize % alignment != 0; aligned_frame_num += sign) {
|
||||
bufsize = aligned_frame_num * bytes_per_frame;
|
||||
/* If the buffer size exceed the max dma size */
|
||||
if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) {
|
||||
if (bufsize > I2S_DMA_BUFFER_MAX_SIZE && sign == 1) {
|
||||
sign = -1; // toggle the search sign
|
||||
aligned_frame_num = dma_frame_num; // Reset the frame num
|
||||
bufsize = aligned_frame_num * bytes_per_frame; // Reset the bufsize
|
||||
@ -377,7 +382,7 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin
|
||||
", bufsize = %"PRIu32, bufsize / bytes_per_frame, alignment, bufsize);
|
||||
}
|
||||
#endif
|
||||
/* Limit DMA buffer size if it is out of range (DMA buffer limitation is 4092 bytes) */
|
||||
/* Limit DMA buffer size if it is out of range */
|
||||
if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) {
|
||||
uint32_t frame_num = I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame;
|
||||
bufsize = frame_num * bytes_per_frame;
|
||||
@ -727,7 +732,7 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
|
||||
if (handle->dir == I2S_DIR_TX) {
|
||||
dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX;
|
||||
/* Register a new GDMA tx channel */
|
||||
ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error");
|
||||
ESP_GOTO_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), err1, TAG, "Connect tx dma channel error");
|
||||
gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback};
|
||||
/* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */
|
||||
@ -735,7 +740,7 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
|
||||
} else {
|
||||
dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX;
|
||||
/* Register a new GDMA rx channel */
|
||||
ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error");
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error");
|
||||
ESP_GOTO_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), err1, TAG, "Connect rx dma channel error");
|
||||
gdma_rx_event_callbacks_t cb = {.on_recv_eof = i2s_dma_rx_callback};
|
||||
/* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */
|
||||
|
@ -39,6 +39,9 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std
|
||||
clk_info->bclk = rate * handle->total_slot * slot_bits;
|
||||
clk_info->mclk = rate * clk_cfg->mclk_multiple;
|
||||
clk_info->bclk_div = clk_info->mclk / clk_info->bclk;
|
||||
if (clk_info->mclk % clk_info->bclk != 0) {
|
||||
ESP_LOGW(TAG, "the current mclk multiple cannot perform integer division (slot_num: %"PRIu32", slot_bits: %"PRIu32")", handle->total_slot, slot_bits);
|
||||
}
|
||||
} else {
|
||||
/* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */
|
||||
clk_info->bclk_div = 8;
|
||||
|
@ -46,6 +46,9 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm
|
||||
clk_info->mclk = clk_info->bclk * clk_info->bclk_div;
|
||||
ESP_LOGW(TAG, "the current mclk multiple is too small, adjust the mclk multiple to %"PRIu32, clk_info->mclk / rate);
|
||||
}
|
||||
if (clk_info->mclk % clk_info->bclk != 0) {
|
||||
ESP_LOGW(TAG, "the current mclk multiple cannot perform integer division (slot_num: %"PRIu32", slot_bits: %"PRIu32")", handle->total_slot, slot_bits);
|
||||
}
|
||||
} else {
|
||||
if (clk_cfg->bclk_div < 8) {
|
||||
ESP_LOGW(TAG, "the current bclk division is too small, adjust the bclk division to 8");
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/dma_types.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_attr.h"
|
||||
@ -841,17 +842,25 @@ TEST_CASE("I2S_package_lost_test", "[i2s]")
|
||||
{
|
||||
/* Steps of calculate appropriate parameters of I2S buffer:
|
||||
* Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms
|
||||
* 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092
|
||||
* dma_frame_num <= 511, dma_frame_num is as big as possible.
|
||||
* 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= DMA_MAX_ALIGNED_SIZE
|
||||
* dma_frame_num <= DMA_MAX_ALIGNED_SIZE / data_bit_width / slot_num * 8, dma_frame_num is as big as possible.
|
||||
* interrupt_interval = dma_frame_num / sample_rate = 3.549 ms
|
||||
* 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3
|
||||
* 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */
|
||||
#define TEST_RECV_BUF_LEN 12276
|
||||
* 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * DMA_MAX_ALIGNED_SIZE */
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#define TEST_RECV_BUF_LEN (3 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED)
|
||||
#else
|
||||
#define TEST_RECV_BUF_LEN (3 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED)
|
||||
#endif
|
||||
i2s_chan_handle_t rx_handle;
|
||||
|
||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
|
||||
chan_cfg.dma_desc_num = 3;
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
chan_cfg.dma_frame_num = 504;
|
||||
#else
|
||||
chan_cfg.dma_frame_num = 511;
|
||||
#endif
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
|
||||
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
|
||||
|
@ -14,17 +14,26 @@ if(CONFIG_SOC_ISP_SUPPORTED)
|
||||
"src/isp_ccm.c"
|
||||
"src/isp_awb.c"
|
||||
"src/isp_ae.c"
|
||||
"src/isp_gamma.c")
|
||||
"src/isp_gamma.c"
|
||||
"src/isp_hist.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ISP_BF_SUPPORTED)
|
||||
list(APPEND srcs "src/isp_bf.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ISP_DEMOSAIC_SUPPORTED)
|
||||
list(APPEND srcs "src/isp_demosaic.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ISP_SHARPEN_SUPPORTED)
|
||||
list(APPEND srcs "src/isp_sharpen.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ISP_COLOR_SUPPORTED)
|
||||
list(APPEND srcs "src/isp_color.c")
|
||||
endif()
|
||||
|
||||
if(NOT ${target} STREQUAL "linux")
|
||||
list(APPEND requires esp_mm)
|
||||
endif()
|
||||
|
@ -17,4 +17,8 @@
|
||||
#include "driver/isp_awb.h"
|
||||
#include "driver/isp_bf.h"
|
||||
#include "driver/isp_ccm.h"
|
||||
#include "driver/isp_demosaic.h"
|
||||
#include "driver/isp_gamma.h"
|
||||
#include "driver/isp_hist.h"
|
||||
#include "driver/isp_sharpen.h"
|
||||
#include "driver/isp_color.h"
|
||||
|
82
components/esp_driver_isp/include/driver/isp_color.h
Normal file
82
components/esp_driver_isp/include/driver/isp_color.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ISP color configurations
|
||||
*/
|
||||
typedef struct {
|
||||
isp_color_contrast_t color_contrast; /*!< The color contrast value, defines the contrast level of the image,
|
||||
* which controls the difference in luminance between the lightest and darkest parts of the image
|
||||
* Range 0 ~ 1, decimal value should be 0~127, default 1
|
||||
*/
|
||||
isp_color_saturation_t color_saturation; /*!< The color saturation value, controls the intensity of colors in the image,
|
||||
* affecting how vivid or muted the colors appear.
|
||||
* Range 0 ~ 1, decimal value should be 0~127, default 1
|
||||
*/
|
||||
uint32_t color_hue; /*!< The color hue value, based on the color wheel.
|
||||
* 0 degrees represents red, 120 degrees represents green, and 240 degrees represents blue. 360 degrees overlaps with 0 degrees
|
||||
* Range 0 ~ 360, default 0.
|
||||
*/
|
||||
int color_brightness; /*!< The color brightness value.
|
||||
* Range -128 ~ 127, default 0.
|
||||
* Negative range (-128 to -1): Decreases brightness, the smaller the value, the darker the image.
|
||||
* Zero (0): Maintains the original brightness, without adjusting the image's brightness.
|
||||
* Positive range (1 to 127): Increases brightness, the larger the value, the brighter the image.
|
||||
*/
|
||||
} esp_isp_color_config_t;
|
||||
|
||||
/**
|
||||
* @brief ISP Color configuration
|
||||
*
|
||||
* @note After calling this API, Color doesn't take into effect until `esp_isp_color_enable` is called
|
||||
* @note API is ISR available
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
* @param[in] config Color configurations, set NULL to de-configure the ISP Color
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
*/
|
||||
esp_err_t esp_isp_color_configure(isp_proc_handle_t proc, const esp_isp_color_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Enable ISP color function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_color_enable(isp_proc_handle_t proc);
|
||||
|
||||
/**
|
||||
* @brief Disable ISP color function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_color_disable(isp_proc_handle_t proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
bool has_line_end_packet; ///< Enable line end packet
|
||||
uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line
|
||||
uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame
|
||||
int intr_priority; ///< The interrupt priority, range 0~3
|
||||
int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)
|
||||
} esp_isp_processor_cfg_t;
|
||||
|
||||
/**
|
||||
|
72
components/esp_driver_isp/include/driver/isp_demosaic.h
Normal file
72
components/esp_driver_isp/include/driver/isp_demosaic.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ISP Demosaic configurations
|
||||
*/
|
||||
typedef struct {
|
||||
isp_demosaic_grad_ratio_t grad_ratio; /**< Demosaic gradient ratio,
|
||||
- gradient_x * grad_ratio < gradient_y, use interpolation results in X direction
|
||||
- gradient_y * grad_ratio < gradient_x, use interpolation results in Y direction
|
||||
- else use the average results between X and Y
|
||||
*/
|
||||
isp_demosaic_edge_padding_mode_t padding_mode; ///< Demosaic edge padding mode
|
||||
uint8_t padding_data; ///< Demosaic edge padding pixel data
|
||||
uint8_t padding_line_tail_valid_start_pixel; ///< Demosaic edge padding line tail valid start pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid
|
||||
uint8_t padding_line_tail_valid_end_pixel; ///< Demosaic edge padding line tail valid end pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid
|
||||
} esp_isp_demosaic_config_t;
|
||||
|
||||
/**
|
||||
* @brief ISP Demosaic configuration
|
||||
*
|
||||
* @note After calling this API, Demosaic doesn't take into effect until `esp_isp_demosaic_enable` is called
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
* @param[in] config Demosaic configurations, set NULL to de-configure the ISP Demosaic
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
*/
|
||||
esp_err_t esp_isp_demosaic_configure(isp_proc_handle_t proc, const esp_isp_demosaic_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Enable ISP Demosaic function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_demosaic_enable(isp_proc_handle_t proc);
|
||||
|
||||
/**
|
||||
* @brief Disable ISP Demosaic function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_demosaic_disable(isp_proc_handle_t proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
186
components/esp_driver_isp/include/driver/isp_hist.h
Normal file
186
components/esp_driver_isp/include/driver/isp_hist.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ISP Histogram Struct
|
||||
* |<----------------------------- INTERVAL_NUMS = 16 ------------------------------>|
|
||||
* | | | | |
|
||||
* | Segment 0 | Segment 1 | ............ | Segment 15 |
|
||||
* 0 threshold 0 threshold 1 ... threshold 14 255
|
||||
* |<------------------------------------------------------------------------------->|
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Hist controller config
|
||||
*/
|
||||
typedef struct {
|
||||
isp_window_t window; /*!< The sampling window of histogram, see `isp_window_t`*/
|
||||
isp_hist_sampling_mode_t hist_mode; /*!< ISP histogram sampling mode */
|
||||
isp_hist_rgb_coefficient_t rgb_coefficient; /*!< RGB coefficients, adjust the sensitivity to red, geen, and blue colors in the image,
|
||||
only effect when hist_mode is ISP_HIST_SAMPLING_RGB, the sum of all coefficients decimal should be 256**/
|
||||
isp_hist_weight_t window_weight[ISP_HIST_BLOCK_X_NUM * ISP_HIST_BLOCK_Y_NUM]; /*!< Weights of histogram's each subwindows, the sum of all subwindows's weight decimal should be 256*/
|
||||
uint32_t segment_threshold[ISP_HIST_INTERVAL_NUMS]; /*!< Threshold to segment the histogram into intervals, range 0~255 */
|
||||
} esp_isp_hist_config_t;
|
||||
|
||||
/**
|
||||
* @brief New an ISP hist controller
|
||||
*
|
||||
* @param[in] isp_proc ISP Processor handle
|
||||
* @param[in] hist_cfg Pointer to hist config. Refer to ``esp_isp_hist_config_t``.
|
||||
* @param[out] ret_hdl hist controller handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
* - ESP_ERR_INVALID_STATE Invalid state
|
||||
* - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
|
||||
* - ESP_ERR_NO_MEM If out of memory
|
||||
*/
|
||||
esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg, isp_hist_ctlr_t *ret_hdl);
|
||||
|
||||
/**
|
||||
* @brief Delete an ISP hist controller
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_del_hist_controller(isp_hist_ctlr_t hist_ctlr);
|
||||
|
||||
/**
|
||||
* @brief Enable an ISP hist controller
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_hist_controller_enable(isp_hist_ctlr_t hist_ctlr);
|
||||
|
||||
/**
|
||||
* @brief Disable an ISP hist controller
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_hist_controller_disable(isp_hist_ctlr_t hist_ctlr);
|
||||
|
||||
/**
|
||||
* @brief Trigger hist reference statistics for one time and get the result
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
* @param[in] timeout_ms Timeout in millisecond
|
||||
* - timeout_ms < 0: Won't return until finished
|
||||
* - timeout_ms = 0: No timeout, trigger one time statistics and return immediately,
|
||||
* in this case, the result won't be assigned in this function,
|
||||
* but you can get the result in the callback `esp_isp_hist_cbs_t::on_statistics_done`
|
||||
* - timeout_ms > 0: Wait for specified milliseconds, if not finished, then return timeout error
|
||||
* @param[out] out_res hist reference statistics result
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_TIMEOUT Wait for the result timeout
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_hist_controller_get_oneshot_statistics(isp_hist_ctlr_t hist_ctlr, int timeout_ms, isp_hist_result_t *out_res);
|
||||
|
||||
/**
|
||||
* @brief Start hist continuous statistics of the reference in the window
|
||||
* @note This function is an asynchronous and non-block function,
|
||||
* it will start the continuous statistics and return immediately.
|
||||
* You have to register the hist callback and get the result from the callback event data.
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG Null pointer
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_hist_controller_start_continuous_statistics(isp_hist_ctlr_t hist_ctlr);
|
||||
|
||||
/**
|
||||
* @brief Stop hist continuous statistics of the reference in the window
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG Null pointer
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_hist_controller_stop_continuous_statistics(isp_hist_ctlr_t hist_ctlr);
|
||||
|
||||
/**
|
||||
* @brief Event data of callbacks
|
||||
*/
|
||||
typedef struct {
|
||||
isp_hist_result_t hist_result; /*!< The histogram reference statistics result */
|
||||
} esp_isp_hist_evt_data_t;
|
||||
|
||||
/**
|
||||
* @brief Prototype of ISP hist event callback
|
||||
*
|
||||
* @param[in] hist_ctlr ISP hist controller handle
|
||||
* @param[in] edata ISP hist event data
|
||||
* @param[in] user_data User registered context, registered when in `esp_isp_hist_register_event_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task is woken up by this function
|
||||
*/
|
||||
typedef bool (*esp_isp_hist_callback_t)(isp_hist_ctlr_t hist_ctlr, const esp_isp_hist_evt_data_t *edata, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Group of ISP hist callbacks
|
||||
*
|
||||
* @note These callbacks are all running in an ISR environment.
|
||||
* @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
|
||||
* Involved variables should be in internal RAM as well.
|
||||
*/
|
||||
typedef struct {
|
||||
esp_isp_hist_callback_t on_statistics_done; ///< Event callback, invoked when histogram statistic done.
|
||||
} esp_isp_hist_cbs_t;
|
||||
|
||||
/**
|
||||
* @brief Register hist event callbacks
|
||||
*
|
||||
* @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member in
|
||||
* the `cbs` structure to NULL.
|
||||
* @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
|
||||
* Involved variables (including `user_data`) should be in internal RAM as well.
|
||||
*
|
||||
* @param[in] hist_ctlr hist controller handle
|
||||
* @param[in] cbs Group of callback functions
|
||||
* @param[in] user_data User data, which will be delivered to the callback functions directly
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: On success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment
|
||||
*/
|
||||
esp_err_t esp_isp_hist_register_event_callbacks(isp_hist_ctlr_t hist_ctlr, const esp_isp_hist_cbs_t *cbs, void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -18,7 +18,7 @@ extern "C" {
|
||||
* @brief ISP Sharpen configurations
|
||||
*/
|
||||
typedef struct {
|
||||
isp_sharpen_h_freq_coeff h_freq_coeff; ///< High freq pixel sharpeness coeff
|
||||
isp_sharpen_h_freq_coeff_t h_freq_coeff; ///< High freq pixel sharpeness coeff
|
||||
isp_sharpen_m_freq_coeff m_freq_coeff; ///< Medium freq pixel sharpeness coeff
|
||||
uint8_t h_thresh; ///< High threshold, pixel value higher than this threshold will be multiplied by `h_freq_coeff`
|
||||
uint8_t l_thresh; ///< Low threshold, pixel value higher than this threshold but lower than `h_thresh` will be multiplied by `m_freq_coeff`. Pixel value lower than this threshold will be set to 0
|
||||
|
@ -76,6 +76,11 @@ typedef struct isp_awb_controller_t *isp_awb_ctlr_t;
|
||||
*/
|
||||
typedef struct isp_ae_controller_t *isp_ae_ctlr_t;
|
||||
|
||||
/**
|
||||
* @brief Type of ISP HIST controller handle
|
||||
*/
|
||||
typedef struct isp_hist_controller_t *isp_hist_ctlr_t;
|
||||
|
||||
/*---------------------------------------------
|
||||
Event Callbacks
|
||||
----------------------------------------------*/
|
||||
|
@ -68,8 +68,11 @@ typedef struct isp_processor_t {
|
||||
isp_af_ctlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS];
|
||||
isp_awb_ctlr_t awb_ctlr;
|
||||
isp_ae_ctlr_t ae_ctlr;
|
||||
isp_hist_ctlr_t hist_ctlr;
|
||||
isp_fsm_t bf_fsm;
|
||||
isp_fsm_t demosaic_fsm;
|
||||
isp_fsm_t sharpen_fsm;
|
||||
isp_fsm_t color_fsm;
|
||||
esp_isp_evt_cbs_t cbs;
|
||||
void *user_data;
|
||||
|
||||
@ -82,6 +85,7 @@ typedef struct isp_processor_t {
|
||||
uint32_t ae_isr_added: 1;
|
||||
uint32_t awb_isr_added: 1;
|
||||
uint32_t sharp_isr_added: 1;
|
||||
uint32_t hist_isr_added: 1;
|
||||
} isr_users;
|
||||
|
||||
} isp_processor_t;
|
||||
@ -92,6 +96,7 @@ typedef enum {
|
||||
ISP_SUBMODULE_AE,
|
||||
ISP_SUBMODULE_AWB,
|
||||
ISP_SUBMODULE_SHARPEN,
|
||||
ISP_SUBMODULE_HIST,
|
||||
} isp_submodule_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
@ -103,6 +108,7 @@ bool esp_isp_af_isr(isp_proc_handle_t proc, uint32_t af_events);
|
||||
bool esp_isp_ae_isr(isp_proc_handle_t proc, uint32_t ae_events);
|
||||
bool esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events);
|
||||
bool esp_isp_sharpen_isr(isp_proc_handle_t proc, uint32_t sharp_events);
|
||||
bool esp_isp_hist_isr(isp_proc_handle_t proc, uint32_t hist_events);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ archive: libesp_driver_isp.a
|
||||
entries:
|
||||
if ISP_CTRL_FUNC_IN_IRAM = y:
|
||||
isp_sharpen: esp_isp_sharpen_configure (noflash)
|
||||
isp_demosaic: esp_isp_demosaic_configure (noflash)
|
||||
isp_gamma: esp_isp_gamma_configure (noflash)
|
||||
isp_gamma: esp_isp_gamma_fill_curve_points (noflash)
|
||||
|
||||
@ -11,3 +12,4 @@ archive: libhal.a
|
||||
entries:
|
||||
if ISP_CTRL_FUNC_IN_IRAM = y:
|
||||
isp_hal: isp_hal_sharpen_config (noflash)
|
||||
isp_hal: isp_hal_demosaic_config (noflash)
|
||||
|
70
components/esp_driver_isp/src/isp_color.c
Normal file
70
components/esp_driver_isp/src/isp_color.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <sys/lock.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/isp_core.h"
|
||||
#include "driver/isp_color.h"
|
||||
#include "soc/isp_periph.h"
|
||||
#include "esp_private/isp_private.h"
|
||||
|
||||
static const char *TAG = "ISP_COLOR";
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Color
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
esp_err_t esp_isp_color_configure(isp_proc_handle_t proc, const esp_isp_color_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
if (config) {
|
||||
ESP_RETURN_ON_FALSE_ISR(((config->color_contrast.val <= ISP_LL_COLOR_CONTRAST_MAX) &&
|
||||
(config->color_saturation.val <= ISP_LL_COLOR_SATURATION_MAX) &&
|
||||
(config->color_hue <= ISP_LL_COLOR_HUE_MAX) &&
|
||||
(config->color_brightness >= ISP_LL_COLOR_BRIGNTNESS_MIN) &&
|
||||
(config->color_brightness <= ISP_LL_COLOR_BRIGNTNESS_MAX)), ESP_ERR_INVALID_ARG, TAG, "invalid color config");
|
||||
isp_hal_color_cfg_t color_hal_cfg = {
|
||||
.color_contrast = config->color_contrast,
|
||||
.color_saturation = config->color_saturation,
|
||||
.color_hue = config->color_hue,
|
||||
.color_brightness = config->color_brightness,
|
||||
};
|
||||
isp_hal_color_config(&(proc->hal), &color_hal_cfg);
|
||||
} else {
|
||||
isp_hal_color_config(&(proc->hal), NULL);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_color_enable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(proc->color_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "color is enabled already");
|
||||
|
||||
isp_ll_color_clk_enable(proc->hal.hw, true);
|
||||
isp_ll_color_enable(proc->hal.hw, true);
|
||||
proc->color_fsm = ISP_FSM_ENABLE;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_color_disable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(proc->color_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "color isn't enabled yet");
|
||||
|
||||
isp_ll_color_enable(proc->hal.hw, false);
|
||||
isp_ll_color_clk_enable(proc->hal.hw, false);
|
||||
proc->color_fsm = ISP_FSM_INIT;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@ -231,6 +231,7 @@ static void IRAM_ATTR s_isp_isr_dispatcher(void *arg)
|
||||
uint32_t awb_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AWB_MASK);
|
||||
uint32_t ae_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AE_MASK);
|
||||
uint32_t sharp_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_SHARP_MASK);
|
||||
uint32_t hist_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_HIST_MASK);
|
||||
|
||||
bool do_dispatch = false;
|
||||
//Deal with hw events
|
||||
@ -274,7 +275,16 @@ static void IRAM_ATTR s_isp_isr_dispatcher(void *arg)
|
||||
}
|
||||
do_dispatch = false;
|
||||
}
|
||||
if (hist_events) {
|
||||
portENTER_CRITICAL_ISR(&proc->spinlock);
|
||||
do_dispatch = proc->isr_users.hist_isr_added;
|
||||
portEXIT_CRITICAL_ISR(&proc->spinlock);
|
||||
|
||||
if (do_dispatch) {
|
||||
need_yield |= esp_isp_hist_isr(proc, hist_events);
|
||||
}
|
||||
do_dispatch = false;
|
||||
}
|
||||
if (need_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
@ -306,6 +316,9 @@ esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule
|
||||
case ISP_SUBMODULE_SHARPEN:
|
||||
proc->isr_users.sharp_isr_added = true;
|
||||
break;
|
||||
case ISP_SUBMODULE_HIST:
|
||||
proc->isr_users.hist_isr_added = true;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
@ -314,7 +327,7 @@ esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule
|
||||
if (do_alloc) {
|
||||
|
||||
uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(proc->hal.hw);
|
||||
uint32_t intr_st_mask = ISP_LL_EVENT_AF_MASK | ISP_LL_EVENT_AE_MASK | ISP_LL_EVENT_AWB_MASK;
|
||||
uint32_t intr_st_mask = ISP_LL_EVENT_AF_MASK | ISP_LL_EVENT_AE_MASK | ISP_LL_EVENT_AWB_MASK | ISP_LL_EVENT_HIST_MASK;
|
||||
ret = esp_intr_alloc_intrstatus(isp_hw_info.instances[proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | proc->intr_priority, intr_st_reg_addr, intr_st_mask,
|
||||
s_isp_isr_dispatcher, (void *)proc, &proc->intr_hdl);
|
||||
if (ret != ESP_OK) {
|
||||
@ -354,6 +367,9 @@ esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodu
|
||||
case ISP_SUBMODULE_SHARPEN:
|
||||
proc->isr_users.sharp_isr_added = false;
|
||||
break;
|
||||
case ISP_SUBMODULE_HIST:
|
||||
proc->isr_users.hist_isr_added = false;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
66
components/esp_driver_isp/src/isp_demosaic.c
Normal file
66
components/esp_driver_isp/src/isp_demosaic.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <sys/lock.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/isp_core.h"
|
||||
#include "driver/isp_demosaic.h"
|
||||
#include "soc/isp_periph.h"
|
||||
#include "esp_private/isp_private.h"
|
||||
|
||||
static const char *TAG = "ISP_DEMOSAIC";
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Demosaic
|
||||
---------------------------------------------------------------*/
|
||||
esp_err_t esp_isp_demosaic_configure(isp_proc_handle_t proc, const esp_isp_demosaic_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
if (config) {
|
||||
bool valid_padding_setting = (!config->padding_line_tail_valid_end_pixel && !config->padding_line_tail_valid_start_pixel) || (config->padding_line_tail_valid_end_pixel > config->padding_line_tail_valid_start_pixel);
|
||||
ESP_RETURN_ON_FALSE_ISR(valid_padding_setting, ESP_ERR_INVALID_ARG, TAG, "wrong padding line tail valid pixel setting");
|
||||
|
||||
isp_hal_demosaic_cfg_t demosaic_hal_cfg = {
|
||||
.grad_ratio = config->grad_ratio,
|
||||
.padding_mode = config->padding_mode,
|
||||
.padding_data = config->padding_data,
|
||||
.padding_line_tail_valid_start_pixel = config->padding_line_tail_valid_start_pixel,
|
||||
.padding_line_tail_valid_end_pixel = config->padding_line_tail_valid_end_pixel,
|
||||
};
|
||||
isp_hal_demosaic_config(&(proc->hal), &demosaic_hal_cfg);
|
||||
} else {
|
||||
isp_hal_demosaic_config(&(proc->hal), NULL);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_demosaic_enable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(proc->demosaic_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "demosaic is enabled already");
|
||||
|
||||
isp_ll_demosaic_enable(proc->hal.hw, true);
|
||||
proc->demosaic_fsm = ISP_FSM_ENABLE;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_demosaic_disable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(proc->demosaic_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "demosaic isn't enabled yet");
|
||||
|
||||
isp_ll_demosaic_enable(proc->hal.hw, false);
|
||||
proc->demosaic_fsm = ISP_FSM_INIT;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
278
components/esp_driver_isp/src/isp_hist.c
Normal file
278
components/esp_driver_isp/src/isp_hist.c
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <sys/lock.h>
|
||||
#include <stdatomic.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "driver/isp_hist.h"
|
||||
#include "esp_private/isp_private.h"
|
||||
|
||||
typedef struct isp_hist_controller_t {
|
||||
_Atomic isp_fsm_t fsm;
|
||||
portMUX_TYPE spinlock;
|
||||
intr_handle_t intr_handle;
|
||||
isp_proc_handle_t isp_proc;
|
||||
QueueHandle_t evt_que;
|
||||
esp_isp_hist_cbs_t cbs;
|
||||
void *user_data;
|
||||
} isp_hist_controller_t;
|
||||
|
||||
static const char *TAG = "ISP_hist";
|
||||
|
||||
/*---------------------------------------------
|
||||
hist
|
||||
----------------------------------------------*/
|
||||
static esp_err_t s_isp_claim_hist_controller(isp_proc_handle_t isp_proc, isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
assert(isp_proc && hist_ctlr);
|
||||
|
||||
bool found = false;
|
||||
portENTER_CRITICAL(&isp_proc->spinlock);
|
||||
if (!isp_proc->hist_ctlr) {
|
||||
isp_proc->hist_ctlr = hist_ctlr;
|
||||
found = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&isp_proc->spinlock);
|
||||
|
||||
if (!found) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void s_isp_declaim_hist_controller(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
if (hist_ctlr && hist_ctlr->isp_proc) {
|
||||
portENTER_CRITICAL(&hist_ctlr->isp_proc->spinlock);
|
||||
hist_ctlr->isp_proc->hist_ctlr = NULL;
|
||||
portEXIT_CRITICAL(&hist_ctlr->isp_proc->spinlock);
|
||||
}
|
||||
}
|
||||
|
||||
static void s_isp_hist_free_controller(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
if (hist_ctlr) {
|
||||
if (hist_ctlr->intr_handle) {
|
||||
esp_intr_free(hist_ctlr->intr_handle);
|
||||
}
|
||||
if (hist_ctlr->evt_que) {
|
||||
vQueueDeleteWithCaps(hist_ctlr->evt_que);
|
||||
}
|
||||
free(hist_ctlr);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t s_esp_isp_hist_config_hardware(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg)
|
||||
{
|
||||
for (int i = 0; i < SOC_ISP_HIST_INTERVAL_NUMS; i++) {
|
||||
ESP_RETURN_ON_FALSE((hist_cfg->segment_threshold[i] > 0 && hist_cfg->segment_threshold[i] < 256), ESP_ERR_INVALID_ARG, TAG, "invalid segment threshold");
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(hist_cfg->rgb_coefficient.coeff_r.integer == 0 && hist_cfg->rgb_coefficient.coeff_g.integer == 0 && hist_cfg->rgb_coefficient.coeff_b.integer == 0, \
|
||||
ESP_ERR_INVALID_ARG, TAG, "The rgb_coefficient's integer value is bigger than 0");
|
||||
|
||||
int weight_sum = 0;
|
||||
for (int i = 0; i < SOC_ISP_HIST_BLOCK_X_NUMS * SOC_ISP_HIST_BLOCK_Y_NUMS; i++) {
|
||||
ESP_RETURN_ON_FALSE(hist_cfg->window_weight[i].integer == 0, ESP_ERR_INVALID_ARG, TAG, "The subwindow weight's integer value is bigger than -");
|
||||
weight_sum = weight_sum + hist_cfg->window_weight[i].decimal;
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(weight_sum == 256, ESP_ERR_INVALID_ARG, TAG, "The sum of all subwindow weight's decimal value is not 256");
|
||||
|
||||
isp_ll_hist_set_mode(isp_proc->hal.hw, hist_cfg->hist_mode);
|
||||
isp_hal_hist_window_config(&isp_proc->hal, &hist_cfg->window);
|
||||
|
||||
isp_ll_hist_set_subwindow_weight(isp_proc->hal.hw, hist_cfg->window_weight);
|
||||
|
||||
isp_ll_hist_set_segment_threshold(isp_proc->hal.hw, hist_cfg->segment_threshold);
|
||||
if (hist_cfg->hist_mode == ISP_HIST_SAMPLING_RGB) {
|
||||
isp_ll_hist_set_rgb_coefficient(isp_proc->hal.hw, &hist_cfg->rgb_coefficient);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg, isp_hist_ctlr_t *ret_hdl)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
ESP_RETURN_ON_FALSE(isp_proc && hist_cfg && ret_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
isp_hist_ctlr_t hist_ctlr = heap_caps_calloc(1, sizeof(isp_hist_controller_t), ISP_MEM_ALLOC_CAPS);
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr, ESP_ERR_NO_MEM, TAG, "no mem for hist controller");
|
||||
hist_ctlr->evt_que = xQueueCreateWithCaps(1, sizeof(isp_hist_result_t), ISP_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(hist_ctlr->evt_que, ESP_ERR_NO_MEM, err1, TAG, "no mem for hist event queue");
|
||||
|
||||
atomic_init(&hist_ctlr->fsm, ISP_FSM_INIT);
|
||||
hist_ctlr->fsm = ISP_FSM_INIT;
|
||||
hist_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
hist_ctlr->isp_proc = isp_proc;
|
||||
|
||||
// Configure the hardware
|
||||
ESP_GOTO_ON_ERROR(s_esp_isp_hist_config_hardware(isp_proc, hist_cfg), err1, TAG, "configure HIST hardware failed");
|
||||
|
||||
// Claim an hist controller
|
||||
ESP_GOTO_ON_ERROR(s_isp_claim_hist_controller(isp_proc, hist_ctlr), err1, TAG, "no available controller");
|
||||
|
||||
// Register the HIGT ISR
|
||||
ESP_GOTO_ON_ERROR(esp_isp_register_isr(hist_ctlr->isp_proc, ISP_SUBMODULE_HIST), err2, TAG, "fail to register ISR");
|
||||
|
||||
*ret_hdl = hist_ctlr;
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
err2:
|
||||
s_isp_declaim_hist_controller(hist_ctlr);
|
||||
err1:
|
||||
s_isp_hist_free_controller(hist_ctlr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_del_hist_controller(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr && hist_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr->isp_proc->hist_ctlr == hist_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use");
|
||||
|
||||
ESP_RETURN_ON_FALSE(atomic_load(&hist_ctlr->fsm) == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller not in init state");
|
||||
|
||||
// Deregister the HIST ISR
|
||||
ESP_RETURN_ON_FALSE(esp_isp_deregister_isr(hist_ctlr->isp_proc, ISP_SUBMODULE_HIST) == ESP_OK, ESP_FAIL, TAG, "fail to deregister ISR");
|
||||
|
||||
s_isp_declaim_hist_controller(hist_ctlr);
|
||||
s_isp_hist_free_controller(hist_ctlr);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_controller_enable(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr && hist_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
isp_fsm_t expected_fsm = ISP_FSM_INIT;
|
||||
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&hist_ctlr->fsm, &expected_fsm, ISP_FSM_ENABLE),
|
||||
ESP_ERR_INVALID_STATE, TAG, "controller not in init state");
|
||||
|
||||
isp_ll_hist_clk_enable(hist_ctlr->isp_proc->hal.hw, true);
|
||||
isp_ll_enable_intr(hist_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_HIST_MASK, true);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_controller_disable(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr && hist_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
|
||||
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&hist_ctlr->fsm, &expected_fsm, ISP_FSM_INIT),
|
||||
ESP_ERR_INVALID_STATE, TAG, "controller not in enable state");
|
||||
|
||||
isp_ll_enable_intr(hist_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_HIST_MASK, false);
|
||||
isp_ll_hist_clk_enable(hist_ctlr->isp_proc->hal.hw, false);
|
||||
esp_intr_disable(hist_ctlr->intr_handle);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_controller_get_oneshot_statistics(isp_hist_ctlr_t hist_ctlr, int timeout_ms, isp_hist_result_t *out_res)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(hist_ctlr && (out_res || timeout_ms == 0), ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
TickType_t ticks = timeout_ms < 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms);
|
||||
|
||||
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
|
||||
ESP_RETURN_ON_FALSE_ISR(atomic_compare_exchange_strong(&hist_ctlr->fsm, &expected_fsm, ISP_FSM_ONESHOT), ESP_ERR_INVALID_STATE, TAG, "controller is not enabled yet");
|
||||
|
||||
// Reset the queue in case receiving the legacy data in the queue
|
||||
xQueueReset(hist_ctlr->evt_que);
|
||||
// Start the histogram reference statistics and waiting it done
|
||||
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, true);
|
||||
// Wait the statistics to finish and receive the result from the queue
|
||||
if (xQueueReceive(hist_ctlr->evt_que, out_res, ticks) != pdTRUE) {
|
||||
ret = ESP_ERR_TIMEOUT;
|
||||
}
|
||||
// Stop the histogram reference statistics
|
||||
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, false);
|
||||
|
||||
atomic_store(&hist_ctlr->fsm, ISP_FSM_ENABLE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_controller_start_continuous_statistics(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(hist_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
|
||||
ESP_RETURN_ON_FALSE_ISR(atomic_compare_exchange_strong(&hist_ctlr->fsm, &expected_fsm, ISP_FSM_CONTINUOUS), ESP_ERR_INVALID_STATE, TAG, "controller is not enabled yet");
|
||||
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, true);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_controller_stop_continuous_statistics(isp_hist_ctlr_t hist_ctlr)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(hist_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
isp_fsm_t expected_fsm = ISP_FSM_CONTINUOUS;
|
||||
ESP_RETURN_ON_FALSE_ISR(atomic_compare_exchange_strong(&hist_ctlr->fsm, &expected_fsm, ISP_FSM_ENABLE),
|
||||
ESP_ERR_INVALID_STATE, TAG, "controller is not running");
|
||||
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, false);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTR
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
bool IRAM_ATTR esp_isp_hist_isr(isp_proc_handle_t proc, uint32_t hist_events)
|
||||
{
|
||||
bool need_yield = false;
|
||||
|
||||
if (hist_events & ISP_LL_EVENT_HIST_FDONE) {
|
||||
isp_hist_ctlr_t hist_ctlr = proc->hist_ctlr;
|
||||
uint32_t hist_value[ISP_HIST_SEGMENT_NUMS] = {};
|
||||
isp_ll_hist_get_histogram_value(proc->hal.hw, hist_value);
|
||||
// Get the statistics result
|
||||
esp_isp_hist_evt_data_t edata = {};
|
||||
for (int i = 0; i < ISP_HIST_SEGMENT_NUMS; i++) {
|
||||
edata.hist_result.hist_value[i] = hist_value[i];
|
||||
}
|
||||
// Invoke the callback if the callback is registered
|
||||
if (hist_ctlr->cbs.on_statistics_done) {
|
||||
need_yield |= hist_ctlr->cbs.on_statistics_done(hist_ctlr, &edata, hist_ctlr->user_data);
|
||||
}
|
||||
BaseType_t high_task_awake = false;
|
||||
// Send the event data to the queue, overwrite the legacy one if exist
|
||||
xQueueOverwriteFromISR(hist_ctlr->evt_que, &edata.hist_result, &high_task_awake);
|
||||
need_yield |= high_task_awake == pdTRUE;
|
||||
|
||||
}
|
||||
|
||||
return need_yield;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_hist_register_event_callbacks(isp_hist_ctlr_t hist_ctlr, const esp_isp_hist_cbs_t *cbs, void *user_data)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(hist_ctlr && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
ESP_RETURN_ON_FALSE(atomic_load(&hist_ctlr->fsm) == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller not in init state");
|
||||
#if CONFIG_ISP_ISR_IRAM_SAFE
|
||||
if (cbs->on_statistics_done) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_env_change), ESP_ERR_INVALID_ARG, TAG, "on_statistics_done callback not in IRAM");
|
||||
}
|
||||
if (user_data) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
|
||||
}
|
||||
#endif
|
||||
hist_ctlr->cbs.on_statistics_done = cbs->on_statistics_done;
|
||||
hist_ctlr->user_data = user_data;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@ -327,3 +327,124 @@ TEST_CASE("ISP AE controller exhausted allocation", "[isp]")
|
||||
}
|
||||
TEST_ESP_OK(esp_isp_del_processor(isp_proc));
|
||||
}
|
||||
|
||||
static bool test_isp_hist_default_on_statistics_done_cb(isp_hist_ctlr_t hist_ctlr, const esp_isp_hist_evt_data_t *edata, void *user_data)
|
||||
{
|
||||
(void) hist_ctlr;
|
||||
(void) edata;
|
||||
(void) user_data;
|
||||
// Do nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
HIST
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("ISP HIST driver basic function", "[isp]")
|
||||
{
|
||||
esp_isp_processor_cfg_t isp_config = {
|
||||
.clk_hz = 80 * 1000 * 1000,
|
||||
.input_data_source = ISP_INPUT_DATA_SOURCE_CSI,
|
||||
.input_data_color_type = ISP_COLOR_RAW8,
|
||||
.output_data_color_type = ISP_COLOR_RGB565,
|
||||
};
|
||||
isp_proc_handle_t isp_proc = NULL;
|
||||
TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||
TEST_ESP_OK(esp_isp_enable(isp_proc));
|
||||
|
||||
isp_hist_ctlr_t hist_ctlr = NULL;
|
||||
isp_hist_result_t hist_res = {};
|
||||
|
||||
/* Test when sum of weight is not 256 */
|
||||
esp_isp_hist_config_t hist_config_error = {
|
||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||
.window_weight = {
|
||||
{{15, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
},
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_new_hist_controller(isp_proc, &hist_config_error, &hist_ctlr));
|
||||
|
||||
esp_isp_hist_config_t hist_config = {
|
||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||
.window_weight = {
|
||||
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
},
|
||||
};
|
||||
TEST_ESP_OK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
||||
|
||||
/* Register HIST callback */
|
||||
esp_isp_hist_cbs_t hist_cb = {
|
||||
.on_statistics_done = test_isp_hist_default_on_statistics_done_cb,
|
||||
};
|
||||
TEST_ESP_OK(esp_isp_hist_register_event_callbacks(hist_ctlr, &hist_cb, NULL));
|
||||
/* Enabled the hist controller */
|
||||
TEST_ESP_OK(esp_isp_hist_controller_enable(hist_ctlr));
|
||||
/* Start continuous HIST statistics */
|
||||
TEST_ESP_OK(esp_isp_hist_controller_start_continuous_statistics(hist_ctlr));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_isp_hist_controller_get_oneshot_statistics(hist_ctlr, 0, &hist_res));
|
||||
/* Stop continuous HIST statistics */
|
||||
TEST_ESP_OK(esp_isp_hist_controller_stop_continuous_statistics(hist_ctlr));
|
||||
TEST_ESP_ERR(ESP_ERR_TIMEOUT, esp_isp_hist_controller_get_oneshot_statistics(hist_ctlr, 1, &hist_res));
|
||||
/* Disable the hist controller */
|
||||
TEST_ESP_OK(esp_isp_hist_controller_disable(hist_ctlr));
|
||||
/* Delete the hist controller and free the resources */
|
||||
TEST_ESP_OK(esp_isp_del_hist_controller(hist_ctlr));
|
||||
|
||||
TEST_ESP_OK(esp_isp_disable(isp_proc));
|
||||
TEST_ESP_OK(esp_isp_del_processor(isp_proc));
|
||||
}
|
||||
|
||||
TEST_CASE("ISP HIST controller exhausted allocation", "[isp]")
|
||||
{
|
||||
esp_isp_processor_cfg_t isp_config = {
|
||||
.clk_hz = 80 * 1000 * 1000,
|
||||
.input_data_source = ISP_INPUT_DATA_SOURCE_CSI,
|
||||
.input_data_color_type = ISP_COLOR_RAW8,
|
||||
.output_data_color_type = ISP_COLOR_RGB565,
|
||||
};
|
||||
isp_proc_handle_t isp_proc = NULL;
|
||||
TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||
|
||||
esp_isp_hist_config_t hist_config = {
|
||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||
.window_weight = {
|
||||
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||
},
|
||||
};
|
||||
|
||||
isp_hist_ctlr_t hist_ctlr[SOC_ISP_HIST_CTLR_NUMS + 1] = {};
|
||||
for (int i = 0; i < SOC_ISP_HIST_CTLR_NUMS; i++) {
|
||||
TEST_ESP_OK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr[i]));
|
||||
}
|
||||
|
||||
TEST_ASSERT(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr[SOC_ISP_HIST_CTLR_NUMS]) == ESP_ERR_NOT_FOUND);
|
||||
|
||||
for (int i = 0; i < SOC_ISP_HIST_CTLR_NUMS; i++) {
|
||||
TEST_ESP_OK(esp_isp_del_hist_controller(hist_ctlr[i]));
|
||||
}
|
||||
TEST_ESP_OK(esp_isp_del_processor(isp_proc));
|
||||
}
|
||||
|
@ -17,4 +17,5 @@ endif()
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${public_include}
|
||||
PRIV_REQUIRES "${priv_requires}"
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
||||
|
6
components/esp_driver_parlio/linker.lf
Normal file
6
components/esp_driver_parlio/linker.lf
Normal file
@ -0,0 +1,6 @@
|
||||
[mapping:parlio_driver_gdma]
|
||||
archive: libesp_hw_support.a
|
||||
entries:
|
||||
if PARLIO_ISR_IRAM_SAFE:
|
||||
gdma_link: gdma_link_mount_buffers (noflash)
|
||||
gdma_link: gdma_link_get_head_addr (noflash)
|
@ -34,6 +34,7 @@
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_private/gdma.h"
|
||||
#include "esp_private/gdma_link.h"
|
||||
|
||||
static const char *TAG = "parlio-tx";
|
||||
|
||||
@ -49,8 +50,7 @@ typedef struct parlio_tx_unit_t {
|
||||
intr_handle_t intr; // allocated interrupt handle
|
||||
esp_pm_lock_handle_t pm_lock; // power management lock
|
||||
gdma_channel_handle_t dma_chan; // DMA channel
|
||||
parlio_dma_desc_t *dma_nodes; // DMA descriptor nodes
|
||||
parlio_dma_desc_t *dma_nodes_nc;// non-cached DMA descriptor nodes
|
||||
gdma_link_list_handle_t dma_link; // DMA link list handle
|
||||
size_t dma_nodes_num; // number of DMA descriptor nodes
|
||||
#if CONFIG_PM_ENABLE
|
||||
char pm_lock_name[PARLIO_PM_LOCK_NAME_LEN_MAX]; // pm lock name
|
||||
@ -123,8 +123,8 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
|
||||
// de-register from group
|
||||
parlio_unregister_unit_from_group(&tx_unit->base);
|
||||
}
|
||||
if (tx_unit->dma_nodes) {
|
||||
free(tx_unit->dma_nodes);
|
||||
if (tx_unit->dma_link) {
|
||||
ESP_RETURN_ON_ERROR(gdma_del_link_list(tx_unit->dma_link), TAG, "delete dma link list failed");
|
||||
}
|
||||
free(tx_unit);
|
||||
return ESP_OK;
|
||||
@ -191,11 +191,19 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit)
|
||||
};
|
||||
gdma_apply_strategy(tx_unit->dma_chan, &gdma_strategy_conf);
|
||||
|
||||
// Link the descriptors
|
||||
// create DMA link list
|
||||
size_t dma_nodes_num = tx_unit->dma_nodes_num;
|
||||
for (int i = 0; i < dma_nodes_num; i++) {
|
||||
tx_unit->dma_nodes_nc[i].next = (i == dma_nodes_num - 1) ? NULL : &(tx_unit->dma_nodes[i + 1]);
|
||||
}
|
||||
gdma_link_list_config_t dma_link_config = {
|
||||
.buffer_alignment = 1,
|
||||
.item_alignment = PARLIO_DMA_DESC_ALIGNMENT,
|
||||
.num_items = dma_nodes_num,
|
||||
.flags = {
|
||||
.check_owner = true,
|
||||
},
|
||||
};
|
||||
|
||||
// throw the error to the caller
|
||||
ESP_RETURN_ON_ERROR(gdma_new_link_list(&dma_link_config, &tx_unit->dma_link), TAG, "create DMA link list failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -280,26 +288,9 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
|
||||
|
||||
// create DMA descriptors
|
||||
// DMA descriptors must be placed in internal SRAM
|
||||
mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
|
||||
size_t dma_nodes_num = config->max_transfer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1;
|
||||
uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
// the alignment should meet both the DMA and cache requirement
|
||||
size_t alignment = MAX(data_cache_line_size, PARLIO_DMA_DESC_ALIGNMENT);
|
||||
size_t dma_nodes_mem_size = ALIGN_UP(dma_nodes_num * sizeof(parlio_dma_desc_t), alignment);
|
||||
parlio_dma_desc_t *dma_nodes = heap_caps_aligned_calloc(alignment, 1, dma_nodes_mem_size, mem_caps);
|
||||
ESP_GOTO_ON_FALSE(dma_nodes, ESP_ERR_NO_MEM, err, TAG, "no memory for DMA nodes");
|
||||
unit->dma_nodes = dma_nodes;
|
||||
unit->dma_nodes_num = dma_nodes_num;
|
||||
|
||||
// write back and then invalidate the cached dma_nodes, we will skip the cache (by non-cacheable address) when access the dma_nodes
|
||||
if (data_cache_line_size) {
|
||||
ESP_GOTO_ON_ERROR(esp_cache_msync(dma_nodes, dma_nodes_mem_size,
|
||||
ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE),
|
||||
err, TAG, "cache sync failed");
|
||||
}
|
||||
// we will use the non-cached address to manipulate the DMA descriptor, for simplicity
|
||||
unit->dma_nodes_nc = PARLIO_GET_NON_CACHED_DESC_ADDR(dma_nodes);
|
||||
|
||||
unit->max_transfer_bits = config->max_transfer_size * 8;
|
||||
unit->base.dir = PARLIO_DIR_TX;
|
||||
unit->data_width = data_width;
|
||||
@ -385,27 +376,6 @@ esp_err_t parlio_del_tx_unit(parlio_tx_unit_handle_t unit)
|
||||
return parlio_destroy_tx_unit(unit);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR parlio_tx_mount_dma_data(parlio_tx_unit_t *tx_unit, const void *buffer, size_t len)
|
||||
{
|
||||
size_t prepared_length = 0;
|
||||
uint8_t *data = (uint8_t *)buffer;
|
||||
uint32_t mount_bytes = 0;
|
||||
parlio_dma_desc_t *desc_nc = tx_unit->dma_nodes_nc;
|
||||
|
||||
while (len) {
|
||||
assert(desc_nc);
|
||||
mount_bytes = len > PARLIO_MAX_ALIGNED_DMA_BUF_SIZE ? PARLIO_MAX_ALIGNED_DMA_BUF_SIZE : len;
|
||||
len -= mount_bytes;
|
||||
desc_nc->dw0.suc_eof = (len == 0); // whether the last frame
|
||||
desc_nc->dw0.size = mount_bytes;
|
||||
desc_nc->dw0.length = mount_bytes;
|
||||
desc_nc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
|
||||
desc_nc->buffer = &data[prepared_length];
|
||||
desc_nc = PARLIO_GET_NON_CACHED_DESC_ADDR(desc_nc->next);
|
||||
prepared_length += mount_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t parlio_tx_unit_wait_all_done(parlio_tx_unit_handle_t tx_unit, int timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
@ -448,7 +418,15 @@ static void IRAM_ATTR parlio_tx_do_transaction(parlio_tx_unit_t *tx_unit, parlio
|
||||
tx_unit->cur_trans = t;
|
||||
|
||||
// DMA transfer data based on bytes not bits, so convert the bit length to bytes, round up
|
||||
parlio_tx_mount_dma_data(tx_unit, t->payload, (t->payload_bits + 7) / 8);
|
||||
gdma_buffer_mount_config_t mount_config = {
|
||||
.buffer = (void *)t->payload,
|
||||
.length = (t->payload_bits + 7) / 8,
|
||||
.flags = {
|
||||
.mark_eof = true,
|
||||
.mark_final = true, // singly link list, mark final descriptor
|
||||
}
|
||||
};
|
||||
gdma_link_mount_buffers(tx_unit->dma_link, 0, &mount_config, 1, NULL);
|
||||
|
||||
parlio_ll_tx_reset_fifo(hal->regs);
|
||||
PARLIO_RCC_ATOMIC() {
|
||||
@ -457,7 +435,7 @@ static void IRAM_ATTR parlio_tx_do_transaction(parlio_tx_unit_t *tx_unit, parlio
|
||||
parlio_ll_tx_set_idle_data_value(hal->regs, t->idle_value);
|
||||
parlio_ll_tx_set_trans_bit_len(hal->regs, t->payload_bits);
|
||||
|
||||
gdma_start(tx_unit->dma_chan, (intptr_t)tx_unit->dma_nodes);
|
||||
gdma_start(tx_unit->dma_chan, gdma_link_get_head_addr(tx_unit->dma_link));
|
||||
// wait until the data goes from the DMA to TX unit's FIFO
|
||||
while (parlio_ll_tx_is_ready(hal->regs) == false);
|
||||
// turn on the core clock after we start the TX unit
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "test_util_rmt_encoders.h"
|
||||
#include "test_board.h"
|
||||
|
||||
#if SOC_RMT_SUPPORT_SLEEP_RETENTION // TODO: IDF-10917
|
||||
typedef struct {
|
||||
TaskHandle_t task_to_notify;
|
||||
size_t received_symbol_num;
|
||||
@ -146,7 +147,6 @@ static void test_rmt_tx_rx_sleep_retention(bool back_up_before_sleep)
|
||||
TEST_CASE("rmt tx+rx after light sleep", "[rmt]")
|
||||
{
|
||||
test_rmt_tx_rx_sleep_retention(false);
|
||||
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
|
||||
test_rmt_tx_rx_sleep_retention(true);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -94,6 +94,7 @@ esp_err_t sdmmc_host_init(void);
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if host has not been initialized using sdmmc_host_init
|
||||
* - ESP_ERR_INVALID_ARG if GPIO pins from slot_config are not valid
|
||||
*/
|
||||
esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config);
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "esp_timer.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_pins.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
@ -28,6 +27,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/sdmmc_hal.h"
|
||||
#include "hal/sd_types.h"
|
||||
#include "hal/sdmmc_ll.h"
|
||||
|
||||
#define SDMMC_EVENT_QUEUE_LENGTH 32
|
||||
@ -46,12 +46,19 @@
|
||||
#define SDMMC_CLK_SRC_ATOMIC()
|
||||
#endif
|
||||
|
||||
static const char *TAG = "sdmmc_periph";
|
||||
|
||||
#define SLOT_CHECK(slot_num) \
|
||||
if (slot_num < 0 || slot_num >= SOC_SDMMC_NUM_SLOTS) { \
|
||||
return ESP_ERR_INVALID_ARG; \
|
||||
}
|
||||
|
||||
static const char *TAG = "sdmmc_periph";
|
||||
#define GPIO_NUM_CHECK(_gpio_num) \
|
||||
if (!GPIO_IS_VALID_GPIO(_gpio_num)) { \
|
||||
esp_err_t _err = ESP_ERR_INVALID_ARG; \
|
||||
ESP_LOGE(TAG, "%s: Invalid GPIO number %d, returned 0x%x", __func__, _gpio_num, _err); \
|
||||
return _err; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Slot contexts
|
||||
@ -89,25 +96,35 @@ static host_ctx_t s_host_ctx = {0};
|
||||
#endif
|
||||
|
||||
static void sdmmc_isr(void *arg);
|
||||
static void sdmmc_host_dma_init(void);
|
||||
static esp_err_t sdmmc_host_pullup_en_internal(int slot, int width);
|
||||
static bool sdmmc_host_slot_initialized(int slot);
|
||||
#if SOC_SDMMC_NUM_SLOTS >= 2
|
||||
static void sdmmc_host_change_to_slot(int slot);
|
||||
#endif
|
||||
|
||||
static void s_module_reset(void)
|
||||
{
|
||||
// reset module
|
||||
sdmmc_ll_reset_controller(s_host_ctx.hal.dev);
|
||||
sdmmc_ll_reset_dma(s_host_ctx.hal.dev);
|
||||
sdmmc_ll_reset_fifo(s_host_ctx.hal.dev);
|
||||
}
|
||||
|
||||
static bool s_is_module_reset_done(void)
|
||||
{
|
||||
bool is_done = sdmmc_ll_is_controller_reset_done(s_host_ctx.hal.dev) && sdmmc_ll_is_dma_reset_done(s_host_ctx.hal.dev) && sdmmc_ll_is_fifo_reset_done(s_host_ctx.hal.dev);
|
||||
return is_done;
|
||||
}
|
||||
|
||||
esp_err_t sdmmc_host_reset(void)
|
||||
{
|
||||
// Set reset bits
|
||||
SDMMC.ctrl.controller_reset = 1;
|
||||
SDMMC.ctrl.dma_reset = 1;
|
||||
SDMMC.ctrl.fifo_reset = 1;
|
||||
s_module_reset();
|
||||
|
||||
// Wait for the reset bits to be cleared by hardware
|
||||
int64_t yield_delay_us = 100 * 1000; // initially 100ms
|
||||
int64_t t0 = esp_timer_get_time();
|
||||
int64_t t1 = 0;
|
||||
while (SDMMC.ctrl.controller_reset || SDMMC.ctrl.fifo_reset || SDMMC.ctrl.dma_reset) {
|
||||
while (!s_is_module_reset_done()) {
|
||||
t1 = esp_timer_get_time();
|
||||
if (t1 - t0 > SDMMC_HOST_RESET_TIMEOUT_US) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
@ -180,14 +197,14 @@ static esp_err_t sdmmc_host_clock_update_command(int slot)
|
||||
}
|
||||
// Sending clock update command to the CIU can generate HLE error.
|
||||
// According to the manual, this is okay and we must retry the command.
|
||||
if (SDMMC.rintsts.hle) {
|
||||
SDMMC.rintsts.hle = 1;
|
||||
if (sdmmc_ll_get_interrupt_raw(s_host_ctx.hal.dev) & SDMMC_LL_EVENT_HLE) {
|
||||
sdmmc_ll_clear_interrupt(s_host_ctx.hal.dev, SDMMC_LL_EVENT_HLE);
|
||||
repeat = true;
|
||||
break;
|
||||
}
|
||||
// When the command is accepted by CIU, start_command bit will be
|
||||
// cleared in SDMMC.cmd register.
|
||||
if (SDMMC.cmd.start_command == 0) {
|
||||
if (sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
|
||||
repeat = false;
|
||||
break;
|
||||
}
|
||||
@ -406,7 +423,7 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
|
||||
int64_t yield_delay_us = 100 * 1000; // initially 100ms
|
||||
int64_t t0 = esp_timer_get_time();
|
||||
int64_t t1 = 0;
|
||||
while (SDMMC.cmd.start_command == 1) {
|
||||
while (!sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
|
||||
t1 = esp_timer_get_time();
|
||||
if (t1 - t0 > SDMMC_HOST_START_CMD_TIMEOUT_US) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
@ -416,10 +433,10 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
SDMMC.cmdarg = arg;
|
||||
sdmmc_ll_set_command_arg(s_host_ctx.hal.dev, arg);
|
||||
cmd.card_num = slot;
|
||||
cmd.start_command = 1;
|
||||
SDMMC.cmd = cmd;
|
||||
sdmmc_ll_set_command(s_host_ctx.hal.dev, cmd);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -433,7 +450,7 @@ static void sdmmc_host_intmask_clear_disable(void)
|
||||
static void sdmmc_host_intmask_set_enable(void)
|
||||
{
|
||||
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, 0xffffffff, false);
|
||||
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, SDMMC_LL_INTMASK_DEFAULT, true);
|
||||
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, SDMMC_LL_EVENT_DEFAULT, true);
|
||||
sdmmc_ll_enable_global_interrupt(s_host_ctx.hal.dev, true);
|
||||
}
|
||||
|
||||
@ -463,7 +480,7 @@ esp_err_t sdmmc_host_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "peripheral version %"PRIx32", hardware config %08"PRIx32, SDMMC.verid, SDMMC.hcon.val);
|
||||
ESP_LOGD(TAG, "peripheral version %"PRIx32", hardware config %08"PRIx32, sdmmc_ll_get_version_id(s_host_ctx.hal.dev), sdmmc_ll_get_hw_config_info(s_host_ctx.hal.dev));
|
||||
|
||||
// Clear interrupt status and set interrupt mask to known state
|
||||
sdmmc_host_intmask_clear_disable();
|
||||
@ -492,10 +509,10 @@ esp_err_t sdmmc_host_init(void)
|
||||
sdmmc_host_intmask_set_enable();
|
||||
|
||||
// Disable generation of Busy Clear Interrupt
|
||||
SDMMC.cardthrctl.busy_clr_int_en = 0;
|
||||
sdmmc_ll_enable_busy_clear_interrupt(s_host_ctx.hal.dev, false);
|
||||
|
||||
// Enable DMA
|
||||
sdmmc_host_dma_init();
|
||||
// Init DMA
|
||||
sdmmc_ll_init_dma(s_host_ctx.hal.dev);
|
||||
|
||||
// Initialize transaction handler
|
||||
ret = sdmmc_host_transaction_handler_init();
|
||||
@ -580,6 +597,7 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
||||
|
||||
// Configure pins
|
||||
const sdmmc_slot_info_t *slot_info = &sdmmc_slot_info[slot];
|
||||
sdmmc_slot_io_info_t *slot_gpio = &s_host_ctx.slot_ctx[slot].slot_gpio_num;
|
||||
|
||||
if (slot_width == SDMMC_SLOT_WIDTH_DEFAULT) {
|
||||
slot_width = slot_info->width;
|
||||
@ -587,8 +605,8 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
s_host_ctx.slot_ctx[slot].slot_width = slot_width;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.cd = gpio_cd;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.wp = gpio_wp;
|
||||
slot_gpio->cd = gpio_cd;
|
||||
slot_gpio->wp = gpio_wp;
|
||||
|
||||
bool pin_not_set = s_check_pin_not_set(slot_config);
|
||||
//SD driver behaviour is: all pins not defined == using iomux
|
||||
@ -608,36 +626,36 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
||||
#if SOC_SDMMC_USE_GPIO_MATRIX
|
||||
if (use_gpio_matrix) {
|
||||
/* Save pin configuration for this slot */
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.clk = slot_config->clk;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.cmd = slot_config->cmd;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d0 = slot_config->d0;
|
||||
slot_gpio->clk = slot_config->clk;
|
||||
slot_gpio->cmd = slot_config->cmd;
|
||||
slot_gpio->d0 = slot_config->d0;
|
||||
/* Save d1 even in 1-line mode, it might be needed for SDIO INT line */
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d1 = slot_config->d1;
|
||||
slot_gpio->d1 = slot_config->d1;
|
||||
if (slot_width >= 4) {
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d2 = slot_config->d2;
|
||||
slot_gpio->d2 = slot_config->d2;
|
||||
}
|
||||
/* Save d3 even for 1-line mode, as it needs to be set high */
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d3 = slot_config->d3;
|
||||
slot_gpio->d3 = slot_config->d3;
|
||||
if (slot_width >= 8) {
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d4 = slot_config->d4;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d5 = slot_config->d5;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d6 = slot_config->d6;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d7 = slot_config->d7;
|
||||
slot_gpio->d4 = slot_config->d4;
|
||||
slot_gpio->d5 = slot_config->d5;
|
||||
slot_gpio->d6 = slot_config->d6;
|
||||
slot_gpio->d7 = slot_config->d7;
|
||||
}
|
||||
} else
|
||||
#endif //#if SOC_SDMMC_USE_GPIO_MATRIX
|
||||
{
|
||||
/* init pin configuration for this slot */
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.clk = sdmmc_slot_gpio_num[slot].clk;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.cmd = sdmmc_slot_gpio_num[slot].cmd;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d0 = sdmmc_slot_gpio_num[slot].d0;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d1 = sdmmc_slot_gpio_num[slot].d1;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d2 = sdmmc_slot_gpio_num[slot].d2;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d3 = sdmmc_slot_gpio_num[slot].d3;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d4 = sdmmc_slot_gpio_num[slot].d4;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d5 = sdmmc_slot_gpio_num[slot].d5;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d6 = sdmmc_slot_gpio_num[slot].d6;
|
||||
s_host_ctx.slot_ctx[slot].slot_gpio_num.d7 = sdmmc_slot_gpio_num[slot].d7;
|
||||
slot_gpio->clk = sdmmc_slot_gpio_num[slot].clk;
|
||||
slot_gpio->cmd = sdmmc_slot_gpio_num[slot].cmd;
|
||||
slot_gpio->d0 = sdmmc_slot_gpio_num[slot].d0;
|
||||
slot_gpio->d1 = sdmmc_slot_gpio_num[slot].d1;
|
||||
slot_gpio->d2 = sdmmc_slot_gpio_num[slot].d2;
|
||||
slot_gpio->d3 = sdmmc_slot_gpio_num[slot].d3;
|
||||
slot_gpio->d4 = sdmmc_slot_gpio_num[slot].d4;
|
||||
slot_gpio->d5 = sdmmc_slot_gpio_num[slot].d5;
|
||||
slot_gpio->d6 = sdmmc_slot_gpio_num[slot].d6;
|
||||
slot_gpio->d7 = sdmmc_slot_gpio_num[slot].d7;
|
||||
}
|
||||
|
||||
bool pullup = slot_config->flags & SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||
@ -645,30 +663,49 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
||||
sdmmc_host_pullup_en_internal(slot, s_host_ctx.slot_ctx[slot].slot_width);
|
||||
}
|
||||
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.clk, sdmmc_slot_gpio_sig[slot].clk, GPIO_MODE_OUTPUT, "clk", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.cmd, sdmmc_slot_gpio_sig[slot].cmd, GPIO_MODE_INPUT_OUTPUT, "cmd", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d0, sdmmc_slot_gpio_sig[slot].d0, GPIO_MODE_INPUT_OUTPUT, "d0", use_gpio_matrix);
|
||||
|
||||
if (slot_width >= 1) {
|
||||
GPIO_NUM_CHECK(slot_gpio->clk);
|
||||
GPIO_NUM_CHECK(slot_gpio->cmd);
|
||||
GPIO_NUM_CHECK(slot_gpio->d0);
|
||||
}
|
||||
if (slot_width >= 4) {
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d1, sdmmc_slot_gpio_sig[slot].d1, GPIO_MODE_INPUT_OUTPUT, "d1", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d2, sdmmc_slot_gpio_sig[slot].d2, GPIO_MODE_INPUT_OUTPUT, "d2", use_gpio_matrix);
|
||||
// Force D3 high to make slave enter SD mode.
|
||||
// Connect to peripheral after width configuration.
|
||||
gpio_config_t gpio_conf = {
|
||||
.pin_bit_mask = BIT64(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = 0,
|
||||
.pull_down_en = 0,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
gpio_config(&gpio_conf);
|
||||
gpio_set_level(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3, 1);
|
||||
GPIO_NUM_CHECK(slot_gpio->d1);
|
||||
GPIO_NUM_CHECK(slot_gpio->d2);
|
||||
GPIO_NUM_CHECK(slot_gpio->d3);
|
||||
}
|
||||
if (slot_width == 8) {
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d4, sdmmc_slot_gpio_sig[slot].d4, GPIO_MODE_INPUT_OUTPUT, "d4", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d5, sdmmc_slot_gpio_sig[slot].d5, GPIO_MODE_INPUT_OUTPUT, "d5", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d6, sdmmc_slot_gpio_sig[slot].d6, GPIO_MODE_INPUT_OUTPUT, "d6", use_gpio_matrix);
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d7, sdmmc_slot_gpio_sig[slot].d7, GPIO_MODE_INPUT_OUTPUT, "d7", use_gpio_matrix);
|
||||
GPIO_NUM_CHECK(slot_gpio->d4);
|
||||
GPIO_NUM_CHECK(slot_gpio->d5);
|
||||
GPIO_NUM_CHECK(slot_gpio->d6);
|
||||
GPIO_NUM_CHECK(slot_gpio->d7);
|
||||
}
|
||||
|
||||
configure_pin(slot_gpio->clk, sdmmc_slot_gpio_sig[slot].clk, GPIO_MODE_OUTPUT, "clk", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->cmd, sdmmc_slot_gpio_sig[slot].cmd, GPIO_MODE_INPUT_OUTPUT, "cmd", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->d0, sdmmc_slot_gpio_sig[slot].d0, GPIO_MODE_INPUT_OUTPUT, "d0", use_gpio_matrix);
|
||||
|
||||
if (slot_width >= 4) {
|
||||
configure_pin(slot_gpio->d1, sdmmc_slot_gpio_sig[slot].d1, GPIO_MODE_INPUT_OUTPUT, "d1", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->d2, sdmmc_slot_gpio_sig[slot].d2, GPIO_MODE_INPUT_OUTPUT, "d2", use_gpio_matrix);
|
||||
// Force D3 high to make slave enter SD mode.
|
||||
// Connect to peripheral after width configuration.
|
||||
if (slot_gpio->d3 > GPIO_NUM_NC) {
|
||||
gpio_config_t gpio_conf = {
|
||||
.pin_bit_mask = BIT64(slot_gpio->d3),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = 0,
|
||||
.pull_down_en = 0,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
gpio_config(&gpio_conf);
|
||||
gpio_set_level(slot_gpio->d3, 1);
|
||||
}
|
||||
}
|
||||
if (slot_width == 8) {
|
||||
configure_pin(slot_gpio->d4, sdmmc_slot_gpio_sig[slot].d4, GPIO_MODE_INPUT_OUTPUT, "d4", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->d5, sdmmc_slot_gpio_sig[slot].d5, GPIO_MODE_INPUT_OUTPUT, "d5", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->d6, sdmmc_slot_gpio_sig[slot].d6, GPIO_MODE_INPUT_OUTPUT, "d6", use_gpio_matrix);
|
||||
configure_pin(slot_gpio->d7, sdmmc_slot_gpio_sig[slot].d7, GPIO_MODE_INPUT_OUTPUT, "d7", use_gpio_matrix);
|
||||
}
|
||||
|
||||
// SDIO slave interrupt is edge sensitive to ~(int_n | card_int | card_detect)
|
||||
@ -853,17 +890,14 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
|
||||
if (sdmmc_slot_info[slot].width < width) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
const uint16_t mask = BIT(slot);
|
||||
if (width == 1) {
|
||||
SDMMC.ctype.card_width_8 &= ~mask;
|
||||
SDMMC.ctype.card_width &= ~mask;
|
||||
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_1_BIT);
|
||||
} else if (width == 4) {
|
||||
SDMMC.ctype.card_width_8 &= ~mask;
|
||||
SDMMC.ctype.card_width |= mask;
|
||||
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_4_BIT);
|
||||
// D3 was set to GPIO high to force slave into SD mode, until 4-bit mode is set
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3, sdmmc_slot_gpio_sig[slot].d3, GPIO_MODE_INPUT_OUTPUT, "d3", s_host_ctx.slot_ctx[slot].use_gpio_matrix);
|
||||
} else if (width == 8) {
|
||||
SDMMC.ctype.card_width_8 |= mask;
|
||||
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_8_BIT);
|
||||
// D3 was set to GPIO high to force slave into SD mode, until 4-bit mode is set
|
||||
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3, sdmmc_slot_gpio_sig[slot].d3, GPIO_MODE_INPUT_OUTPUT, "d3", s_host_ctx.slot_ctx[slot].use_gpio_matrix);
|
||||
} else {
|
||||
@ -908,22 +942,9 @@ esp_err_t sdmmc_host_set_cclk_always_on(int slot, bool cclk_always_on)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void sdmmc_host_dma_init(void)
|
||||
{
|
||||
SDMMC.ctrl.dma_enable = 1;
|
||||
SDMMC.bmod.val = 0;
|
||||
SDMMC.bmod.sw_reset = 1;
|
||||
SDMMC.idinten.ni = 1;
|
||||
SDMMC.idinten.ri = 1;
|
||||
SDMMC.idinten.ti = 1;
|
||||
}
|
||||
|
||||
void sdmmc_host_dma_stop(void)
|
||||
{
|
||||
SDMMC.ctrl.use_internal_dma = 0;
|
||||
SDMMC.ctrl.dma_reset = 1;
|
||||
SDMMC.bmod.fb = 0;
|
||||
SDMMC.bmod.enable = 0;
|
||||
sdmmc_ll_stop_dma(s_host_ctx.hal.dev);
|
||||
}
|
||||
|
||||
void sdmmc_host_dma_prepare(sdmmc_desc_t *desc, size_t block_size, size_t data_size)
|
||||
@ -945,7 +966,7 @@ void sdmmc_host_dma_resume(void)
|
||||
|
||||
bool sdmmc_host_card_busy(void)
|
||||
{
|
||||
return SDMMC.status.data_busy == 1;
|
||||
return sdmmc_ll_is_card_data_busy(s_host_ctx.hal.dev);
|
||||
}
|
||||
|
||||
esp_err_t sdmmc_host_io_int_enable(int slot)
|
||||
@ -1017,12 +1038,12 @@ static void sdmmc_isr(void *arg)
|
||||
sdmmc_event_t event;
|
||||
int higher_priority_task_awoken = pdFALSE;
|
||||
|
||||
uint32_t pending = sdmmc_ll_get_intr_status(s_host_ctx.hal.dev) & 0xFFFF;
|
||||
SDMMC.rintsts.val = pending;
|
||||
uint32_t pending = sdmmc_ll_get_intr_status(s_host_ctx.hal.dev) & SDMMC_LL_SD_EVENT_MASK;
|
||||
sdmmc_ll_clear_interrupt(s_host_ctx.hal.dev, pending);
|
||||
event.sdmmc_status = pending;
|
||||
|
||||
uint32_t dma_pending = SDMMC.idsts.val;
|
||||
SDMMC.idsts.val = dma_pending;
|
||||
uint32_t dma_pending = sdmmc_ll_get_idsts_interrupt_raw(s_host_ctx.hal.dev);
|
||||
sdmmc_ll_clear_idsts_interrupt(s_host_ctx.hal.dev, dma_pending);
|
||||
event.dma_status = dma_pending & 0x1f;
|
||||
|
||||
if (pending != 0 || dma_pending != 0) {
|
||||
|
@ -33,6 +33,14 @@ menu "SDMMC Test Board Configuration"
|
||||
bool "ESP32-P4 Function EV Board"
|
||||
depends on IDF_TARGET_ESP32P4
|
||||
|
||||
config SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI
|
||||
bool "ESP32-P4 Function EV Board with SDSPI breakout"
|
||||
depends on IDF_TARGET_ESP32P4
|
||||
|
||||
config SDMMC_BOARD_ESP32C5_BREAKOUT
|
||||
bool "ESP32-C5 breakout board"
|
||||
depends on IDF_TARGET_ESP32C5
|
||||
|
||||
config SDMMC_BOARD_CUSTOM_SD
|
||||
depends on SOC_SDMMC_HOST_SUPPORTED
|
||||
bool "Custom SD (choose pins)"
|
||||
@ -133,6 +141,8 @@ menu "SDMMC Test Board Configuration"
|
||||
|
||||
config SDMMC_BOARD_CUSTOM_UNUSED
|
||||
int "GPIO not routed on the board"
|
||||
default 34 if IDF_TARGET_ESP32P4
|
||||
default 8 if IDF_TARGET_ESP32C5
|
||||
default -1
|
||||
|
||||
endmenu
|
||||
|
@ -346,6 +346,62 @@ static const sdmmc_test_board_info_t s_board_info = {
|
||||
},
|
||||
};
|
||||
|
||||
#elif CONFIG_SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI
|
||||
|
||||
static const sdmmc_test_board_info_t s_board_info = {
|
||||
.name = "ESP32-P4 Function EV Board with SDSPI breakout",
|
||||
.slot = {
|
||||
{
|
||||
.slot_exists = false
|
||||
},
|
||||
{
|
||||
.slot_exists = true,
|
||||
.bus_width = 1,
|
||||
.clk = 53,
|
||||
.cmd_mosi = 36,
|
||||
.d0_miso = 47,
|
||||
.d1 = GPIO_NUM_NC,
|
||||
.d2 = GPIO_NUM_NC,
|
||||
.d3_cs = 33,
|
||||
.d4 = GPIO_NUM_NC,
|
||||
.d5 = GPIO_NUM_NC,
|
||||
.d6 = GPIO_NUM_NC,
|
||||
.d7 = GPIO_NUM_NC,
|
||||
.cd = CONFIG_SDMMC_BOARD_CUSTOM_CD,
|
||||
.wp = CONFIG_SDMMC_BOARD_CUSTOM_WP,
|
||||
.unused_pin = CONFIG_SDMMC_BOARD_CUSTOM_UNUSED,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#elif CONFIG_SDMMC_BOARD_ESP32C5_BREAKOUT
|
||||
|
||||
static const sdmmc_test_board_info_t s_board_info = {
|
||||
.name = "ESP32-C5 breakout board",
|
||||
.slot = {
|
||||
{
|
||||
.slot_exists = false
|
||||
},
|
||||
{
|
||||
.slot_exists = true,
|
||||
.bus_width = 1,
|
||||
.clk = 5,
|
||||
.cmd_mosi = 4,
|
||||
.d0_miso = 6,
|
||||
.d1 = GPIO_NUM_NC,
|
||||
.d2 = GPIO_NUM_NC,
|
||||
.d3_cs = 1,
|
||||
.d4 = GPIO_NUM_NC,
|
||||
.d5 = GPIO_NUM_NC,
|
||||
.d6 = GPIO_NUM_NC,
|
||||
.d7 = GPIO_NUM_NC,
|
||||
.cd = CONFIG_SDMMC_BOARD_CUSTOM_CD,
|
||||
.wp = CONFIG_SDMMC_BOARD_CUSTOM_WP,
|
||||
.unused_pin = CONFIG_SDMMC_BOARD_CUSTOM_UNUSED,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#elif CONFIG_SDMMC_BOARD_CUSTOM_SD
|
||||
|
||||
static const sdmmc_test_board_info_t s_board_info = {
|
||||
|
@ -6,3 +6,8 @@ set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(sdmmc_test_console)
|
||||
|
||||
message(STATUS "Checking sdmmc registers are not read-write by half-word")
|
||||
include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake)
|
||||
check_register_rw_half_word(SOC_MODULES "sdmmc" "pcr" "hp_sys_clkrst"
|
||||
HAL_MODULES "sdmmc")
|
||||
|
@ -71,6 +71,7 @@ typedef struct {
|
||||
bool gpio_wp_polarity; /*!< GPIO write protect polarity
|
||||
0 means "active low", i.e. card is protected when the GPIO is low;
|
||||
1 means "active high", i.e. card is protected when GPIO is high. */
|
||||
uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
|
||||
} sdspi_device_config_t;
|
||||
|
||||
#define SDSPI_SLOT_NO_CS GPIO_NUM_NC ///< indicates that card select line is not used
|
||||
@ -89,6 +90,7 @@ typedef struct {
|
||||
.gpio_wp = SDSPI_SLOT_NO_WP, \
|
||||
.gpio_int = GPIO_NUM_NC, \
|
||||
.gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW, \
|
||||
.duty_cycle_pos = 0,\
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,7 @@ typedef struct {
|
||||
uint8_t* block_buf;
|
||||
/// semaphore of gpio interrupt
|
||||
SemaphoreHandle_t semphr_int;
|
||||
uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
|
||||
} slot_info_t;
|
||||
|
||||
// Reserved for old API to be back-compatible
|
||||
@ -215,6 +216,7 @@ static esp_err_t configure_spi_dev(slot_info_t *slot, int clock_speed_hz)
|
||||
// rather than a single SPI transaction.
|
||||
.spics_io_num = GPIO_NUM_NC,
|
||||
.queue_size = SDSPI_TRANSACTION_COUNT,
|
||||
.duty_cycle_pos = slot->duty_cycle_pos,
|
||||
};
|
||||
return spi_bus_add_device(slot->host_id, &devcfg, &slot->spi_handle);
|
||||
}
|
||||
@ -337,6 +339,7 @@ esp_err_t sdspi_host_init_device(const sdspi_device_config_t* slot_config, sdspi
|
||||
*slot = (slot_info_t) {
|
||||
.host_id = slot_config->host_id,
|
||||
.gpio_cs = slot_config->gpio_cs,
|
||||
.duty_cycle_pos = slot_config->duty_cycle_pos,
|
||||
};
|
||||
|
||||
// Attach the SD card to the SPI bus
|
||||
|
@ -2,9 +2,8 @@ components/esp_driver_sdspi/test_apps/sdspi:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
disable_test:
|
||||
- if: SOC_GPSPI_SUPPORTED == 1
|
||||
temporary: true
|
||||
reason: will add runners later # TODO: IDF-8747
|
||||
- if: IDF_TARGET not in ["esp32", "esp32s3", "esp32c3", "esp32c5", "esp32p4"]
|
||||
reason: needs special runner, select few typical targets for testing
|
||||
depends_components:
|
||||
- sdmmc
|
||||
- esp_driver_sdspi
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
@ -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
|
||||
*/
|
||||
@ -11,6 +11,8 @@
|
||||
#include "sdmmc_test_board.h"
|
||||
#include "sdmmc_test_begin_end_spi.h"
|
||||
#include "sdmmc_test_cd_wp_common.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
|
||||
TEST_CASE("CD input works in SPI mode", "[sdspi]")
|
||||
{
|
||||
@ -22,6 +24,18 @@ TEST_CASE("CD input works in SPI mode", "[sdspi]")
|
||||
sdmmc_test_board_get_config_sdspi(slot, &config, &bus_config, &dev_config);
|
||||
const int test_gpio = sdmmc_test_board_get_slot_info(slot)->unused_pin;
|
||||
dev_config.gpio_cd = test_gpio;
|
||||
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
#define SDMMC_PWR_LDO_CHANNEL 4
|
||||
sd_pwr_ctrl_ldo_config_t ldo_config = {
|
||||
.ldo_chan_id = SDMMC_PWR_LDO_CHANNEL,
|
||||
};
|
||||
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
|
||||
|
||||
TEST_ESP_OK(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle));
|
||||
config.pwr_ctrl_handle = pwr_ctrl_handle;
|
||||
#endif
|
||||
|
||||
sdmmc_test_board_card_power_set(true);
|
||||
TEST_ESP_OK(spi_bus_initialize(dev_config.host_id, &bus_config, SPI_DMA_CH_AUTO));
|
||||
TEST_ESP_OK(sdspi_host_init());
|
||||
@ -31,9 +45,13 @@ TEST_CASE("CD input works in SPI mode", "[sdspi]")
|
||||
|
||||
sdmmc_test_cd_input(test_gpio, &config);
|
||||
|
||||
TEST_ESP_OK(sdspi_host_remove_device(handle));
|
||||
TEST_ESP_OK(sdspi_host_deinit());
|
||||
TEST_ESP_OK(spi_bus_free(SDSPI_DEFAULT_HOST));
|
||||
sdmmc_test_board_card_power_set(false);
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("WP input works in SPI mode", "[sdspi]")
|
||||
@ -48,6 +66,16 @@ TEST_CASE("WP input works in SPI mode", "[sdspi]")
|
||||
dev_config.gpio_wp = test_gpio;
|
||||
sdmmc_test_board_card_power_set(true);
|
||||
TEST_ESP_OK(spi_bus_initialize(dev_config.host_id, &bus_config, SPI_DMA_CH_AUTO));
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
#define SDMMC_PWR_LDO_CHANNEL 4
|
||||
sd_pwr_ctrl_ldo_config_t ldo_config = {
|
||||
.ldo_chan_id = SDMMC_PWR_LDO_CHANNEL,
|
||||
};
|
||||
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
|
||||
|
||||
TEST_ESP_OK(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle));
|
||||
config.pwr_ctrl_handle = pwr_ctrl_handle;
|
||||
#endif
|
||||
TEST_ESP_OK(sdspi_host_init());
|
||||
TEST_ESP_OK(sdspi_host_init_device(&dev_config, &handle));
|
||||
|
||||
@ -55,7 +83,11 @@ TEST_CASE("WP input works in SPI mode", "[sdspi]")
|
||||
|
||||
sdmmc_test_wp_input(test_gpio, &config);
|
||||
|
||||
TEST_ESP_OK(sdspi_host_remove_device(handle));
|
||||
TEST_ESP_OK(sdspi_host_deinit());
|
||||
TEST_ESP_OK(spi_bus_free(SDSPI_DEFAULT_HOST));
|
||||
sdmmc_test_board_card_power_set(false);
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle));
|
||||
#endif
|
||||
}
|
||||
|
@ -1,7 +1,14 @@
|
||||
# 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_idf import IdfDut
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.sdcard_spimode
|
||||
def test_sdspi(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(reset=True)
|
||||
|
@ -0,0 +1 @@
|
||||
CONFIG_SDMMC_BOARD_ESP32C5_BREAKOUT=y
|
@ -0,0 +1,2 @@
|
||||
CONFIG_SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI=y
|
||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
@ -0,0 +1,2 @@
|
||||
CONFIG_SDMMC_BOARD_ESP32S3_EMMC_TEST=y
|
||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
@ -116,6 +116,7 @@ typedef struct {
|
||||
int data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
|
||||
int data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
|
||||
int data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
|
||||
bool data_io_default_level; ///< Output data IO default level when no transaction.
|
||||
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled.
|
||||
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
|
||||
esp_intr_cpu_affinity_t isr_cpu_id; ///< Select cpu core to register SPI ISR.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user