mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refactor/remove_legacy_ldo_driver' into 'master'
refactor(ldo): remove legacy private ldo driver Closes IDF-9566 See merge request espressif/esp-idf!29834
This commit is contained in:
commit
b2afd70b32
@ -78,7 +78,7 @@ if(NOT BOOTLOADER_BUILD)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SOC_GP_LDO_SUPPORTED)
|
if(CONFIG_SOC_GP_LDO_SUPPORTED)
|
||||||
list(APPEND srcs "ldo/esp_ldo.c" "ldo/esp_ldo_regulator.c")
|
list(APPEND srcs "ldo/esp_ldo_regulator.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED)
|
if(CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED)
|
||||||
|
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "esp_err.h"
|
|
||||||
#include "hal/ldo_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of LDO unit handle
|
|
||||||
*/
|
|
||||||
typedef struct ldo_unit_ctx_t *esp_ldo_unit_handle_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LDO unit configurations
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int voltage_mv; ///< LDO output voltage in mV
|
|
||||||
} esp_ldo_unit_cfg_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LDO driver initial configurations
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int unit_id; ///< LDO ID, this is aligned with datasheet, e.g. you should set this to 1, if using LDO ID 1
|
|
||||||
esp_ldo_unit_cfg_t cfg; ///< LDO unit configuration
|
|
||||||
struct {
|
|
||||||
uint32_t enable_unit: 1; ///< Enable the LDO unit after it's initialised
|
|
||||||
uint32_t shared_ldo: 1; ///< Mark this LDO unit as shared
|
|
||||||
} flags; ///< LDO unit flags
|
|
||||||
} esp_ldo_unit_init_cfg_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Init a LDO during early stage
|
|
||||||
*
|
|
||||||
* @note This API is only for early stage usage
|
|
||||||
*
|
|
||||||
* @param[in] unit_id LDO unit ID
|
|
||||||
* @param[in] cfg LDO unit configuration
|
|
||||||
*
|
|
||||||
* @return LDO unit handle
|
|
||||||
*/
|
|
||||||
esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *init_config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Init a LDO
|
|
||||||
*
|
|
||||||
* @param[in] init_config LDO initial configurations
|
|
||||||
* @param[out] ret_unit LDO unit handle
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK: On success
|
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
|
||||||
* - ESP_ERR_NOT_FOUND: LDO unit is in use already
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_init_unit(const esp_ldo_unit_init_cfg_t *init_config, esp_ldo_unit_handle_t *ret_unit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable a LDO
|
|
||||||
*
|
|
||||||
* @param[in] unit LDO unit handle
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK: On success
|
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
|
||||||
* - ESP_ERR_INVALID_STATE: LDO is enabled already
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set LDO output voltage
|
|
||||||
*
|
|
||||||
* @param[in] unit LDO unit handle
|
|
||||||
* @param[in] voltage_mv Voltage in mV
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK: On success
|
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_set_voltage(esp_ldo_unit_handle_t unit, int voltage_mv);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Brief Disable a LDO
|
|
||||||
*
|
|
||||||
* @param[in] unit LDO unit handle
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK: On success
|
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
|
||||||
* - ESP_ERR_INVALID_STATE: LDO is disabled already
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinit a LDO
|
|
||||||
*
|
|
||||||
* @param[in] unit LDO unit handle
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK: On success
|
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
|
||||||
* - ESP_ERR_INVALID_STATE: LDO is still enabled
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_deinit_unit(esp_ldo_unit_handle_t unit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Dump LDO usages
|
|
||||||
*
|
|
||||||
* @note This API shall not be called from an ISR.
|
|
||||||
* @note This API does not guarantee thread safety
|
|
||||||
*
|
|
||||||
* @param stream stream to print information to; use stdout or stderr to print
|
|
||||||
* to the console; use fmemopen/open_memstream to print to a
|
|
||||||
* string buffer.
|
|
||||||
* @return
|
|
||||||
* - ESP_OK
|
|
||||||
*/
|
|
||||||
esp_err_t esp_ldo_usage_dump(FILE* stream);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "stdatomic.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "esp_heap_caps.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "soc/soc_caps.h"
|
|
||||||
#include "hal/ldo_ll.h"
|
|
||||||
#include "esp_private/esp_ldo.h"
|
|
||||||
|
|
||||||
static const DRAM_ATTR char TAG[] = "ldo";
|
|
||||||
|
|
||||||
typedef struct ldo_unit_ctx_t {
|
|
||||||
int unit_id;
|
|
||||||
int voltage_mv;
|
|
||||||
bool enabled;
|
|
||||||
int ref_cnt;
|
|
||||||
portMUX_TYPE spinlock;
|
|
||||||
} ldo_unit_ctx_t;
|
|
||||||
|
|
||||||
typedef struct ldo_ctx_t {
|
|
||||||
_lock_t mutex;
|
|
||||||
ldo_unit_ctx_t units[LDO_LL_UNIT_NUM];
|
|
||||||
} ldo_ctx_t;
|
|
||||||
|
|
||||||
static ldo_ctx_t s_ctx; //LDO context
|
|
||||||
//LDO1 is always reserved for Flash usage
|
|
||||||
static atomic_bool s_ldo_unit_claimed[LDO_LL_UNIT_NUM] = {ATOMIC_VAR_INIT(true),
|
|
||||||
ATOMIC_VAR_INIT(false),
|
|
||||||
ATOMIC_VAR_INIT(false),
|
|
||||||
ATOMIC_VAR_INIT(false)};
|
|
||||||
|
|
||||||
static bool s_ldo_unit_claim(uint32_t unit);
|
|
||||||
static bool s_ldo_unit_free(uint32_t unit);
|
|
||||||
static bool s_ldo_unit_needs_claim(const esp_ldo_unit_init_cfg_t *init_config);
|
|
||||||
|
|
||||||
|
|
||||||
//This API should always success
|
|
||||||
esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *init_config)
|
|
||||||
{
|
|
||||||
assert(init_config);
|
|
||||||
assert(ldo_ll_is_valid_ldo_id(init_config->unit_id));
|
|
||||||
|
|
||||||
int unit_id = LDO_ID2UNIT(init_config->unit_id);
|
|
||||||
ldo_unit_ctx_t *unit = &s_ctx.units[unit_id];
|
|
||||||
bool needs_claim = s_ldo_unit_needs_claim(init_config);
|
|
||||||
bool success_claim = false;
|
|
||||||
|
|
||||||
if (needs_claim) {
|
|
||||||
success_claim = s_ldo_unit_claim(unit_id);
|
|
||||||
assert(success_claim);
|
|
||||||
unit->unit_id = unit_id;
|
|
||||||
unit->voltage_mv = init_config->cfg.voltage_mv;
|
|
||||||
unit->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
ldo_ll_set_output_voltage_mv(unit_id, init_config->cfg.voltage_mv);
|
|
||||||
|
|
||||||
if (init_config->flags.enable_unit) {
|
|
||||||
ldo_ll_enable(unit_id, true);
|
|
||||||
unit->enabled = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool same_voltage = init_config->cfg.voltage_mv == unit->voltage_mv;
|
|
||||||
assert(same_voltage);
|
|
||||||
}
|
|
||||||
|
|
||||||
unit->ref_cnt++;
|
|
||||||
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_init_unit(const esp_ldo_unit_init_cfg_t *init_config, esp_ldo_unit_handle_t *ret_unit)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
|
||||||
ESP_RETURN_ON_FALSE(ldo_ll_is_valid_ldo_id(init_config->unit_id), ESP_ERR_INVALID_ARG, TAG, "invalid ldo id");
|
|
||||||
|
|
||||||
int unit_id = LDO_ID2UNIT(init_config->unit_id);
|
|
||||||
ldo_unit_ctx_t *unit = &s_ctx.units[unit_id];
|
|
||||||
bool needs_claim = s_ldo_unit_needs_claim(init_config);
|
|
||||||
bool success_claim = false;
|
|
||||||
|
|
||||||
if (needs_claim) {
|
|
||||||
success_claim = s_ldo_unit_claim(unit_id);
|
|
||||||
ESP_RETURN_ON_FALSE(success_claim, ESP_ERR_NOT_FOUND, TAG, "ldo%d is already in use", init_config->unit_id);
|
|
||||||
unit->unit_id = unit_id;
|
|
||||||
unit->voltage_mv = init_config->cfg.voltage_mv;
|
|
||||||
unit->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
ldo_ll_set_output_voltage_mv(unit_id, init_config->cfg.voltage_mv);
|
|
||||||
if (init_config->flags.enable_unit) {
|
|
||||||
ldo_ll_enable(unit_id, true);
|
|
||||||
unit->enabled = true;
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG, "new ldo %d is created", unit->unit_id + 1);
|
|
||||||
} else {
|
|
||||||
bool same_voltage = init_config->cfg.voltage_mv == unit->voltage_mv;
|
|
||||||
ESP_RETURN_ON_FALSE(same_voltage, ESP_ERR_INVALID_ARG, TAG, "not same voltage, cannot share ldo%d", init_config->unit_id);
|
|
||||||
ESP_LOGD(TAG, "new ldo %d is shared", unit->unit_id + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
portENTER_CRITICAL(&unit->spinlock);
|
|
||||||
unit->ref_cnt++;
|
|
||||||
portEXIT_CRITICAL(&unit->spinlock);
|
|
||||||
|
|
||||||
*ret_unit = unit;
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_deinit_unit(esp_ldo_unit_handle_t unit)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: uninitialized handler");
|
|
||||||
ESP_RETURN_ON_FALSE(unit->enabled == false, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is still enabled");
|
|
||||||
|
|
||||||
bool needs_free = false;
|
|
||||||
portENTER_CRITICAL(&unit->spinlock);
|
|
||||||
unit->ref_cnt -= 1;
|
|
||||||
if (unit->ref_cnt == 0) {
|
|
||||||
needs_free = true;
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL(&unit->spinlock);
|
|
||||||
|
|
||||||
if (needs_free) {
|
|
||||||
bool success_free = false;
|
|
||||||
success_free = s_ldo_unit_free(unit->unit_id);
|
|
||||||
ESP_RETURN_ON_FALSE(success_free, ESP_ERR_NOT_FOUND, TAG, "ldo%d isn't in use", unit->unit_id + 1);
|
|
||||||
ESP_LOGD(TAG, "ldo unit%d is deleted", unit->unit_id + 1);
|
|
||||||
_lock_acquire(&s_ctx.mutex);
|
|
||||||
memset(&s_ctx.units[unit->unit_id], 0x0, sizeof(ldo_unit_ctx_t));
|
|
||||||
_lock_release(&s_ctx.mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
|
||||||
ESP_RETURN_ON_FALSE(unit->enabled == false, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is enabled already");
|
|
||||||
|
|
||||||
ldo_ll_enable(unit->unit_id, true);
|
|
||||||
unit->enabled = true;
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_set_voltage(esp_ldo_unit_handle_t unit, int voltage_mv)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
|
||||||
|
|
||||||
ldo_ll_set_output_voltage_mv(unit->unit_id, voltage_mv);
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
|
||||||
ESP_RETURN_ON_FALSE(unit->enabled == true, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is disabled already");
|
|
||||||
|
|
||||||
ldo_ll_enable(unit->unit_id, false);
|
|
||||||
unit->enabled = false;
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_ldo_usage_dump(FILE* stream)
|
|
||||||
{
|
|
||||||
char line[100];
|
|
||||||
fprintf(stream, "LDOs Info:\n");
|
|
||||||
for (int i = 0; i < LDO_LL_UNIT_NUM; i++) {
|
|
||||||
fprintf(stream, "%-15s %-14s %-14s\n", "LDO ID", "voltage_mv", "enabled");
|
|
||||||
|
|
||||||
char *buf = line;
|
|
||||||
size_t len = sizeof(line);
|
|
||||||
memset(line, 0x0, len);
|
|
||||||
snprintf(buf, len, "%-15d 0x%-12d %-11x\n",
|
|
||||||
s_ctx.units[i].unit_id + 1,
|
|
||||||
s_ctx.units[i].voltage_mv,
|
|
||||||
s_ctx.units[i].enabled);
|
|
||||||
fputs(line, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stream, "You can use a disabled LDO unit, or share an enabled LDO unit\n");
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool s_ldo_unit_claim(uint32_t unit)
|
|
||||||
{
|
|
||||||
bool false_var = false;
|
|
||||||
return atomic_compare_exchange_strong(&s_ldo_unit_claimed[unit], &false_var, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool s_ldo_unit_free(uint32_t unit)
|
|
||||||
{
|
|
||||||
bool true_var = true;
|
|
||||||
return atomic_compare_exchange_strong(&s_ldo_unit_claimed[unit], &true_var, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool s_ldo_unit_needs_claim(const esp_ldo_unit_init_cfg_t *init_config)
|
|
||||||
{
|
|
||||||
bool needs_claim = false;
|
|
||||||
int unit_id = LDO_ID2UNIT(init_config->unit_id);
|
|
||||||
|
|
||||||
if (s_ctx.units[unit_id].ref_cnt == 0) {
|
|
||||||
needs_claim = true;
|
|
||||||
} else {
|
|
||||||
if (!init_config->flags.shared_ldo) {
|
|
||||||
needs_claim = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return needs_claim;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user