Skip to content

Commit aebd207

Browse files
committed
feat:[driver][sdmmc]提升读写速度6倍
1 parent fb63fce commit aebd207

File tree

22 files changed

+920
-538
lines changed

22 files changed

+920
-538
lines changed

libraries/HAL_Drivers/drivers/drv_sdmmc.c

Lines changed: 75 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006-2023, RT-Thread Development Team
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -27,7 +27,6 @@
2727
#endif /* DRV_DEBUG */
2828
#include <rtdbg.h>
2929

30-
static struct stm32_sdio_class sdio_obj;
3130
static struct rt_mmcsd_host *host1;
3231
static struct rt_mmcsd_host *host2;
3332

@@ -55,6 +54,11 @@ struct rthw_sdio
5554
rt_align(SDIO_ALIGN_LEN)
5655
static rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
5756

57+
static rt_uint32_t stm32_sdio_clk_get(void)
58+
{
59+
return SDIO_CLOCK_FREQ;
60+
}
61+
5862
/**
5963
* @brief This function get order from sdio.
6064
* @param data
@@ -154,10 +158,6 @@ static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
154158
return;
155159
}
156160

157-
if (sdio->pkg == RT_NULL)
158-
{
159-
return;
160-
}
161161
/* Get Card Specific Data */
162162
cmd->resp[0] = hsd->RESP1;
163163
if (resp_type(cmd) == RESP_R2)
@@ -262,7 +262,7 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
262262
/* data pre configuration */
263263
if (data != RT_NULL)
264264
{
265-
SCB_CleanInvalidateDCache();
265+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cache_buf, data->blks * data->blksize);
266266

267267
reg_cmd |= SDMMC_CMD_CMDTRANS;
268268
__HAL_SD_DISABLE_IT(&sdio->sdio_des.hw_sdio, SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE);
@@ -288,14 +288,21 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
288288
/* Waiting for data to be sent to completion */
289289
if (data != RT_NULL)
290290
{
291-
volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
291+
uint32_t timer = rt_tick_get() + rt_tick_from_millisecond(10);
292292

293-
while (count && (hsd->STA & SDMMC_STA_DPSMACT))
293+
while (timer > rt_tick_get())
294294
{
295-
count--;
295+
if(hsd->STA & SDMMC_STA_DPSMACT)
296+
{
297+
continue;
298+
}
299+
else
300+
{
301+
break;
302+
}
296303
}
297304

298-
if ((count == 0) || (hsd->STA & SDIO_ERRORS))
305+
if (timer < rt_tick_get() || (hsd->STA & SDIO_ERRORS))
299306
{
300307
cmd->err = -RT_ERROR;
301308
}
@@ -307,7 +314,7 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
307314
if (data->flags & DATA_DIR_READ)
308315
{
309316
rt_memcpy(data->buf, cache_buf, data->blks * data->blksize);
310-
SCB_CleanInvalidateDCache();
317+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, cache_buf, data->blks * data->blksize);
311318
}
312319
}
313320
}
@@ -374,6 +381,33 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *
374381
SDMMC_InitTypeDef Init = {0};
375382
rt_uint32_t sdmmc_clk = sdio->sdio_des.clk_get();
376383

