Compare commits

...

30 Commits

Author SHA1 Message Date
Eric Johnson
f8a984957a
Merge 178cee5833 into 9b3eda0974 2024-09-19 17:37:39 -05:00
Sudeep Mohanty
9b3eda0974 Merge branch 'fix/ringbuf_receives_item_not_yet_sent' into 'master'
Some checks failed
docker / docker (push) Has been cancelled
fix(esp_ringbuf): Fixed a bug where in a no-split buffer received items prematurely

Closes IDFGH-13694

See merge request espressif/esp-idf!33555
2024-09-19 17:07:20 +08:00
Jiang Jiang Jian
6b9242b5c7 Merge branch 'bugfix/fix_some_issues_of_cert_test' into 'master'
fix(phy): update cert_test docs

See merge request espressif/esp-idf!33635
2024-09-19 16:45:38 +08:00
Sudeep Mohanty
86c1ad216c Merge branch 'task/enable_freertos_tests_for_h2' into 'master'
test(freertos): Enabled FreeRTOS unit tests for esp32h2

See merge request espressif/esp-idf!33571
2024-09-19 16:42:22 +08:00
Wan Lei
115dec68ae Merge branch 'fix/p4_twai_enable_test' into 'master'
test(twai): p4 twai enable ci test

Closes IDF-8966

See merge request espressif/esp-idf!33428
2024-09-19 15:17:28 +08:00
muhaidong
da4a0798f4 fix(phy): update cert_test docs 2024-09-19 15:13:15 +08:00
Marius Vikhammer
4c7d9f9859 Merge branch 'contrib/github_pr_14384' into 'master'
fix(pthread): Add esp_pthread function implementations for linux target (GitHub PR)

Closes IDFGH-13485

See merge request espressif/esp-idf!33278
2024-09-19 14:42:59 +08:00
Island
c62555d132 Merge branch 'bugfix/fixed_c6_crash_c2_crash_issue' into 'master'
Bugfix/fixed c6 crash c2 crash issue

Closes BLERP-1024, BLERP-1009, BLERP-1010, IDFCI-2365, and IDFCI-2338

See merge request espressif/esp-idf!33575
2024-09-19 14:34:04 +08:00
Armando (Dou Yiwen)
bff2f9b2dd Merge branch 'change/camera_example_readme_change' into 'master'
example(camera): update some info about camera related examples

See merge request espressif/esp-idf!33637
2024-09-19 14:15:42 +08:00
Armando
79da963c62 example(camera): update some info about camera related examples 2024-09-19 14:09:23 +08:00
Rahul Tank
2a12872d0a Merge branch 'fix/added_a_change_to_print_address_of_advertising_instance' into 'master'
fix(nimble): Added a change to print address of an advertising instance

Closes BLERP-1033

See merge request espressif/esp-idf!33550
2024-09-19 14:08:47 +08:00
Jiang Jiang Jian
b01fd6b026 Merge branch 'feat/bringup_esp32c2_rom_mbedtls_to_formal_feature' into 'master'
feat(mbedtls): bringup esp32c2 rom mbedtls feature to formal

See merge request espressif/esp-idf!33434
2024-09-19 11:18:27 +08:00
Michael (XIAO Xufeng)
534c3288ae Merge branch 'docs/update_examples_in_sdio_slave' into 'master'
docs: Update the application examples in sdio_slave

Closes DOC-8319

See merge request espressif/esp-idf!31994
2024-09-19 11:14:49 +08:00
Armando (Dou Yiwen)
cba8c5d7ca Merge branch 'feat/supported_camera_sc2336_lcd_ek79007' into 'master'
camera: supported camera related example using sc2336 and ek79007

Closes IDFGH-13634

See merge request espressif/esp-idf!33518
2024-09-19 11:10:57 +08:00
Armando
b3ccc09ec3 feat(camera): supported camera related example using sc2336 and ek79007
Closes https://github.com/espressif/esp-idf/issues/14517
2024-09-19 10:47:56 +08:00
wanckl
bf9d01bf2a test(twai): p4 twai enable ci test 2024-09-18 20:56:55 +08:00
Sudeep Mohanty
6a82497bdc fix(esp_ringbuf): Fixed a bug where in a no-split buffer received items prematurely
This commit fixes a bug in the no-split buffer which could receive an
item prematurely if the space on the buffer is acquired until the buffer
is full. The commit also adds a unit test for this scenario.

Closes https://github.com/espressif/esp-idf/issues/14568
2024-09-18 13:39:52 +02:00
Sudeep Mohanty
01f521f3a0 test(freertos): Enabled FreeRTOS unit tests for esp32h2 2024-09-18 12:51:24 +02:00
zwl
4d2c44f511 fix(ble): fixed memory leak issue when using uart hci 2024-09-18 15:39:26 +08:00
zwl
0ef9ecb715 fix(ble): fixed occasional assertion issue when enabling logging on ESP32-C2 2024-09-18 15:39:26 +08:00
zwl
c929a01931 fix(ble): fixed occasional acl data packet loss issue when using UHCI on ESP32-H2 2024-09-18 15:39:26 +08:00
zwl
afe08638a0 fix(ble): fixed occasional crash issue in multi-connect scenarios on ESP32-C6 2024-09-18 15:39:26 +08:00
shreeyash
9725f3af74 fix(nimble): Added a change to print address of an advertising instance 2024-09-16 14:00:21 +05:30
Jakob Hasse
f9e7305efd fix(pthread): configuration functions check for null pointer 2024-09-14 16:42:47 +02:00
Jakob Hasse
7834519af8 refactor(pthread): added esp_pthread unit tests for linux target 2024-09-14 16:42:41 +02:00
Jakob Hasse
0b70e296a0 refactor(pthread): avoid conflict due to two PTHREAD_STACK_MIN declarations 2024-09-14 16:34:20 +02:00
JiangGuangMing
ee9a072c82 feat(mbedtls): bringup rom mbedtls feature to formal 2024-09-13 16:40:20 +08:00
Cristian Funes
08a1e1350c fix(pthread): Add esp_pthread function implementations for linux target 2024-09-11 12:20:32 +02:00
shenmengjing
04168efcaf docs: Update the application examples in sdio_slave 2024-08-29 16:00:13 +08:00
Eric Johnson
178cee5833 lwip: port: freertos: Use libc malloc for all allocations
Mixing lwip and libc allocation functions causes heap failures when
LwIPs MEM_STATS feature is enabled. MEM_STATS uses additional
bookkeeping space that is hidden from the caller. If previously
allocated blocks are free'd without taking this into account the heap
will assert. This commit modifies these calls to consistently use libc
malloc
2023-05-29 15:05:25 -05:00
58 changed files with 690 additions and 322 deletions

View File

@ -676,6 +676,5 @@ mainmenu "Espressif IoT Development Framework Configuration"
- CONFIG_ESPTOOLPY_FLASHFREQ_120M && CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR - CONFIG_ESPTOOLPY_FLASHFREQ_120M && CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
- CONFIG_SPIRAM_SPEED_120M && CONFIG_SPIRAM_MODE_OCT - CONFIG_SPIRAM_SPEED_120M && CONFIG_SPIRAM_MODE_OCT
- CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH - CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
- CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL
- CONFIG_ESP_WIFI_EAP_TLS1_3 - CONFIG_ESP_WIFI_EAP_TLS1_3
- CONFIG_ESP_WIFI_ENABLE_ROAMING_APP - CONFIG_ESP_WIFI_ENABLE_ROAMING_APP

@ -1 +1 @@
Subproject commit e652624750341aca124e9f850e261b0c1ac63529 Subproject commit e5c7ef0bf701d02c2203e26081fdd348d45935e5

@ -1 +1 @@
Subproject commit 44e3d21b8f1b1802a6b5282fab5a1ec314d695a6 Subproject commit 3f15aa1d602aedf510dd9c686b3f7e5ea8a44002

@ -1 +1 @@
Subproject commit 58a293a2b4c305157723908ea29c2776f5803bbc Subproject commit 50f567fff506f63b4d06ebea80d0405fe9e39568

View File

@ -154,7 +154,7 @@ hci_driver_uart_deinit(void)
ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port)); ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port));
if (!s_hci_driver_uart_env.tx_sem) { if (s_hci_driver_uart_env.tx_sem) {
vSemaphoreDelete(s_hci_driver_uart_env.tx_sem); vSemaphoreDelete(s_hci_driver_uart_env.tx_sem);
} }

View File

