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