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