@ -86,10 +86,6 @@ components/driver/test_apps/touch_sensor_v2:
components/driver/test_apps/twai: components/driver/test_apps/twai:
disable: disable:
- if: SOC_TWAI_SUPPORTED != 1 - if: SOC_TWAI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: test not pass, should be re-enable # TODO: IDF-8966
depends_filepatterns: depends_filepatterns:
- components/driver/twai/**/* - components/driver/twai/**/*
depends_components: depends_components:

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -16,6 +16,9 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_log.h" #include "esp_log.h"
#define TEST_TWAI_TX_PIN 4
#define TEST_TWAI_RX_PIN 5
#if CONFIG_TWAI_ISR_IN_IRAM #if CONFIG_TWAI_ISR_IN_IRAM
static void IRAM_ATTR test_delay_post_cache_disable(void *args) static void IRAM_ATTR test_delay_post_cache_disable(void *args)
{ {
@ -27,7 +30,7 @@ TEST_CASE("twai_listen_only", "[twai]")
{ {
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(4, 5, TWAI_MODE_LISTEN_ONLY); twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TEST_TWAI_TX_PIN, TEST_TWAI_RX_PIN, TWAI_MODE_LISTEN_ONLY);
#if CONFIG_TWAI_ISR_IN_IRAM #if CONFIG_TWAI_ISR_IN_IRAM
g_config.intr_flags |= ESP_INTR_FLAG_IRAM; g_config.intr_flags |= ESP_INTR_FLAG_IRAM;
#endif #endif
@ -60,8 +63,8 @@ TEST_CASE("twai_remote_request", "[twai]")
twai_handle_t bus_handle; twai_handle_t bus_handle;
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(4, 5, TWAI_MODE_NORMAL); twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TEST_TWAI_TX_PIN, TEST_TWAI_RX_PIN, TWAI_MODE_NORMAL);
#if CONFIG_IDF_TARGET_ESP32C6 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4
g_config.controller_id = 1; g_config.controller_id = 1;
#endif #endif
TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &bus_handle)); TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &bus_handle));

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -99,25 +99,27 @@ TEST_CASE("twai_mode_ext_no_ack_250kbps", "[twai-loop-back]")
.extd = true, // Extended Frame Format (29bit ID) .extd = true, // Extended Frame Format (29bit ID)
}; };
printf("install twai driver\r\n");
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) { for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
g_config.controller_id = i; g_config.controller_id = i;
g_config.tx_io = i; g_config.tx_io = i;
g_config.rx_io = i; g_config.rx_io = i;
printf("install twai driver %d\r\n", g_config.controller_id);
TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &twai_buses[i])); TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &twai_buses[i]));
TEST_ESP_OK(twai_start_v2(twai_buses[i])); TEST_ESP_OK(twai_start_v2(twai_buses[i]));
} }
printf("transmit message\r\n");
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) { for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
printf("transmit message from %d\r\n", i);
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
TEST_ESP_OK(twai_transmit_v2(twai_buses[i], &tx_msg, pdMS_TO_TICKS(1000))); TEST_ESP_OK(twai_transmit_v2(twai_buses[i], &tx_msg, pdMS_TO_TICKS(1000)));
} }
printf("receive message\r\n");
twai_message_t rx_msg; twai_message_t rx_msg;
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) { for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
printf("receive message from %d\r\n", i);
TEST_ESP_OK(twai_receive_v2(twai_buses[i], &rx_msg, pdMS_TO_TICKS(1000))); TEST_ESP_OK(twai_receive_v2(twai_buses[i], &rx_msg, pdMS_TO_TICKS(1000)));
TEST_ASSERT_TRUE(rx_msg.data_length_code == 6); TEST_ASSERT_TRUE(rx_msg.data_length_code == 6);
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
TEST_ASSERT_EQUAL(tx_msg.data[i], rx_msg.data[i]); TEST_ASSERT_EQUAL(tx_msg.data[i], rx_msg.data[i]);
} }

View File

@ -1,12 +1,12 @@
# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import logging import logging
import subprocess import subprocess
from time import sleep from time import sleep
import pytest import pytest
from can import Bus, Message from can import Bus
from can import Message
from pytest_embedded import Dut from pytest_embedded import Dut
@ -16,6 +16,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.generic @pytest.mark.generic
@pytest.mark.parametrize( @pytest.mark.parametrize(
'config', 'config',
@ -46,6 +47,7 @@ def fixture_create_socket_can() -> Bus:
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.twai_std @pytest.mark.twai_std
@pytest.mark.parametrize( @pytest.mark.parametrize(
'config', 'config',
@ -79,6 +81,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.twai_std @pytest.mark.twai_std
@pytest.mark.parametrize( @pytest.mark.parametrize(
'config', 'config',

View File

@ -506,6 +506,13 @@ static BaseType_t prvCheckItemAvail(Ringbuffer_t *pxRingbuffer)
return pdFALSE; //Byte buffers do not allow multiple retrievals before return return pdFALSE; //Byte buffers do not allow multiple retrievals before return
} }
if ((pxRingbuffer->xItemsWaiting > 0) && ((pxRingbuffer->pucRead != pxRingbuffer->pucWrite) || (pxRingbuffer->uxRingbufferFlags & rbBUFFER_FULL_FLAG))) { if ((pxRingbuffer->xItemsWaiting > 0) && ((pxRingbuffer->pucRead != pxRingbuffer->pucWrite) || (pxRingbuffer->uxRingbufferFlags & rbBUFFER_FULL_FLAG))) {
// If the ring buffer is a no-split buffer, the read pointer must point to an item that has been written to.
if ((pxRingbuffer->uxRingbufferFlags & (rbBYTE_BUFFER_FLAG | rbALLOW_SPLIT_FLAG)) == 0) {
ItemHeader_t *pxHeader = (ItemHeader_t *)pxRingbuffer->pucRead;
if ((pxHeader->uxItemFlags & rbITEM_WRITTEN_FLAG) == 0) {
return pdFALSE;
}
}
return pdTRUE; //Items/data available for retrieval return pdTRUE; //Items/data available for retrieval
} else { } else {
return pdFALSE; //No items/data available for retrieval return pdFALSE; //No items/data available for retrieval
@ -979,9 +986,6 @@ BaseType_t xRingbufferSendAcquire(RingbufHandle_t xRingbuffer, void **ppvItem, s
if (xItemSize > pxRingbuffer->xMaxItemSize) { if (xItemSize > pxRingbuffer->xMaxItemSize) {
return pdFALSE; //Data will never ever fit in the queue. return pdFALSE; //Data will never ever fit in the queue.
} }
if ((pxRingbuffer->uxRingbufferFlags & rbBYTE_BUFFER_FLAG) && xItemSize == 0) {
return pdTRUE; //Sending 0 bytes to byte buffer has no effect
}
return prvSendAcquireGeneric(pxRingbuffer, NULL, ppvItem, xItemSize, xTicksToWait); return prvSendAcquireGeneric(pxRingbuffer, NULL, ppvItem, xItemSize, xTicksToWait);
} }

View File

@ -723,6 +723,8 @@ size_t continuous_test_string_len(void)
return sizeof(continuous_data); return sizeof(continuous_data);
} }
#if !CONFIG_FREERTOS_UNICORE
void send_to_buffer(RingbufHandle_t buffer, size_t max_item_size) void send_to_buffer(RingbufHandle_t buffer, size_t max_item_size)
{ {
for (int iter = 0; iter < SMP_TEST_ITERATIONS; iter++) { for (int iter = 0; iter < SMP_TEST_ITERATIONS; iter++) {
@ -916,6 +918,8 @@ TEST_CASE("Test static ring buffer SMP", "[esp_ringbuf][linux]")
} }
#endif #endif
#endif //!CONFIG_FREERTOS_UNICORE
/* ------------------------ Test ring buffer 0 Item Size ----------------------- /* ------------------------ Test ring buffer 0 Item Size -----------------------
* The following test case tests that sending/acquiring an item/bytes of 0 size * The following test case tests that sending/acquiring an item/bytes of 0 size
* is permissible. * is permissible.
@ -961,3 +965,80 @@ TEST_CASE("Test ringbuffer 0 item size", "[esp_ringbuf][linux]")
vRingbufferDelete(allow_split_rb); vRingbufferDelete(allow_split_rb);
vRingbufferDelete(byte_rb); vRingbufferDelete(byte_rb);
} }
/* ---------------------------- Test no-split ring buffer SendAquire and SendComplete ---------------------------
* The following test case tests the SendAquire and SendComplete functions of the no-split ring buffer.
*
* The test case will do the following...
* 1) Create a no-split ring buffer.
* 2) Acquire space on the buffer to send an item.
* 3) Send the item to the buffer.
* 4) Verify that the item is received correctly.
* 5) Acquire space on the buffer until the buffer is full.
* 6) Send the items out-of-order to the buffer.
* 7) Verify that the items are not received until the first item is sent.
* 8) Send the first item.
* 9) Verify that the items are received in the correct order.
*/
TEST_CASE("Test no-split buffers always receive items in order", "[esp_ringbuf][linux]")
{
// Create buffer
RingbufHandle_t buffer_handle = xRingbufferCreate(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT);
TEST_ASSERT_MESSAGE(buffer_handle != NULL, "Failed to create ring buffer");
// Acquire space on the buffer to send an item and write to the item
void *item1;
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSendAcquire(buffer_handle, &item1, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS));
*(uint32_t *)item1 = 0x123;
// Send the item to the buffer
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSendComplete(buffer_handle, item1));
// Verify that the item is received correctly
size_t item_size;
uint32_t *received_item = xRingbufferReceive(buffer_handle, &item_size, TIMEOUT_TICKS);
TEST_ASSERT_NOT_NULL(received_item);
TEST_ASSERT_EQUAL(item_size, MEDIUM_ITEM_SIZE);
TEST_ASSERT_EQUAL(*(uint32_t *)received_item, 0x123);
// Return the space to the buffer after receiving the item
vRingbufferReturnItem(buffer_handle, received_item);
// At this point, the buffer should be empty
UBaseType_t items_waiting;
vRingbufferGetInfo(buffer_handle, NULL, NULL, NULL, NULL, &items_waiting);
TEST_ASSERT_MESSAGE(items_waiting == 0, "Incorrect items waiting");
// Acquire space on the buffer until the buffer is full
#define MAX_NUM_ITEMS ( BUFFER_SIZE / ( MEDIUM_ITEM_SIZE + ITEM_HDR_SIZE ) )
void *items[MAX_NUM_ITEMS];
for (int i = 0; i < MAX_NUM_ITEMS; i++) {
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSendAcquire(buffer_handle, &items[i], MEDIUM_ITEM_SIZE, TIMEOUT_TICKS));
TEST_ASSERT_NOT_NULL(items[i]);
*(uint32_t *)items[i] = (0x100 + i);
}
// Verify that the buffer is full by attempting to acquire space for another item
void *another_item;
TEST_ASSERT_EQUAL(pdFALSE, xRingbufferSendAcquire(buffer_handle, &another_item, MEDIUM_ITEM_SIZE, TIMEOUT_TICKS));
// Send the items out-of-order to the buffer. Verify that the items are not received until the first item is sent.
// In this case, we send the items in the reverse order until the first item is sent.
for (int i = MAX_NUM_ITEMS - 1; i > 0; i--) {
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSendComplete(buffer_handle, items[i]));
TEST_ASSERT_NULL(xRingbufferReceive(buffer_handle, &item_size, 0));
}
// Send the first item
TEST_ASSERT_EQUAL(pdTRUE, xRingbufferSendComplete(buffer_handle, items[0]));
// Verify that the items are received in the correct order
for (int i = 0; i < MAX_NUM_ITEMS; i++) {
received_item = xRingbufferReceive(buffer_handle, &item_size, TIMEOUT_TICKS);
TEST_ASSERT_EQUAL(*(uint32_t *)received_item, (0x100 + i));
vRingbufferReturnItem(buffer_handle, received_item);
}
// Cleanup
vRingbufferDelete(buffer_handle);
}

View File

@ -5,20 +5,15 @@ from pytest_embedded import Dut
CONFIGS = [ CONFIGS = [
pytest.param('default', marks=[ pytest.param('default', marks=[pytest.mark.supported_targets,]),
pytest.mark.supported_targets, pytest.param('freertos_options', marks=[pytest.mark.supported_targets]),
pytest.mark.temp_skip_ci(targets=['esp32h2'], reason='test failed')
]),
pytest.param('freertos_options', marks=[
pytest.mark.supported_targets,
pytest.mark.temp_skip_ci(targets=['esp32h2'], reason='test failed')]),
pytest.param('psram', marks=[pytest.mark.esp32]), pytest.param('psram', marks=[pytest.mark.esp32]),
pytest.param('single_core', marks=[pytest.mark.esp32, pytest.mark.esp32p4]), pytest.param('single_core', marks=[pytest.mark.esp32, pytest.mark.esp32p4]),
# TODO: [ESP32C5] IDF-10335 # TODO: [ESP32C5] IDF-10335
# TODO: [ESP32C61] IDF-11146 # TODO: [ESP32C61] IDF-11146
pytest.param('smp', marks=[ pytest.param('smp', marks=[
pytest.mark.supported_targets, pytest.mark.supported_targets,
pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5', 'esp32c61'],
reason='test failed/TBD IDF-8113') reason='test failed/TBD IDF-8113')
]), ]),
] ]

