| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 | /*----------------------------------------------------------------------// Low level disk I/O module function checker/-----------------------------------------------------------------------// WARNING: The data on the target drive will be lost!*/#ifdef PRINTF_STDLIB#include <stdio.h>#endif#ifdef PRINTF_CUSTOM#include "tinystdio.h"#endif#include <string.h>#include "ff.h"#include "diskio.h"staticDWORD pn (    DWORD pns){    static DWORD lfsr;    UINT n;    if (pns) {        lfsr = pns;        for (n = 0; n < 32; n++) pn(0);    }    if (lfsr & 1) {        lfsr >>= 1;        lfsr ^= 0x80200003;    } else {        lfsr >>= 1;    }    return lfsr;}int test_diskio (    BYTE pdrv,      /* Physical drive number to be checked (all data on the drive will be lost) */    UINT ncyc,      /* Number of test cycles */    DWORD* buff,    /* Pointer to the working buffer */    UINT sz_buff    /* Size of the working buffer in unit of byte */){    UINT n, cc, ns;    DWORD sz_drv, lba, lba2, pns = 1;    WORD sz_sect, sz_eblk;    BYTE *pbuff = (BYTE*)buff;    DSTATUS ds;    DRESULT dr;    printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff);    if (sz_buff < _MAX_SS + 4) {        printf("Insufficient work area to test.\n");        return 1;    }    for (cc = 1; cc <= ncyc; cc++) {        printf("**** Test cycle %u of %u start ****\n", cc, ncyc);        /* Initialization */        printf(" disk_initalize(%u)", pdrv);        ds = disk_initialize(pdrv);        if (ds & STA_NOINIT) {            printf(" - failed.\n");            return 2;        } else {            printf(" - ok.\n");        }        /* Get drive size */        printf("**** Get drive size ****\n");        printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv);        sz_drv = 0;        dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 3;        }        if (sz_drv < 128) {            printf("Failed: Insufficient drive size to test.\n");            return 4;        }        printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv);#if _MAX_SS != _MIN_SS        /* Get sector size */        printf("**** Get sector size ****\n");        printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect);        sz_sect = 0;        dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 5;        }        printf(" Size of sector is %u bytes.\n", sz_sect);#else        sz_sect = _MAX_SS;#endif        /* Get erase block size */        printf("**** Get block size ****\n");        printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk);        sz_eblk = 0;        dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");        }        if (dr == RES_OK || sz_eblk >= 2) {            printf(" Size of the erase block is %u sectors.\n", sz_eblk);        } else {            printf(" Size of the erase block is unknown.\n");        }        /* Single sector write test */        printf("**** Single sector write test 1 ****\n");        lba = 0;        for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0);        printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);        dr = disk_write(pdrv, pbuff, lba, 1);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 6;        }        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);        dr = disk_ioctl(pdrv, CTRL_SYNC, 0);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 7;        }        memset(pbuff, 0, sz_sect);        printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);        dr = disk_read(pdrv, pbuff, lba, 1);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 8;        }        for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) ;        if (n == sz_sect) {            printf(" Data matched.\n");        } else {            printf("Failed: Read data differs from the data written.\n");            return 10;        }        pns++;        /* Multiple sector write test */        printf("**** Multiple sector write test ****\n");        lba = 1; ns = sz_buff / sz_sect;        if (ns > 4) ns = 4;        for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0);        printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);        dr = disk_write(pdrv, pbuff, lba, ns);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 11;        }        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);        dr = disk_ioctl(pdrv, CTRL_SYNC, 0);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 12;        }        memset(pbuff, 0, sz_sect * ns);        printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns);        dr = disk_read(pdrv, pbuff, lba, ns);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 13;        }        for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) ;        if (n == (UINT)(sz_sect * ns)) {            printf(" Data matched.\n");        } else {            printf("Failed: Read data differs from the data written.\n");            return 14;        }        pns++;        /* Single sector write test (misaligned memory address) */        printf("**** Single sector write test 2 ****\n");        lba = 5;        for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);        printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);        dr = disk_write(pdrv, pbuff+3, lba, 1);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 15;        }        printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);        dr = disk_ioctl(pdrv, CTRL_SYNC, 0);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 16;        }        memset(pbuff+5, 0, sz_sect);        printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+5), lba);        dr = disk_read(pdrv, pbuff+5, lba, 1);        if (dr == RES_OK) {            printf(" - ok.\n");        } else {            printf(" - failed.\n");            return 17;        }        for (n = 0, pn(pns); n < sz_sect && pbuff[n+5] == (BYTE)pn(0); n++) ;        if (n == sz_sect) {            printf(" Data matched.\n");        } else {            printf("Failed: Read data differs from the data written.\n");            return 18;        }        pns++;        /* 4GB barrier test */        printf("**** 4GB barrier test ****\n");        if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) {            lba = 6; lba2 = lba + 0x80000000 / (sz_sect / 2);            for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0);            printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);            dr = disk_write(pdrv, pbuff, lba, 1);            if (dr == RES_OK) {                printf(" - ok.\n");            } else {                printf(" - failed.\n");                return 19;            }            printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);            dr = disk_write(pdrv, pbuff+sz_sect, lba2, 1);            if (dr == RES_OK) {                printf(" - ok.\n");            } else {                printf(" - failed.\n");                return 20;            }            printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv);            dr = disk_ioctl(pdrv, CTRL_SYNC, 0);            if (dr == RES_OK) {            printf(" - ok.\n");            } else {                printf(" - failed.\n");                return 21;            }            memset(pbuff, 0, sz_sect * 2);            printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba);            dr = disk_read(pdrv, pbuff, lba, 1);            if (dr == RES_OK) {                printf(" - ok.\n");            } else {                printf(" - failed.\n");                return 22;            }            printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+sz_sect), lba2);            dr = disk_read(pdrv, pbuff+sz_sect, lba2, 1);            if (dr == RES_OK) {                printf(" - ok.\n");            } else {                printf(" - failed.\n");                return 23;            }            for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) ;            if (n == (UINT)(sz_sect * 2)) {                printf(" Data matched.\n");            } else {                printf("Failed: Read data differs from the data written.\n");                return 24;            }        } else {            printf(" Test skipped.\n");        }        pns++;        printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc);    }    return 0;}int main (int argc, char* argv[]){    int rc;    DWORD buff[512];  /* 2048 byte working buffer */    /* Check function/compatibility of the physical drive #0 */    rc = test_diskio(0, 1, buff, sizeof buff);    if (rc) {        printf("Sorry the function/compatibility test failed.\nFatFs will not work on this disk driver.\n");    } else {        printf("Congratulations! The disk I/O layer works well.\n");    }    return rc;}
 |