diff --git a/esphome/components/esp32_dac/esp32_dac.cpp b/esphome/components/esp32_dac/esp32_dac.cpp index 7f37e2ce47..6f1577b8b1 100644 --- a/esphome/components/esp32_dac/esp32_dac.cpp +++ b/esphome/components/esp32_dac/esp32_dac.cpp @@ -7,13 +7,16 @@ #ifdef USE_ARDUINO #include #endif -#ifdef USE_ESP_IDF -#include -#endif namespace esphome { namespace esp32_dac { +#ifdef USE_ESP32_VARIANT_ESP32S2 +static constexpr uint8_t DAC0_PIN = 17; +#else +static constexpr uint8_t DAC0_PIN = 25; +#endif + static const char *const TAG = "esp32_dac"; void ESP32DAC::setup() { @@ -22,8 +25,15 @@ void ESP32DAC::setup() { this->turn_off(); #ifdef USE_ESP_IDF - auto channel = pin_->get_pin() == 25 ? DAC_CHANNEL_1 : DAC_CHANNEL_2; - dac_output_enable(channel); + const dac_channel_t channel = this->pin_->get_pin() == DAC0_PIN ? DAC_CHAN_0 : DAC_CHAN_1; + const dac_oneshot_config_t oneshot_cfg{channel}; + dac_oneshot_new_channel(&oneshot_cfg, &this->dac_handle_); +#endif +} + +void ESP32DAC::on_safe_shutdown() { +#ifdef USE_ESP_IDF + dac_oneshot_del_channel(this->dac_handle_); #endif } @@ -40,8 +50,7 @@ void ESP32DAC::write_state(float state) { state = state * 255; #ifdef USE_ESP_IDF - auto channel = pin_->get_pin() == 25 ? DAC_CHANNEL_1 : DAC_CHANNEL_2; - dac_output_voltage(channel, (uint8_t) state); + dac_oneshot_output_voltage(this->dac_handle_, state); #endif #ifdef USE_ARDUINO dacWrite(this->pin_->get_pin(), state); diff --git a/esphome/components/esp32_dac/esp32_dac.h b/esphome/components/esp32_dac/esp32_dac.h index 0fb1ddebf0..63d0c914a1 100644 --- a/esphome/components/esp32_dac/esp32_dac.h +++ b/esphome/components/esp32_dac/esp32_dac.h @@ -7,6 +7,10 @@ #ifdef USE_ESP32 +#ifdef USE_ESP_IDF +#include +#endif + namespace esphome { namespace esp32_dac { @@ -16,6 +20,7 @@ class ESP32DAC : public output::FloatOutput, public Component { /// Initialize pin void setup() override; + void on_safe_shutdown() override; void dump_config() override; /// HARDWARE setup_priority float get_setup_priority() const override { return setup_priority::HARDWARE; } @@ -24,6 +29,9 @@ class ESP32DAC : public output::FloatOutput, public Component { void write_state(float state) override; InternalGPIOPin *pin_; +#ifdef USE_ESP_IDF + dac_oneshot_handle_t dac_handle_; +#endif }; } // namespace esp32_dac diff --git a/esphome/components/esp32_dac/output.py b/esphome/components/esp32_dac/output.py index f119198618..c80780986f 100644 --- a/esphome/components/esp32_dac/output.py +++ b/esphome/components/esp32_dac/output.py @@ -1,15 +1,27 @@ +import esphome.codegen as cg +import esphome.config_validation as cv from esphome import pins from esphome.components import output -import esphome.config_validation as cv -import esphome.codegen as cg +from esphome.components.esp32 import get_esp32_variant +from esphome.components.esp32.const import VARIANT_ESP32, VARIANT_ESP32S2 from esphome.const import CONF_ID, CONF_NUMBER, CONF_PIN DEPENDENCIES = ["esp32"] +DAC_PINS = { + VARIANT_ESP32: (25, 26), + VARIANT_ESP32S2: (17, 18), +} + def valid_dac_pin(value): - num = value[CONF_NUMBER] - cv.one_of(25, 26)(num) + variant = get_esp32_variant() + try: + valid_pins = DAC_PINS[variant] + except KeyError as ex: + raise cv.Invalid(f"DAC is not supported on {variant}") from ex + given_pin = value[CONF_NUMBER] + cv.one_of(*valid_pins)(given_pin) return value