Skip to content

Commit 77ae280

Browse files
committed
refactor(sd): port legacy sd driver with NG driver
1 parent 402bf0c commit 77ae280

File tree

12 files changed

+328
-1844
lines changed

12 files changed

+328
-1844
lines changed

components/esp_driver_sdmmc/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ idf_build_get_property(target IDF_TARGET)
22

33
set(srcs)
44

5-
set(public_include "include")
5+
set(public_include "include" "legacy/include")
66

77
# SDMMC related source files
88
if(CONFIG_SOC_SDMMC_HOST_SUPPORTED)
9-
list(APPEND srcs "src/sdmmc_transaction.c"
10-
"src/sdmmc_host.c")
9+
list(APPEND srcs "legacy/src/sdmmc_transaction.c"
10+
"legacy/src/sdmmc_host.c"
1111
"src/sd_host_sdmmc.c"
1212
"src/sd_trans_sdmmc.c")
1313
endif()

components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h renamed to components/esp_driver_sdmmc/legacy/include/driver/sdmmc_default_configs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern "C" {
4747
.get_real_freq = &sdmmc_host_get_real_freq, \
4848
.input_delay_phase = SDMMC_DELAY_PHASE_0, \
4949
.set_input_delay = &sdmmc_host_set_input_delay, \
50+
.set_input_delayline = &sdmmc_host_set_input_delayline, \
5051
.dma_aligned_buffer = NULL, \
5152
.pwr_ctrl_handle = NULL, \
5253
.get_dma_info = NULL, \

components/esp_driver_sdmmc/include/driver/sdmmc_host.h renamed to components/esp_driver_sdmmc/legacy/include/driver/sdmmc_host.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,23 @@ esp_err_t sdmmc_host_get_real_freq(int slot, int* real_freq_khz);
274274
*/
275275
esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase);
276276

