123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- /*----------------------------------------------------------------------/
- / Low level disk I/O module function checker
- /-----------------------------------------------------------------------/
- / WARNING: The data on the target drive will be lost!
- */
- #include <stdio.h>
- #include <string.h>
- #include "ff.h"
- #include "diskio.h"
- static
- DWORD 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, 3, buff, sizeof buff);
- if (rc) {
- printf("Sorry the function/compatibility test failed. (rc=%d)\nFatFs will not work on this disk driver.\n", rc);
- } else {
- printf("Congratulations! The disk driver works well.\n");
- }
- return rc;
- }
|