diff --git a/CODEOWNERS b/CODEOWNERS index 4eb4c42a6d..832c571ae4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -146,6 +146,7 @@ esphome/components/esp32_ble_client/* @jesserockz esphome/components/esp32_ble_server/* @Rapsssito @clydebarrow @jesserockz esphome/components/esp32_camera_web_server/* @ayufan esphome/components/esp32_can/* @Sympatron +esphome/components/esp32_hosted/* @swoboda1337 esphome/components/esp32_improv/* @jesserockz esphome/components/esp32_rmt/* @jesserockz esphome/components/esp32_rmt_led_strip/* @jesserockz diff --git a/esphome/components/esp32_hosted/__init__.py b/esphome/components/esp32_hosted/__init__.py new file mode 100644 index 0000000000..330800df12 --- /dev/null +++ b/esphome/components/esp32_hosted/__init__.py @@ -0,0 +1,101 @@ +import os + +from esphome import pins +from esphome.components import esp32 +import esphome.config_validation as cv +from esphome.const import ( + CONF_CLK_PIN, + CONF_RESET_PIN, + CONF_VARIANT, + KEY_CORE, + KEY_FRAMEWORK_VERSION, +) +from esphome.core import CORE + +CODEOWNERS = ["@swoboda1337"] + +CONF_ACTIVE_HIGH = "active_high" +CONF_CMD_PIN = "cmd_pin" +CONF_D0_PIN = "d0_pin" +CONF_D1_PIN = "d1_pin" +CONF_D2_PIN = "d2_pin" +CONF_D3_PIN = "d3_pin" +CONF_SLOT = "slot" + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.Required(CONF_VARIANT): cv.one_of(*esp32.VARIANTS, upper=True), + cv.Required(CONF_ACTIVE_HIGH): cv.boolean, + cv.Required(CONF_CLK_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_CMD_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_D0_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_D1_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_D2_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_D3_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_RESET_PIN): pins.internal_gpio_output_pin_number, + cv.Optional(CONF_SLOT, default=1): cv.int_range(min=0, max=1), + } + ), +) + + +async def to_code(config): + if config[CONF_ACTIVE_HIGH]: + esp32.add_idf_sdkconfig_option( + "CONFIG_ESP_HOSTED_SDIO_RESET_ACTIVE_HIGH", + True, + ) + else: + esp32.add_idf_sdkconfig_option( + "CONFIG_ESP_HOSTED_SDIO_RESET_ACTIVE_LOW", + True, + ) + esp32.add_idf_sdkconfig_option( + "CONFIG_ESP_HOSTED_SDIO_GPIO_RESET_SLAVE", # NOLINT + config[CONF_RESET_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_SLAVE_IDF_TARGET_{config[CONF_VARIANT]}", # NOLINT + True, + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_SDIO_SLOT_{config[CONF_SLOT]}", + True, + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_CLK_SLOT_{config[CONF_SLOT]}", + config[CONF_CLK_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_CMD_SLOT_{config[CONF_SLOT]}", + config[CONF_CMD_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D0_SLOT_{config[CONF_SLOT]}", + config[CONF_D0_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D1_4BIT_BUS_SLOT_{config[CONF_SLOT]}", + config[CONF_D1_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D2_4BIT_BUS_SLOT_{config[CONF_SLOT]}", + config[CONF_D2_PIN], + ) + esp32.add_idf_sdkconfig_option( + f"CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D3_4BIT_BUS_SLOT_{config[CONF_SLOT]}", + config[CONF_D3_PIN], + ) + esp32.add_idf_sdkconfig_option("CONFIG_ESP_HOSTED_CUSTOM_SDIO_PINS", True) + + framework_ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] + os.environ["ESP_IDF_VERSION"] = f"{framework_ver.major}.{framework_ver.minor}" + esp32.add_idf_component(name="espressif/esp_wifi_remote", ref="0.10.2") + esp32.add_idf_component(name="espressif/eppp_link", ref="0.2.0") + esp32.add_idf_component(name="espressif/esp_hosted", ref="2.0.11") + esp32.add_extra_script( + "post", + "esp32_hosted.py", + os.path.join(os.path.dirname(__file__), "esp32_hosted.py.script"), + ) diff --git a/esphome/components/esp32_hosted/esp32_hosted.py.script b/esphome/components/esp32_hosted/esp32_hosted.py.script new file mode 100644 index 0000000000..4be297c500 --- /dev/null +++ b/esphome/components/esp32_hosted/esp32_hosted.py.script @@ -0,0 +1,12 @@ +# pylint: disable=E0602 +Import("env") # noqa + +# Workaround whole archive issue +if "__LIB_DEPS" in env and "libespressif__esp_hosted.a" in env["__LIB_DEPS"]: + env.Append( + LINKFLAGS=[ + "-Wl,--whole-archive", + env["BUILD_DIR"] + "/esp-idf/espressif__esp_hosted/libespressif__esp_hosted.a", + "-Wl,--no-whole-archive", + ] + ) diff --git a/esphome/idf_component.yml b/esphome/idf_component.yml index 8460de5638..7dcfe918eb 100644 --- a/esphome/idf_component.yml +++ b/esphome/idf_component.yml @@ -11,3 +11,15 @@ dependencies: path: components/mdns rules: - if: "idf_version >=5.0" + espressif/esp_wifi_remote: + version: 0.10.2 + rules: + - if: "target in [esp32h2, esp32p4]" + espressif/eppp_link: + version: 0.2.0 + rules: + - if: "target in [esp32h2, esp32p4]" + espressif/esp_hosted: + version: 2.0.11 + rules: + - if: "target in [esp32h2, esp32p4]" diff --git a/tests/components/esp32_hosted/common.yaml b/tests/components/esp32_hosted/common.yaml new file mode 100644 index 0000000000..ab029e5064 --- /dev/null +++ b/tests/components/esp32_hosted/common.yaml @@ -0,0 +1,15 @@ +esp32_hosted: + variant: ESP32C6 + slot: 1 + active_high: true + reset_pin: GPIO15 + cmd_pin: GPIO13 + clk_pin: GPIO12 + d0_pin: GPIO11 + d1_pin: GPIO10 + d2_pin: GPIO9 + d3_pin: GPIO8 + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/esp32_hosted/test.esp32-p4-idf.yaml b/tests/components/esp32_hosted/test.esp32-p4-idf.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/esp32_hosted/test.esp32-p4-idf.yaml @@ -0,0 +1 @@ +<<: !include common.yaml