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