STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
app4.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------/
2 / Low level disk I/O module function checker
3 /-----------------------------------------------------------------------/
4 / WARNING: The data on the target drive will be lost!
5 */
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include "ff.h"
10 #include "diskio.h"
11 
12 
13 static
14 DWORD pn (
15  DWORD pns
16 )
17 {
18  static DWORD lfsr;
19  UINT n;
20 
21 
22  if (pns) {
23  lfsr = pns;
24  for (n = 0; n < 32; n++) pn(0);
25  }
26  if (lfsr & 1) {
27  lfsr >>= 1;
28  lfsr ^= 0x80200003;
29  } else {
30  lfsr >>= 1;
31  }
32  return lfsr;
33 }
34 
35 
37  BYTE pdrv, /* Physical drive number to be checked (all data on the drive will be lost) */
38  UINT ncyc, /* Number of test cycles */
39  DWORD* buff, /* Pointer to the working buffer */
40  UINT sz_buff /* Size of the working buffer in unit of byte */
41 )
42 {
43  UINT n, cc, ns;
44  DWORD sz_drv, lba, lba2, pns = 1;
45  WORD sz_sect, sz_eblk;
46  BYTE *pbuff = (BYTE*)buff;
47  DSTATUS ds;
48  DRESULT dr;
49 
50 
51 
52  printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff);
53 
54  if (sz_buff < _MAX_SS + 4) {
55  printf("Insufficient work area to test.\n");
56  return 1;
57  }
58 
59  for (cc = 1; cc <= ncyc; cc++) {
60  printf("**** Test cycle %u of %u start ****\n", cc, ncyc);
61 
62  /* Initialization */
63  printf(" disk_initalize(%u)", pdrv);
64  ds = disk_initialize(pdrv);
65  if (ds & STA_NOINIT) {
66  printf(" - failed.\n");
67  return 2;
68  } else {
69  printf(" - ok.\n");
70  }
71 
72  /* Get drive size */
73  printf("**** Get drive size ****\n");
74  printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv);
75  sz_drv = 0;
76  dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv);
77  if (dr == RES_OK) {
78  printf(" - ok.\n");
79  } else {
80  printf(" - failed.\n");
81  return 3;
82  }
83  if (sz_drv < 128) {
84  printf("Failed: Insufficient drive size to test.\n");
85  return 4;
86  }
87  printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv);
88 
89 #if _MAX_SS != _MIN_SS
90  /* Get sector size */
91  printf("**** Get sector size ****\n");
92  printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect);
93  sz_sect = 0;
94  dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect);
95  if (dr == RES_OK) {
96  printf(" - ok.\n");
97  } else {
98  printf(" - failed.\n");
99  return 5;
100  }
101  printf(" Size of sector is %u bytes.\n", sz_sect);
102 #else
103  sz_sect = _MAX_SS;
104 #endif
105 
106  /* Get erase block size */
107  printf("**** Get block size ****\n");
108  printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk);
109  sz_eblk = 0;
110  dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk);
111  if (dr == RES_OK) {
112  printf(" - ok.\n");
113  } else {
114  printf(" - failed.\n");
115  }
116  if (dr == RES_OK || sz_eblk >= 2) {
117  printf(" Size of the erase block is %u sectors.\n", sz_eblk);
118  } else {
119  printf(" Size of the erase block is unknown.\n");
120  }
121 
122  /* Single sector write test */
123  printf("**** Single sector write test 1 ****\n");
124  lba = 0;
125  for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0);
126  printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
127  dr = disk_write(pdrv, pbuff, lba, 1);
128  if (dr == RES_OK) {
129  printf(" - ok.\n");
130  } else {
131  printf(" - failed.\n");
132  return 6;
133  }
134  printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
135  dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
136  if (dr == RES_OK) {
137  printf(" - ok.\n");
138  } else {
139  printf(" - failed.\n");
140  return 7;
141  }
142  memset(pbuff, 0, sz_sect);
143  printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
144  dr = disk_read(pdrv, pbuff, lba, 1);
145  if (dr == RES_OK) {
146  printf(" - ok.\n");
147  } else {
148  printf(" - failed.\n");
149  return 8;
150  }
151  for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) ;
152  if (n == sz_sect) {
153  printf(" Data matched.\n");
154  } else {
155  printf("Failed: Read data differs from the data written.\n");
156  return 10;
157  }
158  pns++;
159 
160  /* Multiple sector write test */
161  printf("**** Multiple sector write test ****\n");
162  lba = 1; ns = sz_buff / sz_sect;
163  if (ns > 4) ns = 4;
164  for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0);
165  printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
166  dr = disk_write(pdrv, pbuff, lba, ns);
167  if (dr == RES_OK) {
168  printf(" - ok.\n");
169  } else {
170  printf(" - failed.\n");
171  return 11;
172  }
173  printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
174  dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
175  if (dr == RES_OK) {
176  printf(" - ok.\n");
177  } else {
178  printf(" - failed.\n");
179  return 12;
180  }
181  memset(pbuff, 0, sz_sect * ns);
182  printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);
183  dr = disk_read(pdrv, pbuff, lba, ns);
184  if (dr == RES_OK) {
185  printf(" - ok.\n");
186  } else {
187  printf(" - failed.\n");
188  return 13;
189  }
190  for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ;
191  if (n == (UINT)(sz_sect * ns)) {
192  printf(" Data matched.\n");
193  } else {
194  printf("Failed: Read data differs from the data written.\n");
195  return 14;
196  }
197  pns++;
198 
199  /* Single sector write test (misaligned memory address) */
200  printf("**** Single sector write test 2 ****\n");
201  lba = 5;
202  for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);
203  printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);
204  dr = disk_write(pdrv, pbuff+3, lba, 1);
205  if (dr == RES_OK) {
206  printf(" - ok.\n");
207  } else {
208  printf(" - failed.\n");
209  return 15;
210  }
211  printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
212  dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
213  if (dr == RES_OK) {
214  printf(" - ok.\n");
215  } else {
216  printf(" - failed.\n");
217  return 16;
218  }
219  memset(pbuff+5, 0, sz_sect);
220  printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba);
221  dr = disk_read(pdrv, pbuff+5, lba, 1);
222  if (dr == RES_OK) {
223  printf(" - ok.\n");
224  } else {
225  printf(" - failed.\n");
226  return 17;
227  }
228  for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ;
229  if (n == sz_sect) {
230  printf(" Data matched.\n");
231  } else {
232  printf("Failed: Read data differs from the data written.\n");
233  return 18;
234  }
235  pns++;
236 
237  /* 4GB barrier test */
238  printf("**** 4GB barrier test ****\n");
239  if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) {
240  lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2);
241  for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0);
242  printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
243  dr = disk_write(pdrv, pbuff, lba, 1);
244  if (dr == RES_OK) {
245  printf(" - ok.\n");
246  } else {
247  printf(" - failed.\n");
248  return 19;
249  }
250  printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
251  dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1);
252  if (dr == RES_OK) {
253  printf(" - ok.\n");
254  } else {
255  printf(" - failed.\n");
256  return 20;
257  }
258  printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);
259  dr = disk_ioctl(pdrv, CTRL_SYNC, 0);
260  if (dr == RES_OK) {
261  printf(" - ok.\n");
262  } else {
263  printf(" - failed.\n");
264  return 21;
265  }
266  memset(pbuff, 0, sz_sect * 2);
267  printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);
268  dr = disk_read(pdrv, pbuff, lba, 1);
269  if (dr == RES_OK) {
270  printf(" - ok.\n");
271  } else {
272  printf(" - failed.\n");
273  return 22;
274  }
275  printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);
276  dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1);
277  if (dr == RES_OK) {
278  printf(" - ok.\n");
279  } else {
280  printf(" - failed.\n");
281  return 23;
282  }
283  for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ;
284  if (n == (UINT)(sz_sect * 2)) {
285  printf(" Data matched.\n");
286  } else {
287  printf("Failed: Read data differs from the data written.\n");
288  return 24;
289  }
290  } else {
291  printf(" Test skipped.\n");
292  }
293  pns++;
294 
295  printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc);
296  }
297 
298  return 0;
299 }
300 
301 
302 
303 int main (int argc, char* argv[])
304 {
305  int rc;
306  DWORD buff[512]; /* 2048 byte working buffer */
307 
308  /* Check function/compatibility of the physical drive #0 */
309  rc = test_diskio(0, 1, buff, sizeof buff);
310  if (rc) {
311  printf("Sorry the function/compatibility test failed.\nFatFs will not work on this disk driver.\n");
312  } else {
313  printf("Congratulations! The disk I/O layer works well.\n");
314  }
315 
316  return rc;
317 }
318 
#define GET_BLOCK_SIZE
Definition: diskio.h:55
unsigned short WORD
Definition: integer.h:20
#define STA_NOINIT
Definition: diskio.h:44
#define _MAX_SS
Definition: ffconf.h:226
int test_diskio(BYTE pdrv, UINT ncyc, DWORD *buff, UINT sz_buff)
Definition: app4.c:36
#define GET_SECTOR_COUNT
Definition: diskio.h:53
unsigned long DWORD
Definition: integer.h:29
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
Writes Sector(s)
Definition: diskio.c:114
BYTE DSTATUS
Definition: diskio.h:19
DRESULT
Definition: diskio.h:22
unsigned char BYTE
Definition: integer.h:16
int main(int argc, char *argv[])
Definition: app4.c:303
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
I/O control operation.
Definition: diskio.c:136
Definition: diskio.h:23
DSTATUS disk_initialize(BYTE pdrv)
Initializes a Drive.
Definition: diskio.c:70
unsigned int UINT
Definition: integer.h:25
#define GET_SECTOR_SIZE
Definition: diskio.h:54
#define CTRL_SYNC
Definition: diskio.h:52
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
Reads Sector(s)
Definition: diskio.c:92