View File

@ -205,7 +205,7 @@ sys_sem_free(sys_sem_t *sem)
err_t err_t
sys_mbox_new(sys_mbox_t *mbox, int size) sys_mbox_new(sys_mbox_t *mbox, int size)
{ {
*mbox = mem_malloc(sizeof(struct sys_mbox_s)); *mbox = malloc(sizeof(struct sys_mbox_s));
if (*mbox == NULL){ if (*mbox == NULL){
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox\n")); LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox\n"));
return ERR_MEM; return ERR_MEM;
@ -504,7 +504,7 @@ sys_thread_sem_free(void* data) // destructor for TLS semaphore
sys_sem_t* sys_sem_t*
sys_thread_sem_init(void) sys_thread_sem_init(void)
{ {
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*)); sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
if (!sem){ if (!sem){
ESP_LOGE(TAG, "thread_sem_init: out of memory"); ESP_LOGE(TAG, "thread_sem_init: out of memory");

View File

@ -1138,7 +1138,7 @@ menu "mbedTLS"
config MBEDTLS_USE_CRYPTO_ROM_IMPL config MBEDTLS_USE_CRYPTO_ROM_IMPL
bool "Use ROM implementation of the crypto algorithm" bool "Use ROM implementation of the crypto algorithm"
depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB && IDF_EXPERIMENTAL_FEATURES depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB
default "n" default "n"
select MBEDTLS_SHA512_C select MBEDTLS_SHA512_C
select MBEDTLS_AES_C select MBEDTLS_AES_C

View File

@ -1,3 +1,2 @@
CONFIG_IDF_TARGET="esp32c2" CONFIG_IDF_TARGET="esp32c2"
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y

View File

@ -63,6 +63,7 @@ esp_pthread_cfg_t esp_pthread_get_default_config(void);
* @return * @return
* - ESP_OK if configuration was successfully set * - ESP_OK if configuration was successfully set
* - ESP_ERR_NO_MEM if out of memory * - ESP_ERR_NO_MEM if out of memory
* - ESP_ERR_INVALID_ARG if cfg is NULL
* - ESP_ERR_INVALID_ARG if stack_size is less than PTHREAD_STACK_MIN * - ESP_ERR_INVALID_ARG if stack_size is less than PTHREAD_STACK_MIN
* - ESP_ERR_INVALID_ARG if stack_alloc_caps does not include MALLOC_CAP_8BIT * - ESP_ERR_INVALID_ARG if stack_alloc_caps does not include MALLOC_CAP_8BIT
*/ */
@ -79,6 +80,7 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg);
* *
* @return * @return
* - ESP_OK if the configuration was available * - ESP_OK if the configuration was available
* - ESP_ERR_INVALID_ARG if p is NULL
* - ESP_ERR_NOT_FOUND if a configuration wasn't previously set * - ESP_ERR_NOT_FOUND if a configuration wasn't previously set
*/ */
esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p); esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p);

View File

@ -7,8 +7,25 @@
* pthread port for Linux build * pthread port for Linux build
*/ */
#include <pthread.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_pthread.h" #include "esp_pthread.h"
#include "esp_heap_caps.h"
#include <string.h> #include <string.h>
#include "freertos/FreeRTOS.h"
static pthread_key_t s_pthread_cfg_key;
static void esp_pthread_cfg_key_destructor(void *value)
{
free(value);
}
static int get_default_pthread_core(void)
{
return CONFIG_PTHREAD_TASK_CORE_DEFAULT == -1 ? tskNO_AFFINITY : CONFIG_PTHREAD_TASK_CORE_DEFAULT;
}
/** /**
* @brief Creates a default pthread configuration based * @brief Creates a default pthread configuration based
@ -24,8 +41,8 @@ esp_pthread_cfg_t esp_pthread_get_default_config(void)
.prio = CONFIG_PTHREAD_TASK_PRIO_DEFAULT, .prio = CONFIG_PTHREAD_TASK_PRIO_DEFAULT,
.inherit_cfg = false, .inherit_cfg = false,
.thread_name = NULL, .thread_name = NULL,
.pin_to_core = 0, .pin_to_core = get_default_pthread_core(),
.stack_alloc_caps = 0, .stack_alloc_caps = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT,
}; };
return cfg; return cfg;
@ -33,11 +50,63 @@ esp_pthread_cfg_t esp_pthread_get_default_config(void)
esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg)
{ {
// Not checking the stack size here since PTHREAD_STACK_MIN has two conflicting declarations on Linux
if (cfg == NULL) {
return ESP_ERR_INVALID_ARG;
}
// 0 is treated as default value, hence change caps to MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL in that case
int heap_caps;
if (cfg->stack_alloc_caps == 0) {
heap_caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL;
} else {
// Check that memory is 8-bit capable
if (!(cfg->stack_alloc_caps & MALLOC_CAP_8BIT)) {
return ESP_ERR_INVALID_ARG;
}
heap_caps = cfg->stack_alloc_caps;
}
/* If a value is already set, update that value */
esp_pthread_cfg_t *p = pthread_getspecific(s_pthread_cfg_key);
if (!p) {
p = malloc(sizeof(esp_pthread_cfg_t));
if (!p) {
return ESP_ERR_NO_MEM;
}
}
*p = *cfg;
p->stack_alloc_caps = heap_caps;
p->stack_size = MAX(p->stack_size, 0x4000); // make sure Linux minimal stack size is respected
int __attribute((unused)) res = pthread_setspecific(s_pthread_cfg_key, p);
assert(res == 0);
return ESP_OK; return ESP_OK;
} }
esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p) esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p)
{ {
if (p == NULL) {
return ESP_ERR_INVALID_ARG;
}
esp_pthread_cfg_t *cfg = pthread_getspecific(s_pthread_cfg_key);
if (cfg) {
*p = *cfg;
return ESP_OK;
}
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
return ESP_ERR_NOT_FOUND; return ESP_ERR_NOT_FOUND;
} }
__attribute__((constructor)) esp_err_t esp_pthread_init(void)
{
if (pthread_key_create(&s_pthread_cfg_key, esp_pthread_cfg_key_destructor) != 0) {
return ESP_ERR_NO_MEM;
}
return ESP_OK;
}

View File

@ -142,6 +142,10 @@ static void pthread_delete(esp_pthread_t *pthread)
/* Call this function to configure pthread stacks in Pthreads */ /* Call this function to configure pthread stacks in Pthreads */
esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg)
{ {
if (cfg == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (cfg->stack_size < PTHREAD_STACK_MIN) { if (cfg->stack_size < PTHREAD_STACK_MIN) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
@ -174,12 +178,16 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg)
p->stack_alloc_caps = heap_caps; p->stack_alloc_caps = heap_caps;
pthread_setspecific(s_pthread_cfg_key, p); pthread_setspecific(s_pthread_cfg_key, p);
return 0; return ESP_OK;
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak")
} }
esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p) esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p)
{ {
if (p == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_RETURN_ON_ERROR(lazy_init_pthread_cfg_key(), TAG, "Failed to initialize pthread key"); ESP_RETURN_ON_ERROR(lazy_init_pthread_cfg_key(), TAG, "Failed to initialize pthread key");
esp_pthread_cfg_t *cfg = pthread_getspecific(s_pthread_cfg_key); esp_pthread_cfg_t *cfg = pthread_getspecific(s_pthread_cfg_key);

View File

@ -4,3 +4,7 @@ components/pthread/test_apps/pthread_psram_tests:
enable: enable:
- if: IDF_TARGET in ["esp32"] - if: IDF_TARGET in ["esp32"]
reason: PSRAM only available on ESP32, S2, S3; code is fairly generic reason: PSRAM only available on ESP32, S2, S3; code is fairly generic
components/pthread/test_apps/pthread_unity_tests:
enable:
- if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4", "esp32s2", "esp32s3", "linux"]

View File

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

View File

@ -1,12 +1,19 @@
set(sources "test_app_main.c" idf_build_get_property(target IDF_TARGET)
"test_pthread.c"
"test_pthread_cond_var.c" set(sources "test_app_main.c" "test_esp_pthread.c")
"test_pthread_local_storage.c" set(priv_requires "pthread" "unity")
"test_pthread_cxx.cpp"
"test_pthread_rwlock.c" if(NOT ${target} STREQUAL "linux")
"test_pthread_semaphore.c") list(APPEND sources "test_pthread.c"
"test_pthread_cond_var.c"
"test_pthread_local_storage.c"
"test_pthread_cxx.cpp"
"test_pthread_rwlock.c"
"test_pthread_semaphore.c")
list(APPEND priv_requires "esp_timer" "test_utils")
endif()
idf_component_register(SRCS ${sources} idf_component_register(SRCS ${sources}
INCLUDE_DIRS "." INCLUDE_DIRS "."
REQUIRES pthread esp_timer test_utils REQUIRES ${priv_requires}
WHOLE_ARCHIVE) WHOLE_ARCHIVE)

View File

@ -1,44 +1,35 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdio.h>
#include <errno.h> #include <errno.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "unity.h" #include "unity.h"
#include "unity_test_runner.h" #include "unity_test_runner.h"
#include "esp_heap_caps.h" #include "unity_test_utils_memory.h"
// Some resources are lazy allocated (e.g. newlib locks), the threshold is left for that case // Some resources are lazy allocated (e.g. newlib locks), the threshold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (-200) #define TEST_MEMORY_LEAK_THRESHOLD (-200)
static size_t before_free_8bit;
static size_t before_free_32bit;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void setUp(void) void setUp(void)
{ {
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); unity_utils_set_leak_level(TEST_MEMORY_LEAK_THRESHOLD);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); unity_utils_record_free_mem();
errno = 0; errno = 0;
} }
void tearDown(void) void tearDown(void)
{ {
#ifndef CONFIG_IDF_TARGET_LINUX // on Linux, we don't check for memory leaks with memory utils
// Add a short delay of 200ms to allow the idle task to free remaining memory // Add a short delay of 200ms to allow the idle task to free remaining memory
vTaskDelay(pdMS_TO_TICKS(200)); vTaskDelay(pdMS_TO_TICKS(200));
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); #endif // CONFIG_IDF_TARGET_LINUX
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT"); unity_utils_evaluate_leaks();
check_leak(before_free_32bit, after_free_32bit, "32BIT");
} }
void app_main(void) void app_main(void)

