app4.c 9.8 KB

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