277+
/**
278+
* @brief set input delayline
279+
*
280+
* - This API sets delay when the SDMMC Host samples the signal from the SD Slave.
281+
* - This API will check if the given `delay_line` is valid or not.
282+
* - This API will print out the delay time, in picosecond (ps)
283+
*
284+
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
285+
* @param delay_line delay line, this API will convert the line into picoseconds and print it out
286+
*
287+
* @return
288+
* - ESP_OK: ON success.
289+
* - ESP_ERR_INVALID_ARG: Invalid argument.
290+
* - ESP_ERR_NOT_SUPPORTED: Some chips don't support this feature.
291+
*/
292+
esp_err_t sdmmc_host_set_input_delayline(int slot, sdmmc_delay_line_t delay_line);
293+
277294
/**
278295
* @brief Get the DMA memory information for the host driver
279296
*
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdbool.h>
8+
#include <stddef.h>
9+
#include <string.h>
10+
#include <sys/param.h>
11+
#include "esp_log.h"
12+
#include "esp_check.h"
13+
#include "driver/sdmmc_host.h"
14+
#include "driver/sd_host_sdmmc.h"
15+
#include "driver/sd_host.h"
16+
#include "sdmmc_internal.h"
17+
18+
#define SLOT_CHECK(slot_num) \
19+
if (slot_num < 0 || slot_num >= SOC_SDMMC_NUM_SLOTS) { \
20+
return ESP_ERR_INVALID_ARG; \
21+
}
22+
23+
#define SDMMC_EVENT_QUEUE_LENGTH 32
24+
25+
static const char *TAG = "sdmmc_periph";
26+
static sd_host_ctlr_handle_t s_ctlr = NULL;
27+
static sd_host_slot_handle_t s_slot0 = NULL;
28+
static sd_host_slot_handle_t s_slot1 = NULL;
29+
30+
esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz)
31+
{
32+
SLOT_CHECK(slot);
33+
34+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
35+
sd_host_slot_cfg_t cfg = {
36+
.freq.freq_hz = freq_khz * 1000,
37+
.freq.override = true,
38+
};
39+
ESP_RETURN_ON_ERROR(sd_host_slot_configure(hdl, &cfg), TAG, "failed to configure slot freq");
40+
41+
return ESP_OK;
42+
}
43+
44+
esp_err_t sdmmc_host_get_real_freq(int slot, int *real_freq_khz)
45+
{
46+
SLOT_CHECK(slot);
47+
48+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
49+
sd_host_sdmmc_slot_t *slot_ctx = __containerof(hdl, sd_host_sdmmc_slot_t, drv);
50+
ESP_RETURN_ON_ERROR(sd_host_slot_get_calc_real_freq(slot_ctx, real_freq_khz), TAG, "failed to get slot freq");
51+
52+
return ESP_OK;
53+
}
54+
55+
esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase)
56+
{
57+
SLOT_CHECK(slot);
58+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
59+
sd_host_slot_cfg_t cfg = {
60+
.delay_phase.delayphase = delay_phase,
61+
.delay_phase.override = true,
62+
};
63+
ESP_RETURN_ON_ERROR(sd_host_slot_configure(hdl, &cfg), TAG, "failed to configure slot delay phase");
64+
65+
return ESP_OK;
66+
}
67+
68+
esp_err_t sdmmc_host_set_input_delayline(int slot, sdmmc_delay_line_t delay_line)
69+
{
70+
SLOT_CHECK(slot);
71+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
72+
sd_host_slot_cfg_t cfg = {
73+
.delay_line.delayline = delay_line,
74+
.delay_line.override = true,
75+
};
76+
ESP_RETURN_ON_ERROR(sd_host_slot_configure(hdl, &cfg), TAG, "failed to configure slot delay line");
77+
78+
return ESP_OK;
79+
}
80+
81+
esp_err_t sdmmc_host_init(void)
82+
{
83+
sd_host_sdmmc_cfg_t cfg = {
84+
.event_queue_items = SDMMC_EVENT_QUEUE_LENGTH,
85+
};
86+
esp_err_t ret = sd_host_create_sdmmc_controller(&cfg, &s_ctlr);
87+
ESP_RETURN_ON_ERROR(ret, TAG, "failed to create new SD controller");
88+
89+
return ESP_OK;
90+
}
91+
92+
sd_host_slot_handle_t sdmmc_get_slot_handle(int slot_id)
93+
{
94+
return slot_id == 0 ? s_slot0 : s_slot1;
95+
}
96+
97+
esp_err_t sdmmc_host_is_slot_set_to_uhs1(int slot, bool *is_uhs1)
98+
{
99+
SLOT_CHECK(slot);
100+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
101+
102+
sd_host_slot_info_t info = {};
103+
ESP_RETURN_ON_ERROR(sd_host_slot_get_info(hdl, &info), TAG, "failed to get slot info");
104+
if (info.sd_mode == SD_MODE_UHS1) {
105+
*is_uhs1 = true;
106+
}
107+
108+
return ESP_OK;
109+
}
110+
111+
esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
112+
{
113+
esp_err_t ret = ESP_FAIL;
114+
115+
bool internal_pullup = (slot_config->flags & SDMMC_SLOT_FLAG_INTERNAL_PULLUP);
116+
bool wp_active_high = (slot_config->flags & SDMMC_SLOT_FLAG_WP_ACTIVE_HIGH);
117+
sd_host_slot_sdmmc_init_cfg_t cfg = {
118+
.slot_id = slot,
119+
.sd_mode = (slot_config->flags & SDMMC_SLOT_FLAG_UHS1) ? SD_MODE_UHS1 : SD_MODE_NORMAL,
120+
.io_config = {
121+
.width = slot_config->width,
122+
.clk_io = slot_config->clk,
123+
.cmd_io = slot_config->cmd,
124+
.cd_io = slot_config->cd,
125+
.wp_io = slot_config->wp,
126+
.d0_io = slot_config->d0,
127+
.d1_io = slot_config->d1,
128+
.d2_io = slot_config->d2,
129+
.d3_io = slot_config->d3,
130+
.d4_io = slot_config->d4,
131+
.d5_io = slot_config->d5,
132+
.d6_io = slot_config->d6,
133+
.d7_io = slot_config->d7,
134+
},
135+
.slot_flags.internal_pullup = internal_pullup,
136+
.slot_flags.wp_active_high = wp_active_high,
137+
};
138+
if (slot == 0) {
139+
ret = sd_host_sdmmc_controller_add_slot(s_ctlr, &cfg, &s_slot0);
140+
} else {
141+
ret = sd_host_sdmmc_controller_add_slot(s_ctlr, &cfg, &s_slot1);
142+
}
143+
ESP_RETURN_ON_ERROR(ret, TAG, "failed to add new SD slot");
144+
145+
return ESP_OK;
146+
}
147+
148+
esp_err_t sdmmc_host_deinit_slot(int slot)
149+
{
150+
esp_err_t ret = ESP_FAIL;
151+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
152+
ESP_RETURN_ON_ERROR(sd_host_remove_slot(hdl), TAG, "failed to remove slot");
153+
154+
ret = sd_host_del_controller(s_ctlr);
155+
//for backward compatibility, return ESP_OK when only slot is removed and host is still there
156+
if (ret == ESP_ERR_INVALID_STATE) {
157+
ret = ESP_OK;
158+
}
159+
160+
return ret;
161+
}
162+
163+
esp_err_t sdmmc_host_deinit(void)
164+
{
165+
esp_err_t ret = ESP_FAIL;
166+
sd_host_slot_handle_t hdl[2] = {s_slot0, s_slot1};
167+
for (int i = 0; i < 2; i++) {
168+
if (hdl[i]) {
169+
ret = sd_host_remove_slot(hdl[i]);
170+
ESP_RETURN_ON_ERROR(ret, TAG, "failed to remove slot%d", i);
171+
}
172+
}
173+
ESP_RETURN_ON_ERROR(sd_host_del_controller(s_ctlr), TAG, "failed to delete controller");
174+
175+
return ESP_OK;
176+
}
177+
178+
esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
179+
{
180+
SLOT_CHECK(slot);
181+
182+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
183+
sd_host_slot_cfg_t cfg = {
184+
.width.override = true,
185+
};
186+
ESP_RETURN_ON_ERROR(sd_host_slot_configure(hdl, &cfg), TAG, "failed to configure slot bus width");
187+
188+
return ESP_OK;
189+
}
190+
191+
size_t sdmmc_host_get_slot_width(int slot)
192+
{
193+
SLOT_CHECK(slot);
194+
195+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
196+
sd_host_slot_info_t info = {};
197+
esp_err_t ret = sd_host_slot_get_info(hdl, &info);
198+
assert(ret == ESP_OK);
199+
200+
return info.width;
201+
}
202+
203+
esp_err_t sdmmc_host_set_bus_ddr_mode(int slot, bool ddr_enabled)
204+
{
205+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
206+
sd_host_slot_cfg_t cfg = {
207+
.sampling_mode.mode = ddr_enabled ? SD_SAMPLING_MODE_DDR : SD_SAMPLING_MODE_SDR,
208+
.sampling_mode.override = true,
209+
};
210+
ESP_RETURN_ON_ERROR(sd_host_slot_configure(hdl, &cfg), TAG, "failed to configure slot ddr mode");
211+
212+
return ESP_OK;
213+
}
214+
215+
esp_err_t sdmmc_host_set_cclk_always_on(int slot, bool cclk_always_on)
216+
{
217+
SLOT_CHECK(slot);
218+
219+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
220+
ESP_RETURN_ON_ERROR(sd_host_slot_set_cclk_always_on(hdl, cclk_always_on), TAG, "failed to configure slot cclk always on");
221+
222+
return ESP_OK;
223+
}
224+
225+
esp_err_t sdmmc_host_io_int_enable(int slot)
226+
{
227+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
228+
return sd_host_slot_enable_io_int(hdl);
229+
}
230+
231+
esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks)
232+
{
233+
assert(slot == 0 || slot == 1);
234+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
235+
ESP_RETURN_ON_ERROR(sd_host_slot_wait_io_int(hdl, timeout_ticks), TAG, "failed to wait io interrupt");
236+
237+
return ESP_OK;
238+
}
239+
240+
esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info)
241+
{
242+
SLOT_CHECK(slot);
243+
244+
if (dma_mem_info == NULL) {
245+
return ESP_ERR_INVALID_ARG;
246+
}
247+
dma_mem_info->extra_heap_caps = MALLOC_CAP_DMA;
248+
dma_mem_info->dma_alignment_bytes = 4;
249+
return ESP_OK;
250+
}
251+
252+
bool sdmmc_host_check_buffer_alignment(int slot, const void *buf, size_t size)
253+
{
254+
assert(slot == 0 || slot == 1);
255+
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
256+
sd_host_sdmmc_slot_t *slot_ctx = __containerof(hdl, sd_host_sdmmc_slot_t, drv);
257+
258+
return sd_host_check_buffer_alignment(slot_ctx, buf, size);
259+
}
260+
261+
esp_err_t sdmmc_host_get_state(sdmmc_host_state_t* state)
262+
{
263+
ESP_RETURN_ON_FALSE(state, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
264+
265+
if (s_ctlr) {
266+
state->host_initialized = true;
267+
sd_host_sdmmc_ctlr_t *ctlr_ctx = __containerof(s_ctlr, sd_host_sdmmc_ctlr_t, drv);
268+
state->num_of_init_slots = ctlr_ctx->registered_slot_nums;
269+
}
270+
271+
return ESP_OK;
272+
}
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -12,23 +12,13 @@
1212
#include "freertos/FreeRTOS.h"
1313
#include "freertos/queue.h"
1414
#include "soc/sdmmc_periph.h"
15-
16-
typedef struct {
17-
uint32_t sdmmc_status; ///< masked SDMMC interrupt status
18-
uint32_t dma_status; ///< masked DMA interrupt status
19-
} sdmmc_event_t;
20-
21-
#define SDMMC_HOST_CLOCK_UPDATE_CMD_TIMEOUT_US 1000 * 1000
22-
#define SDMMC_HOST_START_CMD_TIMEOUT_US 1000 * 1000
23-
#define SDMMC_HOST_RESET_TIMEOUT_US 5000 * 1000
15+
#include "esp_private/sd_host_private.h"
2416

2517
esp_err_t sdmmc_host_reset(void);
2618

2719
esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg);
2820

29-
esp_err_t sdmmc_host_wait_for_event(int tick_count, sdmmc_event_t* out_event);
30-
31-
void sdmmc_host_dma_prepare(void* data_ptr, size_t data_size, size_t block_size);
21+
esp_err_t sdmmc_host_wait_for_event(int tick_count, sd_host_sdmmc_event_t* out_event);
3222

3323
void sdmmc_host_dma_stop(void);
3424

@@ -41,3 +31,6 @@ void sdmmc_host_enable_clk_cmd11(int slot, bool enable);
4131
esp_err_t sdmmc_host_transaction_handler_init(void);
4232

4333
void sdmmc_host_transaction_handler_deinit(void);
34+
35+
//get slot handle, for legacy driver compatibility
36+
sd_host_slot_handle_t sdmmc_get_slot_handle(int slot_id);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <string.h>
8+
#include <unistd.h>
9+
#include "esp_err.h"
10+
#include "esp_log.h"
11+
#include "esp_check.h"
12+
#include "driver/sdmmc_types.h"
13+
#include "driver/sdmmc_defs.h"
14+
#include "driver/sdmmc_host.h"
15+
#include "driver/sd_host.h"
16+
#include "sdmmc_internal.h"
17+
18+
static const char* TAG = "sdmmc_req";
19+
20+
esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo)
21+
{
22+
sd_host_slot_handle_t slot_hdl = sdmmc_get_slot_handle(slot);
23+
esp_err_t ret = sd_host_slot_do_transaction(slot_hdl, cmdinfo);
24+
ESP_RETURN_ON_ERROR(ret, TAG, "failed to do SD transaction");
25+
26+
return ESP_OK;
27+
}

0 commit comments

Comments
 (0)