]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_fat.c
2 * (C) Copyright 2014,2016 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
8 * FAT filesystem commands
19 #include "con-utils.h"
20 #include "print-utils.h"
25 /* TODO: use memory size test function (cmd_mem.c) */
26 #define MAX_MEMORY (1ul << 19)
27 #define BUFFER_SIZE 512
30 DWORD
get_fattime (void)
36 gmtime_r(&timer
, &tm_timer
);
38 return fatfs_time(&tm_timer
);
42 static bool check_abort(void)
47 printf_P(PSTR("Abort\n"));
53 static const FLASH
char * const FLASH rc_names
[] = {
63 FSTR("INVALID_OBJECT"),
64 FSTR("WRITE_PROTECTED"),
65 FSTR("INVALID_DRIVE"),
67 FSTR("NO_FILE_SYSTEM"),
71 FSTR("NOT_ENOUGH_CORE"),
72 FSTR("TOO_MANY_OPEN_FILES"),
73 FSTR("INVALID_PARAMETER")
77 void put_rc (FRESULT rc
)
80 printf_P(PSTR("rc=%u FR_"), rc
);
81 my_puts_P(rc
< ARRAY_SIZE(rc_names
) ? rc_names
[rc
] : PSTR(" Unknown Error"));
82 my_puts_P(PSTR("\n"));
84 printf_P(PSTR("rc=%u FR_%S\n"), rc
,
85 rc
< ARRAY_SIZE(rc_names
) ? rc_names
[rc
] : PSTR(" Unknown Error"));
90 static void swirl(void)
92 static const FLASH
char swirlchar
[] = { '-','\\','|','/' };
93 static uint_fast8_t cnt
;
94 static uint32_t tstamp
;
96 if (get_timer(0) > tstamp
) {
97 printf_P(PSTR("\b%c"), swirlchar
[cnt
]);
98 cnt
= (cnt
+1) % ARRAY_SIZE(swirlchar
);
99 tstamp
= get_timer(0) + 250;
103 /* Work register for fs command */
106 WORD AccFiles
, AccDirs
;
112 char *path
, /* Pointer to the working buffer with start path */
113 struct stat_dat_s
*statp
121 res
= f_opendir(&dirs
, path
);
125 while (((res
= f_readdir(&dirs
, &statp
->Finfo
)) == FR_OK
) &&
126 statp
->Finfo
.fname
[0]) {
127 if (FF_FS_RPATH
&& statp
->Finfo
.fname
[0] == '.')
129 fn
= statp
->Finfo
.fname
;
130 if (statp
->Finfo
.fattrib
& AM_DIR
) {
133 strcpy(path
+i
+1, fn
);
134 res
= scan_files(path
, statp
);
139 //printf_P(PSTR("%s/%s\n"), path, fn);
141 statp
->AccSize
+= statp
->Finfo
.fsize
;
155 * fatstat path - Show logical drive status
158 command_ret_t
do_fat_stat(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
164 struct stat_dat_s statp
;
166 (void) cmdtp
; (void) flag
; (void) argc
;
168 path
= (char *) malloc(BUFFER_SIZE
);
170 printf_P(PSTR("fatstat: Out of Memory!\n"));
172 return CMD_RET_FAILURE
;
175 res
= f_getfree(argv
[1], &nfreeclst
, &fs
);
179 "Bytes/Cluster: %lu\n"
180 "Number of FATs: %u\n"
181 "Root DIR entries: %u\n"
183 "Number of clusters: %lu\n"
184 "FAT start (lba): %lu\n"
185 "DIR start (lba,cluster): %lu\n"
186 "Data start (lba): %lu\n"),
187 fs
->fs_type
, (DWORD
)fs
->csize
* 512, fs
->n_fats
,
188 fs
->n_rootdir
, fs
->fsize
, fs
->n_fatent
- 2,
189 fs
->fatbase
, fs
->dirbase
, fs
->database
);
194 res
= f_getlabel(argv
[1], label
, &serial
);
198 "Volume S/N: %04X-%04X\n"),
199 label
, (WORD
)(serial
>> 16), (WORD
)(serial
& 0xFFFF));
203 my_puts_P(PSTR("\nCounting... "));
204 statp
.AccSize
= statp
.AccFiles
= statp
.AccDirs
= 0;
205 strcpy(path
, argv
[1]);
207 res
= scan_files(path
, &statp
);
210 printf_P(PSTR("\r%u files, %lu bytes.\n%u folders.\n"
211 "%lu KB total disk space.\n%lu KB available.\n"),
212 statp
.AccFiles
, statp
.AccSize
, statp
.AccDirs
,
213 (fs
->n_fatent
- 2) * (fs
->csize
/ 2), nfreeclst
* (fs
->csize
/ 2)
221 return CMD_RET_FAILURE
;
223 return CMD_RET_SUCCESS
;
228 * fatls path - Directory listing
231 command_ret_t
do_fat_ls(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
234 DIR Dir
; /* Directory object */
240 (void) cmdtp
; (void) flag
; (void) argc
;
242 res
= f_opendir(&Dir
, argv
[1]);
245 return CMD_RET_FAILURE
;
250 res
= f_readdir(&Dir
, &Finfo
);
251 if ((res
!= FR_OK
) || !Finfo
.fname
[0])
253 if (Finfo
.fattrib
& AM_DIR
) {
256 s1
++; p1
+= Finfo
.fsize
;
258 printf_P(PSTR("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\n"),
259 (Finfo
.fattrib
& AM_DIR
) ? 'D' : '-',
260 (Finfo
.fattrib
& AM_RDO
) ? 'R' : '-',
261 (Finfo
.fattrib
& AM_HID
) ? 'H' : '-',
262 (Finfo
.fattrib
& AM_SYS
) ? 'S' : '-',
263 (Finfo
.fattrib
& AM_ARC
) ? 'A' : '-',
264 (Finfo
.fdate
>> 9) + 1980, (Finfo
.fdate
>> 5) & 15, Finfo
.fdate
& 31,
265 (Finfo
.ftime
>> 11), (Finfo
.ftime
>> 5) & 63,
266 Finfo
.fsize
, Finfo
.fname
);
272 printf_P(PSTR("%4u File(s),%10lu bytes total\n%4u Dir(s)"), s1
, p1
, s2
);
273 if (f_getfree(argv
[1], (DWORD
*)&p1
, &fs
) == FR_OK
)
274 printf_P(PSTR(", %10luK bytes free\n"), p1
* fs
->csize
/ 2);
279 return CMD_RET_FAILURE
;
282 return CMD_RET_SUCCESS
;
286 FRESULT
mkpath(TCHAR
*path
)
295 res
= f_stat (path
, &fd
)
297 p
= strchr(path
, ':');
298 if (p
== NULL
|| *++p
== '\0' || *p
++ != '/')
301 while ((q
= strchr(p
, '/')) != NULL
) {
305 if (ret
!= FR_OK
&& ret
!= FR_EXIST
)
315 * fatread/write - load binary file to/from a dos filesystem
316 * read <d:/path/filename> <addr> [bytes [pos]]
317 * write <d:/path/filename> <addr> <bytes>
319 command_ret_t
do_fat_rw(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
325 unsigned long bytes_rw
;
327 bool dowrite
= (argv
[0][3] == 'w');
333 (void) cmdtp
; (void) flag
;
335 if (argc
< (dowrite
? 4 : 3))
336 return CMD_RET_USAGE
;
338 addr
= eval_arg(argv
[2], NULL
);
339 if (addr
>= MAX_MEMORY
) {
340 printf_P(PSTR("address too high: 0x%0lx\n"), addr
);
341 return CMD_RET_FAILURE
;
344 bytes
= eval_arg(argv
[3], NULL
);
348 pos
= eval_arg(argv
[4], NULL
);
352 if (addr
+ bytes
> MAX_MEMORY
)
353 bytes
= MAX_MEMORY
- addr
;
355 buffer
= (uint8_t *) malloc(BUFFER_SIZE
);
356 if (buffer
== NULL
) {
357 printf_P(PSTR("fatstat: Out of Memory!\n"));
359 return CMD_RET_FAILURE
;
363 res
= mkpath(argv
[1]);
366 res
= f_open(&File
, argv
[1], dowrite
? FA_WRITE
| FA_CREATE_ALWAYS
370 res
= f_lseek(&File
, pos
);
373 timer
= get_timer(0);
375 unsigned int cnt
, br
;
377 if (bytes
>= BUFFER_SIZE
) {
379 bytes
-= BUFFER_SIZE
;
381 cnt
= bytes
; bytes
= 0;
384 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
388 z80_read_block(buffer
, addr
, cnt
);
389 z80_bus_cmd(Release
);
390 res
= f_write(&File
, buffer
, cnt
, &br
);
394 res
= f_read(&File
, buffer
, cnt
, &br
);
397 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
401 z80_write_block(buffer
, addr
, br
);
402 z80_bus_cmd(Release
);
409 printf_P(PSTR("Disk full?\n"));
416 FRESULT fr
= f_close(&File
);
419 timer
= get_timer(timer
);
420 printf_P(PSTR("%lu (0x%lx) bytes read/written with %lu bytes/sec.\n"),
421 bytes_rw
, bytes_rw
, timer
? (bytes_rw
* 1000 / timer
) : 0);
429 my_puts_P(PSTR("Bus timeout\n"));
433 return CMD_RET_FAILURE
;
435 return CMD_RET_SUCCESS
;