1 /*
2 * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-12-30 CDT first version
9 */
10
11 /*
12 * 程序清单:SD/MMC卡 设备使用例程
13 * 例程导出了 sample_sdmmc 命令到控制终端
14 * 命令调用格式:sdmmc_sample
15 * 程序功能:对整个SD/MMC卡进行写和读操作,比较数据是否一致
16 *
17 * 注意: 修改函数SystemClock_Config下面参数,
18 * stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL;
19 * 改为
20 * stcPLLHInit.PLLCFGR_f.PLLN = 100UL - 1UL;
21 */
22
23 #include <stdlib.h>
24 #include <rtthread.h>
25 #include <rtdevice.h>
26 #include <board.h>
27
28 #if defined(BSP_USING_SDIO)
29
30 #define SDMMC_DEVICE_NAME "sd"
31 #define SDMMC_SECTOR_SIZE 512UL
32
33 #define SDMMC_TEST_SECTORS_PER_TIME 100UL
34 #define SDMMC_TEST_TIME 10UL
35
36 #define SDMMC_TEST_SECTORS (SDMMC_TEST_TIME * SDMMC_TEST_SECTORS_PER_TIME)
37 #define SDMMC_TEST_BUF_SIZE (SDMMC_SECTOR_SIZE * SDMMC_TEST_SECTORS_PER_TIME)
38
sdmmc_thread_entry(void * parameter)39 static void sdmmc_thread_entry(void *parameter)
40 {
41 rt_ssize_t size;
42 rt_uint32_t err_count = 0;
43 rt_device_t sd_device;
44 rt_uint32_t sector_start;
45 rt_uint32_t sector_end;;
46 rt_uint32_t sector_cur_start;
47 rt_uint32_t sector_cur_end;
48 rt_uint8_t *sector_rbuf;
49 rt_uint8_t *sector_wbuf;
50
51 sd_device = rt_device_find(SDMMC_DEVICE_NAME);
52 if (sd_device == RT_NULL)
53 {
54 rt_kprintf("no nand device found!\n");
55 return;
56 }
57
58 if (rt_device_open(sd_device, RT_DEVICE_FLAG_RDWR) != RT_EOK)
59 {
60 rt_kprintf("fail to open!\n");
61 return;
62 }
63
64 sector_rbuf = rt_malloc(SDMMC_TEST_BUF_SIZE);
65 if (sector_rbuf == RT_NULL)
66 {
67 rt_kprintf("out of memory!");
68 return;
69 }
70
71 sector_wbuf = rt_malloc(SDMMC_TEST_BUF_SIZE);
72 if (sector_wbuf == RT_NULL)
73 {
74 rt_free(sector_rbuf);
75 rt_kprintf("out of memory!");
76 return;
77 }
78
79 sector_start = ((rt_uint32_t)rand() & 0x00000FFFUL);
80 sector_end = (sector_start + SDMMC_TEST_SECTORS - 1);
81
82 rt_kprintf("sector=[%d, %d]: ......test start...... !\r\n", sector_start, sector_end);
83
84 for (sector_cur_start = sector_start; sector_cur_start <= sector_end; sector_cur_start += SDMMC_TEST_SECTORS_PER_TIME)
85 {
86 sector_cur_end = sector_cur_start + SDMMC_TEST_SECTORS_PER_TIME - 1UL;
87
88 /* initialize buffer data */
89 rt_memset(sector_rbuf, 0, SDMMC_TEST_BUF_SIZE);
90 rt_memset(sector_wbuf, (rt_uint8_t)rand(), SDMMC_TEST_BUF_SIZE);
91
92 /* write sdmmc */
93 size = rt_device_write(sd_device, sector_cur_start, sector_wbuf, SDMMC_TEST_SECTORS_PER_TIME);
94 if (size == SDMMC_TEST_SECTORS_PER_TIME)
95 {
96 rt_kprintf("sector=[%d, %d]: ok wr !\r\n", sector_cur_start, sector_cur_end);
97 }
98 else
99 {
100 err_count++;
101 rt_kprintf("sector=[%d, %d]: error wr !\r\n", sector_cur_start, sector_cur_end);
102 continue;
103 }
104
105 /* read sdmmc */
106 size = rt_device_read(sd_device, sector_cur_start, sector_rbuf, SDMMC_TEST_SECTORS_PER_TIME);
107 if (size == SDMMC_TEST_SECTORS_PER_TIME)
108 {
109 rt_kprintf("sector=[%d, %d]: ok rd !\r\n", sector_cur_start, sector_cur_end);
110 }
111 else
112 {
113 err_count++;
114 rt_kprintf("sector=[%d, %d]: error rd !\r\n", sector_cur_start, sector_cur_end);
115 continue;
116 }
117
118 /* compare data */
119 if (rt_memcmp(sector_wbuf, sector_rbuf, SDMMC_TEST_BUF_SIZE) == 0)
120 {
121 rt_kprintf("sector=[%d, %d]: ok cmp !\r\n", sector_cur_start, sector_cur_end);
122 }
123 else
124 {
125 err_count++;
126 rt_kprintf("sector=[%d, %d]: error cmp !\r\n", sector_cur_start, sector_cur_end);
127 }
128 }
129
130 if (rt_device_close(sd_device) != RT_EOK)
131 {
132 rt_kprintf("fail to close!\n");
133 }
134
135 rt_free(sector_rbuf);
136 rt_free(sector_wbuf);
137
138 if (err_count == 0)
139 {
140 rt_kprintf("sector=[%d, %d]: ...... test ok...... !\r\n\r\n", sector_start, sector_end);
141
142 }
143 else
144 {
145 rt_kprintf("sector=[%d, %d]: ...... test error...... !\r\n\r\n", sector_start, sector_end);
146 }
147 }
148
sdmmc_sample(int argc,char * argv[])149 static void sdmmc_sample(int argc, char *argv[])
150 {
151 rt_thread_t thread = rt_thread_create("sdmmc", sdmmc_thread_entry, RT_NULL, 2048, 15, 10);
152 if (thread != RT_NULL)
153 {
154 rt_thread_startup(thread);
155 }
156 }
157 MSH_CMD_EXPORT(sdmmc_sample, sdmmc sample);
158
159 #endif
160