View File

@ -0,0 +1,95 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <pthread.h>
#include "sdkconfig.h"
#include "esp_pthread.h"
#include "esp_heap_caps.h"
#include "unity.h"
TEST_CASE("esp_pthread_get_default_config creates correct stack memory capabilities", "[cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
// The default must always be internal, 8-bit accessible RAM
TEST_ASSERT_EQUAL_HEX(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, default_config.stack_alloc_caps);
}
TEST_CASE("null pointers are rejected", "[cfg]")
{
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_get_cfg(NULL));
}
TEST_CASE("wrong heap caps are rejected", "[cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&default_config)); // make sure we have saved a known value
// Test the rejection of wrong values
default_config.stack_alloc_caps = MALLOC_CAP_32BIT;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(&default_config));
default_config.stack_alloc_caps = MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(&default_config));
// check that saved values are unaltered
esp_pthread_cfg_t retrieved_config;
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_get_cfg(&retrieved_config));
TEST_ASSERT_EQUAL_HEX(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, retrieved_config.stack_alloc_caps);
}
// On Linux, we silently adjust the stack size since pthread on Linux
// requires a minimum stack size of 0x4000.
#if !CONFIG_IDF_TARGET_LINUX
TEST_CASE("invalid stack size is rejected", "[cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&default_config)); // make sure we have saved a known value
// Test the rejection of wrong values
default_config.stack_size = PTHREAD_STACK_MIN - 1;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(&default_config));
// check that saved values are unaltered
esp_pthread_cfg_t retrieved_config;
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_get_cfg(&retrieved_config));
TEST_ASSERT_EQUAL(CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT, retrieved_config.stack_size);
}
#endif // !CONFIG_IDF_TARGET_LINUX
TEST_CASE("correct memory is accepted", "[cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
default_config.stack_alloc_caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL;
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&default_config));
}
TEST_CASE("configuration is preserved inside pthread", "[cfg]")
{
esp_pthread_cfg_t saved_config;
esp_pthread_cfg_t retrieved_config;
saved_config.stack_size = PTHREAD_STACK_MIN;
saved_config.prio = 5;
saved_config.inherit_cfg = true;
saved_config.thread_name = "test_esp_pthread";
saved_config.pin_to_core = 0;
saved_config.stack_alloc_caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL;
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&saved_config));
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_get_cfg(&retrieved_config));
TEST_ASSERT_EQUAL(saved_config.stack_size, retrieved_config.stack_size);
TEST_ASSERT_EQUAL(saved_config.prio, retrieved_config.prio);
TEST_ASSERT_EQUAL(saved_config.inherit_cfg, retrieved_config.inherit_cfg);
TEST_ASSERT_EQUAL(saved_config.thread_name, retrieved_config.thread_name);
TEST_ASSERT_EQUAL(saved_config.pin_to_core, retrieved_config.pin_to_core);
TEST_ASSERT_EQUAL(saved_config.stack_alloc_caps, retrieved_config.stack_alloc_caps);
esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&cfg));
}

View File

@ -13,33 +13,6 @@
#include "unity.h" #include "unity.h"
TEST_CASE("esp_pthread_get_default_config creates correct stack memory capabilities", "[set_cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
// The default must always be internal, 8-bit accessible RAM
TEST_ASSERT_EQUAL_HEX(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, default_config.stack_alloc_caps);
}
TEST_CASE("wrong heap caps are rejected", "[set_cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
default_config.stack_alloc_caps = MALLOC_CAP_32BIT;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(&default_config));
default_config.stack_alloc_caps = MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_pthread_set_cfg(&default_config));
}
TEST_CASE("correct memory is accepted", "[set_cfg]")
{
esp_pthread_cfg_t default_config = esp_pthread_get_default_config();
default_config.stack_alloc_caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL;
TEST_ASSERT_EQUAL(ESP_OK, esp_pthread_set_cfg(&default_config));
}
static void *compute_square(void *arg) static void *compute_square(void *arg)
{ {
int *num = (int *) arg; int *num = (int *) arg;

View File

@ -62,3 +62,9 @@ def test_pthread_qemu(dut: Dut) -> None:
for case in dut.test_menu: for case in dut.test_menu:
if 'qemu-ignore' not in case.groups and case.type == 'normal': if 'qemu-ignore' not in case.groups and case.type == 'normal':
dut._run_normal_case(case, timeout=75) dut._run_normal_case(case, timeout=75)
@pytest.mark.linux
@pytest.mark.host_test
def test_pthread_linux(dut: Dut) -> None:
dut.run_all_single_board_cases(timeout=120)

View File

@ -280,7 +280,7 @@ There are several ways to use the ``arg`` in the queue parameter:
Application Example Application Example
------------------- -------------------
Slave/master communication: :example:`peripherals/sdio`. - :example:`peripherals/sdio/host` and :example:`peripherals/sdio/slave` demonstrate how to use a host to communicate with an ESP SDIO slave device.
API Reference API Reference
------------- -------------

View File

@ -278,9 +278,9 @@ SDIO 从机驱动程序的相关术语如下:
应用示例 应用示例
------------------- --------
从机/主机通信的相关应用示例请参阅 :example:`peripherals/sdio` - :example:`peripherals/sdio/host`:example:`peripherals/sdio/slave` 演示了如何使用主机与 ESP SDIO 从机进行通信
API 参考 API 参考
------------- -------------

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -105,6 +105,8 @@ ble_multi_adv_set_addr(uint16_t instance)
return rc; return rc;
} }
print_addr(addr.val);
memcpy(&ble_instance_cb[instance].addr, &addr, sizeof(addr)); memcpy(&ble_instance_cb[instance].addr, &addr, sizeof(addr));
return 0; return 0;
} }

View File

