From e8bc0e2903eb677e4abcf0a518efde9fb4281f01 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Mon, 5 Aug 2024 23:55:31 +0800 Subject: [PATCH 1/5] [src]add __rt_fls --- .../drivers/include/drivers/mmcsd_core.h | 46 +------------------ include/rtthread.h | 1 + src/kservice.c | 44 ++++++++++++++++++ 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/components/drivers/include/drivers/mmcsd_core.h b/components/drivers/include/drivers/mmcsd_core.h index 3a6ac13aa9f..9f339851b1a 100644 --- a/components/drivers/include/drivers/mmcsd_core.h +++ b/components/drivers/include/drivers/mmcsd_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -173,50 +173,6 @@ struct rt_mmcsd_req #define R5_STATUS(x) (x & 0xCB00) #define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) - - -/** - * fls - find last (most-significant) bit set - * @x: the word to search - * - * This is defined the same way as ffs. - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ - -rt_inline rt_uint32_t __rt_fls(rt_uint32_t val) -{ - rt_uint32_t bit = 32; - - if (!val) - return 0; - if (!(val & 0xffff0000u)) - { - val <<= 16; - bit -= 16; - } - if (!(val & 0xff000000u)) - { - val <<= 8; - bit -= 8; - } - if (!(val & 0xf0000000u)) - { - val <<= 4; - bit -= 4; - } - if (!(val & 0xc0000000u)) - { - val <<= 2; - bit -= 2; - } - if (!(val & 0x80000000u)) - { - bit -= 1; - } - - return bit; -} - #define MMCSD_HOST_PLUGED 0 #define MMCSD_HOST_UNPLUGED 1 diff --git a/include/rtthread.h b/include/rtthread.h index dc33a6c8352..370a5822ed1 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -786,6 +786,7 @@ rt_device_t rt_console_get_device(void); #endif /* RT_USING_THREADSAFE_PRINTF */ #endif /* defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) */ +int __rt_fls(int val); int __rt_ffs(int value); void rt_show_version(void); diff --git a/src/kservice.c b/src/kservice.c index 915850e89dc..29fc43e12c9 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -1025,6 +1025,50 @@ rt_weak void rt_free_align(void *ptr) RTM_EXPORT(rt_free_align); #endif /* RT_USING_HEAP */ +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ + +int __rt_fls(int val) +{ + int bit = 32; + + if (!val) + { + return 0; + } + if (!(val & 0xffff0000u)) + { + val <<= 16; + bit -= 16; + } + if (!(val & 0xff000000u)) + { + val <<= 8; + bit -= 8; + } + if (!(val & 0xf0000000u)) + { + val <<= 4; + bit -= 4; + } + if (!(val & 0xc0000000u)) + { + val <<= 2; + bit -= 2; + } + if (!(val & 0x80000000u)) + { + bit -= 1; + } + + return bit; +} + #ifndef RT_USING_CPU_FFS #ifdef RT_USING_TINY_FFS const rt_uint8_t __lowest_bit_bitmap[] = From 5baa893d0562c5d40b3219c50d0f8f8615b39a6d Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Mon, 5 Aug 2024 23:56:29 +0800 Subject: [PATCH 2/5] [libcpu][cortex-m7]Canonical alignment --- libcpu/arm/cortex-m7/cpu_cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcpu/arm/cortex-m7/cpu_cache.c b/libcpu/arm/cortex-m7/cpu_cache.c index 6ec4c826d5c..55ed9ffdaf1 100644 --- a/libcpu/arm/cortex-m7/cpu_cache.c +++ b/libcpu/arm/cortex-m7/cpu_cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -36,7 +36,7 @@ rt_base_t rt_hw_cpu_icache_status(void) void rt_hw_cpu_icache_ops(int ops, void* addr, int size) { - rt_uint32_t address = (rt_uint32_t)addr & (rt_uint32_t) ~(L1CACHE_LINESIZE_BYTE - 1); + rt_uint32_t address = RT_ALIGN_DOWN((rt_uint32_t)addr, L1CACHE_LINESIZE_BYTE); rt_int32_t size_byte = size + address - (rt_uint32_t)addr; rt_uint32_t linesize = 32U; if (ops & RT_HW_CACHE_INVALIDATE) @@ -70,7 +70,7 @@ rt_base_t rt_hw_cpu_dcache_status(void) void rt_hw_cpu_dcache_ops(int ops, void* addr, int size) { - rt_uint32_t startAddr = (rt_uint32_t)addr & (rt_uint32_t)~(L1CACHE_LINESIZE_BYTE - 1); + rt_uint32_t startAddr = RT_ALIGN_DOWN((rt_uint32_t)addr, L1CACHE_LINESIZE_BYTE); rt_uint32_t size_byte = size + (rt_uint32_t)addr - startAddr; rt_uint32_t clean_invalid = RT_HW_CACHE_FLUSH | RT_HW_CACHE_INVALIDATE; From f422fc458ccb766fbb42792fa5f0fa269a65d398 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Mon, 5 Aug 2024 23:57:18 +0800 Subject: [PATCH 3/5] [drivers][sdio]Resolves cid,csd,scr, add CSD Version 3.0 support * add SD Specifications Physical Layer Specification Version 9.10 --- .../drivers/include/drivers/mmcsd_card.h | 28 +++- .../drivers/include/drivers/mmcsd_cmd.h | 4 +- .../drivers/include/drivers/mmcsd_host.h | 2 +- components/drivers/sdio/block_dev.c | 2 +- components/drivers/sdio/gpt.c | 5 +- components/drivers/sdio/mmc.c | 12 +- components/drivers/sdio/mmcsd_core.c | 10 +- components/drivers/sdio/sd.c | 138 +++++++++++++++--- components/drivers/sdio/sdio.c | 8 +- 9 files changed, 162 insertions(+), 47 deletions(-) diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h index 13173f1413d..4f6a29aa1d8 100644 --- a/components/drivers/include/drivers/mmcsd_card.h +++ b/components/drivers/include/drivers/mmcsd_card.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,6 +8,7 @@ * 2011-07-25 weety first version * 2024-05-24 HPMicro add HS400 support * 2024-05-26 HPMicro add UHS-I support for SD card + * 2024-08-05 wdfk-prog add SD Specifications Physical Layer Specification Version 9.10 */ #ifndef __MMCSD_CARD_H__ @@ -25,7 +26,7 @@ extern "C" { struct rt_mmcsd_cid { rt_uint8_t mid; /* ManufacturerID */ rt_uint8_t prv; /* Product Revision */ - rt_uint16_t oid; /* OEM/Application ID */ + rt_uint8_t oid[2]; /* OEM/Application ID */ rt_uint32_t psn; /* Product Serial Number */ rt_uint8_t pnm[5]; /* Product Name */ rt_uint8_t reserved1;/* reserved */ @@ -91,8 +92,22 @@ struct rt_sdio_cccr { union rt_sd_status { rt_uint32_t status_words[16]; struct { - rt_uint32_t reserved[12]; - rt_uint64_t : 8; + rt_uint8_t reserved[39]; + + rt_uint64_t fule_support: 1; + rt_uint64_t discard_support: 1; + rt_uint64_t boot_partition_support: 1; + rt_uint64_t wp_upc_support: 1; + rt_uint64_t : 12; + rt_uint64_t performance_enhance : 8; + rt_uint64_t app_perf_class : 4; + rt_uint64_t : 6; + rt_uint64_t sus_addr : 20; + + rt_uint16_t vsc_au_size : 10; + rt_uint16_t : 6; + + rt_uint64_t vsc_speed_class : 8; rt_uint64_t uhs_au_size: 4; rt_uint64_t uhs_speed_grade: 4; rt_uint64_t erase_offset: 2; @@ -106,7 +121,8 @@ union rt_sd_status { rt_uint32_t size_of_protected_area; rt_uint32_t sd_card_type: 16; - rt_uint32_t : 6; + rt_uint32_t secure_cmd_status : 3; + rt_uint32_t : 3; rt_uint32_t : 7; rt_uint32_t secured_mode: 1; rt_uint32_t data_bus_width: 2; @@ -204,6 +220,7 @@ struct rt_mmcsd_card { #define CARD_FLAG_HIGHSPEED (1 << 0) /* SDIO bus speed 50MHz */ #define CARD_FLAG_SDHC (1 << 1) /* SDHC card */ #define CARD_FLAG_SDXC (1 << 2) /* SDXC card */ +#define CARD_FLAG_SDUC (1 << 9) /* SD Ultra Capacity */ #define CARD_FLAG_HIGHSPEED_DDR (1 << 3) /* HIGH SPEED DDR */ #define CARD_FLAG_HS200 (1 << 4) /* BUS SPEED 200MHz */ #define CARD_FLAG_HS400 (1 << 5) /* BUS SPEED 400MHz */ @@ -212,6 +229,7 @@ struct rt_mmcsd_card { #define CARD_FLAG_DDR50 (1 << 8) /* DDR50, works on 1.8V only */ struct rt_sd_scr scr; struct rt_mmcsd_csd csd; + union rt_sd_status sd_status; rt_uint32_t hs_max_data_rate; /* max data transfer rate in high speed mode */ rt_uint8_t sdio_function_num; /* total number of SDIO functions */ diff --git a/components/drivers/include/drivers/mmcsd_cmd.h b/components/drivers/include/drivers/mmcsd_cmd.h index 06212c5162a..00d2eeb4fc6 100644 --- a/components/drivers/include/drivers/mmcsd_cmd.h +++ b/components/drivers/include/drivers/mmcsd_cmd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -16,6 +16,7 @@ extern "C" { #endif +/* MMC commands type argument response */ /* class 1 */ #define GO_IDLE_STATE 0 /* bc */ #define SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ @@ -83,6 +84,7 @@ extern "C" { /* Application commands */ #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ +#define SD_APP_SD_STATUS 13 /* adtc R1 */ #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ #define SD_APP_SEND_SCR 51 /* adtc R1 */ diff --git a/components/drivers/include/drivers/mmcsd_host.h b/components/drivers/include/drivers/mmcsd_host.h index 73c1b971d81..59ae2285ac3 100644 --- a/components/drivers/include/drivers/mmcsd_host.h +++ b/components/drivers/include/drivers/mmcsd_host.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index fcef99f1701..ac108c7aa9e 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/components/drivers/sdio/gpt.c b/components/drivers/sdio/gpt.c index 53b686e9f61..0ef6e48338e 100644 --- a/components/drivers/sdio/gpt.c +++ b/components/drivers/sdio/gpt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -251,7 +251,8 @@ static int is_gpt_valid(struct rt_mmcsd_card *card, size_t lba, gpt_header **gpt goto fail; } /* Check that sizeof_partition_entry has the correct value */ - if ((uint32_t)((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { + if ((uint32_t)((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) + { LOG_E("GUID Partition Entry Size check failed."); goto fail; } diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c index 3723d9db768..f329c014876 100644 --- a/components/drivers/sdio/mmc.c +++ b/components/drivers/sdio/mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -461,7 +461,7 @@ rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host, err = -RT_ETIMEOUT; - rt_thread_mdelay(10); //delay 10ms + rt_thread_mdelay(10); /*delay 10ms*/ } if (rocr && !controller_is_spi(host)) @@ -586,23 +586,23 @@ static int mmc_select_timing(struct rt_mmcsd_card *card) if (card->flags & CARD_FLAG_HS400) { - LOG_I("emmc: switch to HS400 mode\n"); + LOG_I("emmc: switch to HS400 mode"); ret = mmc_select_hs400(card); } else if (card->flags & CARD_FLAG_HS200) { - LOG_I("emmc: switch to HS200 mode\n"); + LOG_I("emmc: switch to HS200 mode"); ret = mmc_select_hs200(card); } else if (card->flags & CARD_FLAG_HIGHSPEED_DDR) { - LOG_I("emmc: switch to HIGH Speed DDR mode\n"); + LOG_I("emmc: switch to HIGH Speed DDR mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_DDR52); mmcsd_set_clock(card->host, card->hs_max_data_rate); } else { - LOG_I("emmc: switch to HIGH Speed mode\n"); + LOG_I("emmc: switch to HIGH Speed mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_HS); mmcsd_set_clock(card->host, card->hs_max_data_rate); } diff --git a/components/drivers/sdio/mmcsd_core.c b/components/drivers/sdio/mmcsd_core.c index 77570268c19..13727c7a4cc 100644 --- a/components/drivers/sdio/mmcsd_core.c +++ b/components/drivers/sdio/mmcsd_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -34,7 +34,6 @@ #endif #endif -//static struct rt_semaphore mmcsd_sem; static struct rt_thread mmcsd_detect_thread; static rt_uint8_t mmcsd_stack[RT_MMCSD_STACK_SIZE]; static struct rt_mailbox mmcsd_detect_mb; @@ -109,7 +108,7 @@ rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host) rt_int32_t err; struct rt_mmcsd_cmd cmd; - if (!controller_is_spi(host)) + if (controller_is_spi(host)) { mmcsd_set_chip_select(host, MMCSD_CS_HIGH); rt_thread_mdelay(1); @@ -125,7 +124,7 @@ rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host) rt_thread_mdelay(1); - if (!controller_is_spi(host)) + if (controller_is_spi(host)) { mmcsd_set_chip_select(host, MMCSD_CS_IGNORE); rt_thread_mdelay(1); @@ -755,7 +754,6 @@ int rt_mmcsd_core_init(void) { rt_err_t ret; - /* initialize detect SD cart thread */ /* initialize mailbox and create detect SD card thread */ ret = rt_mb_init(&mmcsd_detect_mb, "mmcsdmb", &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool) / sizeof(mmcsd_detect_mb_pool[0]), @@ -773,8 +771,6 @@ int rt_mmcsd_core_init(void) rt_thread_startup(&mmcsd_detect_thread); } - rt_sdio_init(); - return 0; } INIT_PREV_EXPORT(rt_mmcsd_core_init); diff --git a/components/drivers/sdio/sd.c b/components/drivers/sdio/sd.c index 6e826d5af57..3aefcb8d478 100644 --- a/components/drivers/sdio/sd.c +++ b/components/drivers/sdio/sd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,6 +7,7 @@ * Date Author Notes * 2011-07-25 weety first version * 2024-05-26 HPMicro add UHS-I support + * 2024-08-05 wdfk-prog Resolves cid,csd,scr, add CSD Version 3.0 support */ #include @@ -20,6 +21,35 @@ #endif /* RT_SDIO_DEBUG */ #include +typedef struct +{ + uint8_t mid; + char *name; +}card_brands_t; + +/* +Manufacturer lID (MlD) are assigned by the SD Assoication (SD-3c LLC),. They consider this infomation confidential so an oficial list is not +published. +The following list was complled by reading the ClD on numerous SD cards. Many card brands are produced by OEM supliers, and the MID +and OEMlD may refiect this, or in some cases they appear to show the producer of the card controller. +*/ +static const card_brands_t card_brands[] = +{ + {0x01, "Panasonic"}, + {0x02, "Toshiba"}, + {0x03, "SanDisk"}, + {0x1B, "ProGrade, Samsung"}, + {0x1D, "AData"}, + {0x27, "AgfaPhoto, Delkin, Integral, Lexar, Patriot, PNY, Polaroid, Sony, Verbatim"}, + {0x28, "Lexar, PNY, ProGrade"}, + {0x31, "Silicon Power"}, + {0x41, "Kingston"}, + {0x74, "Transcend"}, + {0x76, "Patriot"}, + {0x82, "Gobe, Sony"}, + {0x9c, "Angelbird, Hoodman"}, +}; + static const rt_uint32_t tran_unit[] = { 10000, 100000, 1000000, 10000000, @@ -60,16 +90,52 @@ rt_inline rt_uint32_t GET_BITS(rt_uint32_t *resp, return __res & __mask; } +static char *mmcsd_get_card_brand(rt_uint8_t mid) +{ + char *brand = "Unknown"; + for (int i = 0; i < sizeof(card_brands) / sizeof(card_brands_t); i++) + { + if (card_brands[i].mid == mid) + { + brand = card_brands[i].name; + break; + } + } + return brand; +} + +static void mmcsd_parse_cid(struct rt_mmcsd_card *card) +{ + struct rt_mmcsd_cid cid = {0}; + rt_uint32_t *resp = card->resp_cid; + + cid.mid = GET_BITS(resp, 120, 8); + cid.oid[0] = GET_BITS(resp, 112, 8); + cid.oid[1] = GET_BITS(resp, 104, 8); + cid.pnm[0] = GET_BITS(resp, 96, 8); + cid.pnm[1] = GET_BITS(resp, 88, 8); + cid.pnm[2] = GET_BITS(resp, 80, 8); + cid.pnm[3] = GET_BITS(resp, 72, 8); + cid.pnm[4] = GET_BITS(resp, 64, 8); + cid.prv = GET_BITS(resp, 56, 8); + cid.psn = GET_BITS(resp, 24, 32); + cid.mdt = GET_BITS(resp, 8, 12); + LOG_I("SD card MID: %s, OID: %s, PNM: %s, PRV: %d.%d, PSN: 0x%08x, MDT: %dmonth %dyear", + mmcsd_get_card_brand(cid.mid), cid.oid, cid.pnm, + cid.prv >> 4, cid.prv & 0x0F, cid.psn, cid.mdt & 0x0F, (cid.mdt >> 4) + 2000); +} + static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) { struct rt_mmcsd_csd *csd = &card->csd; rt_uint32_t *resp = card->resp_csd; + const char *name[] = {"SDSC", "SDHC or SDXC", "SDUC", "RESERVED"}; csd->csd_structure = GET_BITS(resp, 126, 2); switch (csd->csd_structure) { - case 0: + case 0: /* CSD Version 1.0 */ csd->taac = GET_BITS(resp, 112, 8); csd->nsac = GET_BITS(resp, 104, 8); csd->tran_speed = GET_BITS(resp, 96, 8); @@ -96,7 +162,7 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) break; case 1: - card->flags |= CARD_FLAG_SDHC; + card->flags |= (CARD_FLAG_SDHC | CARD_FLAG_SDXC); /*This field is fixed to 0Eh, which indicates 1 ms. The host should not use TAAC, NSAC, and R2W_FACTOR @@ -124,14 +190,45 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) card->tacc_clks = 0; card->tacc_ns = 0; card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3]; + break; + case 2: /* CSD Version 3.0 */ + /*This field is expanded to 28 bits and can indicate up to 128 TBytes.*/ + card->flags |= (CARD_FLAG_SDUC | CARD_FLAG_SDHC| CARD_FLAG_SDXC); + + /*This field is fixed to 0Eh, which indicates 1 ms. + The host should not use TAAC, NSAC, and R2W_FACTOR + to calculate timeout and should uses fixed timeout + values for read and write operations*/ + csd->taac = GET_BITS(resp, 112, 8); + csd->nsac = GET_BITS(resp, 104, 8); + csd->tran_speed = GET_BITS(resp, 96, 8); + csd->card_cmd_class = GET_BITS(resp, 84, 12); + csd->rd_blk_len = GET_BITS(resp, 80, 4); + csd->rd_blk_part = GET_BITS(resp, 79, 1); + csd->wr_blk_misalign = GET_BITS(resp, 78, 1); + csd->rd_blk_misalign = GET_BITS(resp, 77, 1); + csd->dsr_imp = GET_BITS(resp, 76, 1); + csd->c_size = GET_BITS(resp, 48, 22); + + csd->r2w_factor = GET_BITS(resp, 26, 3); + csd->wr_blk_len = GET_BITS(resp, 22, 4); + csd->wr_blk_partial = GET_BITS(resp, 21, 1); + csd->csd_crc = GET_BITS(resp, 1, 7); + card->card_blksize = 512; + card->card_capacity = (csd->c_size + 1) * 512; /* unit:KB */ + card->card_sec_cnt = card->card_capacity * 2; + card->tacc_clks = 0; + card->tacc_ns = 0; + card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3]; break; default: - LOG_E("unrecognised CSD structure version %d!", csd->csd_structure); - + LOG_W("unrecognised CSD structure version %d!", csd->csd_structure); return -RT_ERROR; } - LOG_I("SD card capacity %d KB.", card->card_capacity); + + LOG_I("SD card version %s,class %d, capacity %d KB.", + name[csd->csd_structure], __rt_fls(csd->card_cmd_class) - 1, card->card_capacity); return 0; } @@ -143,9 +240,17 @@ static rt_int32_t mmcsd_parse_scr(struct rt_mmcsd_card *card) resp[3] = card->resp_scr[1]; resp[2] = card->resp_scr[0]; - scr->sd_version = GET_BITS(resp, 56, 4); + rt_uint8_t sd_spec = GET_BITS(resp, 56, 4); + rt_uint8_t sd_spec3 = GET_BITS(resp, 47, 1); + rt_uint8_t sd_spec4 = GET_BITS(resp, 42, 1); + rt_uint8_t sd_specx = GET_BITS(resp, 38, 4); + scr->sd_bus_widths = GET_BITS(resp, 48, 4); + scr->sd_version = sd_spec + sd_spec3 + sd_spec4 + sd_specx; + scr->sd_version = (sd_specx != 0 && sd_spec4 == 0) ? scr->sd_version + 1 : scr->sd_version; + LOG_I("SD spec version %d", scr->sd_version); + return 0; } @@ -274,7 +379,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card) card->max_data_rate = 50000000; if (switch_func_timing == SD_SWITCH_FUNC_TIMING_SDR104) { - LOG_I("sd: switch to SDR104 mode\n"); + LOG_I("sd: switch to SDR104 mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_SDR104); mmcsd_set_clock(card->host, 208000000); err = mmcsd_excute_tuning(card); @@ -282,7 +387,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card) } else if (switch_func_timing == SD_SWITCH_FUNC_TIMING_SDR50) { - LOG_I("sd: switch to SDR50 mode\n"); + LOG_I("sd: switch to SDR50 mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_SDR50); mmcsd_set_clock(card->host, 100000000); err = mmcsd_excute_tuning(card); @@ -290,13 +395,13 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card) } else if (switch_func_timing == SD_SWITCH_FUNC_TIMING_DDR50) { - LOG_I("sd: switch to DDR50 mode\n"); + LOG_I("sd: switch to DDR50 mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_DDR50); mmcsd_set_clock(card->host, 50000000); } else { - LOG_I("sd: switch to High Speed / SDR25 mode \n"); + LOG_I("sd: switch to High Speed / SDR25 mode"); mmcsd_set_timing(card->host, MMCSD_TIMING_SD_HS); mmcsd_set_clock(card->host, 50000000); } @@ -381,7 +486,6 @@ rt_err_t mmcsd_send_app_cmd(struct rt_mmcsd_host *host, rt_memset(cmd->resp, 0, sizeof(cmd->resp)); req.cmd = cmd; - //cmd->data = NULL; mmcsd_send_request(host, &req); @@ -470,7 +574,7 @@ rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, err = -RT_ETIMEOUT; - rt_thread_mdelay(10); //delay 10ms + rt_thread_mdelay(10); /*delay 10ms*/ } if (rocr && !controller_is_spi(host)) @@ -595,7 +699,7 @@ static rt_err_t mmcsd_read_sd_status(struct rt_mmcsd_card *card, rt_uint32_t *sd req.cmd = &cmd; req.data = &data; - cmd.cmd_code = SEND_STATUS; + cmd.cmd_code = SD_APP_SD_STATUS; cmd.arg = 0; cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; @@ -714,6 +818,7 @@ static rt_int32_t mmcsd_sd_init_card(struct rt_mmcsd_host *host, card->card_type = CARD_TYPE_SD; card->host = host; rt_memcpy(card->resp_cid, resp, sizeof(card->resp_cid)); + mmcsd_parse_cid(card); /* * For native busses: get card RCA and quit open drain mode. @@ -768,11 +873,10 @@ static rt_int32_t mmcsd_sd_init_card(struct rt_mmcsd_host *host, } /* Read and decode SD Status and check whether UHS mode is supported */ - union rt_sd_status sd_status; - err = mmcsd_read_sd_status(card, sd_status.status_words); + err = mmcsd_read_sd_status(card, card->sd_status.status_words); if (err) goto err1; - if ((sd_status.uhs_speed_grade > 0) && (ocr & VDD_165_195)) + if ((card->sd_status.uhs_speed_grade > 0) && (ocr & VDD_165_195)) { /* Assume the card supports all UHS-I modes because we cannot find any mainstreaming card * that can support only part of the following modes. diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c index 9fa3f539cd4..8680711e131 100644 --- a/components/drivers/sdio/sdio.c +++ b/components/drivers/sdio/sdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -1403,9 +1403,3 @@ rt_int32_t sdio_unregister_driver(struct rt_sdio_driver *driver) return 0; } - -void rt_sdio_init(void) -{ - -} - From 75496942c5d05160d2561c89cdc3b0247080252e Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Mon, 5 Aug 2024 23:57:36 +0800 Subject: [PATCH 4/5] [stm32][sdmmc]Optimize execution efficiency and find the right clock division --- .../libraries/HAL_Drivers/drivers/drv_sdmmc.c | 151 +++++++++--------- .../libraries/HAL_Drivers/drivers/drv_sdmmc.h | 14 +- 2 files changed, 82 insertions(+), 83 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.c index 526a4dd5dad..a325289bf8d 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,6 +8,7 @@ * 2020-05-23 liuduanfei first version * 2020-08-25 wanghaijing add sdmmmc2 * 2023-03-26 wdfk-prog Distinguish between SDMMC and SDIO drivers + * 2024-08-05 wdfk-prog Optimize execution efficiency and find the right clock division */ #include "board.h" @@ -27,7 +28,6 @@ #endif /* DRV_DEBUG */ #include -static struct stm32_sdio_class sdio_obj; static struct rt_mmcsd_host *host1; static struct rt_mmcsd_host *host2; @@ -55,6 +55,11 @@ struct rthw_sdio rt_align(SDIO_ALIGN_LEN) static rt_uint8_t cache_buf[SDIO_BUFF_SIZE]; +static rt_uint32_t stm32_sdio_clk_get(void) +{ + return SDIO_CLOCK_FREQ; +} + /** * @brief This function get order from sdio. * @param data @@ -154,10 +159,6 @@ static void rthw_sdio_wait_completed(struct rthw_sdio *sdio) return; } - if (sdio->pkg == RT_NULL) - { - return; - } /* Get Card Specific Data */ cmd->resp[0] = hsd->RESP1; if (resp_type(cmd) == RESP_R2) @@ -262,7 +263,7 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg) /* data pre configuration */ if (data != RT_NULL) { - SCB_CleanInvalidateDCache(); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cache_buf, data->blks * data->blksize); reg_cmd |= SDMMC_CMD_CMDTRANS; __HAL_SD_DISABLE_IT(&sdio->sdio_des.hw_sdio, SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE); @@ -288,14 +289,21 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg) /* Waiting for data to be sent to completion */ if (data != RT_NULL) { - volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS; + uint32_t timer = rt_tick_get() + rt_tick_from_millisecond(10); - while (count && (hsd->STA & SDMMC_STA_DPSMACT)) + while (timer > rt_tick_get()) { - count--; + if(hsd->STA & SDMMC_STA_DPSMACT) + { + continue; + } + else + { + break; + } } - if ((count == 0) || (hsd->STA & SDIO_ERRORS)) + if (timer < rt_tick_get() || (hsd->STA & SDIO_ERRORS)) { cmd->err = -RT_ERROR; } @@ -307,7 +315,7 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg) if (data->flags & DATA_DIR_READ) { rt_memcpy(data->buf, cache_buf, data->blks * data->blksize); - SCB_CleanInvalidateDCache(); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, cache_buf, data->blks * data->blksize); } } } @@ -374,6 +382,33 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg * SDMMC_InitTypeDef Init = {0}; rt_uint32_t sdmmc_clk = sdio->sdio_des.clk_get(); + rt_bool_t stop_flag = RT_TRUE; + + switch (io_cfg->power_mode & 0X03) + { + case MMCSD_POWER_OFF: + /* Set Power State to OFF */ + (void)SDMMC_PowerState_OFF(hsd->Instance); + stop_flag = RT_TRUE; + break; + case MMCSD_POWER_UP: + /* In F4 series chips, 0X01 is reserved bit and has no practical effect. + For F7 series chips, 0X01 is power-on after power-off,The SDMMC disables the function and the card clock stops. + For H7 series chips, 0X03 is the power-on function. + */ + stop_flag = RT_TRUE; + break; + case MMCSD_POWER_ON: + stop_flag = RT_FALSE; + break; + default: + LOG_W("unknown power mode %d", io_cfg->power_mode); + stop_flag = RT_FALSE; + break; + } + + if(stop_flag == RT_TRUE) return; + if (sdmmc_clk < 400 * 1000) { LOG_E("The clock rate is too low! rata:%d", sdmmc_clk); @@ -418,62 +453,37 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg * Init.BusWide = SDMMC_BUS_WIDE_1B; } Init.HardwareFlowControl = hsd->Init.HardwareFlowControl; - /* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */ - if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) - { - Init.ClockDiv = hsd->Init.ClockDiv; - } - //CARD_ULTRA_HIGH_SPEED :UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards and <104Mo/s for SDR104, Spec version 3.01 - else if (MMCSD_TIMING_UHS_SDR50 <= io_cfg->timing && io_cfg->timing <= MMCSD_TIMING_UHS_DDR50) + if(clk != SD_INIT_FREQ) { - /* UltraHigh speed SD card,user Clock div */ - Init.ClockDiv = hsd->Init.ClockDiv; - } - //CARD_HIGH_SPEED: High Speed Card <25Mo/s , Spec version 2.00 - else if (io_cfg->timing == MMCSD_TIMING_SD_HS) - { - /* High speed SD card, Max Frequency = 50Mhz */ - if (hsd->Init.ClockDiv == 0U) + /* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */ + if (hsd->Init.ClockDiv <= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) { - if (sdmmc_clk > SD_HIGH_SPEED_FREQ) - { - Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); - } - else - { - Init.ClockDiv = hsd->Init.ClockDiv; - } + Init.ClockDiv = hsd->Init.ClockDiv; } - else + /*CARD_ULTRA_HIGH_SPEED :UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards and <104Mo/s for SDR104, Spec version 3.01*/ + else if (MMCSD_TIMING_UHS_SDR50 <= io_cfg->timing && io_cfg->timing <= MMCSD_TIMING_UHS_DDR50) { - if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ) - { - Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); - } - else - { - Init.ClockDiv = hsd->Init.ClockDiv; - } + /* UltraHigh speed SD card,user Clock div */ + Init.ClockDiv = hsd->Init.ClockDiv; } - } - //CARD_NORMAL_SPEED: Normal Speed Card <12.5Mo/s , Spec Version 1.01 - else if (io_cfg->timing == MMCSD_TIMING_LEGACY) - { - /* No High speed SD card, Max Frequency = 25Mhz */ - if (hsd->Init.ClockDiv == 0U) + /*CARD_HIGH_SPEED: High Speed Card <25Mo/s , Spec version 2.00*/ + else if (io_cfg->timing == MMCSD_TIMING_SD_HS) { - if (sdmmc_clk > SD_NORMAL_SPEED_FREQ) + /* High speed SD card, Max Frequency = 50Mhz */ + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) < SD_HIGH_SPEED_FREQ) { - Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); } else { Init.ClockDiv = hsd->Init.ClockDiv; } } - else + /*CARD_NORMAL_SPEED: Normal Speed Card <12.5Mo/s , Spec Version 1.01*/ + else if (io_cfg->timing == MMCSD_TIMING_LEGACY) { - if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ) + /* No High speed SD card, Max Frequency = 25Mhz */ + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) < SD_NORMAL_SPEED_FREQ) { Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); } @@ -483,26 +493,16 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg * } } } + else + { + Init.ClockDiv = hsd->Init.ClockDiv; + } (void)SDMMC_Init(hsd->Instance, Init); } - switch ((io_cfg->power_mode)&0X03) + if((io_cfg->power_mode & 0X03) == MMCSD_POWER_ON) { - case MMCSD_POWER_OFF: - /* Set Power State to OFF */ - (void)SDMMC_PowerState_OFF(hsd->Instance); - break; - case MMCSD_POWER_UP: - /* In F4 series chips, 0X01 is reserved bit and has no practical effect. - For F7 series chips, 0X01 is power-on after power-off,The SDMMC disables the function and the card clock stops. - For H7 series chips, 0X03 is the power-on function. - */ - case MMCSD_POWER_ON: /* Set Power State to ON */ (void)SDMMC_PowerState_ON(hsd->Instance); - break; - default: - LOG_W("unknown power mode %d", io_cfg->power_mode); - break; } } @@ -574,7 +574,7 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) if (sdio_des == RT_NULL) { - LOG_E("L:%d F:%s",(sdio_des == RT_NULL ? "sdio_des is NULL" : "")); + LOG_E("sdio_des is NULL"); return RT_NULL; } @@ -582,7 +582,7 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) if (sdio == RT_NULL) { - LOG_E("L:%d F:%s malloc rthw_sdio fail"); + LOG_E("malloc rthw_sdio fail"); return RT_NULL; } @@ -592,12 +592,13 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) if (host == RT_NULL) { - LOG_E("L:%d F:%s mmcsd alloc host fail"); + LOG_E("mmcsd alloc host fail"); rt_free(sdio); return RT_NULL; } rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des)); + sdio->sdio_des.clk_get = (sdio_des->clk_get == RT_NULL ? stm32_sdio_clk_get : sdio_des->clk_get); #ifdef BSP_USING_SDIO1 if(sdio_des->hw_sdio.Instance == SDMMC1) { @@ -626,14 +627,14 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) #endif host->max_seg_size = SDIO_BUFF_SIZE; host->max_dma_segs = 1; - host->max_blk_size = 512; - host->max_blk_count = 512; + host->max_blk_size = BLOCKSIZE; + host->max_blk_count = BLOCKSIZE; /* link up host and sdio */ sdio->host = host; host->private_data = sdio; - rthw_sdio_irq_update(host, 1); + rthw_sdio_irq_update(host, RT_TRUE); /* ready to change */ mmcsd_change(host); diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.h index 6b388d4fb5a..da4b47392ea 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdmmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,6 +8,7 @@ * 2020-05-23 liuduanfei first version * 2020-08-25 wanghaijing add sdmmmc2 * 2023-03-26 wdfk-prog Distinguish between SDMMC and SDIO drivers + * 2024-08-05 wdfk-prog Optimize execution efficiency and find the right clock division */ #ifndef __DRV_SDMMC_H__ @@ -21,9 +22,6 @@ #include #include -#define SDIO_BUFF_SIZE 4096 -#define SDIO_ALIGN_LEN 32 - #define SDIO1_BASE_ADDRESS (SDMMC1_BASE) #define SDIO2_BASE_ADDRESS (SDMMC2_BASE) @@ -39,15 +37,15 @@ #define SDIO_ALIGN_LEN (32) #endif -#ifndef SDIO_MAX_FREQ -#define SDIO_MAX_FREQ (25 * 1000 * 1000) -#endif - /* Frequencies used in the driver for clock divider calculation */ #define SD_INIT_FREQ 400000U /* Initalization phase : 400 kHz max */ #define SD_NORMAL_SPEED_FREQ 25000000U /* Normal speed phase : 25 MHz max */ #define SD_HIGH_SPEED_FREQ 50000000U /* High speed phase : 50 MHz max */ +#ifndef SDIO_MAX_FREQ +#define SDIO_MAX_FREQ (SD_HIGH_SPEED_FREQ) +#endif + #define SDIO_ERRORS \ (SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \ SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \ From 53d1a2627f520bd1a4218566c39f9a9789ad1530 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Mon, 5 Aug 2024 23:59:56 +0800 Subject: [PATCH 5/5] [drivers][sdio] Change the default stack size to 2048 --- components/drivers/sdio/Kconfig | 2 +- components/drivers/sdio/mmcsd_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/drivers/sdio/Kconfig b/components/drivers/sdio/Kconfig index e5bff4549d8..3a464e73cf7 100644 --- a/components/drivers/sdio/Kconfig +++ b/components/drivers/sdio/Kconfig @@ -13,7 +13,7 @@ config RT_USING_SDIO config RT_MMCSD_STACK_SIZE int "The stack size for mmcsd thread" - default 1024 + default 2048 config RT_MMCSD_THREAD_PREORITY int "The priority level value of mmcsd thread" diff --git a/components/drivers/sdio/mmcsd_core.c b/components/drivers/sdio/mmcsd_core.c index 13727c7a4cc..8298ef6baa2 100644 --- a/components/drivers/sdio/mmcsd_core.c +++ b/components/drivers/sdio/mmcsd_core.c @@ -24,7 +24,7 @@ #include #ifndef RT_MMCSD_STACK_SIZE -#define RT_MMCSD_STACK_SIZE 1024 +#define RT_MMCSD_STACK_SIZE 2048 #endif #ifndef RT_MMCSD_THREAD_PREORITY #if (RT_THREAD_PRIORITY_MAX == 32)