384+
rt_bool_t stop_flag = RT_TRUE;
385+
386+
switch (io_cfg->power_mode & 0X03)
387+
{
388+
case MMCSD_POWER_OFF:
389+
/* Set Power State to OFF */
390+
(void)SDMMC_PowerState_OFF(hsd->Instance);
391+
stop_flag = RT_TRUE;
392+
break;
393+
case MMCSD_POWER_UP:
394+
/* In F4 series chips, 0X01 is reserved bit and has no practical effect.
395+
For F7 series chips, 0X01 is power-on after power-off,The SDMMC disables the function and the card clock stops.
396+
For H7 series chips, 0X03 is the power-on function.
397+
*/
398+
stop_flag = RT_TRUE;
399+
break;
400+
case MMCSD_POWER_ON:
401+
stop_flag = RT_FALSE;
402+
break;
403+
default:
404+
LOG_W("unknown power mode %d", io_cfg->power_mode);
405+
stop_flag = RT_FALSE;
406+
break;
407+
}
408+
409+
if(stop_flag == RT_TRUE) return;
410+
377411
if (sdmmc_clk < 400 * 1000)
378412
{
379413
LOG_E("The clock rate is too low! rata:%d", sdmmc_clk);
@@ -418,62 +452,37 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *
418452
Init.BusWide = SDMMC_BUS_WIDE_1B;
419453
}
420454
Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
421-
/* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */
422-
if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ)))
423-
{
424-
Init.ClockDiv = hsd->Init.ClockDiv;
425-
}
426-
//CARD_ULTRA_HIGH_SPEED :UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards and <104Mo/s for SDR104, Spec version 3.01
427-
else if (MMCSD_TIMING_UHS_SDR50 <= io_cfg->timing && io_cfg->timing <= MMCSD_TIMING_UHS_DDR50)
455+
if(clk != SD_INIT_FREQ)
428456
{
429-
/* UltraHigh speed SD card,user Clock div */
430-
Init.ClockDiv = hsd->Init.ClockDiv;
431-
}
432-
//CARD_HIGH_SPEED: High Speed Card <25Mo/s , Spec version 2.00
433-
else if (io_cfg->timing == MMCSD_TIMING_SD_HS)
434-
{
435-
/* High speed SD card, Max Frequency = 50Mhz */
436-
if (hsd->Init.ClockDiv == 0U)
457+
/* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */
458+
if (hsd->Init.ClockDiv <= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ)))
437459
{
438-
if (sdmmc_clk > SD_HIGH_SPEED_FREQ)
439-
{
440-
Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ);
441-
}
442-
else
443-
{
444-
Init.ClockDiv = hsd->Init.ClockDiv;
445-
}
460+
Init.ClockDiv = hsd->Init.ClockDiv;
446461
}
447-
else
462+
/*CARD_ULTRA_HIGH_SPEED :UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards and <104Mo/s for SDR104, Spec version 3.01*/
463+
else if (MMCSD_TIMING_UHS_SDR50 <= io_cfg->timing && io_cfg->timing <= MMCSD_TIMING_UHS_DDR50)
448464
{
449-
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ)
450-
{
451-
Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ);
452-
}
453-
else
454-
{
455-
Init.ClockDiv = hsd->Init.ClockDiv;
456-
}
465+
/* UltraHigh speed SD card,user Clock div */
466+
Init.ClockDiv = hsd->Init.ClockDiv;
457467
}
458-
}
459-
//CARD_NORMAL_SPEED: Normal Speed Card <12.5Mo/s , Spec Version 1.01
460-
else if (io_cfg->timing == MMCSD_TIMING_LEGACY)
461-
{
462-
/* No High speed SD card, Max Frequency = 25Mhz */
463-
if (hsd->Init.ClockDiv == 0U)
468+
/*CARD_HIGH_SPEED: High Speed Card <25Mo/s , Spec version 2.00*/
469+
else if (io_cfg->timing == MMCSD_TIMING_SD_HS)
464470
{
465-
if (sdmmc_clk > SD_NORMAL_SPEED_FREQ)
471+
/* High speed SD card, Max Frequency = 50Mhz */
472+
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) < SD_HIGH_SPEED_FREQ)
466473
{
467-
Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ);
474+
Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ);
468475
}
469476
else
470477
{
471478
Init.ClockDiv = hsd->Init.ClockDiv;
472479
}
473480
}
474-
else
481+
/*CARD_NORMAL_SPEED: Normal Speed Card <12.5Mo/s , Spec Version 1.01*/
482+
else if (io_cfg->timing == MMCSD_TIMING_LEGACY)
475483
{
476-
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ)
484+
/* No High speed SD card, Max Frequency = 25Mhz */
485+
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) < SD_NORMAL_SPEED_FREQ)
477486
{
478487
Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ);
479488
}
@@ -483,26 +492,16 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *
483492
}
484493
}
485494
}
495+
else
496+
{
497+
Init.ClockDiv = hsd->Init.ClockDiv;
498+
}
486499
(void)SDMMC_Init(hsd->Instance, Init);
487500
}
488-
switch ((io_cfg->power_mode)&0X03)
501+
if((io_cfg->power_mode & 0X03) == MMCSD_POWER_ON)
489502
{
490-
case MMCSD_POWER_OFF:
491-
/* Set Power State to OFF */
492-
(void)SDMMC_PowerState_OFF(hsd->Instance);
493-
break;
494-
case MMCSD_POWER_UP:
495-
/* In F4 series chips, 0X01 is reserved bit and has no practical effect.
496-
For F7 series chips, 0X01 is power-on after power-off,The SDMMC disables the function and the card clock stops.
497-
For H7 series chips, 0X03 is the power-on function.
498-
*/
499-
case MMCSD_POWER_ON:
500503
/* Set Power State to ON */
501504
(void)SDMMC_PowerState_ON(hsd->Instance);
502-
break;
503-
default:
504-
LOG_W("unknown power mode %d", io_cfg->power_mode);
505-
break;
506505
}
507506
}
508507

