kopia lustrzana https://github.com/espressif/esp-idf
feat(sd): added power control driver and implementation layer with ldo
rodzic
5154be52ac
commit
ec44556a07
|
@ -43,7 +43,9 @@ extern "C" {
|
||||||
.command_timeout_ms = 0, \
|
.command_timeout_ms = 0, \
|
||||||
.get_real_freq = &sdmmc_host_get_real_freq, \
|
.get_real_freq = &sdmmc_host_get_real_freq, \
|
||||||
.input_delay_phase = SDMMC_DELAY_PHASE_0, \
|
.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
|
#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;
|
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;
|
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);
|
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;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
idf_component_register(SRCS sdmmc_test_board.c sdmmc_test_board_defs.c
|
idf_component_register(SRCS sdmmc_test_board.c sdmmc_test_board_defs.c
|
||||||
INCLUDE_DIRS include
|
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,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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdmmc_test_board.h"
|
#include "sdmmc_test_board.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#include "unity.h"
|
||||||
#include "soc/soc_caps.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)
|
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;
|
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
|
#if SOC_SDMMC_USE_GPIO_MATRIX
|
||||||
out_slot_config->clk = slot->clk;
|
out_slot_config->clk = slot->clk;
|
||||||
out_slot_config->cmd = slot->cmd_mosi;
|
out_slot_config->cmd = slot->cmd_mosi;
|
||||||
|
|
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,8 @@
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "sdmmc_test_begin_end_sd.h"
|
#include "sdmmc_test_begin_end_sd.h"
|
||||||
#include "hal/gpio_hal.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)
|
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");
|
TEST_IGNORE_MESSAGE("Board doesn't have the required slot");
|
||||||
}
|
}
|
||||||
sdmmc_test_board_get_config_sdmmc(slot, &config, &slot_config);
|
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;
|
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 (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");
|
TEST_IGNORE_MESSAGE("Board doesn't support required max_freq_khz");
|
||||||
}
|
}
|
||||||
if (slot_config.width < width) {
|
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");
|
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)
|
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();
|
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.
|
//Need to reset GPIO first, otherrwise cannot discharge VDD of card completely.
|
||||||
sdmmc_test_board_card_power_set(false);
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,8 @@
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
#include "sdmmc_test_cd_wp_common.h"
|
#include "sdmmc_test_cd_wp_common.h"
|
||||||
#include "sdmmc_test_board.h"
|
#include "sdmmc_test_board.h"
|
||||||
|
#include "sd_pwr_ctrl.h"
|
||||||
|
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||||
|
|
||||||
//TODO: IDF-8734
|
//TODO: IDF-8734
|
||||||
#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3
|
#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());
|
TEST_ESP_OK(sdmmc_host_deinit());
|
||||||
sdmmc_test_board_card_power_set(false);
|
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]")
|
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());
|
TEST_ESP_OK(sdmmc_host_deinit());
|
||||||
sdmmc_test_board_card_power_set(false);
|
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
|
#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
|
* 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);
|
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[in] init_config LDO initial configurations
|
||||||
* @param[out] ret_unit LDO unit handle
|
* @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);
|
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
|
* @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);
|
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
|
* @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);
|
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
|
* @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);
|
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 shall not be called from an ISR.
|
||||||
* @note This API does not guarantee thread safety
|
* @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;
|
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_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, 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
|
return() # This component is not supported by the POSIX/Linux simulator
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS "sdmmc_cmd.c"
|
set(srcs "sdmmc_cmd.c"
|
||||||
"sdmmc_common.c"
|
"sdmmc_common.c"
|
||||||
"sdmmc_init.c"
|
"sdmmc_init.c"
|
||||||
"sdmmc_io.c"
|
"sdmmc_io.c"
|
||||||
"sdmmc_mmc.c"
|
"sdmmc_mmc.c"
|
||||||
"sdmmc_sd.c"
|
"sdmmc_sd.c"
|
||||||
INCLUDE_DIRS include
|
"sd_pwr_ctrl/sd_pwr_ctrl.c")
|
||||||
PRIV_REQUIRES soc esp_timer esp_mm)
|
|
||||||
|
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-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>
|
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "sd_pwr_ctrl.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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*/
|
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 */
|
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 */
|
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;
|
} 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 "sdmmc_common.h"
|
||||||
|
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||||
|
#include "sd_pwr_ctrl.h"
|
||||||
|
|
||||||
static const char* TAG = "sdmmc_init";
|
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 sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||||
{
|
{
|
||||||
|
esp_err_t ret = ESP_FAIL;
|
||||||
memset(card, 0, sizeof(*card));
|
memset(card, 0, sizeof(*card));
|
||||||
memcpy(&card->host, config, sizeof(*config));
|
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 always = true;
|
||||||
const bool io_supported = 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.*/
|
/* Allocate cache-aligned buffer for SDIO over SDMMC.*/
|
||||||
SDMMC_INIT_STEP(!is_spi, sdmmc_allocate_aligned_buf);
|
SDMMC_INIT_STEP(!is_spi, sdmmc_allocate_aligned_buf);
|
||||||
|
|
||||||
|
|
|
@ -967,6 +967,10 @@ config SOC_SDMMC_DELAY_PHASE_NUM
|
||||||
int
|
int
|
||||||
default 4
|
default 4
|
||||||
|
|
||||||
|
config SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_SHA_DMA_MAX_BUFFER_SIZE
|
config SOC_SHA_DMA_MAX_BUFFER_SIZE
|
||||||
int
|
int
|
||||||
default 3968
|
default 3968
|
||||||
|
|
|
@ -396,6 +396,7 @@
|
||||||
#define SOC_SDMMC_NUM_SLOTS 2
|
#define SOC_SDMMC_NUM_SLOTS 2
|
||||||
/* Supported host clock delay phase number */
|
/* Supported host clock delay phase number */
|
||||||
#define SOC_SDMMC_DELAY_PHASE_NUM 4
|
#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)
|
// TODO: IDF-5353 (Copy from esp32c3, need check)
|
||||||
/*--------------------------- SHA CAPS ---------------------------------------*/
|
/*--------------------------- SHA CAPS ---------------------------------------*/
|
||||||
|
|
|
@ -21,3 +21,5 @@ INPUT += \
|
||||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/gpio_num.h \
|
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/gpio_num.h \
|
||||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/soc_caps.h \
|
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/soc_caps.h \
|
||||||
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/uart_channel.h \
|
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/uart_channel.h \
|
||||||
|
$(PROJECT_PATH)/components/sdmmc/include/sd_pwr_ctrl.h \
|
||||||
|
$(PROJECT_PATH)/components/sdmmc/include/sd_pwr_ctrl_by_on_chip_ldo.h \
|
||||||
|
|
|
@ -67,7 +67,7 @@ Overview
|
||||||
Pins used by Slot 0 (``HS1_*``) are also used to connect the SPI flash chip in ESP32-WROOM and ESP32-WROVER modules. These pins cannot be concurrently shared between an SD card and an SPI flash. If you need to use Slot 0, establish an alternative connection for the SPI flash using different pins and configure the necessary eFuses accordingly.
|
Pins used by Slot 0 (``HS1_*``) are also used to connect the SPI flash chip in ESP32-WROOM and ESP32-WROVER modules. These pins cannot be concurrently shared between an SD card and an SPI flash. If you need to use Slot 0, establish an alternative connection for the SPI flash using different pins and configure the necessary eFuses accordingly.
|
||||||
|
|
||||||
|
|
||||||
.. only:: esp32s3
|
.. only:: SOC_SDMMC_USE_GPIO_MATRIX
|
||||||
|
|
||||||
Both slots :c:macro:`SDMMC_HOST_SLOT_0` and :c:macro:`SDMMC_HOST_SLOT_1` support 1-, 4- and 8-line SD interfaces. The slots are connected to {IDF_TARGET_NAME} GPIOs using the GPIO matrix. This means that any GPIO may be used for each of the SD card signals.
|
Both slots :c:macro:`SDMMC_HOST_SLOT_0` and :c:macro:`SDMMC_HOST_SLOT_1` support 1-, 4- and 8-line SD interfaces. The slots are connected to {IDF_TARGET_NAME} GPIOs using the GPIO matrix. This means that any GPIO may be used for each of the SD card signals.
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ Overview
|
||||||
- :c:macro:`SDMMC_HOST_SLOT_1` is routed via GPIO Matrix. This means that any GPIO may be used for each of the SD card signals. It is for non UHS-I usage.
|
- :c:macro:`SDMMC_HOST_SLOT_1` is routed via GPIO Matrix. This means that any GPIO may be used for each of the SD card signals. It is for non UHS-I usage.
|
||||||
- :c:macro:`SDMMC_HOST_SLOT_0` is dedicated to UHS-I mode, which is not yet supported in the driver.
|
- :c:macro:`SDMMC_HOST_SLOT_0` is dedicated to UHS-I mode, which is not yet supported in the driver.
|
||||||
|
|
||||||
Currently SDMMC host driver is using the on-chip LDO 4 as the default power supply. SDMMC power control driver is not supported yet. If you buy the ESP32P4 chip itself and plan to use SDMMC peripheral, make sure the VDDPST_5 pin is connected to the on-chip LDO 4 or correct external power supply.
|
On {IDF_TARGET_NAME}, SDMMC host requires an external power supply for the IO voltage. Please refer to :ref:'pwr-ctrl' for details.
|
||||||
|
|
||||||
Supported Speed Modes
|
Supported Speed Modes
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -162,6 +162,21 @@ To configure the bus width, set the ``width`` field of :cpp:class:`sdmmc_slot_co
|
||||||
|
|
||||||
Once :cpp:class:`sdmmc_slot_config_t` structure is initialized this way, you can use it when calling :cpp:func:`sdmmc_host_init_slot` or one of the higher level functions (such as :cpp:func:`esp_vfs_fat_sdmmc_mount`).
|
Once :cpp:class:`sdmmc_slot_config_t` structure is initialized this way, you can use it when calling :cpp:func:`sdmmc_host_init_slot` or one of the higher level functions (such as :cpp:func:`esp_vfs_fat_sdmmc_mount`).
|
||||||
|
|
||||||
|
.. only:: SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
|
||||||
|
.. _pwr-ctrl:
|
||||||
|
|
||||||
|
Configuring Voltage Level
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
{IDF_TARGET_NAME} SDMMC Host requires the IO voltage to be supplied externally via the VDDPST_5 (SD_VREF) pin. If the design doesn't require the higher speed SD modes, this pin can be simply connected to the 3.3V supply.
|
||||||
|
|
||||||
|
If the design does require higher speed SD modes (which only work at 1.8V IO levels), there are two options available:
|
||||||
|
|
||||||
|
- Use the on-chip programmable LDO. In this case, connect the desired LDO output channel to VDDPST_5 (SD_VREF) pin. Call :cpp:func:'sd_pwr_ctrl_new_on_chip_ldo' to initialize the SD power control driver, then set :cpp:class:'sdmmc_host_t::pwr_ctrl_handle' to the resulting handle.
|
||||||
|
- Use an external programmable LDO. Likewise, connect the LDO output to the VDDPST_5 (SD_VREF) pin. Then implement a custom `sd_pwr_ctrl` driver to control your LDO. Finally, assign :cpp:class:'sdmmc_host_t::pwr_ctrl_handle' to the handle of your driver instance.
|
||||||
|
|
||||||
|
|
||||||
DDR Mode for eMMC Chips
|
DDR Mode for eMMC Chips
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,12 @@ SDMMC 主机驱动
|
||||||
|
|
||||||
卡槽 :c:macro:`SDMMC_HOST_SLOT_0` 和 :c:macro:`SDMMC_HOST_SLOT_1` 都支持 1、4、8 线的 SD 接口,这些卡槽通过 GPIO 交换矩阵连接到 {IDF_TARGET_NAME} 的 GPIO,即每个 SD 卡信号都可以使用任意 GPIO 连接。
|
卡槽 :c:macro:`SDMMC_HOST_SLOT_0` 和 :c:macro:`SDMMC_HOST_SLOT_1` 都支持 1、4、8 线的 SD 接口,这些卡槽通过 GPIO 交换矩阵连接到 {IDF_TARGET_NAME} 的 GPIO,即每个 SD 卡信号都可以使用任意 GPIO 连接。
|
||||||
|
|
||||||
|
.. only:: esp32p4
|
||||||
|
|
||||||
|
- 卡槽 :c:macro:`SDMMC_HOST_SLOT_1` 通过GPIO矩阵连接。这意味着任何GPIO都可以用于每个SD卡信号。它适用于非UHS-I用途。
|
||||||
|
- 卡槽 :c:macro:`SDMMC_HOST_SLOT_0` 专用于UHS-I模式,驱动程序中尚不支持该模式。
|
||||||
|
|
||||||
|
目前SDMMC主机需要为IO电平提供外部电压参考。如果您自行购买ESP32P4芯片并计划使用SDMMC外设,请参阅 :ref:'wr-ctrl' 。
|
||||||
|
|
||||||
支持的速率模式
|
支持的速率模式
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -156,6 +162,18 @@ SDMMC 主机驱动支持以下速率模式:
|
||||||
|
|
||||||
通过上述方式初始化 :cpp:class:`sdmmc_slot_config_t` 结构体后,即可在调用 :cpp:func:`sdmmc_host_init_slot` 或其他任意高层函数(如 :cpp:func:`esp_vfs_fat_sdmmc_mount`)时使用该结构体。
|
通过上述方式初始化 :cpp:class:`sdmmc_slot_config_t` 结构体后,即可在调用 :cpp:func:`sdmmc_host_init_slot` 或其他任意高层函数(如 :cpp:func:`esp_vfs_fat_sdmmc_mount`)时使用该结构体。
|
||||||
|
|
||||||
|
.. only:: SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
|
||||||
|
.. _pwr-ctrl:
|
||||||
|
|
||||||
|
配置供电和参考电压
|
||||||
|
------------------
|
||||||
|
|
||||||
|
{IDF_TARGET_NAME} SDMMC主机需要为IO电平提供外部电压参考 ,以支持高速设备, 驱动器将动态配置电压参考。您可以使用片上可编程LDO作为从机电源和电压参考 ,也可以提供正确的外部电源。
|
||||||
|
|
||||||
|
- 要使用片上LDO ,请确保 VDDPST_5(sd_vref) 引脚连接到所选的片上LD通道 ,并调用 :cpp:func:'sd_pwr_ctrl_new_on_chip_ldo' 分配所选的LDO通道 ,然后将 'pwr_ctr_handle' 传递给 :cpp:class:'sdmmc_host_t::pwr_ctl_handle' 。
|
||||||
|
- 要使用外部电源,请确保 VDDPST_5(sd_vref) 引脚已连接,然后按照 :cpp:class:'sd_pwr_ctrl_drv_t' 构造外部电源控制结构体,并将其传递给 :cpp:class:'sdmmc_host_t::pwr_ctr_handle'。
|
||||||
|
|
||||||
eMMC 芯片的 DDR 模式
|
eMMC 芯片的 DDR 模式
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
|
@ -152,4 +152,18 @@ menu "SD/MMC Example Configuration"
|
||||||
|
|
||||||
endif # EXAMPLE_SDMMC_BUS_WIDTH_4
|
endif # EXAMPLE_SDMMC_BUS_WIDTH_4
|
||||||
|
|
||||||
|
config EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO
|
||||||
|
depends on SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
bool "SDMMC IO power supply comes from internal LDO (READ HELP!)"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Please read the schematic first and check if the SDMMC VDD is connected to any internal LDO output.
|
||||||
|
If the SDMMC is powered by an external supplier, unselect me
|
||||||
|
|
||||||
|
config EXAMPLE_SDMMC_IO_LDO_ID
|
||||||
|
depends on SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
int "LDO ID"
|
||||||
|
default 4
|
||||||
|
help
|
||||||
|
Please read the schematic first and input your LDO ID
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
#include "sd_test_io.h"
|
#include "sd_test_io.h"
|
||||||
|
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||||
|
|
||||||
#define EXAMPLE_MAX_CHAR_SIZE 64
|
#define EXAMPLE_MAX_CHAR_SIZE 64
|
||||||
|
|
||||||
|
@ -126,6 +127,23 @@ void app_main(void)
|
||||||
// Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
|
// Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
|
||||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On these chips, the SDMMC IO power is supplied externally
|
||||||
|
*/
|
||||||
|
#if CONFIG_EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO
|
||||||
|
sd_pwr_ctrl_ldo_config_t ldo_config = {
|
||||||
|
.ldo_unit_id = 4,
|
||||||
|
};
|
||||||
|
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
|
||||||
|
|
||||||
|
ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to new an on-chip ldo power control driver");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
host.pwr_ctrl_handle = pwr_ctrl_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
// This initializes the slot without card detect (CD) and write protect (WP) signals.
|
// This initializes the slot without card detect (CD) and write protect (WP) signals.
|
||||||
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
||||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||||
|
@ -239,5 +257,14 @@ void app_main(void)
|
||||||
|
|
||||||
// All done, unmount partition and disable SDMMC peripheral
|
// All done, unmount partition and disable SDMMC peripheral
|
||||||
esp_vfs_fat_sdcard_unmount(mount_point, card);
|
esp_vfs_fat_sdcard_unmount(mount_point, card);
|
||||||
|
|
||||||
|
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||||
|
ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to delete on-chip ldo power control driver");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Card unmounted");
|
ESP_LOGI(TAG, "Card unmounted");
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue