mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 12:14:32 +02:00
Merge branch 'refactor/esp_driver_sdmmc' into 'master'
refactor(sdmmc): place sdmmc driver into a new component See merge request espressif/esp-idf!27059
This commit is contained in:
@@ -88,6 +88,7 @@
|
|||||||
/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154
|
/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154
|
||||||
/components/esp_common/ @esp-idf-codeowners/system
|
/components/esp_common/ @esp-idf-codeowners/system
|
||||||
/components/esp_driver_*/ @esp-idf-codeowners/peripherals
|
/components/esp_driver_*/ @esp-idf-codeowners/peripherals
|
||||||
|
/components/esp_driver_sdmmc/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/storage
|
||||||
/components/esp_eth/ @esp-idf-codeowners/network
|
/components/esp_eth/ @esp-idf-codeowners/network
|
||||||
/components/esp_event/ @esp-idf-codeowners/system
|
/components/esp_event/ @esp-idf-codeowners/system
|
||||||
/components/esp_gdbstub/ @esp-idf-codeowners/debugging
|
/components/esp_gdbstub/ @esp-idf-codeowners/debugging
|
||||||
|
@@ -18,7 +18,6 @@ set(includes "include"
|
|||||||
"parlio/include"
|
"parlio/include"
|
||||||
"rmt/include"
|
"rmt/include"
|
||||||
"sdio_slave/include"
|
"sdio_slave/include"
|
||||||
"sdmmc/include"
|
|
||||||
"sdspi/include"
|
"sdspi/include"
|
||||||
"sigma_delta/include"
|
"sigma_delta/include"
|
||||||
"temperature_sensor/include"
|
"temperature_sensor/include"
|
||||||
@@ -127,12 +126,6 @@ if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED)
|
|||||||
list(APPEND srcs "sdio_slave/sdio_slave.c")
|
list(APPEND srcs "sdio_slave/sdio_slave.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# SDMMC related source files
|
|
||||||
if(CONFIG_SOC_SDMMC_HOST_SUPPORTED)
|
|
||||||
list(APPEND srcs "sdmmc/sdmmc_transaction.c"
|
|
||||||
"sdmmc/sdmmc_host.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Sigma-Delta Modulation related source files
|
# Sigma-Delta Modulation related source files
|
||||||
if(CONFIG_SOC_SDM_SUPPORTED)
|
if(CONFIG_SOC_SDM_SUPPORTED)
|
||||||
list(APPEND srcs "sigma_delta/sdm.c"
|
list(APPEND srcs "sigma_delta/sdm.c"
|
||||||
@@ -199,6 +192,7 @@ else()
|
|||||||
# for backward compatibility, the driver component needs to
|
# for backward compatibility, the driver component needs to
|
||||||
# have a public dependency on other "esp_driver_foo" components
|
# have a public dependency on other "esp_driver_foo" components
|
||||||
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi esp_driver_mcpwm
|
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi esp_driver_mcpwm
|
||||||
|
esp_driver_sdmmc
|
||||||
LDFRAGMENTS ${ldfragments}
|
LDFRAGMENTS ${ldfragments}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
15
components/esp_driver_sdmmc/CMakeLists.txt
Normal file
15
components/esp_driver_sdmmc/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
set(srcs)
|
||||||
|
|
||||||
|
set(public_include "include")
|
||||||
|
|
||||||
|
# SDMMC related source files
|
||||||
|
if(CONFIG_SOC_SDMMC_HOST_SUPPORTED)
|
||||||
|
list(APPEND srcs "src/sdmmc_transaction.c"
|
||||||
|
"src/sdmmc_host.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS ${srcs}
|
||||||
|
INCLUDE_DIRS ${public_include}
|
||||||
|
REQUIRES sdmmc esp_driver_gpio
|
||||||
|
PRIV_REQUIRES esp_timer esp_pm esp_mm
|
||||||
|
)
|
@@ -50,8 +50,6 @@ extern "C" {
|
|||||||
#define SDMMC_SLOT_NO_WP GPIO_NUM_NC ///< indicates that write protect line is not used
|
#define SDMMC_SLOT_NO_WP GPIO_NUM_NC ///< indicates that write protect line is not used
|
||||||
#define SDMMC_SLOT_WIDTH_DEFAULT 0 ///< use the maximum possible width for the slot
|
#define SDMMC_SLOT_WIDTH_DEFAULT 0 ///< use the maximum possible width for the slot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if SOC_SDMMC_USE_IOMUX && !SOC_SDMMC_USE_GPIO_MATRIX
|
#if SOC_SDMMC_USE_IOMUX && !SOC_SDMMC_USE_GPIO_MATRIX
|
||||||
/**
|
/**
|
||||||
* Macro defining default configuration of SDMMC host slot
|
* Macro defining default configuration of SDMMC host slot
|
9
components/esp_driver_sdmmc/include/driver/sdmmc_defs.h
Normal file
9
components/esp_driver_sdmmc/include/driver/sdmmc_defs.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd_protocol_defs.h"
|
@@ -12,7 +12,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "sdmmc_types.h"
|
#include "driver/sdmmc_types.h"
|
||||||
#include "driver/sdmmc_default_configs.h"
|
#include "driver/sdmmc_default_configs.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
@@ -47,15 +47,15 @@ typedef struct {
|
|||||||
uint8_t width; ///< Bus width used by the slot (might be less than the max width supported)
|
uint8_t width; ///< Bus width used by the slot (might be less than the max width supported)
|
||||||
uint32_t flags; ///< Features used by this slot
|
uint32_t flags; ///< Features used by this slot
|
||||||
#define SDMMC_SLOT_FLAG_INTERNAL_PULLUP BIT(0)
|
#define SDMMC_SLOT_FLAG_INTERNAL_PULLUP BIT(0)
|
||||||
/**< Enable internal pullups on enabled pins. The internal pullups
|
/**< Enable internal pullups on enabled pins. The internal pullups
|
||||||
are insufficient however, please make sure external pullups are
|
are insufficient however, please make sure external pullups are
|
||||||
connected on the bus. This is for debug / example purpose only.
|
connected on the bus. This is for debug / example purpose only.
|
||||||
*/
|
*/
|
||||||
#define SDMMC_SLOT_FLAG_WP_ACTIVE_HIGH BIT(1)
|
#define SDMMC_SLOT_FLAG_WP_ACTIVE_HIGH BIT(1)
|
||||||
/**< GPIO write protect polarity.
|
/**< GPIO write protect polarity.
|
||||||
* 0 means "active low", i.e. card is protected when the GPIO is low;
|
* 0 means "active low", i.e. card is protected when the GPIO is low;
|
||||||
* 1 means "active high", i.e. card is protected when GPIO is high.
|
* 1 means "active high", i.e. card is protected when GPIO is high.
|
||||||
*/
|
*/
|
||||||
} sdmmc_slot_config_t;
|
} sdmmc_slot_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
9
components/esp_driver_sdmmc/include/driver/sdmmc_types.h
Normal file
9
components/esp_driver_sdmmc/include/driver/sdmmc_types.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd_protocol_types.h"
|
@@ -45,7 +45,6 @@
|
|||||||
#define SDMMC_CLK_SRC_ATOMIC()
|
#define SDMMC_CLK_SRC_ATOMIC()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "sdmmc_periph";
|
static const char *TAG = "sdmmc_periph";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +69,6 @@ typedef struct host_ctx_t {
|
|||||||
|
|
||||||
static host_ctx_t s_host_ctx;
|
static host_ctx_t s_host_ctx;
|
||||||
|
|
||||||
|
|
||||||
static void sdmmc_isr(void *arg);
|
static void sdmmc_isr(void *arg);
|
||||||
static void sdmmc_host_dma_init(void);
|
static void sdmmc_host_dma_init(void);
|
||||||
static esp_err_t sdmmc_host_pullup_en_internal(int slot, int width);
|
static esp_err_t sdmmc_host_pullup_en_internal(int slot, int width);
|
||||||
@@ -209,10 +207,10 @@ void sdmmc_host_get_clk_dividers(uint32_t freq_khz, int *host_div, int *card_div
|
|||||||
* effective frequency range: 400 kHz - 32 MHz (32.1 - 39.9 MHz cannot be covered with given divider scheme)
|
* effective frequency range: 400 kHz - 32 MHz (32.1 - 39.9 MHz cannot be covered with given divider scheme)
|
||||||
*/
|
*/
|
||||||
*host_div = (clk_src_freq_hz) / (freq_khz * 1000);
|
*host_div = (clk_src_freq_hz) / (freq_khz * 1000);
|
||||||
if (*host_div > 15 ) {
|
if (*host_div > 15) {
|
||||||
*host_div = 2;
|
*host_div = 2;
|
||||||
*card_div = (clk_src_freq_hz / 2) / (2 * freq_khz * 1000);
|
*card_div = (clk_src_freq_hz / 2) / (2 * freq_khz * 1000);
|
||||||
if ( ((clk_src_freq_hz / 2) % (2 * freq_khz * 1000)) > 0 ) {
|
if (((clk_src_freq_hz / 2) % (2 * freq_khz * 1000)) > 0) {
|
||||||
(*card_div)++;
|
(*card_div)++;
|
||||||
}
|
}
|
||||||
} else if ((clk_src_freq_hz % (freq_khz * 1000)) > 0) {
|
} else if ((clk_src_freq_hz % (freq_khz * 1000)) > 0) {
|
||||||
@@ -315,22 +313,22 @@ esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase)
|
|||||||
int delay_phase_num = 0;
|
int delay_phase_num = 0;
|
||||||
sdmmc_ll_delay_phase_t phase = SDMMC_LL_DELAY_PHASE_0;
|
sdmmc_ll_delay_phase_t phase = SDMMC_LL_DELAY_PHASE_0;
|
||||||
switch (delay_phase) {
|
switch (delay_phase) {
|
||||||
case SDMMC_DELAY_PHASE_1:
|
case SDMMC_DELAY_PHASE_1:
|
||||||
phase = SDMMC_LL_DELAY_PHASE_1;
|
phase = SDMMC_LL_DELAY_PHASE_1;
|
||||||
delay_phase_num = 1;
|
delay_phase_num = 1;
|
||||||
break;
|
break;
|
||||||
case SDMMC_DELAY_PHASE_2:
|
case SDMMC_DELAY_PHASE_2:
|
||||||
phase = SDMMC_LL_DELAY_PHASE_2;
|
phase = SDMMC_LL_DELAY_PHASE_2;
|
||||||
delay_phase_num = 2;
|
delay_phase_num = 2;
|
||||||
break;
|
break;
|
||||||
case SDMMC_DELAY_PHASE_3:
|
case SDMMC_DELAY_PHASE_3:
|
||||||
phase = SDMMC_LL_DELAY_PHASE_3;
|
phase = SDMMC_LL_DELAY_PHASE_3;
|
||||||
delay_phase_num = 3;
|
delay_phase_num = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
phase = SDMMC_LL_DELAY_PHASE_0;
|
phase = SDMMC_LL_DELAY_PHASE_0;
|
||||||
delay_phase_num = 0;
|
delay_phase_num = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SDMMC_CLK_SRC_ATOMIC() {
|
SDMMC_CLK_SRC_ATOMIC() {
|
||||||
sdmmc_ll_set_din_delay(s_host_ctx.hal.dev, phase);
|
sdmmc_ll_set_din_delay(s_host_ctx.hal.dev, phase);
|
||||||
@@ -433,13 +431,13 @@ esp_err_t sdmmc_host_init(void)
|
|||||||
}
|
}
|
||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
SDMMC.intmask.val =
|
SDMMC.intmask.val =
|
||||||
SDMMC_INTMASK_CD |
|
SDMMC_INTMASK_CD |
|
||||||
SDMMC_INTMASK_CMD_DONE |
|
SDMMC_INTMASK_CMD_DONE |
|
||||||
SDMMC_INTMASK_DATA_OVER |
|
SDMMC_INTMASK_DATA_OVER |
|
||||||
SDMMC_INTMASK_RCRC | SDMMC_INTMASK_DCRC |
|
SDMMC_INTMASK_RCRC | SDMMC_INTMASK_DCRC |
|
||||||
SDMMC_INTMASK_RTO | SDMMC_INTMASK_DTO | SDMMC_INTMASK_HTO |
|
SDMMC_INTMASK_RTO | SDMMC_INTMASK_DTO | SDMMC_INTMASK_HTO |
|
||||||
SDMMC_INTMASK_SBE | SDMMC_INTMASK_EBE |
|
SDMMC_INTMASK_SBE | SDMMC_INTMASK_EBE |
|
||||||
SDMMC_INTMASK_RESP_ERR | SDMMC_INTMASK_HLE; //sdio is enabled only when use.
|
SDMMC_INTMASK_RESP_ERR | SDMMC_INTMASK_HLE; //sdio is enabled only when use.
|
||||||
SDMMC.ctrl.int_enable = 1;
|
SDMMC.ctrl.int_enable = 1;
|
||||||
|
|
||||||
// Disable generation of Busy Clear Interrupt
|
// Disable generation of Busy Clear Interrupt
|
||||||
@@ -479,7 +477,7 @@ static void configure_pin_iomux(uint8_t gpio_num)
|
|||||||
|
|
||||||
static void configure_pin_gpio_matrix(uint8_t gpio_num, uint8_t gpio_matrix_sig, gpio_mode_t mode, const char *name)
|
static void configure_pin_gpio_matrix(uint8_t gpio_num, uint8_t gpio_matrix_sig, gpio_mode_t mode, const char *name)
|
||||||
{
|
{
|
||||||
assert (gpio_num != (uint8_t) GPIO_NUM_NC);
|
assert(gpio_num != (uint8_t) GPIO_NUM_NC);
|
||||||
ESP_LOGD(TAG, "using GPIO%d as %s pin", gpio_num, name);
|
ESP_LOGD(TAG, "using GPIO%d as %s pin", gpio_num, name);
|
||||||
gpio_reset_pin(gpio_num);
|
gpio_reset_pin(gpio_num);
|
||||||
gpio_set_direction(gpio_num, mode);
|
gpio_set_direction(gpio_num, mode);
|
||||||
@@ -651,7 +649,7 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
|
|||||||
// As hardware expects an active-high signal,
|
// As hardware expects an active-high signal,
|
||||||
// if WP signal is active low, then invert it in GPIO matrix,
|
// if WP signal is active low, then invert it in GPIO matrix,
|
||||||
// else keep it in its default state
|
// else keep it in its default state
|
||||||
esp_rom_gpio_connect_in_signal(matrix_in_wp, slot_info->write_protect, (gpio_wp_polarity? false : true));
|
esp_rom_gpio_connect_in_signal(matrix_in_wp, slot_info->write_protect, (gpio_wp_polarity ? false : true));
|
||||||
|
|
||||||
// By default, set probing frequency (400kHz) and 1-bit bus
|
// By default, set probing frequency (400kHz) and 1-bit bus
|
||||||
esp_err_t ret = sdmmc_host_set_card_clk(slot, 400);
|
esp_err_t ret = sdmmc_host_set_card_clk(slot, 400);
|
||||||
@@ -733,7 +731,7 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
|
|||||||
|
|
||||||
size_t sdmmc_host_get_slot_width(int slot)
|
size_t sdmmc_host_get_slot_width(int slot)
|
||||||
{
|
{
|
||||||
assert( slot == 0 || slot == 1 );
|
assert(slot == 0 || slot == 1);
|
||||||
return s_host_ctx.slot_ctx[slot].slot_width;
|
return s_host_ctx.slot_ctx[slot].slot_width;
|
||||||
}
|
}
|
||||||
|
|
@@ -18,13 +18,11 @@
|
|||||||
#include "driver/sdmmc_types.h"
|
#include "driver/sdmmc_types.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "driver/sdmmc_defs.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
#include "esp_timer.h"
|
|
||||||
#include "esp_cache.h"
|
#include "esp_cache.h"
|
||||||
#include "esp_private/esp_cache_private.h"
|
#include "esp_private/esp_cache_private.h"
|
||||||
#include "sdmmc_private.h"
|
#include "sdmmc_private.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
|
|
||||||
/* Number of DMA descriptors used for transfer.
|
/* Number of DMA descriptors used for transfer.
|
||||||
* Increasing this value above 4 doesn't improve performance for the usual case
|
* Increasing this value above 4 doesn't improve performance for the usual case
|
||||||
* of SD memory cards (most data transfers are multiples of 512 bytes).
|
* of SD memory cards (most data transfers are multiples of 512 bytes).
|
||||||
@@ -56,18 +54,18 @@ typedef struct {
|
|||||||
} sdmmc_transfer_state_t;
|
} sdmmc_transfer_state_t;
|
||||||
|
|
||||||
const uint32_t SDMMC_DATA_ERR_MASK =
|
const uint32_t SDMMC_DATA_ERR_MASK =
|
||||||
SDMMC_INTMASK_DTO | SDMMC_INTMASK_DCRC |
|
SDMMC_INTMASK_DTO | SDMMC_INTMASK_DCRC |
|
||||||
SDMMC_INTMASK_HTO | SDMMC_INTMASK_SBE |
|
SDMMC_INTMASK_HTO | SDMMC_INTMASK_SBE |
|
||||||
SDMMC_INTMASK_EBE;
|
SDMMC_INTMASK_EBE;
|
||||||
|
|
||||||
const uint32_t SDMMC_DMA_DONE_MASK =
|
const uint32_t SDMMC_DMA_DONE_MASK =
|
||||||
SDMMC_IDMAC_INTMASK_RI | SDMMC_IDMAC_INTMASK_TI |
|
SDMMC_IDMAC_INTMASK_RI | SDMMC_IDMAC_INTMASK_TI |
|
||||||
SDMMC_IDMAC_INTMASK_NI;
|
SDMMC_IDMAC_INTMASK_NI;
|
||||||
|
|
||||||
const uint32_t SDMMC_CMD_ERR_MASK =
|
const uint32_t SDMMC_CMD_ERR_MASK =
|
||||||
SDMMC_INTMASK_RTO |
|
SDMMC_INTMASK_RTO |
|
||||||
SDMMC_INTMASK_RCRC |
|
SDMMC_INTMASK_RCRC |
|
||||||
SDMMC_INTMASK_RESP_ERR;
|
SDMMC_INTMASK_RESP_ERR;
|
||||||
|
|
||||||
SDMMC_ALIGN_ATTR static sdmmc_desc_t s_dma_desc[SDMMC_DMA_DESC_CNT];
|
SDMMC_ALIGN_ATTR static sdmmc_desc_t s_dma_desc[SDMMC_DMA_DESC_CNT];
|
||||||
static sdmmc_transfer_state_t s_cur_transfer = { 0 };
|
static sdmmc_transfer_state_t s_cur_transfer = { 0 };
|
||||||
@@ -80,9 +78,9 @@ static esp_pm_lock_handle_t s_pm_lock;
|
|||||||
static esp_err_t handle_idle_state_events(void);
|
static esp_err_t handle_idle_state_events(void);
|
||||||
static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd);
|
static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd);
|
||||||
static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
|
static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
|
||||||
sdmmc_event_t* unhandled_events);
|
sdmmc_event_t* unhandled_events);
|
||||||
static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd,
|
static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd,
|
||||||
sdmmc_req_state_t* pstate, sdmmc_event_t* unhandled_events);
|
sdmmc_req_state_t* pstate, sdmmc_event_t* unhandled_events);
|
||||||
static void process_command_response(uint32_t status, sdmmc_command_t* cmd);
|
static void process_command_response(uint32_t status, sdmmc_command_t* cmd);
|
||||||
static void fill_dma_descriptors(size_t num_desc);
|
static void fill_dma_descriptors(size_t num_desc);
|
||||||
static size_t get_free_descriptors_count(void);
|
static size_t get_free_descriptors_count(void);
|
||||||
@@ -139,7 +137,7 @@ esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
|
|||||||
// Length should be either <4 or >=4 and =0 (mod 4).
|
// Length should be either <4 or >=4 and =0 (mod 4).
|
||||||
if (cmdinfo->datalen >= 4 && cmdinfo->datalen % 4 != 0) {
|
if (cmdinfo->datalen >= 4 && cmdinfo->datalen % 4 != 0) {
|
||||||
ESP_LOGD(TAG, "%s: invalid size: total=%d",
|
ESP_LOGD(TAG, "%s: invalid size: total=%d",
|
||||||
__func__, cmdinfo->datalen);
|
__func__, cmdinfo->datalen);
|
||||||
ret = ESP_ERR_INVALID_SIZE;
|
ret = ESP_ERR_INVALID_SIZE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -247,7 +245,7 @@ static void fill_dma_descriptors(size_t num_desc)
|
|||||||
assert(!desc->owned_by_idmac);
|
assert(!desc->owned_by_idmac);
|
||||||
size_t size_to_fill =
|
size_t size_to_fill =
|
||||||
(s_cur_transfer.size_remaining < SDMMC_DMA_MAX_BUF_LEN) ?
|
(s_cur_transfer.size_remaining < SDMMC_DMA_MAX_BUF_LEN) ?
|
||||||
s_cur_transfer.size_remaining : SDMMC_DMA_MAX_BUF_LEN;
|
s_cur_transfer.size_remaining : SDMMC_DMA_MAX_BUF_LEN;
|
||||||
bool last = size_to_fill == s_cur_transfer.size_remaining;
|
bool last = size_to_fill == s_cur_transfer.size_remaining;
|
||||||
desc->last_descriptor = last;
|
desc->last_descriptor = last;
|
||||||
desc->second_address_chained = 1;
|
desc->second_address_chained = 1;
|
||||||
@@ -261,8 +259,8 @@ static void fill_dma_descriptors(size_t num_desc)
|
|||||||
s_cur_transfer.ptr += size_to_fill;
|
s_cur_transfer.ptr += size_to_fill;
|
||||||
s_cur_transfer.next_desc = (s_cur_transfer.next_desc + 1) % SDMMC_DMA_DESC_CNT;
|
s_cur_transfer.next_desc = (s_cur_transfer.next_desc + 1) % SDMMC_DMA_DESC_CNT;
|
||||||
ESP_LOGV(TAG, "fill %d desc=%d rem=%d next=%d last=%d sz=%d",
|
ESP_LOGV(TAG, "fill %d desc=%d rem=%d next=%d last=%d sz=%d",
|
||||||
num_desc, next, s_cur_transfer.size_remaining,
|
num_desc, next, s_cur_transfer.size_remaining,
|
||||||
s_cur_transfer.next_desc, desc->last_descriptor, desc->buffer1_size);
|
s_cur_transfer.next_desc, desc->last_descriptor, desc->buffer1_size);
|
||||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
esp_err_t ret = esp_cache_msync((void *)desc, sizeof(sdmmc_desc_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
esp_err_t ret = esp_cache_msync((void *)desc, sizeof(sdmmc_desc_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||||
assert(ret == ESP_OK);
|
assert(ret == ESP_OK);
|
||||||
@@ -284,16 +282,15 @@ static esp_err_t handle_idle_state_events(void)
|
|||||||
}
|
}
|
||||||
if (evt.sdmmc_status != 0 || evt.dma_status != 0) {
|
if (evt.sdmmc_status != 0 || evt.dma_status != 0) {
|
||||||
ESP_LOGE(TAG, "handle_idle_state_events unhandled: %08"PRIx32" %08"PRIx32,
|
ESP_LOGE(TAG, "handle_idle_state_events unhandled: %08"PRIx32" %08"PRIx32,
|
||||||
evt.sdmmc_status, evt.dma_status);
|
evt.sdmmc_status, evt.dma_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
|
static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
|
||||||
sdmmc_event_t* unhandled_events)
|
sdmmc_event_t* unhandled_events)
|
||||||
{
|
{
|
||||||
sdmmc_event_t event;
|
sdmmc_event_t event;
|
||||||
esp_err_t err = sdmmc_host_wait_for_event(cmd->timeout_ms / portTICK_PERIOD_MS, &event);
|
esp_err_t err = sdmmc_host_wait_for_event(cmd->timeout_ms / portTICK_PERIOD_MS, &event);
|
||||||
@@ -305,8 +302,8 @@ static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "sdmmc_handle_event: event %08"PRIx32" %08"PRIx32", unhandled %08"PRIx32" %08"PRIx32,
|
ESP_LOGV(TAG, "sdmmc_handle_event: event %08"PRIx32" %08"PRIx32", unhandled %08"PRIx32" %08"PRIx32,
|
||||||
event.sdmmc_status, event.dma_status,
|
event.sdmmc_status, event.dma_status,
|
||||||
unhandled_events->sdmmc_status, unhandled_events->dma_status);
|
unhandled_events->sdmmc_status, unhandled_events->dma_status);
|
||||||
event.sdmmc_status |= unhandled_events->sdmmc_status;
|
event.sdmmc_status |= unhandled_events->sdmmc_status;
|
||||||
event.dma_status |= unhandled_events->dma_status;
|
event.dma_status |= unhandled_events->dma_status;
|
||||||
process_events(event, cmd, state, unhandled_events);
|
process_events(event, cmd, state, unhandled_events);
|
||||||
@@ -357,8 +354,8 @@ static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd)
|
|||||||
res.send_auto_stop = cmd_needs_auto_stop(cmd) ? 1 : 0;
|
res.send_auto_stop = cmd_needs_auto_stop(cmd) ? 1 : 0;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d, auto_stop=%d", __func__,
|
ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d, auto_stop=%d", __func__,
|
||||||
res.cmd_index, res.response_expect, res.check_response_crc,
|
res.cmd_index, res.response_expect, res.check_response_crc,
|
||||||
res.send_auto_stop);
|
res.send_auto_stop);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +399,7 @@ static void process_data_status(uint32_t status, sdmmc_command_t* cmd)
|
|||||||
} else if (status & SDMMC_INTMASK_DCRC) {
|
} else if (status & SDMMC_INTMASK_DCRC) {
|
||||||
cmd->error = ESP_ERR_INVALID_CRC;
|
cmd->error = ESP_ERR_INVALID_CRC;
|
||||||
} else if ((status & SDMMC_INTMASK_EBE) &&
|
} else if ((status & SDMMC_INTMASK_EBE) &&
|
||||||
(cmd->flags & SCF_CMD_READ) == 0) {
|
(cmd->flags & SCF_CMD_READ) == 0) {
|
||||||
cmd->error = ESP_ERR_TIMEOUT;
|
cmd->error = ESP_ERR_TIMEOUT;
|
||||||
} else {
|
} else {
|
||||||
cmd->error = ESP_FAIL;
|
cmd->error = ESP_FAIL;
|
||||||
@@ -418,14 +415,15 @@ static void process_data_status(uint32_t status, sdmmc_command_t* cmd)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool mask_check_and_clear(uint32_t* state, uint32_t mask) {
|
static inline bool mask_check_and_clear(uint32_t* state, uint32_t mask)
|
||||||
|
{
|
||||||
bool ret = ((*state) & mask) != 0;
|
bool ret = ((*state) & mask) != 0;
|
||||||
*state &= ~mask;
|
*state &= ~mask;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd,
|
static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd,
|
||||||
sdmmc_req_state_t* pstate, sdmmc_event_t* unhandled_events)
|
sdmmc_req_state_t* pstate, sdmmc_event_t* unhandled_events)
|
||||||
{
|
{
|
||||||
const char* const s_state_names[] __attribute__((unused)) = {
|
const char* const s_state_names[] __attribute__((unused)) = {
|
||||||
"IDLE",
|
"IDLE",
|
||||||
@@ -435,68 +433,67 @@ static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd,
|
|||||||
};
|
};
|
||||||
sdmmc_event_t orig_evt = evt;
|
sdmmc_event_t orig_evt = evt;
|
||||||
ESP_LOGV(TAG, "%s: state=%s evt=%"PRIx32" dma=%"PRIx32, __func__, s_state_names[*pstate],
|
ESP_LOGV(TAG, "%s: state=%s evt=%"PRIx32" dma=%"PRIx32, __func__, s_state_names[*pstate],
|
||||||
evt.sdmmc_status, evt.dma_status);
|
evt.sdmmc_status, evt.dma_status);
|
||||||
sdmmc_req_state_t next_state = *pstate;
|
sdmmc_req_state_t next_state = *pstate;
|
||||||
sdmmc_req_state_t state = (sdmmc_req_state_t) -1;
|
sdmmc_req_state_t state = (sdmmc_req_state_t) -1;
|
||||||
while (next_state != state) {
|
while (next_state != state) {
|
||||||
state = next_state;
|
state = next_state;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SDMMC_IDLE:
|
case SDMMC_IDLE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDMMC_SENDING_CMD:
|
case SDMMC_SENDING_CMD:
|
||||||
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_CMD_ERR_MASK)) {
|
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_CMD_ERR_MASK)) {
|
||||||
process_command_response(orig_evt.sdmmc_status, cmd);
|
process_command_response(orig_evt.sdmmc_status, cmd);
|
||||||
// In addition to the error interrupt, CMD_DONE will also be
|
// In addition to the error interrupt, CMD_DONE will also be
|
||||||
// reported. It may occur immediately (in the same sdmmc_event_t) or
|
// reported. It may occur immediately (in the same sdmmc_event_t) or
|
||||||
// be delayed until the next interrupt.
|
// be delayed until the next interrupt.
|
||||||
}
|
}
|
||||||
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_INTMASK_CMD_DONE)) {
|
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_INTMASK_CMD_DONE)) {
|
||||||
process_command_response(orig_evt.sdmmc_status, cmd);
|
process_command_response(orig_evt.sdmmc_status, cmd);
|
||||||
if (cmd->error != ESP_OK) {
|
if (cmd->error != ESP_OK) {
|
||||||
next_state = SDMMC_IDLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->data == NULL) {
|
|
||||||
next_state = SDMMC_IDLE;
|
|
||||||
} else {
|
|
||||||
next_state = SDMMC_SENDING_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case SDMMC_SENDING_DATA:
|
|
||||||
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_DATA_ERR_MASK)) {
|
|
||||||
process_data_status(orig_evt.sdmmc_status, cmd);
|
|
||||||
sdmmc_host_dma_stop();
|
|
||||||
}
|
|
||||||
if (mask_check_and_clear(&evt.dma_status, SDMMC_DMA_DONE_MASK)) {
|
|
||||||
s_cur_transfer.desc_remaining--;
|
|
||||||
if (s_cur_transfer.size_remaining) {
|
|
||||||
int desc_to_fill = get_free_descriptors_count();
|
|
||||||
fill_dma_descriptors(desc_to_fill);
|
|
||||||
sdmmc_host_dma_resume();
|
|
||||||
}
|
|
||||||
if (s_cur_transfer.desc_remaining == 0) {
|
|
||||||
next_state = SDMMC_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (orig_evt.sdmmc_status & (SDMMC_INTMASK_SBE | SDMMC_INTMASK_DATA_OVER)) {
|
|
||||||
// On start bit error, DATA_DONE interrupt will not be generated
|
|
||||||
next_state = SDMMC_IDLE;
|
next_state = SDMMC_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case SDMMC_BUSY:
|
if (cmd->data == NULL) {
|
||||||
if (!mask_check_and_clear(&evt.sdmmc_status, SDMMC_INTMASK_DATA_OVER)) {
|
next_state = SDMMC_IDLE;
|
||||||
break;
|
} else {
|
||||||
|
next_state = SDMMC_SENDING_DATA;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDMMC_SENDING_DATA:
|
||||||
|
if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_DATA_ERR_MASK)) {
|
||||||
process_data_status(orig_evt.sdmmc_status, cmd);
|
process_data_status(orig_evt.sdmmc_status, cmd);
|
||||||
|
sdmmc_host_dma_stop();
|
||||||
|
}
|
||||||
|
if (mask_check_and_clear(&evt.dma_status, SDMMC_DMA_DONE_MASK)) {
|
||||||
|
s_cur_transfer.desc_remaining--;
|
||||||
|
if (s_cur_transfer.size_remaining) {
|
||||||
|
int desc_to_fill = get_free_descriptors_count();
|
||||||
|
fill_dma_descriptors(desc_to_fill);
|
||||||
|
sdmmc_host_dma_resume();
|
||||||
|
}
|
||||||
|
if (s_cur_transfer.desc_remaining == 0) {
|
||||||
|
next_state = SDMMC_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (orig_evt.sdmmc_status & (SDMMC_INTMASK_SBE | SDMMC_INTMASK_DATA_OVER)) {
|
||||||
|
// On start bit error, DATA_DONE interrupt will not be generated
|
||||||
next_state = SDMMC_IDLE;
|
next_state = SDMMC_IDLE;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDMMC_BUSY:
|
||||||
|
if (!mask_check_and_clear(&evt.sdmmc_status, SDMMC_INTMASK_DATA_OVER)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
process_data_status(orig_evt.sdmmc_status, cmd);
|
||||||
|
next_state = SDMMC_IDLE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "%s state=%s next_state=%s", __func__, s_state_names[state], s_state_names[next_state]);
|
ESP_LOGV(TAG, "%s state=%s next_state=%s", __func__, s_state_names[state], s_state_names[next_state]);
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ else()
|
|||||||
|
|
||||||
list(APPEND include_dirs "vfs")
|
list(APPEND include_dirs "vfs")
|
||||||
|
|
||||||
list(APPEND requires "sdmmc")
|
list(APPEND requires "sdmmc" "driver") # `driver` will be replaced with `esp_driver_sdspi`
|
||||||
|
|
||||||
list(APPEND priv_requires "vfs" "esp_driver_gpio")
|
list(APPEND priv_requires "vfs" "esp_driver_gpio")
|
||||||
endif()
|
endif()
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@@ -7,8 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "driver/gpio.h"
|
#include "sd_protocol_types.h"
|
||||||
#include "driver/sdmmc_types.h"
|
|
||||||
#include "driver/sdspi_host.h"
|
#include "driver/sdspi_host.h"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "wear_levelling.h"
|
#include "wear_levelling.h"
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
#include "diskio_impl.h"
|
#include "diskio_impl.h"
|
||||||
#include "diskio_sdmmc.h"
|
#include "diskio_sdmmc.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
|
|
||||||
#if SOC_SDMMC_HOST_SUPPORTED
|
#if SOC_SDMMC_HOST_SUPPORTED
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
|
@@ -11,5 +11,4 @@ idf_component_register(SRCS "sdmmc_cmd.c"
|
|||||||
"sdmmc_mmc.c"
|
"sdmmc_mmc.c"
|
||||||
"sdmmc_sd.c"
|
"sdmmc_sd.c"
|
||||||
INCLUDE_DIRS include
|
INCLUDE_DIRS include
|
||||||
REQUIRES driver
|
|
||||||
PRIV_REQUIRES soc esp_timer)
|
PRIV_REQUIRES soc esp_timer)
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* SPDX-FileContributor: 2016-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
|
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
|
||||||
@@ -75,7 +75,6 @@ extern "C" {
|
|||||||
#define SD_IO_RW_DIRECT 52 /* R5 */
|
#define SD_IO_RW_DIRECT 52 /* R5 */
|
||||||
#define SD_IO_RW_EXTENDED 53 /* R5 */
|
#define SD_IO_RW_EXTENDED 53 /* R5 */
|
||||||
|
|
||||||
|
|
||||||
/* OCR bits */
|
/* OCR bits */
|
||||||
#define MMC_OCR_MEM_READY (1<<31) /* memory power-up status bit */
|
#define MMC_OCR_MEM_READY (1<<31) /* memory power-up status bit */
|
||||||
#define MMC_OCR_ACCESS_MODE_MASK 0x60000000 /* bits 30:29 */
|
#define MMC_OCR_ACCESS_MODE_MASK 0x60000000 /* bits 30:29 */
|
||||||
@@ -528,7 +527,6 @@ static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len)
|
|||||||
#define CISTPL_CODE_SDIO_EXT 0x92
|
#define CISTPL_CODE_SDIO_EXT 0x92
|
||||||
#define CISTPL_CODE_END 0xFF
|
#define CISTPL_CODE_END 0xFF
|
||||||
|
|
||||||
|
|
||||||
/* Timing */
|
/* Timing */
|
||||||
#define SDMMC_TIMING_LEGACY 0
|
#define SDMMC_TIMING_LEGACY 0
|
||||||
#define SDMMC_TIMING_HIGHSPEED 1
|
#define SDMMC_TIMING_HIGHSPEED 1
|
@@ -110,15 +110,15 @@ typedef struct {
|
|||||||
* SD/MMC command information
|
* SD/MMC command information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t opcode; /*!< SD or MMC command index */
|
uint32_t opcode; /*!< SD or MMC command index */
|
||||||
uint32_t arg; /*!< SD/MMC command argument */
|
uint32_t arg; /*!< SD/MMC command argument */
|
||||||
sdmmc_response_t response; /*!< response buffer */
|
sdmmc_response_t response; /*!< response buffer */
|
||||||
void* data; /*!< buffer to send or read into */
|
void* data; /*!< buffer to send or read into */
|
||||||
size_t datalen; /*!< length of data in the buffer */
|
size_t datalen; /*!< length of data in the buffer */
|
||||||
size_t buflen; /*!< length of the buffer */
|
size_t buflen; /*!< length of the buffer */
|
||||||
size_t blklen; /*!< block length */
|
size_t blklen; /*!< block length */
|
||||||
int flags; /*!< see below */
|
int flags; /*!< see below */
|
||||||
/** @cond */
|
/** @cond */
|
||||||
#define SCF_ITSDONE 0x0001 /*!< command is complete */
|
#define SCF_ITSDONE 0x0001 /*!< command is complete */
|
||||||
#define SCF_CMD(flags) ((flags) & 0x00f0)
|
#define SCF_CMD(flags) ((flags) & 0x00f0)
|
||||||
#define SCF_CMD_AC 0x0000
|
#define SCF_CMD_AC 0x0000
|
||||||
@@ -131,7 +131,7 @@ typedef struct {
|
|||||||
#define SCF_RSP_CRC 0x0400
|
#define SCF_RSP_CRC 0x0400
|
||||||
#define SCF_RSP_IDX 0x0800
|
#define SCF_RSP_IDX 0x0800
|
||||||
#define SCF_RSP_PRESENT 0x1000
|
#define SCF_RSP_PRESENT 0x1000
|
||||||
/* response types */
|
/* response types */
|
||||||
#define SCF_RSP_R0 0 /*!< none */
|
#define SCF_RSP_R0 0 /*!< none */
|
||||||
#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
||||||
#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
|
#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
|
||||||
@@ -142,11 +142,11 @@ typedef struct {
|
|||||||
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
|
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
|
||||||
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
||||||
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
|
||||||
/* special flags */
|
/* special flags */
|
||||||
#define SCF_WAIT_BUSY 0x2000 /*!< Wait for completion of card busy signal before returning */
|
#define SCF_WAIT_BUSY 0x2000 /*!< Wait for completion of card busy signal before returning */
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
esp_err_t error; /*!< error returned from transfer */
|
esp_err_t error; /*!< error returned from transfer */
|
||||||
uint32_t timeout_ms; /*!< response timeout, in milliseconds */
|
uint32_t timeout_ms; /*!< response timeout, in milliseconds */
|
||||||
} sdmmc_command_t;
|
} sdmmc_command_t;
|
||||||
|
|
||||||
/**
|
/**
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@@ -21,8 +21,8 @@
|
|||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "sys/param.h"
|
#include "sys/param.h"
|
||||||
#include "soc/soc_memory_layout.h"
|
#include "soc/soc_memory_layout.h"
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
|
||||||
|
|
||||||
components/sdmmc/test_apps:
|
|
||||||
disable:
|
|
||||||
- if: IDF_TARGET in ["esp32h2"]
|
|
||||||
temporary: true
|
|
||||||
reason: Console component not supported on H2 yet
|
|
||||||
disable_test:
|
|
||||||
- if: IDF_TARGET not in ["esp32", "esp32s2", "esp32c3"]
|
|
||||||
temporary: true
|
|
||||||
reason: No runners for other targets yet
|
|
@@ -1,4 +0,0 @@
|
|||||||
idf_component_register(SRCS cmd_sdmmc.c
|
|
||||||
INCLUDE_DIRS .
|
|
||||||
PRIV_REQUIRES console sdmmc sdmmc_test_board
|
|
||||||
)
|
|
@@ -98,9 +98,9 @@ INPUT = \
|
|||||||
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_types.h \
|
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_types.h \
|
||||||
$(PROJECT_PATH)/components/driver/sdio_slave/include/driver/sdio_slave.h \
|
$(PROJECT_PATH)/components/driver/sdio_slave/include/driver/sdio_slave.h \
|
||||||
$(PROJECT_PATH)/components/driver/sigma_delta/include/driver/sdm.h \
|
$(PROJECT_PATH)/components/driver/sigma_delta/include/driver/sdm.h \
|
||||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_default_configs.h \
|
$(PROJECT_PATH)/components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h \
|
||||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_host.h \
|
$(PROJECT_PATH)/components/esp_driver_sdmmc/include/driver/sdmmc_host.h \
|
||||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_types.h \
|
$(PROJECT_PATH)/components/esp_driver_sdmmc/include/driver/sdmmc_types.h \
|
||||||
$(PROJECT_PATH)/components/driver/sdspi/include/driver/sdspi_host.h \
|
$(PROJECT_PATH)/components/driver/sdspi/include/driver/sdspi_host.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_common.h \
|
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_common.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_master.h \
|
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_master.h \
|
||||||
|
@@ -8,7 +8,7 @@ Overview
|
|||||||
|
|
||||||
The SD/SDIO/MMC driver currently supports SD memory, SDIO cards, and eMMC chips. This is a protocol level driver built on top of SDMMC and SD SPI host drivers.
|
The SD/SDIO/MMC driver currently supports SD memory, SDIO cards, and eMMC chips. This is a protocol level driver built on top of SDMMC and SD SPI host drivers.
|
||||||
|
|
||||||
SDMMC and SD SPI host drivers (:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` and :component_file:`driver/sdspi/include/driver/sdspi_host.h`) provide API functions for:
|
SDMMC and SD SPI host drivers (:component_file:`esp_driver_sdmmc/include/driver/sdmmc_host.h` and :component_file:`driver/sdspi/include/driver/sdspi_host.h`) provide API functions for:
|
||||||
|
|
||||||
- Sending commands to slave devices
|
- Sending commands to slave devices
|
||||||
- Sending and receiving data
|
- Sending and receiving data
|
||||||
|
@@ -10,6 +10,7 @@ In order to control the dependence of other components on drivers at a smaller g
|
|||||||
- `esp_driver_gpio` - Driver for GPIO
|
- `esp_driver_gpio` - Driver for GPIO
|
||||||
- `esp_driver_spi` - Driver for GPSPI
|
- `esp_driver_spi` - Driver for GPSPI
|
||||||
- `esp_driver_mcpwm` - Driver for Motor Control PWM
|
- `esp_driver_mcpwm` - Driver for Motor Control PWM
|
||||||
|
- `esp_driver_sdmmc` - Driver for SDMMC
|
||||||
|
|
||||||
For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on.
|
For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on.
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ SD/SDIO/MMC 驱动程序
|
|||||||
|
|
||||||
SD/SDIO/MMC 驱动是一种基于 SDMMC 和 SD SPI 主机驱动的协议级驱动程序,目前已支持 SD 存储器、SDIO 卡和 eMMC 芯片。
|
SD/SDIO/MMC 驱动是一种基于 SDMMC 和 SD SPI 主机驱动的协议级驱动程序,目前已支持 SD 存储器、SDIO 卡和 eMMC 芯片。
|
||||||
|
|
||||||
SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` 和 :component_file:`driver/sdspi/include/driver/sdspi_host.h`)为以下功能提供 API:
|
SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`esp_driver_sdmmc/include/driver/sdmmc_host.h` 和 :component_file:`driver/sdspi/include/driver/sdspi_host.h`)为以下功能提供 API:
|
||||||
|
|
||||||
- 发送命令至从设备
|
- 发送命令至从设备
|
||||||
- 接收和发送数据
|
- 接收和发送数据
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
- `esp_driver_gpio` - GPIO 驱动
|
- `esp_driver_gpio` - GPIO 驱动
|
||||||
- `esp_driver_spi` - 通用 SPI 驱动
|
- `esp_driver_spi` - 通用 SPI 驱动
|
||||||
- `esp_driver_mcpwm` - 电机控制 PWM 驱动
|
- `esp_driver_mcpwm` - 电机控制 PWM 驱动
|
||||||
|
- `esp_driver_sdmmc` - SDMMC 驱动
|
||||||
|
|
||||||
为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。
|
为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。
|
||||||
|
|
||||||
|
@@ -11,9 +11,10 @@ examples/storage/custom_flash_driver:
|
|||||||
examples/storage/emmc:
|
examples/storage/emmc:
|
||||||
depends_components:
|
depends_components:
|
||||||
- sdmmc
|
- sdmmc
|
||||||
- driver
|
- driver # `driver` will be replaced with `esp_driver_sdspi`
|
||||||
- fatfs
|
- fatfs
|
||||||
- vfs
|
- vfs
|
||||||
|
- esp_driver_sdmmc
|
||||||
enable:
|
enable:
|
||||||
- if: IDF_TARGET == "esp32s3"
|
- if: IDF_TARGET == "esp32s3"
|
||||||
reason: only support on esp32s3
|
reason: only support on esp32s3
|
||||||
@@ -107,7 +108,7 @@ examples/storage/perf_benchmark:
|
|||||||
- spiffs
|
- spiffs
|
||||||
- wear_levelling
|
- wear_levelling
|
||||||
- esp_partition
|
- esp_partition
|
||||||
- driver
|
- esp_driver_sdmmc
|
||||||
disable:
|
disable:
|
||||||
- if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"]
|
- if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"]
|
||||||
temporary: true
|
temporary: true
|
||||||
@@ -121,7 +122,7 @@ examples/storage/sd_card/sdmmc:
|
|||||||
depends_components:
|
depends_components:
|
||||||
- vfs
|
- vfs
|
||||||
- sdmmc
|
- sdmmc
|
||||||
- driver
|
- esp_driver_sdmmc
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_SDMMC_HOST_SUPPORTED != 1
|
- if: SOC_SDMMC_HOST_SUPPORTED != 1
|
||||||
disable_test:
|
disable_test:
|
||||||
@@ -133,7 +134,7 @@ examples/storage/sd_card/sdspi:
|
|||||||
depends_components:
|
depends_components:
|
||||||
- vfs
|
- vfs
|
||||||
- sdmmc
|
- sdmmc
|
||||||
- driver
|
- driver # To be updated to `esp_driver_sdspi`
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_GPSPI_SUPPORTED != 1
|
- if: SOC_GPSPI_SUPPORTED != 1
|
||||||
disable_test:
|
disable_test:
|
||||||
|
@@ -121,7 +121,7 @@ spiffs:
|
|||||||
|
|
||||||
sdmmc:
|
sdmmc:
|
||||||
include:
|
include:
|
||||||
- 'components/driver/sdmmc/include/driver/'
|
- 'components/esp_driver_sdmmc/include/driver/'
|
||||||
- 'components/sdmmc/'
|
- 'components/sdmmc/'
|
||||||
allowed_licenses:
|
allowed_licenses:
|
||||||
- Apache-2.0
|
- Apache-2.0
|
||||||
|
@@ -87,6 +87,20 @@ tools/test_apps/storage/partition_table_readonly:
|
|||||||
- fatfs
|
- fatfs
|
||||||
- spiffs
|
- spiffs
|
||||||
|
|
||||||
|
tools/test_apps/storage/sdmmc_console:
|
||||||
|
disable:
|
||||||
|
- if: IDF_TARGET in ["esp32h2"]
|
||||||
|
temporary: true
|
||||||
|
reason: Console component not supported on H2 yet
|
||||||
|
disable_test:
|
||||||
|
- if: IDF_TARGET not in ["esp32", "esp32s2", "esp32c3"]
|
||||||
|
temporary: true
|
||||||
|
reason: No runners for other targets yet
|
||||||
|
depends_components:
|
||||||
|
- sdmmc
|
||||||
|
- esp_driver_sdmmc
|
||||||
|
- driver # driver will be replaced with esp_driver_sdspi
|
||||||
|
|
||||||
tools/test_apps/system/bootloader_sections:
|
tools/test_apps/system/bootloader_sections:
|
||||||
disable:
|
disable:
|
||||||
- if: IDF_TARGET == "esp32c2"
|
- if: IDF_TARGET == "esp32c2"
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
idf_component_register(SRCS cmd_sdmmc.c
|
||||||
|
INCLUDE_DIRS .
|
||||||
|
PRIV_REQUIRES console sdmmc esp_driver_sdmmc esp_driver_gpio sdmmc_test_board
|
||||||
|
driver # driver will be replaced with esp_driver_sdspi later
|
||||||
|
)
|
@@ -11,8 +11,8 @@
|
|||||||
#include "esp_check.h"
|
#include "esp_check.h"
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#ifdef SOC_SDMMC_HOST_SUPPORTED
|
#ifdef SOC_SDMMC_HOST_SUPPORTED
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
@@ -3,7 +3,8 @@ idf_component_register(
|
|||||||
sdmmc_test_cd_wp_common.c
|
sdmmc_test_cd_wp_common.c
|
||||||
sdmmc_test_rw_common.c
|
sdmmc_test_rw_common.c
|
||||||
PRIV_REQUIRES
|
PRIV_REQUIRES
|
||||||
sdmmc sdmmc_test_board esp_timer unity test_utils
|
sdmmc esp_driver_sdmmc sdmmc_test_board esp_timer unity test_utils
|
||||||
|
driver # driver will be replaced with esp_driver_sdspi later
|
||||||
WHOLE_ARCHIVE TRUE
|
WHOLE_ARCHIVE TRUE
|
||||||
)
|
)
|
||||||
|
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
@@ -11,7 +11,7 @@
|
|||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "sdmmc_test_board.h"
|
#include "sdmmc_test_board.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "sdmmc_test_begin_end.h"
|
#include "sdmmc_test_begin_end.h"
|
||||||
#include "hal/gpio_hal.h"
|
#include "hal/gpio_hal.h"
|
@@ -11,7 +11,7 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "sdmmc_test_board.h"
|
#include "sdmmc_test_board.h"
|
||||||
#include "driver/sdspi_host.h"
|
#include "driver/sdspi_host.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "sdmmc_test_begin_end.h"
|
#include "sdmmc_test_begin_end.h"
|
||||||
|
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
@@ -12,7 +12,7 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "driver/sdmmc_defs.h"
|
#include "sd_protocol_defs.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "sdmmc_test_rw_common.h"
|
#include "sdmmc_test_rw_common.h"
|
||||||
|
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "driver/sdmmc_types.h"
|
#include "sd_protocol_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
Reference in New Issue
Block a user