Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

FATFS test.

// Built with BFTC Rev. 1.0.0, lun 22 dicembre 2014 15:27:17

/*
    Copyright 2014 Digital Technology Art SRL
    This file is part of Blackfin Toolchain (BFTC) project.

    BFTC is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    BFTC is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Nome-Programma.  If not, see <http://www.gnu.org/licenses/>.
*/

// For FATFS documentation please refer to: http://elm-chan.org/fsw/ff/00index_e.html

#include "main.h"
#include "diskio.h"

#define ARGV(a) _str_field(Argv, a)
#define ST st = Get_TimerCounter(TIMER_0)
#define ET et = Get_TimerCounter(TIMER_0)

#define TIMEBASE 0xFFFFFFFF

// Monitor Commands
typedef struct  command {
    char        text[8];        // Max command lenght is 8 characters
    bool        (*proc)();      // Function pointer
}command;

FATFS FatFs;            // Work area (file system object) for logical drive

char    cmdLine[32];
char    Argv[256];      // Used as string list
int             Argc;           // Argument counter
bool    DiskIsOn = false;

void diskCB(BYTE drv, DWORD sector, BYTE count)
{
    if((sector % 1024) == 0)
        printf("Drive: %d, Sector: %8d, Count: %3d\n", drv, sector, count);
}

FRESULT f_ls(const char * pathName)
{
    FRESULT res;
    DWORD       used, dfree;
    WORD        files;
    WORD        dirs;
    DIR         dir;
    FATFS       fatfs, * _fatfs;
    FILINFO     fileInfo;

    _fatfs = &fatfs;
    used = files = dirs = 0;

    if((res = f_opendir(&dir, pathName)))
    { 
        printf("%s\n", f_printerror(res));
        return res;
    }

    for(;;)
    {
        if(((res = f_readdir(&dir, &fileInfo)) != FR_OK) || !fileInfo.fname[0]) 
            break;

        if(fileInfo.fattrib & AM_DIR) 
            dirs++;
        else 
        {
            files++; 
            used += fileInfo.fsize;
        }

        printf( "\n%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u  %s",
                (fileInfo.fattrib & AM_DIR) ? 'D' : '-',
                (fileInfo.fattrib & AM_RDO) ? 'R' : '-',
                (fileInfo.fattrib & AM_HID) ? 'H' : '-',
                (fileInfo.fattrib & AM_SYS) ? 'S' : '-',
                (fileInfo.fattrib & AM_ARC) ? 'A' : '-',
                (fileInfo.fdate >> 9) + 1980, (fileInfo.fdate >> 5) & 15, fileInfo.fdate & 31,
                (fileInfo.ftime >> 11), (fileInfo.ftime >> 5) & 63,
                fileInfo.fsize, &(fileInfo.fname [0]));
    }

    printf("\n%4u File(s), %10u bytes\n%4u Dir(s)", files, used, dirs);

    if(f_getfree((const BYTE *) "0:", &dfree, &_fatfs) == FR_OK)
        printf(", %11u Kbytes free", (DWORD) (dfree - used) * 4);   // x 4096

    printf("\n");
    return res;
}

void DiskNotInstalled()
{
    printf("SD FAT32 isn't installed please try DM command\n");
}

bool LS()
{
    FRESULT fr;             // FatFs return code
    char    path[80];
    if(DiskIsOn)
    {
        if(Argc == 1)
        {
            fr = f_getcwd(path, 80);
            if(fr == FR_OK)
                fr = f_ls(path);
        }
        else
            fr = f_ls(ARGV(1));
        if(fr)
            printf("%s\n", f_printerror(fr));
    }
    else
        DiskNotInstalled();
    return true;
}

bool DiskMount()
{
    DRESULT dr;
    FRESULT fr; // FatFs return code
    
    // SD disk init
    if(Argc == 1)
    {
        dr = disk_initialize(0);
        if(dr == RES_OK)
        {
            // Register work area to the default drive
            fr = f_mount(&FatFs, "", 0);
            if(fr == RES_OK)
            {
                printf("FAT on SD ready\n");
                DiskIsOn = true;
            }
            else
            {
                printf("%s\n", disk_errString(dr));
                disk_ioctl(0, CTRL_POWER_OFF, 0);
            }
        }
    }
    else
    {
        if(_strcmp(ARGV(1), "OFF") == 0 || _strcmp(ARGV(1), "0"))
        {
            // Unregister work area
            fr = f_mount(0, "", 0);
            disk_ioctl(0, CTRL_POWER_OFF, 0);
            printf("FAT unmounted, SD power OFF\n");
        }
    }
    return true;
}

bool Quit()
{
    return false;
}

bool Remove()
{
    FRESULT fr; // FatFs return code
    if(DiskIsOn)
    {
        if(Argc == 2)
        {
            fr = f_unlink(ARGV(1));
            if(fr)
                printf("%s\n", f_printerror(fr));
        }
        else
            printf("Wrong number of parameters. Usage: RM path | file\n");
    }
    else
        DiskNotInstalled();
    return true;
}

bool MakeDirectory()
{
    FRESULT fr; // FatFs return code
    if(DiskIsOn)
    {
        if(Argc == 2)
        {
            fr = f_mkdir(ARGV(1));
            if(fr)
                printf("%s\n", f_printerror(fr));
        }
        else
            printf("Wrong number of parameters. Usage: MD path\n");
    }
    else
        DiskNotInstalled();
    return true;
}

