Skip to content

Commit 85bc5ac

Browse files
committed
Merge branch 'change/sdmmc_ll_layer' into 'master'
sdmmc: full ll layer Closes IDF-10544 and IDF-10251 See merge request espressif/esp-idf!33156
2 parents 3606d9e + a1da4f8 commit 85bc5ac

File tree

8 files changed

+1038
-140
lines changed

8 files changed

+1038
-140
lines changed

components/esp_driver_sdmmc/src/sdmmc_host.c

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "esp_timer.h"
1414
#include "esp_check.h"
1515
#include "soc/soc_caps.h"
16-
#include "soc/soc_pins.h"
1716
#include "soc/gpio_periph.h"
1817
#include "esp_rom_gpio.h"
1918
#include "esp_rom_sys.h"
@@ -28,6 +27,7 @@
2827
#include "soc/soc_caps.h"
2928
#include "hal/gpio_hal.h"
3029
#include "hal/sdmmc_hal.h"
30+
#include "hal/sd_types.h"
3131
#include "hal/sdmmc_ll.h"
3232

3333
#define SDMMC_EVENT_QUEUE_LENGTH 32
@@ -96,25 +96,35 @@ static host_ctx_t s_host_ctx = {0};
9696
#endif
9797

9898
static void sdmmc_isr(void *arg);
99-
static void sdmmc_host_dma_init(void);
10099
static esp_err_t sdmmc_host_pullup_en_internal(int slot, int width);
101100
static bool sdmmc_host_slot_initialized(int slot);
102101
#if SOC_SDMMC_NUM_SLOTS >= 2
103102
static void sdmmc_host_change_to_slot(int slot);
104103
#endif
105104

