mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[esp_ldo] Implement support for ESP32-P4 LDO (#9009)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -150,6 +150,7 @@ esphome/components/esp32_improv/* @jesserockz | |||||||
| esphome/components/esp32_rmt/* @jesserockz | esphome/components/esp32_rmt/* @jesserockz | ||||||
| esphome/components/esp32_rmt_led_strip/* @jesserockz | esphome/components/esp32_rmt_led_strip/* @jesserockz | ||||||
| esphome/components/esp8266/* @esphome/core | esphome/components/esp8266/* @esphome/core | ||||||
|  | esphome/components/esp_ldo/* @clydebarrow | ||||||
| esphome/components/ethernet_info/* @gtjadsonsantos | esphome/components/ethernet_info/* @gtjadsonsantos | ||||||
| esphome/components/event/* @nohat | esphome/components/event/* @nohat | ||||||
| esphome/components/event_emitter/* @Rapsssito | esphome/components/event_emitter/* @Rapsssito | ||||||
|   | |||||||
							
								
								
									
										91
									
								
								esphome/components/esp_ldo/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								esphome/components/esp_ldo/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | from esphome.automation import Action, register_action | ||||||
|  | import esphome.codegen as cg | ||||||
|  | from esphome.components.esp32 import VARIANT_ESP32P4, only_on_variant | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.const import CONF_CHANNEL, CONF_ID, CONF_VOLTAGE | ||||||
|  | from esphome.final_validate import full_config | ||||||
|  |  | ||||||
|  | CODEOWNERS = ["@clydebarrow"] | ||||||
|  |  | ||||||
|  | DOMAIN = "esp_ldo" | ||||||
|  |  | ||||||
|  | esp_ldo_ns = cg.esphome_ns.namespace("esp_ldo") | ||||||
|  | EspLdo = esp_ldo_ns.class_("EspLdo", cg.Component) | ||||||
|  | AdjustAction = esp_ldo_ns.class_("AdjustAction", Action) | ||||||
|  |  | ||||||
|  | CHANNELS = (3, 4) | ||||||
|  | CONF_ADJUSTABLE = "adjustable" | ||||||
|  |  | ||||||
|  | adjusted_ids = set() | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.All( | ||||||
|  |     cv.ensure_list( | ||||||
|  |         { | ||||||
|  |             cv.GenerateID(): cv.declare_id(EspLdo), | ||||||
|  |             cv.Required(CONF_VOLTAGE): cv.All( | ||||||
|  |                 cv.voltage, cv.float_range(min=0.5, max=2.7) | ||||||
|  |             ), | ||||||
|  |             cv.Required(CONF_CHANNEL): cv.one_of(*CHANNELS, int=True), | ||||||
|  |             cv.Optional(CONF_ADJUSTABLE, default=False): cv.boolean, | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  |     cv.only_with_esp_idf, | ||||||
|  |     only_on_variant(supported=[VARIANT_ESP32P4]), | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(configs): | ||||||
|  |     for config in configs: | ||||||
|  |         var = cg.new_Pvariable(config[CONF_ID], config[CONF_CHANNEL]) | ||||||
|  |         await cg.register_component(var, config) | ||||||
|  |         cg.add(var.set_voltage(config[CONF_VOLTAGE])) | ||||||
|  |         cg.add(var.set_adjustable(config[CONF_ADJUSTABLE])) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def final_validate(configs): | ||||||
|  |     for channel in CHANNELS: | ||||||
|  |         used = [config for config in configs if config[CONF_CHANNEL] == channel] | ||||||
|  |         if len(used) > 1: | ||||||
|  |             raise cv.Invalid( | ||||||
|  |                 f"Multiple LDOs configured for channel {channel}. Each channel must be unique.", | ||||||
|  |                 path=[CONF_CHANNEL, channel], | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |     global_config = full_config.get() | ||||||
|  |     for w in adjusted_ids: | ||||||
|  |         path = global_config.get_path_for_id(w) | ||||||
|  |         ldo_conf = global_config.get_config_for_path(path[:-1]) | ||||||
|  |         if not ldo_conf[CONF_ADJUSTABLE]: | ||||||
|  |             raise cv.Invalid( | ||||||
|  |                 "A non adjustable LDO may not be adjusted.", | ||||||
|  |                 path, | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | FINAL_VALIDATE_SCHEMA = final_validate | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def adjusted_ldo_id(value): | ||||||
|  |     value = cv.use_id(EspLdo)(value) | ||||||
|  |     adjusted_ids.add(value) | ||||||
|  |     return value | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_action( | ||||||
|  |     "esp_ldo.voltage.adjust", | ||||||
|  |     AdjustAction, | ||||||
|  |     cv.Schema( | ||||||
|  |         { | ||||||
|  |             cv.GenerateID(CONF_ID): adjusted_ldo_id, | ||||||
|  |             cv.Required(CONF_VOLTAGE): cv.templatable( | ||||||
|  |                 cv.All(cv.voltage, cv.float_range(min=0.5, max=2.7)) | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  | ) | ||||||
|  | async def ldo_voltage_adjust_to_code(config, action_id, template_arg, args): | ||||||
|  |     parent = await cg.get_variable(config[CONF_ID]) | ||||||
|  |     var = cg.new_Pvariable(action_id, template_arg, parent) | ||||||
|  |     template_ = await cg.templatable(config[CONF_VOLTAGE], args, cg.float_) | ||||||
|  |     cg.add(var.set_voltage(template_)) | ||||||
|  |     return var | ||||||
							
								
								
									
										43
									
								
								esphome/components/esp_ldo/esp_ldo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								esphome/components/esp_ldo/esp_ldo.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | #ifdef USE_ESP32_VARIANT_ESP32P4 | ||||||
|  | #include "esp_ldo.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace esp_ldo { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "esp_ldo"; | ||||||
|  | void EspLdo::setup() { | ||||||
|  |   esp_ldo_channel_config_t config{}; | ||||||
|  |   config.chan_id = this->channel_; | ||||||
|  |   config.voltage_mv = (int) (this->voltage_ * 1000.0f); | ||||||
|  |   config.flags.adjustable = this->adjustable_; | ||||||
|  |   auto err = esp_ldo_acquire_channel(&config, &this->handle_); | ||||||
|  |   if (err != ESP_OK) { | ||||||
|  |     auto msg = str_sprintf("Failed to acquire LDO channel %d with voltage %fV", this->channel_, this->voltage_); | ||||||
|  |     this->mark_failed(msg.c_str()); | ||||||
|  |   } else { | ||||||
|  |     ESP_LOGD(TAG, "Acquired LDO channel %d with voltage %fV", this->channel_, this->voltage_); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | void EspLdo::dump_config() { | ||||||
|  |   ESP_LOGCONFIG(TAG, "ESP LDO Channel %d:", this->channel_); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Voltage: %fV", this->voltage_); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Adjustable: %s", YESNO(this->adjustable_)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EspLdo::adjust_voltage(float voltage) { | ||||||
|  |   if (!std::isfinite(voltage) || voltage < 0.5f || voltage > 2.7f) { | ||||||
|  |     ESP_LOGE(TAG, "Invalid voltage %fV for LDO channel %d", voltage, this->channel_); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   auto erro = esp_ldo_channel_adjust_voltage(this->handle_, (int) (voltage * 1000.0f)); | ||||||
|  |   if (erro != ESP_OK) { | ||||||
|  |     ESP_LOGE(TAG, "Failed to adjust LDO channel %d to voltage %fV: %s", this->channel_, voltage, esp_err_to_name(erro)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace esp_ldo | ||||||
|  | }  // namespace esphome | ||||||
|  |  | ||||||
|  | #endif  // USE_ESP32_VARIANT_ESP32P4 | ||||||
							
								
								
									
										43
									
								
								esphome/components/esp_ldo/esp_ldo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								esphome/components/esp_ldo/esp_ldo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | #pragma once | ||||||
|  | #ifdef USE_ESP32_VARIANT_ESP32P4 | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/core/automation.h" | ||||||
|  | #include "esp_ldo_regulator.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace esp_ldo { | ||||||
|  |  | ||||||
|  | class EspLdo : public Component { | ||||||
|  |  public: | ||||||
|  |   EspLdo(int channel) : channel_(channel) {} | ||||||
|  |  | ||||||
|  |   void setup() override; | ||||||
|  |   void dump_config() override; | ||||||
|  |  | ||||||
|  |   void set_adjustable(bool adjustable) { this->adjustable_ = adjustable; } | ||||||
|  |   void set_voltage(float voltage) { this->voltage_ = voltage; } | ||||||
|  |   void adjust_voltage(float voltage); | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   int channel_; | ||||||
|  |   float voltage_{2.7}; | ||||||
|  |   bool adjustable_{false}; | ||||||
|  |   esp_ldo_channel_handle_t handle_{}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<typename... Ts> class AdjustAction : public Action<Ts...> { | ||||||
|  |  public: | ||||||
|  |   explicit AdjustAction(EspLdo *ldo) : ldo_(ldo) {} | ||||||
|  |  | ||||||
|  |   TEMPLATABLE_VALUE(float, voltage) | ||||||
|  |  | ||||||
|  |   void play(Ts... x) override { this->ldo_->adjust_voltage(this->voltage_.value(x...)); } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   EspLdo *ldo_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace esp_ldo | ||||||
|  | }  // namespace esphome | ||||||
|  |  | ||||||
|  | #endif  // USE_ESP32_VARIANT_ESP32P4 | ||||||
							
								
								
									
										15
									
								
								tests/components/esp_ldo/test.esp32-p4-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/components/esp_ldo/test.esp32-p4-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | esp_ldo: | ||||||
|  |   - id: ldo_id | ||||||
|  |     channel: 3 | ||||||
|  |     voltage: 2.5V | ||||||
|  |     adjustable: true | ||||||
|  |   - id: ldo_4 | ||||||
|  |     channel: 4 | ||||||
|  |     voltage: 2.0V | ||||||
|  |  | ||||||
|  | esphome: | ||||||
|  |   on_boot: | ||||||
|  |     then: | ||||||
|  |       - esp_ldo.voltage.adjust: | ||||||
|  |           id: ldo_id | ||||||
|  |           voltage: !lambda return 2.5; | ||||||
		Reference in New Issue
	
	Block a user