feat(sdmmc): use ldo as power supply on esp32p4

This commit is contained in:
Armando 2023-12-29 15:55:34 +08:00
parent 20f80a2d05
commit 847d525d78
4 changed files with 41 additions and 9 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -19,6 +19,7 @@
#include "driver/gpio.h"
#include "driver/sdmmc_host.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_ldo.h"
#include "sdmmc_private.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
@ -54,6 +55,7 @@ typedef struct slot_ctx_t {
size_t slot_width;
sdmmc_slot_io_info_t slot_gpio_num;
bool use_gpio_matrix;
esp_ldo_unit_handle_t ldo_unit;
} slot_ctx_t;
/**
@ -662,6 +664,21 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
if (ret != ESP_OK) {
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;
}
@ -683,6 +700,16 @@ 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;
}

View File

@ -31,7 +31,6 @@ extern "C" {
/**
* SDMMC capabilities
*/
#define SDMMC_LL_MAX_FREQ_KHZ_FPGA (4*1000)
#define SDMMC_LL_SLOT_SUPPORT_GPIO_MATRIX(SLOT_ID) ((SLOT_ID == 0) ? 0 : 1)
#define SDMMC_LL_IOMUX_FUNC 0

View File

@ -11,4 +11,4 @@ idf_component_register(SRCS "sdmmc_cmd.c"
"sdmmc_mmc.c"
"sdmmc_sd.c"
INCLUDE_DIRS include
PRIV_REQUIRES soc esp_timer)
PRIV_REQUIRES soc esp_timer esp_mm)

View File

@ -17,6 +17,7 @@
#include <inttypes.h>
#include "esp_timer.h"
#include "esp_cache.h"
#include "sdmmc_common.h"
static const char* TAG = "sdmmc_sd";
@ -191,12 +192,14 @@ esp_err_t sdmmc_send_cmd_switch_func(sdmmc_card_t* card,
uint32_t other_func_mask = (0x00ffffff & ~(0xf << group_shift));
uint32_t func_val = (function << group_shift) | other_func_mask;
size_t datalen = sizeof(sdmmc_switch_func_rsp_t);
sdmmc_command_t cmd = {
.opcode = MMC_SWITCH,
.flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1,
.blklen = sizeof(sdmmc_switch_func_rsp_t),
.data = resp->data,
.datalen = sizeof(sdmmc_switch_func_rsp_t),
.datalen = datalen,
.buflen = datalen,
.arg = (!!mode << 31) | func_val
};
@ -233,13 +236,16 @@ esp_err_t sdmmc_enable_hs_mode(sdmmc_card_t* card)
((card->csd.card_command_class & SD_CSD_CCC_SWITCH) == 0)) {
return ESP_ERR_NOT_SUPPORTED;
}
sdmmc_switch_func_rsp_t* response = (sdmmc_switch_func_rsp_t*)
heap_caps_malloc(sizeof(*response), MALLOC_CAP_DMA);
if (response == NULL) {
return ESP_ERR_NO_MEM;
size_t actual_size = 0;
sdmmc_switch_func_rsp_t *response = NULL;
esp_err_t err = esp_dma_malloc(sizeof(*response), 0, (void *)&response, &actual_size);
assert(actual_size == sizeof(*response));
if (err != ESP_OK) {
return err;
}
esp_err_t err = sdmmc_send_cmd_switch_func(card, 0, SD_ACCESS_MODE, 0, response);
err = sdmmc_send_cmd_switch_func(card, 0, SD_ACCESS_MODE, 0, response);
if (err != ESP_OK) {
ESP_LOGD(TAG, "%s: sdmmc_send_cmd_switch_func (1) returned 0x%x", __func__, err);
goto out;