mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
Merge branch 'bugfix/sdspi_wp_cd_pins' into 'master'
sdmmc, sdspi: fix handling of CD and WP See merge request idf/esp-idf!2285
This commit is contained in:
@@ -43,9 +43,9 @@ extern "C" {
|
||||
.set_card_clk = &sdmmc_host_set_card_clk, \
|
||||
.do_transaction = &sdmmc_host_do_transaction, \
|
||||
.deinit = &sdmmc_host_deinit, \
|
||||
.command_timeout_ms = 0, \
|
||||
.io_int_enable = sdmmc_host_io_int_enable, \
|
||||
.io_int_wait = sdmmc_host_io_int_wait, \
|
||||
.command_timeout_ms = 0, \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -40,6 +40,7 @@ extern "C" {
|
||||
.io_voltage = 3.3f, \
|
||||
.init = &sdspi_host_init, \
|
||||
.set_bus_width = NULL, \
|
||||
.get_bus_width = NULL, \
|
||||
.set_card_clk = &sdspi_host_set_card_clk, \
|
||||
.do_transaction = &sdspi_host_do_transaction, \
|
||||
.deinit = &sdspi_host_deinit, \
|
||||
@@ -72,8 +73,8 @@ typedef struct {
|
||||
.gpio_mosi = GPIO_NUM_15, \
|
||||
.gpio_sck = GPIO_NUM_14, \
|
||||
.gpio_cs = GPIO_NUM_13, \
|
||||
.gpio_cd = SDMMC_SLOT_NO_CD, \
|
||||
.gpio_wp = SDMMC_SLOT_NO_WP, \
|
||||
.gpio_cd = SDSPI_SLOT_NO_CD, \
|
||||
.gpio_wp = SDSPI_SLOT_NO_WP, \
|
||||
.dma_channel = 1 \
|
||||
}
|
||||
|
||||
|
@@ -255,6 +255,12 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg) {
|
||||
if (!(slot == 0 || slot == 1)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if ((SDMMC.cdetect.cards & BIT(slot)) != 0) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
if (cmd.data_expected && cmd.rw && (SDMMC.wrtprt.cards & BIT(slot)) != 0) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
while (SDMMC.cmd.start_command == 1) {
|
||||
;
|
||||
}
|
||||
@@ -397,18 +403,36 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
|
||||
|
||||
// SDIO slave interrupt is edge sensitive to ~(int_n | card_int | card_detect)
|
||||
// set this and card_detect to high to enable sdio interrupt
|
||||
gpio_matrix_in(GPIO_FUNC_IN_HIGH, pslot->card_int, 0);
|
||||
if (gpio_cd != -1) {
|
||||
gpio_set_direction(gpio_cd, GPIO_MODE_INPUT);
|
||||
gpio_matrix_in(gpio_cd, pslot->card_detect, 0);
|
||||
} else {
|
||||
gpio_matrix_in(GPIO_FUNC_IN_HIGH, pslot->card_detect, 0);
|
||||
}
|
||||
gpio_matrix_in(GPIO_FUNC_IN_HIGH, pslot->card_int, false);
|
||||
|
||||
if (gpio_wp != -1) {
|
||||
gpio_set_direction(gpio_wp, GPIO_MODE_INPUT);
|
||||
gpio_matrix_in(gpio_wp, pslot->write_protect, 0);
|
||||
// Set up Card Detect input
|
||||
int matrix_in_cd;
|
||||
if (gpio_cd != SDMMC_SLOT_NO_CD) {
|
||||
ESP_LOGD(TAG, "using GPIO%d as CD pin", gpio_cd);
|
||||
gpio_pad_select_gpio(gpio_cd);
|
||||
gpio_set_direction(gpio_cd, GPIO_MODE_INPUT);
|
||||
matrix_in_cd = gpio_cd;
|
||||
} else {
|
||||
// if not set, default to CD low (card present)
|
||||
matrix_in_cd = GPIO_FUNC_IN_LOW;
|
||||
}
|
||||
gpio_matrix_in(matrix_in_cd, pslot->card_detect, false);
|
||||
|
||||
// Set up Write Protect input
|
||||
int matrix_in_wp;
|
||||
if (gpio_wp != SDMMC_SLOT_NO_WP) {
|
||||
ESP_LOGD(TAG, "using GPIO%d as WP pin", gpio_wp);
|
||||
gpio_pad_select_gpio(gpio_wp);
|
||||
gpio_set_direction(gpio_wp, GPIO_MODE_INPUT);
|
||||
matrix_in_wp = gpio_wp;
|
||||
} else {
|
||||
// if not set, default to WP high (not write protected)
|
||||
matrix_in_wp = GPIO_FUNC_IN_HIGH;
|
||||
}
|
||||
// WP signal is normally active low, but hardware expects
|
||||
// an active-high signal, so invert it in GPIO matrix
|
||||
gpio_matrix_in(matrix_in_wp, pslot->write_protect, true);
|
||||
|
||||
// By default, set probing frequency (400kHz) and 1-bit bus
|
||||
esp_err_t ret = sdmmc_host_set_card_clk(slot, 400);
|
||||
if (ret != ESP_OK) {
|
||||
|
@@ -112,6 +112,7 @@ void sdmmc_host_transaction_handler_deinit()
|
||||
|
||||
esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
|
||||
{
|
||||
esp_err_t ret;
|
||||
xSemaphoreTake(s_request_mutex, portMAX_DELAY);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
@@ -124,12 +125,14 @@ esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
|
||||
if (cmdinfo->datalen < 4 || cmdinfo->blklen % 4 != 0) {
|
||||
ESP_LOGD(TAG, "%s: invalid size: total=%d block=%d",
|
||||
__func__, cmdinfo->datalen, cmdinfo->blklen);
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
ret = ESP_ERR_INVALID_SIZE;
|
||||
goto out;
|
||||
}
|
||||
if ((intptr_t) cmdinfo->data % 4 != 0 ||
|
||||
!esp_ptr_dma_capable(cmdinfo->data)) {
|
||||
ESP_LOGD(TAG, "%s: buffer %p can not be used for DMA", __func__, cmdinfo->data);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto out;
|
||||
}
|
||||
// this clears "owned by IDMAC" bits
|
||||
memset(s_dma_desc, 0, sizeof(s_dma_desc));
|
||||
@@ -146,10 +149,9 @@ esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
|
||||
sdmmc_host_dma_prepare(&s_dma_desc[0], cmdinfo->blklen, cmdinfo->datalen);
|
||||
}
|
||||
// write command into hardware, this also sends the command to the card
|
||||
esp_err_t ret = sdmmc_host_start_command(slot, hw_cmd, cmdinfo->arg);
|
||||
ret = sdmmc_host_start_command(slot, hw_cmd, cmdinfo->arg);
|
||||
if (ret != ESP_OK) {
|
||||
xSemaphoreGive(s_request_mutex);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
// process events until transfer is complete
|
||||
cmdinfo->error = ESP_OK;
|
||||
@@ -161,6 +163,8 @@ esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
|
||||
}
|
||||
}
|
||||
s_is_app_cmd = (ret == ESP_OK && cmdinfo->opcode == MMC_APP_CMD);
|
||||
|
||||
out:
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
#endif
|
||||
|
@@ -310,22 +310,22 @@ esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config)
|
||||
// Configure CD and WP pins
|
||||
io_conf = (gpio_config_t) {
|
||||
.intr_type = GPIO_PIN_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pin_bit_mask = 0,
|
||||
.pull_up_en = true
|
||||
};
|
||||
if (slot_config->gpio_cd != SDSPI_SLOT_NO_CD) {
|
||||
io_conf.pin_bit_mask |= (1 << slot_config->gpio_cd);
|
||||
s_slots[slot].gpio_wp = slot_config->gpio_wp;
|
||||
s_slots[slot].gpio_cd = slot_config->gpio_cd;
|
||||
} else {
|
||||
s_slots[slot].gpio_wp = GPIO_UNUSED;
|
||||
s_slots[slot].gpio_cd = GPIO_UNUSED;
|
||||
}
|
||||
|
||||
if (slot_config->gpio_wp != SDSPI_SLOT_NO_WP) {
|
||||
io_conf.pin_bit_mask |= (1 << slot_config->gpio_wp);
|
||||
s_slots[slot].gpio_cd = slot_config->gpio_cd;
|
||||
s_slots[slot].gpio_wp = slot_config->gpio_wp;
|
||||
} else {
|
||||
s_slots[slot].gpio_cd = GPIO_UNUSED;
|
||||
s_slots[slot].gpio_wp = GPIO_UNUSED;
|
||||
}
|
||||
|
||||
if (io_conf.pin_bit_mask != 0) {
|
||||
|
20
components/driver/test/test_sdmmc_sdspi_init.cpp
Normal file
20
components/driver/test/test_sdmmc_sdspi_init.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "driver/sdspi_host.h"
|
||||
|
||||
|
||||
/**
|
||||
* Check that C-style designated initializers are valid in C++ file.
|
||||
*/
|
||||
static void test_initializers() __attribute__((unused));
|
||||
|
||||
static void test_initializers()
|
||||
{
|
||||
sdmmc_host_t sdmmc_host = SDMMC_HOST_DEFAULT();
|
||||
(void) sdmmc_host;
|
||||
sdmmc_slot_config_t sdmmc_slot = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
(void) sdmmc_slot;
|
||||
sdmmc_host_t sdspi_host = SDSPI_HOST_DEFAULT();
|
||||
(void) sdspi_host;
|
||||
sdspi_slot_config_t sdspi_slot = SDSPI_SLOT_CONFIG_DEFAULT();
|
||||
(void) sdspi_slot;
|
||||
}
|
Reference in New Issue
Block a user