mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(sd): added power control driver and implementation layer with ldo
This commit is contained in:
@@ -43,7 +43,9 @@ extern "C" {
|
||||
.command_timeout_ms = 0, \
|
||||
.get_real_freq = &sdmmc_host_get_real_freq, \
|
||||
.input_delay_phase = SDMMC_DELAY_PHASE_0, \
|
||||
.set_input_delay = &sdmmc_host_set_input_delay \
|
||||
.set_input_delay = &sdmmc_host_set_input_delay, \
|
||||
.dma_aligned_buffer = NULL, \
|
||||
.pwr_ctrl_handle = NULL, \
|
||||
}
|
||||
|
||||
#define SDMMC_SLOT_NO_CD GPIO_NUM_NC ///< indicates that card detect line is not used
|
||||
|
||||
@@ -665,20 +665,6 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if SOC_MULTI_USAGE_LDO_SUPPORTED
|
||||
esp_ldo_unit_init_cfg_t init_ldo_cfg = {
|
||||
.unit_id = LDO_UNIT_4,
|
||||
.cfg = {
|
||||
.voltage_mv = 3300,
|
||||
},
|
||||
.flags.shared_ldo = true,
|
||||
};
|
||||
esp_ldo_unit_handle_t ldo_unit = NULL;
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_init_unit(&init_ldo_cfg, &ldo_unit), TAG, "LDO init failed");
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_enable_unit(ldo_unit), TAG, "LDO enable failed");
|
||||
s_host_ctx.slot_ctx[slot].ldo_unit = ldo_unit;
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -700,16 +686,6 @@ esp_err_t sdmmc_host_deinit(void)
|
||||
sdmmc_ll_enable_bus_clock(s_host_ctx.hal.dev, false);
|
||||
}
|
||||
|
||||
#if SOC_MULTI_USAGE_LDO_SUPPORTED
|
||||
for (int i = 0; i < SOC_SDMMC_NUM_SLOTS; i++) {
|
||||
if (s_host_ctx.slot_ctx[i].ldo_unit) {
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_disable_unit(s_host_ctx.slot_ctx[i].ldo_unit), TAG, "LDO disable failed");
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_deinit_unit(s_host_ctx.slot_ctx[i].ldo_unit), TAG, "LDO deinit failed");
|
||||
s_host_ctx.slot_ctx[i].ldo_unit = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
idf_component_register(SRCS sdmmc_test_board.c sdmmc_test_board_defs.c
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES esp_driver_sdmmc esp_driver_sdspi esp_driver_gpio)
|
||||
REQUIRES esp_driver_sdmmc esp_driver_sdspi esp_driver_gpio unity)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
+16
-1
@@ -1,12 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdmmc_test_board.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
|
||||
const sdmmc_test_board_slot_info_t* sdmmc_test_board_get_slot_info(int slot_index)
|
||||
{
|
||||
@@ -32,6 +35,18 @@ void sdmmc_test_board_get_config_sdmmc(int slot_index, sdmmc_host_t *out_host_co
|
||||
out_host_config->max_freq_khz = slot->max_freq_khz;
|
||||
}
|
||||
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
#define SDMMC_PWR_LDO_CHANNEL 4
|
||||
|
||||
sd_pwr_ctrl_ldo_config_t ldo_config = {
|
||||
.ldo_unit_id = SDMMC_PWR_LDO_CHANNEL,
|
||||
};
|
||||
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
|
||||
|
||||
TEST_ESP_OK(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle));
|
||||
out_host_config->pwr_ctrl_handle = pwr_ctrl_handle;
|
||||
#endif
|
||||
|
||||
#if SOC_SDMMC_USE_GPIO_MATRIX
|
||||
out_slot_config->clk = slot->clk;
|
||||
out_slot_config->cmd = slot->cmd_mosi;
|
||||
|
||||
+14
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "sdmmc_test_begin_end_sd.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
|
||||
void sdmmc_test_sd_skip_if_board_incompatible(int slot, int width, int freq_khz, int ddr)
|
||||
{
|
||||
@@ -25,14 +27,22 @@ void sdmmc_test_sd_skip_if_board_incompatible(int slot, int width, int freq_khz,
|
||||
TEST_IGNORE_MESSAGE("Board doesn't have the required slot");
|
||||
}
|
||||
sdmmc_test_board_get_config_sdmmc(slot, &config, &slot_config);
|
||||
|
||||
int board_max_freq_khz = sdmmc_test_board_get_slot_info(slot)->max_freq_khz;
|
||||
if (board_max_freq_khz > 0 && board_max_freq_khz < freq_khz) {
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(config.pwr_ctrl_handle));
|
||||
#endif
|
||||
TEST_IGNORE_MESSAGE("Board doesn't support required max_freq_khz");
|
||||
}
|
||||
if (slot_config.width < width) {
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(config.pwr_ctrl_handle));
|
||||
#endif
|
||||
TEST_IGNORE_MESSAGE("Board doesn't support required bus width");
|
||||
}
|
||||
}
|
||||
|
||||
void sdmmc_test_sd_begin(int slot, int width, int freq_khz, int ddr, sdmmc_card_t *out_card)
|
||||
{
|
||||
sdmmc_host_t config = SDMMC_HOST_DEFAULT();
|
||||
@@ -115,4 +125,7 @@ void sdmmc_test_sd_end(sdmmc_card_t *card)
|
||||
|
||||
//Need to reset GPIO first, otherrwise cannot discharge VDD of card completely.
|
||||
sdmmc_test_board_card_power_set(false);
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(card->host.pwr_ctrl_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "sdmmc_test_cd_wp_common.h"
|
||||
#include "sdmmc_test_board.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
|
||||
//TODO: IDF-8734
|
||||
#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3
|
||||
@@ -27,6 +29,9 @@ TEST_CASE("CD input works in SD mode", "[sdmmc]")
|
||||
|
||||
TEST_ESP_OK(sdmmc_host_deinit());
|
||||
sdmmc_test_board_card_power_set(false);
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(config.pwr_ctrl_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("WP input works in SD mode", "[sdmmc]")
|
||||
@@ -44,5 +49,8 @@ TEST_CASE("WP input works in SD mode", "[sdmmc]")
|
||||
|
||||
TEST_ESP_OK(sdmmc_host_deinit());
|
||||
sdmmc_test_board_card_power_set(false);
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(config.pwr_ctrl_handle));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -52,7 +52,7 @@ typedef struct {
|
||||
esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *init_config);
|
||||
|
||||
/**
|
||||
* @Brief Init a LDO
|
||||
* @brief Init a LDO
|
||||
*
|
||||
* @param[in] init_config LDO initial configurations
|
||||
* @param[out] ret_unit LDO unit handle
|
||||
@@ -65,7 +65,7 @@ esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *ini
|
||||
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
|
||||
* @brief Enable a LDO
|
||||
*
|
||||
* @param[in] unit LDO unit handle
|
||||
*
|
||||
@@ -76,6 +76,18 @@ esp_err_t esp_ldo_init_unit(const esp_ldo_unit_init_cfg_t *init_config, esp_ldo_
|
||||
*/
|
||||
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
|
||||
*
|
||||
@@ -89,7 +101,7 @@ esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit);
|
||||
esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit);
|
||||
|
||||
/**
|
||||
* @Brief Deinit a LDO
|
||||
* @brief Deinit a LDO
|
||||
*
|
||||
* @param[in] unit LDO unit handle
|
||||
*
|
||||
@@ -101,7 +113,7 @@ esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit);
|
||||
esp_err_t esp_ldo_deinit_unit(esp_ldo_unit_handle_t unit);
|
||||
|
||||
/**
|
||||
* Dump LDO usages
|
||||
* @brief Dump LDO usages
|
||||
*
|
||||
* @note This API shall not be called from an ISR.
|
||||
* @note This API does not guarantee thread safety
|
||||
|
||||
@@ -149,6 +149,15 @@ esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit)
|
||||
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");
|
||||
|
||||
@@ -4,11 +4,18 @@ if(${target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "sdmmc_cmd.c"
|
||||
"sdmmc_common.c"
|
||||
"sdmmc_init.c"
|
||||
"sdmmc_io.c"
|
||||
"sdmmc_mmc.c"
|
||||
"sdmmc_sd.c"
|
||||
INCLUDE_DIRS include
|
||||
PRIV_REQUIRES soc esp_timer esp_mm)
|
||||
set(srcs "sdmmc_cmd.c"
|
||||
"sdmmc_common.c"
|
||||
"sdmmc_init.c"
|
||||
"sdmmc_io.c"
|
||||
"sdmmc_mmc.c"
|
||||
"sdmmc_sd.c"
|
||||
"sd_pwr_ctrl/sd_pwr_ctrl.c")
|
||||
|
||||
if(CONFIG_SOC_MULTI_USAGE_LDO_SUPPORTED)
|
||||
list(APPEND srcs "sd_pwr_ctrl/sd_pwr_ctrl_by_on_chip_ldo.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS include
|
||||
PRIV_REQUIRES soc esp_timer esp_mm)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -207,6 +208,7 @@ typedef struct {
|
||||
sdmmc_delay_phase_t input_delay_phase; /*!< input delay phase, this will only take into effect when the host works in SDMMC_FREQ_HIGHSPEED or SDMMC_FREQ_52M. Driver will print out how long the delay is*/
|
||||
esp_err_t (*set_input_delay)(int slot, sdmmc_delay_phase_t delay_phase); /*!< set input delay phase */
|
||||
void* dma_aligned_buffer; /*!< Leave it NULL. Reserved for cache aligned buffers for SDIO mode */
|
||||
sd_pwr_ctrl_handle_t pwr_ctrl_handle; /*!< Power control handle */
|
||||
} sdmmc_host_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bit_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SD power control handle
|
||||
*/
|
||||
typedef struct sd_pwr_ctrl_drv_t *sd_pwr_ctrl_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Set SD IO voltage by a registered SD power control driver handle
|
||||
*
|
||||
* @param[in] handle SD power control driver handle
|
||||
* @param[in] voltage_mv Voltage in mV
|
||||
*/
|
||||
esp_err_t sd_pwr_ctrl_set_io_voltage(sd_pwr_ctrl_handle_t handle, int voltage_mv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
#include "sd_protocol_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LDO configurations
|
||||
*/
|
||||
typedef struct {
|
||||
int ldo_unit_id; ///< On-chip LDO ID
|
||||
} sd_pwr_ctrl_ldo_config_t;
|
||||
|
||||
/**
|
||||
* @brief New an SD power control driver via on-chip LDO
|
||||
*
|
||||
* @param[in] configs On-chip LDO power control driver configurations
|
||||
* @param[out] ret_drv Created power control driver handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG Invalid arguments
|
||||
* - ESP_ERR_NO_MEM Out of memory
|
||||
*/
|
||||
esp_err_t sd_pwr_ctrl_new_on_chip_ldo(const sd_pwr_ctrl_ldo_config_t *configs, sd_pwr_ctrl_handle_t *ret_drv);
|
||||
|
||||
/**
|
||||
* @brief Delete a previously created on-chip LDO power control driver
|
||||
*
|
||||
* @param[in] ctrl_handle Power control driver handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG Invalid arguments
|
||||
*/
|
||||
esp_err_t sd_pwr_ctrl_del_on_chip_ldo(sd_pwr_ctrl_handle_t ctrl_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
#include "esp_types.h"
|
||||
#include "esp_err.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sd_pwr_ctrl_drv_t sd_pwr_ctrl_drv_t;
|
||||
|
||||
struct sd_pwr_ctrl_drv_t {
|
||||
/**
|
||||
* @brief Set SD IO voltage
|
||||
*
|
||||
* @param[in] ctx SD power control specific driver context
|
||||
* @param[in] voltage_mv Voltage in mV
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: On success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
*/
|
||||
esp_err_t (*set_io_voltage)(void *ctx, int voltage_mv);
|
||||
|
||||
/**
|
||||
* @brief SD power control driver context
|
||||
* Can be customized to difference power control methods
|
||||
*/
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sd_pwr_ctrl_interface.h"
|
||||
|
||||
const static char *TAG = "sd_power";
|
||||
|
||||
esp_err_t sd_pwr_ctrl_set_io_voltage(sd_pwr_ctrl_handle_t handle, int voltage_mv)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer");
|
||||
|
||||
return handle->set_io_voltage(handle->ctx, voltage_mv);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_private/esp_ldo.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
#include "sd_pwr_ctrl_interface.h"
|
||||
|
||||
typedef struct {
|
||||
esp_ldo_unit_handle_t ldo_unit;
|
||||
int voltage_mv;
|
||||
} sd_pwr_ctrl_ldo_ctx_t;
|
||||
|
||||
const static char *TAG = "sd_ldo";
|
||||
static esp_err_t s_ldo_set_voltage(void *arg, int voltage_mv);
|
||||
|
||||
esp_err_t sd_pwr_ctrl_new_on_chip_ldo(const sd_pwr_ctrl_ldo_config_t *configs, sd_pwr_ctrl_handle_t *ret_drv)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(configs && ret_drv, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer");
|
||||
|
||||
sd_pwr_ctrl_drv_t *driver = (sd_pwr_ctrl_drv_t *)heap_caps_calloc(1, sizeof(sd_pwr_ctrl_drv_t), MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT);
|
||||
ESP_RETURN_ON_FALSE(driver, ESP_ERR_NO_MEM, TAG, "no mem for on-chip ldo control driver");
|
||||
|
||||
sd_pwr_ctrl_ldo_ctx_t *ctx = (sd_pwr_ctrl_ldo_ctx_t *)heap_caps_calloc(1, sizeof(sd_pwr_ctrl_ldo_ctx_t), MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT);
|
||||
ESP_GOTO_ON_FALSE(ctx, ESP_ERR_NO_MEM, err, TAG, "no mem for on-chip ldo control driver context");
|
||||
|
||||
esp_ldo_unit_init_cfg_t unit_cfg = {
|
||||
.unit_id = configs->ldo_unit_id,
|
||||
.cfg = {
|
||||
.voltage_mv = 0, //will be adjusted dynamically by sdmmc driver later
|
||||
},
|
||||
};
|
||||
esp_ldo_unit_handle_t ldo_unit = NULL;
|
||||
ESP_GOTO_ON_ERROR(esp_ldo_init_unit(&unit_cfg, &ldo_unit), err, TAG, "failed to create an on-chip LDO unit handle");
|
||||
ESP_GOTO_ON_ERROR(esp_ldo_enable_unit(ldo_unit), err, TAG, "failed to enable the on-chip LDO unit");
|
||||
|
||||
driver->set_io_voltage = s_ldo_set_voltage;
|
||||
driver->ctx = ctx;
|
||||
ctx->ldo_unit = ldo_unit;
|
||||
ctx->voltage_mv = 0;
|
||||
*ret_drv = driver;
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
free(ctx);
|
||||
free(driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t sd_pwr_ctrl_del_on_chip_ldo(sd_pwr_ctrl_handle_t handle)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer");
|
||||
|
||||
sd_pwr_ctrl_ldo_ctx_t *ctx = handle->ctx;
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_disable_unit(ctx->ldo_unit), TAG, "failed to disable the on-chip LDO unit");
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_deinit_unit(ctx->ldo_unit), TAG, "failed to deinit the LDO unit handle");
|
||||
free(handle->ctx);
|
||||
handle->ctx = NULL;
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t s_ldo_set_voltage(void *arg, int voltage_mv)
|
||||
{
|
||||
//API checks done by caller
|
||||
sd_pwr_ctrl_ldo_ctx_t *ctx = arg;
|
||||
ESP_RETURN_ON_ERROR(esp_ldo_set_voltage(ctx->ldo_unit, voltage_mv), TAG, "failed to set LDO unit output voltage");
|
||||
ctx->voltage_mv = voltage_mv;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "sdmmc_common.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
#include "sd_pwr_ctrl.h"
|
||||
|
||||
static const char* TAG = "sdmmc_init";
|
||||
|
||||
@@ -33,6 +35,7 @@ static const char* TAG = "sdmmc_init";
|
||||
|
||||
esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
memset(card, 0, sizeof(*card));
|
||||
memcpy(&card->host, config, sizeof(*config));
|
||||
|
||||
@@ -40,6 +43,15 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
const bool always = true;
|
||||
const bool io_supported = true;
|
||||
|
||||
if (config->pwr_ctrl_handle) {
|
||||
int voltage_mv = config->io_voltage * 1000;
|
||||
ret = sd_pwr_ctrl_set_io_voltage(config->pwr_ctrl_handle, voltage_mv);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to set voltage (0x%x)", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate cache-aligned buffer for SDIO over SDMMC.*/
|
||||
SDMMC_INIT_STEP(!is_spi, sdmmc_allocate_aligned_buf);
|
||||
|
||||
|
||||
@@ -967,6 +967,10 @@ config SOC_SDMMC_DELAY_PHASE_NUM
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SHA_DMA_MAX_BUFFER_SIZE
|
||||
int
|
||||
default 3968
|
||||
|
||||
@@ -396,6 +396,7 @@
|
||||
#define SOC_SDMMC_NUM_SLOTS 2
|
||||
/* Supported host clock delay phase number */
|
||||
#define SOC_SDMMC_DELAY_PHASE_NUM 4
|
||||
#define SOC_SDMMC_IO_POWER_EXTERNAL 1 ///< SDMMC IO power controlled by external power supply
|
||||
|
||||
// TODO: IDF-5353 (Copy from esp32c3, need check)
|
||||
/*--------------------------- SHA CAPS ---------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user