]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/cmd_sd.c
Adaptions for fatfs R0.13b
[z180-stamp.git] / avr / cmd_sd.c
CommitLineData
35edb766
L
1/*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7f552300 7#include "common.h"
2d914b45 8//#include <stdlib.h>
7f552300 9
a882a089 10#include "command.h"
7f552300
L
11#include "diskio.h"
12#include "ff.h"
2d914b45 13#include "eval_arg.h"
7f552300 14#include "print-utils.h"
2d914b45 15#include "z80-if.h"
7f552300
L
16
17
7f552300 18/*
8b6edd92 19 * status <pd#> - Show socket status
7f552300
L
20 *
21 */
a882a089 22static
8b6edd92 23command_ret_t do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7f552300 24{
a882a089 25 DSTATUS res;
7f552300 26 BYTE dev;
7f552300
L
27
28 (void) cmdtp; (void) flag;
29
30 if (argc < 2)
31 return CMD_RET_USAGE;
32
2d914b45 33 dev = (BYTE) eval_arg(argv[1], NULL);
a882a089 34 res = disk_status(dev);
8b6edd92
L
35 printf_P(PSTR("Socket status: %02x\n"), res);
36
37 return CMD_RET_SUCCESS;
38}
39
40/*
41 * init <pd#> - Initialize disk
42 *
43 */
44static
45command_ret_t do_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
46{
47 DSTATUS res;
48 BYTE dev;
7f552300 49
8b6edd92
L
50 (void) cmdtp; (void) flag;
51
52 if (argc < 2)
53 return CMD_RET_USAGE;
54
2d914b45 55 dev = (BYTE) eval_arg(argv[1], NULL);
8b6edd92
L
56
57 if (disk_status(dev) & STA_NODISK) {
58 printf_P(PSTR("No Disk\n"));
59 return CMD_RET_FAILURE;
a882a089 60 }
8b6edd92
L
61
62 res = disk_initialize(dev);
a882a089 63 printf_P(PSTR("rc=%.2x\n"), res);
8b6edd92
L
64
65 if (res & (STA_NODISK | STA_NOINIT))
7f552300 66 return CMD_RET_FAILURE;
7f552300 67
7f552300
L
68 return CMD_RET_SUCCESS;
69}
70
71/*
8b6edd92 72 * info <pd#> - Show disk info
7f552300
L
73 *
74 */
a882a089 75static
8b6edd92 76command_ret_t do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7f552300 77{
8b6edd92 78 DSTATUS res;
7f552300
L
79 BYTE dev;
80
a882a089
L
81 union {
82 unsigned char uca[64];
83 unsigned long ul;
84 unsigned char uc;
85 } dat;
86
7f552300
L
87 (void) cmdtp; (void) flag;
88
89 if (argc < 2)
90 return CMD_RET_USAGE;
91
2d914b45 92 dev = (BYTE) eval_arg(argv[1], NULL);
7f552300 93
8b6edd92
L
94 res = disk_status(dev);
95 if (res & (STA_NODISK | STA_NOINIT)) {
96 printf_P(res & STA_NODISK ?
97 PSTR("No disk\n") : PSTR("Not initialized\n"));
98 return CMD_RET_FAILURE;
99 }
a882a089
L
100
101 if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.ul) == RES_OK)
102 printf_P(PSTR("Drive size: %lu sectors\n"), dat.ul);
a882a089
L
103 if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.ul) == RES_OK)
104 printf_P(PSTR("Erase block: %lu sectors\n"), dat.ul);
a882a089
L
105 if (disk_ioctl(dev, MMC_GET_TYPE, &dat.uc) == RES_OK)
106 printf_P(PSTR("Card type: %u\n"), dat.uc);
a882a089 107 if (disk_ioctl(dev, MMC_GET_CSD, dat.uca) == RES_OK)
cca42593 108 dump_ram(dat.uca, 0, 16, "CSD:");
a882a089 109 if (disk_ioctl(dev, MMC_GET_CID, dat.uca) == RES_OK)
cca42593 110 dump_ram(dat.uca, 0, 16, "CID:");
a882a089 111 if (disk_ioctl(dev, MMC_GET_OCR, dat.uca) == RES_OK)
cca42593 112 dump_ram(dat.uca, 0, 4, "OCR:");
a882a089 113 if (disk_ioctl(dev, MMC_GET_SDSTAT, dat.uca) == RES_OK)
cca42593 114 dump_ram(dat.uca, 0, 64, "SD Status:");
a882a089 115
7f552300
L
116 return CMD_RET_SUCCESS;
117}
118
a882a089 119
7f552300 120/*
a882a089 121 * dump <pd#> [<sector> [count]] - Dump sector
7f552300
L
122 *
123 */
a882a089
L
124static
125command_ret_t do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7f552300 126{
a882a089
L
127 static BYTE dev_last;
128 static DWORD sec_last;
d20e9438 129 BYTE buffer[FF_MAX_SS];
a882a089 130 char header[20];
7f552300 131
a882a089
L
132 DRESULT res;
133 BYTE dev;
134 DWORD sec;
135 UINT count;
7f552300
L
136
137 (void) cmdtp; (void) flag;
138
139 if (argc < 2)
140 return CMD_RET_USAGE;
141
2d914b45 142 dev = (BYTE) eval_arg(argv[1], NULL);
a882a089
L
143 if (dev != dev_last)
144 sec_last = 0;
145 sec = sec_last;
146 count = 1;
147
148 if ((flag & CMD_FLAG_REPEAT) == 0) {
149 /* If another parameter, it is the sector to dump. */
150 if (argc > 2)
2d914b45 151 sec = eval_arg(argv[2], NULL);
a882a089 152 if (argc > 3)
2d914b45 153 count = (UINT) eval_arg(argv[3], NULL);
a882a089 154 }
7f552300 155
a882a089
L
156 for ( ; count; count--, sec++) {
157 res = disk_read(dev, buffer, sec, 1);
7f552300 158
a882a089
L
159 if (res) {
160 printf_P(PSTR("rc=%.2x\n"), res);
161 return CMD_RET_FAILURE;
162 }
7f552300 163
a882a089 164 sprintf_P(header, PSTR("Sector: %lu"), sec);
d20e9438 165 dump_ram(buffer, 0, FF_MAX_SS, header);
a882a089
L
166 }
167 dev_last = dev;
168 sec_last = sec;
7f552300 169
a882a089
L
170 return CMD_RET_SUCCESS;
171}
7f552300 172
a882a089
L
173/*
174 * read drive sector count memaddr - Read disk into memory
175 *
176 */
177static
178command_ret_t do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
179{
180 DRESULT res;
181 BYTE dev;
182 DWORD sec;
183 uint32_t addr;
184 int count, nr;
d20e9438 185 BYTE buffer[FF_MAX_SS];
7f552300 186
a882a089
L
187 static DWORD sec_last;
188 static uint32_t addr_last;
7f552300 189
a882a089 190 (void) cmdtp;
7f552300 191
a882a089
L
192 if (argc < 2)
193 return CMD_RET_USAGE;
7f552300 194
2d914b45 195 dev = (BYTE) eval_arg(argv[1], NULL);
a882a089
L
196 sec = sec_last;
197 count = 1;
198 addr = addr_last;
199
200 if ((flag & CMD_FLAG_REPEAT) == 0) {
201 /* If another parameter, it is the sector to dump. */
202 if (argc > 2)
2d914b45 203 sec = eval_arg(argv[2], NULL);
a882a089 204 if (argc > 3)
2d914b45 205 count = eval_arg(argv[3], NULL);
a882a089 206 if (argc > 4)
2d914b45 207 addr = eval_arg(argv[4], NULL);
7f552300 208 }
a882a089
L
209
210 for (nr = 0; nr < count;) {
211 nr++;
212 if ((res = disk_read(dev, buffer, sec, 1)) == RES_OK) {
213 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
214 my_puts_P(PSTR("Bus timeout\n"));
215 return CMD_RET_FAILURE;
216 }
d20e9438 217 z80_write_block(buffer, addr /*+ base*/, FF_MAX_SS);
a882a089 218 z80_bus_cmd(Release);
d20e9438 219 sec++; addr += FF_MAX_SS;
a882a089
L
220 } else
221 break;
7f552300
L
222 }
223
a882a089
L
224 printf_P(PSTR("Read %d sector(s), rc=%.2x.\n"), nr, res);
225 if (res)
226 printf_P(PSTR("Last sector not written!\n"));
227
228 sec_last = sec;
229 addr_last = addr;
7f552300 230
a882a089
L
231 return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
232}
7f552300
L
233
234
235/*
a882a089 236 * write <pd#> <sector> <memaddr> [<n>] - Write memory to disk
7f552300
L
237 *
238 */
a882a089
L
239static
240command_ret_t do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7f552300 241{
a882a089 242 DRESULT res;
7f552300 243 BYTE dev;
a882a089
L
244 DWORD sec;
245 uint32_t addr;
246 int count, nr;
d20e9438 247 BYTE buffer[FF_MAX_SS];
7f552300 248
a882a089
L
249 static DWORD sec_last;
250 static uint32_t addr_last;
251
252 (void) cmdtp;
7f552300
L
253
254 if (argc < 2)
255 return CMD_RET_USAGE;
256
2d914b45 257 dev = (BYTE) eval_arg(argv[1], NULL);
a882a089
L
258 sec = sec_last;
259 addr = addr_last;
260 count = 1;
261
262 if ((flag & CMD_FLAG_REPEAT) == 0) {
263 /* If another parameter, it is the sector to dump. */
264 if (argc > 2)
2d914b45 265 sec = eval_arg(argv[2], NULL);
a882a089 266 if (argc > 3)
2d914b45 267 count = eval_arg(argv[3], NULL);
a882a089 268 if (argc > 4)
2d914b45 269 addr = eval_arg(argv[4], NULL);
a882a089 270 }
7f552300 271
a882a089
L
272 for (nr = 0; nr < count;) {
273 nr++;
274 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
275 my_puts_P(PSTR("Bus timeout\n"));
276 return CMD_RET_FAILURE;
277 }
d20e9438 278 z80_read_block(buffer, addr /*+ base*/, FF_MAX_SS);
a882a089
L
279 z80_bus_cmd(Release);
280
281 res = disk_write(dev, buffer, sec, 1);
282 if (res != RES_OK)
283 break;
d20e9438 284 sec++; addr += FF_MAX_SS;
a882a089
L
285 }
286
287 printf_P(PSTR("%d sector(s) written, rc=%.2x.\n"), nr, res);
288
289 sec_last = sec;
290 addr_last = addr;
291
292 return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
7f552300
L
293}
294
295
296
a882a089
L
297/*
298 * Disk ioctl
8b6edd92 299 * sync <pd#> - CTRL_SYNC
a882a089
L
300 *
301 */
302static
303command_ret_t do_ioctl_sync(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7f552300 304{
a882a089 305 BYTE dev;
7f552300 306
a882a089 307 (void) cmdtp; (void) flag;
7f552300 308
a882a089
L
309 if (argc < 2)
310 return CMD_RET_USAGE;
7f552300 311
2d914b45 312 dev = (BYTE) eval_arg(argv[1], NULL);
a882a089 313 printf_P(PSTR("rc=%.2x\n"), disk_ioctl(dev, CTRL_SYNC, 0));
7f552300
L
314
315 return CMD_RET_SUCCESS;
316}
317
7f552300
L
318
319static
320command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
321
322cmd_tbl_t cmd_sd_sub[] = {
8b6edd92
L
323CMD_TBL_ITEM(
324 status, 2, 1, do_status,
325 "Socket staus",
2d914b45 326 "drive"
8b6edd92 327),
7f552300 328CMD_TBL_ITEM(
a882a089 329 init, 2, 1, do_init,
7f552300 330 "Initialize disk",
2d914b45 331 "drive"
7f552300
L
332),
333CMD_TBL_ITEM(
8b6edd92
L
334 info, 2, 1, do_info,
335 "Disk info",
2d914b45 336 "drive"
7f552300
L
337),
338CMD_TBL_ITEM(
a882a089 339 dump, CONFIG_SYS_MAXARGS, 1, do_dump,
15e476bc 340 "Dump sector(s)",
2d914b45 341 "drive [sector [count ]]"
7f552300
L
342),
343CMD_TBL_ITEM(
a882a089 344 read, 2, 1, do_read,
8b6edd92 345 "Read disk sector(s) into meomory",
2d914b45 346 "drive [sector [count [memaddr]]]"
a882a089
L
347),
348CMD_TBL_ITEM(
349 write, 2, 1, do_write,
8b6edd92 350 "Write sector(s) from meomory to disk",
2d914b45 351 "drive [sector [count [memaddr]]]"
7f552300
L
352),
353CMD_TBL_ITEM(
a882a089
L
354 sync, 2, 1, do_ioctl_sync,
355 "Device control: SYNC",
2d914b45 356 "drive"
7f552300 357),
a882a089 358
7f552300
L
359CMD_TBL_ITEM(
360 help, CONFIG_SYS_MAXARGS, 1, do_help,
8b6edd92 361 "Print sub command description/usage",
7f552300
L
362 "\n"
363 " - print brief description of all sub commands\n"
364 "sd help command ...\n"
365 " - print detailed usage of sub cmd 'command'"
366),
367
368/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
369 {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help,
8b6edd92 370 FSTR("Alias for 'help'"),
7f552300
L
371#ifdef CONFIG_SYS_LONGHELP
372 FSTR(""),
373#endif /* CONFIG_SYS_LONGHELP */
374#ifdef CONFIG_AUTO_COMPLETE
375 0,
376#endif
377},
378};
379
380static
381command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
382{
383 return _do_help(cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub), cmdtp, flag, argc, argv);
384}
385
386
387command_ret_t do_sd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
388{
389 cmd_tbl_t *cp;
390
391 if (argc < 2)
392 return CMD_RET_USAGE;
393
394 /* drop initial "sd" arg */
395 argc--;
396 argv++;
397
398 cp = find_cmd_tbl(argv[0], cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub));
399
400 if (cp)
401 return cp->cmd(cmdtp, flag, argc, argv);
402
403 return CMD_RET_USAGE;
404}