105+
static void s_module_reset(void)
106+
{
107+
// reset module
108+
sdmmc_ll_reset_controller(s_host_ctx.hal.dev);
109+
sdmmc_ll_reset_dma(s_host_ctx.hal.dev);
110+
sdmmc_ll_reset_fifo(s_host_ctx.hal.dev);
111+
}
112+
113+
static bool s_is_module_reset_done(void)
114+
{
115+
bool is_done = sdmmc_ll_is_controller_reset_done(s_host_ctx.hal.dev) && sdmmc_ll_is_dma_reset_done(s_host_ctx.hal.dev) && sdmmc_ll_is_fifo_reset_done(s_host_ctx.hal.dev);
116+
return is_done;
117+
}
118+
106119
esp_err_t sdmmc_host_reset(void)
107120
{
108-
// Set reset bits
109-
SDMMC.ctrl.controller_reset = 1;
110-
SDMMC.ctrl.dma_reset = 1;
111-
SDMMC.ctrl.fifo_reset = 1;
121+
s_module_reset();
112122

113123
// Wait for the reset bits to be cleared by hardware
114124
int64_t yield_delay_us = 100 * 1000; // initially 100ms
115125
int64_t t0 = esp_timer_get_time();
116126
int64_t t1 = 0;
117-
while (SDMMC.ctrl.controller_reset || SDMMC.ctrl.fifo_reset || SDMMC.ctrl.dma_reset) {
127+
while (!s_is_module_reset_done()) {
118128
t1 = esp_timer_get_time();
119129
if (t1 - t0 > SDMMC_HOST_RESET_TIMEOUT_US) {
120130
return ESP_ERR_TIMEOUT;
@@ -187,14 +197,14 @@ static esp_err_t sdmmc_host_clock_update_command(int slot)
187197
}
188198
// Sending clock update command to the CIU can generate HLE error.
189199
// According to the manual, this is okay and we must retry the command.
190-
if (SDMMC.rintsts.hle) {
191-
SDMMC.rintsts.hle = 1;
200+
if (sdmmc_ll_get_interrupt_raw(s_host_ctx.hal.dev) & SDMMC_LL_EVENT_HLE) {
201+
sdmmc_ll_clear_interrupt(s_host_ctx.hal.dev, SDMMC_LL_EVENT_HLE);
192202
repeat = true;
193203
break;
194204
}
195205
// When the command is accepted by CIU, start_command bit will be
196206
// cleared in SDMMC.cmd register.
197-
if (SDMMC.cmd.start_command == 0) {
207+
if (sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
198208
repeat = false;
199209
break;
200210
}
@@ -413,7 +423,7 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
413423
int64_t yield_delay_us = 100 * 1000; // initially 100ms
414424
int64_t t0 = esp_timer_get_time();
415425
int64_t t1 = 0;
416-
while (SDMMC.cmd.start_command == 1) {
426+
while (!sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
417427
t1 = esp_timer_get_time();
418428
if (t1 - t0 > SDMMC_HOST_START_CMD_TIMEOUT_US) {
419429
return ESP_ERR_TIMEOUT;
@@ -423,10 +433,10 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
423433
vTaskDelay(1);
424434
}
425435
}
426-
SDMMC.cmdarg = arg;
436+
sdmmc_ll_set_command_arg(s_host_ctx.hal.dev, arg);
427437
cmd.card_num = slot;
428438
cmd.start_command = 1;
429-
SDMMC.cmd = cmd;
439+
sdmmc_ll_set_command(s_host_ctx.hal.dev, cmd);
430440
return ESP_OK;
431441
}
432442

@@ -440,7 +450,7 @@ static void sdmmc_host_intmask_clear_disable(void)
440450
static void sdmmc_host_intmask_set_enable(void)
441451
{
442452
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, 0xffffffff, false);
443-
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, SDMMC_LL_INTMASK_DEFAULT, true);
453+
sdmmc_ll_enable_interrupt(s_host_ctx.hal.dev, SDMMC_LL_EVENT_DEFAULT, true);
444454
sdmmc_ll_enable_global_interrupt(s_host_ctx.hal.dev, true);
445455
}
446456

@@ -470,7 +480,7 @@ esp_err_t sdmmc_host_init(void)
470480
return err;
471481
}
472482

473-
ESP_LOGD(TAG, "peripheral version %"PRIx32", hardware config %08"PRIx32, SDMMC.verid, SDMMC.hcon.val);
483+
ESP_LOGD(TAG, "peripheral version %"PRIx32", hardware config %08"PRIx32, sdmmc_ll_get_version_id(s_host_ctx.hal.dev), sdmmc_ll_get_hw_config_info(s_host_ctx.hal.dev));
474484

475485
// Clear interrupt status and set interrupt mask to known state
476486
sdmmc_host_intmask_clear_disable();
@@ -499,10 +509,10 @@ esp_err_t sdmmc_host_init(void)
499509
sdmmc_host_intmask_set_enable();
500510

501511
// Disable generation of Busy Clear Interrupt
502-
SDMMC.cardthrctl.busy_clr_int_en = 0;
512+
sdmmc_ll_enable_busy_clear_interrupt(s_host_ctx.hal.dev, false);
503513

504-
// Enable DMA
505-
sdmmc_host_dma_init();
514+
// Init DMA
515+
sdmmc_ll_init_dma(s_host_ctx.hal.dev);
506516

507517
// Initialize transaction handler
508518
ret = sdmmc_host_transaction_handler_init();
@@ -880,17 +890,14 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
880890
if (sdmmc_slot_info[slot].width < width) {
881891
return ESP_ERR_INVALID_ARG;
882892
}
883-
const uint16_t mask = BIT(slot);
884893
if (width == 1) {
885-
SDMMC.ctype.card_width_8 &= ~mask;
886-
SDMMC.ctype.card_width &= ~mask;
894+
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_1_BIT);
887895
} else if (width == 4) {
888-
SDMMC.ctype.card_width_8 &= ~mask;
889-
SDMMC.ctype.card_width |= mask;
896+
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_4_BIT);
890897
// D3 was set to GPIO high to force slave into SD mode, until 4-bit mode is set
891898
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3, sdmmc_slot_gpio_sig[slot].d3, GPIO_MODE_INPUT_OUTPUT, "d3", s_host_ctx.slot_ctx[slot].use_gpio_matrix);
892899
} else if (width == 8) {
893-
SDMMC.ctype.card_width_8 |= mask;
900+
sdmmc_ll_set_card_width(s_host_ctx.hal.dev, slot, SD_BUS_WIDTH_8_BIT);
894901
// D3 was set to GPIO high to force slave into SD mode, until 4-bit mode is set
895902
configure_pin(s_host_ctx.slot_ctx[slot].slot_gpio_num.d3, sdmmc_slot_gpio_sig[slot].d3, GPIO_MODE_INPUT_OUTPUT, "d3", s_host_ctx.slot_ctx[slot].use_gpio_matrix);
896903
} else {
@@ -935,22 +942,9 @@ esp_err_t sdmmc_host_set_cclk_always_on(int slot, bool cclk_always_on)
935942
return ESP_OK;
936943
}
937944