@@ -574,15 +573,15 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
574573

575574
if (sdio_des == RT_NULL)
576575
{
577-
LOG_E("L:%d F:%s",(sdio_des == RT_NULL ? "sdio_des is NULL" : ""));
576+
LOG_E("sdio_des is NULL");
578577
return RT_NULL;
579578
}
580579

581580
sdio = rt_malloc(sizeof(struct rthw_sdio));
582581

583582
if (sdio == RT_NULL)
584583
{
585-
LOG_E("L:%d F:%s malloc rthw_sdio fail");
584+
LOG_E("malloc rthw_sdio fail");
586585
return RT_NULL;
587586
}
588587

@@ -592,12 +591,13 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
592591

593592
if (host == RT_NULL)
594593
{
595-
LOG_E("L:%d F:%s mmcsd alloc host fail");
594+
LOG_E("mmcsd alloc host fail");
596595
rt_free(sdio);
597596
return RT_NULL;
598597
}
599598

600599
rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des));
600+
sdio->sdio_des.clk_get = (sdio_des->clk_get == RT_NULL ? stm32_sdio_clk_get : sdio_des->clk_get);
601601
#ifdef BSP_USING_SDIO1
602602
if(sdio_des->hw_sdio.Instance == SDMMC1)
603603
{
@@ -626,14 +626,14 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
626626
#endif
627627
host->max_seg_size = SDIO_BUFF_SIZE;
628628
host->max_dma_segs = 1;
629-
host->max_blk_size = 512;
630-
host->max_blk_count = 512;
629+
host->max_blk_size = BLOCKSIZE;
630+
host->max_blk_count = BLOCKSIZE;
631631

632632
/* link up host and sdio */
633633
sdio->host = host;
634634
host->private_data = sdio;
635635

636-
rthw_sdio_irq_update(host, 1);
636+
rthw_sdio_irq_update(host, RT_TRUE);
637637

638638
/* ready to change */
639639
mmcsd_change(host);

libraries/HAL_Drivers/drivers/drv_sdmmc.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006-2023, RT-Thread Development Team
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -21,9 +21,6 @@
2121
#include <drivers/mmcsd_core.h>
2222
#include <drivers/sdio.h>
2323

24-
#define SDIO_BUFF_SIZE 4096
25-
#define SDIO_ALIGN_LEN 32
26-
2724
#define SDIO1_BASE_ADDRESS (SDMMC1_BASE)
2825
#define SDIO2_BASE_ADDRESS (SDMMC2_BASE)
2926

@@ -39,15 +36,15 @@
3936
#define SDIO_ALIGN_LEN (32)
4037
#endif
4138

42-
#ifndef SDIO_MAX_FREQ
43-
#define SDIO_MAX_FREQ (25 * 1000 * 1000)
44-
#endif
45-
4639
/* Frequencies used in the driver for clock divider calculation */
4740
#define SD_INIT_FREQ 400000U /* Initalization phase : 400 kHz max */
4841
#define SD_NORMAL_SPEED_FREQ 25000000U /* Normal speed phase : 25 MHz max */
4942
#define SD_HIGH_SPEED_FREQ 50000000U /* High speed phase : 50 MHz max */
5043

44+
#ifndef SDIO_MAX_FREQ
45+
#define SDIO_MAX_FREQ (SD_HIGH_SPEED_FREQ)
46+
#endif
47+
5148
#define SDIO_ERRORS \
5249
(SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
5350
SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \

0 commit comments

Comments
 (0)