#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
typedef struct command {
char text[8];
bool (*proc)();
}command;
FATFS FatFs;
char cmdLine[32];
char Argv[256];
int Argc;
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);
printf("\n");
return res;
}
void DiskNotInstalled()
{
printf("SD FAT32 isn't installed please try DM command\n");
}
bool LS()
{
FRESULT fr;
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;
if(Argc == 1)
{
dr = disk_initialize(0);
if(dr == RES_OK)
{
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"))
{
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;
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;
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;
if(DiskIsOn)
{
disk_setCallback(diskCB);
if(Argc == 1)
fr = f_mkfs("", 0, 4096);
disk_setCallback(0);
}
else
DiskNotInstalled();
return true;
}
bool ChangeDirectory()
{
FRESULT fr;
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;
FIL fsrc, fdst;
BYTE buffer[512];
UINT br, bw;
DWORD st, et, size;
if(DiskIsOn)
{
if(Argc == 3)
{
fr = f_open(&fsrc, ARGV(1), FA_OPEN_EXISTING | FA_READ);
if(fr)
printf("%s\n", f_printerror(fr));
else
{
fr = f_open(&fdst, ARGV(2), FA_CREATE_ALWAYS | FA_WRITE);
if(fr)
printf("%s\n", f_printerror(fr));
else
{
size = f_size(&fsrc);
ST;
for(;;)
{
fr = f_read(&fsrc, buffer, sizeof buffer, &br);
if(fr || br == 0)
break;
fr = f_write(&fdst, buffer, br, &bw);
if(fr || bw < br)
break;
}
ET;
if(fr)
printf("%s\n", f_printerror(fr));
display("File copy", et, st, size);
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;
char line[82];
FRESULT fr;
if(DiskIsOn)
{
if(Argc == 2)
{
fr = f_open(&fil, ARGV(1), FA_READ);
if(fr)
printf("%s\n", f_printerror(fr));
else
{
while(f_gets(line, sizeof line, &fil))
printf(line);
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);
Set_Port();
Set_Uart0(115200);
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> ");
_scanf("%s", cmdLine);
_str_toupper(cmdLine);
_str_simplified(cmdLine);
Argc = _str_split(cmdLine, ' ', 8, Argv);
n = 0;
while(cmd[n].proc)
if(_strcmp(cmd[n].text, ARGV(0)) == 0)
{
printf("\n");
run = (*cmd[n].proc)();
break;
}
else
n++;
if(cmd[n].proc == 0 && _strlen(ARGV(0)) > 0)
printf("Unknown command\n");
}while(run);
}
return 0;
}