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