bool Format()
{
    FRESULT fr; // FatFs return code
    if(DiskIsOn)
    {
        disk_setCallback(diskCB);
        if(Argc == 1)
            fr = f_mkfs("", 0, 4096);
        disk_setCallback(0);
    }
    else
        DiskNotInstalled();
    return true;
}

bool ChangeDirectory()
{
    FRESULT fr; // FatFs return code
    if(DiskIsOn)
    {
        if(Argc == 2)
        {
            fr = f_chdir(ARGV(1));
            if(fr)
                printf("%s\n", f_printerror(fr));
        }
        else
            printf("Wrong number of parameters. Usage: CD path\n");
    }
    else
        DiskNotInstalled();
    return true;
}

void display(const char * header, unsigned int et, unsigned int st, unsigned int size)
{
    unsigned tx;
    if(st > et) tx = TIMEBASE - st + et;
    else tx = et - st;
    printf("%s, Elapsed time: %4ums, %5uKB/s\n", header, tx / 100000, size / (tx / 100000000) / 1024);
}

bool FileCopy()
{
    FRESULT fr;             // FatFs return code
    FIL     fsrc, fdst;     // File objects
    BYTE    buffer[512];    // File copy buffer
    UINT    br, bw;         // File read/write count
    DWORD       st, et, size;
    if(DiskIsOn)
    {
        if(Argc == 3)
        {
            // Open source file
            fr = f_open(&fsrc, ARGV(1), FA_OPEN_EXISTING | FA_READ);
            if(fr)
                printf("%s\n", f_printerror(fr));
            else
            {
                // Create destination file
                fr = f_open(&fdst, ARGV(2), FA_CREATE_ALWAYS | FA_WRITE);
                if(fr)
                    printf("%s\n", f_printerror(fr));
                else
                {
                    size = f_size(&fsrc);
                    // Copy source to destination
                    ST;
                    for(;;)
                    {
                        fr = f_read(&fsrc, buffer, sizeof buffer, &br);  // Read a chunk of source file
                        if(fr || br == 0) 
                            break; // error or eof
                        fr = f_write(&fdst, buffer, br, &bw);            // Write it to the destination file
                        if(fr || bw < br) 
                            break; // error or disk full
                    }
                    ET;
                    if(fr)
                        printf("%s\n", f_printerror(fr));
                    display("File copy", et, st, size);
                    // Close open files
                    f_close(&fsrc);
                    f_close(&fdst);
                }
            }
        }
        else
            printf("Wrong number of parameters. Usage: CP srcFilename dstFilename\n");
    }
    else
        DiskNotInstalled();
    return true;
}

bool Type()
{
    FIL     fil;        // File object
    char    line[82];   // Line buffer
    FRESULT fr;         // FatFs return code
    if(DiskIsOn)
    {
        if(Argc == 2)
        {
            fr = f_open(&fil, ARGV(1), FA_READ);
            if(fr)
                printf("%s\n", f_printerror(fr));
            else
            {
                // Read all lines and display it
                while(f_gets(line, sizeof line, &fil))
                    printf(line);
                // Close the file
                f_close(&fil);
            }
        }
        else
            printf("Wrong number of parameters. Usage: TYPE filePath\n");
    }
    else
        DiskNotInstalled();
    return true;
}

bool Help()
{
    printf("Available commands:\n");
    printf("CD     Change directory. Ex: CD path\n");
    printf("CP     File copy. Ex: CP srcFileName dstFilename\n");
    printf("DM     Disk mount. Ex: DM or for unmount: DM OFF\n");
    printf("FORMAT Disk format.\n");
    printf("HELP   This help.\n");
    printf("LS     List folder contents.\n");
    printf("MD     Make directory. Ex: MD path\n");
    printf("QUIT   Exit from the program.\n");
    printf("RM     Erase a file or a directory\n");
    printf("TYPE   Type a file contents. Ex: TYPE file\n");
    printf("\n");
    return true;
}

const command cmd[] = {
    {"CD",          ChangeDirectory},
    {"CP",          FileCopy},
    {"DM",          DiskMount},
    {"FORMAT",      Format},
    {"HELP",            Help},
    {"LS",                      LS},
    {"MD",          MakeDirectory},
    {"QUIT",        Quit},
    {"RM",          Remove},
    {"TYPE",        Type},
    {"",                        0}
};

int main(void)
{
    bool    run = true;
    int     n;
    
    Set_PLL(16, 4);                 // CORE: 25MHz * 16 = 400MHz, SCLK: 400MHz / 4 = 100MHz
    Set_Port();                     // Set the port according to project set
    Set_Uart0(115200);      // printf is redirected to UART0
    Set_TimerCounter(TIMER_0);
    Set_TimerEnable(TIMER_0, true);

    while(1)
    {
        printf("Press any key to start a new test\n");
        GetChar_Uart0();
        do
        {
            printf("\n> ");             // Prompt
            _scanf("%s", cmdLine);      // Get the command
            _str_toupper(cmdLine);      // To upper case
            _str_simplified(cmdLine);   // Remove too spaces
            Argc = _str_split(cmdLine, ' ', 8, Argv);   // Split the string in different fields
            // Scan the command list....
            n = 0;
            while(cmd[n].proc)
                if(_strcmp(cmd[n].text, ARGV(0)) == 0)
                {
                    printf("\n");
                    // Execute the command
                    run = (*cmd[n].proc)();
                    break;
                }
                else
                    n++;
            if(cmd[n].proc == 0 && _strlen(ARGV(0)) > 0)
                printf("Unknown command\n");
        }while(run);
    }
    return 0;
}

Generated on Tue Apr 7 20:07:44 2015 for BF592A Library by doxygen 1.3.1