diff --git a/esphome/components/camera_encoder/__init__.py b/esphome/components/camera_encoder/__init__.py index 89181d27b4..a0c59a517a 100644 --- a/esphome/components/camera_encoder/__init__.py +++ b/esphome/components/camera_encoder/__init__.py @@ -50,7 +50,7 @@ async def to_code(config: ConfigType) -> None: buffer = cg.new_Pvariable(config[CONF_ENCODER_BUFFER_ID]) cg.add(buffer.set_buffer_size(config[CONF_BUFFER_SIZE])) if config[CONF_TYPE] == ESP32_CAMERA_ENCODER: - add_idf_component(name="espressif/esp32-camera", ref="2.1.1") + add_idf_component(name="espressif/esp32-camera", ref="2.1.5") cg.add_define("USE_ESP32_CAMERA_JPEG_ENCODER") var = cg.new_Pvariable( config[CONF_ID], diff --git a/esphome/components/esp32_camera/__init__.py b/esphome/components/esp32_camera/__init__.py index 3a5d87792b..afab849a7c 100644 --- a/esphome/components/esp32_camera/__init__.py +++ b/esphome/components/esp32_camera/__init__.py @@ -400,7 +400,7 @@ async def to_code(config): if config[CONF_JPEG_QUALITY] != 0 and config[CONF_PIXEL_FORMAT] != "JPEG": cg.add_define("USE_ESP32_CAMERA_JPEG_CONVERSION") - add_idf_component(name="espressif/esp32-camera", ref="2.1.1") + add_idf_component(name="espressif/esp32-camera", ref="2.1.5") add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_NEW", True) add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_LEGACY", False) diff --git a/esphome/components/ledc/ledc_output.cpp b/esphome/components/ledc/ledc_output.cpp index 592fc7bd0c..a3d1e4d392 100644 --- a/esphome/components/ledc/ledc_output.cpp +++ b/esphome/components/ledc/ledc_output.cpp @@ -5,10 +5,9 @@ #include #include +#include #include -#if !defined(SOC_LEDC_SUPPORT_FADE_STOP) #include -#endif #define CLOCK_FREQUENCY 80e6f @@ -161,7 +160,14 @@ void LEDCOutput::write_state(float state) { void LEDCOutput::setup() { if (!ledc_peripheral_reset_done) { ESP_LOGV(TAG, "Resetting LEDC peripheral to clear stale state after reboot"); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0) + PERIPH_RCC_ATOMIC() { + ledc_ll_enable_reset_reg(true); + ledc_ll_enable_reset_reg(false); + } +#else periph_module_reset(PERIPH_LEDC_MODULE); +#endif ledc_peripheral_reset_done = true; } diff --git a/esphome/components/mipi_dsi/mipi_dsi.cpp b/esphome/components/mipi_dsi/mipi_dsi.cpp index 7103e0868d..e8e9ca2bfb 100644 --- a/esphome/components/mipi_dsi/mipi_dsi.cpp +++ b/esphome/components/mipi_dsi/mipi_dsi.cpp @@ -87,7 +87,9 @@ void MIPI_DSI::setup() { .vsync_front_porch = this->vsync_front_porch_, }, .flags = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0) .use_dma2d = true, +#endif }}; // clang-format on err = esp_lcd_new_panel_dpi(this->bus_handle_, &dpi_config, &this->handle_); @@ -95,6 +97,13 @@ void MIPI_DSI::setup() { this->smark_failed(LOG_STR("esp_lcd_new_panel_dpi failed"), err); return; } +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0) + err = esp_lcd_dpi_panel_enable_dma2d(this->handle_); + if (err != ESP_OK) { + this->smark_failed(LOG_STR("esp_lcd_dpi_panel_enable_dma2d failed"), err); + return; + } +#endif if (this->reset_pin_ != nullptr) { this->reset_pin_->setup(); this->reset_pin_->digital_write(true); diff --git a/esphome/components/online_image/online_image.cpp b/esphome/components/online_image/online_image.cpp index da866599c9..22bf6a3056 100644 --- a/esphome/components/online_image/online_image.cpp +++ b/esphome/components/online_image/online_image.cpp @@ -129,7 +129,7 @@ void OnlineImage::update() { } ESP_LOGI(TAG, "Downloading image (Size: %zu)", total_size); - this->start_time_ = ::time(nullptr); + this->start_time_ = millis(); this->enable_loop(); } @@ -155,8 +155,8 @@ void OnlineImage::loop() { // Finalize decoding this->end_decode(); - ESP_LOGD(TAG, "Image fully downloaded, %zu bytes in %" PRIu32 "s", this->downloader_->get_bytes_read(), - (uint32_t) (::time(nullptr) - this->start_time_)); + ESP_LOGD(TAG, "Image fully downloaded, %zu bytes in %" PRIu32 " ms", this->downloader_->get_bytes_read(), + millis() - this->start_time_); // Save caching headers this->etag_ = this->downloader_->get_response_header(ETAG_HEADER_NAME); diff --git a/esphome/components/online_image/online_image.h b/esphome/components/online_image/online_image.h index c7c80c7c66..12c2564526 100644 --- a/esphome/components/online_image/online_image.h +++ b/esphome/components/online_image/online_image.h @@ -97,7 +97,7 @@ class OnlineImage : public PollingComponent, */ std::string last_modified_ = ""; - time_t start_time_; + uint32_t start_time_{0}; }; template class OnlineImageSetUrlAction : public Action { diff --git a/esphome/components/output/float_output.cpp b/esphome/components/output/float_output.cpp index 3b83c85716..46014e0903 100644 --- a/esphome/components/output/float_output.cpp +++ b/esphome/components/output/float_output.cpp @@ -11,16 +11,10 @@ void FloatOutput::set_max_power(float max_power) { this->max_power_ = clamp(max_power, this->min_power_, 1.0f); // Clamp to MIN>=MAX>=1.0 } -float FloatOutput::get_max_power() const { return this->max_power_; } - void FloatOutput::set_min_power(float min_power) { this->min_power_ = clamp(min_power, 0.0f, this->max_power_); // Clamp to 0.0>=MIN>=MAX } -void FloatOutput::set_zero_means_zero(bool zero_means_zero) { this->zero_means_zero_ = zero_means_zero; } - -float FloatOutput::get_min_power() const { return this->min_power_; } - void FloatOutput::set_level(float state) { state = clamp(state, 0.0f, 1.0f); diff --git a/esphome/components/output/float_output.h b/esphome/components/output/float_output.h index 3e2b3ada8d..5225f88c66 100644 --- a/esphome/components/output/float_output.h +++ b/esphome/components/output/float_output.h @@ -48,9 +48,9 @@ class FloatOutput : public BinaryOutput { /** Sets this output to ignore min_power for a 0 state * - * @param zero True if a 0 state should mean 0 and not min_power. + * @param zero_means_zero True if a 0 state should mean 0 and not min_power. */ - void set_zero_means_zero(bool zero_means_zero); + void set_zero_means_zero(bool zero_means_zero) { this->zero_means_zero_ = zero_means_zero; } /** Set the level of this float output, this is called from the front-end. * @@ -70,10 +70,10 @@ class FloatOutput : public BinaryOutput { // (In most use cases you won't need these) /// Get the maximum power output. - float get_max_power() const; + float get_max_power() const { return this->max_power_; } /// Get the minimum power output. - float get_min_power() const; + float get_min_power() const { return this->min_power_; } protected: /// Implement BinarySensor's write_enabled; this should never be called. diff --git a/esphome/components/psram/__init__.py b/esphome/components/psram/__init__.py index 39afb407f1..9b364584ff 100644 --- a/esphome/components/psram/__init__.py +++ b/esphome/components/psram/__init__.py @@ -8,6 +8,7 @@ from esphome.components.esp32 import ( CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES, VARIANT_ESP32, VARIANT_ESP32C5, + VARIANT_ESP32C61, VARIANT_ESP32P4, VARIANT_ESP32S2, VARIANT_ESP32S3, @@ -53,6 +54,7 @@ CONF_ENABLE_ECC = "enable_ecc" SPIRAM_MODES = { VARIANT_ESP32: (TYPE_QUAD,), VARIANT_ESP32C5: (TYPE_QUAD,), + VARIANT_ESP32C61: (TYPE_QUAD,), VARIANT_ESP32S2: (TYPE_QUAD,), VARIANT_ESP32S3: (TYPE_QUAD, TYPE_OCTAL), VARIANT_ESP32P4: (TYPE_HEX,), @@ -62,6 +64,7 @@ SPIRAM_MODES = { SPIRAM_SPEEDS = { VARIANT_ESP32: (40, 80, 120), VARIANT_ESP32C5: (40, 80, 120), + VARIANT_ESP32C61: (40, 80), VARIANT_ESP32S2: (40, 80, 120), VARIANT_ESP32S3: (40, 80, 120), VARIANT_ESP32P4: (20, 100, 200), @@ -178,9 +181,6 @@ async def to_code(config): if config[CONF_MODE] == TYPE_OCTAL: cg.add_platformio_option("board_build.arduino.memory_type", "qio_opi") - add_idf_sdkconfig_option( - f"CONFIG_{get_esp32_variant().upper()}_SPIRAM_SUPPORT", True - ) add_idf_sdkconfig_option("CONFIG_SOC_SPIRAM_SUPPORTED", True) add_idf_sdkconfig_option("CONFIG_SPIRAM", True) add_idf_sdkconfig_option("CONFIG_SPIRAM_USE", True) @@ -195,11 +195,19 @@ async def to_code(config): speed = int(config[CONF_SPEED][:-3]) add_idf_sdkconfig_option(f"CONFIG_SPIRAM_SPEED_{speed}M", True) add_idf_sdkconfig_option("CONFIG_SPIRAM_SPEED", speed) - if config[CONF_MODE] == TYPE_OCTAL and speed == 120: - add_idf_sdkconfig_option("CONFIG_ESPTOOLPY_FLASHFREQ_120M", True) - if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(5, 4, 0): + if speed == 120: + variant = get_esp32_variant() + # On chips with MSPI timing tuning, FLASH and PSRAM share the core + # clock so flash frequency must match PSRAM frequency. + # ESP32 and ESP32-S2 don't have this constraint. + if variant not in (VARIANT_ESP32, VARIANT_ESP32S2): + add_idf_sdkconfig_option("CONFIG_ESPTOOLPY_FLASHFREQ_120M", True) + if config[CONF_MODE] == TYPE_OCTAL and CORE.data[KEY_CORE][ + KEY_FRAMEWORK_VERSION + ] >= cv.Version(5, 4, 0): add_idf_sdkconfig_option( - "CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", True + "CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", + True, ) if config[CONF_ENABLE_ECC]: add_idf_sdkconfig_option("CONFIG_SPIRAM_ECC_ENABLE", True) diff --git a/esphome/components/sha256/sha256.cpp b/esphome/components/sha256/sha256.cpp index 23995e6534..079665c959 100644 --- a/esphome/components/sha256/sha256.cpp +++ b/esphome/components/sha256/sha256.cpp @@ -8,7 +8,28 @@ namespace esphome::sha256 { -#if defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_SHA256_PSA) + +// ESP-IDF 6.0 ships mbedtls 4.0 which removed the legacy mbedtls_sha256_* API. +// Use the PSA Crypto API instead. PSA crypto is auto-initialized by ESP-IDF +// at startup, so no psa_crypto_init() call is needed. + +SHA256::~SHA256() { psa_hash_abort(&this->op_); } + +void SHA256::init() { + psa_hash_abort(&this->op_); + this->op_ = PSA_HASH_OPERATION_INIT; + psa_hash_setup(&this->op_, PSA_ALG_SHA_256); +} + +void SHA256::add(const uint8_t *data, size_t len) { psa_hash_update(&this->op_, data, len); } + +void SHA256::calculate() { + size_t hash_length; + psa_hash_finish(&this->op_, this->digest_, sizeof(this->digest_), &hash_length); +} + +#elif defined(USE_SHA256_MBEDTLS) // CRITICAL ESP32 HARDWARE SHA ACCELERATION REQUIREMENTS (IDF 5.5.x): // diff --git a/esphome/components/sha256/sha256.h b/esphome/components/sha256/sha256.h index bafb359485..0f995fcd91 100644 --- a/esphome/components/sha256/sha256.h +++ b/esphome/components/sha256/sha256.h @@ -10,7 +10,20 @@ #include #include "esphome/core/hash_base.h" -#if defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_ESP32) +#include +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0) +// mbedtls 4.0 (IDF 6.0) removed the legacy mbedtls_sha256_* API. +// Use the PSA Crypto API instead. PSA crypto is auto-initialized by +// ESP-IDF at startup (esp_psa_crypto_init.c, priority 104). +#define USE_SHA256_PSA +#include +#else +#define USE_SHA256_MBEDTLS +#include "mbedtls/sha256.h" +#endif +#elif defined(USE_LIBRETINY) +#define USE_SHA256_MBEDTLS #include "mbedtls/sha256.h" #elif defined(USE_ESP8266) || defined(USE_RP2040) #include @@ -51,7 +64,9 @@ class SHA256 : public esphome::HashBase { size_t get_size() const override { return 32; } protected: -#if defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_SHA256_PSA) + psa_hash_operation_t op_ = PSA_HASH_OPERATION_INIT; +#elif defined(USE_SHA256_MBEDTLS) // The mbedtls context for ESP32-S3 hardware SHA requires proper alignment and stack frame constraints. // See class documentation above for critical requirements. mbedtls_sha256_context ctx_{}; diff --git a/esphome/components/tinyusb/__init__.py b/esphome/components/tinyusb/__init__.py index 90043e969c..df94ad7534 100644 --- a/esphome/components/tinyusb/__init__.py +++ b/esphome/components/tinyusb/__init__.py @@ -54,7 +54,7 @@ async def to_code(config): if config[CONF_USB_SERIAL_STR]: cg.add(var.set_usb_desc_serial(config[CONF_USB_SERIAL_STR])) - add_idf_component(name="espressif/esp_tinyusb", ref="1.7.6~1") + add_idf_component(name="espressif/esp_tinyusb", ref="2.1.1") add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID", False) add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_USE_DEFAULT_PID", False) diff --git a/esphome/components/tinyusb/tinyusb_component.cpp b/esphome/components/tinyusb/tinyusb_component.cpp index 19bb545c4b..7f8fea5264 100644 --- a/esphome/components/tinyusb/tinyusb_component.cpp +++ b/esphome/components/tinyusb/tinyusb_component.cpp @@ -16,10 +16,14 @@ void TinyUSB::setup() { } this->tusb_cfg_ = { - .descriptor = &this->usb_descriptor_, - .string_descriptor = this->string_descriptor_, - .string_descriptor_count = SIZE, - .external_phy = false, + .port = TINYUSB_PORT_FULL_SPEED_0, + .phy = {.skip_setup = false}, + .descriptor = + { + .device = &this->usb_descriptor_, + .string = this->string_descriptor_, + .string_count = SIZE, + }, }; esp_err_t result = tinyusb_driver_install(&this->tusb_cfg_); diff --git a/esphome/components/usb_cdc_acm/usb_cdc_acm.h b/esphome/components/usb_cdc_acm/usb_cdc_acm.h index 624f41cf8c..020542e749 100644 --- a/esphome/components/usb_cdc_acm/usb_cdc_acm.h +++ b/esphome/components/usb_cdc_acm/usb_cdc_acm.h @@ -8,7 +8,7 @@ #include #include "freertos/ringbuf.h" -#include "tusb_cdc_acm.h" +#include "tinyusb_cdc_acm.h" namespace esphome::usb_cdc_acm { diff --git a/esphome/components/usb_cdc_acm/usb_cdc_acm_esp32.cpp b/esphome/components/usb_cdc_acm/usb_cdc_acm_esp32.cpp index 1a36ef9f31..583aa77d06 100644 --- a/esphome/components/usb_cdc_acm/usb_cdc_acm_esp32.cpp +++ b/esphome/components/usb_cdc_acm/usb_cdc_acm_esp32.cpp @@ -11,7 +11,7 @@ #include "esp_log.h" #include "tusb.h" -#include "tusb_cdc_acm.h" +#include "tinyusb_cdc_acm.h" namespace esphome::usb_cdc_acm { @@ -140,7 +140,6 @@ void USBCDCACMInstance::setup() { // Configure this CDC interface const tinyusb_config_cdcacm_t acm_cfg = { - .usb_dev = TINYUSB_USBDEV_0, .cdc_port = static_cast(this->itf_), .callback_rx = &tinyusb_cdc_rx_callback, .callback_rx_wanted_char = NULL, @@ -148,9 +147,9 @@ void USBCDCACMInstance::setup() { .callback_line_coding_changed = &tinyusb_cdc_line_coding_changed_callback, }; - esp_err_t result = tusb_cdc_acm_init(&acm_cfg); + esp_err_t result = tinyusb_cdcacm_init(&acm_cfg); if (result != ESP_OK) { - ESP_LOGE(TAG, "tusb_cdc_acm_init failed: %d", result); + ESP_LOGE(TAG, "tinyusb_cdcacm_init failed: %d", result); this->parent_->mark_failed(); return; } diff --git a/esphome/idf_component.yml b/esphome/idf_component.yml index df651ae15d..bb94de7e05 100644 --- a/esphome/idf_component.yml +++ b/esphome/idf_component.yml @@ -8,7 +8,7 @@ dependencies: espressif/esp-tflite-micro: version: 1.3.3~1 espressif/esp32-camera: - version: 2.1.1 + version: 2.1.5 espressif/mdns: version: 1.10.0 espressif/esp_wifi_remote: @@ -30,7 +30,7 @@ dependencies: rules: - if: "target in [esp32, esp32p4]" espressif/esp_tinyusb: - version: "1.7.6~1" + version: "2.1.1" rules: - if: "target in [esp32s2, esp32s3, esp32p4]" esphome/esp-hub75: diff --git a/tests/components/psram/test.esp32-c61-idf.yaml b/tests/components/psram/test.esp32-c61-idf.yaml new file mode 100644 index 0000000000..d443aab951 --- /dev/null +++ b/tests/components/psram/test.esp32-c61-idf.yaml @@ -0,0 +1,7 @@ +esp32: + framework: + type: esp-idf + +psram: + speed: 80MHz + ignore_not_found: false