@ -6,7 +6,7 @@
## Overview ## Overview
This example demonstrates how to use the esp_driver_cam component to capture camera sensor signals and display it via DSI interface. This example demonstrates how to use the esp_driver_cam component to capture camera sensor signals and display it via DSI interface. This example will auto-detect camera sensors via [ESP camera sensor driver](https://components.espressif.com/components/espressif/esp_cam_sensor/versions/0.5.3) and capture camera sensor signals via CSI interface and display it via DSI interface.
## Usage ## Usage
@ -15,12 +15,19 @@ The subsections below give only absolutely necessary information. For full steps
### Hardware Required ### Hardware Required
This example requires: - OV5647 or SC2336 camera sensor, or other camera sensors
- EK79007 or ILI9881C LCD screen
- OV5647 camera sensor
- ILI9881C LCD screen
- ESP32P4 devkit - ESP32P4 devkit
**Note:** OV5647 has its own ISP functions, whereas SC2336 is a camera sensor without ISP functions. You can use the ESP on-chip ISP functions to tune the image together with the sensor ISP functions, if the image quality is not as expected.
**Note:** For EK79007 you will need to connect following pins:
- 5V - 5V
- GND - GND
- RST_LCD - 3V3
You can also connect camera sensors and LCD screens from other vendors to the ESP chip, you can find corresponding camera or LCD drivers from [ESP Component Registry](https://components.espressif.com), or design your own customized drivers.
GND GND GND GND
┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
@ -40,7 +47,7 @@ This example requires:
│ ├──────────────────────┤ │ DSI DATA 1N │ │ │ ├──────────────────────┤ │ DSI DATA 1N │ │
│ │ │ ├───────────────────────────┤ │ │ │ │ ├───────────────────────────┤ │
│ │ CSI DATA 1N │ ESP32-P4 │ │ │ │ │ CSI DATA 1N │ ESP32-P4 │ │ │
OV5647 ├──────────────────────┤ │ DSI CLK N │ ILI9881C Camera ├──────────────────────┤ │ DSI CLK N │ LCD Screen
│ │ │ ├───────────────────────────┤ │ │ │ │ ├───────────────────────────┤ │
│ │ CSI CLK N │ │ │ │ │ │ CSI CLK N │ │ │ │
│ ├──────────────────────┤ │ DSI CLK P │ │ │ ├──────────────────────┤ │ DSI CLK P │ │
@ -97,6 +104,7 @@ idf.py menuconfig
``` ```
Set CONFIG_CAMERA_OV5647 to y Set CONFIG_CAMERA_OV5647 to y
Set CONFIG_CAMERA_SC2336 to y
``` ```

View File

@ -1,25 +1,48 @@
menu "Example DSI Configuration" menu "Example DSI Configuration"
choice EXAMPLE_LCD_PATTERN
prompt "Select MIPI LCD model"
default EXAMPLE_LCD_PATTERN_EK79007
help
Select LCD controller model.
config EXAMPLE_LCD_PATTERN_EK79007
bool "EK79007"
config EXAMPLE_LCD_PATTERN_ILI9881C
bool "ILI9881C"
endchoice
choice EXAMPLE_MIPI_DSI_DISP_HRES choice EXAMPLE_MIPI_DSI_DISP_HRES
bool "Set MIPI CSI horizontal resolution" bool "Set MIPI CSI horizontal resolution"
default EXAMPLE_MIPI_DSI_DISP_HRES_800 if EXAMPLE_LCD_PATTERN_ILI9881C
default EXAMPLE_MIPI_DSI_DISP_HRES_1024 if EXAMPLE_LCD_PATTERN_EK79007
default EXAMPLE_MIPI_DSI_DISP_HRES_800 default EXAMPLE_MIPI_DSI_DISP_HRES_800
config EXAMPLE_MIPI_DSI_DISP_HRES_800 config EXAMPLE_MIPI_DSI_DISP_HRES_800
bool "800" bool "800"
config EXAMPLE_MIPI_DSI_DISP_HRES_1024
bool "1024"
endchoice endchoice
config EXAMPLE_MIPI_DSI_DISP_HRES config EXAMPLE_MIPI_DSI_DISP_HRES
int int
default 800 if EXAMPLE_MIPI_DSI_DISP_HRES_800 default 800 if EXAMPLE_MIPI_DSI_DISP_HRES_800
default 1024 if EXAMPLE_MIPI_DSI_DISP_HRES_1024
choice EXAMPLE_MIPI_DSI_DISP_VRES choice EXAMPLE_MIPI_DSI_DISP_VRES
bool "Set MIPI CSI vertical resolution" bool "Set MIPI CSI vertical resolution"
default EXAMPLE_MIPI_DSI_DISP_VRES_1280 if EXAMPLE_LCD_PATTERN_ILI9881C
default EXAMPLE_MIPI_DSI_DISP_VRES_600 if EXAMPLE_LCD_PATTERN_EK79007
default EXAMPLE_MIPI_DSI_DISP_VRES_1280 default EXAMPLE_MIPI_DSI_DISP_VRES_1280
config EXAMPLE_MIPI_DSI_DISP_VRES_600
bool "600"
config EXAMPLE_MIPI_DSI_DISP_VRES_1280 config EXAMPLE_MIPI_DSI_DISP_VRES_1280
bool "1280" bool "1280"
endchoice endchoice
config EXAMPLE_MIPI_DSI_DISP_VRES config EXAMPLE_MIPI_DSI_DISP_VRES
int int
default 600 if EXAMPLE_MIPI_DSI_DISP_VRES_600
default 1280 if EXAMPLE_MIPI_DSI_DISP_VRES_1280 default 1280 if EXAMPLE_MIPI_DSI_DISP_VRES_1280
endmenu endmenu

View File

@ -10,10 +10,11 @@
#include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h" #include "esp_lcd_panel_io.h"
#include "esp_lcd_ili9881c.h" #include "esp_lcd_ili9881c.h"
#include "esp_lcd_ek79007.h"
#include "example_dsi_init.h" #include "example_dsi_init.h"
#include "example_dsi_init_config.h" #include "example_dsi_init_config.h"
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer) void example_dsi_resource_alloc(esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
{ {
//---------------DSI resource allocation------------------// //---------------DSI resource allocation------------------//
esp_lcd_dsi_bus_config_t bus_config = { esp_lcd_dsi_bus_config_t bus_config = {
@ -31,16 +32,9 @@ void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp
}; };
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(*mipi_dsi_bus, &dbi_config, mipi_dbi_io)); ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(*mipi_dsi_bus, &dbi_config, mipi_dbi_io));
esp_lcd_panel_dev_config_t lcd_dev_config = {
.bits_per_pixel = 16,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.reset_gpio_num = -1,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(*mipi_dbi_io, &lcd_dev_config, ili9881c_ctrl_panel));
esp_lcd_dpi_panel_config_t dpi_config = { esp_lcd_dpi_panel_config_t dpi_config = {
.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT,
.dpi_clock_freq_mhz = 80, .dpi_clock_freq_mhz = EXAMPLE_MIPI_DSI_DPI_CLK_MHZ,
.virtual_channel = 0, .virtual_channel = 0,
.pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565,
.video_timing = { .video_timing = {
@ -54,17 +48,45 @@ void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp
.vsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_VFP, .vsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_VFP,
}, },
}; };
ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(*mipi_dsi_bus, &dpi_config, mipi_dpi_panel));
#if CONFIG_EXAMPLE_LCD_PATTERN_ILI9881C
ili9881c_vendor_config_t vendor_config = {
.mipi_config = {
.dsi_bus = *mipi_dsi_bus,
.dpi_config = &dpi_config,
.lane_num = 2,
},
};
esp_lcd_panel_dev_config_t lcd_dev_config = {
.reset_gpio_num = -1,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
.vendor_config = &vendor_config,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(*mipi_dbi_io, &lcd_dev_config, mipi_dpi_panel));
#elif CONFIG_EXAMPLE_LCD_PATTERN_EK79007
ek79007_vendor_config_t vendor_config = {
.mipi_config = {
.dsi_bus = *mipi_dsi_bus,
.dpi_config = &dpi_config,
},
};
esp_lcd_panel_dev_config_t lcd_dev_config = {
.reset_gpio_num = -1,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
.vendor_config = &vendor_config,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_ek79007(*mipi_dbi_io, &lcd_dev_config, mipi_dpi_panel));
#endif
ESP_ERROR_CHECK(esp_lcd_dpi_panel_get_frame_buffer(*mipi_dpi_panel, 1, frame_buffer)); ESP_ERROR_CHECK(esp_lcd_dpi_panel_get_frame_buffer(*mipi_dpi_panel, 1, frame_buffer));
} }
void example_dsi_ili9881c_panel_init(esp_lcd_panel_handle_t ili9881c_ctrl_panel) void example_dpi_panel_reset(esp_lcd_panel_handle_t mipi_dpi_panel)
{ {
//---------------DSI Panel Init------------------// //---------------DPI Panel Reset------------------//
ESP_ERROR_CHECK(esp_lcd_panel_reset(ili9881c_ctrl_panel)); ESP_ERROR_CHECK(esp_lcd_panel_reset(mipi_dpi_panel));
ESP_ERROR_CHECK(esp_lcd_panel_init(ili9881c_ctrl_panel));
// turn on display
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(ili9881c_ctrl_panel, true));
} }
void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel) void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel)
@ -73,10 +95,9 @@ void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel)
ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel)); ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel));
} }
void example_dsi_resource_destroy(esp_lcd_panel_handle_t ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel) void example_dsi_resource_destroy(esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel)
{ {
ESP_ERROR_CHECK(esp_lcd_panel_del(mipi_dpi_panel)); ESP_ERROR_CHECK(esp_lcd_panel_del(mipi_dpi_panel));
ESP_ERROR_CHECK(esp_lcd_panel_del(ili9881c_ctrl_panel));
ESP_ERROR_CHECK(esp_lcd_panel_io_del(mipi_dbi_io)); ESP_ERROR_CHECK(esp_lcd_panel_io_del(mipi_dbi_io));
ESP_ERROR_CHECK(esp_lcd_del_dsi_bus(mipi_dsi_bus)); ESP_ERROR_CHECK(esp_lcd_del_dsi_bus(mipi_dsi_bus));
} }

View File

@ -1,4 +1,5 @@
dependencies: dependencies:
esp_lcd_ili9881c: "~0.2.0" esp_lcd_ili9881c: "^1.0.0"
esp_lcd_ek79007: "^1.0.0"
idf: idf:
version: ">=5.3.0" version: ">=5.3.0"

View File

