From 977e74b2e49eca72d7b34d474c07b6a7fa2f3f7e Mon Sep 17 00:00:00 2001 From: Alexander Bobkov Date: Sat, 4 Oct 2025 01:37:30 -0400 Subject: [PATCH] esp32 temperature node --- .../build/local_components_list.temp.yml | 213 ----- .../dependencies.lock | 69 +- .../esp-idf-lib__bmp280/.ackrc | 1 + .../esp-idf-lib__bmp280/.astylerc | 17 + .../esp-idf-lib__bmp280/.clang-format | 66 ++ .../esp-idf-lib__bmp280/.component_hash | 1 + .../esp-idf-lib__bmp280/.eil.yml | 32 + .../esp-idf-lib__bmp280/.gitignore | 7 + .../esp-idf-lib__bmp280/.gitmodules | 3 + .../esp-idf-lib__bmp280/CHECKSUMS.json | 1 + .../esp-idf-lib__bmp280/CMakeLists.txt | 13 + .../esp-idf-lib__bmp280/Kconfig.i2c | 19 + .../esp-idf-lib__bmp280/LICENSE | 22 + .../esp-idf-lib__bmp280/README.md | 30 + .../esp-idf-lib__bmp280/bin/eil-q | 18 + .../esp-idf-lib__bmp280/bmp280.c | 411 ++++++++ .../esp-idf-lib__bmp280/bmp280.h | 256 +++++ .../common/cmake/esp-idf-lib.cmake | 36 + .../esp-idf-lib__bmp280/component.mk | 2 + .../examples/default/CMakeLists.txt | 7 + .../examples/default/Makefile | 5 + .../examples/default/README.md | 21 + .../examples/default/main/CMakeLists.txt | 2 + .../examples/default/main/Kconfig.projbuild | 3 + .../examples/default/main/component.mk | 1 + .../examples/default/main/idf_component.yml | 9 + .../examples/default/main/main.c | 53 ++ .../default/sdkconfig.defaults.esp8266 | 1 + .../esp-idf-lib__bmp280/idf_component.yml | 32 + .../esp-idf-lib__esp_idf_lib_helpers/.ackrc | 1 + .../.astylerc | 17 + .../.clang-format | 66 ++ .../.component_hash | 1 + .../esp-idf-lib__esp_idf_lib_helpers/.eil.yml | 28 + .../.gitignore | 7 + .../.gitmodules | 3 + .../CHECKSUMS.json | 1 + .../CMakeLists.txt | 12 + .../esp-idf-lib__esp_idf_lib_helpers/LICENSE | 13 + .../README.md | 30 + .../bin/eil-q | 18 + .../common/cmake/esp-idf-lib.cmake | 36 + .../component.mk | 8 + .../esp_idf_lib_helpers.h | 101 ++ .../ets_sys.h | 27 + .../examples/default/CMakeLists.txt | 5 + .../examples/default/Makefile | 5 + .../examples/default/README.md | 16 + .../examples/default/main/CMakeLists.txt | 2 + .../examples/default/main/component.mk | 1 + .../examples/default/main/idf_component.yml | 5 + .../examples/default/main/main.c | 39 + .../examples/default/main/my_local_header.h | 20 + .../examples/default/sdkconfig.defaults | 1 + .../idf_component.yml | 29 + .../esp-idf-lib__i2cdev/.ackrc | 1 + .../esp-idf-lib__i2cdev/.astylerc | 17 + .../esp-idf-lib__i2cdev/.clang-format | 66 ++ .../esp-idf-lib__i2cdev/.component_hash | 1 + .../esp-idf-lib__i2cdev/.eil.yml | 28 + .../esp-idf-lib__i2cdev/.gitignore | 7 + .../esp-idf-lib__i2cdev/.gitmodules | 3 + .../esp-idf-lib__i2cdev/CHECKSUMS.json | 1 + .../esp-idf-lib__i2cdev/CMakeLists.txt | 45 + .../esp-idf-lib__i2cdev/Kconfig | 65 ++ .../esp-idf-lib__i2cdev/Kconfig.i2c | 19 + .../esp-idf-lib__i2cdev/LICENSE | 21 + .../esp-idf-lib__i2cdev/README.md | 30 + .../esp-idf-lib__i2cdev/bin/eil-q | 18 + .../common/cmake/esp-idf-lib.cmake | 36 + .../esp-idf-lib__i2cdev/component.mk | 29 + .../examples/default/CMakeLists.txt | 7 + .../examples/default/Makefile | 5 + .../examples/default/README.md | 31 + .../examples/default/main/CMakeLists.txt | 2 + .../examples/default/main/Kconfig.projbuild | 7 + .../examples/default/main/component.mk | 1 + .../examples/default/main/idf_component.yml | 7 + .../examples/default/main/main.c | 43 + .../esp-idf-lib__i2cdev/i2cdev.c | 897 ++++++++++++++++++ .../esp-idf-lib__i2cdev/i2cdev.h | 381 ++++++++ .../esp-idf-lib__i2cdev/i2cdev_legacy.c | 793 ++++++++++++++++ .../esp-idf-lib__i2cdev/idf_component.yml | 30 + 83 files changed, 4220 insertions(+), 214 deletions(-) delete mode 100644 ESP32-IDF_Temperture-Node-v2/build/local_components_list.temp.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.ackrc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.astylerc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.clang-format create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.component_hash create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.eil.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitignore create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitmodules create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CHECKSUMS.json create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/Kconfig.i2c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/LICENSE create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bin/eil-q create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.h create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/common/cmake/esp-idf-lib.cmake create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/Makefile create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/Kconfig.projbuild create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/idf_component.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/main.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/sdkconfig.defaults.esp8266 create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/idf_component.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.ackrc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.astylerc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.clang-format create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.component_hash create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.eil.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitignore create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitmodules create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CHECKSUMS.json create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/LICENSE create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/bin/eil-q create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/common/cmake/esp-idf-lib.cmake create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/esp_idf_lib_helpers.h create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/ets_sys.h create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/Makefile create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/idf_component.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/main.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/my_local_header.h create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/sdkconfig.defaults create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/idf_component.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.ackrc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.astylerc create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.clang-format create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.component_hash create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.eil.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitignore create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitmodules create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CHECKSUMS.json create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig.i2c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/LICENSE create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/bin/eil-q create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/common/cmake/esp-idf-lib.cmake create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/Makefile create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/README.md create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/CMakeLists.txt create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/Kconfig.projbuild create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/component.mk create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/idf_component.yml create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/main.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.h create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev_legacy.c create mode 100644 ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/idf_component.yml diff --git a/ESP32-IDF_Temperture-Node-v2/build/local_components_list.temp.yml b/ESP32-IDF_Temperture-Node-v2/build/local_components_list.temp.yml deleted file mode 100644 index 9af522fcb..000000000 --- a/ESP32-IDF_Temperture-Node-v2/build/local_components_list.temp.yml +++ /dev/null @@ -1,213 +0,0 @@ -components: - - name: "app_trace" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/app_trace" - - name: "app_update" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/app_update" - - name: "bootloader" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/bootloader" - - name: "bootloader_support" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/bootloader_support" - - name: "bt" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/bt" - - name: "cmock" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/cmock" - - name: "console" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/console" - - name: "cxx" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/cxx" - - name: "driver" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/driver" - - name: "efuse" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/efuse" - - name: "esp-tls" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp-tls" - - name: "esp_adc" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_adc" - - name: "esp_app_format" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_app_format" - - name: "esp_bootloader_format" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_bootloader_format" - - name: "esp_coex" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_coex" - - name: "esp_common" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_common" - - name: "esp_driver_ana_cmpr" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_ana_cmpr" - - name: "esp_driver_cam" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_cam" - - name: "esp_driver_dac" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_dac" - - name: "esp_driver_gpio" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_gpio" - - name: "esp_driver_gptimer" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_gptimer" - - name: "esp_driver_i2c" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_i2c" - - name: "esp_driver_i2s" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_i2s" - - name: "esp_driver_isp" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_isp" - - name: "esp_driver_jpeg" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_jpeg" - - name: "esp_driver_ledc" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_ledc" - - name: "esp_driver_mcpwm" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_mcpwm" - - name: "esp_driver_parlio" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_parlio" - - name: "esp_driver_pcnt" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_pcnt" - - name: "esp_driver_ppa" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_ppa" - - name: "esp_driver_rmt" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_rmt" - - name: "esp_driver_sdio" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_sdio" - - name: "esp_driver_sdm" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_sdm" - - name: "esp_driver_sdmmc" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_sdmmc" - - name: "esp_driver_sdspi" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_sdspi" - - name: "esp_driver_spi" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_spi" - - name: "esp_driver_touch_sens" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_touch_sens" - - name: "esp_driver_tsens" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_tsens" - - name: "esp_driver_uart" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_uart" - - name: "esp_driver_usb_serial_jtag" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_driver_usb_serial_jtag" - - name: "esp_eth" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_eth" - - name: "esp_event" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_event" - - name: "esp_gdbstub" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_gdbstub" - - name: "esp_hid" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_hid" - - name: "esp_http_client" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_http_client" - - name: "esp_http_server" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_http_server" - - name: "esp_https_ota" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_https_ota" - - name: "esp_https_server" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_https_server" - - name: "esp_hw_support" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_hw_support" - - name: "esp_lcd" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_lcd" - - name: "esp_local_ctrl" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_local_ctrl" - - name: "esp_mm" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_mm" - - name: "esp_netif" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_netif" - - name: "esp_netif_stack" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_netif_stack" - - name: "esp_partition" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_partition" - - name: "esp_phy" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_phy" - - name: "esp_pm" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_pm" - - name: "esp_psram" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_psram" - - name: "esp_ringbuf" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_ringbuf" - - name: "esp_rom" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_rom" - - name: "esp_security" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_security" - - name: "esp_system" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_system" - - name: "esp_timer" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_timer" - - name: "esp_vfs_console" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_vfs_console" - - name: "esp_wifi" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esp_wifi" - - name: "espcoredump" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/espcoredump" - - name: "esptool_py" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/esptool_py" - - name: "fatfs" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/fatfs" - - name: "freertos" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/freertos" - - name: "hal" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/hal" - - name: "heap" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/heap" - - name: "http_parser" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/http_parser" - - name: "idf_test" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/idf_test" - - name: "ieee802154" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/ieee802154" - - name: "json" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/json" - - name: "linux" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/linux" - - name: "log" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/log" - - name: "lwip" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/lwip" - - name: "mbedtls" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/mbedtls" - - name: "mqtt" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/mqtt" - - name: "newlib" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/newlib" - - name: "nvs_flash" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/nvs_flash" - - name: "nvs_sec_provider" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/nvs_sec_provider" - - name: "openthread" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/openthread" - - name: "partition_table" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/partition_table" - - name: "perfmon" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/perfmon" - - name: "protobuf-c" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/protobuf-c" - - name: "protocomm" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/protocomm" - - name: "pthread" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/pthread" - - name: "riscv" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/riscv" - - name: "rt" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/rt" - - name: "sdmmc" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/sdmmc" - - name: "soc" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/soc" - - name: "spi_flash" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/spi_flash" - - name: "spiffs" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/spiffs" - - name: "tcp_transport" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/tcp_transport" - - name: "touch_element" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/touch_element" - - name: "ulp" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/ulp" - - name: "unity" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/unity" - - name: "usb" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/usb" - - name: "vfs" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/vfs" - - name: "wear_levelling" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/wear_levelling" - - name: "wifi_provisioning" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/wifi_provisioning" - - name: "wpa_supplicant" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/wpa_supplicant" - - name: "xtensa" - path: "/home/abobkov/esp/v5.4.1/esp-idf/components/xtensa" - - name: "main" - path: "/home/abobkov/MyProjects/ESP-Nodes/ESP32-IDF_Temperture-Node-v2/main" diff --git a/ESP32-IDF_Temperture-Node-v2/dependencies.lock b/ESP32-IDF_Temperture-Node-v2/dependencies.lock index 5bb3cdfc2..14cf09529 100644 --- a/ESP32-IDF_Temperture-Node-v2/dependencies.lock +++ b/ESP32-IDF_Temperture-Node-v2/dependencies.lock @@ -1,4 +1,70 @@ dependencies: + esp-idf-lib/bmp280: + component_hash: 82b01a37c200ed66a6c451026e2afdbe8046c6f702d41085e5a1d83aec3a90d8 + dependencies: + - name: esp-idf-lib/esp_idf_lib_helpers + registry_url: https://components.espressif.com + require: private + version: '*' + - name: esp-idf-lib/i2cdev + registry_url: https://components.espressif.com + require: private + version: '*' + source: + registry_url: https://components.espressif.com/ + type: service + targets: + - esp32 + - esp32c2 + - esp32c3 + - esp32c5 + - esp32c6 + - esp32c61 + - esp32h2 + - esp32p4 + - esp32s2 + - esp32s3 + version: 1.0.7 + esp-idf-lib/esp_idf_lib_helpers: + component_hash: a8049b1e609679fb54b2d57b0399dd29c4d1fda09a797edac9926f7810aa5703 + dependencies: [] + source: + registry_url: https://components.espressif.com + type: service + targets: + - esp32 + - esp32c2 + - esp32c3 + - esp32c5 + - esp32c6 + - esp32c61 + - esp32h2 + - esp32p4 + - esp32s2 + - esp32s3 + version: 1.3.10 + esp-idf-lib/i2cdev: + component_hash: 11c08f9e1a7d346b5dd763196dc2567cf2209ae49042402c2c2d296624601c14 + dependencies: + - name: esp-idf-lib/esp_idf_lib_helpers + registry_url: https://components.espressif.com + require: private + version: '*' + source: + registry_url: https://components.espressif.com + type: service + targets: + - esp32 + - esp32c2 + - esp32c3 + - esp32c5 + - esp32c6 + - esp32c61 + - esp32h2 + - esp32p4 + - esp32s2 + - esp32s3 + version: 2.0.8 espressif/bme280: component_hash: 873d97d0bd30004f45d1653f078a4bafe39c1767e57d4bae0f0a13bc3a4d5e3d dependencies: @@ -46,8 +112,9 @@ dependencies: type: idf version: 5.4.1 direct_dependencies: +- esp-idf-lib/bmp280 - espressif/bme280 - idf -manifest_hash: 56655df8035b9ce03ff888e9decae7c9c07a8c31eb7c6c080e638f76e687b00e +manifest_hash: 6a0a2f31ea59f281811a0fd0eb315dfa46b1a0f45d9af8d29ab20fcc8152290c target: esp32 version: 2.0.0 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.ackrc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.ackrc new file mode 100644 index 000000000..b32579583 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.ackrc @@ -0,0 +1 @@ +--ignore-dir=build diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.astylerc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.astylerc new file mode 100644 index 000000000..30389cee7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.astylerc @@ -0,0 +1,17 @@ +--align-reference=name +--attach-classes +--attach-classes +--attach-namespaces +--convert-tabs +--exclude=build +--exclude=common +--exclude=managed_components +--ignore-exclude-errors +--indent-switches +--indent=spaces=4 +--keep-one-line-statements +--max-continuation-indent=120 +--pad-header +--pad-oper +--style=allman +--unpad-paren diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.clang-format b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.clang-format new file mode 100644 index 000000000..123d6a848 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.clang-format @@ -0,0 +1,66 @@ +--- +Language: Cpp +BasedOnStyle: WebKit +AlignConsecutiveMacros: true +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +ColumnLimit: 200 +CompactNamespaces: true +Cpp11BracedListStyle: false +FixNamespaceComments: true +IndentCaseLabels: true +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeInheritanceColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.component_hash b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.component_hash new file mode 100644 index 000000000..b130b77d8 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.component_hash @@ -0,0 +1 @@ +82b01a37c200ed66a6c451026e2afdbe8046c6f702d41085e5a1d83aec3a90d8 \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.eil.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.eil.yml new file mode 100644 index 000000000..0bd3fbc7c --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.eil.yml @@ -0,0 +1,32 @@ +--- +name: bmp280 +description: Driver for BMP280/BME280 digital pressure sensor +version: 1.0.7 +groups: + - pressure + - temperature +code_owners: + - UncleRus +depends: + - i2cdev + - log + - esp_idf_lib_helpers +thread_safe: yes +targets: + - esp32 + - esp8266 + - esp32s2 + - esp32c3 + - esp32s3 + - esp32c2 + - esp32c6 + - esp32h2 + - esp32p4 + - esp32c5 + - esp32c61 +license: MIT +copyrights: + - name: sheinz + year: 2016 + - name: UncleRus + year: 2018 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitignore b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitignore new file mode 100644 index 000000000..9cccbfb72 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitignore @@ -0,0 +1,7 @@ +examples/**/sdkconfig +examples/**/sdkconfig.old +examples/**/build/ +examples/**/dependencies.lock +docs/_*/ +docs/doxygen.log +*.swp diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitmodules b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitmodules new file mode 100644 index 000000000..a9554a22c --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = https://github.com/esp-idf-lib/common.git diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CHECKSUMS.json b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CHECKSUMS.json new file mode 100644 index 000000000..05b06772d --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CHECKSUMS.json @@ -0,0 +1 @@ +{"version": "1.0", "algorithm": "sha256", "created_at": "2025-07-31T11:56:00.065336+00:00", "files": [{"path": ".ackrc", "size": 19, "hash": "ad251fb2384460920327843ab53f696de85a385a179e9ff06f2dd496607a2f31"}, {"path": ".astylerc", "size": 324, "hash": "07a888d14b14e7d39e3e645c7f75addb9620ec9026248a5393baa63ef207556f"}, {"path": ".clang-format", "size": 1814, "hash": "b23e699f74909593d399c31f56d38e02c8a71c7dae0102813429e73520783101"}, {"path": ".eil.yml", "size": 457, "hash": "64746c5ae60a16c7b54aa010139564c531a855e8bf29c232914d73ed9a236875"}, {"path": ".gitignore", "size": 129, "hash": "44cc4e80bc8c455013cbdbd2338b690b62da9ded5368d66f4a576401e0aaa189"}, {"path": ".gitmodules", "size": 85, "hash": "bdbdfe664e912bb32da537de8e7137eccce5869bbe030b254bd96d31891295e5"}, {"path": "CMakeLists.txt", "size": 366, "hash": "ce941164a14cc769e45f931eb00cf84140df0464462d9c686ff41369d38d6c96"}, {"path": "Kconfig.i2c", "size": 848, "hash": "541dae0eb78e6309736d6e6f0d1c415c0881d65e7a6668e9135d4e0b55f56a89"}, {"path": "LICENSE", "size": 1164, "hash": "759ac97707f5e9ba2aa49c1672e47c560a54fa20cac1c51aac326c6f18379dfd"}, {"path": "README.md", "size": 1398, "hash": "e106e6a77e5b753cc23f8947340a16ff9b713402dc21219a8dcb728f5558ea0e"}, {"path": "bmp280.c", "size": 14401, "hash": "0c30035adbe635f5a48222b2a8bb22ff3a4cbbb763f0d9a3f9da6efea8c8243c"}, {"path": "bmp280.h", "size": 7280, "hash": "a9ad0b7e0cc7d31dfddfb2e15b4b981df0bac84c5c4b6c9216ed880737d61374"}, {"path": "component.mk", "size": 81, "hash": "5a79f4b9750e2189b11141694f761f5c13f9b38eee3dfd860bedd443fad81356"}, {"path": "idf_component.yml", "size": 738, "hash": "45e19c437f58d192ceb44792d475fd946f2f2baeba49c2ebb7ef7e52d6c92645"}, {"path": "bin/eil-q", "size": 399, "hash": "52bfaca6bfc34bba78c5707ed4013bac1839ef67ab4fa6feb8885b6face2c86a"}, {"path": "common/.git", "size": 31, "hash": "3c08a82d0d8b9fc7bb41dbf0d0836636c5b5e89a73243f77817467f7d1ffccbc"}, {"path": "examples/default/CMakeLists.txt", "size": 244, "hash": "b4b2f70858d4efc7b66f0544d91e338459483af7aa623af4ddb77411ba610a36"}, {"path": "examples/default/Makefile", "size": 77, "hash": "39df247069fd61b8a148bfa06d06c0fa1c11dff812bccd7b4b2c89882b01886f"}, {"path": "examples/default/README.md", "size": 684, "hash": "a0590f4cd58f0abae7c321d6a6969c9bd1626104ebbe1940b6f88ec27d9d130e"}, {"path": "examples/default/sdkconfig.defaults.esp8266", "size": 37, "hash": "91b9d5c57c163b5914b4e07c446b7cfa7a93dc754644675951452d934686b4ca"}, {"path": "examples/default/main/CMakeLists.txt", "size": 75, "hash": "27d6d39ef0cb6a9097984b41e080b09f7ff972339a0bb4ddf771db4001cb9782"}, {"path": "examples/default/main/Kconfig.projbuild", "size": 72, "hash": "8ca9b29c2c6f3253ffbe9307c8a5a960f608ea05241bce86e549b210c2ea7dd1"}, {"path": "examples/default/main/component.mk", "size": 39, "hash": "532e7836f005fd3b10f1955409e4956ad69fd386e80b12de11d96f8e84977843"}, {"path": "examples/default/main/idf_component.yml", "size": 180, "hash": "c64c9a1fb13f38ec33cb37ee91a058c922e43e37164884532223521f579d6899"}, {"path": "examples/default/main/main.c", "size": 1536, "hash": "e959afe2bc5b756ac04f16feeed24612c69b0113c0292fb66a0df47a26ca5665"}, {"path": "common/cmake/esp-idf-lib.cmake", "size": 1119, "hash": "ea0f8a819ac721dfbf5ab5f109c75c32c90c8060e6fcc9fbad1ce9de29451405"}]} \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CMakeLists.txt new file mode 100644 index 000000000..67e0f4344 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/CMakeLists.txt @@ -0,0 +1,13 @@ +idf_component_register( + SRCS bmp280.c + INCLUDE_DIRS . + REQUIRES i2cdev log esp_idf_lib_helpers +) + +# include common cmake file for components +set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake) +if(EXISTS ${ESP_IDF_LIB_CMAKE}) + include(${ESP_IDF_LIB_CMAKE}) +else() + message(WARNING "${ESP_IDF_LIB_CMAKE} not found") +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/Kconfig.i2c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/Kconfig.i2c new file mode 100644 index 000000000..29d0ac2d7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/Kconfig.i2c @@ -0,0 +1,19 @@ +config EXAMPLE_I2C_MASTER_SCL + int "SCL GPIO Number" + default 5 if IDF_TARGET_ESP8266 + default 6 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61 + default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 4 if IDF_TARGET_ESP32H2 + default 4 if IDF_TARGET_ESP32P4 + help + GPIO number for I2C Master clock line. + +config EXAMPLE_I2C_MASTER_SDA + int "SDA GPIO Number" + default 4 if IDF_TARGET_ESP8266 + default 5 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61 + default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 3 if IDF_TARGET_ESP32H2 + default 3 if IDF_TARGET_ESP32P4 + help + GPIO number for I2C Master data line. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/LICENSE b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/LICENSE new file mode 100644 index 000000000..3bed1c196 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 sheinz (https://github.com/sheinz) +Copyright (c) 2018 Ruslan V. Uss (https://github.com/UncleRus) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/README.md new file mode 100644 index 000000000..c5d243548 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/README.md @@ -0,0 +1,30 @@ +# esp-idf-lib/bmp280 + +[![Build examples](https://github.com/esp-idf-lib/bmp280/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/bmp280/actions/workflows//build.yml) +[![Build docs](https://github.com/esp-idf-lib/bmp280/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/bmp280/actions/workflows//build-docs.yml) +[![Validation](https://github.com/esp-idf-lib/bmp280/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/bmp280/actions/workflows//validate-component.yml) + +Driver for BMP280/BME280 digital pressure sensor. + +* [Documentation](https://esp-idf-lib.github.io/bmp280/) +* [Repository](https://github.com/esp-idf-lib/bmp280) +* [Issues](https://github.com/esp-idf-lib/bmp280/issues) +* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions) +* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/bmp280) + +## Installation + +```sh +idf.py add-dependency esp-idf-lib/bmp280 +``` + +## Support + +For questions and discussions about the component, please use +[Discussions](https://github.com/esp-idf-lib/core/discussions) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). + +## Contributing + +Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bin/eil-q b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bin/eil-q new file mode 100644 index 000000000..870625afb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bin/eil-q @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require "pathname" +require "yaml" + +# A simple CLI to get values in .eil.yml + +key = ARGV.shift +project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent +eil_file = project_root / ".eil.yml" +doc = YAML.safe_load(File.read eil_file) + +case key +when "copyright_string" + puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ") +else + puts doc[key] +end diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.c new file mode 100644 index 000000000..ace752026 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.c @@ -0,0 +1,411 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 sheinz + * Copyright (c) 2018 Ruslan V. Uss + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file bmp280.c + * + * ESP-IDF driver for BMP280/BME280 digital pressure sensor + * + * Ported from esp-open-rtos + * + * Copyright (c) 2016 sheinz \n + * Copyright (c) 2018 Ruslan V. Uss + * + * MIT Licensed as described in the file LICENSE + */ + +#include "bmp280.h" +#include +#include +#include + +#define I2C_FREQ_HZ 1000000 // Max 1MHz for esp-idf + +static const char *TAG = "bmp280"; + +/** + * BMP280 registers + */ +#define BMP280_REG_TEMP_XLSB 0xFC /* bits: 7-4 */ +#define BMP280_REG_TEMP_LSB 0xFB +#define BMP280_REG_TEMP_MSB 0xFA +#define BMP280_REG_TEMP (BMP280_REG_TEMP_MSB) +#define BMP280_REG_PRESS_XLSB 0xF9 /* bits: 7-4 */ +#define BMP280_REG_PRESS_LSB 0xF8 +#define BMP280_REG_PRESS_MSB 0xF7 +#define BMP280_REG_PRESSURE (BMP280_REG_PRESS_MSB) +#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */ +#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */ +#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */ +#define BMP280_REG_CTRL_HUM 0xF2 /* bits: 2-0 osrs_h; */ +#define BMP280_REG_RESET 0xE0 +#define BMP280_REG_ID 0xD0 +#define BMP280_REG_CALIB 0x88 +#define BMP280_REG_HUM_CALIB 0x88 + +#define BMP280_RESET_VALUE 0xB6 + +#define CHECK(x) do { esp_err_t __; if ((__ = x) != ESP_OK) return __; } while (0) +#define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0) +#define CHECK_LOGE(dev, x, msg, ...) do { \ + esp_err_t __; \ + if ((__ = x) != ESP_OK) { \ + I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); \ + ESP_LOGE(TAG, msg, ## __VA_ARGS__); \ + return __; \ + } \ + } while (0) + +static esp_err_t read_register16(i2c_dev_t *dev, uint8_t reg, uint16_t *r) +{ + uint8_t d[] = { 0, 0 }; + + CHECK(i2c_dev_read_reg(dev, reg, d, 2)); + *r = d[0] | (d[1] << 8); + + return ESP_OK; +} + +inline static esp_err_t write_register8(i2c_dev_t *dev, uint8_t addr, uint8_t value) +{ + return i2c_dev_write_reg(dev, addr, &value, 1); +} + +static esp_err_t read_calibration_data(bmp280_t *dev) +{ + CHECK(read_register16(&dev->i2c_dev, 0x88, &dev->dig_T1)); + CHECK(read_register16(&dev->i2c_dev, 0x8a, (uint16_t *)&dev->dig_T2)); + CHECK(read_register16(&dev->i2c_dev, 0x8c, (uint16_t *)&dev->dig_T3)); + CHECK(read_register16(&dev->i2c_dev, 0x8e, &dev->dig_P1)); + CHECK(read_register16(&dev->i2c_dev, 0x90, (uint16_t *)&dev->dig_P2)); + CHECK(read_register16(&dev->i2c_dev, 0x92, (uint16_t *)&dev->dig_P3)); + CHECK(read_register16(&dev->i2c_dev, 0x94, (uint16_t *)&dev->dig_P4)); + CHECK(read_register16(&dev->i2c_dev, 0x96, (uint16_t *)&dev->dig_P5)); + CHECK(read_register16(&dev->i2c_dev, 0x98, (uint16_t *)&dev->dig_P6)); + CHECK(read_register16(&dev->i2c_dev, 0x9a, (uint16_t *)&dev->dig_P7)); + CHECK(read_register16(&dev->i2c_dev, 0x9c, (uint16_t *)&dev->dig_P8)); + CHECK(read_register16(&dev->i2c_dev, 0x9e, (uint16_t *)&dev->dig_P9)); + + ESP_LOGD(TAG, "Calibration data received:"); + ESP_LOGD(TAG, "dig_T1=%d", dev->dig_T1); + ESP_LOGD(TAG, "dig_T2=%d", dev->dig_T2); + ESP_LOGD(TAG, "dig_T3=%d", dev->dig_T3); + ESP_LOGD(TAG, "dig_P1=%d", dev->dig_P1); + ESP_LOGD(TAG, "dig_P2=%d", dev->dig_P2); + ESP_LOGD(TAG, "dig_P3=%d", dev->dig_P3); + ESP_LOGD(TAG, "dig_P4=%d", dev->dig_P4); + ESP_LOGD(TAG, "dig_P5=%d", dev->dig_P5); + ESP_LOGD(TAG, "dig_P6=%d", dev->dig_P6); + ESP_LOGD(TAG, "dig_P7=%d", dev->dig_P7); + ESP_LOGD(TAG, "dig_P8=%d", dev->dig_P8); + ESP_LOGD(TAG, "dig_P9=%d", dev->dig_P9); + + return ESP_OK; +} + +static esp_err_t read_hum_calibration_data(bmp280_t *dev) +{ + uint16_t h4, h5; + + CHECK(i2c_dev_read_reg(&dev->i2c_dev, 0xa1, &dev->dig_H1, 1)); + CHECK(read_register16(&dev->i2c_dev, 0xe1, (uint16_t *)&dev->dig_H2)); + CHECK(i2c_dev_read_reg(&dev->i2c_dev, 0xe3, &dev->dig_H3, 1)); + CHECK(read_register16(&dev->i2c_dev, 0xe4, &h4)); + CHECK(read_register16(&dev->i2c_dev, 0xe5, &h5)); + CHECK(i2c_dev_read_reg(&dev->i2c_dev, 0xe7, (uint8_t *)&dev->dig_H6, 1)); + + dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8; + dev->dig_H5 = h5 >> 4; + ESP_LOGD(TAG, "Calibration data received:"); + ESP_LOGD(TAG, "dig_H1=%d", dev->dig_H1); + ESP_LOGD(TAG, "dig_H2=%d", dev->dig_H2); + ESP_LOGD(TAG, "dig_H3=%d", dev->dig_H3); + ESP_LOGD(TAG, "dig_H4=%d", dev->dig_H4); + ESP_LOGD(TAG, "dig_H5=%d", dev->dig_H5); + ESP_LOGD(TAG, "dig_H6=%d", dev->dig_H6); + + return ESP_OK; +} + +esp_err_t bmp280_init_desc(bmp280_t *dev, uint8_t addr, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio) +{ + CHECK_ARG(dev); + + if (addr != BMP280_I2C_ADDRESS_0 && addr != BMP280_I2C_ADDRESS_1) + { + ESP_LOGE(TAG, "Invalid I2C address"); + return ESP_ERR_INVALID_ARG; + } + + dev->i2c_dev.port = port; + dev->i2c_dev.addr = addr; + dev->i2c_dev.cfg.sda_io_num = sda_gpio; + dev->i2c_dev.cfg.scl_io_num = scl_gpio; +#if HELPER_TARGET_IS_ESP32 + dev->i2c_dev.cfg.master.clk_speed = I2C_FREQ_HZ; +#endif + + return i2c_dev_create_mutex(&dev->i2c_dev); +} + +esp_err_t bmp280_free_desc(bmp280_t *dev) +{ + CHECK_ARG(dev); + + return i2c_dev_delete_mutex(&dev->i2c_dev); +} + +esp_err_t bmp280_init_default_params(bmp280_params_t *params) +{ + CHECK_ARG(params); + + params->mode = BMP280_MODE_NORMAL; + params->filter = BMP280_FILTER_OFF; + params->oversampling_pressure = BMP280_STANDARD; + params->oversampling_temperature = BMP280_STANDARD; + params->oversampling_humidity = BMP280_STANDARD; + params->standby = BMP280_STANDBY_250; + + return ESP_OK; +} + +esp_err_t bmp280_init(bmp280_t *dev, bmp280_params_t *params) +{ + CHECK_ARG(dev && params); + + I2C_DEV_TAKE_MUTEX(&dev->i2c_dev); + + CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, BMP280_REG_ID, &dev->id, 1), "Sensor not found"); + + if (dev->id != BMP280_CHIP_ID && dev->id != BME280_CHIP_ID) + { + CHECK_LOGE(dev, ESP_ERR_INVALID_VERSION, + "Invalid chip ID: expected: 0x%x (BME280) or 0x%x (BMP280) got: 0x%x", + BME280_CHIP_ID, BMP280_CHIP_ID, dev->id); + } + + // Soft reset. + CHECK_LOGE(dev, write_register8(&dev->i2c_dev, BMP280_REG_RESET, BMP280_RESET_VALUE), "Failed to reset sensor"); + + // Wait until finished copying over the NVP data. + while (1) + { + uint8_t status; + if (!i2c_dev_read_reg(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1) && (status & 1) == 0) + break; + } + + CHECK_LOGE(dev, read_calibration_data(dev), "Failed to read calibration data"); + + if (dev->id == BME280_CHIP_ID) + { + CHECK_LOGE(dev, read_hum_calibration_data(dev), "Failed to read humidity calibration data"); + } + + uint8_t config = (params->standby << 5) | (params->filter << 2); + ESP_LOGD(TAG, "Writing config reg=%x", config); + + CHECK_LOGE(dev, write_register8(&dev->i2c_dev, BMP280_REG_CONFIG, config), "Failed to configure sensor"); + + if (params->mode == BMP280_MODE_FORCED) + { + params->mode = BMP280_MODE_SLEEP; // initial mode for forced is sleep + } + + uint8_t ctrl = (params->oversampling_temperature << 5) | (params->oversampling_pressure << 2) | (params->mode); + + if (dev->id == BME280_CHIP_ID) + { + // Write crtl hum reg first, only active after write to BMP280_REG_CTRL. + uint8_t ctrl_hum = params->oversampling_humidity; + ESP_LOGD(TAG, "Writing ctrl hum reg=%x", ctrl_hum); + CHECK_LOGE(dev, write_register8(&dev->i2c_dev, BMP280_REG_CTRL_HUM, ctrl_hum), "Failed to control sensor"); + } + + ESP_LOGD(TAG, "Writing ctrl reg=%x", ctrl); + CHECK_LOGE(dev, write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl), "Failed to control sensor"); + + I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); + + return ESP_OK; +} + +esp_err_t bmp280_force_measurement(bmp280_t *dev) +{ + CHECK_ARG(dev); + + I2C_DEV_TAKE_MUTEX(&dev->i2c_dev); + + uint8_t ctrl; + I2C_DEV_CHECK(&dev->i2c_dev, i2c_dev_read_reg(&dev->i2c_dev, BMP280_REG_CTRL, &ctrl, 1)); + ctrl &= ~0b11; // clear two lower bits + ctrl |= BMP280_MODE_FORCED; + ESP_LOGD(TAG, "Writing ctrl reg=%x", ctrl); + CHECK_LOGE(dev, write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl), "Failed to start forced mode"); + + I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); + + return ESP_OK; +} + +esp_err_t bmp280_is_measuring(bmp280_t *dev, bool *busy) +{ + CHECK_ARG(dev && busy); + + I2C_DEV_TAKE_MUTEX(&dev->i2c_dev); + + const uint8_t regs[2] = { BMP280_REG_STATUS, BMP280_REG_CTRL }; + uint8_t status[2]; + CHECK_LOGE(dev, i2c_dev_read(&dev->i2c_dev, regs, 2, status, 2), "Failed to read status registers"); + + // Check mode - FORCED means BM280 is busy (it switches to SLEEP mode when finished) + // Additionally, check 'measuring' bit in status register + *busy = ((status[1] & 0b11) == BMP280_MODE_FORCED) || (status[0] & (1 << 3)); + + I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); + + return ESP_OK; +} + +/** + * Compensation algorithm is taken from BMP280 datasheet. + * + * Return value is in degrees Celsius. + */ +static inline int32_t compensate_temperature(bmp280_t *dev, int32_t adc_temp, int32_t *fine_temp) +{ + int32_t var1, var2; + + var1 = ((((adc_temp >> 3) - ((int32_t)dev->dig_T1 << 1))) * (int32_t)dev->dig_T2) >> 11; + var2 = (((((adc_temp >> 4) - (int32_t)dev->dig_T1) * ((adc_temp >> 4) - (int32_t)dev->dig_T1)) >> 12) * (int32_t)dev->dig_T3) >> 14; + + *fine_temp = var1 + var2; + return (*fine_temp * 5 + 128) >> 8; +} + +/** + * Compensation algorithm is taken from BMP280 datasheet. + * + * Return value is in Pa, 24 integer bits and 8 fractional bits. + */ +static inline uint32_t compensate_pressure(bmp280_t *dev, int32_t adc_press, int32_t fine_temp) +{ + int64_t var1, var2, p; + + var1 = (int64_t)fine_temp - 128000; + var2 = var1 * var1 * (int64_t)dev->dig_P6; + var2 = var2 + ((var1 * (int64_t)dev->dig_P5) << 17); + var2 = var2 + (((int64_t)dev->dig_P4) << 35); + var1 = ((var1 * var1 * (int64_t)dev->dig_P3) >> 8) + ((var1 * (int64_t)dev->dig_P2) << 12); + var1 = (((int64_t)1 << 47) + var1) * ((int64_t)dev->dig_P1) >> 33; + + if (var1 == 0) + { + return 0; // avoid exception caused by division by zero + } + + p = 1048576 - adc_press; + p = (((p << 31) - var2) * 3125) / var1; + var1 = ((int64_t)dev->dig_P9 * (p >> 13) * (p >> 13)) >> 25; + var2 = ((int64_t)dev->dig_P8 * p) >> 19; + + p = ((p + var1 + var2) >> 8) + ((int64_t)dev->dig_P7 << 4); + return p; +} + +/** + * Compensation algorithm is taken from BME280 datasheet. + * + * Return value is in Pa, 24 integer bits and 8 fractional bits. + */ +static inline uint32_t compensate_humidity(bmp280_t *dev, int32_t adc_hum, int32_t fine_temp) +{ + int32_t v_x1_u32r; + + v_x1_u32r = fine_temp - (int32_t)76800; + v_x1_u32r = ((((adc_hum << 14) - ((int32_t)dev->dig_H4 << 20) - ((int32_t)dev->dig_H5 * v_x1_u32r)) + (int32_t)16384) >> 15) + * (((((((v_x1_u32r * (int32_t)dev->dig_H6) >> 10) * (((v_x1_u32r * (int32_t)dev->dig_H3) >> 11) + (int32_t)32768)) >> 10) + + (int32_t)2097152) * (int32_t)dev->dig_H2 + 8192) >> 14); + v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * (int32_t)dev->dig_H1) >> 4); + v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r; + v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r; + return v_x1_u32r >> 12; +} + +esp_err_t bmp280_read_fixed(bmp280_t *dev, int32_t *temperature, uint32_t *pressure, uint32_t *humidity) +{ + CHECK_ARG(dev && temperature && pressure); + + int32_t adc_pressure; + int32_t adc_temp; + uint8_t data[8]; + + // Only the BME280 supports reading the humidity. + if (dev->id != BME280_CHIP_ID) + { + if (humidity) + *humidity = 0; + humidity = NULL; + } + + I2C_DEV_TAKE_MUTEX(&dev->i2c_dev); + + // Need to read in one sequence to ensure they match. + size_t size = humidity ? 8 : 6; + CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, 0xf7, data, size), "Failed to read data"); + + adc_pressure = data[0] << 12 | data[1] << 4 | data[2] >> 4; + adc_temp = data[3] << 12 | data[4] << 4 | data[5] >> 4; + ESP_LOGD(TAG, "ADC temperature: %" PRIi32, adc_temp); + ESP_LOGD(TAG, "ADC pressure: %" PRIi32, adc_pressure); + + int32_t fine_temp; + *temperature = compensate_temperature(dev, adc_temp, &fine_temp); + *pressure = compensate_pressure(dev, adc_pressure, fine_temp); + + if (humidity) + { + int32_t adc_humidity = data[6] << 8 | data[7]; + ESP_LOGD(TAG, "ADC humidity: %" PRIi32, adc_humidity); + *humidity = compensate_humidity(dev, adc_humidity, fine_temp); + } + + I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); + + return ESP_OK; +} + +esp_err_t bmp280_read_float(bmp280_t *dev, float *temperature, float *pressure, float *humidity) +{ + int32_t fixed_temperature; + uint32_t fixed_pressure; + uint32_t fixed_humidity; + CHECK(bmp280_read_fixed(dev, &fixed_temperature, &fixed_pressure, humidity ? &fixed_humidity : NULL)); + *temperature = (float)fixed_temperature / 100; + *pressure = (float)fixed_pressure / 256; + if (humidity) + *humidity = (float)fixed_humidity / 1024; + + return ESP_OK; +} diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.h b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.h new file mode 100644 index 000000000..d1e8b8c98 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/bmp280.h @@ -0,0 +1,256 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 sheinz + * Copyright (c) 2018 Ruslan V. Uss + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file bmp280.h + * @defgroup bmp280 bmp280 + * @{ + * + * ESP-IDF driver for BMP280/BME280 digital pressure sensor + * + * Ported from esp-open-rtos + * + * Copyright (c) 2016 sheinz \n + * Copyright (c) 2018 Ruslan V. Uss + * + * MIT Licensed as described in the file LICENSE + */ +#ifndef __BMP280_H__ +#define __BMP280_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BMP280_I2C_ADDRESS_0 0x76 //!< I2C address when SDO pin is low +#define BMP280_I2C_ADDRESS_1 0x77 //!< I2C address when SDO pin is high + +#define BMP280_CHIP_ID 0x58 //!< BMP280 has chip-id 0x58 +#define BME280_CHIP_ID 0x60 //!< BME280 has chip-id 0x60 + +/** + * Mode of BMP280 module operation. + */ +typedef enum +{ + BMP280_MODE_SLEEP = 0, //!< Sleep mode + BMP280_MODE_FORCED = 1, //!< Measurement is initiated by user + BMP280_MODE_NORMAL = 3 //!< Continues measurement +} BMP280_Mode; + +typedef enum +{ + BMP280_FILTER_OFF = 0, + BMP280_FILTER_2 = 1, + BMP280_FILTER_4 = 2, + BMP280_FILTER_8 = 3, + BMP280_FILTER_16 = 4 +} BMP280_Filter; + +/** + * Pressure oversampling settings + */ +typedef enum +{ + BMP280_SKIPPED = 0, //!< no measurement + BMP280_ULTRA_LOW_POWER = 1, //!< oversampling x1 + BMP280_LOW_POWER = 2, //!< oversampling x2 + BMP280_STANDARD = 3, //!< oversampling x4 + BMP280_HIGH_RES = 4, //!< oversampling x8 + BMP280_ULTRA_HIGH_RES = 5 //!< oversampling x16 +} BMP280_Oversampling; + +/** + * Stand by time between measurements in normal mode + */ +typedef enum +{ + BMP280_STANDBY_05 = 0, //!< stand by time 0.5ms + BMP280_STANDBY_62 = 1, //!< stand by time 62.5ms + BMP280_STANDBY_125 = 2, //!< stand by time 125ms + BMP280_STANDBY_250 = 3, //!< stand by time 250ms + BMP280_STANDBY_500 = 4, //!< stand by time 500ms + BMP280_STANDBY_1000 = 5, //!< stand by time 1s + BMP280_STANDBY_2000 = 6, //!< stand by time 2s BMP280, 10ms BME280 + BMP280_STANDBY_4000 = 7, //!< stand by time 4s BMP280, 20ms BME280 +} BMP280_StandbyTime; + +/** + * Configuration parameters for BMP280 module. + * Use function ::bmp280_init_default_params() to use default configuration. + */ +typedef struct +{ + BMP280_Mode mode; + BMP280_Filter filter; + BMP280_Oversampling oversampling_pressure; + BMP280_Oversampling oversampling_temperature; + BMP280_Oversampling oversampling_humidity; + BMP280_StandbyTime standby; +} bmp280_params_t; + +/** + * Device descriptor + */ +typedef struct +{ + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; + + /* Humidity compensation for BME280 */ + uint8_t dig_H1; + int16_t dig_H2; + uint8_t dig_H3; + int16_t dig_H4; + int16_t dig_H5; + int8_t dig_H6; + + i2c_dev_t i2c_dev; //!< I2C device descriptor + uint8_t id; //!< Chip ID +} bmp280_t; + +/** + * @brief Initialize device descriptor + * + * @param dev Device descriptor + * @param addr BMP280 address + * @param port I2C port number + * @param sda_gpio GPIO pin for SDA + * @param scl_gpio GPIO pin for SCL + * @return `ESP_OK` on success + */ +esp_err_t bmp280_init_desc(bmp280_t *dev, uint8_t addr, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio); + +/** + * @brief Free device descriptor + * + * @param dev Device descriptor + * @return `ESP_OK` on success + */ +esp_err_t bmp280_free_desc(bmp280_t *dev); + +/** + * @brief Initialize default parameters + * + * Default configuration: + * + * - mode: NORMAL + * - filter: OFF + * - oversampling: x4 + * - standby time: 250ms + * + * @param[out] params Default parameters + * @return `ESP_OK` on success + */ +esp_err_t bmp280_init_default_params(bmp280_params_t *params); + +/** + * @brief Initialize BMP280 module + * + * Probes for the device, soft resets the device, reads the calibration + * constants, and configures the device using the supplied parameters. + * + * This may be called again to soft reset the device and initialize it again. + * + * @param dev Device descriptor + * @param params Parameters + * @return `ESP_OK` on success + */ +esp_err_t bmp280_init(bmp280_t *dev, bmp280_params_t *params); + +/** + * @brief Start measurement in forced mode + * + * The module remains in forced mode after this call. + * Do not call this method in normal mode. + * + * @param dev Device descriptor + * @return `ESP_OK` on success + */ +esp_err_t bmp280_force_measurement(bmp280_t *dev); + +/** + * @brief Check if BMP280 is busy + * + * @param dev Device descriptor + * @param[out] busy true if BMP280 measures temperature/pressure + * @return `ESP_OK` on success + */ +esp_err_t bmp280_is_measuring(bmp280_t *dev, bool *busy); + +/** + * @brief Read raw compensated temperature and pressure data + * + * Temperature in degrees Celsius times 100. + * + * Pressure in Pascals in fixed point 24 bit integer 8 bit fraction format. + * + * Humidity is optional and only read for the BME280, in percent relative + * humidity as a fixed point 22 bit integer and 10 bit fraction format. + * + * @param dev Device descriptor + * @param[out] temperature Temperature, deg.C * 100 + * @param[out] pressure Pressure + * @param[out] humidity Humidity, optional + * @return `ESP_OK` on success + */ +esp_err_t bmp280_read_fixed(bmp280_t *dev, int32_t *temperature, + uint32_t *pressure, uint32_t *humidity); + +/** + * @brief Read compensated temperature and pressure data + * + * Humidity is optional and only read for the BME280. + * + * @param dev Device descriptor + * @param[out] temperature Temperature, deg.C + * @param[out] pressure Pressure, Pascal + * @param[out] humidity Relative humidity, percents (optional) + * @return `ESP_OK` on success + */ +esp_err_t bmp280_read_float(bmp280_t *dev, float *temperature, + float *pressure, float *humidity); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif // __BMP280_H__ diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/common/cmake/esp-idf-lib.cmake b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/common/cmake/esp-idf-lib.cmake new file mode 100644 index 000000000..33ff7347f --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/common/cmake/esp-idf-lib.cmake @@ -0,0 +1,36 @@ +# Set common build flags but enable them only when the build is in our CI, +# making them optional. The idea is, fail when compiled in our CI but just +# warn in any other cases. Code that compiles with one toolchain warning-free +# may not do so with another toolchain, which creates a project dependency on +# specific toolchain vendors and versions. +# +# Define flags that may cause failures here. +if (DEFINED ENV{ESP_IDF_LIB_CI}) + set(ESP_IDF_LIB_CI_FLAGS + -Werror=unused-variable + -Werror=unused-function + -Werror=write-strings + -Werror + ) +endif() + +# Set common build flags. Mandatory. +# +# Define flags that do not cause failures here. +set(ESP_IDF_LIB_FLAGS + -Wextra + -Wwrite-strings + -Wunused-variable + -Wunused-function + -Wreturn-type +) + +# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not +# set the flags. +get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE) +if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY") + target_compile_options(${COMPONENT_LIB} PRIVATE + ${ESP_IDF_LIB_FLAGS} + ${ESP_IDF_LIB_CI_FLAGS} + ) +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/component.mk new file mode 100644 index 000000000..a3610e863 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/component.mk @@ -0,0 +1,2 @@ +COMPONENT_ADD_INCLUDEDIRS = . +COMPONENT_DEPENDS = i2cdev log esp_idf_lib_helpers diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/CMakeLists.txt new file mode 100644 index 000000000..7add8c88a --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/CMakeLists.txt @@ -0,0 +1,7 @@ +# 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.5) + + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(example-bmp280) diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/Makefile b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/Makefile new file mode 100644 index 000000000..aac5bd844 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/Makefile @@ -0,0 +1,5 @@ +#V := 1 +PROJECT_NAME := example-bmp280 + + +include $(IDF_PATH)/make/project.mk diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/README.md new file mode 100644 index 000000000..8713b9f17 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/README.md @@ -0,0 +1,21 @@ +# Example for `bmp280` driver + +## What it does + +It shows device name, `BME280` or `BMP280`, found on I2C bus. + +It shows temperature and pressure in a loop. + +## Wiring + +Connect `SCL` and `SDA` pins to the following pins with appropriate pull-up +resistors. + +| Name | Description | Defaults | +|------|-------------|----------| +| `CONFIG_EXAMPLE_I2C_MASTER_SCL` | GPIO number for `SCL` | "5" for `esp8266`, "6" for `esp32c3`, "19" for `esp32`, `esp32s2`, and `esp32s3` | +| `CONFIG_EXAMPLE_I2C_MASTER_SDA` | GPIO number for `SDA` | "4" for `esp8266`, "5" for `esp32c3`, "18" for `esp32`, `esp32s2`, and `esp32s3` | + +## Notes + +`CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL` must be `y` on `esp8266`. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/CMakeLists.txt new file mode 100644 index 000000000..cf2c455cb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/Kconfig.projbuild b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/Kconfig.projbuild new file mode 100644 index 000000000..1a5f332bc --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/Kconfig.projbuild @@ -0,0 +1,3 @@ +menu "Example configuration" + rsource "../../../Kconfig.i2c" +endmenu diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/component.mk new file mode 100644 index 000000000..7700ea99b --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . include/ diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/idf_component.yml new file mode 100644 index 000000000..5d31ad0c9 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/idf_component.yml @@ -0,0 +1,9 @@ +dependencies: + esp-idf-lib/bmp280: + version: '*' + esp-idf-lib/esp_idf_lib_helpers: + version: '*' + esp-idf-lib/i2cdev: + version: '*' +description: default +version: 1.0.0 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/main.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/main.c new file mode 100644 index 000000000..2b4cc93f9 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/main/main.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include + +#ifndef APP_CPU_NUM +#define APP_CPU_NUM PRO_CPU_NUM +#endif + +void bmp280_test(void *pvParameters) +{ + bmp280_params_t params; + bmp280_init_default_params(¶ms); + bmp280_t dev; + memset(&dev, 0, sizeof(bmp280_t)); + + ESP_ERROR_CHECK(bmp280_init_desc(&dev, BMP280_I2C_ADDRESS_0, 0, CONFIG_EXAMPLE_I2C_MASTER_SDA, CONFIG_EXAMPLE_I2C_MASTER_SCL)); + ESP_ERROR_CHECK(bmp280_init(&dev, ¶ms)); + + bool bme280p = dev.id == BME280_CHIP_ID; + printf("BMP280: found %s\n", bme280p ? "BME280" : "BMP280"); + + float pressure, temperature, humidity; + + while (1) + { + vTaskDelay(pdMS_TO_TICKS(500)); + if (bmp280_read_float(&dev, &temperature, &pressure, &humidity) != ESP_OK) + { + printf("Temperature/pressure reading failed\n"); + continue; + } + + /* float is used in printf(). you need non-default configuration in + * sdkconfig for ESP8266, which is enabled by default for this + * example. see sdkconfig.defaults.esp8266 + */ + printf("Pressure: %.2f Pa, Temperature: %.2f C", pressure, temperature); + if (bme280p) + printf(", Humidity: %.2f\n", humidity); + else + printf("\n"); + } +} + +void app_main() +{ + ESP_ERROR_CHECK(i2cdev_init()); + xTaskCreatePinnedToCore(bmp280_test, "bmp280_test", configMINIMAL_STACK_SIZE * 8, NULL, 5, NULL, APP_CPU_NUM); +} + diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/sdkconfig.defaults.esp8266 b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/sdkconfig.defaults.esp8266 new file mode 100644 index 000000000..79a53171f --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/examples/default/sdkconfig.defaults.esp8266 @@ -0,0 +1 @@ +CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL=y diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/idf_component.yml new file mode 100644 index 000000000..25519996b --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__bmp280/idf_component.yml @@ -0,0 +1,32 @@ +dependencies: + esp-idf-lib/esp_idf_lib_helpers: + version: '*' + esp-idf-lib/i2cdev: + version: '*' +description: Driver for BMP280/BME280 digital pressure sensor +discussion: https://github.com/esp-idf-lib/core/discussions +documentation: https://esp-idf-lib.github.io/bmp280/ +files: + exclude: + - docs/**/* +issues: https://github.com/esp-idf-lib/bmp280/issues +license: MIT +maintainers: +- Ruslan V. Uss (@UncleRus) +repository: git://github.com/esp-idf-lib/bmp280.git +repository_info: + commit_sha: ba9aaa92d7416740703b044a53462c0e9b8ee4e8 + path: . +targets: +- esp32 +- esp32c2 +- esp32c3 +- esp32c5 +- esp32c6 +- esp32c61 +- esp32h2 +- esp32p4 +- esp32s2 +- esp32s3 +url: https://github.com/esp-idf-lib/core +version: 1.0.7 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.ackrc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.ackrc new file mode 100644 index 000000000..b32579583 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.ackrc @@ -0,0 +1 @@ +--ignore-dir=build diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.astylerc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.astylerc new file mode 100644 index 000000000..30389cee7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.astylerc @@ -0,0 +1,17 @@ +--align-reference=name +--attach-classes +--attach-classes +--attach-namespaces +--convert-tabs +--exclude=build +--exclude=common +--exclude=managed_components +--ignore-exclude-errors +--indent-switches +--indent=spaces=4 +--keep-one-line-statements +--max-continuation-indent=120 +--pad-header +--pad-oper +--style=allman +--unpad-paren diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.clang-format b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.clang-format new file mode 100644 index 000000000..123d6a848 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.clang-format @@ -0,0 +1,66 @@ +--- +Language: Cpp +BasedOnStyle: WebKit +AlignConsecutiveMacros: true +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +ColumnLimit: 200 +CompactNamespaces: true +Cpp11BracedListStyle: false +FixNamespaceComments: true +IndentCaseLabels: true +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeInheritanceColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.component_hash b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.component_hash new file mode 100644 index 000000000..762296eb1 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.component_hash @@ -0,0 +1 @@ +a8049b1e609679fb54b2d57b0399dd29c4d1fda09a797edac9926f7810aa5703 \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.eil.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.eil.yml new file mode 100644 index 000000000..e5b255c64 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.eil.yml @@ -0,0 +1,28 @@ +--- +name: esp_idf_lib_helpers +description: Common support library for esp-idf-lib +version: 1.3.10 +groups: + - common +code_owners: + - trombik + - UncleRus +depends: + - freertos +thread_safe: n/a +targets: + - esp32 + - esp8266 + - esp32s2 + - esp32c3 + - esp32s3 + - esp32c2 + - esp32c6 + - esp32h2 + - esp32p4 + - esp32c5 + - esp32c61 +license: ISC +copyrights: + - name: trombik + year: 2019 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitignore b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitignore new file mode 100644 index 000000000..9cccbfb72 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitignore @@ -0,0 +1,7 @@ +examples/**/sdkconfig +examples/**/sdkconfig.old +examples/**/build/ +examples/**/dependencies.lock +docs/_*/ +docs/doxygen.log +*.swp diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitmodules b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitmodules new file mode 100644 index 000000000..a9554a22c --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = https://github.com/esp-idf-lib/common.git diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CHECKSUMS.json b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CHECKSUMS.json new file mode 100644 index 000000000..eb982e7c3 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CHECKSUMS.json @@ -0,0 +1 @@ +{"version": "1.0", "algorithm": "sha256", "created_at": "2025-07-31T11:58:03.784223+00:00", "files": [{"path": ".ackrc", "size": 19, "hash": "ad251fb2384460920327843ab53f696de85a385a179e9ff06f2dd496607a2f31"}, {"path": ".astylerc", "size": 324, "hash": "07a888d14b14e7d39e3e645c7f75addb9620ec9026248a5393baa63ef207556f"}, {"path": ".clang-format", "size": 1814, "hash": "b23e699f74909593d399c31f56d38e02c8a71c7dae0102813429e73520783101"}, {"path": ".eil.yml", "size": 392, "hash": "bca7818e8535faa07a803f8128f11a27dcad7a2b3d39f9f613de2234489eade3"}, {"path": ".gitignore", "size": 129, "hash": "44cc4e80bc8c455013cbdbd2338b690b62da9ded5368d66f4a576401e0aaa189"}, {"path": ".gitmodules", "size": 85, "hash": "bdbdfe664e912bb32da537de8e7137eccce5869bbe030b254bd96d31891295e5"}, {"path": "CMakeLists.txt", "size": 326, "hash": "bf2befdeb8c2cb5e647057b4838d3020b7f4e5848500ab53498c1356b30722a2"}, {"path": "LICENSE", "size": 747, "hash": "8af15098bd9750efab7c1fce707e3826e269de336a0186ee3d87c29756f2e48d"}, {"path": "README.md", "size": 1544, "hash": "b0877176e744b8f63555cee4ea5af15f7c352eb31b6fa60babe6f51a75819f8c"}, {"path": "component.mk", "size": 141, "hash": "17a9935132097f4e1e39cf5c462434049cdcf2a605ea626d01588902a15e9ee6"}, {"path": "esp_idf_lib_helpers.h", "size": 3893, "hash": "2000c263dbe8de1e85d667ff255fed76f8640b218f6ac743bcbf82c6f716a605"}, {"path": "ets_sys.h", "size": 814, "hash": "d3d72ec5eee58d270843a944905b9f6b2855316a68dfa62a9cdb9d3a2f67a371"}, {"path": "idf_component.yml", "size": 726, "hash": "2173955049ce47e8a25072670af1845ca72ae2bc2340554efcc5211b324ebab9"}, {"path": "bin/eil-q", "size": 399, "hash": "52bfaca6bfc34bba78c5707ed4013bac1839ef67ab4fa6feb8885b6face2c86a"}, {"path": "common/.git", "size": 31, "hash": "3c08a82d0d8b9fc7bb41dbf0d0836636c5b5e89a73243f77817467f7d1ffccbc"}, {"path": "examples/default/CMakeLists.txt", "size": 113, "hash": "14df6860fe3c63b899ed7513c11c1d03089cd759651472fd49a8856527822618"}, {"path": "examples/default/Makefile", "size": 78, "hash": "62afae4841ff92184346fd8fabb18747d2593af2acb6dd3b97b8e98cbf1d7620"}, {"path": "examples/default/README.md", "size": 339, "hash": "208bcdb94e248ee8d5addcca246342b31894973703b0bef017dedc5a19c7cf1f"}, {"path": "examples/default/sdkconfig.defaults", "size": 57, "hash": "d7bbc11a66b1ad3722ec594540a4463f613a42674bd7c844a0236031d8b27ac9"}, {"path": "examples/default/main/CMakeLists.txt", "size": 75, "hash": "27d6d39ef0cb6a9097984b41e080b09f7ff972339a0bb4ddf771db4001cb9782"}, {"path": "examples/default/main/component.mk", "size": 30, "hash": "d2059eace95f81f03ac0e38a92f119418d56d44efa3869f373639a91c9e7da21"}, {"path": "examples/default/main/idf_component.yml", "size": 102, "hash": "b436b739c8de5770c3432665e86ea5c6fde3b8c9282c3d7092703ac2fd5d8b3f"}, {"path": "examples/default/main/main.c", "size": 1218, "hash": "675eb4d5afd116ba05f06857e29b28a2f099d7f6c1affb509d9949422eb5104b"}, {"path": "examples/default/main/my_local_header.h", "size": 870, "hash": "60f0ca3babd18d86129b28088b0af7927f8a906839b44cac7258dfa5c4497d5b"}, {"path": "common/cmake/esp-idf-lib.cmake", "size": 1119, "hash": "ea0f8a819ac721dfbf5ab5f109c75c32c90c8060e6fcc9fbad1ce9de29451405"}]} \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CMakeLists.txt new file mode 100644 index 000000000..476822eb7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/CMakeLists.txt @@ -0,0 +1,12 @@ +idf_component_register( + INCLUDE_DIRS . + REQUIRES freertos +) + +# include common cmake file for components +set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake) +if(EXISTS ${ESP_IDF_LIB_CMAKE}) + include(${ESP_IDF_LIB_CMAKE}) +else() + message(WARNING "${ESP_IDF_LIB_CMAKE} not found") +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/LICENSE b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/LICENSE new file mode 100644 index 000000000..f81d3d2f6 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2019 Tomoyuki Sakurai + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/README.md new file mode 100644 index 000000000..fa8c3a2a7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/README.md @@ -0,0 +1,30 @@ +# esp-idf-lib/esp_idf_lib_helpers + +[![Build examples](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build.yml) +[![Build docs](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build-docs.yml) +[![Validation](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//validate-component.yml) + +Common support library for esp-idf-lib. + +* [Documentation](https://esp-idf-lib.github.io/esp_idf_lib_helpers/) +* [Repository](https://github.com/esp-idf-lib/esp_idf_lib_helpers) +* [Issues](https://github.com/esp-idf-lib/esp_idf_lib_helpers/issues) +* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions) +* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/esp_idf_lib_helpers) + +## Installation + +```sh +idf.py add-dependency esp-idf-lib/esp_idf_lib_helpers +``` + +## Support + +For questions and discussions about the component, please use +[Discussions](https://github.com/esp-idf-lib/core/discussions) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). + +## Contributing + +Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/bin/eil-q b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/bin/eil-q new file mode 100644 index 000000000..870625afb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/bin/eil-q @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require "pathname" +require "yaml" + +# A simple CLI to get values in .eil.yml + +key = ARGV.shift +project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent +eil_file = project_root / ".eil.yml" +doc = YAML.safe_load(File.read eil_file) + +case key +when "copyright_string" + puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ") +else + puts doc[key] +end diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/common/cmake/esp-idf-lib.cmake b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/common/cmake/esp-idf-lib.cmake new file mode 100644 index 000000000..33ff7347f --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/common/cmake/esp-idf-lib.cmake @@ -0,0 +1,36 @@ +# Set common build flags but enable them only when the build is in our CI, +# making them optional. The idea is, fail when compiled in our CI but just +# warn in any other cases. Code that compiles with one toolchain warning-free +# may not do so with another toolchain, which creates a project dependency on +# specific toolchain vendors and versions. +# +# Define flags that may cause failures here. +if (DEFINED ENV{ESP_IDF_LIB_CI}) + set(ESP_IDF_LIB_CI_FLAGS + -Werror=unused-variable + -Werror=unused-function + -Werror=write-strings + -Werror + ) +endif() + +# Set common build flags. Mandatory. +# +# Define flags that do not cause failures here. +set(ESP_IDF_LIB_FLAGS + -Wextra + -Wwrite-strings + -Wunused-variable + -Wunused-function + -Wreturn-type +) + +# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not +# set the flags. +get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE) +if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY") + target_compile_options(${COMPONENT_LIB} PRIVATE + ${ESP_IDF_LIB_FLAGS} + ${ESP_IDF_LIB_CI_FLAGS} + ) +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/component.mk new file mode 100644 index 000000000..c03a32eba --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/component.mk @@ -0,0 +1,8 @@ +COMPONENT_ADD_INCLUDEDIRS = . + +ifdef CONFIG_IDF_TARGET_ESP8266 +COMPONENT_DEPENDS = esp8266 freertos +else +COMPONENT_DEPENDS = freertos +endif + diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/esp_idf_lib_helpers.h b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/esp_idf_lib_helpers.h new file mode 100644 index 000000000..c1c9c4a1c --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/esp_idf_lib_helpers.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019 Tomoyuki Sakurai + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__ESP_IDF_LIB_HELPERS__H__) +#define __ESP_IDF_LIB_HELPERS__H__ + +/* XXX this header file does not need to include freertos/FreeRTOS.h. + * but without it, ESP8266 RTOS SDK does not include `sdkconfig.h` in correct + * order. as this header depends on sdkconfig.h, sdkconfig.h must be included + * first. however, the SDK includes this header first, then includes + * `sdkconfig.h` when freertos/FreeRTOS.h is not explicitly included. an + * evidence can be found in `build/${COMPONENT}/${COMPONENT}.d` in a failed + * build. + */ +#include +#include + +#if !defined(ESP_IDF_VERSION) || !defined(ESP_IDF_VERSION_VAL) +#error Unknown ESP-IDF/ESP8266 RTOS SDK version +#endif + +/* Minimal supported version for ESP32, ESP32S2 */ +#define HELPER_ESP32_MIN_VER ESP_IDF_VERSION_VAL(3, 3, 5) +/* Minimal supported version for ESP8266 */ +#define HELPER_ESP8266_MIN_VER ESP_IDF_VERSION_VAL(3, 3, 0) + +/* HELPER_TARGET_IS_ESP32 + * 1 when the target is esp32 + */ +#if defined(CONFIG_IDF_TARGET_ESP32) \ + || defined(CONFIG_IDF_TARGET_ESP32S2) \ + || defined(CONFIG_IDF_TARGET_ESP32S3) \ + || defined(CONFIG_IDF_TARGET_ESP32C2) \ + || defined(CONFIG_IDF_TARGET_ESP32C3) \ + || defined(CONFIG_IDF_TARGET_ESP32C5) \ + || defined(CONFIG_IDF_TARGET_ESP32C6) \ + || defined(CONFIG_IDF_TARGET_ESP32P4) \ + || defined(CONFIG_IDF_TARGET_ESP32C61) \ + || defined(CONFIG_IDF_TARGET_ESP32H2) +#define HELPER_TARGET_IS_ESP32 (1) + +/* HELPER_TARGET_IS_ESP8266 + * 1 when the target is esp8266 + */ +#elif defined(CONFIG_IDF_TARGET_ESP8266) +#define HELPER_TARGET_IS_ESP8266 (1) +#else +#error BUG: cannot determine the target +#endif + +#if HELPER_TARGET_IS_ESP32 && ESP_IDF_VERSION < HELPER_ESP32_MIN_VER +#error Unsupported ESP-IDF version. Please update! +#endif + +#if HELPER_TARGET_IS_ESP8266 && ESP_IDF_VERSION < HELPER_ESP8266_MIN_VER +#error Unsupported ESP8266 RTOS SDK version. Please update! +#endif + +/* HELPER_SPI_HOST_DEFAULT + * + * The default SPI_HOST for spi_host_device_t + */ +#if CONFIG_IDF_TARGET_ESP32 +#define HELPER_SPI_HOST_DEFAULT HSPI_HOST +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#define HELPER_SPI_HOST_DEFAULT SPI2_HOST +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 +#define HELPER_SPI_HOST_DEFAULT SPI1_HOST +#elif CONFIG_IDF_TARGET_ESP32H2 +#define HELPER_SPI_HOST_DEFAULT SPI1_HOST +#elif CONFIG_IDF_TARGET_ESP32P4 +#define HELPER_SPI_HOST_DEFAULT SPI1_HOST +#endif + +/* show the actual values for debugging */ +#if DEBUG +#define VALUE_TO_STRING(x) #x +#define VALUE(x) VALUE_TO_STRING(x) +#define VAR_NAME_VALUE(var) #var "=" VALUE(var) +#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32C3)) +#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32H2)) +#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32S2)) +#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32)) +#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP8266)) +#pragma message(VAR_NAME_VALUE(ESP_IDF_VERSION_MAJOR)) +#endif + +#endif diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/ets_sys.h b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/ets_sys.h new file mode 100644 index 000000000..51c5d0f64 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/ets_sys.h @@ -0,0 +1,27 @@ +#if CONFIG_IDF_TARGET_ESP32 +#include +#elif CONFIG_IDF_TARGET_ESP32C2 +#include +#elif CONFIG_IDF_TARGET_ESP32C3 +#include +#elif CONFIG_IDF_TARGET_ESP32C5 +#include +#elif CONFIG_IDF_TARGET_ESP32C6 +#include +#elif CONFIG_IDF_TARGET_ESP32C61 +#include +#elif CONFIG_IDF_TARGET_ESP32H2 +#include +#elif CONFIG_IDF_TARGET_ESP32H4 +#include +#elif CONFIG_IDF_TARGET_ESP32S2 +#include +#elif CONFIG_IDF_TARGET_ESP32S3 +#include +#elif CONFIG_IDF_TARGET_ESP32P4 +#include +#elif CONFIG_IDF_TARGET_ESP8266 +#include +#else +#error "ets_sys: Unknown target" +#endif diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/CMakeLists.txt new file mode 100644 index 000000000..e784b3a66 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(example_example) diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/Makefile b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/Makefile new file mode 100644 index 000000000..95161b435 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/Makefile @@ -0,0 +1,5 @@ +#V := 1 +PROJECT_NAME := example_example + + +include $(IDF_PATH)/make/project.mk diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/README.md new file mode 100644 index 000000000..d429260d1 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/README.md @@ -0,0 +1,16 @@ +# Example application for `example` component + +## What the example does + +The example does nothing but waits in a loop. + +## Configuration + +No configuration is available. + +## Notes + +This is an example application of `example`. It is intended as an example +application for new component. + +The code under `main` should conform the code style. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/CMakeLists.txt new file mode 100644 index 000000000..cf2c455cb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/component.mk new file mode 100644 index 000000000..004b18e68 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/idf_component.yml new file mode 100644 index 000000000..c27bfc7e7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/idf_component.yml @@ -0,0 +1,5 @@ +dependencies: + esp-idf-lib/esp_idf_lib_helpers: + version: '*' +description: default +version: 1.0.0 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/main.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/main.c new file mode 100644 index 000000000..b584dee77 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/main.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) YYYY YOUR NAME HERE + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "my_local_header.h" + +static char *tag = "main"; + +void app_main() +{ + ESP_LOGI(tag, "An example log"); +#if HELPER_TARGET_IS_ESP32 + ESP_LOGI(tag, "the target is ESP32"); +#else + ESP_LOGI(tag, "the target is not ESP32"); +#endif + while (1) + { + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/my_local_header.h b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/my_local_header.h new file mode 100644 index 000000000..4d2a70bba --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/main/my_local_header.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) YYYY YOUR NAME HERE + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__MY_LOCAL_HEADER__H__) +#define __MY_LOCAL_HEADER__H__ + +#endif diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/sdkconfig.defaults b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/sdkconfig.defaults new file mode 100644 index 000000000..cd8cb4359 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/examples/default/sdkconfig.defaults @@ -0,0 +1 @@ +# add required non-default option for the example if any diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/idf_component.yml new file mode 100644 index 000000000..eee32209f --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__esp_idf_lib_helpers/idf_component.yml @@ -0,0 +1,29 @@ +dependencies: {} +description: Common support library for esp-idf-lib +discussion: https://github.com/esp-idf-lib/core/discussions +documentation: https://esp-idf-lib.github.io/esp_idf_lib_helpers/ +files: + exclude: + - docs/**/* +issues: https://github.com/esp-idf-lib/esp_idf_lib_helpers/issues +license: ISC +maintainers: +- Tomoyuki Sakurai (@trombik) +- Ruslan V. Uss (@UncleRus) +repository: git://github.com/esp-idf-lib/esp_idf_lib_helpers.git +repository_info: + commit_sha: 57bbd8f3cda9c5ad390fc3ea5585e0ad80672584 + path: . +targets: +- esp32 +- esp32c2 +- esp32c3 +- esp32c5 +- esp32c6 +- esp32c61 +- esp32h2 +- esp32p4 +- esp32s2 +- esp32s3 +url: https://github.com/esp-idf-lib/core +version: 1.3.10 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.ackrc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.ackrc new file mode 100644 index 000000000..b32579583 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.ackrc @@ -0,0 +1 @@ +--ignore-dir=build diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.astylerc b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.astylerc new file mode 100644 index 000000000..30389cee7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.astylerc @@ -0,0 +1,17 @@ +--align-reference=name +--attach-classes +--attach-classes +--attach-namespaces +--convert-tabs +--exclude=build +--exclude=common +--exclude=managed_components +--ignore-exclude-errors +--indent-switches +--indent=spaces=4 +--keep-one-line-statements +--max-continuation-indent=120 +--pad-header +--pad-oper +--style=allman +--unpad-paren diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.clang-format b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.clang-format new file mode 100644 index 000000000..123d6a848 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.clang-format @@ -0,0 +1,66 @@ +--- +Language: Cpp +BasedOnStyle: WebKit +AlignConsecutiveMacros: true +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +ColumnLimit: 200 +CompactNamespaces: true +Cpp11BracedListStyle: false +FixNamespaceComments: true +IndentCaseLabels: true +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeInheritanceColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.component_hash b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.component_hash new file mode 100644 index 000000000..ca7b1a191 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.component_hash @@ -0,0 +1 @@ +11c08f9e1a7d346b5dd763196dc2567cf2209ae49042402c2c2d296624601c14 \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.eil.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.eil.yml new file mode 100644 index 000000000..7cfd1fbf2 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.eil.yml @@ -0,0 +1,28 @@ +name: i2cdev +description: ESP-IDF I2C master thread-safe utilities +version: 2.0.8 +groups: + - common +code_owners: + - UncleRus +depends: + - driver + - freertos + - esp_idf_lib_helpers +thread_safe: yes +targets: + - esp32 + - esp8266 + - esp32s2 + - esp32c3 + - esp32s3 + - esp32c2 + - esp32c6 + - esp32h2 + - esp32p4 + - esp32c5 + - esp32c61 +license: MIT +copyrights: + - name: UncleRus + year: 2018 \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitignore b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitignore new file mode 100644 index 000000000..9cccbfb72 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitignore @@ -0,0 +1,7 @@ +examples/**/sdkconfig +examples/**/sdkconfig.old +examples/**/build/ +examples/**/dependencies.lock +docs/_*/ +docs/doxygen.log +*.swp diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitmodules b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitmodules new file mode 100644 index 000000000..a9554a22c --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = https://github.com/esp-idf-lib/common.git diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CHECKSUMS.json b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CHECKSUMS.json new file mode 100644 index 000000000..aded64b46 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CHECKSUMS.json @@ -0,0 +1 @@ +{"version": "1.0", "algorithm": "sha256", "created_at": "2025-07-31T11:59:22.902787+00:00", "files": [{"path": ".ackrc", "size": 19, "hash": "ad251fb2384460920327843ab53f696de85a385a179e9ff06f2dd496607a2f31"}, {"path": ".astylerc", "size": 324, "hash": "07a888d14b14e7d39e3e645c7f75addb9620ec9026248a5393baa63ef207556f"}, {"path": ".clang-format", "size": 1814, "hash": "b23e699f74909593d399c31f56d38e02c8a71c7dae0102813429e73520783101"}, {"path": ".eil.yml", "size": 399, "hash": "81bef46273987e32b13c2abbe0c0218b298825835c2445489910673776967a59"}, {"path": ".gitignore", "size": 129, "hash": "44cc4e80bc8c455013cbdbd2338b690b62da9ded5368d66f4a576401e0aaa189"}, {"path": ".gitmodules", "size": 85, "hash": "bdbdfe664e912bb32da537de8e7137eccce5869bbe030b254bd96d31891295e5"}, {"path": "CMakeLists.txt", "size": 1856, "hash": "fc8eb0fd7edaf7dfa3417693b0c34a623bc3494e47c405388cef5c56882c1657"}, {"path": "Kconfig", "size": 1962, "hash": "310886b17b2008a2d158efe166d3a63618761a26827da8c3a064fed131bce9a3"}, {"path": "Kconfig.i2c", "size": 848, "hash": "541dae0eb78e6309736d6e6f0d1c415c0881d65e7a6668e9135d4e0b55f56a89"}, {"path": "LICENSE", "size": 1110, "hash": "f54868b4773b62faa573ab1b4fef25bce6ed3eeadd251aa1e64cba4aa2989e8c"}, {"path": "README.md", "size": 1390, "hash": "168a0788b5190354bbe8878bd31f27fead4ee632a7293d97c7d1d0ee8505dab9"}, {"path": "component.mk", "size": 997, "hash": "49cbc0a3b20a663096a511c21cb66ec38f8d76ba58e47ce9c301e787a57f570a"}, {"path": "i2cdev.c", "size": 38491, "hash": "e36b5d30420542c90b770900f9bfc6333c693b811355c94b844e717e84364d23"}, {"path": "i2cdev.h", "size": 20460, "hash": "76bfed831af20b08f7d427fab591b1cda4357c2d20372d39e9049f5a6df0b371"}, {"path": "i2cdev_legacy.c", "size": 30385, "hash": "2e5c8ecf2460c1e89a73f553d45b47a25c626747a19f31ce2d828b005457af11"}, {"path": "idf_component.yml", "size": 691, "hash": "cb9bfc8a87a4057949284a24b9f35cc1d7ac420900f980bc3a8d6846b144639a"}, {"path": "bin/eil-q", "size": 399, "hash": "52bfaca6bfc34bba78c5707ed4013bac1839ef67ab4fa6feb8885b6face2c86a"}, {"path": "common/.git", "size": 31, "hash": "3c08a82d0d8b9fc7bb41dbf0d0836636c5b5e89a73243f77817467f7d1ffccbc"}, {"path": "examples/default/CMakeLists.txt", "size": 241, "hash": "e24ced9feffe63db786ede147dc76cf3efd6a9fcbdc49b964e8da02c9b72ab85"}, {"path": "examples/default/Makefile", "size": 74, "hash": "6264f313c2f50e2389a6098ee3be3bdeaf9cd7869d430cc665b666a67812a81a"}, {"path": "examples/default/README.md", "size": 1122, "hash": "1948009bf2f95f8fae896c19c07ef8c37ea2ac5c31274e1294c0efc732d724c7"}, {"path": "examples/default/main/CMakeLists.txt", "size": 75, "hash": "27d6d39ef0cb6a9097984b41e080b09f7ff972339a0bb4ddf771db4001cb9782"}, {"path": "examples/default/main/Kconfig.projbuild", "size": 170, "hash": "ed0ad26fe91667f0938b979c958690492f49afbf74fdcecf2ac86c04120e4018"}, {"path": "examples/default/main/component.mk", "size": 39, "hash": "532e7836f005fd3b10f1955409e4956ad69fd386e80b12de11d96f8e84977843"}, {"path": "examples/default/main/idf_component.yml", "size": 141, "hash": "aa7904c346077651a3fdf34f8806125f057a443bb0154776963b3aae11b81882"}, {"path": "examples/default/main/main.c", "size": 1116, "hash": "ff14517c06a94dbe15832ea00b0f475e798e790a5931247a26cdd7048c1d1f40"}, {"path": "common/cmake/esp-idf-lib.cmake", "size": 1119, "hash": "ea0f8a819ac721dfbf5ab5f109c75c32c90c8060e6fcc9fbad1ce9de29451405"}]} \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CMakeLists.txt new file mode 100644 index 000000000..f98fc708d --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/CMakeLists.txt @@ -0,0 +1,45 @@ +# ESP-IDF CMake component for i2cdev library +set(req driver freertos esp_idf_lib_helpers) + +# ESP-IDF version detection for automatic driver selection +# Check for manual override via Kconfig +if(CONFIG_I2CDEV_USE_LEGACY_DRIVER) + set(USE_LEGACY_DRIVER TRUE) + message(STATUS "i2cdev: Manual override - using legacy driver (CONFIG_I2CDEV_USE_LEGACY_DRIVER=y)") +elseif(NOT DEFINED IDF_VERSION_MAJOR) + # In case older ESP-IDF versions that don't define IDF_VERSION_MAJOR + set(USE_LEGACY_DRIVER TRUE) + message(STATUS "i2cdev: IDF_VERSION_MAJOR not defined, using legacy driver") +elseif(IDF_VERSION_MAJOR LESS 5) + set(USE_LEGACY_DRIVER TRUE) + message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.x detected, using legacy driver") +elseif(IDF_VERSION_MAJOR EQUAL 5 AND IDF_VERSION_MINOR LESS 3) + set(USE_LEGACY_DRIVER TRUE) + message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR} detected, using legacy driver") +else() + set(USE_LEGACY_DRIVER FALSE) + message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR} detected, using new i2c_master driver") +endif() + +# Conditionally set the source file based on version detection or Kconfig override +if(USE_LEGACY_DRIVER) + set(SRCS "i2cdev_legacy.c") + message(STATUS "i2cdev: Compiling with legacy I2C driver (i2cdev_legacy.c)") +else() + set(SRCS "i2cdev.c") + message(STATUS "i2cdev: Compiling with new I2C master driver (i2cdev.c)") +endif() + +# Register the component +idf_component_register(SRCS ${SRCS} + INCLUDE_DIRS "." + REQUIRES ${req}) + + +# include common cmake file for components +set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake) +if(EXISTS ${ESP_IDF_LIB_CMAKE}) + include(${ESP_IDF_LIB_CMAKE}) +else() + message(WARNING "${ESP_IDF_LIB_CMAKE} not found") +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig new file mode 100644 index 000000000..74aa96700 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig @@ -0,0 +1,65 @@ +menu "I2C Device Library" + +config I2CDEV_USE_LEGACY_DRIVER + bool "Use Legacy I2C Driver API" + default n + help + Select this option to use the older ESP-IDF I2C driver API (driver/i2c.h) + instead of the newer driver API (driver/i2c_master.h). + + This is automatically determined by the build system based on your ESP-IDF version. + For ESP-IDF versions prior to v5.3, the legacy driver will be used automatically. + You can manually override this setting if needed. + +config I2CDEV_AUTO_ENABLE_PULLUPS + bool "Automatically enable internal I2C pullups when not configured" + default n + depends on !IDF_TARGET_ESP8266 + help + When enabled, internal pullup resistors are automatically enabled + when both sda_pullup_en and scl_pullup_en are false (default state). + + Useful for development and prototyping. Disable for production + systems with external pullups to avoid interference. + + Considerations: + - May increase power consumption slightly + - Could interfere with carefully tuned external pullups + - Not recommended for battery-powered applications + + Note: This option only affects the modern i2cdev driver (ESP32 family). + Legacy driver behavior is unchanged for compatibility. + +config I2CDEV_DEFAULT_SDA_PIN + int "Default I2C SDA pin" + default 21 + help + Default SDA pin for I2C devices. + +config I2CDEV_DEFAULT_SCL_PIN + int "Default I2C SCL pin" + default 22 + help + Default SCL pin for I2C devices. + +config I2CDEV_MAX_DEVICES_PER_PORT + int "Maximum number of devices per I2C port" + default 8 + help + Maximum number of devices that can be registered on a single I2C port. + +config I2CDEV_TIMEOUT + int "I2C transaction timeout, milliseconds" + default 1000 + range 10 5000 + +config I2CDEV_NOLOCK + bool "Disable the use of mutexes" + default n + help + Attention! After enabling this option, all I2C device + drivers will become non-thread safe. + Use this option if you need to access your I2C devices + from interrupt handlers. + +endmenu \ No newline at end of file diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig.i2c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig.i2c new file mode 100644 index 000000000..29d0ac2d7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/Kconfig.i2c @@ -0,0 +1,19 @@ +config EXAMPLE_I2C_MASTER_SCL + int "SCL GPIO Number" + default 5 if IDF_TARGET_ESP8266 + default 6 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61 + default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 4 if IDF_TARGET_ESP32H2 + default 4 if IDF_TARGET_ESP32P4 + help + GPIO number for I2C Master clock line. + +config EXAMPLE_I2C_MASTER_SDA + int "SDA GPIO Number" + default 4 if IDF_TARGET_ESP8266 + default 5 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61 + default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 3 if IDF_TARGET_ESP32H2 + default 3 if IDF_TARGET_ESP32P4 + help + GPIO number for I2C Master data line. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/LICENSE b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/LICENSE new file mode 100644 index 000000000..d54667368 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Ruslan V. Uss (https://github.com/UncleRus) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/README.md new file mode 100644 index 000000000..61d46a762 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/README.md @@ -0,0 +1,30 @@ +# esp-idf-lib/i2cdev + +[![Build examples](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build.yml) +[![Build docs](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build-docs.yml) +[![Validation](https://github.com/esp-idf-lib/i2cdev/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//validate-component.yml) + +ESP-IDF I2C master thread-safe utilities. + +* [Documentation](https://esp-idf-lib.github.io/i2cdev/) +* [Repository](https://github.com/esp-idf-lib/i2cdev) +* [Issues](https://github.com/esp-idf-lib/i2cdev/issues) +* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions) +* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/i2cdev) + +## Installation + +```sh +idf.py add-dependency esp-idf-lib/i2cdev +``` + +## Support + +For questions and discussions about the component, please use +[Discussions](https://github.com/esp-idf-lib/core/discussions) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). + +## Contributing + +Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md) +at [esp-idf-lib/core](https://github.com/esp-idf-lib/core). diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/bin/eil-q b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/bin/eil-q new file mode 100644 index 000000000..870625afb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/bin/eil-q @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require "pathname" +require "yaml" + +# A simple CLI to get values in .eil.yml + +key = ARGV.shift +project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent +eil_file = project_root / ".eil.yml" +doc = YAML.safe_load(File.read eil_file) + +case key +when "copyright_string" + puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ") +else + puts doc[key] +end diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/common/cmake/esp-idf-lib.cmake b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/common/cmake/esp-idf-lib.cmake new file mode 100644 index 000000000..33ff7347f --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/common/cmake/esp-idf-lib.cmake @@ -0,0 +1,36 @@ +# Set common build flags but enable them only when the build is in our CI, +# making them optional. The idea is, fail when compiled in our CI but just +# warn in any other cases. Code that compiles with one toolchain warning-free +# may not do so with another toolchain, which creates a project dependency on +# specific toolchain vendors and versions. +# +# Define flags that may cause failures here. +if (DEFINED ENV{ESP_IDF_LIB_CI}) + set(ESP_IDF_LIB_CI_FLAGS + -Werror=unused-variable + -Werror=unused-function + -Werror=write-strings + -Werror + ) +endif() + +# Set common build flags. Mandatory. +# +# Define flags that do not cause failures here. +set(ESP_IDF_LIB_FLAGS + -Wextra + -Wwrite-strings + -Wunused-variable + -Wunused-function + -Wreturn-type +) + +# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not +# set the flags. +get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE) +if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY") + target_compile_options(${COMPONENT_LIB} PRIVATE + ${ESP_IDF_LIB_FLAGS} + ${ESP_IDF_LIB_CI_FLAGS} + ) +endif() diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/component.mk new file mode 100644 index 000000000..2f812ff78 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/component.mk @@ -0,0 +1,29 @@ +COMPONENT_ADD_INCLUDEDIRS = . + +ifdef CONFIG_IDF_TARGET_ESP8266 +COMPONENT_DEPENDS = esp8266 freertos esp_idf_lib_helpers +# ESP8266 RTOS SDK auto-detects all .c files, so use COMPONENT_OBJS to override +# This prevents both i2cdev.c and i2cdev_legacy.c from being compiled +COMPONENT_OBJS := i2cdev_legacy.o +COMPONENT_SRCDIRS := . +else +COMPONENT_DEPENDS = driver freertos esp_idf_lib_helpers +# For ESP32 family, check for manual override first +ifdef CONFIG_I2CDEV_USE_LEGACY_DRIVER +COMPONENT_SRCS = i2cdev_legacy.c +else +# Check if version variables are available, fallback to legacy if not +ifdef IDF_VERSION_MAJOR +ifeq ($(shell test $(IDF_VERSION_MAJOR) -lt 5 && echo 1),1) +COMPONENT_SRCS = i2cdev_legacy.c +else ifeq ($(shell test $(IDF_VERSION_MAJOR) -eq 5 -a $(IDF_VERSION_MINOR) -lt 3 && echo 1),1) +COMPONENT_SRCS = i2cdev_legacy.c +else +COMPONENT_SRCS = i2cdev.c +endif +else +# Version variables not available - fallback to legacy driver for safety +COMPONENT_SRCS = i2cdev_legacy.c +endif +endif +endif diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/CMakeLists.txt new file mode 100644 index 000000000..a3755d2a7 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/CMakeLists.txt @@ -0,0 +1,7 @@ +# 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.5) + + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2c_scanner) diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/Makefile b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/Makefile new file mode 100644 index 000000000..2bb2b90cb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/Makefile @@ -0,0 +1,5 @@ +#V := 1 +PROJECT_NAME := i2c_scanner + + +include $(IDF_PATH)/make/project.mk diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/README.md b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/README.md new file mode 100644 index 000000000..7cc21bfa2 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/README.md @@ -0,0 +1,31 @@ +# I2C bus scanner + +## What it does + +This example scans the i2c bus in a loop and prints out a table with the addresses of the found i2c devices. + +## Wiring + +Connect `SCL` and `SDA` pins to the following pins with appropriate pull-up +resistors. + +| Name | Description | Defaults | +|------|-------------|----------| +| `CONFIG_EXAMPLE_I2C_MASTER_SCL` | GPIO number for `SCL` | "5" for `esp8266`, "6" for `esp32c3`, "19" for `esp32`, `esp32s2`, and `esp32s3` | +| `CONFIG_EXAMPLE_I2C_MASTER_SDA` | GPIO number for `SDA` | "4" for `esp8266`, "5" for `esp32c3`, "18" for `esp32`, `esp32s2`, and `esp32s3` | + +## Example output + +Three devices found on a bus: 0x38, 0x60 and 0x77 + +``` + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- 77 +``` diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/CMakeLists.txt b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/CMakeLists.txt new file mode 100644 index 000000000..cf2c455cb --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/Kconfig.projbuild b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/Kconfig.projbuild new file mode 100644 index 000000000..6f5494053 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/Kconfig.projbuild @@ -0,0 +1,7 @@ +menu "I2C scanner configuration" + config EXAMPLE_I2C_CLOCK_HZ + int "I2C clock frequency, Hz" + default 100000 + + rsource "../../../Kconfig.i2c" +endmenu diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/component.mk b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/component.mk new file mode 100644 index 000000000..7700ea99b --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . include/ diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/idf_component.yml new file mode 100644 index 000000000..55cf9a315 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/idf_component.yml @@ -0,0 +1,7 @@ +dependencies: + esp-idf-lib/esp_idf_lib_helpers: + version: '*' + esp-idf-lib/i2cdev: + version: '*' +description: default +version: 1.0.0 diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/main.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/main.c new file mode 100644 index 000000000..cc7c85aba --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/examples/default/main/main.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +void task(void *ignore) +{ + i2c_dev_t dev = { 0 }; + dev.cfg.sda_io_num = CONFIG_EXAMPLE_I2C_MASTER_SDA; + dev.cfg.scl_io_num = CONFIG_EXAMPLE_I2C_MASTER_SCL; +#if HELPER_TARGET_IS_ESP32 + dev.cfg.master.clk_speed = CONFIG_EXAMPLE_I2C_CLOCK_HZ; // 100kHz +#endif + while (1) + { + esp_err_t res; + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + printf("00: "); + for (uint8_t addr = 3; addr < 0x78; addr++) + { + if (addr % 16 == 0) + printf("\n%.2x:", addr); + + dev.addr = addr; + res = i2c_dev_probe(&dev, I2C_DEV_WRITE); + + if (res == 0) + printf(" %.2x", addr); + else + printf(" --"); + } + printf("\n\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + +void app_main() +{ + // Init i2cdev library + ESP_ERROR_CHECK(i2cdev_init()); + // Start task + xTaskCreate(task, "i2c_scanner", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL); +} diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.c new file mode 100644 index 000000000..b690b17df --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.c @@ -0,0 +1,897 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Ruslan V. Uss + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file i2cdev.c + * + * ESP-IDF I2C master thread-safe functions for communication with I2C slave + * + * Copyright (C) 2018 Ruslan V. Uss + * Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API + * + * MIT Licensed as described in the file LICENSE + */ + +#include "i2cdev.h" +#include +#include +#include +#include +#include +#include + +static const char *TAG = "i2cdev"; + +// Fallback definition for platforms without 10-bit address support +#ifndef I2C_ADDR_BIT_LEN_10 +#define I2C_ADDR_BIT_LEN_10 1 +#endif + +#define I2C_DEFAULT_FREQ_HZ 400000 +#define I2C_MAX_RETRIES 3 +#define I2C_RETRY_BASE_DELAY_MS 20 +#define I2CDEV_MAX_STACK_ALLOC_SIZE 32 // Stack allocation threshold to avoid heap fragmentation for small buffers + +typedef struct +{ + SemaphoreHandle_t lock; // Mutex for exclusive access to this port's state + i2c_master_bus_handle_t bus_handle; // Handle to the initialized I2C master bus + bool installed; // Flag indicating if the bus for this port has been installed + uint32_t ref_count; // Number of devices currently active on this bus port + int sda_pin_current; // Actual SDA pin the bus was initialized with + int scl_pin_current; // Actual SCL pin the bus was initialized with +} i2c_port_state_t; + +static i2c_port_state_t i2c_ports[I2C_NUM_MAX] = { 0 }; +static i2c_dev_t *active_devices[I2C_NUM_MAX][CONFIG_I2CDEV_MAX_DEVICES_PER_PORT] = { { NULL } }; + +// Helper to register a device +static esp_err_t register_device(i2c_dev_t *dev) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + int port = dev->port; + if (port >= I2C_NUM_MAX) + return ESP_ERR_INVALID_ARG; + + // Note: Port mutex should be held by caller + for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++) + { + if (active_devices[port][i] == NULL) + { + active_devices[port][i] = dev; + ESP_LOGV(TAG, "[0x%02x at %d] Registered device in slot %d", dev->addr, port, i); + return ESP_OK; + } + } + ESP_LOGE(TAG, "[0x%02x at %d] No free slots to register device - limit reached", dev->addr, port); + return ESP_ERR_NO_MEM; +} + +// Helper to deregister a device +static void deregister_device(i2c_dev_t *dev) +{ + if (!dev) + return; + int port = dev->port; + if (port >= I2C_NUM_MAX) + return; + for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++) + { + if (active_devices[port][i] == dev) + { + active_devices[port][i] = NULL; + ESP_LOGV(TAG, "[0x%02x at %d] Deregistered device from slot %d", dev->addr, port, i); + return; + } + } +} + +esp_err_t i2cdev_init(void) +{ + ESP_LOGV(TAG, "Initializing I2C subsystem..."); + memset(active_devices, 0, sizeof(active_devices)); + for (int i = 0; i < I2C_NUM_MAX; i++) + { + if (!i2c_ports[i].lock) + { + i2c_ports[i].lock = xSemaphoreCreateMutex(); + if (!i2c_ports[i].lock) + { + ESP_LOGE(TAG, "Could not create port mutex %d", i); + return ESP_ERR_NO_MEM; + } + ESP_LOGV(TAG, "Created port mutex %d", i); + } + i2c_ports[i].installed = false; + i2c_ports[i].ref_count = 0; + i2c_ports[i].bus_handle = NULL; + i2c_ports[i].sda_pin_current = -1; + i2c_ports[i].scl_pin_current = -1; + } + ESP_LOGV(TAG, "I2C subsystem initialized."); + return ESP_OK; +} + +esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Creating device mutex...", dev->addr, dev->port); + if (dev->mutex) + { + ESP_LOGW(TAG, "[0x%02x at %d] device mutex already exists (Handle: %p)", dev->addr, dev->port, dev->mutex); + return ESP_OK; // Already created + } + + dev->mutex = xSemaphoreCreateMutex(); + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not create device mutex", dev->addr, dev->port); + return ESP_ERR_NO_MEM; // Use ESP_ERR_NO_MEM for memory allocation failures + } + + ESP_LOGV(TAG, "[0x%02x at %d] Device mutex created (Handle: %p)", dev->addr, dev->port, dev->mutex); + + // Register the device for cleanup tracking (under port mutex for consistency) + if (dev->port < I2C_NUM_MAX && i2c_ports[dev->port].lock) + { + if (xSemaphoreTake(i2c_ports[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE) + { + esp_err_t reg_res = register_device(dev); + if (reg_res != ESP_OK) + { + ESP_LOGW(TAG, "[0x%02x at %d] Failed to register device: %s - device will work but cleanup tracking disabled", dev->addr, dev->port, esp_err_to_name(reg_res)); + // Continue - device can still function without registration tracking + } + else + { + ESP_LOGV(TAG, "[0x%02x at %d] Device registered successfully for cleanup tracking", dev->addr, dev->port); + } + xSemaphoreGive(i2c_ports[dev->port].lock); + } + else + { + ESP_LOGW(TAG, "[0x%02x at %d] Could not take port mutex for device registration", dev->addr, dev->port); + // Continue - device can still function without registration tracking + } + } + + // Set default address bit length if not explicitly set + if (dev->addr_bit_len != I2C_ADDR_BIT_LEN_7 && dev->addr_bit_len != I2C_ADDR_BIT_LEN_10) + { + ESP_LOGV(TAG, "[0x%02x at %d] Setting default 7-bit address format", dev->addr, dev->port); + dev->addr_bit_len = I2C_ADDR_BIT_LEN_7; + } +#else + ESP_LOGV(TAG, "[0x%02x at %d] Mutex creation skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port); +#endif + return ESP_OK; +} + +esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Deleting device mutex and cleaning up resources", dev->addr, dev->port); + + // Remove device from bus if handle exists + if (dev->dev_handle) + { + ESP_LOGV(TAG, "[0x%02x at %d] Removing device handle %p from bus", dev->addr, dev->port, dev->dev_handle); + esp_err_t rm_res = i2c_master_bus_rm_device((i2c_master_dev_handle_t)dev->dev_handle); + if (rm_res != ESP_OK) + { + ESP_LOGW(TAG, "[0x%02x at %d] Failed to remove device handle: %s", dev->addr, dev->port, esp_err_to_name(rm_res)); + // Continue with cleanup despite error + } + dev->dev_handle = NULL; + } + + // Deregister the device + deregister_device(dev); + + // Update port reference count if port is valid + if (dev->port < I2C_NUM_MAX) + { + if (xSemaphoreTake(i2c_ports[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE) + { + if (i2c_ports[dev->port].installed && i2c_ports[dev->port].ref_count > 0) + { + i2c_ports[dev->port].ref_count--; + ESP_LOGV(TAG, "[Port %d] Decremented ref_count to %" PRIu32, dev->port, i2c_ports[dev->port].ref_count); + + // If last device on this port, delete the bus + if (i2c_ports[dev->port].ref_count == 0) + { + ESP_LOGI(TAG, "[Port %d] Last device removed, cleaning up THIS port's bus", dev->port); + // Just clean up this port's bus + if (i2c_ports[dev->port].bus_handle) + { + ESP_LOGI(TAG, "[Port %d] Deleting bus handle %p", dev->port, i2c_ports[dev->port].bus_handle); + esp_err_t del_bus_res = i2c_del_master_bus(i2c_ports[dev->port].bus_handle); + if (del_bus_res != ESP_OK) + { + ESP_LOGE(TAG, "[Port %d] Failed to delete master bus: %s", dev->port, esp_err_to_name(del_bus_res)); + } + i2c_ports[dev->port].bus_handle = NULL; + } + i2c_ports[dev->port].installed = false; + i2c_ports[dev->port].sda_pin_current = -1; + i2c_ports[dev->port].scl_pin_current = -1; + } + } + xSemaphoreGive(i2c_ports[dev->port].lock); + } + else + { + ESP_LOGW(TAG, "[0x%02x at %d] Could not take port mutex for ref_count update", dev->addr, dev->port); + } + } + + // Delete the mutex itself last + if (dev->mutex) + { + vSemaphoreDelete(dev->mutex); + dev->mutex = NULL; + } + else + { + ESP_LOGV(TAG, "[0x%02x at %d] Device mutex was NULL, nothing to delete", dev->addr, dev->port); + } +#endif + return ESP_OK; +} + +esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Attempting to take device mutex (Handle: %p)...", dev->addr, dev->port, dev->mutex); + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Attempt to take NULL device mutex!", dev->addr, dev->port); + return ESP_ERR_INVALID_STATE; // Mutex doesn't exist + } + + TickType_t timeout_ticks = pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT); + ESP_LOGV(TAG, "[0x%02x at %d] Taking device mutex with timeout %d ms (%lu ticks)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT, (unsigned long)timeout_ticks); + if (!xSemaphoreTake(dev->mutex, timeout_ticks)) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take device mutex (Timeout after %d ms)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT); + return ESP_ERR_TIMEOUT; + } + ESP_LOGV(TAG, "[0x%02x at %d] Device mutex taken successfully.", dev->addr, dev->port); +#else + ESP_LOGV(TAG, "[0x%02x at %d] Mutex take skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port); +#endif + return ESP_OK; +} + +esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Giving device mutex (Handle: %p)...", dev->addr, dev->port, dev->mutex); + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Attempt to give NULL device mutex!", dev->addr, dev->port); + return ESP_ERR_INVALID_STATE; + } + + if (!xSemaphoreGive(dev->mutex)) + { + // This case should ideally not happen if the mutex was taken correctly + ESP_LOGE(TAG, "[0x%02x at %d] Could not give device mutex (Was it taken?) (Handle: %p)", dev->addr, dev->port, dev->mutex); + return ESP_FAIL; + } + ESP_LOGV(TAG, "[0x%02x at %d] Device mutex given successfully.", dev->addr, dev->port); +#else + ESP_LOGV(TAG, "[0x%02x at %d] Mutex give skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port); +#endif + return ESP_OK; +} + +// i2c_setup_port: Initializes the I2C master bus for a given port if not already done. +// It uses pin configurations from dev->cfg.sda_io_num and dev->cfg.scl_io_num. +// The pins for a port are fixed after the first device initializes it. +static esp_err_t i2c_setup_port(i2c_dev_t *dev) // dev is non-const to update dev->sda_pin, dev->scl_pin +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + if (dev->port >= I2C_NUM_MAX) + { + ESP_LOGE(TAG, "Invalid I2C port number: %d", dev->port); + return ESP_ERR_INVALID_ARG; + } + + esp_err_t res = ESP_OK; + i2c_port_state_t *port_state = &i2c_ports[dev->port]; + + ESP_LOGV(TAG, "[Port %d] Setup request for device 0x%02x", dev->port, dev->addr); + if (xSemaphoreTake(port_state->lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) + { + ESP_LOGE(TAG, "[Port %d] Could not take port mutex for setup", dev->port); + return ESP_ERR_TIMEOUT; + } + + if (!port_state->installed) + { + // Pin Selection Logic: Use device-specified pins, fallback to Kconfig defaults if -1 + gpio_num_t sda_pin = (dev->cfg.sda_io_num == (gpio_num_t) -1) ? (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SDA_PIN : dev->cfg.sda_io_num; + gpio_num_t scl_pin = (dev->cfg.scl_io_num == (gpio_num_t) -1) ? (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SCL_PIN : dev->cfg.scl_io_num; + + // Validate pins (basic check, gpio_is_valid_gpio could be used for more robust check) + if (sda_pin < 0 || scl_pin < 0) + { + ESP_LOGE(TAG, "[Port %d] Invalid SCL/SDA pins: SDA=%d, SCL=%d. Check driver or Kconfig defaults.", dev->port, sda_pin, scl_pin); + xSemaphoreGive(port_state->lock); + return ESP_ERR_INVALID_ARG; + } + + /* + * OPTIONAL I2C PULLUP AUTO-CONFIGURATION + * + * By default: Uses whatever sda_pullup_en/scl_pullup_en you set (usually false) + * + * When CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y: If both pullup flags are false, + * automatically change them to true to enable internal pullups (~45kΩ). + * + * Manual pullup configuration: + * - Set sda_pullup_en=true, scl_pullup_en=true for internal pullups + * - Set sda_pullup_en=false, scl_pullup_en=false for external pullups + */ + + // Read user's pullup configuration (default false if not set) + bool sda_pullup = dev->cfg.sda_pullup_en; + bool scl_pullup = dev->cfg.scl_pullup_en; + +#if CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS + // CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y: If user didn't configure pullups, enable them automatically + if (!sda_pullup && !scl_pullup) + { + sda_pullup = true; + scl_pullup = true; + ESP_LOGI(TAG, "[Port %d] Auto-enabling internal pullups (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y)", dev->port); + } +#endif + + ESP_LOGI(TAG, + "[Port %d] First initialization. Configuring bus with SDA=%d, SCL=%d (Pullups " + "SCL:%d SDA:%d)", + dev->port, sda_pin, scl_pin, scl_pullup, sda_pullup); + + i2c_master_bus_config_t bus_config = + { + .i2c_port = dev->port, + .sda_io_num = sda_pin, + .scl_io_num = scl_pin, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 7, + .flags.enable_internal_pullup = (sda_pullup || scl_pullup), + // Bus speed is not set here. It's per-device or a global target for the bus can be set + // if desired, but i2c_master supports per-device speeds. + }; + + res = i2c_new_master_bus(&bus_config, &port_state->bus_handle); + if (res == ESP_OK) + { + port_state->installed = true; + port_state->ref_count = 0; // Will be incremented when a device is successfully added + port_state->sda_pin_current = sda_pin; + port_state->scl_pin_current = scl_pin; + dev->sda_pin = sda_pin; // Update dev struct with actual pins used + dev->scl_pin = scl_pin; + ESP_LOGI(TAG, "[Port %d] Successfully installed I2C master bus (Handle: %p).", dev->port, port_state->bus_handle); + } + else + { + ESP_LOGE(TAG, "[Port %d] Failed to create master bus: %d (%s)", dev->port, res, esp_err_to_name(res)); + port_state->installed = false; + port_state->bus_handle = NULL; + port_state->sda_pin_current = -1; + port_state->scl_pin_current = -1; + } + } + else + { + ESP_LOGV(TAG, "[Port %d] Port already installed (SDA=%d, SCL=%d, Handle: %p).", dev->port, port_state->sda_pin_current, port_state->scl_pin_current, port_state->bus_handle); + // Pin Consistency Check: For subsequent devices, ensure pins match already-configured bus + gpio_num_t sda_desired = (dev->cfg.sda_io_num == (gpio_num_t) -1) ? (gpio_num_t)port_state->sda_pin_current : dev->cfg.sda_io_num; + gpio_num_t scl_desired = (dev->cfg.scl_io_num == (gpio_num_t) -1) ? (gpio_num_t)port_state->scl_pin_current : dev->cfg.scl_io_num; + + if (sda_desired != port_state->sda_pin_current || scl_desired != port_state->scl_pin_current) + { + ESP_LOGE(TAG, + "[Port %d] Pin mismatch for device 0x%02x! Bus on SDA=%d,SCL=%d. Device wants " + "SDA=%d,SCL=%d", + dev->port, dev->addr, port_state->sda_pin_current, port_state->scl_pin_current, sda_desired, scl_desired); + res = ESP_ERR_INVALID_STATE; // Cannot change pins for an installed bus + } + else + { + dev->sda_pin = port_state->sda_pin_current; // Update dev struct with actual pins used + dev->scl_pin = port_state->scl_pin_current; + } + // ref_count is managed by i2c_setup_device when adding/removing device handles + } + + xSemaphoreGive(port_state->lock); + ESP_LOGV(TAG, "[Port %d] Port setup finished with res %d.", dev->port, res); + return res; +} + +// i2c_setup_device: Ensures port is set up and adds the device to the bus if not already added. +// It also registers the device in active_devices for cleanup purposes. +static esp_err_t i2c_setup_device(i2c_dev_t *dev) // dev is non-const - modifies dev->dev_handle, dev->addr_bit_len +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Setting up device context...", dev->addr, dev->port); + + esp_err_t res = i2c_setup_port(dev); + if (res != ESP_OK) + { + ESP_LOGE(TAG, "[0x%02x at %d] Port setup failed during device setup: %d (%s)", dev->addr, dev->port, res, esp_err_to_name(res)); + return res; + } + + // If addr_bit_len is not set (e.g. 0, which is invalid for i2c_addr_bit_len_t enum), default to + // 7-bit. Modified to conditionally check for I2C_ADDR_BIT_LEN_10 based on hardware support + if (dev->addr_bit_len != I2C_ADDR_BIT_LEN_7 +#if SOC_I2C_SUPPORT_10BIT_ADDR + && dev->addr_bit_len != I2C_ADDR_BIT_LEN_10 +#endif + ) + { + ESP_LOGD(TAG, "[0x%02x at %d] addr_bit_len not explicitly set, defaulting to 7-bit.", dev->addr, dev->port); + dev->addr_bit_len = I2C_ADDR_BIT_LEN_7; + } + + // Only warn about address size if the device is actually using 10-bit addressing + if (dev->addr_bit_len == I2C_ADDR_BIT_LEN_7 && dev->addr > 0x7F) + { + ESP_LOGW(TAG, + "[0x%02x at %d] Device address > 0x7F but addr_bit_len is 7-bit. Ensure address " + "is correct.", + dev->addr, dev->port); + } + +#if !defined(SOC_I2C_SUPPORT_10BIT_ADDR) || !SOC_I2C_SUPPORT_10BIT_ADDR + // On platforms without 10-bit support, force 7-bit addressing regardless of user setting + if (dev->addr_bit_len == I2C_ADDR_BIT_LEN_10) + { + ESP_LOGW(TAG, "[0x%02x at %d] 10-bit addressing not supported on this platform, forcing 7-bit mode", dev->addr, dev->port); + dev->addr_bit_len = I2C_ADDR_BIT_LEN_7; + } +#endif + + if (dev->dev_handle == NULL) + { + i2c_port_state_t *port_state = &i2c_ports[dev->port]; + if (xSemaphoreTake(port_state->lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for device add", dev->addr, dev->port); + return ESP_ERR_TIMEOUT; + } + + if (!port_state->installed || !port_state->bus_handle) + { + ESP_LOGE(TAG, "[0x%02x at %d] Cannot add device, bus for port %d not ready!", dev->addr, dev->port, dev->port); + xSemaphoreGive(port_state->lock); + return ESP_ERR_INVALID_STATE; + } + + ESP_LOGV(TAG, "[0x%02x at %d] Adding device to bus (Bus Handle: %p)...", dev->addr, dev->port, port_state->bus_handle); + + uint32_t effective_dev_speed = dev->cfg.master.clk_speed; + if (effective_dev_speed == 0) + { + ESP_LOGW(TAG, + "[0x%02x at %d] Device speed (dev->cfg.master.clk_speed) is 0, using default: " + "%" PRIu32 " Hz", + dev->addr, dev->port, (uint32_t)I2C_DEFAULT_FREQ_HZ); + effective_dev_speed = I2C_DEFAULT_FREQ_HZ; + } + + i2c_device_config_t dev_config = + { + // Use the possibly modified addr_bit_len that respects hardware capabilities + .dev_addr_length = dev->addr_bit_len, + .device_address = dev->addr, + .scl_speed_hz = effective_dev_speed, + .flags.disable_ack_check = false, + }; + + res = i2c_master_bus_add_device(port_state->bus_handle, &dev_config, (i2c_master_dev_handle_t *)&dev->dev_handle); + if (res == ESP_OK) + { + ESP_LOGI(TAG, "[0x%02x at %d] Device added successfully (Device Handle: %p, Speed: %" PRIu32 " Hz).", dev->addr, dev->port, dev->dev_handle, effective_dev_speed); + + // Increment the port reference count for each device successfully added + port_state->ref_count++; + ESP_LOGV(TAG, "[Port %d] Incremented ref_count to %" PRIu32, dev->port, port_state->ref_count); + } + else + { + ESP_LOGE(TAG, "[0x%02x at %d] Failed to add device to bus: %d (%s)", dev->addr, dev->port, res, esp_err_to_name(res)); + dev->dev_handle = NULL; + } + xSemaphoreGive(port_state->lock); + } + else + { + ESP_LOGV(TAG, "[0x%02x at %d] Device handle %p already exists. Skipping add.", dev->addr, dev->port, dev->dev_handle); + res = ESP_OK; + } + + ESP_LOGV(TAG, "[0x%02x at %d] Device context setup finished with res %d.", dev->addr, dev->port, res); + return res; +} + +// Helper function with retry mechanism for I2C operations +static esp_err_t i2c_do_operation_with_retry(i2c_dev_t *dev, esp_err_t (*i2c_func)(i2c_master_dev_handle_t, const void *, size_t, void *, size_t, int), const void *write_buffer, size_t write_size, + void *read_buffer, size_t read_size) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + esp_err_t res = ESP_FAIL; + int retry = 0; + int timeout_ms = CONFIG_I2CDEV_TIMEOUT; + + ESP_LOGV(TAG, "[0x%02x at %d] Performing I2C operation (timeout %d ms)...", dev->addr, dev->port, timeout_ms); + + while (retry <= I2C_MAX_RETRIES) + { + // Ensure device is set up before each attempt, in case handle became stale or bus was reset + // This is more robust if issues like bus errors or device resets occur. + res = i2c_setup_device(dev); + if (res != ESP_OK) + { + ESP_LOGE(TAG, "[0x%02x at %d] Device setup failed (Try %d): %d (%s). Retrying setup...", dev->addr, dev->port, retry, res, esp_err_to_name(res)); + // No point continuing this attempt if setup fails, but the loop will retry setup. + vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << (retry)))); + retry++; + continue; + } + if (!dev->dev_handle) + { + ESP_LOGE(TAG, + "[0x%02x at %d] Device handle is NULL after setup (Try %d)! Cannot perform " + "operation.", + dev->addr, dev->port, retry); + // This indicates a persistent problem with adding the device to the bus. + // No point retrying the i2c_func if handle is null. + res = ESP_ERR_INVALID_STATE; + vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << (retry)))); + retry++; + continue; + } + + ESP_LOGV(TAG, "[0x%02x at %d] Attempting I2C op (Try %d, Handle %p)", dev->addr, dev->port, retry, dev->dev_handle); + res = i2c_func(dev->dev_handle, write_buffer, write_size, read_buffer, read_size, timeout_ms); + + if (res == ESP_OK) + { + ESP_LOGV(TAG, "[0x%02x at %d] I2C operation successful (Try %d).", dev->addr, dev->port, retry); + return ESP_OK; + } + + ESP_LOGW(TAG, "[0x%02x at %d] I2C op failed (Try %d, Handle %p): %d (%s).", dev->addr, dev->port, retry, dev->dev_handle, res, esp_err_to_name(res)); + + // Only remove handle on errors that indicate handle corruption or permanent invalidity + // Don't remove on temporary errors like ESP_ERR_TIMEOUT, ESP_FAIL (NACK), etc. + bool should_remove_handle = false; + switch (res) + { + case ESP_ERR_INVALID_ARG: + // Handle was likely removed by another task or is corrupted + should_remove_handle = true; + ESP_LOGW(TAG, "[0x%02x at %d] Invalid argument error - handle may be corrupted", dev->addr, dev->port); + break; + case ESP_ERR_INVALID_STATE: + // I2C driver is in invalid state, handle likely needs recreation + should_remove_handle = true; + ESP_LOGW(TAG, "[0x%02x at %d] Invalid state error - handle may need recreation", dev->addr, dev->port); + break; + default: + // For other errors (timeout, NACK, bus busy, etc.), keep the handle + // These are usually temporary and don't require handle recreation + should_remove_handle = false; + ESP_LOGV(TAG, "[0x%02x at %d] Temporary error - keeping handle for retry", dev->addr, dev->port); + break; + } + + if (should_remove_handle && dev->dev_handle) + { + ESP_LOGW(TAG, "[0x%02x at %d] Removing potentially corrupted device handle %p after permanent error", dev->addr, dev->port, dev->dev_handle); + // Try to remove the handle from the bus before nullifying + esp_err_t rm_res = i2c_master_bus_rm_device(dev->dev_handle); + if (rm_res != ESP_OK) + { + ESP_LOGW(TAG, "[0x%02x at %d] Failed to remove corrupted handle (expected): %s", dev->addr, dev->port, esp_err_to_name(rm_res)); + // This is expected if the handle was already invalid - continue cleanup + } + dev->dev_handle = NULL; + } + + retry++; + if (retry <= I2C_MAX_RETRIES) + { + vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << retry))); // Exponential backoff + ESP_LOGW(TAG, "[0x%02x at %d] Retrying operation...", dev->addr, dev->port); + } + } + + ESP_LOGE(TAG, "[0x%02x at %d] I2C operation failed after %d retries. Last error: %d (%s)", dev->addr, dev->port, I2C_MAX_RETRIES + 1, res, esp_err_to_name(res)); + return res; +} + +// Wrapper functions for the I2C master API to use with the retry mechanism +// i2c_do_operation_with_retry() needs a unified function signature for all I2C operations +static esp_err_t i2c_master_transmit_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms) +{ + return i2c_master_transmit(handle, write_buffer, write_size, timeout_ms); +} + +static esp_err_t i2c_master_receive_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms) +{ + return i2c_master_receive(handle, read_buffer, read_size, timeout_ms); +} + +static esp_err_t i2c_master_transmit_receive_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms) +{ + return i2c_master_transmit_receive(handle, write_buffer, write_size, read_buffer, read_size, timeout_ms); +} + +esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size) +{ + if (!dev || !in_data || !in_size) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read called (out_size: %u, in_size: %u)", dev->addr, dev->port, out_size, in_size); + + esp_err_t result = i2c_do_operation_with_retry((i2c_dev_t *)dev, // Cast to non-const for i2c_setup_device internal modifications + out_data && out_size ? i2c_master_transmit_receive_wrapper : i2c_master_receive_wrapper, out_data, out_size, in_data, in_size); + + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read result: %s (%d)", dev->addr, dev->port, esp_err_to_name(result), result); + return result; +} + +esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + if ((!out_reg || !out_reg_size) && (!out_data || !out_size)) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write called (reg_size: %u, data_size: %u)", dev->addr, dev->port, out_reg_size, out_size); + + esp_err_t res; + if (out_reg && out_reg_size && out_data && out_size) + { + size_t total_write_size = out_reg_size + out_size; + + // Check for overflow before proceeding + if (total_write_size < out_reg_size || total_write_size < out_size) + { + ESP_LOGE(TAG, "[0x%02x at %d] Write size overflow: reg_size=%u + data_size=%u", dev->addr, dev->port, out_reg_size, out_size); + return ESP_ERR_INVALID_ARG; + } + + // Use stack for small buffers to avoid heap fragmentation + if (total_write_size <= I2CDEV_MAX_STACK_ALLOC_SIZE) + { + // Use stack allocation for small buffers + uint8_t stack_buf[I2CDEV_MAX_STACK_ALLOC_SIZE]; + memcpy(stack_buf, out_reg, out_reg_size); + memcpy(stack_buf + out_reg_size, out_data, out_size); + res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, stack_buf, total_write_size, NULL, 0); + } + else + { + uint8_t *heap_buf = malloc(total_write_size); + if (!heap_buf) + { + ESP_LOGE(TAG, "[0x%02x at %d] Failed to allocate %u bytes for write", dev->addr, dev->port, total_write_size); + return ESP_ERR_NO_MEM; + } + memcpy(heap_buf, out_reg, out_reg_size); + memcpy(heap_buf + out_reg_size, out_data, out_size); + res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, heap_buf, total_write_size, NULL, 0); + free(heap_buf); // Free buffer regardless of operation result + } + } + else if (out_reg && out_reg_size) + { + res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, out_reg, out_reg_size, NULL, 0); + } + else if (out_data && out_size) + { + res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, out_data, out_size, NULL, 0); + } + else + { + return ESP_ERR_INVALID_ARG; // Shouldn't reach here given the earlier check + } + + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write result: %s (%d)", dev->addr, dev->port, esp_err_to_name(res), res); + return res; +} + +esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *data, size_t size) +{ + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read_reg called (reg: 0x%02x, size: %u)", dev->addr, dev->port, reg, size); + return i2c_dev_read(dev, ®, 1, data, size); +} + +esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *data, size_t size) +{ + ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write_reg called (reg: 0x%02x, size: %u)", dev->addr, dev->port, reg, size); + return i2c_dev_write(dev, ®, 1, data, size); +} + +esp_err_t i2c_dev_check_present(const i2c_dev_t *dev_const) +{ + if (!dev_const) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Probing device presence...", dev_const->addr, dev_const->port); + + // Cast to non-const for i2c_setup_port (which may modify internal state) + i2c_dev_t *dev = (i2c_dev_t *)dev_const; + + // Ensure the I2C port is set up before probing + esp_err_t setup_res = i2c_setup_port(dev); + if (setup_res != ESP_OK) + { + ESP_LOGE(TAG, "[0x%02x at %d] Failed to setup port for probe: %s", dev_const->addr, dev_const->port, esp_err_to_name(setup_res)); + return setup_res; + } + + // Now probe using the initialized bus + if (dev_const->port < I2C_NUM_MAX && i2c_ports[dev_const->port].lock) + { + if (xSemaphoreTake(i2c_ports[dev_const->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE) + { + if (i2c_ports[dev_const->port].installed && i2c_ports[dev_const->port].bus_handle) + { + // Use ESP-IDF's built-in probe function - completely non-intrusive + esp_err_t probe_res = i2c_master_probe(i2c_ports[dev_const->port].bus_handle, dev_const->addr, CONFIG_I2CDEV_TIMEOUT); + xSemaphoreGive(i2c_ports[dev_const->port].lock); + + if (probe_res == ESP_OK) + { + ESP_LOGV(TAG, "[0x%02x at %d] Device probe successful - device present", dev_const->addr, dev_const->port); + return ESP_OK; + } + else + { + ESP_LOGV(TAG, "[0x%02x at %d] Device probe failed: %s", dev_const->addr, dev_const->port, esp_err_to_name(probe_res)); + return probe_res; + } + } + else + { + xSemaphoreGive(i2c_ports[dev_const->port].lock); + ESP_LOGW(TAG, "[0x%02x at %d] Cannot probe - bus not ready on port %d", dev_const->addr, dev_const->port, dev_const->port); + return ESP_ERR_INVALID_STATE; + } + } + else + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for probe", dev_const->addr, dev_const->port); + return ESP_ERR_TIMEOUT; + } + } + else + { + ESP_LOGE(TAG, "[0x%02x at %d] Invalid port or port not initialized", dev_const->addr, dev_const->port); + return ESP_ERR_INVALID_ARG; + } +} + +// Compatibility wrapper for legacy code that still calls i2c_dev_probe +// The new driver implementation uses i2c_master_probe which doesn't need operation_type +esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type) +{ + ESP_LOGV(TAG, "[0x%02x at %d] Legacy probe called (operation_type %d), redirecting to new implementation", dev->addr, dev->port, operation_type); + + return i2c_dev_check_present(dev); +} + +// Clean up function to be called at application exit +esp_err_t i2cdev_done(void) +{ + esp_err_t result = ESP_OK; + ESP_LOGV(TAG, "Cleaning up I2C subsystem (i2c_master)..."); + for (int i = 0; i < I2C_NUM_MAX; i++) + { + if (i2c_ports[i].lock) + { + ESP_LOGV(TAG, "[Port %d] Cleaning up port...", i); + if (xSemaphoreTake(i2c_ports[i].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) + { + ESP_LOGE(TAG, "[Port %d] Could not take port mutex for cleanup", i); + result = ESP_FAIL; + } + else + { + if (i2c_ports[i].installed) + { + ESP_LOGV(TAG, "[Port %d] Removing active devices before deleting bus...", i); + // Remove all registered devices for this port from the bus + for (int j = 0; j < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; j++) + { + i2c_dev_t *dev_ptr = active_devices[i][j]; + if (dev_ptr != NULL && dev_ptr->dev_handle != NULL) + { + ESP_LOGV(TAG, "[Port %d] Removing device 0x%02x (Handle %p)", i, dev_ptr->addr, dev_ptr->dev_handle); + esp_err_t rm_res = i2c_master_bus_rm_device(dev_ptr->dev_handle); + if (rm_res != ESP_OK) + { + ESP_LOGE(TAG, "[Port %d] Failed to remove device 0x%02x handle: %d", i, dev_ptr->addr, rm_res); + // Continue cleanup despite error + if (result == ESP_OK) + result = rm_res; // Report first error + } + dev_ptr->dev_handle = NULL; + } + } + + ESP_LOGV(TAG, "[Port %d] Deleting master bus handle %p...", i, i2c_ports[i].bus_handle); + esp_err_t del_res = i2c_del_master_bus(i2c_ports[i].bus_handle); + if (del_res != ESP_OK) + { + ESP_LOGE(TAG, "[Port %d] Failed to delete I2C bus during cleanup: %d", i, del_res); + if (result == ESP_OK) + result = del_res; + } + i2c_ports[i].installed = false; + i2c_ports[i].bus_handle = NULL; + i2c_ports[i].ref_count = 0; + } + xSemaphoreGive(i2c_ports[i].lock); + } // End else (mutex taken) + + ESP_LOGV(TAG, "[Port %d] Deleting port mutex...", i); + vSemaphoreDelete(i2c_ports[i].lock); + i2c_ports[i].lock = NULL; + // Clear the active device list for this port + memset(active_devices[i], 0, sizeof(active_devices[i])); + ESP_LOGV(TAG, "[Port %d] Cleanup complete.", i); + + } // end if lock exists + } // end for loop + ESP_LOGV(TAG, "I2C subsystem cleanup finished with result: %d", result); + return result; +} diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.h b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.h new file mode 100644 index 000000000..1cde92578 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev.h @@ -0,0 +1,381 @@ +/** + * @file i2cdev.h + * @defgroup i2cdev i2cdev + * @{ + * + * ESP-IDF I2C master thread-safe functions for communication with I2C slave + * + * This implementation uses the newer ESP-IDF I2C master driver (v5.0+). + * For ESP-IDF versions using the legacy I2C driver, use i2cdev_legacy.c instead. + * + * Copyright (C) 2018 Ruslan V. Uss + * Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API + * + * MIT Licensed as described in the file LICENSE + * + * ============================================================================ + * OPTIONAL I2C PULLUP AUTO-CONFIGURATION + * ============================================================================ + * + * This library can optionally enable internal I2C pullups when no explicit + * pullup configuration is provided. Feature is DISABLED by default for + * backward compatibility (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=n). + * + * Optional auto-pullup (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y): + * - If both pullup flags are false (not set/default state), automatically enables internal pullups + * - Only available on ESP32 family (modern driver) + * - Legacy driver always uses explicit configuration + * + * + * Example - Enable internal pullups: + * i2c_dev_t sensor = { + * .port = I2C_NUM_0, + * .addr = 0x48, + * .cfg = { + * .sda_io_num = GPIO_NUM_21, + * .scl_io_num = GPIO_NUM_22, + * .sda_pullup_en = true, // Enable internal pullups + * .scl_pullup_en = true, // Enable internal pullups + * .master.clk_speed = 400000 + * } + * }; + * + * ============================================================================ + */ + +#ifndef __I2CDEV_H__ +#define __I2CDEV_H__ + +#include +#include +#include +#include +#include +#include + +// Define missing types for older ESP-IDF versions +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0) +typedef enum +{ + I2C_ADDR_BIT_LEN_7 = 0, /*!< I2C 7bit address for slave mode */ + I2C_ADDR_BIT_LEN_10, /*!< I2C 10bit address for slave mode */ +} i2c_addr_bit_len_t; +#endif + +// Definition for I2CDEV_MAX_STRETCH_TIME +#if HELPER_TARGET_IS_ESP8266 +#define I2CDEV_MAX_STRETCH_TIME 0xffffffff +#else +#include // For I2C_TIME_OUT_VALUE_V, etc. +#if defined(I2C_TIME_OUT_VALUE_V) +#define I2CDEV_MAX_STRETCH_TIME I2C_TIME_OUT_VALUE_V +#elif defined(I2C_TIME_OUT_REG_V) +#define I2CDEV_MAX_STRETCH_TIME I2C_TIME_OUT_REG_V +#else +#define I2CDEV_MAX_STRETCH_TIME 0x00ffffff +#endif +#endif /* HELPER_TARGET_IS_ESP8266 */ + +#ifndef CONFIG_I2CDEV_TIMEOUT +#define CONFIG_I2CDEV_TIMEOUT 1000 // Default 1 second timeout +#endif + +#ifndef CONFIG_I2CDEV_NOLOCK +#define CONFIG_I2CDEV_NOLOCK 0 // Enable locking by default +#endif + +#ifndef CONFIG_I2CDEV_MAX_DEVICES_PER_PORT +#define CONFIG_I2CDEV_MAX_DEVICES_PER_PORT 8 // Maximum devices per I2C port +#endif + +#ifndef CONFIG_I2CDEV_DEFAULT_SDA_PIN +#define CONFIG_I2CDEV_DEFAULT_SDA_PIN 21 // Default SDA pin +#endif + +#ifndef CONFIG_I2CDEV_DEFAULT_SCL_PIN +#define CONFIG_I2CDEV_DEFAULT_SCL_PIN 22 // Default SCL pin +#endif + +#ifndef CONFIG_FREERTOS_HZ +#define CONFIG_FREERTOS_HZ 100 // Default value in most ESP-IDF configs +#endif + +#ifndef CONFIG_LOG_MAXIMUM_LEVEL +#define CONFIG_LOG_MAXIMUM_LEVEL 3 // INFO level as default +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2C transaction type for legacy probe + */ +typedef enum +{ + I2C_DEV_WRITE = 0, /**< Write operation for probe */ + I2C_DEV_READ /**< Read operation for probe */ +} i2c_dev_type_t; + +/** + * I2C device descriptor + * + * This structure supports both legacy ESP-IDF I2C driver and modern i2c_master driver. + * + * @note INITIALIZATION CHECKLIST - Set these fields before calling i2c_dev_create_mutex(): + * + * ┌─── REQUIRED (Set by user) ───────────────────────────────────────────┐ + * │ - dev->port - I2C port number (e.g., I2C_NUM_0) │ + * │ - dev->addr - Device I2C address (e.g., 0x48) │ + * │ - dev->cfg.sda_io_num - SDA pin (-1 = use Kconfig default) │ + * │ - dev->cfg.scl_io_num - SCL pin (-1 = use Kconfig default) │ + * │ - dev->cfg.master.clk_speed - Clock speed in Hz (e.g., 400000) │ + * └──────────────────────────────────────────────────────────────────────┘ + * + * ┌─── OPTIONAL (Set by user if needed) ─────────────────────────────────┐ + * │ - dev->addr_bit_len - Address format (defaults to 7-bit) - NEW │ + * │ - dev->cfg.sda_pullup_en - Enable internal SDA pullup │ + * │ - dev->cfg.scl_pullup_en - Enable internal SCL pullup │ + * │ - dev->timeout_ticks - Legacy driver timeout (legacy only) │ + * └──────────────────────────────────────────────────────────────────────┘ + * + * ┌─── AUTO-POPULATED (library fills these) ─────────────────────────────┐ + * │ - dev->mutex - Device mutex handle │ + * │ - dev->dev_handle - I2C device handle (modern driver) - NEW │ + * │ - dev->sda_pin - Actual SDA pin used by bus │ + * │ - dev->scl_pin - Actual SCL pin used by bus │ + * └──────────────────────────────────────────────────────────────────────┘ + * + * @note BACKWARD COMPATIBILITY DESIGN: + * The custom 'cfg' structure mimics ESP-IDF's deprecated i2c_config_t layout + * to maintain zero-change compatibility with existing device drivers. + * ESP-IDF ≥5.2 deprecated i2c_config_t and split it into separate bus/device + * configs, but this library preserves the familiar field paths like: + * dev->cfg.sda_io_num, dev->cfg.scl_io_num, dev->cfg.master.clk_speed + */ +typedef struct +{ + // ═══ Core Device Identity (REQUIRED) ═══ + i2c_port_t port; //!< I2C port number (e.g., I2C_NUM_0) + uint16_t addr; //!< Device I2C address (e.g., 0x48 for 7-bit) + i2c_addr_bit_len_t addr_bit_len; //!< Address format: I2C_ADDR_BIT_LEN_7 (default) or I2C_ADDR_BIT_LEN_10 + + // ═══ Library Internal State (AUTO-POPULATED) ═══ + SemaphoreHandle_t mutex; //!< Device mutex - Created by i2c_dev_create_mutex() + void *dev_handle; //!< Device handle - Modern driver only, created lazily (when actual I2C operation is performed) + int sda_pin; //!< Actual SDA pin used - Populated after port setup + int scl_pin; //!< Actual SCL pin used - Populated after port setup + + // ═══ Legacy Driver Compatibility ═══ + uint32_t timeout_ticks; //!< Clock stretching timeout - Legacy driver only + + // ═══ User Configuration (REQUIRED) ═══ + // Configuration structure with i2c_config_t compatible field layout. + struct + { + gpio_num_t sda_io_num; //!< Desired SDA pin (-1 = use Kconfig default) + gpio_num_t scl_io_num; //!< Desired SCL pin (-1 = use Kconfig default) + uint8_t sda_pullup_en; //!< Enable internal SDA pullup (optional) + uint8_t scl_pullup_en; //!< Enable internal SCL pullup (optional) + uint32_t clk_flags; //!< Bitwise of ``I2C_SCLK_SRC_FLAG_**FOR_DFS**`` for clk source choice + struct + { + uint32_t clk_speed; //!< Clock speed in Hz + } master; //!< Master-specific config (mimics old i2c_config_t.master) + } cfg; //!< Configuration set by device drivers (i2c_config_t compatible layout) +} i2c_dev_t; + +/** + * @brief Initialize I2C subsystem (port mutexes and internal states) + * + * @note This should be called once at the beginning of your application + * before any I2C devices are initialized. + * + * @return ESP_OK on success + */ +esp_err_t i2cdev_init(void); + +/** + * @brief Release I2C subsystem (deletes all devices, buses, and mutexes) + * + * @note Call this when no more I2C operations will be performed + * to clean up resources. + * + * @return ESP_OK on success + */ +esp_err_t i2cdev_done(void); + +/** + * @brief Create mutex for device descriptor and register device + * + * @note IMPORTANT: Before calling this function, you must properly initialize the i2c_dev_t + * structure with device address, port, and pin settings. For ESP-IDF legacy driver, + * set pins in dev->cfg.sda_io_num and dev->cfg.scl_io_num. For newer ESP-IDF version, + * either method is compatible. See the structure documentation for details. + * + * @param dev Pointer to device descriptor + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev); + +/** + * @brief Delete mutex for device descriptor and perform device cleanup + * + * @note This function performs cleanup tasks including removing the device from the + * I2C bus, deregistering it, and deleting its mutex. + * + * @param dev Pointer to device descriptor + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev); + +/** + * @brief Take device mutex + * + * @param dev Pointer to device descriptor + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev); + +/** + * @brief Give device mutex + * + * @param dev Pointer to device descriptor + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev); + +/** + * @brief Check the availability of a device on the I2C bus (New Driver) - legacy's i2c_dev_probe function equivalent. + * + * This function attempts to communicate with the I2C device to see if it ACKs. + * It is non-intrusive; if the device is found, any temporary setup for + * the check is torn down. Uses the new I2C driver logic. + * + * @param dev Pointer to the device descriptor. Pins and address must be configured. + * @return `ESP_OK` if the device ACKs (is present), an error code otherwise. + */ +esp_err_t i2c_dev_check_present(const i2c_dev_t *dev); + +/** + * @brief Check the availability of a device on the I2C bus (Legacy Driver). + * + * Issue an operation of `operation_type` to the I2C device then stops. + * Primarily for use with the legacy i2cdev_legacy.c implementation. + * + * @param dev Device descriptor. + * @param operation_type Operation type (I2C_DEV_WRITE or I2C_DEV_READ). + * @return `ESP_OK` if device is available for the specified operation type. + */ +esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type); + +/** + * @brief Read from device + * + * @param dev Pointer to device descriptor + * @param[in] out_data Data to write before reading (can be NULL if out_size is 0) + * @param out_size Size of data to write + * @param[out] in_data Buffer to store data read + * @param in_size Number of bytes to read + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size); + +/** + * @brief Write to device + * + * @param dev Pointer to device descriptor + * @param[in] out_reg Register address to write to (can be NULL if out_reg_size is 0) + * @param out_reg_size Size of register address + * @param[in] out_data Data to write (can be NULL if out_size is 0) + * @param out_size Size of data to write + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size); + +/** + * @brief Read from device register (8-bit register address) + * + * @param dev Pointer to device descriptor + * @param reg Command to write before reading + * @param[out] data Buffer to store data + * @param size Number of bytes to read + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *data, size_t size); + +/** + * @brief Write to device register (8-bit register address) + * + * @param dev Pointer to device descriptor + * @param reg Command to write before writing data + * @param data Buffer with data to write + * @param size Number of bytes to write + * @return `ESP_OK` on success + */ +esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *data, size_t size); + +/** + * @brief Take device mutex with error checking + */ +#define I2C_DEV_TAKE_MUTEX(dev) \ + do \ + { \ + esp_err_t __ = i2c_dev_take_mutex(dev); \ + if (__ != ESP_OK) \ + return __; \ + } \ + while (0) + +/** + * @brief Give device mutex with error checking + */ +#define I2C_DEV_GIVE_MUTEX(dev) \ + do \ + { \ + esp_err_t __ = i2c_dev_give_mutex(dev); \ + if (__ != ESP_OK) \ + return __; \ + } \ + while (0) + +/** + * @brief Execute operation, assuming mutex is held. Gives mutex ONLY on error. + */ +#define I2C_DEV_CHECK(dev, X) \ + do \ + { \ + esp_err_t ___ = X; /* Execute operation */ \ + if (___ != ESP_OK) \ + { \ + /* Give mutex ONLY if error occurred */ \ + i2c_dev_give_mutex(dev); \ + return ___; \ + } \ + } \ + while (0) + +/** + * @brief Execute operation, assuming mutex is held. Gives mutex ONLY on error, logs error. + */ +#define I2C_DEV_CHECK_LOGE(dev, X, msg, ...) \ + do \ + { \ + esp_err_t ___ = X; /* Execute operation */ \ + if (___ != ESP_OK) \ + { \ + /* Give mutex ONLY if error occurred */ \ + i2c_dev_give_mutex(dev); \ + ESP_LOGE(TAG, msg, ##__VA_ARGS__); \ + return ___; \ + } \ + } \ + while (0) + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif /* __I2CDEV_H__ */ diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev_legacy.c b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev_legacy.c new file mode 100644 index 000000000..3a5c67957 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/i2cdev_legacy.c @@ -0,0 +1,793 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Ruslan V. Uss + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file i2cdev.c + * + * ESP-IDF I2C master thread-safe functions for communication with I2C slave + * + * Copyright (c) 2018 Ruslan V. Uss + * Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API + * MIT Licensed as described in the file LICENSE + */ +#include "esp_idf_lib_helpers.h" // For HELPER_TARGET_IS_ESP32 etc. +#include "i2cdev.h" // Common header +#include // Legacy I2C driver +#include +#include +#include +#include +#include +#if !HELPER_TARGET_IS_ESP8266 +#include // For APB_CLK_FREQ +#endif +#include + +static const char *TAG = "i2cdev_legacy"; + +typedef struct +{ + SemaphoreHandle_t lock; + i2c_config_t config; // Use legacy config struct + bool installed; + uint32_t ref_count; + i2c_dev_t *devices[CONFIG_I2CDEV_MAX_DEVICES_PER_PORT]; // Track devices registered on this port +} i2c_port_state_t; + +static i2c_port_state_t states[I2C_NUM_MAX] = { 0 }; + +#if CONFIG_I2CDEV_NOLOCK +#define SEMAPHORE_TAKE(port) +#else +#define SEMAPHORE_TAKE(port) \ + do \ + { \ + if (!xSemaphoreTake(states[port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT))) \ + { \ + ESP_LOGE(TAG, "Could not take port mutex %d", port); \ + return ESP_ERR_TIMEOUT; \ + } \ + } \ + while (0) +#endif + +#if CONFIG_I2CDEV_NOLOCK +#define SEMAPHORE_GIVE(port) +#else +#define SEMAPHORE_GIVE(port) \ + do \ + { \ + if (!xSemaphoreGive(states[port].lock)) \ + { \ + ESP_LOGE(TAG, "Could not give port mutex %d", port); \ + return ESP_FAIL; \ + } \ + } \ + while (0) +#endif + +/** + * @brief Register an I2C device for tracking and resource management + * + * This function adds a device to the port's tracking array, which helps with: + * - Monitoring which devices are active on each port + * - Proper cleanup when the system shuts down + * - Diagnostics and debugging + * + * Each port can track up to CONFIG_I2CDEV_MAX_DEVICES_PER_PORT devices. + * + * @param dev Device descriptor to register + * @return ESP_OK if registration succeeded, or an error code + */ +static esp_err_t register_device(i2c_dev_t *dev) +{ + if (!dev || dev->port >= I2C_NUM_MAX) + return ESP_ERR_INVALID_ARG; + if (!states[dev->port].lock) + return ESP_ERR_INVALID_STATE; + + esp_err_t ret = ESP_ERR_NO_MEM; + + // Take the mutex directly instead of using the macro + if (xSemaphoreTake(states[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for registration", dev->addr, dev->port); + return ESP_ERR_TIMEOUT; + } + + // Search for an empty slot in the device tracking array + for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++) + { + if (states[dev->port].devices[i] == NULL) + { + // Found empty slot - register the device here + states[dev->port].devices[i] = dev; + ESP_LOGV(TAG, "[0x%02x at %d] Registered device in slot %d", dev->addr, dev->port, i); + ret = ESP_OK; + break; + } + } + + // All slots full - this will still allow communication but prevents automatic cleanup + if (ret != ESP_OK) + { + ESP_LOGW(TAG, "[0x%02x at %d] No free slots to register device", dev->addr, dev->port); + } + + // Release the mutex + if (!xSemaphoreGive(states[dev->port].lock)) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not give port mutex after registration", dev->addr, dev->port); + // If can't give the mutex, that's a serious error that overrides the registration result + return ESP_FAIL; + } + + return ret; +} + +/** + * @brief Deregister a device and update reference counting + * + * This function: + * 1. Removes the device from the port's tracking array + * 2. Decrements the port's reference count + * 3. Cleans up the I2C driver if this was the last device on the port + * + * This is called during device cleanup to ensure proper resource management. + * + * @param dev Device descriptor to deregister + */ +static void deregister_device(i2c_dev_t *dev) +{ + if (!dev || dev->port >= I2C_NUM_MAX) + return; + + // Don't use macros that return values since this is a void function + if (states[dev->port].lock) + { + if (xSemaphoreTake(states[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for deregistration", dev->addr, dev->port); + return; // Cannot proceed without lock + } + + // Find the device in the tracking array + for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++) + { + if (states[dev->port].devices[i] == dev) + { + // Clear this slot + states[dev->port].devices[i] = NULL; + ESP_LOGV(TAG, "[0x%02x at %d] Deregistered device from slot %d", dev->addr, dev->port, i); + break; + } + } + + // Manage reference counting for this port + if (states[dev->port].ref_count > 0) + { + states[dev->port].ref_count--; + ESP_LOGD(TAG, "[Port %d] Decremented ref_count to %" PRIu32, dev->port, states[dev->port].ref_count); + + // If this was the last device using this port, clean up the driver + if (states[dev->port].ref_count == 0 && states[dev->port].installed) + { + ESP_LOGI(TAG, "[Port %d] Last device removed, uninstalling driver", dev->port); + i2c_driver_delete(dev->port); + states[dev->port].installed = false; + } + } + + // Release the mutex + if (!xSemaphoreGive(states[dev->port].lock)) + { + ESP_LOGE(TAG, "[Port %d] Could not give port mutex after deregistration", dev->port); + // Can't do much about this error except log it + } + } +} + +esp_err_t i2cdev_init() +{ + memset(states, 0, sizeof(states)); + +#if !CONFIG_I2CDEV_NOLOCK + for (int i = 0; i < I2C_NUM_MAX; i++) + { + states[i].lock = xSemaphoreCreateMutex(); + if (!states[i].lock) + { + ESP_LOGE(TAG, "Could not create port mutex %d", i); + return ESP_FAIL; + } + } +#endif + + return ESP_OK; +} + +esp_err_t i2cdev_done() +{ + ESP_LOGV(TAG, "Cleaning up I2C subsystem (legacy)..."); + for (int i = 0; i < I2C_NUM_MAX; i++) + { + if (!states[i].lock) + continue; + + if (states[i].installed) + { + SEMAPHORE_TAKE(i); + + // First, clean up any devices still registered on this port + for (int j = 0; j < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; j++) + { + if (states[i].devices[j] != NULL) + { + i2c_dev_t *dev = states[i].devices[j]; + ESP_LOGW(TAG, "[Port %d] Device 0x%02x still registered during cleanup", i, dev->addr); + states[i].devices[j] = NULL; + } + } + + i2c_driver_delete(i); + states[i].installed = false; + states[i].ref_count = 0; + + SEMAPHORE_GIVE(i); + } +#if !CONFIG_I2CDEV_NOLOCK + vSemaphoreDelete(states[i].lock); +#endif + states[i].lock = NULL; + } + ESP_LOGV(TAG, "I2C subsystem cleanup finished (legacy)."); + return ESP_OK; +} + +esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Creating device mutex", dev->addr, dev->port); + + // Initialize device pins to -1 to ensure consistent pattern with new driver + if (dev->sda_pin == 0 && dev->scl_pin == 0) + { + dev->sda_pin = -1; + dev->scl_pin = -1; + ESP_LOGD(TAG, "[0x%02x at %d] Initialized pins to -1", dev->addr, dev->port); + } + + if (dev->mutex) + { + ESP_LOGW(TAG, "[0x%02x at %d] Device mutex already exists", dev->addr, dev->port); + return ESP_OK; // Already created + } + + dev->mutex = xSemaphoreCreateMutex(); + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not create device mutex", dev->addr, dev->port); + return ESP_FAIL; + } + + // Register device for tracking + esp_err_t reg_res = register_device(dev); + if (reg_res != ESP_OK) + { + ESP_LOGW(TAG, "[0x%02x at %d] Could not register device: %s", dev->addr, dev->port, esp_err_to_name(reg_res)); + // Continue anyway since this is not critical + } +#endif + + return ESP_OK; +} + +esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Deleting device mutex and cleaning up", dev->addr, dev->port); + + // Deregister and update ref counts + deregister_device(dev); + + // Delete mutex if exists + if (dev->mutex) + { + vSemaphoreDelete(dev->mutex); + dev->mutex = NULL; + } + else + { + ESP_LOGV(TAG, "[0x%02x at %d] Device mutex was NULL", dev->addr, dev->port); + } +#endif + return ESP_OK; +} + +esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Taking mutex", dev->addr, dev->port); + + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Attempt to take NULL mutex!", dev->addr, dev->port); + return ESP_ERR_INVALID_STATE; + } + + if (!xSemaphoreTake(dev->mutex, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT))) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not take device mutex (timeout %d ms)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT); + return ESP_ERR_TIMEOUT; + } +#endif + return ESP_OK; +} + +esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev) +{ +#if !CONFIG_I2CDEV_NOLOCK + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Giving mutex", dev->addr, dev->port); + + if (!dev->mutex) + { + ESP_LOGE(TAG, "[0x%02x at %d] Attempt to give NULL mutex!", dev->addr, dev->port); + return ESP_ERR_INVALID_STATE; + } + + if (!xSemaphoreGive(dev->mutex)) + { + ESP_LOGE(TAG, "[0x%02x at %d] Could not give device mutex", dev->addr, dev->port); + return ESP_FAIL; + } +#endif + return ESP_OK; +} + +inline static bool cfg_equal(const i2c_config_t *a, const i2c_config_t *b) +{ + bool clock_equal; +#ifdef CONFIG_IDF_TARGET_ESP8266 + clock_equal = (a->clk_stretch_tick == b->clk_stretch_tick); +#else + clock_equal = (a->master.clk_speed == b->master.clk_speed); +#endif + + return a->mode == b->mode && a->scl_io_num == b->scl_io_num && a->sda_io_num == b->sda_io_num && a->scl_pullup_en == b->scl_pullup_en && a->sda_pullup_en == b->sda_pullup_en && clock_equal; + // Note: Ignoring clk_flags for comparison as it might not be consistently set by users +} + +/** + * @brief Configure and initialize the I2C port for a device + * + * This function is responsible for: + * 1. Determining which pins to use (from device or config) + * 2. Validating pin configuration + * 3. Installing/configuring the I2C driver if not already done + * 4. Managing reference counting for the port + * 5. Setting up clock stretching timeout + * + * This is a critical function that must succeed before any I2C operations + * can be performed with a device. + * + * @param dev Device descriptor with configuration info + * @return ESP_OK on success, or an error code on failure + */ +static esp_err_t i2c_setup_port(i2c_dev_t *dev) +{ + if (!dev) + { + ESP_LOGE(TAG, "Device is NULL"); + return ESP_ERR_INVALID_ARG; + } + + if (dev->port >= I2C_NUM_MAX) + { + ESP_LOGE(TAG, "Invalid I2C port number: %d", dev->port); + return ESP_ERR_INVALID_ARG; + } + + // Pin Selection Logic: + // Pins are taken from dev->cfg.xyz_io_num. + // If -1, Kconfig defaults are used. + gpio_num_t sda_pin; // Effective SDA pin to be used + gpio_num_t scl_pin; // Effective SCL pin to be used + + if (dev->cfg.sda_io_num == (gpio_num_t) -1) + { + sda_pin = (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SDA_PIN; + } + else + { + sda_pin = dev->cfg.sda_io_num; + } + + if (dev->cfg.scl_io_num == (gpio_num_t) -1) + { + scl_pin = (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SCL_PIN; + } + else + { + scl_pin = dev->cfg.scl_io_num; + } + + ESP_LOGD(TAG, "[0x%02x at %d] Based on cfg: sda_cfg=%d, scl_cfg=%d. Effective pins for setup: SDA=%d, SCL=%d", dev->addr, dev->port, dev->cfg.sda_io_num, dev->cfg.scl_io_num, sda_pin, scl_pin); + + // Perform basic validation of effective pins + if (sda_pin < 0 || scl_pin < 0) + { + ESP_LOGE(TAG, "[0x%02x at %d] Invalid effective SDA/SCL pins (%d, %d). Check Kconfig defaults if cfg pins were -1.", dev->addr, dev->port, sda_pin, scl_pin); + return ESP_ERR_INVALID_ARG; + } + + if (sda_pin == scl_pin) + { + ESP_LOGE(TAG, "[0x%02x at %d] Effective SDA and SCL pins cannot be the same (%d).", dev->addr, dev->port, sda_pin); + return ESP_ERR_INVALID_ARG; + } + + // Initialize common fields + i2c_config_t legacy_cfg = { .mode = I2C_MODE_MASTER, + .sda_io_num = sda_pin, // Use locally determined pins + .scl_io_num = scl_pin, // Use locally determined pins + .sda_pullup_en = dev->cfg.sda_pullup_en ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, + .scl_pullup_en = dev->cfg.scl_pullup_en ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE + }; + +#ifdef CONFIG_IDF_TARGET_ESP8266 + // ESP8266 uses clk_stretch_tick instead of master.clk_speed + // Clock speed will be handled during driver installation + uint32_t desired_speed = dev->cfg.master.clk_speed > 0 ? dev->cfg.master.clk_speed : 400000; + ESP_LOGD(TAG, "Final I2C config for port %d: SDA=%d, SCL=%d, speed=%lu (ESP8266)", dev->port, legacy_cfg.sda_io_num, legacy_cfg.scl_io_num, (unsigned long)desired_speed); +#else + // ESP32 family uses master.clk_speed + legacy_cfg.master.clk_speed = dev->cfg.master.clk_speed > 0 ? dev->cfg.master.clk_speed : 400000; + ESP_LOGD(TAG, "Final I2C config for port %d: SDA=%d, SCL=%d, speed=%lu", dev->port, legacy_cfg.sda_io_num, legacy_cfg.scl_io_num, (unsigned long)legacy_cfg.master.clk_speed); +#endif + +#ifdef CONFIG_IDF_TARGET_ESP32 + legacy_cfg.clk_flags = 0; +#endif + + esp_err_t err = ESP_OK; + + // Part 1: Driver Installation / Reconfiguration + if (!cfg_equal(&legacy_cfg, &states[dev->port].config) || !states[dev->port].installed) + { + ESP_LOGD(TAG, "[0x%02x at %d] Reconfiguring I2C driver", dev->addr, dev->port); + + if (states[dev->port].installed) + { + ESP_LOGD(TAG, "Uninstalling previous I2C driver configuration for port %d", dev->port); + i2c_driver_delete(dev->port); + states[dev->port].installed = false; + states[dev->port].ref_count = 0; + } + + vTaskDelay(1); + +// Target-specific driver installation/configuration sequence +#if HELPER_TARGET_IS_ESP32 || HELPER_TARGET_IS_ESP32S2 || HELPER_TARGET_IS_ESP32S3 || HELPER_TARGET_IS_ESP32C3 || HELPER_TARGET_IS_ESP32C6 +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) + ESP_LOGD(TAG, "Using IDF >= 5.1.0 driver install order for ESP32 family"); + err = i2c_driver_install(dev->port, legacy_cfg.mode, 0, 0, 0); + if (err == ESP_OK) + { + err = i2c_param_config(dev->port, &legacy_cfg); + } +#else + ESP_LOGD(TAG, "Using IDF < 5.1.0 driver install order for ESP32 family"); + err = i2c_param_config(dev->port, &legacy_cfg); + if (err == ESP_OK) + { + err = i2c_driver_install(dev->port, legacy_cfg.mode, 0, 0, 0); + } +#endif +#elif HELPER_TARGET_IS_ESP8266 + ESP_LOGD(TAG, "Using ESP8266 specific driver installation"); + legacy_cfg.clk_stretch_tick = dev->timeout_ticks ? dev->timeout_ticks : I2CDEV_MAX_STRETCH_TIME; + err = i2c_driver_install(dev->port, legacy_cfg.mode); + if (err == ESP_OK) + { + err = i2c_param_config(dev->port, &legacy_cfg); + } + // ESP8266 note: Clock speed is not directly configurable through i2c_config_t + // The desired speed was: %lu Hz", desired_speed +#else + // If legacy mode is off, and target detection fails, this avoids a compile error. + // The legacy driver just won't support any target in this case. + ESP_LOGW(TAG, "i2cdev_legacy.c: No specific target (ESP32/ESP32-S2/ESP32-S3/ESP32-C3/ESP32-C6/ESP8266) detected " + "for driver installation. Legacy driver might be inactive or misconfigured."); + err = ESP_ERR_NOT_SUPPORTED; // Indicate that setup can't proceed. +#endif + + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Failed to install/configure I2C driver for port %d: %d (%s)", dev->port, err, esp_err_to_name(err)); + states[dev->port].installed = false; // Ensure state reflects failure + return err; + } + + memcpy(&states[dev->port].config, &legacy_cfg, sizeof(i2c_config_t)); + states[dev->port].installed = true; + states[dev->port].ref_count++; + + dev->sda_pin = legacy_cfg.sda_io_num; + dev->scl_pin = legacy_cfg.scl_io_num; + + ESP_LOGD(TAG, "I2C driver successfully installed/reconfigured on port %d, ref_count=%" PRIu32, dev->port, states[dev->port].ref_count); + } + else + { + states[dev->port].ref_count++; + ESP_LOGV(TAG, "I2C driver already installed on port %d with matching config, ref_count=%" PRIu32, dev->port, states[dev->port].ref_count); + + dev->sda_pin = states[dev->port].config.sda_io_num; + dev->scl_pin = states[dev->port].config.scl_io_num; + } + +// Part 2: Timeout Configuration (ESP32 family specific hardware timeout) +#if HELPER_TARGET_IS_ESP32 || HELPER_TARGET_IS_ESP32S2 || HELPER_TARGET_IS_ESP32S3 || HELPER_TARGET_IS_ESP32C3 || HELPER_TARGET_IS_ESP32C6 + int current_timeout_hw; + err = i2c_get_timeout(dev->port, ¤t_timeout_hw); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Failed to get HW timeout for port %d: %d (%s)", dev->port, err, esp_err_to_name(err)); + return err; + } + uint32_t timeout_ticks_val = dev->timeout_ticks ? dev->timeout_ticks : I2CDEV_MAX_STRETCH_TIME; + if (timeout_ticks_val != (uint32_t)current_timeout_hw) + { + ESP_LOGV(TAG, "Port %d: Updating HW timeout from %d to %" PRIu32 " ticks", dev->port, current_timeout_hw, timeout_ticks_val); + err = i2c_set_timeout(dev->port, timeout_ticks_val); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Failed to set HW timeout for port %d: %d (%s)", dev->port, err, esp_err_to_name(err)); + return err; + } + ESP_LOGD(TAG, "HW Timeout: ticks = %" PRIu32 " (%" PRIu32 " usec) on port %d", timeout_ticks_val, timeout_ticks_val / 80, dev->port); + } +#endif + + return ESP_OK; +} + +esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + + SEMAPHORE_TAKE(dev->port); + + esp_err_t res = i2c_setup_port((i2c_dev_t *)dev); + if (res == ESP_OK) + { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1 | (operation_type == I2C_DEV_READ ? 1 : 0), true); + // Alternative Write-style probe for better device compatibility + // many devices don't respond well to blind read probes. + // i2c_master_write_byte(cmd, dev->addr << 1 | 0, true); // Force write bit (0) + i2c_master_stop(cmd); + + res = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)); + + i2c_cmd_link_delete(cmd); + } + + SEMAPHORE_GIVE(dev->port); + + return res; +} + +esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size) +{ + if (!dev || !in_data || !in_size) + return ESP_ERR_INVALID_ARG; + + SEMAPHORE_TAKE(dev->port); + + // Use a local status variable to track errors + esp_err_t err = i2c_setup_port((i2c_dev_t *)dev); + if (err == ESP_OK) + { + // Only create a command handle if setup was successful + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + if (out_data && out_size) + { + // Write phase - typically used to specify a register address + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1, true); // Addr + Write bit (0) + i2c_master_write(cmd, (void *)out_data, out_size, true); + } + + // Read phase - get data from the device + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->addr << 1) | 1, true); // Addr + Read bit (1) + i2c_master_read(cmd, in_data, in_size, + I2C_MASTER_LAST_NACK); // NACK the last byte to signal end + i2c_master_stop(cmd); + + // Execute the command + err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed for read: %d (%s)", err, esp_err_to_name(err)); + } + + // Always delete the command handle + i2c_cmd_link_delete(cmd); + } + + // Always release the semaphore before returning + SEMAPHORE_GIVE(dev->port); + return err; +} + +esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + if ((!out_reg || !out_reg_size) && (!out_data || !out_size)) + return ESP_ERR_INVALID_ARG; + + SEMAPHORE_TAKE(dev->port); + + // Use a local status variable to track errors + esp_err_t err = i2c_setup_port((i2c_dev_t *)dev); + if (err == ESP_OK) + { + // Only create a command handle if setup was successful + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1, true); + + // Write register address/command if provided + if (out_reg && out_reg_size) + { + i2c_master_write(cmd, (void *)out_reg, out_reg_size, true); + } + + // Write data if provided + if (out_data && out_size) + { + i2c_master_write(cmd, (void *)out_data, out_size, true); + } + + i2c_master_stop(cmd); + + // Execute the command + err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed for write: %d (%s)", err, esp_err_to_name(err)); + } + + // Always delete the command handle + i2c_cmd_link_delete(cmd); + } + + // Always release the semaphore before returning + SEMAPHORE_GIVE(dev->port); + return err; +} + +esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *out_data, size_t out_size) +{ + if (!dev || !out_data || !out_size) + return ESP_ERR_INVALID_ARG; + + SEMAPHORE_TAKE(dev->port); + + // Use a local status variable to track errors + esp_err_t err = i2c_setup_port((i2c_dev_t *)dev); + if (err == ESP_OK) + { + // Only create a command handle if setup was successful + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true); // Addr + Write bit + i2c_master_write_byte(cmd, reg, true); // Register address + if (out_data && out_size) + { + i2c_master_write(cmd, (void *)out_data, out_size, true); // Data to write + } + i2c_master_stop(cmd); + + // Execute the command + err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed for write_reg: %d (%s)", err, esp_err_to_name(err)); + } + + // Always delete the command handle + i2c_cmd_link_delete(cmd); + } + + // Always release the semaphore before returning + SEMAPHORE_GIVE(dev->port); + return err; +} + +esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *in_data, size_t in_size) +{ + if (!dev || !in_data || !in_size) + return ESP_ERR_INVALID_ARG; + + SEMAPHORE_TAKE(dev->port); + + // Use a local status variable to track errors + esp_err_t err = i2c_setup_port((i2c_dev_t *)dev); + if (err == ESP_OK) + { + // Only create a command handle if setup was successful + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_READ, true); + i2c_master_read(cmd, in_data, in_size, I2C_MASTER_LAST_NACK); + i2c_master_stop(cmd); + + // Execute the command + err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "i2c_master_cmd_begin failed for read_reg: %d (%s)", err, esp_err_to_name(err)); + } + + // Always delete the command handle + i2c_cmd_link_delete(cmd); + } + + // Always release the semaphore before returning + SEMAPHORE_GIVE(dev->port); + return err; +} + +// Implementation of i2c_dev_check_present (updated version of i2c_dev_probe) using legacy I2C driver +esp_err_t i2c_dev_check_present(const i2c_dev_t *dev) +{ + if (!dev) + return ESP_ERR_INVALID_ARG; + + ESP_LOGV(TAG, "[0x%02x at %d] Checking device presence (legacy driver)...", dev->addr, dev->port); + + // Use the exact same pattern as i2c_dev_probe with WRITE operation to ensure consistent behavior + return i2c_dev_probe(dev, I2C_DEV_WRITE); +} diff --git a/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/idf_component.yml b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/idf_component.yml new file mode 100644 index 000000000..6c7263ce1 --- /dev/null +++ b/ESP32-IDF_Temperture-Node-v2/managed_components/esp-idf-lib__i2cdev/idf_component.yml @@ -0,0 +1,30 @@ +dependencies: + esp-idf-lib/esp_idf_lib_helpers: + version: '*' +description: ESP-IDF I2C master thread-safe utilities +discussion: https://github.com/esp-idf-lib/core/discussions +documentation: https://esp-idf-lib.github.io/i2cdev/ +files: + exclude: + - docs/**/* +issues: https://github.com/esp-idf-lib/i2cdev/issues +license: MIT +maintainers: +- Ruslan V. Uss (@UncleRus) +repository: git://github.com/esp-idf-lib/i2cdev.git +repository_info: + commit_sha: abf0ebc8f0f826373e9a9ee07cf96727a49ed87b + path: . +targets: +- esp32 +- esp32c2 +- esp32c3 +- esp32c5 +- esp32c6 +- esp32c61 +- esp32h2 +- esp32p4 +- esp32s2 +- esp32s3 +url: https://github.com/esp-idf-lib/core +version: 2.0.8