From 3574fc1918dcf39c7c153a6a20236df72ce2333c Mon Sep 17 00:00:00 2001 From: Zim Kalinowski Date: Tue, 17 Jan 2023 18:55:15 +0100 Subject: [PATCH] cxx: removed cxx experimental components --- .gitlab/ci/rules.yml | 1 - examples/cxx/.build-test-rules.yml | 35 - .../cxx/experimental/blink_cxx/CMakeLists.txt | 10 - examples/cxx/experimental/blink_cxx/README.md | 60 -- .../blink_cxx/main/CMakeLists.txt | 2 - .../cxx/experimental/blink_cxx/main/main.cpp | 39 - .../experimental/blink_cxx/sdkconfig.defaults | 3 - .../esp_event_async_cxx/CMakeLists.txt | 10 - .../esp_event_async_cxx/README.md | 44 - .../esp_event_async_cxx/main/CMakeLists.txt | 2 - .../main/esp_event_async_cxx_example.cpp | 111 --- .../esp_event_async_cxx/sdkconfig.defaults | 3 - .../experimental/esp_event_cxx/CMakeLists.txt | 10 - .../cxx/experimental/esp_event_cxx/README.md | 47 -- .../esp_event_cxx/main/CMakeLists.txt | 2 - .../main/esp_event_cxx_example.cpp | 80 -- .../esp_event_cxx/sdkconfig.defaults | 3 - .../components/esp_mqtt_cxx/CMakeLists.txt | 23 - .../components/esp_mqtt_cxx/esp_mqtt_cxx.cpp | 293 ------- .../esp_mqtt_cxx/include/esp_mqtt.hpp | 229 ------ .../include/esp_mqtt_client_config.hpp | 221 ----- .../esp_mqtt_cxx/ssl/CMakeLists.txt | 14 - .../experimental/esp_mqtt_cxx/ssl/README.md | 2 - .../esp_mqtt_cxx/ssl/main/CMakeLists.txt | 2 - .../esp_mqtt_cxx/ssl/main/Kconfig.projbuild | 9 - .../ssl/main/mqtt_eclipse_org.pem | 27 - .../ssl/main/mqtt_eclipseprojects_io.pem | 30 - .../ssl/main/mqtt_ssl_example.cpp | 86 -- .../esp_mqtt_cxx/ssl/sdkconfig.defaults | 3 - .../esp_mqtt_cxx/tcp/CMakeLists.txt | 12 - .../experimental/esp_mqtt_cxx/tcp/README.md | 2 - .../esp_mqtt_cxx/tcp/main/CMakeLists.txt | 2 - .../esp_mqtt_cxx/tcp/main/Kconfig.projbuild | 9 - .../tcp/main/mqtt_tcp_example.cpp | 83 -- .../esp_mqtt_cxx/tcp/sdkconfig.defaults | 3 - .../experimental/esp_timer_cxx/CMakeLists.txt | 8 - .../cxx/experimental/esp_timer_cxx/README.md | 51 -- .../esp_timer_cxx/main/CMakeLists.txt | 2 - .../esp_timer_cxx/main/esp_timer_example.cpp | 38 - .../esp_timer_cxx/sdkconfig.defaults | 3 - .../experimental_cpp_component/CMakeLists.txt | 17 - .../experimental_cpp_component/README.md | 20 - .../esp_event_api.cpp | 115 --- .../esp_event_cxx.cpp | 226 ------ .../esp_exception.cpp | 29 - .../esp_timer_cxx.cpp | 60 -- .../experimental_cpp_component/gpio_cxx.cpp | 214 ----- .../host_test/esp_timer/CMakeLists.txt | 10 - .../host_test/esp_timer/README.md | 36 - .../host_test/esp_timer/main/CMakeLists.txt | 5 - .../esp_timer/main/esp_timer_test.cpp | 196 ----- .../esp_timer/pytest_esp_timer_cxx.py | 10 - .../host_test/esp_timer/sdkconfig.defaults | 3 - .../host_test/fixtures/test_fixtures.hpp | 361 --------- .../host_test/gpio/CMakeLists.txt | 13 - .../host_test/gpio/README.md | 8 - .../host_test/gpio/main/CMakeLists.txt | 13 - .../host_test/gpio/main/gpio_cxx_test.cpp | 404 ---------- .../host_test/gpio/pytest_gpio_cxx.py | 10 - .../host_test/gpio/sdkconfig.defaults | 3 - .../host_test/i2c/CMakeLists.txt | 14 - .../host_test/i2c/README.md | 8 - .../host_test/i2c/main/CMakeLists.txt | 11 - .../host_test/i2c/main/i2c_cxx_test.cpp | 463 ----------- .../host_test/i2c/pytest_i2c_cxx.py | 10 - .../host_test/i2c/sdkconfig.defaults | 3 - .../host_test/spi/CMakeLists.txt | 14 - .../host_test/spi/README.md | 8 - .../host_test/spi/main/CMakeLists.txt | 9 - .../host_test/spi/main/spi_cxx_test.cpp | 453 ----------- .../host_test/spi/pytest_spi_cxx.py | 10 - .../host_test/spi/sdkconfig.defaults | 3 - .../host_test/system/CMakeLists.txt | 34 - .../host_test/system/README.md | 8 - .../host_test/system/main/CMakeLists.txt | 12 - .../host_test/system/main/system_cxx_test.cpp | 95 --- .../host_test/system/pytest_system_cxx.py | 10 - .../host_test/system/sdkconfig.defaults | 3 - .../experimental_cpp_component/i2c_cxx.cpp | 305 ------- .../include/esp_event_api.hpp | 122 --- .../include/esp_event_cxx.hpp | 463 ----------- .../include/esp_exception.hpp | 66 -- .../include/esp_timer_cxx.hpp | 145 ---- .../include/gpio_cxx.hpp | 402 --------- .../include/i2c_cxx.hpp | 623 -------------- .../include/spi_cxx.hpp | 152 ---- .../include/spi_host_cxx.hpp | 414 ---------- .../include/system_cxx.hpp | 145 ---- .../private_include/spi_host_private_cxx.hpp | 141 ---- .../experimental_cpp_component/spi_cxx.cpp | 33 - .../spi_host_cxx.cpp | 267 ------ .../test/CMakeLists.txt | 4 - .../test/test_cxx_exceptions.cpp | 61 -- .../test/test_esp_event_cxx.cpp | 761 ------------------ .../test/test_esp_timer.cpp | 114 --- .../test/test_i2c.cpp | 261 ------ .../test/unity_cxx.hpp | 37 - .../simple_i2c_rw_example/CMakeLists.txt | 8 - .../simple_i2c_rw_example/README.md | 63 -- .../simple_i2c_rw_example/main/CMakeLists.txt | 2 - .../main/Kconfig.projbuild | 17 - .../main/simple_i2c_rw_example.cpp | 55 -- .../simple_i2c_rw_example/sdkconfig.defaults | 3 - .../simple_spi_rw_example/CMakeLists.txt | 8 - .../simple_spi_rw_example/README.md | 71 -- .../simple_spi_rw_example/main/CMakeLists.txt | 3 - .../main/simple_spi_rw_example.cpp | 49 -- .../simple_spi_rw_example/sdkconfig.defaults | 3 - tools/ci/check_copyright_ignore.txt | 21 - .../test_idf_size/app_esp32s3_32k_icache.map | 1 - tools/unit-test-app/CMakeLists.txt | 1 - tools/unit-test-app/configs/cxx_experimental | 2 - tools/unit-test-app/configs/default_2 | 2 +- tools/unit-test-app/configs/default_2_c3 | 2 +- tools/unit-test-app/configs/default_2_s2 | 2 +- tools/unit-test-app/configs/default_2_s3 | 2 +- tools/unit-test-app/configs/psram | 2 +- tools/unit-test-app/configs/release_2 | 2 +- tools/unit-test-app/configs/release_2_s2 | 2 +- tools/unit-test-app/configs/single_core_2 | 2 +- tools/unit-test-app/configs/single_core_2_s2 | 2 +- 121 files changed, 9 insertions(+), 9367 deletions(-) delete mode 100644 examples/cxx/experimental/blink_cxx/CMakeLists.txt delete mode 100644 examples/cxx/experimental/blink_cxx/README.md delete mode 100644 examples/cxx/experimental/blink_cxx/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/blink_cxx/main/main.cpp delete mode 100644 examples/cxx/experimental/blink_cxx/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/esp_event_async_cxx/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_event_async_cxx/README.md delete mode 100644 examples/cxx/experimental/esp_event_async_cxx/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp delete mode 100644 examples/cxx/experimental/esp_event_async_cxx/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/esp_event_cxx/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_event_cxx/README.md delete mode 100644 examples/cxx/experimental/esp_event_cxx/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp delete mode 100644 examples/cxx/experimental/esp_event_cxx/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/esp_mqtt_cxx.cpp delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/README.md delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/main/Kconfig.projbuild delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipse_org.pem delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipseprojects_io.pem delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/ssl/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/README.md delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/main/Kconfig.projbuild delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp delete mode 100644 examples/cxx/experimental/esp_mqtt_cxx/tcp/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/esp_timer_cxx/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_timer_cxx/README.md delete mode 100644 examples/cxx/experimental/esp_timer_cxx/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp delete mode 100644 examples/cxx/experimental/esp_timer_cxx/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/gpio_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/pytest_esp_timer_cxx.py delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/gpio_cxx_test.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/pytest_gpio_cxx.py delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/gpio/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/pytest_i2c_cxx.py delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/i2c/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/spi_cxx_test.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/pytest_spi_cxx.py delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/spi/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/README.md delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/main/system_cxx_test.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/pytest_system_cxx.py delete mode 100644 examples/cxx/experimental/experimental_cpp_component/host_test/system/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/esp_event_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/gpio_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/spi_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/spi_host_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/include/system_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/private_include/spi_host_private_cxx.hpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/spi_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/spi_host_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/test_esp_timer.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp delete mode 100644 examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/CMakeLists.txt delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/README.md delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/main/Kconfig.projbuild delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/main/simple_i2c_rw_example.cpp delete mode 100644 examples/cxx/experimental/simple_i2c_rw_example/sdkconfig.defaults delete mode 100644 examples/cxx/experimental/simple_spi_rw_example/CMakeLists.txt delete mode 100644 examples/cxx/experimental/simple_spi_rw_example/README.md delete mode 100644 examples/cxx/experimental/simple_spi_rw_example/main/CMakeLists.txt delete mode 100644 examples/cxx/experimental/simple_spi_rw_example/main/simple_spi_rw_example.cpp delete mode 100644 examples/cxx/experimental/simple_spi_rw_example/sdkconfig.defaults delete mode 100644 tools/unit-test-app/configs/cxx_experimental diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index d46e1fe926..f3124d2ba9 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -40,7 +40,6 @@ .patterns-build_components: &patterns-build_components - "components/**/*" - - "examples/cxx/experimental/experimental_cpp_component/*" .patterns-downloadable-tools: &patterns-downloadable-tools - "tools/idf_tools.py" diff --git a/examples/cxx/.build-test-rules.yml b/examples/cxx/.build-test-rules.yml index cd393b6766..70149243f5 100644 --- a/examples/cxx/.build-test-rules.yml +++ b/examples/cxx/.build-test-rules.yml @@ -6,41 +6,6 @@ examples/cxx/exceptions: temporary: true reason: lack of runners -examples/cxx/experimental/esp_modem_cxx: - enable: - - if: IDF_TARGET in ["esp32", "esp32s2"] - temporary: true - reason: the other targets are not tested yet - -examples/cxx/experimental/esp_mqtt_cxx/ssl: - disable: - - if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c6 is not supported yet - -examples/cxx/experimental/esp_mqtt_cxx/tcp: - disable: - - if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c6 is not supported yet - -examples/cxx/experimental/experimental_cpp_component/host_test: - enable: - - if: IDF_TARGET == "linux" - reason: only test on linux - -examples/cxx/experimental/simple_i2c_rw_example: - disable: - - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"] - temporary: true - reason: target(s) not supported yet - -examples/cxx/experimental/simple_spi_rw_example: - disable: - - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"] - temporary: true - reason: target(s) not supported yet - examples/cxx/pthread: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] diff --git a/examples/cxx/experimental/blink_cxx/CMakeLists.txt b/examples/cxx/experimental/blink_cxx/CMakeLists.txt deleted file mode 100644 index 824a3ae00e..0000000000 --- a/examples/cxx/experimental/blink_cxx/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# For more information about build system see -# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html -# The following five lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component") - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(blink_cxx) diff --git a/examples/cxx/experimental/blink_cxx/README.md b/examples/cxx/experimental/blink_cxx/README.md deleted file mode 100644 index 2396178dc6..0000000000 --- a/examples/cxx/experimental/blink_cxx/README.md +++ /dev/null @@ -1,60 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | - -# Example: Blink C++ example - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -This example demonstrates usage of the `GPIO_Output` C++ class in ESP-IDF. - -In this example, the `sdkconfig.defaults` file sets the `CONFIG_COMPILER_CXX_EXCEPTIONS` option. -This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling. -This is necessary for the C++ APIs. - -## How to use example - -### Hardware Required - -Any ESP32 family development board. - -Connect an LED to the corresponding pin (default is pin 4). If the board has a normal LED already, you can use the pin number to which that one is connected. - -Development boards with an RGB LED that only has one data line like the ESP32-C3-DevKitC-02 and ESP32-C3-DevKitM-1 will not work. In this case, please connect an external normal LED to the chosen pin. - -### Configure the project - -``` -idf.py menuconfig -``` - -### Build and Flash - -``` -idf.py -p PORT flash monitor -``` - -(Replace PORT with the name of the serial port.) - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -... -I (339) cpu_start: Starting scheduler. -I (343) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -LED ON -LED OFF -LED ON -LED OFF -LED ON -LED OFF -LED ON -LED OFF -LED ON -LED OFF - -``` - diff --git a/examples/cxx/experimental/blink_cxx/main/CMakeLists.txt b/examples/cxx/experimental/blink_cxx/main/CMakeLists.txt deleted file mode 100644 index 9eb7ec47a0..0000000000 --- a/examples/cxx/experimental/blink_cxx/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "main.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/blink_cxx/main/main.cpp b/examples/cxx/experimental/blink_cxx/main/main.cpp deleted file mode 100644 index f997e13ac3..0000000000 --- a/examples/cxx/experimental/blink_cxx/main/main.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* Blink C++ Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include -#include "esp_log.h" -#include "gpio_cxx.hpp" - -using namespace idf; -using namespace std; - -extern "C" void app_main(void) -{ - /* The functions of GPIO_Output throws exceptions in case of parameter errors or if there are underlying driver - errors. */ - try { - /* This line may throw an exception if the pin number is invalid. - * Alternatively to 4, choose another output-capable pin. */ - GPIO_Output gpio(GPIONum(4)); - - while (true) { - printf("LED ON\n"); - gpio.set_high(); - this_thread::sleep_for(std::chrono::seconds(1)); - printf("LED OFF\n"); - gpio.set_low(); - this_thread::sleep_for(std::chrono::seconds(1)); - } - } catch (GPIOException &e) { - printf("GPIO exception occurred: %s\n", esp_err_to_name(e.error)); - printf("stopping.\n"); - } -} diff --git a/examples/cxx/experimental/blink_cxx/sdkconfig.defaults b/examples/cxx/experimental/blink_cxx/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/blink_cxx/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/esp_event_async_cxx/CMakeLists.txt b/examples/cxx/experimental/esp_event_async_cxx/CMakeLists.txt deleted file mode 100644 index ea73cfbeed..0000000000 --- a/examples/cxx/experimental/esp_event_async_cxx/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# The following five lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -# (Not part of the boilerplate) -# This example uses an experimental c++ component. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp_event_async_cxx) diff --git a/examples/cxx/experimental/esp_event_async_cxx/README.md b/examples/cxx/experimental/esp_event_async_cxx/README.md deleted file mode 100644 index ae6d93e816..0000000000 --- a/examples/cxx/experimental/esp_event_async_cxx/README.md +++ /dev/null @@ -1,44 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | - -# ESP-Event asynchronous example - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - - -## How to use example - -### Configure the project - -``` -idf.py menuconfig -``` - -* Set serial port under Serial Flasher Options. - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -The object is created twice, hence the started Eventloop and finished destruction lines appear twice. -``` -NORMAL TESTING... -received event: test/0; data: 47 -received event: test/1 - -TIMEOUT TESTING... -received event: test/0 - -TIMEOUT for event: test/0 -I (10419) ESP Event C++ Async: Finished example -``` diff --git a/examples/cxx/experimental/esp_event_async_cxx/main/CMakeLists.txt b/examples/cxx/experimental/esp_event_async_cxx/main/CMakeLists.txt deleted file mode 100644 index 3eb45d4792..0000000000 --- a/examples/cxx/experimental/esp_event_async_cxx/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "esp_event_async_cxx_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp b/examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp deleted file mode 100644 index 91156c29d1..0000000000 --- a/examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* ESP Event C++ Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include "esp_event_cxx.hpp" -#include "esp_event.h" -#include "esp_err.h" - -using namespace idf::event; -using namespace std; - -ESP_EVENT_DEFINE_BASE(TEST_EVENT_BASE); -const ESPEventID TEST_EVENT_ID_0(0); -const ESPEventID TEST_EVENT_ID_1(1); - -ESPEvent TEMPLATE_EVENT_0(TEST_EVENT_BASE, TEST_EVENT_ID_0); -ESPEvent TEMPLATE_EVENT_1(TEST_EVENT_BASE, TEST_EVENT_ID_1); - -// We use "normal" static functions here. However, passing std::function types also works with -// ESPEventLoop::register_event() and ESPEventLoop::register_event_timed(), allowing to reference custom data. -static void callback(const ESPEvent &event, void *data) -{ - cout << "received event: " << event.base << "/" << event.id; - if (data) { - cout << "; data: " << *(static_cast(data)); - } - cout << endl; -}; - -static void timeout_callback(const ESPEvent &event) -{ - cout << "TIMEOUT for event: " << event.base << "/" << event.id << endl; -}; - -extern "C" void app_main(void) -{ - { - cout << "Normal testing..." << endl; - ESPEventLoop loop; - int data = 47; - int captured_data = 42; - - unique_ptr reg_1 = loop.register_event(TEMPLATE_EVENT_0, - [captured_data](const ESPEvent &event, void *data) { - cout << "received event: " << event.base << "/" << event.id; - if (data) { - cout << "; event data: " << *(static_cast(data)); - } - cout << "; handler data: " << captured_data << endl; - }); - unique_ptr reg_2; - - // Run for 4 seconds... - for (int i = 0; i < 4; i++) { - switch (i) { - case 0: - // will be received - loop.post_event_data(TEMPLATE_EVENT_0, data); - break; - case 1: - // will NOT be received because TEST_EVENT_ID_1 hasn't been registered yet - loop.post_event_data(TEMPLATE_EVENT_1); - break; - case 2: - // register TEST_EVENT_ID_1 - reg_2 = loop.register_event(TEMPLATE_EVENT_1, callback); - // will be received - loop.post_event_data(TEMPLATE_EVENT_1); - break; - case 3: - // unregister callback with TEST_EVENT_ID_1 again - reg_2.reset(); - // will NOT be received - loop.post_event_data(TEMPLATE_EVENT_1); - break; - - } - this_thread::sleep_for(chrono::seconds(1)); - } - } - - { - cout << endl << "Timeout testing..." << endl; - ESPEventLoop loop; - - // Setting timeout and sending event early enough. - unique_ptr timed_reg = loop.register_event_timed(TEMPLATE_EVENT_0, - callback, - chrono::milliseconds(500), - timeout_callback); - loop.post_event_data(TEMPLATE_EVENT_0); - cout << endl; - - // Setting timeout and sending event too late. - // Note: the old registration will be properly unregistered by resetting the unique_ptr. - timed_reg = loop.register_event_timed(TEMPLATE_EVENT_0, - callback, - chrono::milliseconds(500), - timeout_callback); - this_thread::sleep_for(chrono::seconds(1)); - loop.post_event_data(TEMPLATE_EVENT_0); - - } - cout << "Finished example" << endl; -} diff --git a/examples/cxx/experimental/esp_event_async_cxx/sdkconfig.defaults b/examples/cxx/experimental/esp_event_async_cxx/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/esp_event_async_cxx/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/esp_event_cxx/CMakeLists.txt b/examples/cxx/experimental/esp_event_cxx/CMakeLists.txt deleted file mode 100644 index ce069a2320..0000000000 --- a/examples/cxx/experimental/esp_event_cxx/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# The following five lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -# (Not part of the boilerplate) -# This example uses an experimental c++ component. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp_event_cxx) diff --git a/examples/cxx/experimental/esp_event_cxx/README.md b/examples/cxx/experimental/esp_event_cxx/README.md deleted file mode 100644 index 9577bab5fc..0000000000 --- a/examples/cxx/experimental/esp_event_cxx/README.md +++ /dev/null @@ -1,47 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | - -# ESP Event synchronous example - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - - -## How to use example - -### Configure the project - -``` -idf.py menuconfig -``` - -* Set serial port under Serial Flasher Options. - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (409) ESP Event C++: started event loop -event base test, ID: 0; called first round -event base test, ID: 1; called first round -received timeout -event base test, ID: 0; called second round -event base test, ID: 1; called second round -event base test, ID: 0; called second round -event base test, ID: 1; called second round -event base test, ID: 0; called second round -event base test, ID: 1; called second round -event base test, ID: 0; called second round -event base test, ID: 1; called second round -I (10419) ESP Event C++: Missed: 0 events -``` diff --git a/examples/cxx/experimental/esp_event_cxx/main/CMakeLists.txt b/examples/cxx/experimental/esp_event_cxx/main/CMakeLists.txt deleted file mode 100644 index 8170a3920d..0000000000 --- a/examples/cxx/experimental/esp_event_cxx/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "esp_event_cxx_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp b/examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp deleted file mode 100644 index 7c9d974597..0000000000 --- a/examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* ESP Event C++ Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include -#include "esp_event_cxx.hpp" -#include "esp_event.h" -#include "esp_err.h" - -using namespace idf::event; -using namespace std; - -#define EVENT_NUM 10 - -ESP_EVENT_DEFINE_BASE(TEST_EVENT_BASE); -static ESPEventID TEST_EVENT_ID_0(0); -static ESPEventID TEST_EVENT_ID_1(1); - -// the events we want to register -static ESPEvent TEMPLATE_EVENT_0(TEST_EVENT_BASE, TEST_EVENT_ID_0); -static ESPEvent TEMPLATE_EVENT_1(TEST_EVENT_BASE, TEST_EVENT_ID_1); - -// helper function to post events, simulating an event source -void post_events() { - for (int i = 0; i < EVENT_NUM; i++) { - ESP_ERROR_CHECK(esp_event_post(TEST_EVENT_BASE, - i % 2 ? TEST_EVENT_ID_1.get_id() : TEST_EVENT_ID_0.get_id(), - nullptr, - 0, - portMAX_DELAY)); - this_thread::sleep_for(chrono::seconds(1)); - } -} - -extern "C" void app_main(void) -{ - ESPEventHandlerSync event_handler(make_shared()); - event_handler.listen_to(TEMPLATE_EVENT_0); - event_handler.listen_to(TEMPLATE_EVENT_1); - cout << "started event loop" << endl; - - thread th(post_events); - - // waiting for two events to be posted via post_events() - this_thread::sleep_for(chrono::milliseconds(1100)); - - // reading the two already received events, then running into timeout - for (;;) { - ESPEventHandlerSync::EventResultTimed result = event_handler.wait_event_for(std::chrono::milliseconds(500)); - - if (result.timeout) { // if timeout, then the default esp event will be sent with invalid base - break; - } else { - cout << "event base " << result.event.base - << ", ID: " << result.event.id - << "; called first round" << endl; - } - } - - cout << "received timeout" << endl; - this_thread::sleep_for(chrono::milliseconds(2000)); - - // Read the events we missed up until now and then continue reading - for (int i = 0; i < EVENT_NUM - 2; i++) { - ESPEventHandlerSync::EventResult result = event_handler.wait_event(); - cout << "event base " << result.event.base - << ", ID: " << result.event.id - << "; called second round" << endl; - } - - th.join(); - - // checking whether events were missed by the ESPEventHandlerSync class - cout << "Missed: " << event_handler.get_send_queue_errors() << " events" << endl; -} diff --git a/examples/cxx/experimental/esp_event_cxx/sdkconfig.defaults b/examples/cxx/experimental/esp_event_cxx/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/esp_event_cxx/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/CMakeLists.txt b/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/CMakeLists.txt deleted file mode 100644 index 15809a21ef..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -idf_build_get_property(target IDF_TARGET) - -idf_component_register(SRCS "esp_mqtt_cxx.cpp" - INCLUDE_DIRS "include" - ) - -if(TEST_BUILD) - message(STATUS "Test build") - idf_component_get_property(mqtt_dir mqtt COMPONENT_DIR) - idf_component_get_property(experimental_cpp_component_dir experimental_cpp_component COMPONENT_DIR) - idf_component_get_property(esp_common_dir esp_common COMPONENT_DIR) - idf_component_get_property(esp_event_dir esp_event COMPONENT_DIR) - target_include_directories(${COMPONENT_LIB} PUBLIC ${mqtt_dir}/esp-mqtt/include - ${esp_event_dir}/include - ${experimental_cpp_component_dir}/include - ${esp_common_dir}/include) - -else() - idf_component_get_property(mqtt_lib mqtt COMPONENT_LIB) - idf_component_get_property(log_lib log COMPONENT_LIB) - idf_component_get_property(experimental_cpp_component_lib experimental_cpp_component COMPONENT_LIB) - target_link_libraries(${COMPONENT_LIB} PUBLIC ${log_lib} ${mqtt_lib} ${experimental_cpp_component_lib}) -endif() diff --git a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/esp_mqtt_cxx.cpp b/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/esp_mqtt_cxx.cpp deleted file mode 100644 index 125e0aeec7..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/esp_mqtt_cxx.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#include "mqtt_client.h" -#include "esp_log.h" - -#include "esp_mqtt.hpp" -#include "esp_mqtt_client_config.hpp" - -namespace { - -// Helper for static assert. -template -constexpr bool always_false = false; - -template struct overloaded : Ts... { - using Ts::operator()...; -}; -template overloaded(Ts...) -> overloaded; - -using namespace idf::mqtt; - -/* - * This function is responsible for fill in the configurations for the broker related data - * of mqtt_client_config_t - */ -void config_broker(esp_mqtt_client_config_t &mqtt_client_cfg, BrokerConfiguration const &broker) -{ - std::visit(overloaded{ - [&mqtt_client_cfg](Host const & host) - { - mqtt_client_cfg.broker.address.hostname = host.address.c_str(); - mqtt_client_cfg.broker.address.path = host.path.c_str(); - mqtt_client_cfg.broker.address.transport = host.transport; - }, - [&mqtt_client_cfg](URI const & uri) - { - mqtt_client_cfg.broker.address.uri = uri.address.c_str(); - }, - []([[maybe_unused ]]auto & unknown) - { - static_assert(always_false, "Missing type handler for variant handler"); - } - }, - broker.address.address); - - std::visit(overloaded{ - []([[maybe_unused]]Insecure const & insecure) {}, - [&mqtt_client_cfg](GlobalCAStore const & use_global_store) - { - mqtt_client_cfg.broker.verification.use_global_ca_store = true; - }, - [&mqtt_client_cfg](CryptographicInformation const & certificates) - { - std::visit(overloaded{ - [&mqtt_client_cfg](PEM const & pem) - { - mqtt_client_cfg.broker.verification.certificate= pem.data; - }, [&mqtt_client_cfg](DER const & der) - { - mqtt_client_cfg.broker.verification.certificate = der.data; - mqtt_client_cfg.broker.verification.certificate_len = der.len; - }}, certificates); - }, - []([[maybe_unused]] PSK const & psk) {}, - []([[maybe_unused]] auto & unknown) - { - static_assert(always_false, "Missing type handler for variant handler"); - } - }, - broker.security); - mqtt_client_cfg.broker.address.port = broker.address.port; -} - -/* - * This function is responsible for fill in the configurations for the client credentials related data - * of mqtt_client_config_t - */ -void config_client_credentials(esp_mqtt_client_config_t &mqtt_client_cfg, ClientCredentials const &credentials) -{ - mqtt_client_cfg.credentials.client_id = credentials.client_id.has_value() ? credentials.client_id.value().c_str() : nullptr ; - mqtt_client_cfg.credentials.username = credentials.username.has_value() ? credentials.username.value().c_str() : nullptr ; - std::visit(overloaded{ - [&mqtt_client_cfg](Password const & password) - { - mqtt_client_cfg.credentials.authentication.password = password.data.c_str(); - }, - [](ClientCertificate const & certificate) {}, - [](SecureElement const & enable_secure_element) {}, - []([[maybe_unused ]]auto & unknown) - { - static_assert(always_false, "Missing type handler for variant handler"); - } - }, credentials.authentication); -} - -esp_mqtt_client_config_t make_config(BrokerConfiguration const &broker, ClientCredentials const &credentials, Configuration const &config) -{ - esp_mqtt_client_config_t mqtt_client_cfg{}; - config_broker(mqtt_client_cfg, broker); - config_client_credentials(mqtt_client_cfg, credentials); - return mqtt_client_cfg; -} -} - -namespace idf::mqtt { - -Client::Client(BrokerConfiguration const &broker, ClientCredentials const &credentials, Configuration const &config): Client(make_config(broker, credentials, config)) {} - -Client::Client(esp_mqtt_client_config_t const &config) : handler(esp_mqtt_client_init(&config)) -{ - if (handler == nullptr) { - throw MQTTException(ESP_FAIL); - }; - CHECK_THROW_SPECIFIC(esp_mqtt_client_register_event(handler.get(), MQTT_EVENT_ANY, mqtt_event_handler, this), mqtt::MQTTException); - CHECK_THROW_SPECIFIC(esp_mqtt_client_start(handler.get()), mqtt::MQTTException); -} - - -void Client::mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) noexcept -{ - ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32, base, event_id); - auto *event = static_cast(event_data); - auto &client = *static_cast(handler_args); - switch (event->event_id) { - case MQTT_EVENT_CONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); - client.on_connected(event); - break; - case MQTT_EVENT_DISCONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); - client.on_disconnected(event); - break; - - case MQTT_EVENT_SUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); - client.on_subscribed(event); - break; - case MQTT_EVENT_UNSUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); - client.on_unsubscribed(event); - break; - case MQTT_EVENT_PUBLISHED: - ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); - client.on_published(event); - break; - case MQTT_EVENT_DATA: - ESP_LOGI(TAG, "MQTT_EVENT_DATA"); - client.on_data(event); - break; - case MQTT_EVENT_ERROR: - ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - client.on_error(event); - break; - case MQTT_EVENT_BEFORE_CONNECT: - ESP_LOGI(TAG, "MQTT_EVENT_BEFORE_CONNECT"); - client.on_before_connect(event); - break; - default: - ESP_LOGI(TAG, "Other event id:%d", event->event_id); - break; - } -} - -void Client::on_error(esp_mqtt_event_handle_t const event) -{ - auto log_error_if_nonzero = [](const char *message, int error_code) { - if (error_code != 0) { - ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code); - } - }; - if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { - log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err); - log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err); - log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno); - ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); - } -} -void Client::on_disconnected(esp_mqtt_event_handle_t const event) -{ -} -void Client::on_subscribed(esp_mqtt_event_handle_t const event) -{ - printf("Subscribed to %.*s\r\n", event->topic_len, event->topic); -} -void Client::on_unsubscribed(esp_mqtt_event_handle_t const event) -{ -} -void Client::on_published(esp_mqtt_event_handle_t const event) -{ -} -void Client::on_before_connect(esp_mqtt_event_handle_t const event) -{ -} -void Client::on_connected(esp_mqtt_event_handle_t const event) -{ -} -void Client::on_data(esp_mqtt_event_handle_t const event) -{ -} - -std::optional Client::subscribe(std::string const &topic, QoS qos) -{ - auto res = esp_mqtt_client_subscribe(handler.get(), topic.c_str(), - static_cast(qos)); - if (res < 0) { - return std::nullopt; - } - return MessageID{res}; -} - -bool is_valid(std::string::const_iterator first, std::string::const_iterator last) -{ - if (first == last) { - return false; - } - auto number = std::find(first, last, '#'); - if (number != last) { - if (std::next(number) != last) { - return false; - } - if (*std::prev(number) != '/' && number != first) { - return false; - } - } - - auto plus = std::find(first, last, '+'); - if (plus != last) { - if (*(std::prev(plus)) != '/' && plus != first) { - return false; - } - if (std::next(plus) != last && *(std::next(plus)) != '/') { - return false; - } - } - return true; -} - -Filter::Filter(std::string user_filter) : filter(std::move(user_filter)) -{ - if (!is_valid(filter.begin(), filter.end())) { - throw std::domain_error("Forbidden Filter string"); - } -} - -[[nodiscard]] bool Filter::match(std::string::const_iterator topic_begin, std::string::const_iterator topic_end) const noexcept -{ - auto filter_begin = filter.begin(); - auto filter_end = filter.end(); - for (auto mismatch = std::mismatch(filter_begin, filter_end, topic_begin); - mismatch.first != filter.end() and mismatch.second != topic_end; - mismatch = std::mismatch(filter_begin, filter_end, topic_begin)) { - if (*mismatch.first != '#' and * mismatch.first != '+') { - return false; - } - if (*mismatch.first == '#') { - return true; - } - if (*mismatch.first == '+') { - filter_begin = advance(mismatch.first, filter_end); - topic_begin = advance(mismatch.second, topic_end); - if (filter_begin == filter_end and topic_begin != topic_end) { - return false; - } - } - } - return true; -} -const std::string &Filter::get() -{ - return filter; -} - -[[nodiscard]] bool Filter::match(char const *const first, int size) const noexcept -{ - auto it = static_cast(first); - return match(it, it + size); -} -std::string::const_iterator Filter::advance(std::string::const_iterator first, std::string::const_iterator last) const -{ - constexpr auto separator = '/'; - return std::find(first, last, separator); -} - -} diff --git a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp b/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp deleted file mode 100644 index 9d071f247a..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#pragma once - -#include -#ifndef __cpp_exceptions -#error MQTT class can only be used when __cpp_exceptions is enabled. Enable CONFIG_COMPILER_CXX_EXCEPTIONS in Kconfig -#endif - -#include -#include -#include -#include -#include -#include "esp_exception.hpp" -#include "esp_mqtt_client_config.hpp" -#include "mqtt_client.h" - -namespace idf::mqtt { - -constexpr auto *TAG = "mqtt_client_cpp"; - -struct MQTTException : ESPException { - using ESPException::ESPException; -}; - -/** - * @brief QoS for publish and subscribe - * - * Sets the QoS as: - * AtMostOnce : Best effort delivery of messages. Message loss can occur. - * AtLeastOnce : Guaranteed delivery of messages. Duplicates can occur. - * ExactlyOnce : Guaranteed delivery of messages exactly once. - * - */ -enum class QoS { AtMostOnce = 0, AtLeastOnce = 1, ExactlyOnce = 2 }; - -/** - * @brief Sets if a message must be retained. - * - * Retained messages are delivered to future subscribers that match the topic name. - * - */ -enum class Retain : bool { NotRetained = false, Retained = true }; - - -/** - * @brief Message class template to publish. - * - */ -template struct Message { - T data; /*!< Data for publish. Should be a contiguous type*/ - QoS qos = QoS::AtLeastOnce; /*!< QoS for the message*/ - Retain retain = Retain::NotRetained; /*!< Retention mark for the message.*/ -}; - -/** - * @brief Message type that holds std::string for data - * - */ -using StringMessage = Message; - -[[nodiscard]] bool filter_is_valid(std::string::const_iterator first, std::string::const_iterator last); - -/** - * @brief Filter for mqtt topic subscription. - * @throws std::domain_error if the filter is invalid. - * - * Topic filter. - * - */ -class Filter { -public: - - explicit Filter(std::string user_filter); - - - /** - * @brief Get the filter string used. - * - */ - const std::string &get(); - - /** - * @brief Checks the filter string against a topic name. - * - * @param first Iterator to the beginning of the sequence. - * @param last Iterator to the end of the sequence. - * - * @return true if the topic name match the filter - */ - [[nodiscard]] bool match(std::string::const_iterator first, - std::string::const_iterator last) const noexcept; - - /** - * @brief Checks the filter string against a topic name. - * - * @param topic topic name - * - * @return true if the topic name match the filter - */ - [[nodiscard]] bool match(const std::string &topic) const noexcept; - - /** - * @brief Checks the filter string against a topic name. - * - * @param first Char array with topic name. - * @param last Size of given topic name. - * - * @return true if the topic name match the filter - */ - [[nodiscard]] bool match(const char *const begin, int size) const noexcept; - - -private: - - /** - * @brief Advance the topic to the next level. - * - * An mqtt topic ends with a /. This function is used to iterate in topic levels. - * - * @return Iterator to the start of the topic. - */ - [[nodiscard]] std::string::const_iterator advance(std::string::const_iterator begin, std::string::const_iterator end) const; - std::string filter; -}; - -/** - * @brief Message identifier to track delivery. - * - */ -enum class MessageID : int {}; - -/** - * @brief Base class for MQTT client - * - * Should be inherited to provide event handlers. - */ -class Client { -public: - - Client(const BrokerConfiguration &broker,const ClientCredentials &credentials,const Configuration &config); - - Client(const esp_mqtt_client_config_t &config); - - /** - * @brief Subscribe to topic - * - * @param filter - * @param qos QoS subscription, defaulted as QoS::AtLeastOnce - * - * @return Optional MessageID. In case of failure std::nullopt is returned. - */ - std::optional subscribe(const std::string &filter, QoS qos = QoS::AtLeastOnce); - - /** - * @brief publish message to topic - * - * @tparam Container Type for data container. Must be a contiguous memory. - * @param topic Topic name - * @param message Message struct containing data, qos and retain configuration. - * - * @return Optional MessageID. In case of failure std::nullopt is returned. - */ - template std::optional publish(const std::string &topic, const Message& message) - { - return publish(topic, std::begin(message.data), std::end(message.data), message.qos, message.retain); - } - - /** - * @brief publish message to topic - * - * @tparam InputIt Input data iterator type. - * @param topic Topic name - * @param first, last Iterator pair of data to publish - * @param message Message struct containing data, qos and retain configuration. - * - * @return Optional MessageID. In case of failure std::nullopt is returned. - */ - template - std::optional publish(const std::string &topic, InputIt first, InputIt last, QoS qos = QoS::AtLeastOnce, Retain retain = Retain::NotRetained) - { - auto size = std::distance(first, last); - auto res = esp_mqtt_client_publish(handler.get(), topic.c_str(), &(*first), size, static_cast(qos), - static_cast(retain)); - if (res < 0) { - return std::nullopt; - } - return MessageID{res}; - } - - virtual ~Client() = default; - -protected: - struct MqttClientDeleter { - void operator()(esp_mqtt_client *client_handler) - { - esp_mqtt_client_destroy(client_handler); - } - }; - - using ClientHandler = std::unique_ptr; - ClientHandler handler; - -private: - static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, - void *event_data) noexcept; - void init(const esp_mqtt_client_config_t &config); - virtual void on_error(const esp_mqtt_event_handle_t event); - virtual void on_disconnected(const esp_mqtt_event_handle_t event); - virtual void on_subscribed(const esp_mqtt_event_handle_t event); - virtual void on_unsubscribed(const esp_mqtt_event_handle_t event); - virtual void on_published(const esp_mqtt_event_handle_t event); - virtual void on_before_connect(const esp_mqtt_event_handle_t event); - virtual void on_connected(const esp_mqtt_event_handle_t event) = 0; - virtual void on_data(const esp_mqtt_event_handle_t event) = 0; -}; -} // namespace idf::mqtt diff --git a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp b/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp deleted file mode 100644 index 0fbba636fc..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#pragma once - -#include -#include -#include -#include -#include - -#include "mqtt_client.h" - -namespace idf::mqtt { - - - -/** - * @brief Broker addresss - * - * Use this to set the broker without parsing the URI string. - * - */ -struct Host { - std::string address; /*!< Host name*/ - std::string path; /*!< Route path of the broker in host*/ - esp_mqtt_transport_t transport; /*!< Transport scheme to use. */ -}; - -/** - * @brief Broker addresss URI - * - * Use this to set the broker address using the URI. - * - */ -struct URI { - std::string address; /*!< Broker adddress URI*/ -}; - - -/** - * @brief Broker addresss. - * - */ -struct BrokerAddress { - std::variant address; /*!< Address, defined by URI or Host struct */ - uint32_t port = 0; /*!< Port used, defaults to 0 to select common port for the scheme used */ -}; - -/** - * @brief PEM formated data - * - * Store certificates, keys and cryptographic data. - * - */ -struct PEM { - const char *data; -}; - -/** - * @brief DER formated data - * - * Store certificates, keys and cryptographic data. - * - */ -struct DER { - const char *data; - size_t len; -}; - -/** - * @brief Holds cryptography related information - * - * Hold PEM or DER formated cryptographic data. - * - */ -using CryptographicInformation = std::variant; - - -/** - * @brief Do not verify broker certificate. - * - * To be used when doing MQTT over TLS connection but not verify broker's certificates. - * - */ -struct Insecure {}; - -/** - * @brief Use global CA store - * - * To be used when client should use the Global CA Store to get trusted certificates for the broker. - * - */ -struct GlobalCAStore {}; - -/** - * @brief Use a pre shared key for broker authentication. - * - * To be used when client should use a PSK to authenticate the broker. - * - */ -struct PSK { - const struct psk_key_hint *hint_key;/* Pointer to PSK struct defined in esp_tls.h to enable PSK authentication */ -}; - - -/** - * @brief Authentication method for Broker - * - * Selects the method for authentication based on the type it holds. - * - */ -using BrokerAuthentication = std::variant; - -/** - * @brief Password related data. - * - */ -struct Password { - std::string data; -}; - -/** - * @brief Data to authenticate client with certificates. - * - */ -struct ClientCertificate { - CryptographicInformation certificate; /*!< Certificate in PEM or DER format.*/ - CryptographicInformation key; /*!< Key data in PEM or DER format.*/ - std::optional key_password = std::nullopt; /*!< Optional password for key */ -}; - -/** - * @brief Used to select usage of Secure Element - * - * Enables the usage of the secure element present in ESP32-WROOM-32SE. - * - */ -struct SecureElement {}; - - -/** - * @brief Used to select usage of Digital Signature Peripheral. - * - * Enables the usage of the Digital Signature hardware accelerator. - * - */ -struct DigitalSignatureData { - void *ds_data; /* carrier of handle for digital signature parameters */ -}; - -using AuthenticationFactor = std::variant; - -struct BrokerConfiguration { - BrokerAddress address; - BrokerAuthentication security; -}; - -struct ClientCredentials { - std::optional username; // MQTT username - AuthenticationFactor authentication; - std::vector alpn_protos; /*!< List of supported application protocols to be used for ALPN */ - /* default is ``ESP32_%CHIPID%`` where %CHIPID% are last 3 bytes of MAC address in hex format */ - std::optional client_id = std::nullopt; -}; - -struct Event { - mqtt_event_callback_t event_handle; /*!< handle for MQTT events as a callback in legacy mode */ - esp_event_loop_handle_t event_loop_handle; /*!< handle for MQTT event loop library */ -}; - -struct LastWill { - const char *lwt_topic; /*!< LWT (Last Will and Testament) message topic (NULL by default) */ - const char *lwt_msg; /*!< LWT message (NULL by default) */ - int lwt_qos; /*!< LWT message qos */ - int lwt_retain; /*!< LWT retained message flag */ - int lwt_msg_len; /*!< LWT message length */ -}; - -struct Session { - LastWill last_will; - int disable_clean_session; /*!< mqtt clean session, default clean_session is true */ - int keepalive; /*!< mqtt keepalive, default is 120 seconds */ - bool disable_keepalive; /*!< Set disable_keepalive=true to turn off keep-alive mechanism, false by default (keepalive is active by default). Note: setting the config value `keepalive` to `0` doesn't disable keepalive feature, but uses a default keepalive period */ - esp_mqtt_protocol_ver_t protocol_ver; /*!< MQTT protocol version used for connection, defaults to value from menuconfig*/ -}; - -struct Task { - int task_prio; /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */ - int task_stack; /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */ -}; - -struct Connection { - esp_mqtt_transport_t transport; /*!< overrides URI transport */ - int reconnect_timeout_ms; /*!< Reconnect to the broker after this value in miliseconds if auto reconnect is not disabled (defaults to 10s) */ - int network_timeout_ms; /*!< Abort network operation if it is not completed after this value, in milliseconds (defaults to 10s) */ - int refresh_connection_after_ms; /*!< Refresh connection after this value (in milliseconds) */ - bool disable_auto_reconnect; /*!< this mqtt client will reconnect to server (when errors/disconnect). Set disable_auto_reconnect=true to disable */ -}; - -struct Configuration { - Event event; - Task task; - Session session; - Connection connection; - void *user_context; /*!< pass user context to this option, then can receive that context in ``event->user_context`` */ - int buffer_size; /*!< size of MQTT send/receive buffer, default is 1024 (only receive buffer size if ``out_buffer_size`` defined) */ - int out_buffer_size; /*!< size of MQTT output buffer. If not defined, both output and input buffers have the same size defined as ``buffer_size`` */ -}; - -} // idf::mqtt diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/CMakeLists.txt b/examples/cxx/experimental/esp_mqtt_cxx/ssl/CMakeLists.txt deleted file mode 100644 index 01cc1fff5f..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# The following four lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -# (Not part of the boilerplate) -# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common - $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component - $ENV{IDF_PATH}/examples/cxx/experimental/esp_mqtt_cxx/components) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(mqtt_ssl_cxx) - -target_add_binary_data(mqtt_ssl_cxx.elf "main/mqtt_eclipseprojects_io.pem" TEXT) diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/README.md b/examples/cxx/experimental/esp_mqtt_cxx/ssl/README.md deleted file mode 100644 index b5be4985c5..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/CMakeLists.txt b/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/CMakeLists.txt deleted file mode 100644 index e06e5975be..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "mqtt_ssl_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/Kconfig.projbuild b/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/Kconfig.projbuild deleted file mode 100644 index 6d8dc0a35b..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/Kconfig.projbuild +++ /dev/null @@ -1,9 +0,0 @@ -menu "Example Configuration" - - config BROKER_URI - string "Broker URL" - default "mqtts://mqtt.eclipse.org:8883" - help - URL of the broker to connect to - -endmenu diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipse_org.pem b/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipse_org.pem deleted file mode 100644 index 0002462ce8..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipse_org.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow -SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT -GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF -q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 -SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 -Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA -a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj -/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T -AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG -CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv -bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k -c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw -VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC -ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz -MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu -Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF -AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo -uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ -wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu -X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG -PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 -KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== ------END CERTIFICATE----- diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipseprojects_io.pem b/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipseprojects_io.pem deleted file mode 100644 index 43b222a60a..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_eclipseprojects_io.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw -WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg -RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP -R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx -sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm -NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg -Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG -/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB -Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA -FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw -AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw -Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB -gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W -PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl -ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz -CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm -lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 -avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 -yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O -yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids -hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ -HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv -MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX -nLRbwHOoq7hHwg== ------END CERTIFICATE----- diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp b/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp deleted file mode 100644 index 21fd2f9d4c..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* C++ MQTT (over TCP) Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include -#include -#include "esp_mqtt_client_config.hpp" -#include "nvs_flash.h" -#include "protocol_examples_common.h" - - -#include "esp_log.h" -#include "esp_mqtt.hpp" - -namespace { -constexpr auto *TAG = "MQTT_EXAMPLE"; - -extern const char mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipseprojects_io_pem_start"); -extern const char mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipseprojects_io_pem_end"); - -class MyClient final : public idf::mqtt::Client { -public: - using idf::mqtt::Client::Client; -private: - void on_connected(esp_mqtt_event_handle_t const event) override - { - using idf::mqtt::QoS; - subscribe(messages.get()); - subscribe(sent_load.get(), QoS::AtMostOnce); - } - void on_data(esp_mqtt_event_handle_t const event) override - { - if (messages.match(event->topic, event->topic_len)) { - ESP_LOGI(TAG, "Received in the messages topic"); - } - } - idf::mqtt::Filter messages{std::string{"$SYS/broker/messages/received"}}; - idf::mqtt::Filter sent_load{std::string{"$SYS/broker/load/+/sent"}}; -}; -} - -namespace mqtt = idf::mqtt; - -extern "C" void app_main(void) -{ - ESP_LOGI(TAG, "[APP] Startup.."); - ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size()); - ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); - - esp_log_level_set("*", ESP_LOG_INFO); - esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE); - esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); - esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. - * Read "Establishing Wi-Fi or Ethernet Connection" section in - * examples/protocols/README.md for more information about this function. - */ - ESP_ERROR_CHECK(example_connect()); - - mqtt::BrokerConfiguration broker{ - .address = {mqtt::URI{std::string{CONFIG_BROKER_URI}}}, - .security = mqtt::CryptographicInformation{mqtt::PEM{mqtt_eclipse_org_pem_start}} - }; - idf::mqtt::ClientCredentials credentials{}; - idf::mqtt::Configuration config{}; - - MyClient client{broker, credentials, config}; - while (true) { - constexpr TickType_t xDelay = 500 / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); - } -} diff --git a/examples/cxx/experimental/esp_mqtt_cxx/ssl/sdkconfig.defaults b/examples/cxx/experimental/esp_mqtt_cxx/ssl/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/ssl/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/CMakeLists.txt b/examples/cxx/experimental/esp_mqtt_cxx/tcp/CMakeLists.txt deleted file mode 100644 index ef6daba536..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# The following four lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -# (Not part of the boilerplate) -# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common - $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component - $ENV{IDF_PATH}/examples/cxx/experimental/esp_mqtt_cxx/components) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(mqtt_tcp_cxx) diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/README.md b/examples/cxx/experimental/esp_mqtt_cxx/tcp/README.md deleted file mode 100644 index b5be4985c5..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/CMakeLists.txt b/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/CMakeLists.txt deleted file mode 100644 index eeaa9534e5..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "mqtt_tcp_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/Kconfig.projbuild b/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/Kconfig.projbuild deleted file mode 100644 index 34c04a02cb..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/Kconfig.projbuild +++ /dev/null @@ -1,9 +0,0 @@ -menu "Example Configuration" - - config BROKER_URL - string "Broker URL" - default "mqtt://mqtt.eclipse.org" - help - URL of the broker to connect to - -endmenu diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp b/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp deleted file mode 100644 index c1e6f3b77e..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* C++ MQTT (over TCP) Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include - -#include "nvs_flash.h" -#include "protocol_examples_common.h" - -#include "esp_log.h" -#include "esp_mqtt.hpp" -#include "esp_mqtt_client_config.hpp" - -namespace mqtt = idf::mqtt; - -namespace { -constexpr auto *TAG = "MQTT_EXAMPLE"; - -class MyClient final : public mqtt::Client { -public: - using mqtt::Client::Client; - -private: - void on_connected(esp_mqtt_event_handle_t const event) override - { - using mqtt::QoS; - subscribe(messages.get()); - subscribe(sent_load.get(), QoS::AtMostOnce); - } - void on_data(esp_mqtt_event_handle_t const event) override - { - if (messages.match(event->topic, event->topic_len)) { - ESP_LOGI(TAG, "Received in the messages topic"); - } - } - mqtt::Filter messages{"$SYS/broker/messages/received"}; - mqtt::Filter sent_load{"$SYS/broker/load/+/sent"}; -}; -} - -extern "C" void app_main(void) -{ - ESP_LOGI(TAG, "[APP] Startup.."); - ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size()); - ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); - - esp_log_level_set("*", ESP_LOG_INFO); - esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE); - esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); - esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. - * Read "Establishing Wi-Fi or Ethernet Connection" section in - * examples/protocols/README.md for more information about this function. - */ - ESP_ERROR_CHECK(example_connect()); - - mqtt::BrokerConfiguration broker{ - .address = {mqtt::URI{std::string{CONFIG_BROKER_URL}}}, - .security = mqtt::Insecure{} - }; - mqtt::ClientCredentials credentials{}; - mqtt::Configuration config{}; - - MyClient client{broker, credentials, config}; - - while (true) { - constexpr TickType_t xDelay = 500 / portTICK_PERIOD_MS; - vTaskDelay(xDelay); - } -} diff --git a/examples/cxx/experimental/esp_mqtt_cxx/tcp/sdkconfig.defaults b/examples/cxx/experimental/esp_mqtt_cxx/tcp/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/esp_mqtt_cxx/tcp/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/esp_timer_cxx/CMakeLists.txt b/examples/cxx/experimental/esp_timer_cxx/CMakeLists.txt deleted file mode 100644 index 241d24f519..0000000000 --- a/examples/cxx/experimental/esp_timer_cxx/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component") - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp_timer_cxx) diff --git a/examples/cxx/experimental/esp_timer_cxx/README.md b/examples/cxx/experimental/esp_timer_cxx/README.md deleted file mode 100644 index 19d82b3838..0000000000 --- a/examples/cxx/experimental/esp_timer_cxx/README.md +++ /dev/null @@ -1,51 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | - -# Example: ESPTimer C++ class - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -This example demonstrates usage of the ESPTimer c++ class in ESP-IDF. - -In this example, the `sdkconfig.defaults` file sets the `CONFIG_COMPILER_CXX_EXCEPTIONS` option. -This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling. -This is necessary for the C++ APIs. - -## How to use example - -### Hardware Required - -Any ESP32 family development board. - -### Configure the project - -``` -idf.py menuconfig -``` - -### Build and Flash - -``` -idf.py -p PORT flash monitor -``` - -(Replace PORT with the name of the serial port.) - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -Setting up timer to trigger in 500ms -timeout -Setting up timer to periodically every 200ms -periodic timeout -periodic timeout -periodic timeout -periodic timeout -periodic timeout - -``` - diff --git a/examples/cxx/experimental/esp_timer_cxx/main/CMakeLists.txt b/examples/cxx/experimental/esp_timer_cxx/main/CMakeLists.txt deleted file mode 100644 index 6b245fe111..0000000000 --- a/examples/cxx/experimental/esp_timer_cxx/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "esp_timer_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp b/examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp deleted file mode 100644 index a79856a75f..0000000000 --- a/examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* ESP Timer C++ Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include -#include - -#include "esp_timer_cxx.hpp" -#include "esp_exception.hpp" - -using namespace std; -using namespace idf; -using namespace idf::esp_timer; - -extern "C" void app_main(void) -{ - try { - cout << "Setting up timer to trigger in 500ms" << endl; - ESPTimer timer([]() { cout << "timeout" << endl; }); - timer.start(chrono::microseconds(200 * 1000)); - - this_thread::sleep_for(std::chrono::milliseconds(550)); - - cout << "Setting up timer to trigger periodically every 200ms" << endl; - ESPTimer timer2([]() { cout << "periodic timeout" << endl; }); - timer2.start_periodic(chrono::microseconds(200 * 1000)); - - this_thread::sleep_for(std::chrono::milliseconds(1050)); - } catch (const ESPException &e) { - cout << "Exception with error: " << e.error << endl; - } -} diff --git a/examples/cxx/experimental/esp_timer_cxx/sdkconfig.defaults b/examples/cxx/experimental/esp_timer_cxx/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/esp_timer_cxx/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt deleted file mode 100644 index 164a39845e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -idf_build_get_property(target IDF_TARGET) - -set(srcs "esp_timer_cxx.cpp" "esp_exception.cpp" "gpio_cxx.cpp" "i2c_cxx.cpp" "spi_cxx.cpp" "spi_host_cxx.cpp") -set(requires "esp_timer" "driver") - -if(NOT ${target} STREQUAL "linux") - list(APPEND srcs - "esp_event_api.cpp" - "esp_event_cxx.cpp") - list(APPEND requires "esp_event") -endif() - -idf_component_register(SRCS ${srcs} - INCLUDE_DIRS "include" - PRIV_INCLUDE_DIRS "private_include" - PRIV_REQUIRES freertos - REQUIRES ${requires}) diff --git a/examples/cxx/experimental/experimental_cpp_component/README.md b/examples/cxx/experimental/experimental_cpp_component/README.md deleted file mode 100644 index dba16a1881..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Experimental C++ Component - -*Warning:* This component is subject to change without notice. Don't consider it as a stable API. -It proposes future C++ interfaces of IDF components. - -# Usage/Build -To use and build this component, add it as an extra component in your project's cmake file: -```cmake -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component) -``` - -# Tests -To build the tests, first add them to the unit test's CMakeLists.txt: -```cmake -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") -``` -Then go to the unit test app's directory and run: -```bash -idf.py -T experimental_cpp_component build -``` diff --git a/examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp b/examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp deleted file mode 100644 index bc49a5b54e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "esp_event.h" -#include "esp_event_cxx.hpp" -#include "esp_event_api.hpp" - -#ifdef __cpp_exceptions - -namespace idf { - -namespace event { - -ESPEventAPIDefault::ESPEventAPIDefault() -{ - esp_err_t res = esp_event_loop_create_default(); - if (res != ESP_OK) { - throw idf::event::EventException(res); - } -} - -ESPEventAPIDefault::~ESPEventAPIDefault() -{ - esp_event_loop_delete_default(); -} - -esp_err_t ESPEventAPIDefault::handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void *event_handler_arg, - esp_event_handler_instance_t *instance) -{ - return esp_event_handler_instance_register(event_base, - event_id, - event_handler, - event_handler_arg, - instance); -} - -esp_err_t ESPEventAPIDefault::handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) -{ - return esp_event_handler_instance_unregister(event_base, event_id, instance); -} - -esp_err_t ESPEventAPIDefault::post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) -{ - return esp_event_post(event_base, - event_id, - event_data, - event_data_size, - ticks_to_wait); - -} - -ESPEventAPICustom::ESPEventAPICustom(const esp_event_loop_args_t &event_loop_args) -{ - esp_err_t res = esp_event_loop_create(&event_loop_args, &event_loop); - if (res != ESP_OK) { - throw idf::event::EventException(res); - } -} - -ESPEventAPICustom::~ESPEventAPICustom() -{ - esp_event_loop_delete(event_loop); -} - -esp_err_t ESPEventAPICustom::handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void *event_handler_arg, - esp_event_handler_instance_t *instance) -{ - return esp_event_handler_instance_register_with(event_loop, - event_base, - event_id, - event_handler, - event_handler_arg, - instance); -} - -esp_err_t ESPEventAPICustom::handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) -{ - return esp_event_handler_instance_unregister_with(event_loop, event_base, event_id, instance); -} - -esp_err_t ESPEventAPICustom::post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) -{ - return esp_event_post_to(event_loop, - event_base, - event_id, - event_data, - event_data_size, - ticks_to_wait); -} - -esp_err_t ESPEventAPICustom::run(TickType_t ticks_to_run) -{ - return esp_event_loop_run(event_loop, ticks_to_run); -} - -} // event - -} // idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp deleted file mode 100644 index e363861e2e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "esp_event_cxx.hpp" - -#ifdef __cpp_exceptions - -using namespace idf::event; -using namespace std; - -namespace idf { - -namespace event { - -const std::chrono::milliseconds PLATFORM_MAX_DELAY_MS(portMAX_DELAY *portTICK_PERIOD_MS); - -ESPEventReg::ESPEventReg(std::function cb, - const ESPEvent& ev, - std::shared_ptr api) - : cb(cb), event(ev), api(api) -{ - if (!cb) throw EventException(ESP_ERR_INVALID_ARG); - if (!api) throw EventException(ESP_ERR_INVALID_ARG); - - esp_err_t reg_result = api->handler_register(ev.base, ev.id.get_id(), event_handler_hook, this, &instance); - if (reg_result != ESP_OK) { - throw ESPEventRegisterException(reg_result, event); - } -} - -ESPEventReg::~ESPEventReg() -{ - api->handler_unregister(event.base, event.id.get_id(), instance); -} - -void ESPEventReg::dispatch_event_handling(ESPEvent event, void *event_data) -{ - cb(event, event_data); -} - -void ESPEventReg::event_handler_hook(void *handler_arg, - esp_event_base_t event_base, - int32_t event_id, - void *event_data) -{ - ESPEventReg *object = static_cast(handler_arg); - object->dispatch_event_handling(ESPEvent(event_base, ESPEventID(event_id)), event_data); -} - -ESPEventRegTimed::ESPEventRegTimed(std::function cb, - const ESPEvent& ev, - std::function timeout_cb, - const std::chrono::microseconds &timeout, - std::shared_ptr api) - : ESPEventReg(cb, ev, api), timeout_cb(timeout_cb) -{ - if (!timeout_cb || timeout < MIN_TIMEOUT) { - throw EventException(ESP_ERR_INVALID_ARG); - } - - const esp_timer_create_args_t oneshot_timer_args { - timer_cb_hook, - static_cast(this), - ESP_TIMER_TASK, - "event", - false // skip_unhandled_events - }; - - esp_err_t res = esp_timer_create(&oneshot_timer_args, &timer); - if (res != ESP_OK) { - throw EventException(res); - } - - esp_err_t timer_result = esp_timer_start_once(timer, timeout.count()); - if (timer_result != ESP_OK) { - esp_timer_delete(timer); - throw EventException(timer_result); - } -} - -ESPEventRegTimed::~ESPEventRegTimed() -{ - std::lock_guard guard(timeout_mutex); - esp_timer_stop(timer); - esp_timer_delete(timer); - // TODO: is it guaranteed that there is no pending timer callback for timer? -} - -void ESPEventRegTimed::dispatch_event_handling(ESPEvent event, void *event_data) -{ - if (timeout_mutex.try_lock()) { - esp_timer_stop(timer); - cb(event, event_data); - timeout_mutex.unlock(); - } -} - -void ESPEventRegTimed::timer_cb_hook(void *arg) -{ - ESPEventRegTimed *object = static_cast(arg); - if (object->timeout_mutex.try_lock()) { - object->timeout_cb(object->event); - object->api->handler_unregister(object->event.base, object->event.id.get_id(), object->instance); - object->timeout_mutex.unlock(); - } -} - -ESPEventLoop::ESPEventLoop(std::shared_ptr api) : api(api) { - if (!api) throw EventException(ESP_ERR_INVALID_ARG); -} - -ESPEventLoop::~ESPEventLoop() { } - -unique_ptr ESPEventLoop::register_event(const ESPEvent &event, - function cb) -{ - return unique_ptr(new ESPEventReg(cb, event, api)); -} - -std::unique_ptr ESPEventLoop::register_event_timed(const ESPEvent &event, - std::function cb, - const std::chrono::microseconds &timeout, - std::function timer_cb) -{ - return std::unique_ptr(new ESPEventRegTimed(cb, event, timer_cb, timeout, api)); -} - -void ESPEventLoop::post_event_data(const ESPEvent &event, - const chrono::milliseconds &wait_time) -{ - esp_err_t result = api->post(event.base, - event.id.get_id(), - nullptr, - 0, - convert_ms_to_ticks(wait_time)); - - if (result != ESP_OK) { - throw ESPException(result); - } -} - -ESPEventHandlerSync::ESPEventHandlerSync(std::shared_ptr event_loop, - size_t queue_max_size, - TickType_t queue_send_timeout) - : send_queue_errors(0), - queue_send_timeout(queue_send_timeout), - event_loop(event_loop) -{ - if (!event_loop) throw EventException(ESP_ERR_INVALID_ARG); - if (queue_max_size < 1) throw EventException(ESP_ERR_INVALID_ARG); - - event_queue = xQueueCreate(queue_max_size, sizeof(EventResult)); - if (event_queue == nullptr) { - esp_event_loop_delete_default(); - throw EventException(ESP_FAIL); - } -} - -ESPEventHandlerSync::~ESPEventHandlerSync() -{ - vQueueDelete(event_queue); -} - -ESPEventHandlerSync::EventResult ESPEventHandlerSync::wait_event() -{ - EventResult event_result; - BaseType_t result = pdFALSE; - while (result != pdTRUE) { - result = xQueueReceive(event_queue, &event_result, convert_ms_to_ticks(PLATFORM_MAX_DELAY_MS)); - } - - return event_result; -} - -ESPEventHandlerSync::EventResultTimed ESPEventHandlerSync::wait_event_for(const std::chrono::milliseconds &timeout) -{ - EventResult event_result; - BaseType_t result = xQueueReceive(event_queue, &event_result, convert_ms_to_ticks(timeout)); - - EventResultTimed event_result_timed(event_result, result != pdTRUE); - return event_result_timed; -} - -void ESPEventHandlerSync::listen_to(const ESPEvent &event) -{ - std::shared_ptr reg = event_loop->register_event(event, [this](const ESPEvent &event, void *data) { - EventResult result(event, data); - post_event(result); - }); - registry.push_back(reg); -} - -void ESPEventHandlerSync::post_event(const EventResult &event_result) -{ - BaseType_t result = xQueueSendToBack(event_queue, (void *) &event_result, queue_send_timeout); - if (result != pdTRUE) { - ++send_queue_errors; - } -} - -size_t ESPEventHandlerSync::get_send_queue_errors() const -{ - return send_queue_errors; -} - -TickType_t convert_ms_to_ticks(const std::chrono::milliseconds &time) -{ - return time.count() / portTICK_PERIOD_MS; -} - -} // namespace event - -} // namespace idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp b/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp deleted file mode 100644 index 3ac2661cd0..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifdef __cpp_exceptions - -#include "esp_exception.hpp" - -namespace idf { - -ESPException::ESPException(esp_err_t error) : error(error) { } - -const char *ESPException::what() const noexcept { - return esp_err_to_name(error); -} - -} // namespace idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp deleted file mode 100644 index f4b28440ca..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifdef __cpp_exceptions - -#include -#include "esp_timer_cxx.hpp" -#include "esp_exception.hpp" - -using namespace std; - -namespace idf { - -namespace esp_timer { - -ESPTimer::ESPTimer(function timeout_cb, const string &timer_name) - : timeout_cb(timeout_cb), name(timer_name) -{ - if (timeout_cb == nullptr) { - throw ESPException(ESP_ERR_INVALID_ARG); - } - - esp_timer_create_args_t timer_args = {}; - timer_args.callback = esp_timer_cb; - timer_args.arg = this; - timer_args.dispatch_method = ESP_TIMER_TASK; - timer_args.name = name.c_str(); - - CHECK_THROW(esp_timer_create(&timer_args, &timer_handle)); -} - -ESPTimer::~ESPTimer() -{ - // Ignore potential ESP_ERR_INVALID_STATE here to not throw exception. - esp_timer_stop(timer_handle); - esp_timer_delete(timer_handle); -} - -void ESPTimer::esp_timer_cb(void *arg) -{ - ESPTimer *timer = static_cast(arg); - timer->timeout_cb(); -} - -} // esp_timer - -} // idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/gpio_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/gpio_cxx.cpp deleted file mode 100644 index d2401ec6f7..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/gpio_cxx.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#if __cpp_exceptions - -#include -#include "driver/gpio.h" -#include "gpio_cxx.hpp" - -namespace idf { - -#define GPIO_CHECK_THROW(err) CHECK_THROW_SPECIFIC((err), GPIOException) - -namespace { -#if CONFIG_IDF_TARGET_LINUX -constexpr std::array INVALID_GPIOS = {24}; -#elif CONFIG_IDF_TARGET_ESP32 -constexpr std::array INVALID_GPIOS = {24}; -#elif CONFIG_IDF_TARGET_ESP32S2 -constexpr std::array INVALID_GPIOS = {22, 23, 24, 25}; -#elif CONFIG_IDF_TARGET_ESP32S3 -constexpr std::array INVALID_GPIOS = {22, 23, 24, 25}; -#elif CONFIG_IDF_TARGET_ESP32C3 -constexpr std::array INVALID_GPIOS = {}; -#elif CONFIG_IDF_TARGET_ESP32C2 -constexpr std::array INVALID_GPIOS = {}; -#elif CONFIG_IDF_TARGET_ESP32C6 -constexpr std::array INVALID_GPIOS = {}; -#elif CONFIG_IDF_TARGET_ESP32H2 -constexpr std::array INVALID_GPIOS = {}; -#else -#error "No GPIOs defined for the current target" -#endif - -gpio_num_t gpio_to_driver_type(const GPIONum &gpio_num) -{ - return static_cast(gpio_num.get_num()); -} - -} - -GPIOException::GPIOException(esp_err_t error) : ESPException(error) { } - -esp_err_t check_gpio_pin_num(uint32_t pin_num) noexcept -{ - if (pin_num >= GPIO_NUM_MAX) { - return ESP_ERR_INVALID_ARG; - } - - for (auto num: INVALID_GPIOS) - { - if (pin_num == num) { - return ESP_ERR_INVALID_ARG; - } - } - - return ESP_OK; -} - -esp_err_t check_gpio_drive_strength(uint32_t strength) noexcept -{ - if (strength >= GPIO_DRIVE_CAP_MAX) { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -GPIOPullMode GPIOPullMode::FLOATING() -{ - return GPIOPullMode(GPIO_FLOATING); -} - -GPIOPullMode GPIOPullMode::PULLUP() -{ - return GPIOPullMode(GPIO_PULLUP_ONLY); -} - -GPIOPullMode GPIOPullMode::PULLDOWN() -{ - return GPIOPullMode(GPIO_PULLDOWN_ONLY); -} - -GPIOWakeupIntrType GPIOWakeupIntrType::LOW_LEVEL() -{ - return GPIOWakeupIntrType(GPIO_INTR_LOW_LEVEL); -} - -GPIOWakeupIntrType GPIOWakeupIntrType::HIGH_LEVEL() -{ - return GPIOWakeupIntrType(GPIO_INTR_HIGH_LEVEL); -} - -GPIODriveStrength GPIODriveStrength::DEFAULT() -{ - return MEDIUM(); -} - -GPIODriveStrength GPIODriveStrength::WEAK() -{ - return GPIODriveStrength(GPIO_DRIVE_CAP_0); -} - -GPIODriveStrength GPIODriveStrength::LESS_WEAK() -{ - return GPIODriveStrength(GPIO_DRIVE_CAP_1); -} - -GPIODriveStrength GPIODriveStrength::MEDIUM() -{ - return GPIODriveStrength(GPIO_DRIVE_CAP_2); -} - -GPIODriveStrength GPIODriveStrength::STRONGEST() -{ - return GPIODriveStrength(GPIO_DRIVE_CAP_3); -} - -GPIOBase::GPIOBase(GPIONum num) : gpio_num(num) -{ - GPIO_CHECK_THROW(gpio_reset_pin(gpio_to_driver_type(gpio_num))); -} - -void GPIOBase::hold_en() -{ - GPIO_CHECK_THROW(gpio_hold_en(gpio_to_driver_type(gpio_num))); -} - -void GPIOBase::hold_dis() -{ - GPIO_CHECK_THROW(gpio_hold_dis(gpio_to_driver_type(gpio_num))); -} - -void GPIOBase::set_drive_strength(GPIODriveStrength strength) -{ - GPIO_CHECK_THROW(gpio_set_drive_capability(gpio_to_driver_type(gpio_num), - static_cast(strength.get_strength()))); -} - -GPIO_Output::GPIO_Output(GPIONum num) : GPIOBase(num) -{ - GPIO_CHECK_THROW(gpio_set_direction(gpio_to_driver_type(gpio_num), GPIO_MODE_OUTPUT)); -} - -void GPIO_Output::set_high() -{ - GPIO_CHECK_THROW(gpio_set_level(gpio_to_driver_type(gpio_num), 1)); -} - -void GPIO_Output::set_low() -{ - GPIO_CHECK_THROW(gpio_set_level(gpio_to_driver_type(gpio_num), 0)); -} - -GPIODriveStrength GPIOBase::get_drive_strength() -{ - gpio_drive_cap_t strength; - GPIO_CHECK_THROW(gpio_get_drive_capability(gpio_to_driver_type(gpio_num), &strength)); - return GPIODriveStrength(static_cast(strength)); -} - -GPIOInput::GPIOInput(GPIONum num) : GPIOBase(num) -{ - GPIO_CHECK_THROW(gpio_set_direction(gpio_to_driver_type(gpio_num), GPIO_MODE_INPUT)); -} - -GPIOLevel GPIOInput::get_level() const noexcept -{ - int level = gpio_get_level(gpio_to_driver_type(gpio_num)); - if (level) { - return GPIOLevel::HIGH; - } else { - return GPIOLevel::LOW; - } -} - -void GPIOInput::set_pull_mode(GPIOPullMode mode) -{ - GPIO_CHECK_THROW(gpio_set_pull_mode(gpio_to_driver_type(gpio_num), - static_cast(mode.get_pull_mode()))); -} - -void GPIOInput::wakeup_enable(GPIOWakeupIntrType interrupt_type) -{ - GPIO_CHECK_THROW(gpio_wakeup_enable(gpio_to_driver_type(gpio_num), - static_cast(interrupt_type.get_level()))); -} - -void GPIOInput::wakeup_disable() -{ - GPIO_CHECK_THROW(gpio_wakeup_disable(gpio_to_driver_type(gpio_num))); -} - -GPIO_OpenDrain::GPIO_OpenDrain(GPIONum num) : GPIOInput(num) -{ - GPIO_CHECK_THROW(gpio_set_direction(gpio_to_driver_type(gpio_num), GPIO_MODE_INPUT_OUTPUT_OD)); -} - -void GPIO_OpenDrain::set_floating() -{ - GPIO_CHECK_THROW(gpio_set_level(gpio_to_driver_type(gpio_num), 1)); -} - -void GPIO_OpenDrain::set_low() -{ - GPIO_CHECK_THROW(gpio_set_level(gpio_to_driver_type(gpio_num), 0)); -} - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/CMakeLists.txt deleted file mode 100644 index 29440b7954..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) - -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") -project(test_esp_timer_cxx_host) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/README.md b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/README.md deleted file mode 100644 index 287456d261..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/README.md +++ /dev/null @@ -1,36 +0,0 @@ -| Supported Targets | Linux | -| ----------------- | ----- | - -# C++ ESPTimer test on Linux target - -This unit test tests basic functionality of the `ESPTimer` class. The test does not use mocks. Instead, it runs the whole implementation of the component on the Linux host. The test framework is CATCH. - -## Requirements - -* A Linux system -* The usual IDF requirements for Linux system, as described in the [Getting Started Guides](../../../../../../docs/en/get-started/index.rst). -* The host's gcc/g++ - -This application has been tested on Ubuntu 20.04 with `gcc` version *9.3.0*. - -## Build - -First, make sure that the target is set to Linux. Run `idf.py --preview set-target linux` if you are not sure. Then do a normal IDF build: `idf.py build`. - -## Run - -IDF monitor doesn't work yet for Linux. You have to run the app manually: - -```bash -build/test_esp_timer_cxx_host.elf -``` - -## Example Output - -Ideally, all tests pass, which is indicated by "All tests passed" in the last line: - -```bash -$ build/test_esp_timer_cxx_host.elf -=============================================================================== -All tests passed (9 assertions in 11 test cases) -``` diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/CMakeLists.txt deleted file mode 100644 index ae9f501091..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register(SRCS "esp_timer_test.cpp" - INCLUDE_DIRS - "." - $ENV{IDF_PATH}/tools/catch - REQUIRES cmock esp_timer experimental_cpp_component) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp deleted file mode 100644 index f379e6049c..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* ESP Timer C++ unit tests - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#define CATCH_CONFIG_MAIN - -#include -#include -#include "esp_err.h" -#include "esp_timer_cxx.hpp" - -#include "catch.hpp" - -extern "C" { -#include "Mockesp_timer.h" -} - -// TODO: IDF-2693, function definition just to satisfy linker, mock esp_common instead -const char *esp_err_to_name(esp_err_t code) { - return "test"; -} - -using namespace std; -using namespace idf; -using namespace idf::esp_timer; - -struct FixtureException : std::exception { - const char *what() const noexcept override { - return "CMock failed"; - } -}; - -struct TimerCreationFixture { - TimerCreationFixture(bool expect_stop = false) : out_handle(reinterpret_cast(1)) - { - if (!TEST_PROTECT()) { - throw FixtureException(); - } - esp_timer_create_ExpectAnyArgsAndReturn(ESP_OK); - esp_timer_create_ReturnThruPtr_out_handle(&out_handle); - if (expect_stop) { - esp_timer_stop_ExpectAndReturn(out_handle, ESP_OK); // implementation may always call stop - } else { - esp_timer_stop_IgnoreAndReturn(ESP_OK); // implementation may always call stop - } - esp_timer_delete_ExpectAndReturn(out_handle, ESP_OK); - } - - virtual ~TimerCreationFixture() - { - Mockesp_timer_Verify(); - } - - esp_timer_handle_t out_handle; -}; - -static void (*trigger_timer_callback)(void *data) = nullptr; - -esp_err_t cmock_timer_create_callback(const esp_timer_create_args_t* create_args, esp_timer_handle_t* out_handle, int cmock_num_calls) -{ - trigger_timer_callback = create_args->callback; - return ESP_OK; -} - -struct TimerCallbackFixture : public TimerCreationFixture { - TimerCallbackFixture(bool expect_stop = false) : TimerCreationFixture(expect_stop) - { - esp_timer_create_AddCallback(cmock_timer_create_callback); - } - - ~TimerCallbackFixture() - { - trigger_timer_callback = nullptr; - } -}; - -TEST_CASE("get_time works") -{ - esp_timer_get_time_ExpectAndReturn(static_cast(0xfeeddeadbeef)); - - CHECK(get_time() == std::chrono::microseconds(0xfeeddeadbeef)); -} - -TEST_CASE("get_next_alarm works") -{ - esp_timer_get_next_alarm_ExpectAndReturn(static_cast(47u)); - - CHECK(get_next_alarm() == std::chrono::microseconds(47u)); -} - -TEST_CASE("ESPTimer null function") -{ - CHECK_THROWS_AS(ESPTimer(nullptr), ESPException&); -} - -TEST_CASE("ESPTimer empty std::function") -{ - function nothing; - CHECK_THROWS_AS(ESPTimer(nothing, "test"), ESPException&); -} - -TEST_CASE("ESPTimer initializes and deletes itself") -{ - TimerCreationFixture fix; - - function timer_cb = [&]() { }; - - ESPTimer(timer_cb, "test"); -} - -TEST_CASE("ESPTimer start throws on invalid state failure") -{ - TimerCreationFixture fix; - esp_timer_start_once_ExpectAndReturn(fix.out_handle, 5000, ESP_ERR_INVALID_STATE); - - function timer_cb = [&]() { }; - - ESPTimer timer(timer_cb); - - CHECK_THROWS_AS(timer.start(chrono::microseconds(5000)), ESPException&); -} - -TEST_CASE("ESPTimer start periodically throws on invalid state failure") -{ - TimerCreationFixture fix; - esp_timer_start_periodic_ExpectAndReturn(fix.out_handle, 5000, ESP_ERR_INVALID_STATE); - - function timer_cb = [&]() { }; - - ESPTimer timer(timer_cb); - - CHECK_THROWS_AS(timer.start_periodic(chrono::microseconds(5000)), ESPException&); -} - -TEST_CASE("ESPTimer stopp throws on invaid state failure") -{ - TimerCreationFixture fix; - - // Overriding stop part of the fixture - esp_timer_stop_StopIgnore(); - esp_timer_stop_IgnoreAndReturn(ESP_ERR_INVALID_STATE); - - function timer_cb = [&]() { }; - - ESPTimer timer(timer_cb); - - CHECK_THROWS_AS(timer.stop(), ESPException&); -} - -TEST_CASE("ESPTimer stops in destructor") -{ - TimerCreationFixture fix(true); - esp_timer_start_once_ExpectAndReturn(fix.out_handle, 5000, ESP_OK); - - function timer_cb = [&]() { }; - - ESPTimer timer(timer_cb); - - timer.start(chrono::microseconds(5000)); -} - -TEST_CASE("ESPTimer stops correctly") -{ - TimerCreationFixture fix(true); - esp_timer_start_once_ExpectAndReturn(fix.out_handle, 5000, ESP_OK); - - // Additional stop needed because stop is called in ESPTimer::stop and ~ESPTimer. - esp_timer_stop_ExpectAndReturn(fix.out_handle, ESP_OK); - - function timer_cb = [&]() { }; - - ESPTimer timer(timer_cb); - - timer.start(chrono::microseconds(5000)); - - timer.stop(); -} - -TEST_CASE("ESPTimer callback works") -{ - TimerCallbackFixture fix; - int flag = 0; - - function timer_cb = [&]() { flag = 47; }; - - ESPTimer timer(timer_cb); - - trigger_timer_callback(&timer); - - REQUIRE(trigger_timer_callback != nullptr); - CHECK(flag == 47); -} diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/pytest_esp_timer_cxx.py b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/pytest_esp_timer_cxx.py deleted file mode 100644 index 5ff567d4c3..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/pytest_esp_timer_cxx.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import pytest -from pytest_embedded import Dut - - -@pytest.mark.linux -@pytest.mark.host_test -def test_esp_timer_cxx(dut: Dut) -> None: - dut.expect_exact('All tests passed', timeout=5) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/sdkconfig.defaults b/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/sdkconfig.defaults deleted file mode 100644 index a057733348..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n -CONFIG_IDF_TARGET="linux" -CONFIG_CXX_EXCEPTIONS=y diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp b/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp deleted file mode 100644 index 1de85ab65f..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include "catch.hpp" -#include "gpio_cxx.hpp" -#include "driver/spi_master.h" -#include "spi_cxx.hpp" -#include "i2c_cxx.hpp" -extern "C" { -#include "Mockgpio.h" -#include "Mockspi_master.h" -#include "Mockspi_common.h" -#include "Mocki2c.h" -} - -static const idf::GPIONum VALID_GPIO(18); - -/** - * Exception which is thrown if there is some internal cmock error which results in a - * longjump to the location of a TEST_PROTECT() call. - * - * @note This is a temporary solution until there is a better integration of CATCH into CMock. - * Note also that usually there will be a segfault when cmock fails a second time. - * This means paying attention to the first error message is crucial for removing errors. - */ -class CMockException : public std::exception { -public: - virtual ~CMockException() { } - - /** - * @return A reminder to look at the actual cmock log. - */ - virtual const char *what() const noexcept - { - return "CMock encountered an error. Look at the CMock log"; - } -}; - -/** - * Helper macro for setting up a test protect call for CMock. - * - * This macro should be used at the beginning of any test cases - * that uses generated CMock mock functions. - * This is necessary because CMock uses longjmp which screws up C++ stacks and - * also the CATCH mechanisms. - * - * @note This is a temporary solution until there is a better integration of CATCH into CMock. - * Note also that usually there will be a segfault when cmock fails a second time. - * This means paying attention to the first error message is crucial for removing errors. - */ -#define CMOCK_SETUP() \ - do { \ - if (!TEST_PROTECT()) { \ - throw CMockException(); \ - } \ - } \ - while (0) - -struct CMockFixture { - CMockFixture() - { - CMOCK_SETUP(); - } - - ~CMockFixture() - { - // Verify that all expected methods have been called. - Mockgpio_Verify(); - Mockspi_master_Verify(); - Mockspi_common_Verify(); - } -}; - -struct GPIOFixture : public CMockFixture { - GPIOFixture(idf::GPIONum gpio_num = idf::GPIONum(18), gpio_mode_t mode = GPIO_MODE_OUTPUT) - : CMockFixture(), num(gpio_num) - { - gpio_reset_pin_ExpectAndReturn(static_cast(num.get_num()), ESP_OK); - gpio_set_direction_ExpectAndReturn(static_cast(num.get_num()), mode, ESP_OK); - } - - idf::GPIONum num; -}; - -struct SPIFix; -struct SPIDevFix; -struct SPITransactionDescriptorFix; -struct SPITransactionTimeoutFix; -struct SPITransactionFix; - -static SPIFix *g_fixture; -static SPIDevFix *g_dev_fixture; -static SPITransactionDescriptorFix *g_trans_desc_fixture; -static SPITransactionTimeoutFix *g_trans_timeout_fixture; -static SPITransactionFix *g_trans_fixture; - -struct SPIFix : public CMockFixture { - SPIFix(spi_host_device_t host_id = spi_host_device_t(1), - uint32_t mosi = 1, - uint32_t miso = 2, - uint32_t sclk = 3) : CMockFixture(), bus_config() { - bus_config.mosi_io_num = mosi; - bus_config.miso_io_num = miso; - bus_config.sclk_io_num = sclk; - bus_config.quadwp_io_num = -1; - bus_config.quadhd_io_num = -1; - - spi_bus_initialize_ExpectWithArrayAndReturn(host_id, &bus_config, 1, spi_common_dma_t::SPI_DMA_CH_AUTO, ESP_OK); - spi_bus_free_ExpectAnyArgsAndReturn(ESP_OK); - - g_fixture = this; - } - - ~SPIFix() { - g_fixture = nullptr; - } - - spi_bus_config_t bus_config; -}; - -struct QSPIFix : public SPIFix { - QSPIFix(spi_host_device_t host_id = spi_host_device_t(1), - uint32_t mosi = 1, - uint32_t miso = 2, - uint32_t sclk = 3, - uint32_t wp = 4, - uint32_t hd = 5) : SPIFix(host_id, mosi, miso, sclk) - { - bus_config.quadwp_io_num = wp; - bus_config.quadhd_io_num = hd; - } -}; - -enum class CreateAnd { - FAIL, - SUCCEED, - IGNORE -}; - -struct SPIDevFix { - SPIDevFix(CreateAnd flags) - : dev_handle(reinterpret_cast(47)), - dev_config() - { - dev_config.spics_io_num = 4; - if (flags == CreateAnd::FAIL) { - spi_bus_add_device_ExpectAnyArgsAndReturn(ESP_FAIL); - } else if (flags == CreateAnd::IGNORE) { - spi_bus_add_device_IgnoreAndReturn(ESP_OK); - spi_bus_remove_device_IgnoreAndReturn(ESP_OK); - } else { - spi_bus_add_device_AddCallback(add_dev_cb); - spi_bus_add_device_ExpectAnyArgsAndReturn(ESP_OK); - spi_bus_remove_device_ExpectAndReturn(dev_handle, ESP_OK); - } - - g_dev_fixture = this; - } - - ~SPIDevFix() - { - spi_bus_add_device_AddCallback(nullptr); - g_dev_fixture = nullptr; - } - - spi_device_handle_t dev_handle; - spi_device_interface_config_t dev_config; - - static esp_err_t add_dev_cb(spi_host_device_t host_id, - const spi_device_interface_config_t* dev_config, - spi_device_handle_t* handle, - int cmock_num_calls) - { - SPIDevFix *fix = static_cast(g_dev_fixture); - *handle = fix->dev_handle; - fix->dev_config = *dev_config; - return ESP_OK; - } -}; - -struct SPITransactionFix { - SPITransactionFix(esp_err_t get_trans_return = ESP_OK) : get_transaction_return(get_trans_return) - { - spi_device_queue_trans_AddCallback(queue_trans_cb); - spi_device_get_trans_result_AddCallback(get_trans_result_cb); - - spi_device_queue_trans_ExpectAnyArgsAndReturn(ESP_OK); - spi_device_get_trans_result_ExpectAnyArgsAndReturn(get_trans_return); - - g_trans_fixture = this; - } - - ~SPITransactionFix() - { - spi_device_get_trans_result_AddCallback(nullptr); - spi_device_queue_trans_AddCallback(nullptr); - g_trans_fixture = nullptr; - } - - static esp_err_t queue_trans_cb(spi_device_handle_t handle, - spi_transaction_t* trans_desc, - TickType_t ticks_to_wait, - int cmock_num_calls) - { - SPITransactionFix *fix = static_cast (g_trans_fixture); - fix->orig_trans = trans_desc; - return ESP_OK; - } - - static esp_err_t get_trans_result_cb(spi_device_handle_t handle, - spi_transaction_t** trans_desc, - TickType_t ticks_to_wait, - int cmock_num_calls) - { - SPITransactionFix *fix = static_cast (g_trans_fixture); - - *trans_desc = fix->orig_trans; - - return fix->get_transaction_return; - } - - esp_err_t get_transaction_return; - spi_transaction_t *orig_trans; -}; - -struct SPITransactionDescriptorFix { - SPITransactionDescriptorFix(size_t size = 1, bool ignore_handle = false, TickType_t wait_time = portMAX_DELAY) - : size(size), handle(reinterpret_cast(0x01020304)) - { - spi_device_queue_trans_AddCallback(queue_trans_cb); - spi_device_get_trans_result_AddCallback(get_trans_result_cb); - - spi_device_acquire_bus_ExpectAndReturn(handle, portMAX_DELAY, ESP_OK); - if (ignore_handle) { - spi_device_acquire_bus_IgnoreArg_device(); - } - spi_device_queue_trans_ExpectAndReturn(handle, nullptr, 0, ESP_OK); - spi_device_queue_trans_IgnoreArg_trans_desc(); - if (ignore_handle) { - spi_device_queue_trans_IgnoreArg_handle(); - } - - spi_device_get_trans_result_ExpectAndReturn(handle, nullptr, wait_time, ESP_OK); - spi_device_get_trans_result_IgnoreArg_trans_desc(); - if (ignore_handle) { - spi_device_get_trans_result_IgnoreArg_handle(); - } - spi_device_release_bus_ExpectAnyArgs(); - - g_trans_desc_fixture = this; - } - - ~SPITransactionDescriptorFix() - { - spi_device_get_trans_result_AddCallback(nullptr); - spi_device_queue_trans_AddCallback(nullptr); - g_trans_desc_fixture = nullptr; - } - - static esp_err_t queue_trans_cb(spi_device_handle_t handle, - spi_transaction_t* trans_desc, - TickType_t ticks_to_wait, - int cmock_num_calls) - { - SPITransactionDescriptorFix *fix = static_cast (g_trans_desc_fixture); - fix->orig_trans = trans_desc; - return ESP_OK; - } - - static esp_err_t get_trans_result_cb(spi_device_handle_t handle, - spi_transaction_t** trans_desc, - TickType_t ticks_to_wait, - int cmock_num_calls) - { - SPITransactionDescriptorFix *fix = static_cast (g_trans_desc_fixture); - - for (int i = 0; i < fix->size; i++) { - static_cast(fix->orig_trans->rx_buffer)[i] = fix->rx_data[i]; - } - - *trans_desc = fix->orig_trans; - - return ESP_OK; - } - - size_t size; - spi_transaction_t *orig_trans; - spi_device_handle_t handle; - std::vector tx_data; - std::vector rx_data; -}; - -struct I2CMasterFix { - I2CMasterFix(i2c_port_t port_arg = I2C_NUM_0) : i2c_conf(), port(port_arg) - { - i2c_conf.mode = i2c_mode_t::I2C_MODE_MASTER; - i2c_conf.sda_io_num = 2; - i2c_conf.scl_io_num = 1; - i2c_conf.sda_pullup_en = true; - i2c_conf.scl_pullup_en = true; - i2c_conf.master.clk_speed = 400000; - i2c_conf.clk_flags = 0; - i2c_param_config_ExpectWithArrayAndReturn(i2c_port_t(0), &i2c_conf, 1, ESP_OK); - i2c_driver_install_ExpectAndReturn(i2c_port_t(0), i2c_mode_t::I2C_MODE_MASTER, 0, 0, 0, ESP_OK); - i2c_driver_delete_ExpectAndReturn(i2c_port_t(0), ESP_OK); - } - - i2c_config_t i2c_conf; - i2c_port_t port; -}; - -#if CONFIG_SOC_I2C_SUPPORT_SLAVE -struct I2CSlaveFix { - I2CSlaveFix(CreateAnd flags, i2c_port_t port_arg = I2C_NUM_0, size_t buffer_size = 64) : i2c_conf(), port(port_arg) - { - if (flags == CreateAnd::SUCCEED) { - i2c_conf.mode = i2c_mode_t::I2C_MODE_SLAVE; - i2c_conf.sda_io_num = 2; - i2c_conf.scl_io_num = 1; - i2c_conf.sda_pullup_en = true; - i2c_conf.scl_pullup_en = true; - i2c_conf.slave.addr_10bit_en = 0; - i2c_conf.slave.slave_addr = 0x47; - i2c_param_config_ExpectWithArrayAndReturn(port, &i2c_conf, 1, ESP_OK); - i2c_driver_install_ExpectAndReturn(port, i2c_mode_t::I2C_MODE_SLAVE, buffer_size, buffer_size, 0, ESP_OK); - i2c_driver_delete_ExpectAndReturn(port, ESP_OK); - } else if (flags == CreateAnd::IGNORE) { - i2c_param_config_IgnoreAndReturn(ESP_OK); - i2c_driver_install_IgnoreAndReturn(ESP_OK); - i2c_driver_delete_IgnoreAndReturn(ESP_OK); - } else { - throw idf::I2CException(ESP_ERR_INVALID_ARG); - } - } - - i2c_config_t i2c_conf; - i2c_port_t port; -}; -#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE - -struct I2CCmdLinkFix -{ - I2CCmdLinkFix(uint8_t expected_addr, i2c_rw_t type = I2C_MASTER_WRITE) : dummy_handle(reinterpret_cast(0xbeef)) - { - i2c_cmd_link_create_ExpectAndReturn(&dummy_handle); - i2c_master_start_ExpectAndReturn(&dummy_handle, ESP_OK); - i2c_master_write_byte_ExpectAndReturn(&dummy_handle, expected_addr << 1 | type, true, ESP_OK); - i2c_cmd_link_delete_Expect(&dummy_handle); - } - - i2c_cmd_handle_t dummy_handle; -}; diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/CMakeLists.txt deleted file mode 100644 index 37c11659fa..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) - -# Overriding components which should be mocked -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") - -# Including experimental component here because it's outside IDF's main component directory -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") - -project(test_gpio_cxx_host) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/README.md b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/README.md deleted file mode 100644 index a376df2c64..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/README.md +++ /dev/null @@ -1,8 +0,0 @@ -| Supported Targets | Linux | -| ----------------- | ----- | - -# Build -`idf.py build` (sdkconfig.defaults sets the linux target by default) - -# Run -`build/test_gpio_cxx_host.elf` diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/CMakeLists.txt deleted file mode 100644 index 6f8842cefb..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -idf_component_get_property(spi_flash_dir spi_flash COMPONENT_DIR) -idf_component_get_property(cpp_component experimental_cpp_component COMPONENT_DIR) - -idf_component_register(SRCS "gpio_cxx_test.cpp" - "${cpp_component}/esp_exception.cpp" - "${cpp_component}/gpio_cxx.cpp" - INCLUDE_DIRS - "." - "${cpp_component}/host_test/fixtures" - "${cpp_component}/include" - "${cpp_component}/test" # FIXME for unity_cxx.hpp, make it generally available instead - $ENV{IDF_PATH}/tools/catch - REQUIRES driver cmock) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/gpio_cxx_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/gpio_cxx_test.cpp deleted file mode 100644 index a6aa647085..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/main/gpio_cxx_test.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - * - * GPIO C++ unit tests - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ -#define CATCH_CONFIG_MAIN - -#include -#include "esp_err.h" -#include "unity.h" -#include "freertos/FreeRTOS.h" -#include "freertos/portmacro.h" -#include "gpio_cxx.hpp" -#include "test_fixtures.hpp" - -#include "catch.hpp" - -extern "C" { -#include "Mockgpio.h" -} - -// TODO: IDF-2693, function definition just to satisfy linker, mock esp_common instead -const char *esp_err_to_name(esp_err_t code) { - return "test"; -} - -using namespace std; -using namespace idf; - -TEST_CASE("gpio num out of range") -{ - CHECK_THROWS_AS(GPIONum(-1), GPIOException&); - CHECK_THROWS_AS(GPIONum(static_cast(GPIO_NUM_MAX)), GPIOException&); - CHECK_THROWS_AS(GPIONum(24), GPIOException&); // On ESP32, 24 isn't a valid GPIO number -} - -TEST_CASE("gpio num operator") -{ - GPIONum gpio_num_0(18u); - GPIONum gpio_num_1(18u); - GPIONum gpio_num_2(19u); - - CHECK(gpio_num_0 == gpio_num_1); - CHECK(gpio_num_2 != gpio_num_1); -} - -TEST_CASE("drive strength out of range") -{ - CHECK_THROWS_AS(GPIODriveStrength(-1), GPIOException&); - CHECK_THROWS_AS(GPIODriveStrength(static_cast(GPIO_DRIVE_CAP_MAX)), GPIOException&); -} - -TEST_CASE("drive strength as expected") -{ - CHECK(GPIODriveStrength::DEFAULT().get_strength() == GPIO_DRIVE_CAP_2); - CHECK(GPIODriveStrength::WEAK().get_strength() == GPIO_DRIVE_CAP_0); - CHECK(GPIODriveStrength::LESS_WEAK().get_strength() == GPIO_DRIVE_CAP_1); - CHECK(GPIODriveStrength::MEDIUM().get_strength() == GPIO_DRIVE_CAP_2); - CHECK(GPIODriveStrength::STRONGEST().get_strength() == GPIO_DRIVE_CAP_3); -} - -TEST_CASE("pull mode create functions work as expected") -{ - CHECK(GPIOPullMode::FLOATING().get_pull_mode() == 3); - CHECK(GPIOPullMode::PULLUP().get_pull_mode() == 0); - CHECK(GPIOPullMode::PULLDOWN().get_pull_mode() == 1); -} - -TEST_CASE("GPIOIntrType create functions work as expected") -{ - CHECK(GPIOWakeupIntrType::LOW_LEVEL().get_level() == GPIO_INTR_LOW_LEVEL); - CHECK(GPIOWakeupIntrType::HIGH_LEVEL().get_level() == GPIO_INTR_HIGH_LEVEL); -} - -TEST_CASE("output resetting pin fails") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(GPIO_Output gpio(VALID_GPIO), GPIOException&); - - Mockgpio_Verify(); -} - -TEST_CASE("output setting direction fails") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAnyArgsAndReturn(ESP_OK); - gpio_set_direction_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(GPIO_Output gpio(VALID_GPIO), GPIOException&); - - Mockgpio_Verify(); -} - -TEST_CASE("output constructor sets correct arguments") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), ESP_OK); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), GPIO_MODE_OUTPUT, ESP_OK); - - GPIO_Output gpio(VALID_GPIO); - - Mockgpio_Verify(); -} - -TEST_CASE("output set high fails") -{ - GPIOFixture fix; - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 1, ESP_FAIL); - - GPIO_Output gpio(fix.num); - - CHECK_THROWS_AS(gpio.set_high(), GPIOException&); -} - -TEST_CASE("output set high success") -{ - GPIOFixture fix; - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 1, ESP_OK); - - GPIO_Output gpio(fix.num); - - gpio.set_high(); -} - -TEST_CASE("output set low fails") -{ - GPIOFixture fix; - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 0, ESP_FAIL); - - GPIO_Output gpio(fix.num); - - CHECK_THROWS_AS(gpio.set_low(), GPIOException&); -} - -TEST_CASE("output set low success") -{ - GPIOFixture fix; - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 0, ESP_OK); - - GPIO_Output gpio(fix.num); - - gpio.set_low(); -} - -TEST_CASE("output set drive strength") -{ - GPIOFixture fix(VALID_GPIO); - gpio_set_drive_capability_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_DRIVE_CAP_0, ESP_OK); - - GPIO_Output gpio(fix.num); - - gpio.set_drive_strength(GPIODriveStrength::WEAK()); -} - -TEST_CASE("output get drive strength") -{ - GPIOFixture fix(VALID_GPIO); - gpio_drive_cap_t drive_strength = GPIO_DRIVE_CAP_3; - gpio_get_drive_capability_ExpectAnyArgsAndReturn(ESP_OK); - gpio_get_drive_capability_ReturnThruPtr_strength(&drive_strength); - - GPIO_Output gpio(fix.num); - - CHECK(gpio.get_drive_strength() == GPIODriveStrength::STRONGEST()); -} - -TEST_CASE("GPIOInput setting direction fails") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAnyArgsAndReturn(ESP_OK); - gpio_set_direction_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(GPIOInput gpio(VALID_GPIO), GPIOException&); - - Mockgpio_Verify(); -} - -TEST_CASE("constructor sets correct arguments") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), ESP_OK); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), GPIO_MODE_INPUT, ESP_OK); - - GPIOInput gpio(VALID_GPIO); - - Mockgpio_Verify(); -} - -TEST_CASE("get level low") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_get_level_ExpectAndReturn(static_cast(fix.num.get_num()), 0); - - GPIOInput gpio(fix.num); - - CHECK(gpio.get_level() == GPIOLevel::LOW); -} - -TEST_CASE("get level high") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_get_level_ExpectAndReturn(static_cast(fix.num.get_num()), 1); - - GPIOInput gpio(fix.num); - - CHECK(gpio.get_level() == GPIOLevel::HIGH); -} - -TEST_CASE("set pull mode fails") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_pull_mode_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_FLOATING, ESP_FAIL); - - GPIOInput gpio(fix.num); - - CHECK_THROWS_AS(gpio.set_pull_mode(GPIOPullMode::FLOATING()), GPIOException&); -} - -TEST_CASE("GPIOInput set pull mode floating") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_pull_mode_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_FLOATING, ESP_OK); - - GPIOInput gpio(fix.num); - - gpio.set_pull_mode(GPIOPullMode::FLOATING()); -} - -TEST_CASE("GPIOInput set pull mode pullup") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_pull_mode_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_PULLUP_ONLY, ESP_OK); - - GPIOInput gpio(fix.num); - - gpio.set_pull_mode(GPIOPullMode::PULLUP()); -} - -TEST_CASE("GPIOInput set pull mode pulldown") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_pull_mode_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_PULLDOWN_ONLY, ESP_OK); - - GPIOInput gpio(fix.num); - - gpio.set_pull_mode(GPIOPullMode::PULLDOWN()); -} - -TEST_CASE("GPIOInput wake up enable fails") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_wakeup_enable_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_INTR_LOW_LEVEL, ESP_FAIL); - - GPIOInput gpio(fix.num); - - CHECK_THROWS_AS(gpio.wakeup_enable(GPIOWakeupIntrType::LOW_LEVEL()), GPIOException&); -} - -TEST_CASE("GPIOInput wake up enable high int") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_wakeup_enable_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_INTR_HIGH_LEVEL, ESP_OK); - - GPIOInput gpio(fix.num); - - gpio.wakeup_enable(GPIOWakeupIntrType::HIGH_LEVEL()); -} - -TEST_CASE("GPIOInput wake up disable fails") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_wakeup_disable_ExpectAndReturn(static_cast(fix.num.get_num()), ESP_FAIL); - - GPIOInput gpio(fix.num); - - CHECK_THROWS_AS(gpio.wakeup_disable(), GPIOException&); -} - -TEST_CASE("GPIOInput wake up disable high int") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_wakeup_disable_ExpectAndReturn(static_cast(fix.num.get_num()), ESP_OK); - - GPIOInput gpio(fix.num); - - gpio.wakeup_disable(); -} - -TEST_CASE("GPIO_OpenDrain setting direction fails") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAnyArgsAndReturn(ESP_OK); - gpio_set_direction_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(GPIO_OpenDrain gpio(VALID_GPIO), GPIOException&); - - Mockgpio_Verify(); -} - -TEST_CASE("GPIO_OpenDrain constructor sets correct arguments") -{ - CMOCK_SETUP(); - gpio_reset_pin_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), ESP_OK); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT, - ESP_OK); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - - GPIO_OpenDrain gpio(VALID_GPIO); - - Mockgpio_Verify(); -} - -TEST_CASE("GPIO_OpenDrain set floating fails") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 1, ESP_FAIL); - - GPIO_OpenDrain gpio(fix.num); - - CHECK_THROWS_AS(gpio.set_floating(), GPIOException&); -} - -TEST_CASE("GPIO_OpenDrain set floating success") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 1, ESP_OK); - - GPIO_OpenDrain gpio(fix.num); - - gpio.set_floating(); -} - -TEST_CASE("GPIO_OpenDrain set low fails") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 0, ESP_FAIL); - - GPIO_OpenDrain gpio(fix.num); - - CHECK_THROWS_AS(gpio.set_low(), GPIOException&); -} - -TEST_CASE("GPIO_OpenDrain set low success") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - gpio_set_level_ExpectAndReturn(static_cast(fix.num.get_num()), 0, ESP_OK); - - GPIO_OpenDrain gpio(fix.num); - - gpio.set_low(); -} - -TEST_CASE("GPIO_OpenDrain set drive strength") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - - gpio_set_drive_capability_ExpectAndReturn(static_cast(fix.num.get_num()), GPIO_DRIVE_CAP_0, ESP_OK); - GPIO_OpenDrain gpio(fix.num); - - gpio.set_drive_strength(GPIODriveStrength::WEAK()); -} - -TEST_CASE("GPIO_OpenDrain get drive strength") -{ - GPIOFixture fix(VALID_GPIO, GPIO_MODE_INPUT); - gpio_set_direction_ExpectAndReturn(static_cast(VALID_GPIO.get_num()), - GPIO_MODE_INPUT_OUTPUT_OD, - ESP_OK); - gpio_drive_cap_t drive_strength = GPIO_DRIVE_CAP_3; - gpio_get_drive_capability_ExpectAnyArgsAndReturn(ESP_OK); - gpio_get_drive_capability_ReturnThruPtr_strength(&drive_strength); - - GPIO_OpenDrain gpio(fix.num); - - CHECK(gpio.get_drive_strength() == GPIODriveStrength::STRONGEST()); -} diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/pytest_gpio_cxx.py b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/pytest_gpio_cxx.py deleted file mode 100644 index f070954501..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/pytest_gpio_cxx.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import pytest -from pytest_embedded import Dut - - -@pytest.mark.linux -@pytest.mark.host_test -def test_gpio_cxx(dut: Dut) -> None: - dut.expect_exact('All tests passed', timeout=5) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/sdkconfig.defaults b/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/sdkconfig.defaults deleted file mode 100644 index a057733348..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/gpio/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n -CONFIG_IDF_TARGET="linux" -CONFIG_CXX_EXCEPTIONS=y diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/CMakeLists.txt deleted file mode 100644 index 948f0697f5..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) - -# Overriding components which should be mocked -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer/") - -# Including experimental component here because it's outside IDF's main component directory -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") - -project(test_i2c_cxx_host) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/README.md b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/README.md deleted file mode 100644 index e2981b6ec1..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/README.md +++ /dev/null @@ -1,8 +0,0 @@ -| Supported Targets | Linux | -| ----------------- | ----- | - -# Build -`idf.py build` (sdkconfig.defaults sets the linux target by default) - -# Run -`build/host_i2c_cxx_test.elf` diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/CMakeLists.txt deleted file mode 100644 index 785828b3fd..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -idf_component_get_property(cpp_component experimental_cpp_component COMPONENT_DIR) - -idf_component_register(SRCS "i2c_cxx_test.cpp" - INCLUDE_DIRS - "." - "${cpp_component}/host_test/fixtures" - "${cpp_component}/private_include" - $ENV{IDF_PATH}/tools/catch - REQUIRES cmock driver experimental_cpp_component) - -target_link_libraries(${COMPONENT_LIB} -lpthread) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp deleted file mode 100644 index be28b99e0e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - * - * I2C C++ unit tests - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ -#define CATCH_CONFIG_MAIN -#include -#include "unity.h" -#include "freertos/FreeRTOS.h" -#include "freertos/portmacro.h" -#include "driver/i2c.h" -#include "i2c_cxx.hpp" -#include "system_cxx.hpp" -#include "test_fixtures.hpp" - -#include "catch.hpp" - -extern "C" { -#include "Mocki2c.h" -} - -// TODO: IDF-2693, function definition just to satisfy linker, mock esp_common instead -const char *esp_err_to_name(esp_err_t code) { - return "host_test error"; -} - -using namespace std; -using namespace idf; - -TEST_CASE("I2CNumber") -{ - CMockFixture fix; - CHECK(I2CNumber::I2C0().get_num() == 0); -} - -TEST_CASE("I2CAddr") -{ - CMockFixture fix; - CHECK_THROWS_AS(I2CAddress(-1), I2CException&); - I2CAddress(0); - I2CAddress(127); - CHECK_THROWS_AS(I2CAddress(128), I2CException&); - - I2CAddress addr(47); - CHECK(addr.get_addr() == 47); -} - -TEST_CASE("I2CMaster parameter configuration fails") -{ - CMockFixture fix; - i2c_param_config_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(I2CMaster(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)), I2CException&); -} - -TEST_CASE("I2CMaster driver install failure") -{ - CMockFixture fix; - i2c_param_config_ExpectAnyArgsAndReturn(ESP_OK); - i2c_driver_install_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(I2CMaster(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)), I2CException&); -} - -TEST_CASE("I2CMaster success") -{ - CMockFixture fix; - I2CMasterFix master_fix; - - I2CMaster(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)); -} - -TEST_CASE("I2CWrite empty data throws") -{ - CMockFixture fix; - std::vector empty; - CHECK_THROWS_AS(I2CWrite writer(empty), I2CException&); -} - -TEST_CASE("I2CRead zero length throws") -{ - CMockFixture fix; - std::vector empty; - CHECK_THROWS_AS(I2CRead reader(0), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer fails at link creation") -{ - CMockFixture fix; - i2c_cmd_link_create_ExpectAndReturn(nullptr); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer fails at start") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_IgnoreAndReturn(&dummy_handle); - i2c_master_start_ExpectAnyArgsAndReturn(ESP_FAIL); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer fails at write byte") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_IgnoreAndReturn(&dummy_handle); - i2c_master_start_IgnoreAndReturn(ESP_OK); - i2c_master_write_byte_ExpectAnyArgsAndReturn(ESP_FAIL); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer fails at write") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_IgnoreAndReturn(&dummy_handle); - i2c_master_start_IgnoreAndReturn(ESP_OK); - i2c_master_write_byte_IgnoreAndReturn(ESP_OK); - i2c_master_write_ExpectAnyArgsAndReturn(ESP_FAIL); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer fails at stop") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_IgnoreAndReturn(&dummy_handle); - i2c_master_start_IgnoreAndReturn(ESP_OK); - i2c_master_write_byte_IgnoreAndReturn(ESP_OK); - i2c_master_write_IgnoreAndReturn(ESP_OK); - i2c_master_stop_ExpectAnyArgsAndReturn(ESP_FAIL); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CWrite do_transfer execution times out") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_IgnoreAndReturn(&dummy_handle); - i2c_master_start_IgnoreAndReturn(ESP_OK); - i2c_master_write_byte_IgnoreAndReturn(ESP_OK); - i2c_master_write_IgnoreAndReturn(ESP_OK); - i2c_master_stop_IgnoreAndReturn(ESP_OK); - i2c_master_cmd_begin_ExpectAnyArgsAndReturn(ESP_ERR_TIMEOUT); - i2c_cmd_link_delete_Ignore(); - I2CWrite writer({47}); - - CHECK_THROWS_AS(writer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CTransferException&); -} - -TEST_CASE("I2CWrite calls driver correctly") -{ - CMockFixture fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_WRITE); - uint8_t expected_write [] = {0xAB, 0xBA}; - const size_t WRITE_SIZE = sizeof(expected_write); - const size_t EXPECTED_DATA_LEN = WRITE_SIZE; - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually write the data but for the tests it is enough for now - i2c_master_write_ExpectWithArrayAndReturn(&cmd_fix.dummy_handle, expected_write, WRITE_SIZE, EXPECTED_DATA_LEN, true, ESP_OK); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - std::vector WRITE_BYTES = {0xAB, 0xBA}; - I2CWrite write(WRITE_BYTES); - write.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)); -} - -TEST_CASE("I2CRead do_transfer fails at read") -{ - CMockFixture fix; - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - i2c_cmd_link_create_ExpectAndReturn(&dummy_handle); - i2c_master_start_ExpectAnyArgsAndReturn(ESP_OK); - i2c_master_write_byte_ExpectAnyArgsAndReturn(ESP_OK); - i2c_master_read_ExpectAnyArgsAndReturn(ESP_FAIL); - i2c_cmd_link_delete_Ignore(); - I2CRead reader(2); - - CHECK_THROWS_AS(reader.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)), I2CException&); -} - -TEST_CASE("I2CRead calls driver correctly") -{ - CMockFixture fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_READ); - uint8_t READ_DATA [] = {0xAB, 0xBA}; - const size_t READ_SIZE = sizeof(READ_DATA); - - i2c_master_read_ExpectAndReturn(&cmd_fix.dummy_handle, nullptr, READ_SIZE, i2c_ack_type_t::I2C_MASTER_LAST_NACK, ESP_OK); - i2c_master_read_IgnoreArg_data(); - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually read the data but for the tests it is enough for now - i2c_master_read_ReturnArrayThruPtr_data(READ_DATA, READ_SIZE); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CRead reader(READ_SIZE); - std::vector result = reader.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)); - CHECK(result[0] == 0xAB); - CHECK(result[1] == 0xBA); -} - -TEST_CASE("I2CComposed try to read size 0 throws") -{ - CMockFixture fix; - I2CComposed composed_transfer; - CHECK_THROWS_AS(composed_transfer.add_read(0), I2CException&); -} - -TEST_CASE("I2CComposed try to write empy vector throws") -{ - CMockFixture fix; - I2CComposed composed_transfer; - CHECK_THROWS_AS(composed_transfer.add_write({}), I2CException&); -} - -TEST_CASE("I2CComposed calls driver correctly") -{ - CMockFixture fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_WRITE); - uint8_t expected_write [] = {0x47, 0x48, 0x49}; - const size_t WRITE_SIZE = sizeof(expected_write); - const size_t EXPECTED_DATA_LEN = WRITE_SIZE; - uint8_t READ_DATA [] = {0xAB, 0xBA}; - const size_t READ_SIZE = sizeof(READ_DATA); - - // the write-read transaction with repeated start: - i2c_master_write_ExpectWithArrayAndReturn(&cmd_fix.dummy_handle, expected_write, WRITE_SIZE, EXPECTED_DATA_LEN, true, ESP_OK); - i2c_master_start_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_write_byte_ExpectAndReturn(&cmd_fix.dummy_handle, 0x47 << 1 | I2C_MASTER_READ, true, ESP_OK); - i2c_master_read_ExpectAndReturn(&cmd_fix.dummy_handle, nullptr, 2, i2c_ack_type_t::I2C_MASTER_LAST_NACK, ESP_OK); - i2c_master_read_IgnoreArg_data(); - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually read the data but for the tests it is enough for now - i2c_master_read_ReturnArrayThruPtr_data(READ_DATA, READ_SIZE); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CComposed composed_transfer; - composed_transfer.add_write({0x47, 0x48, 0x49}); - composed_transfer.add_read(READ_SIZE); - - vector > read_result = composed_transfer.do_transfer(I2CNumber::I2C0(), I2CAddress(0x47)); - - TEST_ASSERT_EQUAL(1, read_result.size()); - TEST_ASSERT_EQUAL(READ_SIZE, read_result[0].size()); - for (int i = 0; i < READ_SIZE; i++) { - TEST_ASSERT_EQUAL(READ_DATA[i], read_result[0][i]); - } -} - -TEST_CASE("I2CWrite transfer calls driver correctly") -{ - CMockFixture fix; - I2CMasterFix master_fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_WRITE); - uint8_t expected_write [] = {0xAB, 0xBA}; - const size_t WRITE_SIZE = sizeof(expected_write); - const size_t EXPECTED_DATA_LEN = WRITE_SIZE; - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually write the data but for the tests it is enough for now - i2c_master_write_ExpectWithArrayAndReturn(&cmd_fix.dummy_handle, expected_write, WRITE_SIZE, EXPECTED_DATA_LEN, true, ESP_OK); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CMaster master(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)); - std::vector WRITE_BYTES = {0xAB, 0xBA}; - auto writer = make_shared(WRITE_BYTES); - master.transfer(I2CAddress(0x47), writer); -} - -TEST_CASE("I2CMaster synchronous write") -{ - CMockFixture fix; - I2CMasterFix master_fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_WRITE); - uint8_t expected_write [] = {0xAB, 0xBA}; - const size_t WRITE_SIZE = sizeof(expected_write); - const size_t EXPECTED_DATA_LEN = WRITE_SIZE; - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually write the data but for the tests it is enough for now - i2c_master_write_ExpectWithArrayAndReturn(&cmd_fix.dummy_handle, expected_write, WRITE_SIZE, EXPECTED_DATA_LEN, true, ESP_OK); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CMaster master(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)); - std::vector WRITE_BYTES = {0xAB, 0xBA}; - master.sync_write(I2CAddress(0x47), WRITE_BYTES); -} - -TEST_CASE("I2CMaster synchronous read") -{ - CMockFixture fix; - I2CMasterFix master_fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_READ); - uint8_t READ_DATA [] = {0xAB, 0xBA}; - const size_t READ_SIZE = sizeof(READ_DATA); - - i2c_master_read_ExpectAndReturn(&cmd_fix.dummy_handle, nullptr, READ_SIZE, i2c_ack_type_t::I2C_MASTER_LAST_NACK, ESP_OK); - i2c_master_read_IgnoreArg_data(); - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually read the data but for the tests it is enough for now - i2c_master_read_ReturnArrayThruPtr_data(READ_DATA, READ_SIZE); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CMaster master(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)); - std::vector result = master.sync_read(I2CAddress(0x47), READ_SIZE); - - REQUIRE(result.size() == READ_SIZE); - CHECK(result[0] == 0xAB); - CHECK(result[1] == 0xBA); -} - -TEST_CASE("I2CMaster syncronous transfer (read and write)") -{ - CMockFixture fix; - I2CMasterFix master_fix; - I2CCmdLinkFix cmd_fix(0x47, I2C_MASTER_WRITE); - i2c_cmd_handle_t dummy_handle = reinterpret_cast(0xbeef); - uint8_t expected_write [] = {0x47, 0x48, 0x49}; - const size_t WRITE_SIZE = sizeof(expected_write); - const size_t EXPECTED_DATA_LEN = WRITE_SIZE; - uint8_t READ_DATA [] = {0xAB, 0xBA}; - const size_t READ_SIZE = sizeof(READ_DATA); - - // the write-read transaction with repeated start: - i2c_master_write_ExpectWithArrayAndReturn(&cmd_fix.dummy_handle, expected_write, WRITE_SIZE, EXPECTED_DATA_LEN, true, ESP_OK); - i2c_master_start_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_write_byte_ExpectAndReturn(&cmd_fix.dummy_handle, 0x47 << 1 | I2C_MASTER_READ, true, ESP_OK); - i2c_master_read_ExpectAndReturn(&cmd_fix.dummy_handle, nullptr, 2, i2c_ack_type_t::I2C_MASTER_LAST_NACK, ESP_OK); - i2c_master_read_IgnoreArg_data(); - - // note that this behavior is not entirely correct, in th real driver, only i2c_master_cmd_begin() - // will actually read the data but for the tests it is enough for now - i2c_master_read_ReturnArrayThruPtr_data(READ_DATA, READ_SIZE); - i2c_master_stop_ExpectAndReturn(&cmd_fix.dummy_handle, ESP_OK); - i2c_master_cmd_begin_ExpectAndReturn(I2C_NUM_0, &cmd_fix.dummy_handle, 1000 / portTICK_PERIOD_MS, ESP_OK); - - I2CMaster master(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), Frequency(400000)); - vector read_result = master.sync_transfer(I2CAddress(0x47), {0x47, 0x48, 0x49}, READ_SIZE); - - CHECK(read_result.size() == READ_SIZE); - for (int i = 0; i < READ_SIZE; i++) { - CHECK(read_result[i] == READ_DATA[i]); - } -} - -#if SOC_I2C_SUPPORT_SLAVE -TEST_CASE("I2CSlave parameter configuration fails") -{ - CMockFixture fix; - i2c_param_config_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(I2CSlave(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), I2CAddress(0x47), 64, 64), I2CException&); -} - -TEST_CASE("I2CSlave driver installation fails") -{ - CMockFixture fix; - i2c_param_config_IgnoreAndReturn(ESP_OK); - i2c_driver_install_IgnoreAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(I2CSlave (I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), I2CAddress(0x47), 64, 64), I2CException&); -} - -TEST_CASE("I2CSlave calls driver functions correctly") -{ - CMockFixture fix; - I2CSlaveFix slave_fix(CreateAnd::SUCCEED); - - I2CSlave slave(I2CNumber::I2C0(), SCL_GPIO(1), SDA_GPIO(2), I2CAddress(0x47), 64, 64); -} - -TEST_CASE("I2CSlave write fails") -{ - CMockFixture fix; - I2CSlaveFix slave_fix(CreateAnd::IGNORE); - const uint8_t WRITE_BUFFER[] = {0xAB, 0xCD}; - const size_t WRITE_BUFFER_LEN = sizeof(WRITE_BUFFER); - i2c_slave_write_buffer_ExpectAnyArgsAndReturn(-1); - - I2CSlave slave(I2CNumber::I2C0(), SCL_GPIO(3), SDA_GPIO(4), I2CAddress(0x47), 64, 64); - CHECK(slave.write_raw(WRITE_BUFFER, WRITE_BUFFER_LEN, chrono::milliseconds(0)) == -1); -} - -TEST_CASE("I2CSlave write calls driver functions correctly") -{ - CMockFixture fix; - I2CSlaveFix slave_fix(CreateAnd::IGNORE); - const uint8_t WRITE_BUFFER[] = {0xAB, 0xCD}; - const size_t WRITE_BUFFER_LEN = sizeof(WRITE_BUFFER); - i2c_slave_write_buffer_ExpectWithArrayAndReturn(0, - WRITE_BUFFER, - WRITE_BUFFER_LEN, - WRITE_BUFFER_LEN, - 500 / portTICK_PERIOD_MS, - WRITE_BUFFER_LEN); - - I2CSlave slave(I2CNumber::I2C0(), SCL_GPIO(3), SDA_GPIO(4), I2CAddress(0x47), 64, 64); - CHECK(slave.write_raw(WRITE_BUFFER, WRITE_BUFFER_LEN, chrono::milliseconds(500)) == WRITE_BUFFER_LEN); -} - -TEST_CASE("I2CSlave read fails") -{ - CMockFixture fix; - I2CSlaveFix slave_fix(CreateAnd::IGNORE); - const size_t READ_BUFFER_LEN = 2; - uint8_t read_buffer[READ_BUFFER_LEN]; - i2c_slave_read_buffer_ExpectAnyArgsAndReturn(-1); - - I2CSlave slave(I2CNumber::I2C0(), SCL_GPIO(3), SDA_GPIO(4), I2CAddress(0x47), 64, 64); - CHECK(slave.read_raw(read_buffer, READ_BUFFER_LEN, chrono::milliseconds(0)) == -1); -} - -TEST_CASE("I2CSlave read calls driver functions correctly") -{ - CMockFixture fix; - I2CSlaveFix slave_fix(CreateAnd::IGNORE); - uint8_t WRITE_BUFFER[] = {0xAB, 0xCD}; - const size_t BUFFER_LEN = sizeof(WRITE_BUFFER); - uint8_t read_buffer[BUFFER_LEN]; - i2c_slave_read_buffer_ExpectAndReturn(0, read_buffer, BUFFER_LEN, 500 / portTICK_PERIOD_MS, BUFFER_LEN); - i2c_slave_read_buffer_ReturnArrayThruPtr_data(WRITE_BUFFER, BUFFER_LEN); - - I2CSlave slave(I2CNumber::I2C0(), SCL_GPIO(3), SDA_GPIO(4), I2CAddress(0x47), 64, 64); - CHECK(slave.read_raw(read_buffer, BUFFER_LEN, chrono::milliseconds(500)) == BUFFER_LEN); - for (size_t i = 0; i < BUFFER_LEN; i++) { - CHECK(read_buffer[i] == WRITE_BUFFER[i]); - } -} -#endif // SOC_I2C_SUPPORT_SLAVE diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/pytest_i2c_cxx.py b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/pytest_i2c_cxx.py deleted file mode 100644 index 647cd8b631..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/pytest_i2c_cxx.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import pytest -from pytest_embedded import Dut - - -@pytest.mark.linux -@pytest.mark.host_test -def test_i2c_cxx(dut: Dut) -> None: - dut.expect_exact('All tests passed', timeout=5) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/sdkconfig.defaults b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/sdkconfig.defaults deleted file mode 100644 index a057733348..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n -CONFIG_IDF_TARGET="linux" -CONFIG_CXX_EXCEPTIONS=y diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/CMakeLists.txt deleted file mode 100644 index b0d4046a8d..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) - -# Overriding components which should be mocked -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/esp_timer/") - -# Including experimental component here because it's outside IDF's main component directory -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") - -project(test_spi_cxx_host) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/README.md b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/README.md deleted file mode 100644 index 3b6179a6e4..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/README.md +++ /dev/null @@ -1,8 +0,0 @@ -| Supported Targets | Linux | -| ----------------- | ----- | - -# Build -`idf.py build` (sdkconfig.defaults sets the linux target by default) - -# Run -`build/host_spi_cxx_test.elf` diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/CMakeLists.txt deleted file mode 100644 index fa465d396a..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -idf_component_get_property(cpp_component experimental_cpp_component COMPONENT_DIR) - -idf_component_register(SRCS "spi_cxx_test.cpp" - INCLUDE_DIRS - "." - "${cpp_component}/host_test/fixtures" - "${cpp_component}/private_include" - $ENV{IDF_PATH}/tools/catch - REQUIRES cmock driver experimental_cpp_component) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/spi_cxx_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/spi_cxx_test.cpp deleted file mode 100644 index 472c66fbfc..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/main/spi_cxx_test.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - * - * This test code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ - -#define CATCH_CONFIG_MAIN -#include -#include "unity.h" -#include "freertos/FreeRTOS.h" -#include "freertos/portmacro.h" -#include "spi_host_cxx.hpp" -#include "spi_host_private_cxx.hpp" -#include "system_cxx.hpp" -#include "test_fixtures.hpp" - -#include "catch.hpp" - -// TODO: IDF-2693, function definition just to satisfy linker, mock esp_common instead -const char *esp_err_to_name(esp_err_t code) { - return "host_test error"; -} - -using namespace std; -using namespace idf; - -TEST_CASE("SPITransferSize basic construction") -{ - SPITransferSize transfer_size_0(0); - CHECK(0 == transfer_size_0.get_value()); - SPITransferSize transfer_size_1(47); - CHECK(47 == transfer_size_1.get_value()); - SPITransferSize transfer_size_default = SPITransferSize::default_size(); - CHECK(0 == transfer_size_default.get_value()); -} - -TEST_CASE("SPI gpio numbers work correctly") -{ - GPIONum gpio_num_0(19); - MOSI mosi_0(18); - MOSI mosi_1(gpio_num_0.get_num()); - MOSI mosi_2(mosi_0); - CHECK(mosi_0 != mosi_1); - CHECK(mosi_2 == mosi_0); - CHECK(mosi_2.get_num() == 18u); -} - -TEST_CASE("SPI_DMAConfig valid") -{ - CHECK(SPI_DMAConfig::AUTO().get_num() == spi_common_dma_t::SPI_DMA_CH_AUTO); - CHECK(SPI_DMAConfig::DISABLED().get_num() == spi_common_dma_t::SPI_DMA_DISABLED); -} - -TEST_CASE("SPINum invalid argument") -{ - CHECK_THROWS_AS(SPINum(-1), SPIException&); - uint32_t host_raw = spi_host_device_t::SPI_HOST_MAX; - CHECK_THROWS_AS(SPINum host(host_raw), SPIException&); -} - -TEST_CASE("Master init failure") -{ - CMockFixture cmock_fix; - spi_bus_initialize_ExpectAnyArgsAndReturn(ESP_FAIL); - - CHECK_THROWS_AS(SPIMaster master(SPINum(SPI2_HOST), MOSI(1), MISO(2), SCLK(3)), SPIException&); -} - -TEST_CASE("Master invalid state") -{ - CMockFixture cmock_fix; - spi_bus_initialize_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE); - - CHECK_THROWS_AS(SPIMaster master(SPINum(SPI2_HOST), MOSI(1), MISO(2), SCLK(3)), SPIException&); -} - -TEST_CASE("build master") -{ - SPIFix fix; - - SPIMaster master(SPINum(SPI2_HOST), - MOSI(fix.bus_config.mosi_io_num), - MISO(fix.bus_config.miso_io_num), - SCLK(fix.bus_config.sclk_io_num)); -} - -TEST_CASE("build QSPI master") -{ - QSPIFix fix; - - SPIMaster master(SPINum(SPI2_HOST), - MOSI(fix.bus_config.mosi_io_num), - MISO(fix.bus_config.miso_io_num), - SCLK(fix.bus_config.sclk_io_num), - QSPIWP(fix.bus_config.quadwp_io_num), - QSPIHD(fix.bus_config.quadhd_io_num)); -} - -TEST_CASE("Master build device") -{ - SPIFix fix; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - - SPIMaster master(SPINum(SPI2_HOST), - MOSI(fix.bus_config.mosi_io_num), - MISO(fix.bus_config.miso_io_num), - SCLK(fix.bus_config.sclk_io_num)); - - master.create_dev(CS(4), Frequency::MHz(1)); -} - -TEST_CASE("SPIDeviceHandle throws on driver error") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::FAIL); - CHECK_THROWS_AS(SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)), SPIException&); -} - -TEST_CASE("SPIDeviceHandle succeed") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); -} - -TEST_CASE("SPIDevice succeed") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); -} - -TEST_CASE("SPI transaction empty data throws") -{ - CHECK_THROWS_AS(SPITransactionDescriptor transaction({}, reinterpret_cast(4747)), SPIException&); -} - -TEST_CASE("SPI transaction device handle nullptr throws") -{ - CHECK_THROWS_AS(SPITransactionDescriptor transaction({47}, nullptr), SPIException&); -} - -TEST_CASE("SPI transaction not started wait_for") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::IGNORE); - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47}, &handle); - - CHECK_THROWS_AS(transaction.wait_for(std::chrono::milliseconds(47)), SPITransferException&); -} - -TEST_CASE("SPI transaction not started wait") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::IGNORE); - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47}, &handle); - - CHECK_THROWS_AS(transaction.wait(), SPITransferException&); -} - -TEST_CASE("SPI transaction not started get") -{ - CMockFixture cmock_fix; - SPIDevFix dev_fix(CreateAnd::IGNORE); - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47}, &handle); - - CHECK_THROWS_AS(transaction.get(), SPITransferException&); -} - -TEST_CASE("SPI transaction wait_for timeout") -{ - CMockFixture cmock_fix; - SPITransactionFix transaction_fix(ESP_ERR_TIMEOUT); - SPIDevFix dev_fix(CreateAnd::IGNORE); - spi_device_acquire_bus_IgnoreAndReturn(ESP_OK); - spi_device_release_bus_Ignore(); - - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47}, &handle); - transaction.start(); - - CHECK(transaction.wait_for(std::chrono::milliseconds(47)) == false); - - // We need to finish the transaction, otherwise it goes out of scope without finishing and cleaning up the - // allocated transaction descriptor. - transaction_fix.get_transaction_return = ESP_OK; - spi_device_get_trans_result_ExpectAnyArgsAndReturn(ESP_OK); - transaction.wait(); -} - -TEST_CASE("SPI transaction one byte") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix fix(1, true); - SPIDevFix dev_fix(CreateAnd::IGNORE); - fix.rx_data = {0xA6}; - - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47}, &handle); - - transaction.start(); - auto out_data = transaction.get(); - - CHECK(1 * 8 == fix.orig_trans->length); - CHECK(47 == ((uint8_t*) fix.orig_trans->tx_buffer)[0]); - REQUIRE(out_data.begin() != out_data.end()); - CHECK(0xA6 == out_data[0]); -} - -TEST_CASE("SPI transaction two byte") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix fix(2, true); - SPIDevFix dev_fix(CreateAnd::IGNORE); - fix.rx_data = {0xA6, 0xA7}; - - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - SPITransactionDescriptor transaction({47, 48}, &handle); - transaction.start(); - auto out_data = transaction.get(); - - CHECK(fix.size * 8 == fix.orig_trans->length); - CHECK(47 == ((uint8_t*) fix.orig_trans->tx_buffer)[0]); - CHECK(48 == ((uint8_t*) fix.orig_trans->tx_buffer)[1]); - REQUIRE(out_data.begin() != out_data.end()); - REQUIRE(out_data.size() == 2); - CHECK(0xA6 == out_data[0]); - CHECK(0xA7 == out_data[1]); -} - -TEST_CASE("SPI transaction future") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::IGNORE); - - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - auto result = dev.transfer({47}); - vector out_data = result.get(); - - CHECK(1 * 8 == trans_fix.orig_trans->length); - CHECK(47 == ((uint8_t*) trans_fix.orig_trans->tx_buffer)[0]); - REQUIRE(out_data.begin() != out_data.end()); - CHECK(out_data.size() == 1); - CHECK(0xA6 == out_data[0]); -} - -TEST_CASE("SPI transaction with pre_callback") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - bool pre_cb_called = false; - - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - auto result = dev.transfer({47}, [&] (void *user) { pre_cb_called = true; }); - vector out_data = result.get(); - - SPITransactionDescriptor *transaction = reinterpret_cast(trans_fix.orig_trans->user); - dev_fix.dev_config.pre_cb(trans_fix.orig_trans); - CHECK(true == pre_cb_called); - CHECK(1 * 8 == trans_fix.orig_trans->length); - CHECK(47 == ((uint8_t*) trans_fix.orig_trans->tx_buffer)[0]); - REQUIRE(out_data.begin() != out_data.end()); - CHECK(out_data.size() == 1); - CHECK(0xA6 == out_data[0]); -} - -TEST_CASE("SPI transaction with post_callback") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - bool post_cb_called = false; - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - - auto result = dev.transfer({47}, [&] (void *user) { }, [&] (void *user) { post_cb_called = true; }); - vector out_data = result.get(); - - dev_fix.dev_config.post_cb(trans_fix.orig_trans); - CHECK(true == post_cb_called); - CHECK(1 * 8 == trans_fix.orig_trans->length); - CHECK(47 == ((uint8_t*) trans_fix.orig_trans->tx_buffer)[0]); - REQUIRE(out_data.begin() != out_data.end()); - CHECK(out_data.size() == 1); - CHECK(0xA6 == out_data[0]); -} - -TEST_CASE("SPI transaction data routed to pre callback") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - bool pre_cb_called = false; - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - - auto result = dev.transfer({47}, - [&] (void *user) { *(static_cast(user)) = true; }, - [&] (void *user) { }, - &pre_cb_called); - result.get(); - - dev_fix.dev_config.pre_cb(trans_fix.orig_trans); - CHECK(true == pre_cb_called); - -} - -TEST_CASE("SPI transaction data routed to post callback") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - bool post_cb_called = false; - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - - auto result = dev.transfer({47}, - [&] (void *user) { }, - [&] (void *user) { *(static_cast(user)) = true; }, - &post_cb_called); - result.get(); - - dev_fix.dev_config.post_cb(trans_fix.orig_trans); - CHECK(true == post_cb_called); -} - -TEST_CASE("SPI two transactions") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::SUCCEED); - bool pre_cb_called = false; - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - std::function pre_callback = [&] (void *user) { - pre_cb_called = true; - }; - - auto result = dev.transfer({47}, pre_callback); - vector out_data = result.get(); - - dev_fix.dev_config.pre_cb(trans_fix.orig_trans); - CHECK(true == pre_cb_called); - - CHECK(1 * 8 == trans_fix.orig_trans->length); - CHECK(47 == ((uint8_t*) trans_fix.orig_trans->tx_buffer)[0]); - - REQUIRE(out_data.begin() != out_data.end()); - CHECK(out_data.size() == 1); - CHECK(0xA6 == out_data[0]); - - // preparing the second transfer - pre_cb_called = false; - spi_device_acquire_bus_ExpectAndReturn(trans_fix.handle, portMAX_DELAY, ESP_OK); - spi_device_acquire_bus_IgnoreArg_device(); - spi_device_queue_trans_ExpectAndReturn(trans_fix.handle, nullptr, 0, ESP_OK); - spi_device_queue_trans_IgnoreArg_trans_desc(); - spi_device_queue_trans_IgnoreArg_handle(); - spi_device_get_trans_result_ExpectAndReturn(trans_fix.handle, nullptr, portMAX_DELAY, ESP_OK); - spi_device_get_trans_result_IgnoreArg_trans_desc(); - spi_device_get_trans_result_IgnoreArg_handle(); - spi_device_release_bus_Ignore(); - - - result = dev.transfer({47}, pre_callback); - result.get(); - - dev_fix.dev_config.pre_cb(trans_fix.orig_trans); - CHECK(true == pre_cb_called); -} - -TEST_CASE("SPIFuture invalid after default construction") -{ - SPIFuture future; - CHECK(false == future.valid()); -} - -TEST_CASE("SPIFuture valid") -{ - CMOCK_SETUP(); - SPIDevFix dev_fix(CreateAnd::IGNORE); - - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - shared_ptr trans(new SPITransactionDescriptor(std::vector(47), &handle)); - SPIFuture future(trans); - - CHECK(true == future.valid()); -} - -TEST_CASE("SPIFuture wait_for timeout") -{ - CMockFixture cmock_fix; - SPITransactionFix transaction_fix(ESP_ERR_TIMEOUT); - SPIDevFix dev_fix(CreateAnd::IGNORE); - spi_device_acquire_bus_IgnoreAndReturn(ESP_OK); - spi_device_release_bus_Ignore(); - - SPIDeviceHandle handle(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - shared_ptr transaction(new SPITransactionDescriptor(std::vector(47), &handle)); - SPIFuture future(transaction); - transaction->start(); - - CHECK(future.wait_for(std::chrono::milliseconds(47)) == std::future_status::timeout); - - // We need to finish the transaction, otherwise it goes out of scope without finishing and cleaning up the - // allocated transaction descriptor. - transaction_fix.get_transaction_return = ESP_OK; - spi_device_get_trans_result_ExpectAnyArgsAndReturn(ESP_OK); - - future.wait(); -} - -TEST_CASE("SPIFuture wait_for on SPIFuture") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true, 20); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::IGNORE); - - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - auto result = dev.transfer({47}); - - CHECK(result.wait_for(std::chrono::milliseconds(20)) == std::future_status::ready); -} - -TEST_CASE("SPIFuture wait on SPIFuture") -{ - CMockFixture cmock_fix; - SPITransactionDescriptorFix trans_fix(1, true); - trans_fix.rx_data = {0xA6}; - SPIDevFix dev_fix(CreateAnd::IGNORE); - - SPIDevice dev(SPINum(SPI2_HOST), CS(4), Frequency::MHz(1), QueueSize(10)); - auto result = dev.transfer({47}); - - result.wait(); - - vector out_data = result.get(); - CHECK(out_data.size() == 1); -} diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/pytest_spi_cxx.py b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/pytest_spi_cxx.py deleted file mode 100644 index 93bd4e0cd8..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/pytest_spi_cxx.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import pytest -from pytest_embedded import Dut - - -@pytest.mark.linux -@pytest.mark.host_test -def test_spi_cxx(dut: Dut) -> None: - dut.expect_exact('All tests passed', timeout=5) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/sdkconfig.defaults b/examples/cxx/experimental/experimental_cpp_component/host_test/spi/sdkconfig.defaults deleted file mode 100644 index a057733348..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/spi/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n -CONFIG_IDF_TARGET="linux" -CONFIG_CXX_EXCEPTIONS=y diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/system/CMakeLists.txt deleted file mode 100644 index ccd8f2c37e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) - -idf_component_set_property(driver USE_MOCK 1) - -# Overriding components which should be mocked -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") - -# Including experimental component here because it's outside IDF's main component directory -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") -project(test_system_cxx_host) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage.info" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" - COMMAND lcov --capture --directory . --output-file coverage.info - COMMENT "Create coverage report" - ) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage_report/" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage.info" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" - COMMAND genhtml coverage.info --output-directory coverage_report/ - COMMENT "Turn coverage report into html-based visualization" - ) - -add_custom_target(coverage - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" - DEPENDS "coverage_report/" - ) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/README.md b/examples/cxx/experimental/experimental_cpp_component/host_test/system/README.md deleted file mode 100644 index 6d04729934..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/README.md +++ /dev/null @@ -1,8 +0,0 @@ -| Supported Targets | Linux | -| ----------------- | ----- | - -# Build -`idf.py build` (sdkconfig.defaults sets the linux target by default) - -# Run -`build/system_cxx_host_test.elf` diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/CMakeLists.txt deleted file mode 100644 index 107218154c..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -idf_component_get_property(cpp_component experimental_cpp_component COMPONENT_DIR) - -idf_component_register(SRCS "system_cxx_test.cpp" - "${cpp_component}/esp_exception.cpp" - INCLUDE_DIRS - "." - "${cpp_component}/include" - $ENV{IDF_PATH}/tools/catch - REQUIRES driver) - -target_compile_options(${COMPONENT_LIB} PUBLIC --coverage) -target_link_libraries(${COMPONENT_LIB} --coverage) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/system_cxx_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/system_cxx_test.cpp deleted file mode 100644 index 958a3bcee3..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/main/system_cxx_test.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0 - * - * This test code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. - */ - -#define CATCH_CONFIG_MAIN - -#include "catch.hpp" -#include "system_cxx.hpp" - -// TODO: IDF-2693, function definition just to satisfy linker, mock esp_common instead -const char *esp_err_to_name(esp_err_t code) { - return "test"; -} - -using namespace std; -using namespace idf; - -TEST_CASE("Frequency invalid") -{ - CHECK_THROWS_AS(Frequency(0), ESPException&); -} - -TEST_CASE("Frequency constructors correct") -{ - Frequency f0(440); - CHECK(440 == f0.get_value()); - Frequency f1 = Frequency::Hz(440); - CHECK(440 == f1.get_value()); - Frequency f2 = Frequency::KHz(440); - CHECK(440000 == f2.get_value()); - Frequency f3 = Frequency::MHz(440); - CHECK(440000000 == f3.get_value()); -} - -TEST_CASE("Frequency op ==") -{ - Frequency f0(440); - Frequency f1(440); - CHECK(f1 == f0); -} - -TEST_CASE("Frequency op !=") -{ - Frequency f0(440); - Frequency f1(441); - CHECK(f1 != f0); -} - -TEST_CASE("Frequency op >") -{ - Frequency f0(440); - Frequency f1(441); - Frequency f2(440); - CHECK(f1 > f0); - CHECK(!(f0 > f1)); - CHECK(!(f0 > f2)); -} - -TEST_CASE("Frequency op <") -{ - Frequency f0(440); - Frequency f1(441); - Frequency f2(440); - CHECK(f0 < f1); - CHECK(!(f1 < f0)); - CHECK(!(f0 < f2)); -} - -TEST_CASE("Frequency op >=") -{ - Frequency f0(440); - Frequency f1(441); - Frequency f2(440); - CHECK (f1 >= f0); - CHECK(!(f0 >= f1)); - CHECK (f0 >= f2); -} - -TEST_CASE("Frequency op <=") -{ - Frequency f0(440); - Frequency f1(441); - Frequency f2(440); - CHECK (f0 <= f1); - CHECK(!(f1 <= f0)); - CHECK (f0 <= f2); -} diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/pytest_system_cxx.py b/examples/cxx/experimental/experimental_cpp_component/host_test/system/pytest_system_cxx.py deleted file mode 100644 index 9166372bee..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/pytest_system_cxx.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Unlicense OR CC0-1.0 -import pytest -from pytest_embedded import Dut - - -@pytest.mark.linux -@pytest.mark.host_test -def test_system_cxx(dut: Dut) -> None: - dut.expect_exact('All tests passed', timeout=5) diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/system/sdkconfig.defaults b/examples/cxx/experimental/experimental_cpp_component/host_test/system/sdkconfig.defaults deleted file mode 100644 index a057733348..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/system/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n -CONFIG_IDF_TARGET="linux" -CONFIG_CXX_EXCEPTIONS=y diff --git a/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp deleted file mode 100644 index fab4ed85b4..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifdef __cpp_exceptions - -#include "driver/i2c.h" -#include "i2c_cxx.hpp" - -using namespace std; - -namespace idf { - -#define I2C_CHECK_THROW(err) CHECK_THROW_SPECIFIC((err), I2CException) - -/** - * I2C bus are defined in the header files, let's check that the values are correct - */ -#if SOC_I2C_NUM >= 2 -static_assert(I2C_NUM_1 == 1, "I2C_NUM_1 must be equal to 1"); -#endif // SOC_I2C_NUM >= 2 -static_assert(I2C_NUM_MAX == SOC_I2C_NUM, "I2C_NUM_MAX must be equal to SOC_I2C_NUM"); - -namespace { -i2c_port_t i2c_num_to_driver_type(I2CNumber num) { - return static_cast(num.get_num()); -} -} - -esp_err_t check_i2c_num(uint32_t i2c_num) noexcept -{ - if (i2c_num >= I2C_NUM_MAX) { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -esp_err_t check_i2c_addr(uint32_t addr) noexcept -{ - // maximum I2C address currently supported in the C++ classes is 127 - if (addr > 0x7f) { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -I2CException::I2CException(esp_err_t error) : ESPException(error) { } - -I2CTransferException::I2CTransferException(esp_err_t error) : I2CException(error) { } - -uint32_t I2CNumber::get_num() -{ - return get_value(); -} - -I2CAddress::I2CAddress(uint8_t addr) : StrongValueComparable (addr) -{ - esp_err_t error = check_i2c_addr(addr); - if (error != ESP_OK) { - throw I2CException(error); - } -} - -uint8_t I2CAddress::get_addr() -{ - return get_value(); -} - -I2CCommandLink::I2CCommandLink() -{ - handle = i2c_cmd_link_create(); - if (!handle) { - throw I2CException(ESP_ERR_NO_MEM); - } -} - -I2CCommandLink::~I2CCommandLink() -{ - i2c_cmd_link_delete(handle); -} - -void I2CCommandLink::start() -{ - I2C_CHECK_THROW(i2c_master_start(handle)); -} - -void I2CCommandLink::write(const std::vector &bytes, bool expect_ack) -{ - I2C_CHECK_THROW(i2c_master_write(handle, bytes.data(), bytes.size(), expect_ack)); -} - -void I2CCommandLink::write_byte(uint8_t byte, bool expect_ack) -{ - I2C_CHECK_THROW(i2c_master_write_byte(handle, byte, expect_ack)); -} - -void I2CCommandLink::read(std::vector &bytes) -{ - I2C_CHECK_THROW(i2c_master_read(handle, bytes.data(), bytes.size(), I2C_MASTER_LAST_NACK)); -} - -void I2CCommandLink::stop() -{ - I2C_CHECK_THROW(i2c_master_stop(handle)); -} - -void I2CCommandLink::execute_transfer(I2CNumber i2c_num, chrono::milliseconds driver_timeout) -{ - esp_err_t err = i2c_master_cmd_begin(i2c_num_to_driver_type(i2c_num), handle, driver_timeout.count() / portTICK_PERIOD_MS); - if (err != ESP_OK) { - throw I2CTransferException(err); - } -} - -I2CBus::I2CBus(I2CNumber i2c_number) : i2c_num(std::move(i2c_number)) { } - -I2CBus::~I2CBus() { } - -I2CMaster::I2CMaster(I2CNumber i2c_number, - SCL_GPIO scl_gpio, - SDA_GPIO sda_gpio, - Frequency clock_speed, - bool scl_pullup, - bool sda_pullup) - : I2CBus(std::move(i2c_number)) -{ - i2c_config_t conf = {}; - conf.mode = I2C_MODE_MASTER; - conf.scl_io_num = scl_gpio.get_num(); - conf.scl_pullup_en = scl_pullup; - conf.sda_io_num = sda_gpio.get_num(); - conf.sda_pullup_en = sda_pullup; - conf.master.clk_speed = clock_speed.get_value(); - I2C_CHECK_THROW(i2c_param_config(i2c_num_to_driver_type(i2c_num), &conf)); - I2C_CHECK_THROW(i2c_driver_install(i2c_num_to_driver_type(i2c_num), conf.mode, 0, 0, 0)); -} - -I2CMaster::~I2CMaster() -{ - i2c_driver_delete(i2c_num_to_driver_type(i2c_num)); -} - -void I2CMaster::sync_write(I2CAddress i2c_addr, const vector &data) -{ - I2CWrite writer(data); - - writer.do_transfer(i2c_num, i2c_addr); -} - -std::vector I2CMaster::sync_read(I2CAddress i2c_addr, size_t n_bytes) -{ - I2CRead reader(n_bytes); - - return reader.do_transfer(i2c_num, i2c_addr); -} - -vector I2CMaster::sync_transfer(I2CAddress i2c_addr, - const std::vector &write_data, - size_t read_n_bytes) -{ - I2CComposed composed_transfer; - composed_transfer.add_write(write_data); - composed_transfer.add_read(read_n_bytes); - - return composed_transfer.do_transfer(i2c_num, i2c_addr)[0]; -} - -#if CONFIG_SOC_I2C_SUPPORT_SLAVE -I2CSlave::I2CSlave(I2CNumber i2c_number, - SCL_GPIO scl_gpio, - SDA_GPIO sda_gpio, - I2CAddress slave_addr, - size_t rx_buf_len, - size_t tx_buf_len, - bool scl_pullup, - bool sda_pullup) - : I2CBus(std::move(i2c_number)) -{ - i2c_config_t conf = {}; - conf.mode = I2C_MODE_SLAVE; - conf.scl_io_num = scl_gpio.get_value(); - conf.scl_pullup_en = scl_pullup; - conf.sda_io_num = sda_gpio.get_value(); - conf.sda_pullup_en = sda_pullup; - conf.slave.addr_10bit_en = 0; - conf.slave.slave_addr = slave_addr.get_addr(); - I2C_CHECK_THROW(i2c_param_config(i2c_num_to_driver_type(i2c_num), &conf)); - I2C_CHECK_THROW(i2c_driver_install(i2c_num_to_driver_type(i2c_num), conf.mode, rx_buf_len, tx_buf_len, 0)); -} - -I2CSlave::~I2CSlave() -{ - i2c_driver_delete(i2c_num_to_driver_type(i2c_num)); -} - -int I2CSlave::write_raw(const uint8_t *data, size_t data_len, chrono::milliseconds timeout) -{ - return i2c_slave_write_buffer(i2c_num_to_driver_type(i2c_num), data, data_len, (TickType_t) timeout.count() / portTICK_PERIOD_MS); -} - -int I2CSlave::read_raw(uint8_t *buffer, size_t buffer_len, chrono::milliseconds timeout) -{ - return i2c_slave_read_buffer(i2c_num_to_driver_type(i2c_num), buffer, buffer_len, (TickType_t) timeout.count() / portTICK_PERIOD_MS); -} -#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE - -I2CWrite::I2CWrite(const vector &bytes, chrono::milliseconds driver_timeout) - : I2CTransfer(driver_timeout), bytes(bytes) -{ - if (bytes.empty()) { - throw I2CException(ESP_ERR_INVALID_ARG); - } -} - -void I2CWrite::queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) -{ - handle.start(); - handle.write_byte(i2c_addr.get_value() << 1 | I2C_MASTER_WRITE); - handle.write(bytes); -} - -void I2CWrite::process_result() { } - -I2CRead::I2CRead(size_t size, chrono::milliseconds driver_timeout) - : I2CTransfer >(driver_timeout), bytes(size) -{ - if (size == 0) { - throw I2CException(ESP_ERR_INVALID_ARG); - } -} - -void I2CRead::queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) -{ - handle.start(); - handle.write_byte(i2c_addr.get_value() << 1 | I2C_MASTER_READ); - handle.read(bytes); -} - -vector I2CRead::process_result() -{ - return bytes; -} - -I2CComposed::I2CComposed(chrono::milliseconds driver_timeout) - : I2CTransfer > >(driver_timeout), transfer_list() { } - -void I2CComposed::CompTransferNodeRead::queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) -{ - handle.write_byte(i2c_addr.get_value() << 1 | I2C_MASTER_READ); - handle.read(bytes); -} - -void I2CComposed::CompTransferNodeRead::process_result(std::vector > &read_results) -{ - read_results.push_back(bytes); -} - -void I2CComposed::CompTransferNodeWrite::queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) -{ - handle.write_byte(i2c_addr.get_value() << 1 | I2C_MASTER_WRITE); - handle.write(bytes); -} - -void I2CComposed::add_read(size_t size) -{ - if (!size) { - throw I2CException(ESP_ERR_INVALID_ARG); - } - - transfer_list.push_back(make_shared(size)); -} - -void I2CComposed::add_write(std::vector bytes) -{ - if (bytes.empty()) { - throw I2CException(ESP_ERR_INVALID_ARG); - } - - transfer_list.push_back(make_shared(bytes)); -} - -void I2CComposed::queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) -{ - for (auto it = transfer_list.begin(); it != transfer_list.end(); it++) { - handle.start(); - (*it)->queue_cmd(handle, i2c_addr); - } -} - -std::vector > I2CComposed::process_result() -{ - std::vector > results; - for (auto it = transfer_list.begin(); it != transfer_list.end(); it++) { - (*it)->process_result(results); - } - return results; -} - -} // idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp b/examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp deleted file mode 100644 index 81f9d28c06..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef ESP_EVENT_API_HPP_ -#define ESP_EVENT_API_HPP_ - -#include "esp_event.h" - -namespace idf { - -namespace event { - -/** - * Abstract interface for direct calls to esp_event C-API. - * This is generally not intended to be used directly. - * It's main purpose is to provide ESPEventLoop a unified API not dependent on whether the default event loop or a - * custom event loop is used. - * The interface resembles the C-API, have a look there for further documentation. - */ -class ESPEventAPI { -public: - virtual ~ESPEventAPI() { } - - virtual esp_err_t handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void* event_handler_arg, - esp_event_handler_instance_t *instance) = 0; - - virtual esp_err_t handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) = 0; - - virtual esp_err_t post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) = 0; -}; - -/** - * @brief API version with default event loop. - * - * It will direct calls to the default event loop API. - */ -class ESPEventAPIDefault : public ESPEventAPI { -public: - ESPEventAPIDefault(); - virtual ~ESPEventAPIDefault(); - - /** - * Copying would lead to deletion of event loop through destructor. - */ - ESPEventAPIDefault(const ESPEventAPIDefault &o) = delete; - ESPEventAPIDefault& operator=(const ESPEventAPIDefault&) = delete; - - esp_err_t handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void* event_handler_arg, - esp_event_handler_instance_t *instance) override; - - esp_err_t handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) override; - - esp_err_t post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) override; -}; - -/** - * @brief API version with custom event loop. - * - * It will direct calls to the custom event loop API. - * The loop parameters are given in the constructor the same way it's done in esp_event_loop_create() in event.h. - * This class also provides a run method in case the custom event loop was created without its own task. - */ -class ESPEventAPICustom : public ESPEventAPI { -public: - /** - * @param event_loop_args the event loop arguments, refer to esp_event_loop_create() in event.h. - */ - ESPEventAPICustom(const esp_event_loop_args_t &event_loop_args); - - virtual ~ESPEventAPICustom(); - - /** - * Copying would lead to deletion of event loop through destructor. - */ - ESPEventAPICustom(const ESPEventAPICustom &o) = delete; - ESPEventAPICustom& operator=(const ESPEventAPICustom&) = delete; - - esp_err_t handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void* event_handler_arg, - esp_event_handler_instance_t *instance) override; - - esp_err_t handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) override; - - esp_err_t post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) override; - - /** - * Run the event loop. The behavior is the same as esp_event_loop_run in esp_event.h. - */ - esp_err_t run(TickType_t ticks_to_run); - -private: - esp_event_loop_handle_t event_loop; -}; - -} // event - -} // idf - -#endif // ESP_EVENT_API_HPP_ diff --git a/examples/cxx/experimental/experimental_cpp_component/include/esp_event_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/esp_event_cxx.hpp deleted file mode 100644 index 41e229d16f..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/esp_event_cxx.hpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ESP_EVENT_CXX_H_ -#define ESP_EVENT_CXX_H_ - -#ifdef __cpp_exceptions - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "esp_timer.h" -#include "esp_err.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" - -#include "esp_exception.hpp" -#include "esp_event_api.hpp" - -namespace idf { - -namespace event { - -extern const std::chrono::milliseconds PLATFORM_MAX_DELAY_MS; - -const std::chrono::microseconds MIN_TIMEOUT(200); - -class EventException : public ESPException { -public: - EventException(esp_err_t error) : ESPException(error) { } -}; - -/** - * @brief - * Thrown to signal a timeout in EventHandlerSync. - */ -class EventTimeout : public idf::event::EventException { -public: - EventTimeout(esp_err_t error) : EventException(error) { } -}; - -/** - * @brief - * Event ID wrapper class to make C++ APIs more explicit. - * - * This prevents APIs from taking raw ints as event IDs which are not very expressive and may be - * confused with other parameters of a function. - */ -class ESPEventID { -public: - ESPEventID() : id(0) { } - explicit ESPEventID(int32_t event_id) : id(event_id) { } - ESPEventID(const ESPEventID &rhs) : id(rhs.id) { } - - inline bool operator==(const ESPEventID &rhs) const { - return id == rhs.get_id(); - } - - inline ESPEventID &operator=(const ESPEventID& other) { - id = other.id; - return *this; - } - - inline int32_t get_id() const { - return id; - } - - friend std::ostream& operator<<(std::ostream& os, const ESPEventID& id); - -private: - int32_t id; -}; - -inline std::ostream& operator<<(std::ostream &os, const ESPEventID& id) { - os << id.id; - return os; -} - -/* - * Helper struct to bundle event base and event ID. - */ -struct ESPEvent { - ESPEvent() - : base(nullptr), id() { } - ESPEvent(esp_event_base_t event_base, const ESPEventID &event_id) - : base(event_base), id(event_id) { } - - esp_event_base_t base; - ESPEventID id; -}; - -/** - * Thrown if event registration, i.e. \c register_event() or \c register_event_timed(), fails. - */ -struct ESPEventRegisterException : public EventException { - ESPEventRegisterException(esp_err_t err, const ESPEvent& event) - : EventException(err), esp_event(event) { } - - const char *what() const noexcept - { - std::string ret_message = "Event base: " + std::string(esp_event.base) - + ", Event ID: " + std::to_string(esp_event.id.get_id()); - return ret_message.c_str(); - } - - const ESPEvent esp_event; -}; - -inline bool operator==(const ESPEvent &lhs, const ESPEvent &rhs) -{ - return lhs.base == rhs.base && lhs.id == rhs.id; -} - -TickType_t convert_ms_to_ticks(const std::chrono::milliseconds &time); - -/** - * Callback-event combination for ESPEventLoop. - * - * Used to bind class-based handler instances to event_handler_hook which is registered into the C-based - * esp event loop. - * It can be used directly, however, the recommended way is to obtain a unique_ptr via ESPEventLoop::register_event(). - */ -class ESPEventReg { -public: - /** - * Register the event handler \c cb to handle the events defined by \c ev. - * - * @param cb The handler to be called. - * @param ev The event for which the handler is registered. - * @param api The esp event api implementation. - */ - ESPEventReg(std::function cb, - const ESPEvent& ev, - std::shared_ptr api); - - /** - * Unregister the event handler. - */ - virtual ~ESPEventReg(); - -protected: - /** - * This is esp_event's handler, all events registered go through this. - */ - static void event_handler_hook(void *handler_arg, - esp_event_base_t event_base, - int32_t event_id, - void *event_data); - - /** - * User event handler. - */ - std::function cb; - - /** - * Helper function to enter the instance's scope from the generic \c event_handler_hook(). - */ - virtual void dispatch_event_handling(ESPEvent event, void *event_data); - - /** - * Save the event here to be able to un-register from the event loop on destruction. - */ - ESPEvent event; - - /** - * This API handle allows different sets of APIs to be applied, e.g. default event loop API and - * custom event loop API. - */ - std::shared_ptr api; - - /** - * Event handler instance from the esp event C API. - */ - esp_event_handler_instance_t instance; -}; - -/** - * Callback-event combination for ESPEventLoop with builtin timeout. - * - * Used to bind class-based handler instances to event_handler_hook which is registered into the C-based - * esp event loop. - * It can be used directly, however, the recommended way is to obtain a unique_ptr via ESPEventLoop::register_event(). - */ -class ESPEventRegTimed : public ESPEventReg { -public: - /** - * Register the event handler \c cb to handle the events as well as a timeout callback in case the event doesn't - * arrive on time. - * - * If the event \c ev is received before \c timeout milliseconds, then the event handler is invoked. - * If no such event is received before \c timeout milliseconds, then the timeout callback is invoked. - * After the timeout or the first occurance of the event, the timer will be deactivated. - * The event handler registration will only be deactivated if the timeout occurs. - * If event handler and timeout occur at the same time, only either the event handler or the timeout callback - * will be invoked. - * - * @param cb The handler to be called. - * @param ev The event for which the handler is registered. - * @param timeout_cb The timeout callback which is called in case there is no event for \c timeout microseconds. - * @param timeout The timeout in microseconds. - * @param api The esp event api implementation. - */ - ESPEventRegTimed(std::function cb, - const ESPEvent& ev, - std::function timeout_cb, - const std::chrono::microseconds &timeout, - std::shared_ptr api); - - /** - * Unregister the event handler, stop and delete the timer. - */ - virtual ~ESPEventRegTimed(); - -protected: - - /** - * Helper function to hook directly into esp timer callback. - */ - static void timer_cb_hook(void *arg); - - /** - * Helper function to enter the instance's scope from the generic \c event_handler_hook(). - */ - void dispatch_event_handling(ESPEvent event, void *event_data) override; - - /** - * The timer callback which will be called on timeout. - */ - std::function timeout_cb; - - /** - * Timer used for event timeouts. - */ - esp_timer_handle_t timer; - - /** - * This mutex makes sure that a timeout and event callbacks aren't invoked both. - */ - std::mutex timeout_mutex; -}; - -class ESPEventLoop { -public: - /** - * Creates the ESP default event loop. - * - * @param api the interface to the esp_event api; this determines whether the default event loop is used - * or a custom loop (or just a mock up for tests). May be nullptr, in which case it will created - * here. - * - * @note may throw EventException - */ - ESPEventLoop(std::shared_ptr api = std::make_shared()); - - /** - * Deletes the event loop implementation (depends on \c api). - */ - virtual ~ESPEventLoop(); - - /** - * Registers a specific handler-event combination to the event loop. - * - * @return a reference to the combination of handler and event which can be used to unregister - * this combination again later on. - * - * @note registering the same event twice will result in unregistering the earlier registered handler. - * @note may throw EventException, ESPEventRegisterException - */ - std::unique_ptr register_event(const ESPEvent &event, - std::function cb); - - /** - * Sets a timeout for event. If the specified event isn't received within timeout, - * timer_cb is called. - * - * @note this is independent from the normal event handling. Hence, registering an event for - * timeout does not interfere with a different client that has registered normally for the - * same event. - */ - std::unique_ptr register_event_timed(const ESPEvent &event, - std::function cb, - const std::chrono::microseconds &timeout, - std::function timer_cb); - - /** - * Posts an event and corresponding data. - * - * @param event the event to post - * @param event_data The event data. A copy will be made internally and a pointer to the copy will be passed to the - * event handler. - * @param wait_time the maximum wait time the function tries to post the event - */ - template - void post_event_data(const ESPEvent &event, - T &event_data, - const std::chrono::milliseconds &wait_time = PLATFORM_MAX_DELAY_MS); - - /** - * Posts an event. - * - * No event data will be send. The event handler will receive a nullptr. - * - * @param event the event to post - * @param wait_time the maximum wait time the function tries to post the event - */ - void post_event_data(const ESPEvent &event, - const std::chrono::milliseconds &wait_time = PLATFORM_MAX_DELAY_MS); - -private: - /** - * This API handle allows different sets of APIs to be applied, e.g. default event loop API and - * custom event loop API. - */ - std::shared_ptr api; -}; - -/** - * ESPEventHandlerSync builds upon ESPEventLoop to create a class which allows synchronous event handling. - * - * It is built around a queue which buffers received events. This queue is also used to wait synchronously (blocking) - * for an event. The consequence is that once an event is registered with this class, it is guaranteed to be received - * as long as the queue can handle all incoming events (see \c get_send_queue_errors()). - */ -class ESPEventHandlerSync { -public: - /** - * Result type for synchronous waiting. - */ - struct EventResult { - EventResult() : event(), ev_data(nullptr) { } - EventResult(ESPEvent ev, void *ev_data) : event(ev), ev_data(ev_data) { } - ESPEvent event; - void *ev_data; - }; - - /** - * Result type for synchronous waiting with timeout. - */ - struct EventResultTimed : public EventResult { - EventResultTimed(EventResult event_result, bool timeout_arg) - : EventResult(event_result), timeout(timeout_arg) { } - bool timeout; - }; - - /** - * Sets up synchronous event handling and registers event with it. - * - * @param event_loop ESPEventLoop implementation to manage esp events. - * @param queue_max_size The queue size of the underlying FreeRTOS queue. - * The memory to store queue_max_size number of events is allocated during construction - * and held until destruction! - * @param queue_send_timeout The timeout for posting events to the internal queue - */ - ESPEventHandlerSync(std::shared_ptr event_loop, - size_t queue_max_size = 10, - TickType_t queue_send_timeout = 0); - - /** - * Unregister all formerly registered events via automatic destruction in registry. - */ - virtual ~ESPEventHandlerSync(); - - /** - * Waits for any of the events registered before with listen_to(). - */ - EventResult wait_event(); - - /** - * Waits for an event either PLATFORM_MAX_DELAY_MS ms or timeout ms. - * - * @param timeout the maximum waiting time for new events if no event is pending - * The timeout is restricted by the TickType_t and configTICK_RATE_HZ. - * TickType_t's width determines the maximum wait time. configTICK_RATE_HZ - * determines the minimum wait time. - * - * Throws EventTimeout in case of a timeout. - */ - EventResultTimed wait_event_for(const std::chrono::milliseconds &timeout); - - /** - * Register additional event to listen for. - * - * @note this will unregister all earlier registered events of the same event type from the event loop. - */ - void listen_to(const ESPEvent &event); - - /** - * Indicates whether there were errors inserting an event into the queue. - * This is the case e.g. if the queue with waiting events is full already. - * Use this function to adjust the queue size (\c queue_send_timeout in constructor) in your application. - */ - size_t get_send_queue_errors() const; - -protected: - /** - * Posts an event to the internal queue. - */ - void post_event(const EventResult &result); - -private: - /** - * Keeps track if there are any errors inserting an event into this class's event queue. - */ - std::atomic send_queue_errors; - - /** - * The queue which saves events if they were received already or waits if no event was - * received. - */ - QueueHandle_t event_queue; - - /** - * Timeout used to posting to the queue when using \c post_event(). Can be adjusted in constructor. - */ - TickType_t queue_send_timeout; - - /** - * The event loop used for this synchronous event handling class. - */ - std::shared_ptr event_loop; - - /** - * Keeps track of all events which are registered already for synchronous handling. - * - * This is necessary to keep the registration. - */ - std::vector > registry; -}; - -template -void ESPEventLoop::post_event_data(const ESPEvent &event, - T &event_data, - const std::chrono::milliseconds &wait_time) -{ - esp_err_t result = api->post(event.base, - event.id.get_id(), - &event_data, - sizeof(event_data), - convert_ms_to_ticks(wait_time)); - - if (result != ESP_OK) { - throw ESPException(result); - } -} - -} // namespace event - -} // namespace idf - -#endif // __cpp_exceptions - -#endif // ESP_EVENT_CXX_H_ diff --git a/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp b/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp deleted file mode 100644 index 19f2f297f3..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cpp_exceptions - -#include "esp_err.h" -#include - -namespace idf { - -/** - * @brief - * General exception class for all C++ exceptions in IDF. - * - * All throwing code in IDF should use either this exception directly or a sub-classes. - * An error from the underlying IDF function is mandatory. The idea is to wrap the orignal IDF error code to keep - * the error scheme partially compatible. If an exception occurs in a higher level C++ code not directly wrapping - * IDF functions, an appropriate error code reflecting the cause must be chosen or newly created. - */ -class ESPException : public std::exception { -public: - /** - * @param error Error from underlying IDF functions. - */ - ESPException(esp_err_t error); - - virtual ~ESPException() { } - - /** - * @return A textual representation of the contained error. This method only wraps \c esp_err_to_name. - */ - virtual const char *what() const noexcept; - - /** - * Error from underlying IDF functions. If an exception occurs in a higher level C++ code not directly wrapping - * IDF functions, an appropriate error code reflecting the cause must be chosen or newly created. - */ - const esp_err_t error; -}; - -/** - * Convenience macro to help converting IDF error codes into ESPException. - */ -#define CHECK_THROW(error_) \ - do { \ - esp_err_t result = error_; \ - if (result != ESP_OK) throw idf::ESPException(result); \ - } while (0) - -/** - * Convenience macro to help converting IDF error codes into a child of ESPException. - */ -#define CHECK_THROW_SPECIFIC(error_, exception_type_) \ - do { \ - esp_err_t result = (error_); \ - if (result != ESP_OK) throw idf::exception_type_(result); \ - } while (0) - -} // namespace idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp deleted file mode 100644 index a83eefaee8..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#ifdef __cpp_exceptions - -#include -#include -#include -#include "esp_exception.hpp" -#include "esp_timer.h" - -namespace idf { - -namespace esp_timer { - -/** - * @brief Get time since boot - * @return time since \c esp_timer_init() was called (this normally happens early during application startup). - */ -static inline std::chrono::microseconds get_time() -{ - return std::chrono::microseconds(esp_timer_get_time()); -} - -/** - * @brief Get the timestamp when the next timeout is expected to occur - * @return Timestamp of the nearest timer event. - * The timebase is the same as for the values returned by \c get_time(). - */ -static inline std::chrono::microseconds get_next_alarm() -{ - return std::chrono::microseconds(esp_timer_get_next_alarm()); -} - - -/** - * @brief - * A timer using the esp_timer component which can be started either as one-shot timer or periodically. - */ -class ESPTimer { -public: - /** - * @param timeout_cb The timeout callback. - * @param timer_name The name of the timer (optional). This is for debugging using \c esp_timer_dump(). - */ - ESPTimer(std::function timeout_cb, const std::string &timer_name = "ESPTimer"); - - /** - * Stop the timer if necessary and delete it. - */ - ~ESPTimer(); - - /** - * Default copy constructor is deleted since one instance of esp_timer_handle_t must not be shared. - */ - ESPTimer(const ESPTimer&) = delete; - - /** - * Default copy assignment is deleted since one instance of esp_timer_handle_t must not be shared. - */ - ESPTimer &operator=(const ESPTimer&) = delete; - - /** - * @brief Start one-shot timer - * - * Timer should not be running (started) when this function is called. - * - * @param timeout timer timeout, in microseconds relative to the current moment. - * - * @throws ESPException with error ESP_ERR_INVALID_STATE if the timer is already running. - */ - inline void start(std::chrono::microseconds timeout) - { - CHECK_THROW(esp_timer_start_once(timer_handle, timeout.count())); - } - - /** - * @brief Start periodic timer - * - * Timer should not be running when this function is called. This function will - * start a timer which will trigger every 'period' microseconds. - * - * Timer should not be running (started) when this function is called. - * - * @param timeout timer timeout, in microseconds relative to the current moment. - * - * @throws ESPException with error ESP_ERR_INVALID_STATE if the timer is already running. - */ - inline void start_periodic(std::chrono::microseconds period) - { - CHECK_THROW(esp_timer_start_periodic(timer_handle, period.count())); - } - - /** - * @brief Stop the previously started timer. - * - * This function stops the timer previously started using \c start() or \c start_periodic(). - * - * @throws ESPException with error ESP_ERR_INVALID_STATE if the timer has not been started yet. - */ - inline void stop() - { - CHECK_THROW(esp_timer_stop(timer_handle)); - } - -private: - /** - * Internal callback to hook into esp_timer component. - */ - static void esp_timer_cb(void *arg); - - /** - * Timer instance of the underlying esp_event component. - */ - esp_timer_handle_t timer_handle; - - /** - * Callback which will be called once the timer triggers. - */ - std::function timeout_cb; - - /** - * Name of the timer, will be passed to the underlying timer framework and is used for debugging. - */ - const std::string name; -}; - -} // esp_timer - -} // idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/include/gpio_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/gpio_cxx.hpp deleted file mode 100644 index 8cd347f26b..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/gpio_cxx.hpp +++ /dev/null @@ -1,402 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#if __cpp_exceptions - -#include "esp_exception.hpp" -#include "system_cxx.hpp" - -namespace idf { - -/** - * @brief Exception thrown for errors in the GPIO C++ API. - */ -struct GPIOException : public ESPException { - /** - * @param error The IDF error representing the error class of the error to throw. - */ - GPIOException(esp_err_t error); -}; - -/** - * Check if the numeric pin number is valid on the current hardware. - */ -esp_err_t check_gpio_pin_num(uint32_t pin_num) noexcept; - -/** - * Check if the numeric value of a drive strength is valid on the current hardware. - */ -esp_err_t check_gpio_drive_strength(uint32_t strength) noexcept; - -/** - * This is a "Strong Value Type" class for GPIO. The GPIO pin number is checked during construction according to - * the hardware capabilities. This means that any GPIONumBase object is guaranteed to contain a valid GPIO number. - * See also the template class \c StrongValue. - */ -template -class GPIONumBase final : public StrongValueComparable { -public: - /** - * @brief Create a numerical pin number representation and make sure it's correct. - * - * @throw GPIOException if the number does not reflect a valid GPIO number on the current hardware. - */ - explicit GPIONumBase(uint32_t pin) : StrongValueComparable(pin) - { - esp_err_t pin_check_result = check_gpio_pin_num(pin); - if (pin_check_result != ESP_OK) { - throw GPIOException(pin_check_result); - } - } - - using StrongValueComparable::operator==; - using StrongValueComparable::operator!=; - - /** - * Retrieves the valid numerical representation of the GPIO number. - */ - uint32_t get_num() const { return get_value(); }; -}; - -/** - * This is a TAG type whose sole purpose is to create a distinct type from GPIONumBase. - */ -class GPIONumType; - -/** - * A GPIO number type used for general GPIOs, in contrast to specific GPIO pins like e.g. SPI_SCLK. - */ -using GPIONum = GPIONumBase; - -/** - * Level of an input GPIO. - */ -enum class GPIOLevel { - HIGH, - LOW -}; - -/** - * Represents a valid pull up configuration for GPIOs. - * It is supposed to resemble an enum type, hence it has static creation methods and a private constructor. - * This class is a "Strong Value Type", see also the template class \c StrongValue for more properties. - */ -class GPIOPullMode final : public StrongValueComparable { -private: - /** - * Constructor is private since it should only be accessed by the static creation methods. - * - * @param pull_mode A valid numerical respresentation of the pull up configuration. Must be valid! - */ - explicit GPIOPullMode(uint32_t pull_mode) : StrongValueComparable(pull_mode) { } - -public: - /** - * Create a representation of a floating pin configuration. - * For more information, check the driver and HAL files. - */ - static GPIOPullMode FLOATING(); - - /** - * Create a representation of a pullup configuration. - * For more information, check the driver and HAL files. - */ - static GPIOPullMode PULLUP(); - - /** - * Create a representation of a pulldown configuration. - * For more information, check the driver and HAL files. - */ - static GPIOPullMode PULLDOWN(); - - using StrongValueComparable::operator==; - using StrongValueComparable::operator!=; - - /** - * Retrieves the valid numerical representation of the pull mode. - */ - uint32_t get_pull_mode() const { return get_value(); }; -}; - -/** - * @brief Represents a valid wakup interrupt type for GPIO inputs. - * - * This class is a "Strong Value Type", see also the template class \c StrongValue for more properties. - * It is supposed to resemble an enum type, hence it has static creation methods and a private constructor. - * For a detailed mapping of interrupt types to numeric values, please refer to the driver types and implementation. - */ -class GPIOWakeupIntrType final: public StrongValueComparable { -private: - /** - * Constructor is private since it should only be accessed by the static creation methods. - * - * @param pull_mode A valid numerical respresentation of a possible interrupt level to wake up. Must be valid! - */ - explicit GPIOWakeupIntrType(uint32_t interrupt_level) : StrongValueComparable(interrupt_level) { } - -public: - static GPIOWakeupIntrType LOW_LEVEL(); - static GPIOWakeupIntrType HIGH_LEVEL(); - - /** - * Retrieves the valid numerical representation of the pull mode. - */ - uint32_t get_level() const noexcept { return get_value(); }; -}; - -/** - * Class representing a valid drive strength for GPIO outputs. - * This class is a "Strong Value Type", see also the template class \c StrongValue for more properties. - * For a detailed mapping for values to drive strengths, please refer to the datasheet of the chip you are using. - * E.g. for ESP32, the values in general are the following: - * - WEAK: 5mA - * - STRONGER: 10mA - * - DEFAULT/MEDIUM: 20mA - * - STRONGEST: 40mA - */ -class GPIODriveStrength final : public StrongValueComparable { -public: - /** - * @brief Create a drive strength representation and checks its validity. - * - * After construction, this class should have a guaranteed valid strength representation. - * - * @param strength the numeric value mapping for a particular strength. For possible ranges, look at the - * static creation functions below. - * @throws GPIOException if the supplied number is out of the hardware capable range. - */ - explicit GPIODriveStrength(uint32_t strength) : StrongValueComparable(strength) - { - esp_err_t strength_check_result = check_gpio_drive_strength(strength); - if (strength_check_result != ESP_OK) { - throw GPIOException(strength_check_result); - } - } - - /** - * Create a representation of the default drive strength. - * For more information, check the datasheet and driver and HAL files. - */ - static GPIODriveStrength DEFAULT(); - - /** - * Create a representation of the weak drive strength. - * For more information, check the datasheet and driver and HAL files. - */ - static GPIODriveStrength WEAK(); - - /** - * Create a representation of the less weak drive strength. - * For more information, check the datasheet and driver and HAL files. - */ - static GPIODriveStrength LESS_WEAK(); - - /** - * Create a representation of the medium drive strength. - * For more information, check the datasheet and driver and HAL files. - */ - static GPIODriveStrength MEDIUM(); - - /** - * Create a representation of the strong drive strength. - */ - static GPIODriveStrength STRONGEST(); - - using StrongValueComparable::operator==; - using StrongValueComparable::operator!=; - - /** - * Retrieves the valid numerical representation of the drive strength. - */ - uint32_t get_strength() const { return get_value(); }; - -}; - -/** - * @brief Implementations commonly used functionality for all GPIO configurations. - * - * Some functionality is only for specific configurations (set and get drive strength) but is necessary here - * to avoid complicating the inheritance hierarchy of the GPIO classes. - * Child classes implementing any GPIO configuration (output, input, etc.) are meant to intherit from this class - * and possibly make some of the functionality publicly available. - */ -class GPIOBase { -protected: - /** - * @brief Construct a GPIO. - * - * This constructor will only reset the GPIO but leaves the actual configuration (input, output, etc.) to - * the sub class. - * - * @param num GPIO pin number of the GPIO to be configured. - * - * @throws GPIOException - * - if the underlying driver function fails - */ - GPIOBase(GPIONum num); - - /** - * @brief Enable gpio pad hold function. - * - * The gpio pad hold function works in both input and output modes, but must be output-capable gpios. - * If pad hold enabled: - * in output mode: the output level of the pad will be force locked and can not be changed. - * in input mode: the input value read will not change, regardless the changes of input signal. - * - * @throws GPIOException if the underlying driver function fails. - */ - void hold_en(); - - /** - * @brief Disable gpio pad hold function. - * - * @throws GPIOException if the underlying driver function fails. - */ - void hold_dis(); - - /** - * @brief Configure the drive strength of the GPIO. - * - * @param strength The drive strength. Refer to \c GPIODriveStrength for more details. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_drive_strength(GPIODriveStrength strength); - - /** - * @brief Return the current drive strength of the GPIO. - * - * @return The currently configured drive strength. Refer to \c GPIODriveStrength for more details. - * - * @throws GPIOException if the underlying driver function fails. - */ - GPIODriveStrength get_drive_strength(); - - /** - * @brief The number of the configured GPIO pin. - */ - GPIONum gpio_num; -}; - -/** - * @brief This class represents a GPIO which is configured as output. - */ -class GPIO_Output : public GPIOBase { -public: - /** - * @brief Construct and configure a GPIO as output. - * - * @param num GPIO pin number of the GPIO to be configured. - * - * @throws GPIOException - * - if the underlying driver function fails - */ - GPIO_Output(GPIONum num); - - /** - * @brief Set GPIO to high level. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_high(); - - /** - * @brief Set GPIO to low level. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_low(); - - using GPIOBase::set_drive_strength; - using GPIOBase::get_drive_strength; -}; - -/** - * @brief This class represents a GPIO which is configured as input. - */ -class GPIOInput : public GPIOBase { -public: - /** - * @brief Construct and configure a GPIO as input. - * - * @param num GPIO pin number of the GPIO to be configured. - * - * @throws GPIOException - * - if the underlying driver function fails - */ - GPIOInput(GPIONum num); - - /** - * @brief Read the current level of the GPIO. - * - * @return The GPIO current level of the GPIO. - */ - GPIOLevel get_level() const noexcept; - - /** - * @brief Configure the internal pull-up and pull-down restors. - * - * @param mode The pull-up/pull-down configuration see \c GPIOPullMode. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_pull_mode(GPIOPullMode mode); - - /** - * @brief Configure the pin as wake up pin. - * - * @throws GPIOException if the underlying driver function fails. - */ - void wakeup_enable(GPIOWakeupIntrType interrupt_type); - - /** - * @brief Disable wake up functionality for this pin if it was enabled before. - * - * @throws GPIOException if the underlying driver function fails. - */ - void wakeup_disable(); -}; - -/** - * @brief This class represents a GPIO which is configured as open drain output and input at the same time. - * - * This class facilitates bit-banging for single wire protocols. - */ -class GPIO_OpenDrain : public GPIOInput { -public: - /** - * @brief Construct and configure a GPIO as open drain output as well as input. - * - * @param num GPIO pin number of the GPIO to be configured. - * - * @throws GPIOException - * - if the underlying driver function fails - */ - GPIO_OpenDrain(GPIONum num); - - /** - * @brief Set GPIO to floating level. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_floating(); - - /** - * @brief Set GPIO to low level. - * - * @throws GPIOException if the underlying driver function fails. - */ - void set_low(); - - using GPIOBase::set_drive_strength; - using GPIOBase::get_drive_strength; -}; - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp deleted file mode 100644 index 8342a21965..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp +++ /dev/null @@ -1,623 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifndef __cpp_exceptions -#error I2C class can only be used when __cpp_exceptions is enabled. Enable CONFIG_COMPILER_CXX_EXCEPTIONS in Kconfig -#endif - -#include -#include -#include -#include -#include -#include - -#include "sdkconfig.h" -#include "esp_exception.hpp" -#include "system_cxx.hpp" -#include "gpio_cxx.hpp" - -namespace idf { - -/** - * @brief Check if the provided numerical value is a valid I2C address. - * - * @param addr raw number to be checked. - * @return ESP_OK if \c addr is a valid I2C address, otherwise ESP_ERR_INVALID_ARG. - */ -esp_err_t check_i2c_addr(uint32_t addr) noexcept; - -struct I2CException : public ESPException { - I2CException(esp_err_t error); -}; - -struct I2CTransferException : public I2CException { - I2CTransferException(esp_err_t error); -}; - -/** - * @brief Represents a valid SDA signal pin number. - */ -class SDA_type; -using SDA_GPIO = GPIONumBase; - -/** - * @brief Represents a valid SCL signal pin number. - */ -class SCL_type; -using SCL_GPIO = GPIONumBase; - -/** - * @brief Valid representation of I2C number. - * - * A chip can have multiple I2C interfaces, each identified by a bus number, subsequently called I2C number. - * Instances of this class are guaranteed to always contain a valid I2C number. - */ -class I2CNumber : public StrongValueComparable { - /** - * Construct a valid representation of the I2C number. - * - * This constructor is private because the it can only be accessed but the static creation methods below. - * This guarantees that an instance of I2CNumber always carries a valid number. - */ - constexpr explicit I2CNumber(uint32_t number) : StrongValueComparable(number) { } - -public: - /** - * @brief create an I2C number representing the first I2C bus of the chip. - */ - constexpr static I2CNumber I2C0() { - return I2CNumber(0); - } - -#if CONFIG_SOC_I2C_NUM == 2 - /** - * @brief create an I2C number representing the second I2C bus of the chip. - */ - constexpr static I2CNumber I2C1() { - return I2CNumber(1); - } -#endif - - /** - * Retrieves the valid numerical representation of the I2C number. - */ - uint32_t get_num(); -}; - -/** - * @brief Valid representation of I2C address. - * - * Instances of this class are guaranteed to always contain a valid I2C address. - */ -class I2CAddress : public StrongValueComparable { -public: - /** - * - */ - explicit I2CAddress(uint8_t addr); - - /** - * Retrieves the valid numerical representation of the I2C adress. - */ - uint8_t get_addr(); -}; - -/** - * @brief Low-level I2C transaction descriptor - * - * This class records and decribes a low-level transaction. Users use the methods (except \c execute_transfer) - * to record the transaction. Afterwards, the transaction will be executed by calling \c execute_transfer, - * which blocks until the transaction is finished. - * - * @note This is a low-level class, which only exists due to the underlying I2C driver. All data referenced in - * read and write calls must not be changed and must stay allocated until at least \c execute_transfer - * has finished. - */ -class I2CCommandLink { -public: - /** - * @brief Allocate and create the transaction descriptor. - */ - I2CCommandLink(); - - /** - * @brief Delete the transaction descriptor, de-allocate all resources. - */ - ~I2CCommandLink(); - - I2CCommandLink(const I2CCommandLink&) = delete; - I2CCommandLink operator=(const I2CCommandLink&) = delete; - - /** - * @brief Record a start signal on the I2C bus. - */ - void start(); - - /** - * @brief Record a write of the vector \c bytes on the I2C bus. - * - * @param[in] bytes The data to be written. Must stay allocated until execute_transfer has finished or - * destructor of this class has been called. - * @param[in] expect_ack If acknowledgement shall be requested after each written byte, pass true, - * otherwise false. - */ - void write(const std::vector &bytes, bool expect_ack = true); - - /** - * @brief Record a one-byte-write on the I2C bus. - * - * @param[in] byte The data to be written. No restrictions apply. - * @param[in] expect_ack If acknowledgement shall be requested after writing the byte, pass true, - * otherwise false. - */ - void write_byte(uint8_t byte, bool expect_ack = true); - - /** - * @brief Record a read of the size of vector \c bytes on the I2C bus. - * - * @param[in] bytes Vector with the size of the data to be read (in bytes). Must stay allocated until - * execute_transfer has finished or destructor of this class has been called. - * @param[in] expect_ack If acknowledgement shall be requested after each written byte, pass true, - * otherwise false. - */ - void read(std::vector &bytes); - - /** - * @brief Record a stop command on the I2C bus. - */ - void stop(); - - /** - * @brief Execute the transaction and wait until it has finished. - * - * This method will issue the transaction with the operations in the order in which they have been recorded - * before. - * - * @param i2c_num I2C bus number on the chip. - * @param driver_timeout Timeout for this transaction. - */ - void execute_transfer(I2CNumber i2c_num, std::chrono::milliseconds driver_timeout); - -private: - /** - * @brief Internal driver data. - */ - void *handle; -}; - -/** - * Superclass for all transfer objects which are accepted by \c I2CMaster::transfer(). - */ -template -class I2CTransfer { -public: - /** - * Helper typedef to facilitate type resolution during calls to I2CMaster::transfer(). - */ - typedef TReturn TransferReturnT; - - /** - * @param driver_timeout The timeout used for calls like i2c_master_cmd_begin() to the underlying driver. - */ - I2CTransfer(std::chrono::milliseconds driver_timeout_arg = std::chrono::milliseconds(1000)); - - virtual ~I2CTransfer() { } - - /** - * Do all general parts of the I2C transfer: - * - initialize the command link - * - issuing a start to the command link queue - * - calling \c queue_cmd() in the subclass to issue specific commands to the command link queue - * - issuing a stop to the command link queue - * - executing the assembled commands on the I2C bus - * - calling \c process_result() to process the results of the commands or calling process_exception() if - * there was an exception - * - deleting the command link - * This method is normally called by I2CMaster, but can also be used stand-alone if the bus corresponding to - * \c i2c_num has be initialized. - * - * @throws I2CException for any particular I2C error - */ - TReturn do_transfer(I2CNumber i2c_num, I2CAddress i2c_addr); - -protected: - /** - * Implementation of the I2C command is implemented by subclasses. - * The I2C command handle is initialized already at this stage. - * The first action is issuing the I2C address and the read/write bit, depending on what the subclass implements. - * On error, this method has to throw an instance of I2CException. - * - * @param handle the initialized command handle of the I2C driver. - * @param i2c_addr The slave's I2C address. - * - * @throw I2CException - */ - virtual void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) = 0; - - /** - * Implementation of whatever neccessary action after successfully sending the I2C command. - * On error, this method has to throw an instance of I2CException. - * - * @throw I2CException - */ - virtual TReturn process_result() = 0; - - /** - * For some calls to the underlying driver (e.g. \c i2c_master_cmd_begin() ), this general timeout will be passed. - */ - std::chrono::milliseconds driver_timeout; -}; - -/** - * @brief Super class for any I2C master or slave - */ -class I2CBus { -public: - /* - * @brief Initialize I2C master bus. - * - * Initialize and install the bus driver in master mode. - * - * @param i2c_number The I2C port number. - */ - explicit I2CBus(I2CNumber i2c_number); - - /** - * @brief uninstall the bus driver. - */ - virtual ~I2CBus(); - - /** - * The I2C port number. - */ - const I2CNumber i2c_num; -}; - -/** - * @brief Simple I2C Master object - * - * This class provides to ways to issue I2C read and write requests. The simplest way is to use \c sync_write() and - * sync_read() to write and read, respectively. As the name suggests, they block during the whole transfer. - * For all asynchrounous transfers as well as combined write-read transfers, use \c transfer(). - */ -class I2CMaster : public I2CBus { -public: - /** - * Initialize and install the driver of an I2C master peripheral. - * - * Initialize and install the bus driver in master mode. Pullups will be enabled for both pins. If you want a - * different configuration, use configure() and i2c_set_pin() of the underlying driver to disable one or both - * pullups. - * - * @param i2c_number The number of the I2C device. - * @param scl_gpio GPIO number of the SCL line. - * @param sda_gpio GPIO number of the SDA line. - * @param clock_speed The master clock speed. - * @param scl_pullup Enable SCL pullup. - * @param sda_pullup Enable SDA pullup. - * - * @throws I2CException with the corrsponding esp_err_t return value if something goes wrong - */ - explicit I2CMaster(I2CNumber i2c_number, - SCL_GPIO scl_gpio, - SDA_GPIO sda_gpio, - Frequency clock_speed, - bool scl_pullup = true, - bool sda_pullup = true); - - /** - * Delete the driver. - */ - virtual ~I2CMaster(); - - /** - * Issue an asynchronous I2C transfer which is executed in the background. - * - * This method uses a C++ \c std::future as mechanism to wait for the asynchronous return value. - * The return value can be accessed with \c future::get(). \c future::get() also synchronizes with the thread - * doing the work in the background, i.e. it waits until the return value has been issued. - * - * The actual implementation is delegated to the TransferT object. It will be given the I2C number to work - * with. - * - * Requirements for TransferT: It should implement or imitate the interface of I2CTransfer. - * - * @param xfer The transfer to execute. What the transfer does, depends on it's implementation in - * \c TransferT::do_transfer(). It also determines the future template of this function, indicated by - * \c TransferT::TransferReturnT. - * - * @param i2c_addr The address of the I2C slave device targeted by the transfer. - * - * @return A future with \c TransferT::TransferReturnT. It depends on which template type is used for xfer. - * In case of a simple write (I2CWrite), it's future. - * In case of a read (I2CRead), it's future > corresponding to the length of the read - * operation. - * If TransferT is a combined transfer with repeated reads (I2CComposed), then the return type is - * future > >, a vector of results corresponding to the queued read operations. - * - * @throws I2CException with the corrsponding esp_err_t return value if something goes wrong - * @throws std::exception for failures in libstdc++ - */ - template - std::future transfer(I2CAddress i2c_addr, std::shared_ptr xfer); - - /** - * Do a synchronous write. - * - * All data in data will be written to the I2C device with i2c_addr at once. - * This method will block until the I2C write is complete. - * - * @param i2c_addr The address of the I2C device to which the data shall be sent. - * @param data The data to send (size to be sent is determined by data.size()). - * - * @throws I2CException with the corrsponding esp_err_t return value if something goes wrong - * @throws std::exception for failures in libstdc++ - */ - void sync_write(I2CAddress i2c_addr, const std::vector &data); - - /** - * Do a synchronous read. - * This method will block until the I2C read is complete. - * - * n_bytes bytes of data will be read from the I2C device with i2c_addr. - * While reading the last byte, the master finishes the reading by sending a NACK, before issuing a stop. - * - * @param i2c_addr The address of the I2C device from which to read. - * @param n_bytes The number of bytes to read. - * - * @return the read bytes - * - * @throws I2CException with the corrsponding esp_err_t return value if something goes wrong - * @throws std::exception for failures in libstdc++ - */ - std::vector sync_read(I2CAddress i2c_addr, size_t n_bytes); - - /** - * Do a simple synchronous write-read transfer. - * - * First, \c write_data will be written to the bus, then a number of \c read_n_bytes will be read from the bus - * with a repeated start condition. The slave device is determined by \c i2c_addr. - * While reading the last byte, the master finishes the reading by sending a NACK, before issuing a stop. - * This method will block until the I2C transfer is complete. - * - * @param i2c_addr The address of the I2C device from which to read. - * @param write_data The data to write to the bus before reading. - * @param read_n_bytes The number of bytes to read. - * - * @return the read bytes - * - * @throws I2CException with the corrsponding esp_err_t return value if something goes wrong - * @throws std::exception for failures in libstdc++ - */ - std::vector sync_transfer(I2CAddress i2c_addr, - const std::vector &write_data, - size_t read_n_bytes); -}; - -#if CONFIG_SOC_I2C_SUPPORT_SLAVE -/** - * @brief Responsible for initialization and de-initialization of an I2C slave peripheral. - */ -class I2CSlave : public I2CBus { -public: - /** - * Initialize and install the driver of an I2C slave peripheral. - * - * Initialize and install the bus driver in slave mode. Pullups will be enabled for both pins. If you want a - * different configuration, use configure() and i2c_set_pin() of the underlying driver to disable one or both - * pullups. - * - * @param i2c_number The number of the I2C device. - * @param scl_gpio GPIO number of the SCL line. - * @param sda_gpio GPIO number of the SDA line. - * @param slave_addr The address of the slave device on the I2C bus. - * @param rx_buf_len Receive buffer length. - * @param tx_buf_len Transmit buffer length. - * @param scl_pullup Enable SCL pullup. - * @param sda_pullup Enable SDA pullup. - * - * @throws - */ - I2CSlave(I2CNumber i2c_number, - SCL_GPIO scl_gpio, - SDA_GPIO sda_gpio, - I2CAddress slave_addr, - size_t rx_buf_len, - size_t tx_buf_len, - bool scl_pullup = true, - bool sda_pullup = true); - - /** - * Delete the driver. - */ - virtual ~I2CSlave(); - - /** - * Schedule a raw data write once master is ready. - * - * The data is saved in a buffer, waiting for the master to pick it up. - */ - virtual int write_raw(const uint8_t* data, size_t data_len, std::chrono::milliseconds timeout); - - /** - * Read raw data from the bus. - * - * The data is read directly from the buffer. Hence, it has to be written already by master. - */ - virtual int read_raw(uint8_t* buffer, size_t buffer_len, std::chrono::milliseconds timeout); -}; -#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE - -/** - * Implementation for simple I2C writes, which can be executed by \c I2CMaster::transfer(). - * It stores the bytes to be written as a vector. - */ -class I2CWrite : public I2CTransfer { -public: - /** - * @param bytes The bytes which should be written. - * @param driver_timeout The timeout used for calls like i2c_master_cmd_begin() to the underlying driver. - */ - I2CWrite(const std::vector &bytes, std::chrono::milliseconds driver_timeout = std::chrono::milliseconds(1000)); - -protected: - /** - * Write the address and set the read bit to 0 to issue the address and request a write. - * Then write the bytes. - * - * @param handle The initialized I2C command handle. - * @param i2c_addr The I2C address of the slave. - */ - void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) override; - - /** - * Set the value of the promise to unblock any callers waiting on it. - */ - void process_result() override; - -private: - /** - * The bytes to write. - */ - std::vector bytes; -}; - -/** - * Implementation for simple I2C reads, which can be executed by \c I2CMaster::transfer(). - * It stores the bytes to be read as a vector to be returned later via a future. - */ -class I2CRead : public I2CTransfer > { -public: - /** - * @param The number of bytes to read. - * @param driver_timeout The timeout used for calls like i2c_master_cmd_begin() to the underlying driver. - */ - I2CRead(size_t size, std::chrono::milliseconds driver_timeout = std::chrono::milliseconds(1000)); - -protected: - /** - * Write the address and set the read bit to 1 to issue the address and request a read. - * Then read into bytes. - * - * @param handle The initialized I2C command handle. - * @param i2c_addr The I2C address of the slave. - */ - void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) override; - - /** - * Set the return value of the promise to unblock any callers waiting on it. - */ - std::vector process_result() override; - -private: - /** - * The bytes to read. - */ - std::vector bytes; -}; - -/** - * This kind of transfer uses repeated start conditions to chain transfers coherently. - * In particular, this can be used to chain multiple single write and read transfers into a single transfer with - * repeated starts as it is commonly done for I2C devices. - * The result is a vector of vectors representing the reads in the order of how they were added using add_read(). - */ -class I2CComposed : public I2CTransfer > > { -public: - I2CComposed(std::chrono::milliseconds driver_timeout = std::chrono::milliseconds(1000)); - - /** - * Add a read to the chain. - * - * @param size The size of the read in bytes. - */ - void add_read(size_t size); - - /** - * Add a write to the chain. - * - * @param bytes The bytes to write; size will be bytes.size() - */ - void add_write(std::vector bytes); - -protected: - /** - * Write all chained transfers, including a repeated start issue after each but the last transfer. - * - * @param handle The initialized I2C command handle. - * @param i2c_addr The I2C address of the slave. - */ - void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) override; - - /** - * Creates the vector with the vectors from all reads. - */ - std::vector > process_result() override; - -private: - class CompTransferNode { - public: - virtual ~CompTransferNode() { } - virtual void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) = 0; - virtual void process_result(std::vector > &read_results) { } - }; - - class CompTransferNodeRead : public CompTransferNode { - public: - CompTransferNodeRead(size_t size) : bytes(size) { } - void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) override; - - void process_result(std::vector > &read_results) override; - private: - std::vector bytes; - }; - - class CompTransferNodeWrite : public CompTransferNode { - public: - CompTransferNodeWrite(std::vector bytes) : bytes(bytes) { } - void queue_cmd(I2CCommandLink &handle, I2CAddress i2c_addr) override; - private: - std::vector bytes; - }; - - /** - * The chained transfers. - */ - std::list > transfer_list; -}; - -template -I2CTransfer::I2CTransfer(std::chrono::milliseconds driver_timeout_arg) - : driver_timeout(driver_timeout_arg) { } - -template -TReturn I2CTransfer::do_transfer(I2CNumber i2c_num, I2CAddress i2c_addr) -{ - I2CCommandLink cmd_link; - - queue_cmd(cmd_link, i2c_addr); - - cmd_link.stop(); - - cmd_link.execute_transfer(i2c_num, driver_timeout); - - return process_result(); -} - -template -std::future I2CMaster::transfer(I2CAddress i2c_addr, std::shared_ptr xfer) -{ - if (!xfer) throw I2CException(ESP_ERR_INVALID_ARG); - - return std::async(std::launch::async, [this](std::shared_ptr xfer, I2CAddress i2c_addr) { - return xfer->do_transfer(i2c_num, i2c_addr); - }, xfer, i2c_addr); -} - -} // idf diff --git a/examples/cxx/experimental/experimental_cpp_component/include/spi_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/spi_cxx.hpp deleted file mode 100644 index fc50db0bb6..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/spi_cxx.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#if __cpp_exceptions - -#include "esp_exception.hpp" -#include "gpio_cxx.hpp" -#include "system_cxx.hpp" - -namespace idf { - -/** - * @brief Exception which is thrown in the context of SPI C++ classes. - */ -struct SPIException : public ESPException { - SPIException(esp_err_t error); -}; - -/** - * @brief The maximum SPI transfer size in bytes. - */ -class SPITransferSize : public StrongValueOrdered { -public: - /** - * @brief Create a valid SPI transfer size. - * - * @param transfer_size The raw transfer size in bytes. - */ - explicit SPITransferSize(size_t transfer_size) noexcept : StrongValueOrdered(transfer_size) { } - - static SPITransferSize default_size() { - return SPITransferSize(0); - } -}; - -/** - * @brief Check if the raw uint32_t spi number is in the range according to the hardware. - */ -esp_err_t check_spi_num(uint32_t spi_num) noexcept; - -/** - * @brief Represents a valid SPI host number. - * - * ESP chips may have different independent SPI peripherals. This SPI number distinguishes between them. - */ -class SPINum : public StrongValueComparable { -public: - /** - * @brief Create a valid SPI host number. - * - * @param host_id_raw The raw SPI host number. - * - * @throw SPIException if the passed SPI host number is incorrect. - */ - explicit SPINum(uint32_t host_id_raw) : StrongValueComparable(host_id_raw) - { - esp_err_t spi_num_check_result = check_spi_num(host_id_raw); - if (spi_num_check_result != ESP_OK) { - throw SPIException(spi_num_check_result); - } - } - - /** - * @brief Return the raw value of the SPI host. - * - * This should only be used when calling driver and other interfaces which don't support the C++ class. - * - * @return the raw value of the SPI host. - */ - uint32_t get_spi_num() const - { - return get_value(); - } -}; - -/** - * @brief Represents a valid MOSI signal pin number. - */ -class MOSI_type; -using MOSI = GPIONumBase; - -/** - * @brief Represents a valid MISO signal pin number. - */ -class MISO_type; -using MISO = GPIONumBase; - -/** - * @brief Represents a valid SCLK signal pin number. - */ -class SCLK_type; -using SCLK = GPIONumBase; - -/** - * @brief Represents a valid CS (chip select) signal pin number. - */ -class CS_type; -using CS = GPIONumBase; - -/** - * @brief Represents a valid QSPIWP signal pin number. - */ -class QSPIWP_type; -using QSPIWP = GPIONumBase; - -/** - * @brief Represents a valid QSPIHD signal pin number. - */ -class QSPIHD_type; -using QSPIHD = GPIONumBase; - -/** - * @brief Represents a valid SPI DMA configuration. Use it similar to an enum. - */ -class SPI_DMAConfig : public StrongValueComparable { - /** - * Constructor is hidden to enforce object invariants. - * Use the static creation methods to create instances. - */ - explicit SPI_DMAConfig(uint32_t channel_num) : StrongValueComparable(channel_num) { } - -public: - /** - * @brief Create a configuration with DMA disabled. - */ - static SPI_DMAConfig DISABLED(); - - /** - * @brief Create a configuration where the driver allocates DMA. - */ - static SPI_DMAConfig AUTO(); - - /** - * @brief Return the raw value of the DMA configuration. - * - * This should only be used when calling driver and other interfaces which don't support the C++ class. - * - * @return the raw value of the DMA configuration. - */ - uint32_t get_num() const { - return get_value(); - } -}; - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/include/spi_host_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/spi_host_cxx.hpp deleted file mode 100644 index 57a194a24e..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/spi_host_cxx.hpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#if __cpp_exceptions - -#include -#include -#include -#include -#include -#include - -#include "system_cxx.hpp" -#include "spi_cxx.hpp" - -namespace idf { - -/** - * @brief Exception which is thrown in the context of SPI Transactions. - */ -struct SPITransferException : public SPIException { - SPITransferException(esp_err_t error); -}; - -class SPIDevice; -class SPIDeviceHandle; - -/** - * @brief Describes and encapsulates the transaction. - * - * @note This class is intended to be used internally by the SPI C++ classes, but not publicly. - * Furthermore, currently only one transaction per time can be handled. If you need to - * send several transactions in parallel, you need to build your own mechanism around a - * FreeRTOS task and a queue. - */ -class SPITransactionDescriptor { - friend class SPIDeviceHandle; -public: - /** - * @brief Create a SPITransactionDescriptor object, describing a full duplex transaction. - * - * @param data_to_send The data sent to the SPI device. It can be dummy data if a read-only - * transaction is intended. Its length determines the length of both write and read operation. - * @param handle to the internal driver handle - * @param pre_callback If non-empty, this callback will be called directly before the transaction. - * @param post_callback If non-empty, this callback will be called directly after the transaction. - * @param user_data optional data which will be accessible in the callbacks declared above - */ - SPITransactionDescriptor(const std::vector &data_to_send, - SPIDeviceHandle *handle, - std::function pre_callback = nullptr, - std::function post_callback = nullptr, - void* user_data = nullptr); - - /** - * @brief Deinitialize and delete all data of the transaction. - * - * @note This destructor must not becalled before the transaction is finished by the driver. - */ - ~SPITransactionDescriptor(); - - SPITransactionDescriptor(const SPITransactionDescriptor&) = delete; - SPITransactionDescriptor operator=(const SPITransactionDescriptor&) = delete; - - /** - * @brief Queue the transaction asynchronously. - */ - void start(); - - /** - * @brief Synchronously (blocking) wait for the result and return the result data or throw an exception. - * - * @return The data read from the SPI device. Its length is the length of \c data_to_send passed in the - * constructor. - * @throws SPIException in case of an error of the underlying driver or if the driver returns a wrong - * transaction descriptor for some reason. In the former case, the error code is the one from the - * underlying driver, in the latter case, the error code is ESP_ERR_INVALID_STATE. - */ - std::vector get(); - - /** - * @brief Wait until the asynchronous operation is done. - * - * @throws SPIException in case of an error of the underlying driver or if the driver returns a wrong - * transaction descriptor for some reason. In the former case, the error code is the one from the - * underlying driver, in the latter case, the error code is ESP_ERR_INVALID_STATE. - */ - void wait(); - - - /** - * @brief Wait for a result of the transaction up to timeout ms. - * - * @param timeout Maximum timeout value for waiting - * - * @return true if result is available, false if wait timed out - * - * @throws SPIException in case of an error of the underlying driver or if the driver returns a wrong - * transaction descriptor for some reason. In the former case, the error code is the one from the - * underlying driver, in the latter case, the error code is ESP_ERR_INVALID_STATE. - */ - bool wait_for(const std::chrono::milliseconds &timeout); - -private: - /** - * Private descriptor data. - */ - void *private_transaction_desc; - - /** - * Private device data. - */ - SPIDeviceHandle *device_handle; - - /** - * @brief If non-empty, this callback will be called directly before the transaction. - */ - std::function pre_callback; - - /** - * @brief If non-empty, this callback will be called directly after the transaction. - */ - std::function post_callback; - - /** - * Buffer in spi_transaction_t is const, so we have to declare it here because we want to - * allocate and delete it. - */ - uint8_t *tx_buffer; - - /** - * @brief User data which will be provided in the callbacks. - */ - void *user_data; - - /** - * Tells if data has been received, i.e. the transaction has finished and the result can be acquired. - */ - bool received_data; - - /** - * Tells if the transaction has been initiated and is at least in-flight, if not finished. - */ - bool started; -}; - -/** - * @brief SPIFuture for asynchronous transaction results, mostly equivalent to std::future. - * - * This re-implementation is necessary as std::future is incompatible with the IDF SPI driver interface. - */ -class SPIFuture { -public: - /** - * @brief Create an invalid future. - */ - SPIFuture(); - - /** - * @brief Create a valid future with \c transaction as shared state. - * - * @param transaction the shared transaction state - */ - SPIFuture(std::shared_ptr transaction); - - SPIFuture(const SPIFuture &other) = delete; - - /** - * @brief Move constructor as in std::future, leaves \c other invalid. - * - * @param other object to move from, will become invalid during this constructor - */ - SPIFuture(SPIFuture &&other) noexcept; - - /** - * @brief Move assignment as in std::future, leaves \c other invalid. - * - * @param other object to move from, will become invalid during this constructor - * @return A reference to the newly created SPIFuture object - */ - SPIFuture &operator=(SPIFuture&& other) noexcept; - - /** - * @brief Wait until the asynchronous operation is done and return the result or throw and exception. - * - * @throws std::future_error if this future is not valid. - * @throws SPIException in case of an error of the underlying driver or if the driver returns a wrong - * transaction descriptor for some reason. In the former case, the error code is the one from the - * underlying driver, in the latter case, the error code is ESP_ERR_INVALID_STATE. - * @return The result of the asynchronous SPI transaction. - */ - std::vector get(); - - /** - * @brief Wait for a result up to timeout ms. - * - * @param timeout Maximum timeout value for waiting - * - * @return std::future_status::ready if result is available, std::future_status::timeout if wait timed out - */ - std::future_status wait_for(std::chrono::milliseconds timeout); - - /** - * @brief Wait for a result indefinitely. - */ - void wait(); - - /** - * @return true if this future is valid, otherwise false. - */ - bool valid() const noexcept; - -private: - /** - * The SPITransactionDescriptor, which is the shared state of this future. - */ - std::shared_ptr transaction; - - /** - * Indicates if this future is valid. - */ - bool is_valid; -}; - -/** - * @brief Represents an device on an initialized Master Bus. - */ -class SPIDevice { -public: - /** - * @brief Create and initialize a device on the master bus corresponding to spi_host. - * - * @param cs The pin number of the chip select signal for the device to create. - * @param spi_host the spi_host (bus) to which the device shall be attached. - * @param frequency The devices frequency. this frequency will be set during transactions to the device which will be - * created. - * @param transaction_queue_size The of the transaction queue of this device. This determines how many - * transactions can be queued at the same time. Currently, it is set to 1 since the - * implementation exclusively acquires the bus for each transaction. This may change in the future. - */ - SPIDevice(SPINum spi_host, - CS cs, - Frequency frequency = Frequency::MHz(1), - QueueSize transaction_queue_size = QueueSize(1u)); - - SPIDevice(const SPIDevice&) = delete; - SPIDevice operator=(const SPIDevice&) = delete; - - /** - * @brief De-initializes and destroys the device. - * - * @warning Behavior is undefined if a device is destroyed while there is still an ongoing transaction - * from that device. - */ - ~SPIDevice(); - - /** - * @brief Queue a transfer to this device. - * - * This method creates a full-duplex transfer to the device represented by the current instance of this class. - * It then queues that transfer and returns a "future" object. The future object will become ready once - * the transfer finishes. - * - * @param data_to_send Data which will be sent to the device. The length of the data determines the length - * of the full-deplex transfer. I.e., the same amount of bytes will be received from the device. - * @param pre_callback If non-empty, this callback will be called directly before the transaction. - * If empty, it will be ignored. - * @param post_callback If non-empty, this callback will be called directly after the transaction. - * If empty, it will be ignored. - * @param user_data This pointer will be sent to pre_callback and/or pre_callback, if any of them is non-empty. - * - * @return a future object which will become ready once the transfer has finished. See also \c SPIFuture. - */ - SPIFuture transfer(const std::vector &data_to_send, - std::function pre_callback = nullptr, - std::function post_callback = nullptr, - void* user_data = nullptr); - - /** - * @brief Queue a transfer to this device like \c transfer, but using begin/end iterators instead of a - * data vector. - * - * This method is equivalent to \c transfer(), except for the parameters. - * - * @param begin Iterator to the begin of the data which will be sent to the device. - * @param end Iterator to the end of the data which will be sent to the device. - * This iterator determines the length of the data and hence the length of the full-deplex transfer. - * I.e., the same amount of bytes will be received from the device. - * @param pre_callback If non-empty, this callback will be called directly before the transaction. - * If empty, it will be ignored. - * @param post_callback If non-empty, this callback will be called directly after the transaction. - * If empty, it will be ignored. - * @param user_data This pointer will be sent to pre_callback and/or pre_callback, if any of them is non-empty. - * - * @return a future object which will become ready once the transfer has finished. See also \c SPIFuture. - */ - template - SPIFuture transfer(IteratorT begin, - IteratorT end, - std::function pre_callback = nullptr, - std::function post_callback = nullptr, - void* user_data = nullptr); - -private: - /** - * Private device data. - */ - SPIDeviceHandle *device_handle; - - /** - * Saves the current transaction descriptor in case the user's loses its future with the other - * reference to the transaction. - */ - std::shared_ptr current_transaction; -}; - -/** - * @brief Represents an SPI Master Bus. - */ -class SPIMaster { -public: - /* - * @brief Create an SPI Master Bus. - * - * @param host The SPI host (bus) which should be used. ESP chips have a number of different possible SPI hosts, - * each of which will create its own bus. Consult the datasheet and TRM on which host to choose. - * @param mosi The pin number for the MOSI signal of this bus. - * @param miso The pin number for the MISO signal of this bus. - * @param sclk The pin number for the clock signal of this bus. - * @param dma_config The DMA configuration for this bus, see \c DMAConfig. - * @param max_transfer_size The maximum transfer size in bytes. - * - * @throws SPIException with IDF error code if the underlying driver fails. - */ - explicit SPIMaster(SPINum host, - const MOSI &mosi, - const MISO &miso, - const SCLK &sclk, - SPI_DMAConfig dma_config = SPI_DMAConfig::AUTO(), - SPITransferSize max_transfer_size = SPITransferSize::default_size()); - - /* - * @brief Create an SPI Master Bus. - * - * @param host The SPI host (bus) which should be used. ESP chips have a number of different possible SPI hosts, - * each of which will create its own bus. Consult the datasheet and TRM on which host to choose. - * @param mosi The pin number for the MOSI signal of this bus. - * @param miso The pin number for the MISO signal of this bus. - * @param sclk The pin number for the clock signal of this bus. - * @param qspiwp The pin number for the QSPIWP signal of this bus. - * @param qspihd The pin number for the QSPIHD signal of this bus. - * @param dma_config The DMA configuration for this bus, see \c DMAConfig. - * @param max_transfer_size The maximum transfer size in bytes. - * - * @throws SPIException with IDF error code if the underlying driver fails. - */ - explicit SPIMaster(SPINum host, - const MOSI &mosi, - const MISO &miso, - const SCLK &sclk, - const QSPIWP &qspiwp, - const QSPIHD &qspihd, - SPI_DMAConfig dma_config = SPI_DMAConfig::AUTO(), - SPITransferSize max_transfer_size = SPITransferSize::default_size()); - - SPIMaster(const SPIMaster&) = delete; - SPIMaster operator=(const SPIMaster&) = delete; - - SPIMaster(SPIMaster&&) = default; - SPIMaster &operator=(SPIMaster&&) = default; - - /* - * @brief De-initializes and destroys the SPI Master Bus. - * - * @note Devices created before which try to initialize an exception after the bus is destroyed will throw - * and exception. - */ - virtual ~SPIMaster(); - - /** - * @brief Create a representation of a device on this bus. - * - * @param cs The pin number for the CS (chip select) signal to talk to the device. - * @param f The frequency used to talk to the device. - */ - std::shared_ptr create_dev(CS cs, Frequency frequency = Frequency::MHz(1)); - -private: - /** - * @brief Host identifier for internal use. - */ - SPINum spi_host; -}; - -template -SPIFuture SPIDevice::transfer(IteratorT begin, - IteratorT end, - std::function pre_callback, - std::function post_callback, - void* user_data) -{ - std::vector write_data; - write_data.assign(begin, end); - return transfer(write_data, pre_callback, post_callback, user_data); -} - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/include/system_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/system_cxx.hpp deleted file mode 100644 index 2a4f8c6274..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/include/system_cxx.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * This file contains helper classes for commonly used IDF types. The classes make the use of these types easier and - * safer. - * In particular, their usage provides greater type-safety of function arguments and "correctness by construction". - */ -#pragma once - -#ifndef __cpp_exceptions -#error system C++ classes only usable when C++ exceptions enabled. Enable CONFIG_COMPILER_CXX_EXCEPTIONS in Kconfig -#endif - -#include "esp_exception.hpp" - -/** - * This is a "Strong Value Type" base class for types in IDF C++ classes. - * The idea is that subclasses completely check the contained value during construction. - * After that, it's trapped and encapsulated inside and cannot be changed anymore. - * Consequently, the API functions receiving a correctly implemented sub class as parameter - * don't need to check it anymore. Only at API boundaries the valid value will be retrieved - * with get_value(). - */ -template -class StrongValue { -protected: - constexpr StrongValue(ValueT value_arg) : value(value_arg) { } - - ValueT get_value() const { - return value; - } - -private: - ValueT value; -}; - -/** - * This class adds comparison properties to StrongValue, but no sorting and ordering properties. - */ -template -class StrongValueComparable : public StrongValue { -protected: - constexpr StrongValueComparable(ValueT value_arg) : StrongValue(value_arg) { } - -public: - using StrongValue::get_value; - - bool operator==(const StrongValueComparable &other_gpio) const - { - return get_value() == other_gpio.get_value(); - } - - bool operator!=(const StrongValueComparable &other_gpio) const - { - return get_value() != other_gpio.get_value(); - } -}; - -namespace idf { - -/** - * This class adds ordering and sorting properties to StrongValue. - */ -template -class StrongValueOrdered : public StrongValueComparable { -public: - StrongValueOrdered(ValueT value) : StrongValueComparable(value) { } - - using StrongValueComparable::get_value; - - bool operator>(const StrongValueOrdered &other) const - { - return get_value() > other.get_value(); - } - - bool operator<(const StrongValueOrdered &other) const - { - return get_value() < other.get_value(); - } - - bool operator>=(const StrongValueOrdered &other) const - { - return get_value() >= other.get_value(); - } - - bool operator<=(const StrongValueOrdered &other) const - { - return get_value() <= other.get_value(); - } -}; - -/** - * A general frequency class to be used whereever an unbound frequency value is necessary. - */ -class Frequency : public StrongValueOrdered { -public: - explicit Frequency(size_t frequency) : StrongValueOrdered(frequency) - { - if (frequency == 0) { - throw ESPException(ESP_ERR_INVALID_ARG); - } - } - - Frequency(const Frequency&) = default; - Frequency &operator=(const Frequency&) = default; - - using StrongValueOrdered::get_value; - - static Frequency Hz(size_t frequency) - { - return Frequency(frequency); - } - - static Frequency KHz(size_t frequency) - { - return Frequency(frequency * 1000); - } - - static Frequency MHz(size_t frequency) - { - return Frequency(frequency * 1000 * 1000); - } -}; - -/** - * Queue size mainly for operating system queues. - */ -class QueueSize { -public: - explicit QueueSize(size_t q_size) : queue_size(q_size) { } - - size_t get_size() - { - return queue_size; - } - -private: - size_t queue_size; -}; - -} diff --git a/examples/cxx/experimental/experimental_cpp_component/private_include/spi_host_private_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/private_include/spi_host_private_cxx.hpp deleted file mode 100644 index 253aaa8525..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/private_include/spi_host_private_cxx.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * The code in this file includes driver headers directly, hence it's a private include. - * It should only be used in C++ source files, while header files use forward declarations of the types. - * This way, public headers don't need to depend on (i.e. include) driver headers. - */ - -#ifdef __cpp_exceptions - -#include "hal/spi_types.h" -#include "driver/spi_master.h" - -using namespace std; - -namespace idf { - -#define SPI_CHECK_THROW(err) CHECK_THROW_SPECIFIC((err), SPIException) - -namespace { - -/** - * @brief Convenience method to convert a SPINum object into the driver type. Avoids long static casts. - */ -spi_host_device_t spi_num_to_driver_type(const SPINum &num) noexcept { - return static_cast(num.get_spi_num()); -} - -} - -/** - * This class wraps closely around the SPI master device driver functions. - * It is used to hide the implementation, in particular the dependencies on the driver and HAL layer headers. - * Public header files only use a pointer to this class which is forward declared in spi_host_cxx.hpp. - * Implementations (source files) can include this private header and use the class definitions. - * - * Furthermore, this class ensures RAII-capabilities of an SPI master device allocation and initiates pre- and - * post-transaction callback for each transfer. In constrast to the IDF driver, the callbacks are not per-device - * but per transaction in the C++ wrapper framework. - * - * For information on the public member functions, refer to the corresponding driver functions in spi_master.h - */ -class SPIDeviceHandle { -public: - /** - * Create a device instance on the SPI bus identified by spi_host, allocate all corresponding resources. - */ - SPIDeviceHandle(SPINum spi_host, CS cs, Frequency frequency, QueueSize q_size) - { - spi_device_interface_config_t dev_config = {}; - dev_config.clock_speed_hz = frequency.get_value(); - dev_config.spics_io_num = cs.get_num(); - dev_config.pre_cb = pr_cb; - dev_config.post_cb = post_cb; - dev_config.queue_size = q_size.get_size(); - SPI_CHECK_THROW(spi_bus_add_device(spi_num_to_driver_type(spi_host), &dev_config, &handle)); - } - - SPIDeviceHandle(const SPIDeviceHandle &other) = delete; - - SPIDeviceHandle(SPIDeviceHandle &&other) noexcept : handle(std::move(other.handle)) - { - // Only to indicate programming errors where users use an instance after moving it. - other.handle = nullptr; - } - - /** - * Remove device instance from the SPI bus, deallocate all corresponding resources. - */ - ~SPIDeviceHandle() - { - // We ignore the return value here. - // Only possible errors are wrong handle (impossible by object invariants) and - // handle already freed, which we can ignore. - spi_bus_remove_device(handle); - } - - SPIDeviceHandle &operator=(SPIDeviceHandle&& other) noexcept - { - if (this != &other) { - handle = std::move(other.handle); - - // Only to indicate programming errors where users use an instance after moving it. - other.handle = nullptr; - } - return *this; - } - - esp_err_t acquire_bus(TickType_t wait) - { - return spi_device_acquire_bus(handle, portMAX_DELAY); - } - - esp_err_t queue_trans(spi_transaction_t *trans_desc, TickType_t wait) - { - return spi_device_queue_trans(handle, trans_desc, wait); - } - - esp_err_t get_trans_result(spi_transaction_t **trans_desc, TickType_t ticks_to_wait) - { - return spi_device_get_trans_result(handle, trans_desc, ticks_to_wait); - } - - void release_bus() - { - spi_device_release_bus(handle); - } - -private: - /** - * Route the callback to the callback in the specific SPITransactionDescriptor instance. - */ - static void pr_cb(spi_transaction_t *driver_transaction) - { - SPITransactionDescriptor *transaction = static_cast(driver_transaction->user); - if (transaction->pre_callback) { - transaction->pre_callback(transaction->user_data); - } - } - - /** - * Route the callback to the callback in the specific SPITransactionDescriptor instance. - */ - static void post_cb(spi_transaction_t *driver_transaction) - { - SPITransactionDescriptor *transaction = static_cast(driver_transaction->user); - if (transaction->post_callback) { - transaction->post_callback(transaction->user_data); - } - } - - spi_device_handle_t handle; -}; - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/spi_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/spi_cxx.cpp deleted file mode 100644 index 18f3e82dc7..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/spi_cxx.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#if __cpp_exceptions - -#include "driver/spi_common.h" -#include "esp_exception.hpp" -#include "spi_cxx.hpp" - -namespace idf { - -esp_err_t check_spi_num(uint32_t spi_num) noexcept { - if (spi_num >= static_cast(SPI_HOST_MAX)) { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -SPI_DMAConfig SPI_DMAConfig::DISABLED() { - return SPI_DMAConfig(static_cast(spi_common_dma_t::SPI_DMA_DISABLED)); -} - -SPI_DMAConfig SPI_DMAConfig::AUTO() { - return SPI_DMAConfig(static_cast(spi_common_dma_t::SPI_DMA_CH_AUTO)); -} - -} - -#endif diff --git a/examples/cxx/experimental/experimental_cpp_component/spi_host_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/spi_host_cxx.cpp deleted file mode 100644 index 603d8015e3..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/spi_host_cxx.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#if __cpp_exceptions - -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/portmacro.h" -#include "hal/spi_types.h" -#include "driver/spi_master.h" -#include "spi_host_cxx.hpp" -#include "spi_host_private_cxx.hpp" - -using namespace std; - -namespace idf { - -SPIException::SPIException(esp_err_t error) : ESPException(error) { } - -SPITransferException::SPITransferException(esp_err_t error) : SPIException(error) { } - -SPIMaster::SPIMaster(SPINum host, - const MOSI &mosi, - const MISO &miso, - const SCLK &sclk, - SPI_DMAConfig dma_config, - SPITransferSize transfer_size) - : spi_host(host) -{ - spi_bus_config_t bus_config = {}; - bus_config.mosi_io_num = mosi.get_num(); - bus_config.miso_io_num = miso.get_num(); - bus_config.sclk_io_num = sclk.get_num(); - bus_config.quadwp_io_num = -1; - bus_config.quadhd_io_num = -1; - bus_config.max_transfer_sz = transfer_size.get_value(); - - SPI_CHECK_THROW(spi_bus_initialize(spi_num_to_driver_type(spi_host), &bus_config, dma_config.get_num())); -} - -SPIMaster::SPIMaster(SPINum host, - const MOSI &mosi, - const MISO &miso, - const SCLK &sclk, - const QSPIWP &qspiwp, - const QSPIHD &qspihd, - SPI_DMAConfig dma_config, - SPITransferSize transfer_size) - : spi_host(host) -{ - spi_bus_config_t bus_config = {}; - bus_config.mosi_io_num = mosi.get_num(); - bus_config.miso_io_num = miso.get_num(); - bus_config.sclk_io_num = sclk.get_num(); - bus_config.quadwp_io_num = qspiwp.get_num(); - bus_config.quadhd_io_num = qspihd.get_num(); - bus_config.max_transfer_sz = transfer_size.get_value(); - - SPI_CHECK_THROW(spi_bus_initialize(spi_num_to_driver_type(spi_host), &bus_config, dma_config.get_num())); -} - -SPIMaster::~SPIMaster() -{ - spi_bus_free(spi_num_to_driver_type(spi_host)); -} - -shared_ptr SPIMaster::create_dev(CS cs, Frequency frequency) -{ - return make_shared(spi_host, cs, frequency); -} - -SPIFuture::SPIFuture() - : transaction(), is_valid(false) -{ -} - -SPIFuture::SPIFuture(shared_ptr transaction) - : transaction(transaction), is_valid(true) -{ -} - -SPIFuture::SPIFuture(SPIFuture &&other) noexcept - : transaction(std::move(other.transaction)), is_valid(true) -{ - other.is_valid = false; -} - -SPIFuture &SPIFuture::operator=(SPIFuture &&other) noexcept -{ - if (this != &other) { - transaction = std::move(other.transaction); - is_valid = other.is_valid; - other.is_valid = false; - } - return *this; -} - -vector SPIFuture::get() -{ - if (!is_valid) { - throw std::future_error(future_errc::no_state); - } - - return transaction->get(); -} - -future_status SPIFuture::wait_for(chrono::milliseconds timeout) -{ - if (transaction->wait_for(timeout)) { - return std::future_status::ready; - } else { - return std::future_status::timeout; - } -} - -void SPIFuture::wait() -{ - transaction->wait(); -} - -bool SPIFuture::valid() const noexcept -{ - return is_valid; -} - -SPIDevice::SPIDevice(SPINum spi_host, CS cs, Frequency frequency, QueueSize q_size) : device_handle() -{ - device_handle = new SPIDeviceHandle(spi_host, cs, frequency, q_size); -} - -SPIDevice::~SPIDevice() -{ - delete device_handle; -} - -SPIFuture SPIDevice::transfer(const vector &data_to_send, - std::function pre_callback, - std::function post_callback, - void* user_data) -{ - current_transaction = make_shared(data_to_send, - device_handle, - std::move(pre_callback), - std::move(post_callback), - user_data); - current_transaction->start(); - return SPIFuture(current_transaction); -} - -SPITransactionDescriptor::SPITransactionDescriptor(const std::vector &data_to_send, - SPIDeviceHandle *handle, - std::function pre_callback, - std::function post_callback, - void* user_data_arg) - : device_handle(handle), - pre_callback(std::move(pre_callback)), - post_callback(std::move(post_callback)), - user_data(user_data_arg), - received_data(false), - started(false) -{ - // C++11 vectors don't have size() or empty() members yet - if (data_to_send.begin() == data_to_send.end()) { - throw SPITransferException(ESP_ERR_INVALID_ARG); - } - if (handle == nullptr) { - throw SPITransferException(ESP_ERR_INVALID_ARG); - } - - size_t trans_size = data_to_send.size(); - spi_transaction_t *trans_desc; - trans_desc = new spi_transaction_t; - memset(trans_desc, 0, sizeof(spi_transaction_t)); - trans_desc->rx_buffer = new uint8_t [trans_size]; - tx_buffer = new uint8_t [trans_size]; - for (size_t i = 0; i < trans_size; i++) { - tx_buffer[i] = data_to_send[i]; - } - trans_desc->length = trans_size * 8; - trans_desc->tx_buffer = tx_buffer; - trans_desc->user = this; - - private_transaction_desc = trans_desc; -} - -SPITransactionDescriptor::~SPITransactionDescriptor() -{ - if (started) { - assert(received_data); // We need to make sure that trans_desc has been received, otherwise the - // driver may still write into it afterwards. - } - - spi_transaction_t *trans_desc = reinterpret_cast(private_transaction_desc); - delete [] tx_buffer; - delete [] static_cast(trans_desc->rx_buffer); - delete trans_desc; -} - -void SPITransactionDescriptor::start() -{ - spi_transaction_t *trans_desc = reinterpret_cast(private_transaction_desc); - SPI_CHECK_THROW(device_handle->acquire_bus(portMAX_DELAY)); - SPI_CHECK_THROW(device_handle->queue_trans(trans_desc, 0)); - started = true; -} - -void SPITransactionDescriptor::wait() -{ - while (wait_for(chrono::milliseconds(portMAX_DELAY)) == false) { } -} - -bool SPITransactionDescriptor::wait_for(const chrono::milliseconds &timeout_duration) -{ - if (received_data) { - return true; - } - - if (!started) { - throw SPITransferException(ESP_ERR_INVALID_STATE); - } - - spi_transaction_t *acquired_trans_desc; - esp_err_t err = device_handle->get_trans_result(&acquired_trans_desc, - (TickType_t) timeout_duration.count() / portTICK_PERIOD_MS); - - if (err == ESP_ERR_TIMEOUT) { - return false; - } - - if (err != ESP_OK) { - throw SPITransferException(err); - } - - if (acquired_trans_desc != reinterpret_cast(private_transaction_desc)) { - throw SPITransferException(ESP_ERR_INVALID_STATE); - } - - received_data = true; - device_handle->release_bus(); - - return true; -} - -std::vector SPITransactionDescriptor::get() -{ - if (!received_data) { - wait(); - } - - spi_transaction_t *trans_desc = reinterpret_cast(private_transaction_desc); - const size_t TRANSACTION_LENGTH = trans_desc->length / 8; - vector result(TRANSACTION_LENGTH); - - for (int i = 0; i < TRANSACTION_LENGTH; i++) { - result[i] = static_cast(trans_desc->rx_buffer)[i]; - } - - return result; -} - -} // idf - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt deleted file mode 100644 index 017495bf43..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS . - PRIV_REQUIRES cmock test_utils experimental_cpp_component) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp deleted file mode 100644 index f9021334d9..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include "unity.h" - -#include "unity_cxx.hpp" -#include "esp_exception.hpp" - -#ifdef __cpp_exceptions - -using namespace std; -using namespace idf; - -#define TAG "CXX Exception Test" - -#if CONFIG_IDF_TARGET_ESP32 -#define LEAKS "300" -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 -#define LEAKS "800" -#else -#error "unknown target in CXX tests, can't set leaks threshold" -#endif - -TEST_CASE("TEST_THROW catches exception", "[cxx exception][leaks=" LEAKS "]") -{ - TEST_THROW(throw ESPException(ESP_FAIL);, ESPException); -} - -/* The following two test cases are expected to fail */ - -TEST_CASE("TEST_THROW asserts catching different exception", "[cxx exception][ignore]") -{ - TEST_THROW(throw std::exception();, ESPException); -} - -TEST_CASE("TEST_THROW asserts not catching any exception", "[cxx exception][ignore]") -{ - TEST_THROW(printf(" ");, ESPException); // need statement with effect -} - -TEST_CASE("CHECK_THROW continues on ESP_OK", "[cxx exception][leaks=" LEAKS "]") -{ - esp_err_t error = ESP_OK; - CHECK_THROW(error); -} - -TEST_CASE("CHECK_THROW throws", "[cxx exception][leaks=" LEAKS "]") -{ - esp_err_t error = ESP_FAIL; - TEST_THROW(CHECK_THROW(error), ESPException); -} - -TEST_CASE("ESPException has working what() method", "[cxx exception][leaks=" LEAKS "]") -{ - try { - throw ESPException(ESP_FAIL); - } catch (ESPException &e) { - TEST_ASSERT(strcmp(esp_err_to_name(ESP_FAIL), e.what()) == 0); - } -} - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp deleted file mode 100644 index 048c82dcf4..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp +++ /dev/null @@ -1,761 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "unity.h" -#include "unity_cxx.hpp" -#include "esp_timer.h" -#include "esp_heap_caps.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" - -#include "esp_event_cxx.hpp" -#include "esp_event_api.hpp" - -#include "esp_exception.hpp" - -#ifdef __cpp_exceptions - -#ifdef CONFIG_ESP_TIMER_PROFILING -#define WITH_PROFILING 1 -#endif - -using namespace idf::event; -using namespace std; - -ESP_EVENT_DEFINE_BASE(TEST_EVENT_BASE_0); -ESP_EVENT_DEFINE_BASE(TEST_EVENT_BASE_1); -static ESPEventID TEST_EVENT_ID_0(0); -static ESPEventID TEST_EVENT_ID_1(1); - -#define TAG "Event CXX Test" - -ESPEvent TEMPLATE_EVENT_0(TEST_EVENT_BASE_0, TEST_EVENT_ID_0); -ESPEvent TEMPLATE_EVENT_1(TEST_EVENT_BASE_0, TEST_EVENT_ID_1); - -/** - * Mock which only returns a certain error message. - */ -class ESPEventMock : public ESPEventAPIDefault { -public: - esp_err_t next_error; - - esp_err_t handler_register(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_t event_handler, - void* event_handler_arg, - esp_event_handler_instance_t *instance) override { - return next_error; - } - - esp_err_t handler_unregister(esp_event_base_t event_base, - int32_t event_id, - esp_event_handler_instance_t instance) override { - return next_error; - } - - esp_err_t post(esp_event_base_t event_base, - int32_t event_id, - void* event_data, - size_t event_data_size, - TickType_t ticks_to_wait) override { - return next_error; - } -}; - -/* The initial logging "initializing test" is to ensure mutex allocation is not counted against memory not being freed - * during teardown. - * esp_event_loop_delete_default() tries to mitigate side effects of failed tests where objects - * with automatic storage duration weren't destructed. - * - * TODO: The final "testing mem..." is to prevent memory leaks which occur for yet unknown reasons - */ -struct EventFixture { - EventFixture() : free_mem_before(0) { - ESP_LOGI(TAG, "initializing test"); - - esp_event_loop_delete_default(); - - free_mem_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); - } - - virtual ~EventFixture() - { - ESP_LOGI(TAG, "de-initializing test..."); - } - - size_t free_mem_before; -}; - -struct EventLoopFix : public EventFixture { - EventLoopFix() - : EventFixture(), - api(new ESPEventAPIDefault()), - event_loop(api), - ev0_called(false), - ev1_called(false), - timeout(false), - ev0(), - ev1() - { - handler0 = [this](const ESPEvent& ev, const void* data) { - ev0 = ev; - ev0_called = true; - }; - - handler1 = [this](const ESPEvent& ev, const void* data) { - ev1 = ev; - ev1_called = true; - }; - - timer_cb = [this](const ESPEvent& ev) { - timeout_event = ev; - timeout = true; - }; - } - - std::function handler0; - - std::function handler1; - - std::function timer_cb; - - std::shared_ptr api; - ESPEventLoop event_loop; - bool ev0_called; - bool ev1_called; - bool timeout; - ESPEvent ev0; - ESPEvent ev1; - ESPEvent timeout_event; -}; - -void send_default_event(ESPEventID event_id = TEST_EVENT_ID_0) { - TEST_ASSERT_EQUAL(ESP_OK, esp_event_post(TEST_EVENT_BASE_0, - event_id.get_id(), - nullptr, - 0, - portMAX_DELAY)); -} - -TEST_CASE("ESPEventAPIDefault deinitialization without failure", "[cxx event]") -{ - EventFixture f; - std::shared_ptr api(new ESPEventAPIDefault()); - esp_event_loop_delete_default(); - - // destructor of ESPEventAPI needs to run without failure -} - -TEST_CASE("ESPEventReg cb nullptr", "[cxx event]") -{ - EventFixture f; - std::shared_ptr api(new ESPEventAPIDefault()); - ESPEventLoop event_loop(api); - TEST_THROW(ESPEventReg reg(nullptr, TEMPLATE_EVENT_0, api), EventException); -} - -TEST_CASE("ESPEventReg api nullptr", "[cxx event]") -{ - EventFixture f; - function cb = [](const ESPEvent &event, const void *data) {}; - shared_ptr api(new ESPEventAPIDefault()); - ESPEventLoop event_loop(api); - TEST_THROW(ESPEventReg reg(cb, TEMPLATE_EVENT_0, nullptr), EventException); -} - -TEST_CASE("ESPEventReg event api not initialized", "[cxx event]") -{ - EventFixture f; - - std::shared_ptr api(new ESPEventMock()); - api->next_error = ESP_ERR_INVALID_STATE; - TEST_THROW(ESPEventReg cb([](const ESPEvent &, const void* data) { }, TEMPLATE_EVENT_0, api), - ESPEventRegisterException); -} - -TEST_CASE("ESPEventReg event register failure no loop initialized", "[cxx event]") -{ - EventFixture f; - // registering will fail because default event loop isn't initialized - std::shared_ptr api(new ESPEventAPIDefault()); - esp_event_loop_delete_default(); - TEST_THROW(ESPEventReg cb([](const ESPEvent &, const void* data) { }, TEMPLATE_EVENT_0, api), - ESPEventRegisterException); -} - -TEST_CASE("ESPEventReg initialization failure", "[cxx event]") -{ - ESPEvent event; - EventFixture f; - std::shared_ptr api = std::make_shared(); - - TEST_THROW(ESPEventReg([&](const ESPEvent &ev, const void*) { event = ev; }, ESPEvent(), api), - ESPEventRegisterException); -} - -TEST_CASE("ESPEventReg registration success", "[cxx event]") -{ - ESPEvent event; - EventFixture f; - std::shared_ptr api = std::make_shared(); - ESPEventLoop loop(api); - - ESPEventReg registration([&event](const ESPEvent &ev, const void *) { event = ev; }, TEMPLATE_EVENT_0, api); - send_default_event(); - - TEST_ASSERT(event == TEMPLATE_EVENT_0); -} - -TEST_CASE("ESPEventLoopCB event passes data", "[cxx event]") -{ - EventLoopFix fix; - int data_sent = 47; - int data_received = 0; - - ESPEvent event; - - ESPEventReg cb([&event, &data_received](const ESPEvent & ev, const void* data) { - event = ev; - data_received = *((int*) data); - }, TEMPLATE_EVENT_0, fix.api); - - fix.event_loop.post_event_data(ESPEvent(TEST_EVENT_BASE_0, TEST_EVENT_ID_0), data_sent); - - TEST_ASSERT(TEMPLATE_EVENT_0 == event); - TEST_ASSERT(data_sent == data_received); -} - -TEST_CASE("ESPEventLoop Create event loop failure", "[cxx event]") -{ - EventFixture f; - esp_event_loop_create_default(); - - TEST_THROW(ESPEventLoop event_loop, EventException); - - // just in case - esp_event_loop_delete_default(); -} - -TEST_CASE("ESPEventLoop registration invalid event callback", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - std::function event_cb; - TEST_THROW(event_loop.register_event(TEMPLATE_EVENT_0, event_cb), EventException); -} - -TEST_CASE("ESPEventLoop timed registration invalid event callback", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - std::function event_cb; - std::function timer_cb = [](const ESPEvent &ev) { }; - TEST_THROW(event_loop.register_event_timed(TEMPLATE_EVENT_0, event_cb, std::chrono::microseconds(10), timer_cb), - EventException); -} - -TEST_CASE("ESPEventLoop timed registration invalid timeout callback", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - std::function event_cb = [](const ESPEvent &ev, const void *data) { }; - std::function timer_cb; - TEST_THROW(event_loop.register_event_timed(TEMPLATE_EVENT_0, event_cb, std::chrono::microseconds(10), timer_cb), - EventException); -} - -TEST_CASE("ESPEventLoop make sure timeout is off after register exception", "[cxx event]") -{ - EventFixture f; - ESPEvent timeout_event; - bool timeout = false; - - ESPEventLoop event_loop; - std::function event_cb = [&](const ESPEvent &ev, const void *data) { - timeout_event = ev; - }; - std::function timer_cb = [&](const ESPEvent& ev) { - timeout_event = ev; - timeout = true; - }; - esp_event_loop_delete_default(); - - // Below ~35 microseconds the timer expires too fast for esp_timer_stop() to prevent it from being called. - TEST_THROW(event_loop.register_event_timed(TEMPLATE_EVENT_0, event_cb, std::chrono::microseconds(40), timer_cb), - ESPEventRegisterException); - - TEST_ASSERT_EQUAL(false, timeout); - TEST_ASSERT(timeout_event == ESPEvent()); -} - -TEST_CASE("ESPEventLoop Delete event loop failure - no error", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - - esp_event_loop_delete_default(); - - // destructor of ESPEventLoop needs to run without failure -} - -TEST_CASE("ESPEventLoop post nullptr event without registrations", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - ESPEvent event(TEST_EVENT_BASE_0, TEST_EVENT_ID_0); - void *ptr = nullptr; - event_loop.post_event_data(event, ptr); -} - -TEST_CASE("ESPEventLoop post int event without registrations", "[cxx event]") -{ - EventFixture f; - - ESPEventLoop event_loop; - ESPEvent event(TEST_EVENT_BASE_0, TEST_EVENT_ID_0); - int fourtyseven = 47; - event_loop.post_event_data(event, fourtyseven); -} - -TEST_CASE("ESPEventLoop can create, use and delete ESPEventLoop", "[cxx event]") -{ - EventLoopFix fix; - bool tested = false; - - std::function cb = [&tested](const ESPEvent& event, const void* data) { - tested = true; - }; - - ESPEventReg registration(fix.handler0, TEMPLATE_EVENT_0, fix.api); - - void *ptr = nullptr; - fix.event_loop.post_event_data(ESPEvent(TEST_EVENT_BASE_0, TEST_EVENT_ID_0), ptr); - - TEST_ASSERT_EQUAL(true, fix.ev0_called); -} - -TEST_CASE("ESPEventLoop Register, receive, unregister ESPEvent", "[cxx event]") -{ - EventLoopFix fix; - - std::unique_ptr registration(new ESPEventReg(fix.handler0, TEMPLATE_EVENT_0, fix.api)); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - - registration.reset(); - fix.ev0 = ESPEvent(); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == ESPEvent()); -} - -TEST_CASE("ESPEventLoop register multiple ESPEvents, same cb", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventReg registration0(fix.handler0, TEMPLATE_EVENT_0, fix.api); - ESPEventReg registration1(fix.handler1, TEMPLATE_EVENT_1, fix.api); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - fix.ev0 = ESPEvent(); - - send_default_event(TEST_EVENT_ID_1); - - TEST_ASSERT(fix.ev1 == TEMPLATE_EVENT_1); -} - -TEST_CASE("ESPEventLoop register multiple ESPEvents, multiple cbs", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventReg registration0(fix.handler0, TEMPLATE_EVENT_0, fix.api); - ESPEventReg registration1(fix.handler1, TEMPLATE_EVENT_1, fix.api); - - send_default_event(); - send_default_event(TEST_EVENT_ID_1); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - TEST_ASSERT(fix.ev1 == TEMPLATE_EVENT_1); -} - -TEST_CASE("ESPEventLoop register to all events of one event base", "[cxx event]") -{ - EventLoopFix fix; - - ESPEvent any_id_event(ESP_EVENT_ANY_BASE, ESPEventID(ESP_EVENT_ANY_ID)); - ESPEventReg registration(fix.handler0, any_id_event, fix.api); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - - send_default_event(TEST_EVENT_ID_1); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_1); -} - -TEST_CASE("ESPEventLoop register to all ESP events", "[cxx event]") -{ - EventLoopFix fix; - - ESPEvent any_event(ESP_EVENT_ANY_BASE, ESPEventID(ESP_EVENT_ANY_ID)); - ESPEventReg registration(fix.handler0, any_event, fix.api); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - - send_default_event(TEST_EVENT_ID_1); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_1); - - void *ptr = nullptr; - fix.event_loop.post_event_data(ESPEvent(TEST_EVENT_BASE_1, TEST_EVENT_ID_0), ptr); - - // check reception of event with different base - TEST_ASSERT_EQUAL(TEST_EVENT_BASE_1, fix.ev0.base); - TEST_ASSERT_EQUAL(TEST_EVENT_ID_0.get_id(), fix.ev0.id.get_id()); -} - -TEST_CASE("ESPEventLoop direct register, receive, unregister ESPEvent", "[cxx event]") -{ - EventLoopFix fix; - - std::unique_ptr registration = fix.event_loop.register_event(TEMPLATE_EVENT_0, fix.handler0); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - - registration.reset(); - fix.ev0 = ESPEvent(); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == ESPEvent()); -} - -TEST_CASE("ESPEventLoop set timeout invalid timeout", "[cxx event]") -{ - EventLoopFix fix; - - const std::chrono::microseconds INVALID_US(MIN_TIMEOUT - chrono::microseconds(1)); - - TEST_THROW(ESPEventRegTimed(fix.handler0, TEMPLATE_EVENT_0, fix.timer_cb, INVALID_US, fix.api), - EventException); -} - -TEST_CASE("ESPEventLoop lonely timeout", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventRegTimed timed_reg(fix.handler0, TEMPLATE_EVENT_0, fix.timer_cb, MIN_TIMEOUT, fix.api); - - vTaskDelay(10 / portTICK_PERIOD_MS); - TEST_ASSERT_EQUAL(true, fix.timeout); - TEST_ASSERT_EQUAL(false, fix.ev0_called); -} - -TEST_CASE("ESPEventLoop timeout unregisters from loop", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventRegTimed timed_reg(fix.handler0, TEMPLATE_EVENT_0, fix.timer_cb, MIN_TIMEOUT, fix.api); - - vTaskDelay(10 / portTICK_PERIOD_MS); - - send_default_event(TEST_EVENT_ID_0); - - TEST_ASSERT_EQUAL(true, fix.timeout); - TEST_ASSERT_EQUAL(false, fix.ev0_called); -} - -TEST_CASE("ESPEventLoop no timeout", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventRegTimed timed_reg(fix.handler0, TEMPLATE_EVENT_0, fix.timer_cb, std::chrono::microseconds(500000), fix.api); - - vTaskDelay(10 / portTICK_PERIOD_MS); - send_default_event(); - - TEST_ASSERT_EQUAL(false, fix.timeout); - TEST_ASSERT_EQUAL(true, fix.ev0_called); -} - - -/** - * Registers an event via both set_timeout() and register_event(). - * Result: both handlers will be invoked, the timeout callback won't be called. - */ -TEST_CASE("ESPEventLoop register timeout and event - no timeout", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventReg reg(fix.handler0, TEMPLATE_EVENT_0, fix.api); - ESPEventRegTimed timed_reg(fix.handler1, TEMPLATE_EVENT_0, fix.timer_cb, std::chrono::microseconds(500000), fix.api); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - TEST_ASSERT(fix.ev1 == TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(false, fix.timeout); -} - -/** - * Registers an event via both set_timeout() and register_event(). - * Result: both handlers will be invoked, the timeout callback won't be called. - */ -TEST_CASE("ESPEventLoop direct register timeout and event - no timeout", "[cxx event]") -{ - EventLoopFix fix; - - unique_ptr reg = fix.event_loop.register_event(TEMPLATE_EVENT_0, fix.handler0); - unique_ptr timed_reg = fix.event_loop.register_event_timed(TEMPLATE_EVENT_0, - fix.handler1, - std::chrono::microseconds(500000), - fix.timer_cb); - - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - TEST_ASSERT(fix.ev1 == TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(false, fix.timeout); -} - -/** - * Registers an event via both set_timeout() and register_event(). - * Result: both handlers will be invoked, the timeout callback won't be called. - */ -TEST_CASE("ESPEventLoop register timeout and event - timeout", "[cxx event]") -{ - EventLoopFix fix; - - ESPEventReg reg(fix.handler0, TEMPLATE_EVENT_0, fix.api); - ESPEventRegTimed timed_reg(fix.handler1, TEMPLATE_EVENT_0, fix.timer_cb, MIN_TIMEOUT, fix.api); - - vTaskDelay(10 / portTICK_PERIOD_MS); - send_default_event(); - - TEST_ASSERT(fix.ev0 == TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(false, fix.ev1_called); - TEST_ASSERT(fix.timeout_event == TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(true, fix.timeout); -} - -TEST_CASE("ESPEventLoop custom loop register, receive, unregister ESPEvent", "[cxx event]") -{ - EventFixture f; - ESPEvent event; - esp_event_loop_args_t loop_args; - loop_args.queue_size = 32; - loop_args.task_name = "sys_evt"; - loop_args.task_stack_size = 2304; - loop_args.task_priority = 20; - loop_args.task_core_id = 0; - - std::shared_ptr api(new ESPEventAPICustom(loop_args)); - - ESPEventLoop event_loop(api); - std::function cb = [&event](const ESPEvent& ev, const void* data) { - event = ev; - }; - shared_ptr registration = event_loop.register_event(TEMPLATE_EVENT_0, cb); - - void *ptr = nullptr; - event_loop.post_event_data(ESPEvent(TEST_EVENT_BASE_0, TEST_EVENT_ID_0), ptr); - - ESP_ERROR_CHECK(api->run(1)); - - TEST_ASSERT(event == TEMPLATE_EVENT_0); - - registration.reset(); - event = ESPEvent(); - - event_loop.post_event_data(ESPEvent(TEST_EVENT_BASE_0, TEST_EVENT_ID_0), ptr); - - ESP_ERROR_CHECK(api->run(1)); - - TEST_ASSERT(event == ESPEvent()); -} - -TEST_CASE("ESPEventHandlerSync simple construction and destruction", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); -} - -TEST_CASE("ESPEventHandlerSync simple event wait", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); - - send_default_event(); - - ESPEventHandlerSync::EventResult result = handler.wait_event(); - - TEST_ASSERT_EQUAL(TEMPLATE_EVENT_0.base, result.event.base); - TEST_ASSERT_EQUAL(TEMPLATE_EVENT_0.id.get_id(), result.event.id.get_id()); -} - -TEST_CASE("ESPEventHandlerSync wait_for(0) succeed", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); - - send_default_event(); - - ESPEventHandlerSync::EventResult result = handler.wait_event_for(chrono::milliseconds(0)); - TEST_ASSERT(TEMPLATE_EVENT_0 == result.event); -} - -TEST_CASE("ESPEventHandlerSync start waiting after events arrived", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); - - send_default_event(); - send_default_event(); - - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); -} - -// helper function to post events, simulating an event source -void post_events(int event_num) { - for (int i = 0; i < event_num; i++) { - ESP_ERROR_CHECK(esp_event_post(TEST_EVENT_BASE_0, - TEST_EVENT_ID_0.get_id(), - nullptr, - 0, - portMAX_DELAY)); - vTaskDelay(10 / portTICK_PERIOD_MS); - } -} - -TEST_CASE("ESPEventHandlerSync simultaneous event handling", "[cxx event]") -{ - EventFixture f; - // Create handler with queue size 1 - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); - thread th(post_events, 3); - - // no for-loop for better feedback (line numbers) - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); - - TEST_ASSERT_EQUAL(0, handler.get_send_queue_errors()); - th.join(); -} - -TEST_CASE("ESPEventHandlerSync wait_for(0) timeout", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - - ESPEventHandlerSync::EventResultTimed result = handler.wait_event_for(chrono::milliseconds(0)); - TEST_ASSERT_EQUAL(true, result.timeout); -} - -TEST_CASE("ESPEventHandlerSync register default event fails", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - TEST_THROW(handler.listen_to(ESPEvent()), EventException); -} - -TEST_CASE("ESPEventHandlerSync null pointer", "[cxx event]") -{ - EventFixture f; - TEST_THROW(ESPEventHandlerSync handler(nullptr), EventException); -} - -TEST_CASE("ESPEventHandlerSync empty shared_ptr", "[cxx event]") -{ - EventFixture f; - shared_ptr event_loop; - TEST_THROW(ESPEventHandlerSync handler(event_loop), EventException); -} - -TEST_CASE("ESPEventHandlerSync queue size 0", "[cxx event]") -{ - EventFixture f; - - TEST_THROW(ESPEventHandlerSync handler(make_shared(), 0), EventException); -} - -TEST_CASE("ESPEventHandlerSync receive after timeout", "[cxx event]") -{ - EventFixture f; - ESPEventHandlerSync handler(make_shared()); - handler.listen_to(TEMPLATE_EVENT_0); - - TEST_ASSERT_EQUAL(true, handler.wait_event_for(chrono::milliseconds(0)).timeout); - - send_default_event(); - - ESPEvent event = handler.wait_event().event; - TEST_ASSERT(TEMPLATE_EVENT_0 == event); -} - -TEST_CASE("ESPEventHandlerSync send too many events", "[cxx event]") -{ - EventFixture f; - // Create handler with queue size 1 - ESPEventHandlerSync handler(make_shared(), 1); - handler.listen_to(TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(0, handler.get_send_queue_errors()); - - send_default_event(); - send_default_event(); - TEST_ASSERT(handler.wait_event().event == TEMPLATE_EVENT_0); - TEST_ASSERT_EQUAL(true, handler.wait_event_for(chrono::milliseconds(10)).timeout); - TEST_ASSERT_EQUAL(1, handler.get_send_queue_errors()); -} - -TEST_CASE("ESPEventAPIDefault initialization failure", "[cxx event]") -{ - EventFixture f; - esp_event_loop_create_default(); - TEST_THROW(std::shared_ptr api(new ESPEventAPIDefault()), EventException); - esp_event_loop_delete_default(); -} - -TEST_CASE("ESPEventAPICustom no mem", "[cxx event]") -{ - EventFixture f; - esp_event_loop_args_t loop_args; - loop_args.queue_size = 1000000; - loop_args.task_name = "custom_evt"; - loop_args.task_stack_size = 2304; - loop_args.task_priority = 20; - loop_args.task_core_id = 0; - - esp_event_loop_create_default(); - - TEST_THROW(std::shared_ptr api(new ESPEventAPICustom(loop_args)), EventException); - - esp_event_loop_delete_default(); -} - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_esp_timer.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_esp_timer.cpp deleted file mode 100644 index c352c8d508..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/test_esp_timer.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifdef __cpp_exceptions - -#include "unity.h" -#include "unity_cxx.hpp" -#include -#include - -#include -#include "test_utils.h" // ref clock -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" - -#include "esp_timer_cxx.hpp" -#include "esp_exception.hpp" - -using namespace std; -using namespace idf; -using namespace idf::esp_timer; - -struct RefClock { - RefClock() - { - ref_clock_init(); - }; - - ~RefClock() - { - ref_clock_deinit(); - } -}; - -TEST_CASE("ESPTimer produces correct delay", "[ESPTimer]") -{ - int64_t t_end; - - RefClock ref_clock; - - function timer_cb = [&t_end]() { - t_end = ref_clock_get(); - }; - - ESPTimer timer(timer_cb, "timer1"); - - const int delays_ms[] = {20, 100, 200, 250}; - const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]); - - for (size_t i = 0; i < delays_count; ++i) { - t_end = 0; - int64_t t_start = ref_clock_get(); - - timer.start(chrono::microseconds(delays_ms[i] * 1000)); - - vTaskDelay(delays_ms[i] * 2 / portTICK_PERIOD_MS); - TEST_ASSERT(t_end != 0); - int32_t ms_diff = (t_end - t_start) / 1000; - printf("%d %d\n", delays_ms[i], ms_diff); - - TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff); - } -} - -TEST_CASE("ESPtimer produces correct periodic delays", "[ESPTimer]") -{ - const size_t NUM_INTERVALS = 3u; - - size_t cur_interval = 0; - int intervals[NUM_INTERVALS]; - int64_t t_start; - SemaphoreHandle_t done; - - const int DELAY_MS = 100; - function timer_cb = [&]() { - int64_t t_end = ref_clock_get(); - int32_t ms_diff = (t_end - t_start) / 1000; - printf("timer #%d %dms\n", cur_interval, ms_diff); - if (cur_interval < NUM_INTERVALS) { - intervals[cur_interval++] = ms_diff; - } - // Deliberately make timer handler run longer. - // We check that this doesn't affect the result. - esp_rom_delay_us(10*1000); - if (cur_interval == NUM_INTERVALS) { - printf("done\n"); - xSemaphoreGive(done); - } - }; - - ESPTimer timer(timer_cb, "timer1"); - RefClock ref_clock; - t_start = ref_clock_get(); - done = xSemaphoreCreateBinary(); - timer.start_periodic(chrono::microseconds(DELAY_MS * 1000)); - - TEST_ASSERT(xSemaphoreTake(done, DELAY_MS * NUM_INTERVALS * 2)); - timer.stop(); - - TEST_ASSERT_EQUAL_UINT32(NUM_INTERVALS, cur_interval); - for (size_t i = 0; i < NUM_INTERVALS; ++i) { - TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * DELAY_MS, intervals[i]); - } - TEST_ESP_OK(esp_timer_dump(stdout)); - - vSemaphoreDelete(done); -#undef NUM_INTERVALS -} - -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp deleted file mode 100644 index 2574fe9013..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "unity.h" -#include "unity_cxx.hpp" -#include -#include - -#include -#include "test_utils.h" // unity_send_signal - -#ifdef __cpp_exceptions -#include "i2c_cxx.hpp" -#include "driver/i2c.h" - -using namespace std; -using namespace idf; - -#define ADDR 0x47 - -#define MAGIC_TEST_NUMBER 47 - -static constexpr I2CNumber I2C_SLAVE_NUM(I2CNumber::I2C0()); /*! &data_arg = {47u}) : - master(new I2CMaster(I2CNumber(I2C_MASTER_NUM), - SCL_GPIO(I2C_MASTER_SCL_IO), - SDA_GPIO(I2C_MASTER_SDA_IO), - Frequency(400000))), - data(data_arg) { } - - std::shared_ptr master; - vector data; -}; - -// TODO The I2C driver tests are disabled, so disable them here, too. Probably due to no runners. -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C2, ESP32C6, ESP32H2) - -static void i2c_slave_read_raw_byte(void) -{ - I2CSlave slave(I2CNumber(I2C_SLAVE_NUM), SCL_GPIO(I2C_SLAVE_SCL_IO), SDA_GPIO(I2C_SLAVE_SDA_IO), I2CAddress(ADDR), 512, 512); - uint8_t buffer = 0; - - unity_send_signal("slave init"); - unity_wait_for_signal("master write"); - - TEST_ASSERT_EQUAL(1, slave.read_raw(&buffer, 1, chrono::milliseconds(1000))); - - TEST_ASSERT_EQUAL(MAGIC_TEST_NUMBER, buffer); -} - -static void i2c_slave_write_raw_byte(void) -{ - I2CSlave slave(I2CNumber(I2C_SLAVE_NUM), SCL_GPIO(I2C_SLAVE_SCL_IO), SDA_GPIO(I2C_SLAVE_SDA_IO), I2CAddress(ADDR), 512, 512); - uint8_t WRITE_BUFFER = MAGIC_TEST_NUMBER; - - unity_wait_for_signal("master init"); - - TEST_ASSERT_EQUAL(1, slave.write_raw(&WRITE_BUFFER, 1, chrono::milliseconds(1000))); - - unity_send_signal("slave write"); - - // This last synchronization is necessary to prevent slave from going out of scope hence de-initializing already - // before master has read - unity_wait_for_signal("master read done"); -} - -static void i2c_slave_read_multiple_raw_bytes(void) -{ - I2CSlave slave(I2CNumber(I2C_SLAVE_NUM), SCL_GPIO(I2C_SLAVE_SCL_IO), SDA_GPIO(I2C_SLAVE_SDA_IO), I2CAddress(ADDR), 512, 512); - uint8_t buffer [8] = {}; - - unity_send_signal("slave init"); - unity_wait_for_signal("master write"); - - TEST_ASSERT_EQUAL(8, slave.read_raw(buffer, 8, chrono::milliseconds(1000))); - - for (int i = 0; i < 8; i++) { - TEST_ASSERT_EQUAL(i, buffer[i]); - } -} - -static void i2c_slave_write_multiple_raw_bytes(void) -{ - I2CSlave slave(I2CNumber(I2C_SLAVE_NUM), SCL_GPIO(I2C_SLAVE_SCL_IO), SDA_GPIO(I2C_SLAVE_SDA_IO), I2CAddress(ADDR), 512, 512); - uint8_t WRITE_BUFFER [8] = {0, 1, 2, 3, 4, 5, 6, 7}; - - unity_wait_for_signal("master init"); - - TEST_ASSERT_EQUAL(8, slave.write_raw(WRITE_BUFFER, 8, chrono::milliseconds(1000))); - - unity_send_signal("slave write"); - unity_wait_for_signal("master read done"); -} - -static void i2c_slave_composed_trans(void) -{ - I2CSlave slave(I2CNumber(I2C_SLAVE_NUM), SCL_GPIO(I2C_SLAVE_SCL_IO), SDA_GPIO(I2C_SLAVE_SDA_IO), I2CAddress(ADDR), 512, 512); - size_t BUF_SIZE = 2; - const uint8_t SLAVE_WRITE_BUFFER [BUF_SIZE] = {0xde, 0xad}; - uint8_t slave_read_buffer = 0; - - unity_send_signal("slave init"); - - TEST_ASSERT_EQUAL(BUF_SIZE, slave.write_raw(SLAVE_WRITE_BUFFER, BUF_SIZE, chrono::milliseconds(1000))); - - unity_wait_for_signal("master transfer"); - - TEST_ASSERT_EQUAL(1, slave.read_raw(&slave_read_buffer, 1, chrono::milliseconds(1000))); - - TEST_ASSERT_EQUAL(MAGIC_TEST_NUMBER, slave_read_buffer); -} - -static void i2c_master_read_raw_byte(void) -{ - MasterFixture fix; - - unity_send_signal("master init"); - unity_wait_for_signal("slave write"); - - std::shared_ptr reader(new I2CRead(1)); - - future > fut = fix.master->transfer(I2CAddress(ADDR), reader); - - vector data; - data = fut.get(); - unity_send_signal("master read done"); - - TEST_ASSERT_EQUAL(1, data.size()); - TEST_ASSERT_EQUAL(MAGIC_TEST_NUMBER, data[0]); -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster read one byte", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_read_raw_byte, i2c_slave_write_raw_byte); - -static void i2c_master_write_raw_byte(void) -{ - MasterFixture fix; - - unity_wait_for_signal("slave init"); - - std::shared_ptr writer(new I2CWrite(fix.data)); - future fut = fix.master->transfer(I2CAddress(ADDR), writer); - - fut.get(); - unity_send_signal("master write"); -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster write one byte", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_write_raw_byte, i2c_slave_read_raw_byte); - -static void i2c_master_read_multiple_raw_bytes(void) -{ - MasterFixture fix; - - unity_send_signal("master init"); - unity_wait_for_signal("slave write"); - - std::shared_ptr reader(new I2CRead(8)); - - future > fut = fix.master->transfer(I2CAddress(ADDR), reader); - - vector data = fut.get(); - unity_send_signal("master read done"); - - TEST_ASSERT_EQUAL(8, data.size()); - for (int i = 0; i < 8; i++) { - TEST_ASSERT_EQUAL(i, data[i]); - } -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster read multiple bytes", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_read_multiple_raw_bytes, i2c_slave_write_multiple_raw_bytes); - -static void i2c_master_write_multiple_raw_bytes(void) -{ - MasterFixture fix({0, 1, 2, 3, 4, 5, 6, 7}); - - unity_wait_for_signal("slave init"); - - std::shared_ptr writer(new I2CWrite(fix.data)); - future fut = fix.master->transfer(I2CAddress(ADDR), writer); - - fut.get(); - unity_send_signal("master write"); -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster write multiple bytes", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_write_multiple_raw_bytes, i2c_slave_read_multiple_raw_bytes); - -static void i2c_master_sync_transfer(void) -{ - MasterFixture fix; - size_t READ_SIZE = 2; - const uint8_t DESIRED_READ [READ_SIZE] = {0xde, 0xad}; - - unity_wait_for_signal("slave init"); - - vector read_data = fix.master->sync_transfer(I2CAddress(ADDR), fix.data, READ_SIZE); - - unity_send_signal("master transfer"); - TEST_ASSERT_EQUAL(READ_SIZE, read_data.size()); - for (int i = 0; i < READ_SIZE; i++) { - TEST_ASSERT_EQUAL(DESIRED_READ[i], read_data[i]); - } -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster sync transfer", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_sync_transfer, i2c_slave_composed_trans); - -static void i2c_master_composed_trans(void) -{ - MasterFixture fix; - size_t BUF_SIZE = 2; - const uint8_t SLAVE_WRITE_BUFFER [BUF_SIZE] = {0xde, 0xad}; - - std::shared_ptr composed_transfer(new I2CComposed); - composed_transfer->add_write({47u}); - composed_transfer->add_read(BUF_SIZE); - - unity_wait_for_signal("slave init"); - - future > > result = fix.master->transfer(I2CAddress(ADDR), composed_transfer); - - unity_send_signal("master transfer"); - - vector > read_data = result.get(); - - TEST_ASSERT_EQUAL(1, read_data.size()); - TEST_ASSERT_EQUAL(2, read_data[0].size()); - for (int i = 0; i < BUF_SIZE; i++) { - TEST_ASSERT_EQUAL(SLAVE_WRITE_BUFFER[i], read_data[0][i]); - } -} - -TEST_CASE_MULTIPLE_DEVICES("I2CMaster Composed transfer", "[cxx i2c][test_env=UT_T2_I2C][timeout=150]", - i2c_master_composed_trans, i2c_slave_composed_trans); - -#endif //TEMPORARY_DISABLED_FOR_TARGETS(...) -#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp deleted file mode 100644 index a258f64a90..0000000000 --- a/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "unity.h" - -#define CXX_UNITY_TYPE_TO_STR(x) #x - -/** - * Very simple helper macro to catch exceptions. - * - * @note - * * If there is any exception which not a child of std::exception, it will terminate the program! - * * If there is no exception, it will jump from the current frame without de-initializing - * destructors! - */ -#define TEST_THROW(expr_, exception_) \ - do { \ - bool caught = false; \ - bool caught_different = false; \ - try { \ - expr_; \ - } catch ( exception_ &e) { \ - caught = true; \ - } catch ( std::exception &e) { \ - caught_different = true; \ - } \ - TEST_ASSERT_FALSE_MESSAGE(caught_different, "ERROR: Expected " CXX_UNITY_TYPE_TO_STR(exception_) \ - ", but caught different exception."); \ - TEST_ASSERT_TRUE_MESSAGE(caught, "ERROR: Expected " CXX_UNITY_TYPE_TO_STR(exception_) \ - ", but no exception thrown."); \ - } \ - while (0) diff --git a/examples/cxx/experimental/simple_i2c_rw_example/CMakeLists.txt b/examples/cxx/experimental/simple_i2c_rw_example/CMakeLists.txt deleted file mode 100644 index cfb53515cc..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component") - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(simple_i2c_rw_example) diff --git a/examples/cxx/experimental/simple_i2c_rw_example/README.md b/examples/cxx/experimental/simple_i2c_rw_example/README.md deleted file mode 100644 index 3f08db27d6..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/README.md +++ /dev/null @@ -1,63 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | - -# Example: C++ I2C sensor read for MPU9250 - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -This example demonstrates usage of C++ exceptions in ESP-IDF. It is the C++ equivalent to the [I2C Simple Example](../../../peripherals/i2c/i2c_simple/) which is written in C. - -In this example, the `sdkconfig.defaults` file sets the `CONFIG_COMPILER_CXX_EXCEPTIONS` option. This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling. This is necessary for the C++ I2C API. - -## How to Use This Example - -### Hardware Required - -To run this example, you should have one ESP32, ESP32-S series or ESP32-C series based development board as well as an MPU9250. MPU9250 is an inertial measurement unit, which contains an accelerometer, gyroscope as well as a magnetometer, for more information about it, you can read the [datasheet of the MPU9250 sensor](https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf). - -#### Pin Assignment: - -**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` . - -| | SDA | SCL | -| ---------------- | -------------- | -------------- | -| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL | -| MPU9250 Sensor | SDA | SCL | - - -For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL`, see `Example Configuration` in `menuconfig`. - -**Note:** There's no need to add external pull-up resistors for SDA/SCL pins, because the driver will enable the internal pull-up resistors. - -### Configure the project - -``` -idf.py menuconfig -``` - -### Build and Flash - -``` -idf.py -p flash monitor -``` - -Replace with the name of the serial port. To exit the serial monitor, type ``Ctrl-]``. - -See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -If the sensor is read correctly: - -```bash -I (328) i2c-simple-example: I2C initialized successfully -I (338) i2c-simple-example: WHO_AM_I = 71 -I (338) i2c-simple-example: I2C de-initialized successfully -``` - -If something went wrong: -``` -I2C Exception with error: ESP_FAIL (-1) -Couldn't read sensor! -``` - diff --git a/examples/cxx/experimental/simple_i2c_rw_example/main/CMakeLists.txt b/examples/cxx/experimental/simple_i2c_rw_example/main/CMakeLists.txt deleted file mode 100644 index 8bb6cb3094..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "simple_i2c_rw_example.cpp" - INCLUDE_DIRS ".") diff --git a/examples/cxx/experimental/simple_i2c_rw_example/main/Kconfig.projbuild b/examples/cxx/experimental/simple_i2c_rw_example/main/Kconfig.projbuild deleted file mode 100644 index dc9568c775..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config I2C_MASTER_SCL - int "SCL GPIO Num" - default 6 if IDF_TARGET_ESP32C3 - default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 - help - GPIO number for I2C Master clock line. - - config I2C_MASTER_SDA - int "SDA GPIO Num" - default 5 if IDF_TARGET_ESP32C3 - default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 - help - GPIO number for I2C Master data line. - -endmenu diff --git a/examples/cxx/experimental/simple_i2c_rw_example/main/simple_i2c_rw_example.cpp b/examples/cxx/experimental/simple_i2c_rw_example/main/simple_i2c_rw_example.cpp deleted file mode 100644 index a1a908d69e..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/main/simple_i2c_rw_example.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - * - * MPU9250 I2C Sensor C++ Example - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include "esp_log.h" -#include "i2c_cxx.hpp" - -using namespace std; -using namespace idf; - -static const char *TAG = "i2c-cxx-simple-example"; - -constexpr I2CNumber I2C_MASTER_NUM(I2CNumber::I2C0()); /*!< I2C master i2c port number, the number of i2c peripheral - interfaces available will depend on the chip */ -#define I2C_MASTER_SCL_IO SCL_GPIO(CONFIG_I2C_MASTER_SCL) /*!< GPIO number used for I2C master clock */ -#define I2C_MASTER_SDA_IO SDA_GPIO(CONFIG_I2C_MASTER_SDA) /*!< GPIO number used for I2C master data */ - -#define MPU9250_SENSOR_ADDR I2CAddress(0x68) /*!< Slave address of the MPU9250 sensor */ -constexpr uint8_t MPU9250_WHO_AM_I_REG_ADDR = 0x75; /*!< Register addresses of the "who am I" register */ - -extern "C" void app_main(void) -{ - try { - // creating master bus - shared_ptr master(new I2CMaster(I2C_MASTER_NUM, - I2C_MASTER_SCL_IO, - I2C_MASTER_SDA_IO, - Frequency(400000))); - ESP_LOGI(TAG, "I2C initialized successfully"); - - // writing the pointer to the WHO_AM_I register to the device - master->sync_write(MPU9250_SENSOR_ADDR, {MPU9250_WHO_AM_I_REG_ADDR}); - - // reading back the value of WHO_AM_I register which should be 71 - vector data = master->sync_read(MPU9250_SENSOR_ADDR, 2); - - ESP_LOGI(TAG, "WHO_AM_I = %X", data[0]); - } catch (const I2CException &e) { - ESP_LOGI(TAG, "I2C Exception with error: %s (0x%X)", e.what(), e.error); - ESP_LOGI(TAG, "Couldn't read sensor!"); - } - - // The I2CMaster object is de-initialized in its destructor when going out of scope. - ESP_LOGI(TAG, "I2C de-initialized successfully"); -} diff --git a/examples/cxx/experimental/simple_i2c_rw_example/sdkconfig.defaults b/examples/cxx/experimental/simple_i2c_rw_example/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/simple_i2c_rw_example/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/examples/cxx/experimental/simple_spi_rw_example/CMakeLists.txt b/examples/cxx/experimental/simple_spi_rw_example/CMakeLists.txt deleted file mode 100644 index c64ba4c768..0000000000 --- a/examples/cxx/experimental/simple_spi_rw_example/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) - -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component") - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(simple_spi_rw_example) diff --git a/examples/cxx/experimental/simple_spi_rw_example/README.md b/examples/cxx/experimental/simple_spi_rw_example/README.md deleted file mode 100644 index dfc017bccc..0000000000 --- a/examples/cxx/experimental/simple_spi_rw_example/README.md +++ /dev/null @@ -1,71 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | - -# Example: C++ SPI sensor read for MCU9250 inertial/giroscope sensor - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -This example demonstrates usage of C++ SPI classes in ESP-IDF to read the `WHO_AM_I` register of the sensor. - -In this example, the `sdkconfig.defaults` file sets the `CONFIG_COMPILER_CXX_EXCEPTIONS` option. -This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling. -This is necessary for the C++ SPI API. - -## How to use example - -### Hardware Required - -An MCU9250 sensor and any commonly available ESP32 development board. - -### Configure the project - -``` -idf.py menuconfig -``` - -### Build and Flash - -``` -idf.py -p PORT flash monitor -``` - -(Replace PORT with the name of the serial port.) - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -If the sensor is read correctly: - -``` -... -I (0) cpu_start: Starting scheduler on APP CPU. -Result of WHO_AM_I register: 0x71 -I (437) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (447) gpio: GPIO[25]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (457) gpio: GPIO[26]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (467) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 - -Done -``` - -If there's an error with the SPI peripheral: -``` -... -I (0) cpu_start: Starting scheduler on APP CPU. -E (434) spi: spicommon_bus_initialize_io(429): mosi not valid -Couldn't read SPI! -``` - -If the SPI pins are not connected properly, the resulting read may just return 0, this error can not be detected: -``` -... -I (0) cpu_start: Starting scheduler on APP CPU. -Result of WHO_AM_I register: 0x00 -I (437) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (447) gpio: GPIO[25]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (457) gpio: GPIO[26]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -I (467) gpio: GPIO[27]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 -``` diff --git a/examples/cxx/experimental/simple_spi_rw_example/main/CMakeLists.txt b/examples/cxx/experimental/simple_spi_rw_example/main/CMakeLists.txt deleted file mode 100644 index b5339733ef..0000000000 --- a/examples/cxx/experimental/simple_spi_rw_example/main/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRCS "simple_spi_rw_example.cpp" - INCLUDE_DIRS "." - REQUIRES experimental_cpp_component) diff --git a/examples/cxx/experimental/simple_spi_rw_example/main/simple_spi_rw_example.cpp b/examples/cxx/experimental/simple_spi_rw_example/main/simple_spi_rw_example.cpp deleted file mode 100644 index 41cbcbc5c6..0000000000 --- a/examples/cxx/experimental/simple_spi_rw_example/main/simple_spi_rw_example.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - * - * MPU9250 SPI Sensor C++ Example - * - * This example code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include -#include "spi_host_cxx.hpp" - -using namespace std; -using namespace idf; - -static const GPIONum NSS(23); -static const uint8_t READ_FLAG = 0x80; -static const uint8_t MPU9250_WHO_AM_I_REG_ADDR = 0x75; - -extern "C" void app_main(void) -{ - try { - - SPIMaster master(SPINum(2), - MOSI(25), - MISO(26), - SCLK(27)); - - shared_ptr spi_dev = master.create_dev(CS(NSS.get_num()), Frequency::MHz(1)); - - vector write_data = {MPU9250_WHO_AM_I_REG_ADDR | READ_FLAG, 0x00}; - vector result = spi_dev->transfer(write_data).get(); - - cout << "Result of WHO_AM_I register: 0x"; - printf("%02X", result[1]); - cout << endl; - - this_thread::sleep_for(std::chrono::seconds(2)); - - } catch (const SPIException &e) { - cout << "Couldn't read SPI!" << endl; - } -} diff --git a/examples/cxx/experimental/simple_spi_rw_example/sdkconfig.defaults b/examples/cxx/experimental/simple_spi_rw_example/sdkconfig.defaults deleted file mode 100644 index a365ac6589..0000000000 --- a/examples/cxx/experimental/simple_spi_rw_example/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -# Enable C++ exceptions and set emergency pool size for exception objects -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024 diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index c4f694fdce..16db65e504 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1422,27 +1422,6 @@ examples/custom_bootloader/bootloader_hooks/main/bootloader_hooks_example_main.c examples/custom_bootloader/bootloader_override/example_test.py examples/cxx/exceptions/example_test.py examples/cxx/exceptions/main/exception_example_main.cpp -examples/cxx/experimental/blink_cxx/main/main.cpp -examples/cxx/experimental/esp_event_async_cxx/main/esp_event_async_cxx_example.cpp -examples/cxx/experimental/esp_event_cxx/main/esp_event_cxx_example.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_client.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_mqtt_client.cpp -examples/cxx/experimental/esp_modem_cxx/main/simple_mqtt_client.hpp -examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt.hpp -examples/cxx/experimental/esp_mqtt_cxx/components/esp_mqtt_cxx/include/esp_mqtt_client_config.hpp -examples/cxx/experimental/esp_mqtt_cxx/ssl/main/mqtt_ssl_example.cpp -examples/cxx/experimental/esp_mqtt_cxx/tcp/main/mqtt_tcp_example.cpp -examples/cxx/experimental/esp_timer_cxx/main/esp_timer_example.cpp -examples/cxx/experimental/experimental_cpp_component/esp_event_api.cpp -examples/cxx/experimental/experimental_cpp_component/esp_event_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp -examples/cxx/experimental/experimental_cpp_component/esp_timer_cxx.cpp -examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer/main/esp_timer_test.cpp -examples/cxx/experimental/experimental_cpp_component/include/esp_event_api.hpp -examples/cxx/experimental/experimental_cpp_component/include/esp_timer_cxx.hpp -examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp -examples/cxx/experimental/experimental_cpp_component/test/test_esp_event_cxx.cpp -examples/cxx/experimental/sensor_mcp9808/main/sensor_mcp9808.cpp examples/cxx/pthread/example_test.py examples/cxx/pthread/main/cpp_pthread.cpp examples/cxx/rtti/example_test.py diff --git a/tools/test_idf_size/app_esp32s3_32k_icache.map b/tools/test_idf_size/app_esp32s3_32k_icache.map index 344356c0e8..0236988aa2 100644 --- a/tools/test_idf_size/app_esp32s3_32k_icache.map +++ b/tools/test_idf_size/app_esp32s3_32k_icache.map @@ -13277,7 +13277,6 @@ LOAD esp-idf/ulp/libulp.a LOAD esp-idf/usb/libusb.a LOAD esp-idf/wifi_provisioning/libwifi_provisioning.a LOAD esp-idf/main/libmain.a -LOAD esp-idf/experimental_cpp_component/libexperimental_cpp_component.a LOAD esp-idf/esp_serial_slave_link/libesp_serial_slave_link.a LOAD esp-idf/test_driver_utils/libtest_driver_utils.a LOAD esp-idf/test_utils/libtest_utils.a diff --git a/tools/unit-test-app/CMakeLists.txt b/tools/unit-test-app/CMakeLists.txt index b29033ec3a..010ca75e7b 100644 --- a/tools/unit-test-app/CMakeLists.txt +++ b/tools/unit-test-app/CMakeLists.txt @@ -2,7 +2,6 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/components/driver/test_apps/components") include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/tools/unit-test-app/configs/cxx_experimental b/tools/unit-test-app/configs/cxx_experimental deleted file mode 100644 index 88d1fef3c3..0000000000 --- a/tools/unit-test-app/configs/cxx_experimental +++ /dev/null @@ -1,2 +0,0 @@ -TEST_COMPONENTS=experimental_cpp_component -CONFIG_COMPILER_CXX_EXCEPTIONS=y diff --git a/tools/unit-test-app/configs/default_2 b/tools/unit-test-app/configs/default_2 index 2a76134ebd..548e6d5a47 100644 --- a/tools/unit-test-app/configs/default_2 +++ b/tools/unit-test-app/configs/default_2 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils diff --git a/tools/unit-test-app/configs/default_2_c3 b/tools/unit-test-app/configs/default_2_c3 index 54bedf8982..dc2a555504 100644 --- a/tools/unit-test-app/configs/default_2_c3 +++ b/tools/unit-test-app/configs/default_2_c3 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded CONFIG_IDF_TARGET="esp32c3" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs lwip spiffs experimental_cpp_component perfmon test_utils +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs lwip spiffs perfmon test_utils diff --git a/tools/unit-test-app/configs/default_2_s2 b/tools/unit-test-app/configs/default_2_s2 index 178dadce02..3df8ab2324 100644 --- a/tools/unit-test-app/configs/default_2_s2 +++ b/tools/unit-test-app/configs/default_2_s2 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs diff --git a/tools/unit-test-app/configs/default_2_s3 b/tools/unit-test-app/configs/default_2_s3 index e8aacbb2c7..34ffcda355 100644 --- a/tools/unit-test-app/configs/default_2_s3 +++ b/tools/unit-test-app/configs/default_2_s3 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s3" -TEST_EXCLUDE_COMPONENTS=bt esp32s3 esp_system driver soc spi_flash vfs experimental_cpp_component test_utils +TEST_EXCLUDE_COMPONENTS=bt esp32s3 esp_system driver soc spi_flash vfs test_utils diff --git a/tools/unit-test-app/configs/psram b/tools/unit-test-app/configs/psram index 78257ede8d..c6e2cd4be6 100644 --- a/tools/unit-test-app/configs/psram +++ b/tools/unit-test-app/configs/psram @@ -1,5 +1,5 @@ CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=bt driver esp_system spi_flash test_utils soc experimental_cpp_component esp-tls sdmmc +TEST_EXCLUDE_COMPONENTS=bt driver esp_system spi_flash test_utils soc esp-tls sdmmc CONFIG_SPIRAM=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_SPIRAM_OCCUPY_NO_HOST=y diff --git a/tools/unit-test-app/configs/release_2 b/tools/unit-test-app/configs/release_2 index 7cecfb413d..bb792f4e69 100644 --- a/tools/unit-test-app/configs/release_2 +++ b/tools/unit-test-app/configs/release_2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/release_2_s2 b/tools/unit-test-app/configs/release_2_s2 index 8f6bd3d32e..f9a9870c2c 100644 --- a/tools/unit-test-app/configs/release_2_s2 +++ b/tools/unit-test-app/configs/release_2_s2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/single_core_2 b/tools/unit-test-app/configs/single_core_2 index bc0527e5fd..f93af667cd 100644 --- a/tools/unit-test-app/configs/single_core_2 +++ b/tools/unit-test-app/configs/single_core_2 @@ -1,5 +1,5 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs test_utils CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y diff --git a/tools/unit-test-app/configs/single_core_2_s2 b/tools/unit-test-app/configs/single_core_2_s2 index d434854c49..1ea4d72d76 100644 --- a/tools/unit-test-app/configs/single_core_2_s2 +++ b/tools/unit-test-app/configs/single_core_2_s2 @@ -1,5 +1,5 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=bt esp_system driver soc spi_flash vfs CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y