@ -8,7 +8,6 @@
#include "esp_lcd_mipi_dsi.h" #include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_ops.h"
#include "esp_lcd_ili9881c.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -17,20 +16,19 @@ extern "C" {
/** /**
* @brief DSI init function * @brief DSI init function
* *
* @param[out] ili9881c_ctrl_panel ILI9881C panel handle
* @param[out] mipi_dsi_bus MIPI DSI bus handle * @param[out] mipi_dsi_bus MIPI DSI bus handle
* @param[out] mipi_dbi_io MIPI DBI io handle * @param[out] mipi_dbi_io MIPI DBI io handle
* @param[out] mipi_dpi_panel MIPI DPI panel handle * @param[out] mipi_dpi_panel MIPI DPI panel handle
* @param[out] frame_buffer frame buffer * @param[out] frame_buffer frame buffer
*/ */
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer); void example_dsi_resource_alloc(esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer);
/** /**
* @brief DSI ILI9881C panel init function * @brief DPI panel reset function
* *
* @param[in] ili9881c_ctrl_panel ILI9881C panel handle * @param[in] mipi_dpi_panel MIPI DPI panel handle
*/ */
void example_dsi_ili9881c_panel_init(esp_lcd_panel_handle_t ili9881c_ctrl_panel); void example_dpi_panel_reset(esp_lcd_panel_handle_t mipi_dpi_panel);
/** /**
* @brief DPI panel init function * @brief DPI panel init function
@ -42,12 +40,11 @@ void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel);
/** /**
* @brief Destroy DSI related resources * @brief Destroy DSI related resources
* *
* @param[in] ili9881c_ctrl_panel ILI9881C panel handle
* @param[in] mipi_dsi_bus MIPI DSI bus handle * @param[in] mipi_dsi_bus MIPI DSI bus handle
* @param[in] mipi_dbi_io MIPI DBI io handle * @param[in] mipi_dbi_io MIPI DBI io handle
* @param[in] mipi_dpi_panel MIPI DPI panel handle * @param[in] mipi_dpi_panel MIPI DPI panel handle
*/ */
void example_dsi_resource_destroy(esp_lcd_panel_handle_t ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel); void example_dsi_resource_destroy(esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,16 +6,31 @@
#pragma once #pragma once
#include "sdkconfig.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 40 #if CONFIG_EXAMPLE_LCD_PATTERN_ILI9881C
#define EXAMPLE_MIPI_DSI_IMAGE_HBP 140 // FPS = 80000000/(40+140+40+800)/(4+16+16+1280) = 60Hz
#define EXAMPLE_MIPI_DSI_IMAGE_HFP 40 #define EXAMPLE_MIPI_DSI_DPI_CLK_MHZ 80
#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 4 #define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 40
#define EXAMPLE_MIPI_DSI_IMAGE_VBP 16 #define EXAMPLE_MIPI_DSI_IMAGE_HBP 140
#define EXAMPLE_MIPI_DSI_IMAGE_VFP 16 #define EXAMPLE_MIPI_DSI_IMAGE_HFP 40
#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 4
#define EXAMPLE_MIPI_DSI_IMAGE_VBP 16
#define EXAMPLE_MIPI_DSI_IMAGE_VFP 16
#elif CONFIG_EXAMPLE_LCD_PATTERN_EK79007
// FPS = 48000000/(10+120+120+1024)/(1+20+10+600) = 60Hz
#define EXAMPLE_MIPI_DSI_DPI_CLK_MHZ 48
#define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 10
#define EXAMPLE_MIPI_DSI_IMAGE_HBP 120
#define EXAMPLE_MIPI_DSI_IMAGE_HFP 120
#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 1
#define EXAMPLE_MIPI_DSI_IMAGE_VBP 20
#define EXAMPLE_MIPI_DSI_IMAGE_VFP 10
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -0,0 +1,3 @@
idf_component_register(SRCS "example_sensor_init.c"
INCLUDE_DIRS "include"
)

View File

@ -0,0 +1,102 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_err.h"
#include "driver/i2c_master.h"
#include "esp_sccb_intf.h"
#include "esp_sccb_i2c.h"
#include "esp_cam_sensor.h"
#include "esp_cam_sensor_detect.h"
#include "example_sensor_init.h"
#include "example_sensor_init_config.h"
static const char *TAG = "sensor_init";
void example_sensor_init(int i2c_port, i2c_master_bus_handle_t *out_i2c_bus_handle)
{
esp_err_t ret = ESP_FAIL;
//---------------I2C Init------------------//
i2c_master_bus_config_t i2c_bus_conf = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.sda_io_num = EXAMPLE_CAM_SCCB_SDA_IO,
.scl_io_num = EXAMPLE_CAM_SCCB_SCL_IO,
.i2c_port = i2c_port,
.flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t i2c_bus_handle = NULL;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &i2c_bus_handle));
//---------------SCCB Init------------------//
esp_sccb_io_handle_t sccb_io_handle = NULL;
esp_cam_sensor_config_t cam_config = {
.sccb_handle = sccb_io_handle,
.reset_pin = -1,
.pwdn_pin = -1,
.xclk_pin = -1,
.sensor_port = ESP_CAM_SENSOR_MIPI_CSI,
};
esp_cam_sensor_device_t *cam = NULL;
for (esp_cam_sensor_detect_fn_t *p = &__esp_cam_sensor_detect_fn_array_start; p < &__esp_cam_sensor_detect_fn_array_end; ++p) {
sccb_i2c_config_t i2c_config = {
.scl_speed_hz = EXAMPLE_CAM_SCCB_FREQ,
.device_address = p->sccb_addr,
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
};
ESP_ERROR_CHECK(sccb_new_i2c_io(i2c_bus_handle, &i2c_config, &cam_config.sccb_handle));
cam = (*(p->detect))(&cam_config);
if (cam) {
if (p->port != ESP_CAM_SENSOR_MIPI_CSI) {
ESP_LOGE(TAG, "detect a camera sensor with mismatched interface");
return;
}
break;
}
ESP_ERROR_CHECK(esp_sccb_del_i2c_io(cam_config.sccb_handle));
}
if (!cam) {
ESP_LOGE(TAG, "failed to detect camera sensor");
return;
}
esp_cam_sensor_format_array_t cam_fmt_array = {0};
esp_cam_sensor_query_format(cam, &cam_fmt_array);
const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array;
for (int i = 0; i < cam_fmt_array.count; i++) {
ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name);
}
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
for (int i = 0; i < cam_fmt_array.count; i++) {
if (!strcmp(parray[i].name, EXAMPLE_CAM_FORMAT)) {
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
}
}
ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Format set fail");
} else {
ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name);
}
int enable_flag = 1;
// Set sensor output stream
ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Start stream fail");
}
ESP_ERROR_CHECK(ret);
*out_i2c_bus_handle = i2c_bus_handle;
}

View File

@ -0,0 +1,4 @@
dependencies:
espressif/esp_cam_sensor: "^0.5.1"
idf:
version: ">=5.3.0"

View File

@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "driver/i2c_master.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief SCCB Interface and Sensor Init
*
* @param[in] i2c_port I2C port
* @param[out] out_i2c_bus_handle I2C bus handle
*/
void example_sensor_init(int i2c_port, i2c_master_bus_handle_t *out_i2c_bus_handle);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EXAMPLE_CAM_SCCB_FREQ (100000)
#define EXAMPLE_CAM_SCCB_SCL_IO (8)
#define EXAMPLE_CAM_SCCB_SDA_IO (7)
#if CONFIG_EXAMPLE_MIPI_CSI_HRES_800
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
#define EXAMPLE_CAM_FORMAT "MIPI_2lane_24Minput_RAW8_800x640_50fps"
#else
#define EXAMPLE_CAM_FORMAT "MIPI_2lane_24Minput_RAW8_800x1280_50fps"
#endif
#endif
#if CONFIG_EXAMPLE_MIPI_CSI_HRES_1024
#define EXAMPLE_CAM_FORMAT "MIPI_2lane_24Minput_RAW8_1024x600_30fps"
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,4 +1,4 @@
idf_component_register(SRCS "camera_dsi_main.c" idf_component_register(SRCS "camera_dsi_main.c"
INCLUDE_DIRS "." INCLUDE_DIRS "."
REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c dsi_init REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c dsi_init sensor_init
) )

View File

@ -14,20 +14,25 @@ menu "Example Configuration"
choice EXAMPLE_MIPI_CSI_DISP_HRES choice EXAMPLE_MIPI_CSI_DISP_HRES
bool "Set MIPI CSI horizontal resolution" bool "Set MIPI CSI horizontal resolution"
default EXAMPLE_MIPI_CSI_HRES_800 default EXAMPLE_MIPI_CSI_HRES_1024
config EXAMPLE_MIPI_CSI_HRES_800 config EXAMPLE_MIPI_CSI_HRES_800
bool "800" bool "800"
config EXAMPLE_MIPI_CSI_HRES_1024
bool "1024"
endchoice endchoice
config EXAMPLE_MIPI_CSI_DISP_HRES config EXAMPLE_MIPI_CSI_DISP_HRES
int int
default 800 if EXAMPLE_MIPI_CSI_HRES_800 default 800 if EXAMPLE_MIPI_CSI_HRES_800
default 1024 if EXAMPLE_MIPI_CSI_HRES_1024
choice EXAMPLE_MIPI_CSI_DISP_VRES choice EXAMPLE_MIPI_CSI_DISP_VRES
bool "Set MIPI CSI vertical resolution" bool "Set MIPI CSI vertical resolution"
default EXAMPLE_MIPI_CSI_VRES_640 default EXAMPLE_MIPI_CSI_VRES_600
config EXAMPLE_MIPI_CSI_VRES_600
bool "600"
config EXAMPLE_MIPI_CSI_VRES_640 config EXAMPLE_MIPI_CSI_VRES_640
bool "640" bool "640"
config EXAMPLE_MIPI_CSI_VRES_1280 config EXAMPLE_MIPI_CSI_VRES_1280
@ -36,6 +41,7 @@ menu "Example Configuration"
config EXAMPLE_MIPI_CSI_DISP_VRES config EXAMPLE_MIPI_CSI_DISP_VRES
int int
default 600 if EXAMPLE_MIPI_CSI_VRES_600
default 640 if EXAMPLE_MIPI_CSI_VRES_640 default 640 if EXAMPLE_MIPI_CSI_VRES_640
default 1280 if EXAMPLE_MIPI_CSI_VRES_1280 default 1280 if EXAMPLE_MIPI_CSI_VRES_1280
endmenu endmenu

View File

