]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_sd.c
Merge branch 'master' into cmdline_edit
[z180-stamp.git] / avr / cmd_sd.c
1 /*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include "common.h"
8 #include <stdlib.h>
9
10 #include "command.h"
11 #include "diskio.h"
12 #include "ff.h"
13 #include "z80-if.h"
14 #include "print-utils.h"
15
16
17 /*
18 * status <pd#> - Show socket status
19 *
20 */
21 static
22 command_ret_t do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
23 {
24 DSTATUS res;
25 BYTE dev;
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);
33 res = disk_status(dev);
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 */
43 static
44 command_ret_t do_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
45 {
46 DSTATUS res;
47 BYTE dev;
48
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;
59 }
60
61 res = disk_initialize(dev);
62 printf_P(PSTR("rc=%.2x\n"), res);
63
64 if (res & (STA_NODISK | STA_NOINIT))
65 return CMD_RET_FAILURE;
66
67 return CMD_RET_SUCCESS;
68 }
69
70 /*
71 * info <pd#> - Show disk info
72 *
73 */
74 static
75 command_ret_t do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
76 {
77 DSTATUS res;
78 BYTE dev;
79
80 union {
81 unsigned char uca[64];
82 unsigned long ul;
83 unsigned char uc;
84 } dat;
85
86 (void) cmdtp; (void) flag;
87
88 if (argc < 2)
89 return CMD_RET_USAGE;
90
91 dev = (BYTE) strtoul(argv[1], 0, 10);
92
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 }
99
100 if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.ul) == RES_OK)
101 printf_P(PSTR("Drive size: %lu sectors\n"), dat.ul);
102 if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.ul) == RES_OK)
103 printf_P(PSTR("Erase block: %lu sectors\n"), dat.ul);
104 if (disk_ioctl(dev, MMC_GET_TYPE, &dat.uc) == RES_OK)
105 printf_P(PSTR("Card type: %u\n"), dat.uc);
106 if (disk_ioctl(dev, MMC_GET_CSD, dat.uca) == RES_OK)
107 dump_ram(dat.uca, 0, 16, "CSD:");
108 if (disk_ioctl(dev, MMC_GET_CID, dat.uca) == RES_OK)
109 dump_ram(dat.uca, 0, 16, "CID:");
110 if (disk_ioctl(dev, MMC_GET_OCR, dat.uca) == RES_OK)
111 dump_ram(dat.uca, 0, 4, "OCR:");
112 if (disk_ioctl(dev, MMC_GET_SDSTAT, dat.uca) == RES_OK)
113 dump_ram(dat.uca, 0, 64, "SD Status:");
114
115 return CMD_RET_SUCCESS;
116 }
117
118
119 /*
120 * dump <pd#> [<sector> [count]] - Dump sector
121 *
122 */
123 static
124 command_ret_t do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
125 {
126 static BYTE dev_last;
127 static DWORD sec_last;
128 BYTE buffer[_MAX_SS];
129 char header[20];
130
131 DRESULT res;
132 BYTE dev;
133 DWORD sec;
134 UINT count;
135
136 (void) cmdtp; (void) flag;
137
138 if (argc < 2)
139 return CMD_RET_USAGE;
140
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 }
154
155 for ( ; count; count--, sec++) {
156 res = disk_read(dev, buffer, sec, 1);
157
158 if (res) {
159 printf_P(PSTR("rc=%.2x\n"), res);
160 return CMD_RET_FAILURE;
161 }
162
163 sprintf_P(header, PSTR("Sector: %lu"), sec);
164 dump_ram(buffer, 0, _MAX_SS, header);
165 }
166 dev_last = dev;
167 sec_last = sec;
168
169 return CMD_RET_SUCCESS;
170 }
171
172 /*
173 * read drive sector count memaddr - Read disk into memory
174 *
175 */
176 static
177 command_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];
185
186 static DWORD sec_last;
187 static uint32_t addr_last;
188
189 (void) cmdtp;
190
191 if (argc < 2)
192 return CMD_RET_USAGE;
193
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);
207 }
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;
221 }
222
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;
229
230 return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
231 }
232
233
234 /*
235 * write <pd#> <sector> <memaddr> [<n>] - Write memory to disk
236 *
237 */
238 static
239 command_ret_t do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
240 {
241 DRESULT res;
242 BYTE dev;
243 DWORD sec;
244 uint32_t addr;
245 int count, nr;
246 BYTE buffer[_MAX_SS];
247
248 static DWORD sec_last;
249 static uint32_t addr_last;
250
251 (void) cmdtp;
252
253 if (argc < 2)
254 return CMD_RET_USAGE;
255
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 }
270
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;
292 }
293
294
295
296 /*
297 * Disk ioctl
298 * sync <pd#> - CTRL_SYNC
299 *
300 */
301 static
302 command_ret_t do_ioctl_sync(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
303 {
304 BYTE dev;
305
306 (void) cmdtp; (void) flag;
307
308 if (argc < 2)
309 return CMD_RET_USAGE;
310
311 dev = (BYTE) strtoul(argv[1], 0, 10);
312 printf_P(PSTR("rc=%.2x\n"), disk_ioctl(dev, CTRL_SYNC, 0));
313
314 return CMD_RET_SUCCESS;
315 }
316
317
318 static
319 command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
320
321 cmd_tbl_t cmd_sd_sub[] = {
322 CMD_TBL_ITEM(
323 status, 2, 1, do_status,
324 "Socket staus",
325 ""
326 ),
327 CMD_TBL_ITEM(
328 init, 2, 1, do_init,
329 "Initialize disk",
330 ""
331 ),
332 CMD_TBL_ITEM(
333 info, 2, 1, do_info,
334 "Disk info",
335 ""
336 ),
337 CMD_TBL_ITEM(
338 dump, CONFIG_SYS_MAXARGS, 1, do_dump,
339 "Dump sector(s)",
340 "<drive> [sector [count ]]"
341 ),
342 CMD_TBL_ITEM(
343 read, 2, 1, do_read,
344 "Read disk sector(s) into meomory",
345 "<drive> [sector [count [memaddr]]]"
346 ),
347 CMD_TBL_ITEM(
348 write, 2, 1, do_write,
349 "Write sector(s) from meomory to disk",
350 "<drive> [sector [count [memaddr]]]"
351 ),
352 CMD_TBL_ITEM(
353 sync, 2, 1, do_ioctl_sync,
354 "Device control: SYNC",
355 ""
356 ),
357
358 CMD_TBL_ITEM(
359 help, CONFIG_SYS_MAXARGS, 1, do_help,
360 "Print sub command description/usage",
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,
369 FSTR("Alias for 'help'"),
370 #ifdef CONFIG_SYS_LONGHELP
371 FSTR(""),
372 #endif /* CONFIG_SYS_LONGHELP */
373 #ifdef CONFIG_AUTO_COMPLETE
374 0,
375 #endif
376 },
377 };
378
379 static
380 command_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
386 command_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 }