938-
static void sdmmc_host_dma_init(void)
939-
{
940-
SDMMC.ctrl.dma_enable = 1;
941-
SDMMC.bmod.val = 0;
942-
SDMMC.bmod.sw_reset = 1;
943-
SDMMC.idinten.ni = 1;
944-
SDMMC.idinten.ri = 1;
945-
SDMMC.idinten.ti = 1;
946-
}
947-
948945
void sdmmc_host_dma_stop(void)
949946
{
950-
SDMMC.ctrl.use_internal_dma = 0;
951-
SDMMC.ctrl.dma_reset = 1;
952-
SDMMC.bmod.fb = 0;
953-
SDMMC.bmod.enable = 0;
947+
sdmmc_ll_stop_dma(s_host_ctx.hal.dev);
954948
}
955949

956950
void sdmmc_host_dma_prepare(sdmmc_desc_t *desc, size_t block_size, size_t data_size)
@@ -972,7 +966,7 @@ void sdmmc_host_dma_resume(void)
972966

973967
bool sdmmc_host_card_busy(void)
974968
{
975-
return SDMMC.status.data_busy == 1;
969+
return sdmmc_ll_is_card_data_busy(s_host_ctx.hal.dev);
976970
}
977971

978972
esp_err_t sdmmc_host_io_int_enable(int slot)
@@ -1044,12 +1038,12 @@ static void sdmmc_isr(void *arg)
10441038
sdmmc_event_t event;
10451039
int higher_priority_task_awoken = pdFALSE;
10461040

1047-
uint32_t pending = sdmmc_ll_get_intr_status(s_host_ctx.hal.dev) & 0xFFFF;
1048-
SDMMC.rintsts.val = pending;
1041+
uint32_t pending = sdmmc_ll_get_intr_status(s_host_ctx.hal.dev) & SDMMC_LL_SD_EVENT_MASK;
1042+
sdmmc_ll_clear_interrupt(s_host_ctx.hal.dev, pending);
10491043
event.sdmmc_status = pending;
10501044

1051-
uint32_t dma_pending = SDMMC.idsts.val;
1052-
SDMMC.idsts.val = dma_pending;
1045+
uint32_t dma_pending = sdmmc_ll_get_idsts_interrupt_raw(s_host_ctx.hal.dev);
1046+
sdmmc_ll_clear_idsts_interrupt(s_host_ctx.hal.dev, dma_pending);
10531047
event.dma_status = dma_pending & 0x1f;
10541048

10551049
if (pending != 0 || dma_pending != 0) {

components/esp_driver_sdmmc/test_apps/sdmmc/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ set(COMPONENTS main)
66

77
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
88
project(sdmmc_test_console)
9+
10+
message(STATUS "Checking sdmmc registers are not read-write by half-word")
11+
include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake)
12+
check_register_rw_half_word(SOC_MODULES "sdmmc" "pcr" "hp_sys_clkrst"
13+
HAL_MODULES "sdmmc")

0 commit comments

Comments
 (0)