@ -6,24 +6,21 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "sdkconfig.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_lcd_mipi_dsi.h" #include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_ops.h"
#include "esp_lcd_ili9881c.h"
#include "esp_ldo_regulator.h" #include "esp_ldo_regulator.h"
#include "esp_cache.h" #include "esp_cache.h"
#include "driver/i2c_master.h" #include "driver/i2c_master.h"
#include "driver/isp.h" #include "driver/isp.h"
#include "esp_cam_ctlr_csi.h" #include "esp_cam_ctlr_csi.h"
#include "esp_cam_ctlr.h" #include "esp_cam_ctlr.h"
#include "esp_sccb_intf.h"
#include "esp_sccb_i2c.h"
#include "esp_cam_sensor.h"
#include "ov5647.h"
#include "example_dsi_init.h" #include "example_dsi_init.h"
#include "example_dsi_init_config.h" #include "example_dsi_init_config.h"
#include "example_sensor_init.h"
#include "example_config.h" #include "example_config.h"
static const char *TAG = "cam_dsi"; static const char *TAG = "cam_dsi";
@ -36,7 +33,6 @@ void app_main(void)
esp_err_t ret = ESP_FAIL; esp_err_t ret = ESP_FAIL;
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL;
esp_lcd_panel_handle_t mipi_dpi_panel = NULL; esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
void *frame_buffer = NULL; void *frame_buffer = NULL;
size_t frame_buffer_size = 0; size_t frame_buffer_size = 0;
@ -55,7 +51,7 @@ void app_main(void)
* ISP convert to RGB565 * ISP convert to RGB565
*/ */
//---------------DSI Init------------------// //---------------DSI Init------------------//
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer); example_dsi_resource_alloc(&mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);
//---------------Necessary variable config------------------// //---------------Necessary variable config------------------//
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8; frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
@ -69,25 +65,9 @@ void app_main(void)
.buflen = frame_buffer_size, .buflen = frame_buffer_size,
}; };
//---------------I2C Init------------------// //--------Camera Sensor and SCCB Init-----------//
i2c_master_bus_config_t i2c_bus_conf = { i2c_master_bus_handle_t i2c_bus_handle = NULL;
.clk_source = I2C_CLK_SRC_DEFAULT, example_sensor_init(I2C_NUM_0, &i2c_bus_handle);
.sda_io_num = EXAMPLE_MIPI_SCCB_SDA_IO,
.scl_io_num = EXAMPLE_MIPI_SCCB_SCL_IO,
.i2c_port = I2C_NUM_0,
.flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t bus_handle = NULL;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &bus_handle));
//---------------SCCB Init------------------//
esp_sccb_io_handle_t ov5647_io_handle = NULL;
sccb_i2c_config_t i2c_config = {
.scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ,
.device_address = EXAMPLE_OV5647_DEV_ADDR,
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
};
ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &ov5647_io_handle));
//---------------CSI Init------------------// //---------------CSI Init------------------//
esp_cam_ctlr_csi_config_t csi_config = { esp_cam_ctlr_csi_config_t csi_config = {
@ -134,8 +114,8 @@ void app_main(void)
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc)); ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
ESP_ERROR_CHECK(esp_isp_enable(isp_proc)); ESP_ERROR_CHECK(esp_isp_enable(isp_proc));
//---------------DSI Panel Init------------------// //---------------DPI Reset------------------//
example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel); example_dpi_panel_reset(mipi_dpi_panel);
//init to all white //init to all white
memset(frame_buffer, 0xFF, frame_buffer_size); memset(frame_buffer, 0xFF, frame_buffer_size);
@ -146,53 +126,6 @@ void app_main(void)
return; return;
} }
esp_cam_sensor_config_t cam_config = {
.sccb_handle = ov5647_io_handle,
.reset_pin = -1,
.pwdn_pin = -1,
.xclk_pin = -1,
.sensor_port = ESP_CAM_SENSOR_MIPI_CSI,
};
esp_cam_sensor_device_t *cam = ov5647_detect(&cam_config);
if (!cam) {
ESP_LOGE(TAG, "failed to detect 5647");
return;
}
esp_cam_sensor_format_array_t cam_fmt_array = {0};
esp_cam_sensor_query_format(cam, &cam_fmt_array);
const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array;
for (int i = 0; i < cam_fmt_array.count; i++) {
ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name);
}
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
for (int i = 0; i < cam_fmt_array.count; i++) {
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) {
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
}
#else
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x1280_50fps")) {
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
}
#endif
}
ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Format set fail");
} else {
ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name);
}
int enable_flag = 1;
// Set sensor output stream
ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Start stream fail");
}
example_dpi_panel_init(mipi_dpi_panel); example_dpi_panel_init(mipi_dpi_panel);
while (1) { while (1) {

View File

@ -11,13 +11,9 @@ extern "C" {
#endif #endif
#define EXAMPLE_RGB565_BITS_PER_PIXEL 16 #define EXAMPLE_RGB565_BITS_PER_PIXEL 16
#define EXAMPLE_MIPI_SCCB_FREQ (100000)
#define EXAMPLE_MIPI_SCCB_SCL_IO (8)
#define EXAMPLE_MIPI_SCCB_SDA_IO (7)
#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000) #define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000)
#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4 #define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4
#define EXAMPLE_OV5647_DEV_ADDR 0x36
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,7 +1,7 @@
dependencies: dependencies:
espressif/esp_cam_sensor: "^0.5.1"
espressif/esp_lcd_ili9881c: "~0.2.0"
idf: idf:
version: ">=5.3.0" version: ">=5.3.0"
dsi_init: dsi_init:
path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init
sensor_init:
path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/sensor_init

View File

@ -1,4 +1,5 @@
CONFIG_SPIRAM=y CONFIG_SPIRAM=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=y CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM_SPEED_200M=y CONFIG_SPIRAM_SPEED_200M=y
CONFIG_CAMERA_SC2336=y
CONFIG_CAMERA_OV5647=y CONFIG_CAMERA_OV5647=y

View File

@ -6,10 +6,14 @@
## Overview ## Overview
This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will capture camera sensor signals via CSI interface and display it via DSI interface. This example enables This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will auto-detect camera sensors via [ESP camera sensor driver](https://components.espressif.com/components/espressif/esp_cam_sensor/versions/0.5.3) and capture camera sensor signals via CSI interface and display it via DSI interface. This example enables following ISP functions:
- ISP AF (auto-focus) feature - ISP AF (auto-focus) feature
- ISP BF (bayer denoise) feature - ISP BF (bayer denoise) feature
- ISP Sharpen feature - ISP Sharpen feature
- ISP Demosaic feature
- ISP GAMMA feature
- ISP Color feature
## Usage ## Usage
@ -20,10 +24,18 @@ The subsections below give only absolutely necessary information. For full steps
This example requires: This example requires:
- OV5647 camera sensor with VCM (Voice Coil Motor). The VCM used in this example is DW9714. - OV5647 or SC2336 camera sensor, or other camera sensors
- ILI9881C LCD screen - EK79007 or ILI9881C LCD screen
- ESP32P4 devkit - ESP32P4 devkit
**Note:** OV5647 has its own ISP functions, whereas SC2336 is a camera sensor without ISP functions. You can use the ESP on-chip ISP functions to tune the image together with the sensor ISP functions, if the image quality is not as expected.
**Note:** For EK79007 you will need to connect following pins:
- 5V - 5V
- GND - GND
- RST_LCD - 3V3
You can also connect camera sensors and LCD screens from other vendors to the ESP chip, you can find corresponding camera or LCD drivers from [ESP Component Registry](https://components.espressif.com), or design your own customized drivers.
GND GND GND GND
┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
@ -43,7 +55,7 @@ This example requires:
│ ├──────────────────────┤ │ DSI DATA 1N │ │ │ ├──────────────────────┤ │ DSI DATA 1N │ │
│ │ │ ├───────────────────────────┤ │ │ │ │ ├───────────────────────────┤ │
│ │ CSI DATA 1N │ ESP32-P4 │ │ │ │ │ CSI DATA 1N │ ESP32-P4 │ │ │
OV5647 ├──────────────────────┤ │ DSI CLK N │ ILI9881C Camera ├──────────────────────┤ │ DSI CLK N │ LCD Screen
│ │ │ ├───────────────────────────┤ │ │ │ │ ├───────────────────────────┤ │
│ │ CSI CLK N │ │ │ │ │ │ CSI CLK N │ │ │ │
│ ├──────────────────────┤ │ DSI CLK P │ │ │ ├──────────────────────┤ │ DSI CLK P │ │
@ -100,6 +112,7 @@ idf.py menuconfig
``` ```
Set CONFIG_CAMERA_OV5647 to y Set CONFIG_CAMERA_OV5647 to y
Set CONFIG_CAMERA_SC2336 to y
``` ```

View File

@ -1,4 +1,4 @@
idf_component_register(SRCS "isp_dsi_main.c" idf_component_register(SRCS "isp_dsi_main.c"
INCLUDE_DIRS "." INCLUDE_DIRS "."
REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd dsi_init REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd dsi_init sensor_init
) )

View File

@ -14,20 +14,25 @@ menu "Example Configuration"
choice EXAMPLE_MIPI_CSI_DISP_HRES choice EXAMPLE_MIPI_CSI_DISP_HRES
bool "Set MIPI CSI horizontal resolution" bool "Set MIPI CSI horizontal resolution"
default EXAMPLE_MIPI_CSI_HRES_800 default EXAMPLE_MIPI_CSI_HRES_1024
config EXAMPLE_MIPI_CSI_HRES_800 config EXAMPLE_MIPI_CSI_HRES_800
bool "800" bool "800"
config EXAMPLE_MIPI_CSI_HRES_1024
bool "1024"
endchoice endchoice
config EXAMPLE_MIPI_CSI_DISP_HRES config EXAMPLE_MIPI_CSI_DISP_HRES
int int
default 800 if EXAMPLE_MIPI_CSI_HRES_800 default 800 if EXAMPLE_MIPI_CSI_HRES_800
default 1024 if EXAMPLE_MIPI_CSI_HRES_1024
choice EXAMPLE_MIPI_CSI_DISP_VRES choice EXAMPLE_MIPI_CSI_DISP_VRES
bool "Set MIPI CSI vertical resolution" bool "Set MIPI CSI vertical resolution"
default EXAMPLE_MIPI_CSI_VRES_640 default EXAMPLE_MIPI_CSI_VRES_600
config EXAMPLE_MIPI_CSI_VRES_600
bool "600"
config EXAMPLE_MIPI_CSI_VRES_640 config EXAMPLE_MIPI_CSI_VRES_640
bool "640" bool "640"
config EXAMPLE_MIPI_CSI_VRES_1280 config EXAMPLE_MIPI_CSI_VRES_1280
@ -36,6 +41,7 @@ menu "Example Configuration"
config EXAMPLE_MIPI_CSI_DISP_VRES config EXAMPLE_MIPI_CSI_DISP_VRES
int int
default 600 if EXAMPLE_MIPI_CSI_VRES_600
default 640 if EXAMPLE_MIPI_CSI_VRES_640 default 640 if EXAMPLE_MIPI_CSI_VRES_640
default 1280 if EXAMPLE_MIPI_CSI_VRES_1280 default 1280 if EXAMPLE_MIPI_CSI_VRES_1280
endmenu endmenu

View File

@ -12,12 +12,8 @@ extern "C" {
#define EXAMPLE_RGB565_BITS_PER_PIXEL 16 #define EXAMPLE_RGB565_BITS_PER_PIXEL 16
#define EXAMPLE_MIPI_SCCB_FREQ (100000) #define EXAMPLE_MIPI_SCCB_FREQ (100000)
#define EXAMPLE_MIPI_SCCB_SCL_IO (8)
#define EXAMPLE_MIPI_SCCB_SDA_IO (7)
#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000)
#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4 #define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4
#define EXAMPLE_OV5647_DEV_ADDR 0x36
#define EXAMPLE_DW9714_DEV_ADDR 0xC #define EXAMPLE_DW9714_DEV_ADDR 0xC
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,9 +1,10 @@
dependencies: dependencies:
espressif/esp_cam_sensor: "^0.5.*" espressif/esp_cam_sensor: "^0.5.*"
espressif/esp_lcd_ili9881c: "~0.2.0"
idf: idf:
version: ">=5.3.0" version: ">=5.3.0"
isp_af_schemes: isp_af_schemes:
path: ${IDF_PATH}/examples/peripherals/isp/multi_pipelines/components/isp_af_schemes path: ${IDF_PATH}/examples/peripherals/isp/multi_pipelines/components/isp_af_schemes
dsi_init: dsi_init:
path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init
sensor_init:
path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/sensor_init

View File

@ -7,12 +7,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "esp_lcd_mipi_dsi.h" #include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_ops.h"
#include "esp_lcd_ili9881c.h"
#include "esp_ldo_regulator.h" #include "esp_ldo_regulator.h"
#include "esp_cache.h" #include "esp_cache.h"
#include "driver/i2c_master.h" #include "driver/i2c_master.h"
@ -23,9 +23,9 @@
#include "esp_sccb_intf.h" #include "esp_sccb_intf.h"
#include "esp_sccb_i2c.h" #include "esp_sccb_i2c.h"
#include "esp_cam_sensor.h" #include "esp_cam_sensor.h"
#include "ov5647.h"
#include "example_dsi_init.h" #include "example_dsi_init.h"
#include "example_dsi_init_config.h" #include "example_dsi_init_config.h"
#include "example_sensor_init.h"
#include "example_config.h" #include "example_config.h"
static const char *TAG = "isp_dsi"; static const char *TAG = "isp_dsi";
@ -190,7 +190,6 @@ void app_main(void)
esp_err_t ret = ESP_FAIL; esp_err_t ret = ESP_FAIL;
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL;
esp_lcd_panel_handle_t mipi_dpi_panel = NULL; esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
void *frame_buffer = NULL; void *frame_buffer = NULL;
size_t frame_buffer_size = 0; size_t frame_buffer_size = 0;
@ -209,7 +208,7 @@ void app_main(void)
* ISP convert to RGB565 * ISP convert to RGB565
*/ */
//---------------DSI Init------------------// //---------------DSI Init------------------//
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer); example_dsi_resource_alloc(&mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);
//---------------Necessary variable config------------------// //---------------Necessary variable config------------------//
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8; frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
@ -223,29 +222,18 @@ void app_main(void)
.buflen = frame_buffer_size, .buflen = frame_buffer_size,
}; };
//---------------I2C Init------------------// //--------Camera Sensor and SCCB Init-----------//
i2c_master_bus_config_t i2c_bus_conf = { i2c_master_bus_handle_t i2c_bus_handle = NULL;
.clk_source = I2C_CLK_SRC_DEFAULT, example_sensor_init(I2C_NUM_0, &i2c_bus_handle);
.sda_io_num = EXAMPLE_MIPI_SCCB_SDA_IO,
.scl_io_num = EXAMPLE_MIPI_SCCB_SCL_IO,
.i2c_port = I2C_NUM_0,
.flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t bus_handle = NULL;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &bus_handle));
//---------------SCCB Init------------------// //---------------VCM SCCB Init------------------//
esp_sccb_io_handle_t ov5647_io_handle = NULL; esp_sccb_io_handle_t dw9714_io_handle = NULL;
sccb_i2c_config_t i2c_config = { sccb_i2c_config_t i2c_config = {
.scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ, .scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ,
.device_address = EXAMPLE_OV5647_DEV_ADDR, .device_address = EXAMPLE_DW9714_DEV_ADDR,
.dev_addr_length = I2C_ADDR_BIT_LEN_7, .dev_addr_length = I2C_ADDR_BIT_LEN_7,
}; };
ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &ov5647_io_handle)); ESP_ERROR_CHECK(sccb_new_i2c_io(i2c_bus_handle, &i2c_config, &dw9714_io_handle));
esp_sccb_io_handle_t dw9714_io_handle = NULL;
i2c_config.device_address = EXAMPLE_DW9714_DEV_ADDR;
ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &dw9714_io_handle));
//---------------CSI Init------------------// //---------------CSI Init------------------//
esp_cam_ctlr_csi_config_t csi_config = { esp_cam_ctlr_csi_config_t csi_config = {
@ -370,8 +358,8 @@ void app_main(void)
}; };
xTaskCreatePinnedToCore(af_task, "af_task", 8192, &af_task_param, 5, NULL, 0); xTaskCreatePinnedToCore(af_task, "af_task", 8192, &af_task_param, 5, NULL, 0);
//---------------DSI Panel Init------------------// //---------------DPI Reset------------------//
example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel); example_dpi_panel_reset(mipi_dpi_panel);
//init to all white //init to all white
memset(frame_buffer, 0xFF, frame_buffer_size); memset(frame_buffer, 0xFF, frame_buffer_size);
@ -382,55 +370,6 @@ void app_main(void)
return; return;
} }
esp_cam_sensor_config_t cam_config = {
.sccb_handle = ov5647_io_handle,
.reset_pin = -1,
.pwdn_pin = -1,
.xclk_pin = -1,
.sensor_port = ESP_CAM_SENSOR_MIPI_CSI,
};
esp_cam_sensor_device_t *cam = ov5647_detect(&cam_config);
if (!cam) {
ESP_LOGE(TAG, "failed to detect 5647");
return;
}
esp_cam_sensor_format_array_t cam_fmt_array = {0};
esp_cam_sensor_query_format(cam, &cam_fmt_array);
const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array;
for (int i = 0; i < cam_fmt_array.count; i++) {
ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name);
}
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
for (int i = 0; i < cam_fmt_array.count; i++) {
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) {
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
break;
}
#else
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x1280_50fps")) {
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
break;
}
#endif
}
ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Format set fail");
} else {
ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name);
}
int enable_flag = 1;
// Set sensor output stream
ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Start stream fail");
}
example_dpi_panel_init(mipi_dpi_panel); example_dpi_panel_init(mipi_dpi_panel);
while (1) { while (1) {

View File

@ -1,4 +1,5 @@
CONFIG_SPIRAM=y CONFIG_SPIRAM=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=y CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM_SPEED_200M=y CONFIG_SPIRAM_SPEED_200M=y
CONFIG_CAMERA_SC2336=y
CONFIG_CAMERA_OV5647=y CONFIG_CAMERA_OV5647=y

View File

@ -19,9 +19,14 @@ The subsections below give only absolutely necessary information. For full steps
This example requires: This example requires:
- ILI9881C LCD screen - EK79007 or ILI9881C LCD screen
- ESP32P4 devkit - ESP32P4 devkit
**Note:** For EK79007 you will need to connect following pins:
- 5V - 5V
- GND - GND
- RST_LCD - 3V3
GND GND
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
@ -41,7 +46,7 @@ This example requires:
│ │ DSI DATA 1N │ │ │ │ DSI DATA 1N │ │
│ ├───────────────────────────┤ │ │ ├───────────────────────────┤ │
│ ESP32-P4 │ │ │ │ ESP32-P4 │ │ │
│ │ DSI CLK N │ ILI9881C │ │ DSI CLK N │ LCD Screen
│ ├───────────────────────────┤ │ │ ├───────────────────────────┤ │
│ │ │ │ │ │ │ │
│ │ DSI CLK P │ │ │ │ DSI CLK P │ │

View File

@ -1,5 +1,4 @@
dependencies: dependencies:
espressif/esp_lcd_ili9881c: "~0.2.0"
idf: idf:
version: ">=5.3.0" version: ">=5.3.0"
dsi_init: dsi_init:

View File

@ -12,7 +12,6 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "esp_lcd_mipi_dsi.h" #include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_ops.h"
#include "esp_lcd_ili9881c.h"
#include "esp_ldo_regulator.h" #include "esp_ldo_regulator.h"
#include "driver/ppa.h" #include "driver/ppa.h"
#include "example_dsi_init.h" #include "example_dsi_init.h"
@ -319,7 +318,6 @@ void app_main(void)
uint16_t *pixels = NULL; uint16_t *pixels = NULL;
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL;
esp_lcd_panel_handle_t mipi_dpi_panel = NULL; esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
//---------------MIPI LDO Init------------------// //---------------MIPI LDO Init------------------//
@ -331,8 +329,8 @@ void app_main(void)
ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));
//---------------DSI Init------------------// //---------------DSI Init------------------//
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, NULL); example_dsi_resource_alloc(&mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, NULL);
example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel); example_dpi_panel_reset(mipi_dpi_panel);
example_dpi_panel_init(mipi_dpi_panel); example_dpi_panel_init(mipi_dpi_panel);
//---------------Get Source image------------------// //---------------Get Source image------------------//
@ -400,5 +398,5 @@ void app_main(void)
ESP_ERROR_CHECK(ppa_unregister_client(ppa_srm_handle)); ESP_ERROR_CHECK(ppa_unregister_client(ppa_srm_handle));
ESP_ERROR_CHECK(ppa_unregister_client(ppa_blend_handle)); ESP_ERROR_CHECK(ppa_unregister_client(ppa_blend_handle));
ESP_ERROR_CHECK(ppa_unregister_client(ppa_fill_handle)); ESP_ERROR_CHECK(ppa_unregister_client(ppa_fill_handle));
example_dsi_resource_destroy(ili9881c_ctrl_panel, mipi_dsi_bus, mipi_dbi_io, mipi_dpi_panel); example_dsi_resource_destroy(mipi_dsi_bus, mipi_dbi_io, mipi_dpi_panel);
} }

View File

@ -13,7 +13,7 @@ Before project configuration and build, be sure to set the correct chip target u
### Hardware Required ### Hardware Required
* A development board with ESP32-C3/ESP32-S3/ SoC. * A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-C6/ESP32-H2/ESP32-S2/ESP32-S3/ SoC.
* A USB cable for Power supply and programming * A USB cable for Power supply and programming
### Configure the project ### Configure the project
@ -34,11 +34,6 @@ Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.) (To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/index.html)
## Example Output ## Example Output
The command and output logs for each test are as follows: The command and output logs for each test are as follows:

View File

@ -1,9 +1,10 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "sdkconfig.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "esp_console.h" #include "esp_console.h"
@ -38,7 +39,7 @@ void app_main(void)
register_phy_cmd(); register_phy_cmd();
/* rftest.a requirements */ /* rftest.a requirements */
#ifndef CONFIG_IDF_TARGET_ESP32H2 #if CONFIG_SOC_WIFI_SUPPORTED
esp_wifi_power_domain_on(); esp_wifi_power_domain_on();
#endif #endif
@ -46,12 +47,17 @@ void app_main(void)
esp_phy_rftest_init(); esp_phy_rftest_init();
#endif #endif
int help_index = 1;
printf("\n ==================================================\n"); printf("\n ==================================================\n");
printf(" | RF certification test |\n"); printf(" | RF certification test |\n");
printf(" | |\n"); printf(" | |\n");
printf(" | 1. Print 'help' to gain overview of commands |\n"); printf(" | 1. Print 'help' to gain overview of commands |\n");
printf(" | 2. Wi-Fi certification test |\n"); #if CONFIG_SOC_WIFI_SUPPORTED
printf(" | 3. Bluetooth certification test |\n"); printf(" | %d. Wi-Fi certification test |\n", ++help_index);
#endif
#if CONFIG_SOC_BT_SUPPORTED
printf(" | %d. Bluetooth certification test |\n", ++help_index);
#endif
printf(" | |\n"); printf(" | |\n");
printf(" =================================================\n\n"); printf(" =================================================\n\n");

View File

@ -3,6 +3,8 @@
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_log.h" #include "esp_log.h"