From: Leo C Date: Tue, 25 Nov 2014 09:57:14 +0000 (+0100) Subject: Sd card commands: read sector, write sector X-Git-Tag: hexrel-4~17 X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/commitdiff_plain/a882a089ae73d71acf57f92096e36313ede5b9c5 Sd card commands: read sector, write sector --- diff --git a/avr/cmd_sd.c b/avr/cmd_sd.c index 55acf2f..a0c6f52 100644 --- a/avr/cmd_sd.c +++ b/avr/cmd_sd.c @@ -1,9 +1,10 @@ #include "common.h" #include +#include "command.h" #include "diskio.h" #include "ff.h" -#include "command.h" +#include "z80-if.h" #include "print-utils.h" @@ -37,27 +38,22 @@ void put_rc (FRESULT rc) #else printf_P(PSTR("rc=%u FR_"), rc); my_puts_P(rc_names[rc]); - printf_P(PSTR("\n")); + my_puts_P(PSTR("\n")); #endif } -#define BUFF_SIZE 1024 -BYTE Buff[BUFF_SIZE]; /* Working buffer */ - -static DWORD last_sect; - /* - * dd [] - Dump sector + * di - Initialize disk * */ -command_ret_t do_dd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static +command_ret_t do_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - FRESULT res; + DSTATUS res; BYTE dev; - unsigned long sec; (void) cmdtp; (void) flag; @@ -65,182 +61,310 @@ command_ret_t do_dd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_USAGE; dev = (BYTE) strtoul(argv[1], 0, 10); + res = disk_status(dev); + printf_P(PSTR("disk_status=%.2x\n"), res); - if (argc > 2) - sec = strtoul(argv[2], 0, 10); - else - sec = last_sect; - - res = disk_read(dev, Buff, sec, 1); - + if ((res & STA_NODISK) == 0) { + res = disk_initialize(dev); + } + printf_P(PSTR("rc=%.2x\n"), res); if (res) { - printf_P(PSTR("rc=%.2x\n"), res); return CMD_RET_FAILURE; } - last_sect = sec + 1; - printf_P(PSTR("Sector:%lu\n"), sec); - dump_ram((uint32_t) (size_t) Buff, 0, 0x200, NULL); - return CMD_RET_SUCCESS; } /* - * di - Initialize disk + * ds - Show disk status * */ -command_ret_t do_di(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static +command_ret_t do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - FRESULT res; BYTE dev; + union { + unsigned char uca[64]; + unsigned long ul; + unsigned char uc; + } dat; + (void) cmdtp; (void) flag; if (argc < 2) return CMD_RET_USAGE; dev = (BYTE) strtoul(argv[1], 0, 10); - res = disk_status(dev); - printf_P(PSTR("disk_status=%.2x\n"), res); - if ((res & STA_NODISK) == 0) { - res = disk_initialize(dev); + + if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.ul) == RES_OK) + printf_P(PSTR("Drive size: %lu sectors\n"), dat.ul); + + if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.ul) == RES_OK) + printf_P(PSTR("Erase block: %lu sectors\n"), dat.ul); + + if (disk_ioctl(dev, MMC_GET_TYPE, &dat.uc) == RES_OK) + printf_P(PSTR("Card type: %u\n"), dat.uc); + + if (disk_ioctl(dev, MMC_GET_CSD, dat.uca) == RES_OK) + dump_ram((uint32_t) (size_t) dat.uca, 0, 16, "CSD:"); + + if (disk_ioctl(dev, MMC_GET_CID, dat.uca) == RES_OK) + dump_ram((uint32_t) (size_t) dat.uca, 0, 16, "CID:"); + + if (disk_ioctl(dev, MMC_GET_OCR, dat.uca) == RES_OK) + dump_ram((uint32_t) (size_t) dat.uca, 0, 4, "OCR:"); + + if (disk_ioctl(dev, MMC_GET_SDSTAT, dat.uca) == RES_OK) + dump_ram((uint32_t) (size_t) dat.uca, 0, 64, "SD Status:"); + + if (disk_ioctl(dev, ATA_GET_MODEL, dat.uca) == RES_OK) { + dat.uca[40] = '\0'; + printf_P(PSTR("Model: %s\n"), dat.uca); } - printf_P(PSTR("rc=%.2x\n"), res); - if (res) { - return CMD_RET_FAILURE; + if (disk_ioctl(dev, ATA_GET_SN, dat.uca) == RES_OK) { + dat.uca[20] = '\0'; printf_P(PSTR("S/N: %s\n"), dat.uca); } return CMD_RET_SUCCESS; } + /* - * ds - Show disk status + * dump [ [count]] - Dump sector * */ -command_ret_t do_ds(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static +command_ret_t do_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - BYTE dev; + static BYTE dev_last; + static DWORD sec_last; + BYTE buffer[_MAX_SS]; + char header[20]; - union { - unsigned long lval; - unsigned char cval; - } dat; + DRESULT res; + BYTE dev; + DWORD sec; + UINT count; (void) cmdtp; (void) flag; if (argc < 2) return CMD_RET_USAGE; - dev = (BYTE) strtoul(argv[1], 0, 10); + dev = (BYTE) strtoul(argv[1], NULL, 10); + if (dev != dev_last) + sec_last = 0; + sec = sec_last; + count = 1; + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* If another parameter, it is the sector to dump. */ + if (argc > 2) + sec = strtoul(argv[2], 0, 10); + if (argc > 3) + count = (UINT) strtoul(argv[3], 0, 10); + } + for ( ; count; count--, sec++) { + res = disk_read(dev, buffer, sec, 1); - if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.lval) == RES_OK) - printf_P(PSTR("Drive size: %lu sectors\n"), dat.lval); + if (res) { + printf_P(PSTR("rc=%.2x\n"), res); + return CMD_RET_FAILURE; + } - if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.lval) == RES_OK) - printf_P(PSTR("Erase block: %lu sectors\n"), dat.lval); + sprintf_P(header, PSTR("Sector: %lu"), sec); + dump_ram((uint32_t) (size_t) buffer, 0, _MAX_SS, header); + } + dev_last = dev; + sec_last = sec; - if (disk_ioctl(dev, MMC_GET_TYPE, &dat.cval) == RES_OK) - printf_P(PSTR("Card type: %u\n"), dat.cval); + return CMD_RET_SUCCESS; +} - if (disk_ioctl(dev, MMC_GET_CSD, Buff) == RES_OK) - dump_ram((uint32_t) (size_t) Buff, 0, 16, "CSD:"); +/* + * read drive sector count memaddr - Read disk into memory + * + */ +static +command_ret_t do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + DRESULT res; + BYTE dev; + DWORD sec; + uint32_t addr; + int count, nr; + BYTE buffer[_MAX_SS]; - if (disk_ioctl(dev, MMC_GET_CID, Buff) == RES_OK) - dump_ram((uint32_t) (size_t) Buff, 0, 16, "CID:"); + static DWORD sec_last; + static uint32_t addr_last; - if (disk_ioctl(dev, MMC_GET_OCR, Buff) == RES_OK) - dump_ram((uint32_t) (size_t) Buff, 0, 4, "OCR:"); + (void) cmdtp; - if (disk_ioctl(dev, MMC_GET_SDSTAT, Buff) == RES_OK) - dump_ram((uint32_t) (size_t) Buff, 0, 64, "SD Status:"); + if (argc < 2) + return CMD_RET_USAGE; - if (disk_ioctl(dev, ATA_GET_MODEL, Buff) == RES_OK) { - Buff[40] = '\0'; - printf_P(PSTR("Model: %s\n"), Buff); + dev = (BYTE) strtoul(argv[1], NULL, 10); + sec = sec_last; + count = 1; + addr = addr_last; + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* If another parameter, it is the sector to dump. */ + if (argc > 2) + sec = strtoul(argv[2], 0, 10); + if (argc > 3) + count = strtoul(argv[3], 0, 10); + if (argc > 4) + addr = strtoul(argv[4], 0, 16); } - if (disk_ioctl(dev, ATA_GET_SN, Buff) == RES_OK) { - Buff[20] = '\0'; printf_P(PSTR("S/N: %s\n"), Buff); + + for (nr = 0; nr < count;) { + nr++; + if ((res = disk_read(dev, buffer, sec, 1)) == RES_OK) { + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return CMD_RET_FAILURE; + } + z80_write_block(buffer, addr /*+ base*/, _MAX_SS); + z80_bus_cmd(Release); + sec++; addr += _MAX_SS; + } else + break; } - return CMD_RET_SUCCESS; -} + printf_P(PSTR("Read %d sector(s), rc=%.2x.\n"), nr, res); + if (res) + printf_P(PSTR("Last sector not written!\n")); + + sec_last = sec; + addr_last = addr; + return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} /* - * Disk ioctl - * dcs - CTRL_SYNC + * write [] - Write memory to disk * */ -command_ret_t do_dcs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static +command_ret_t do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + DRESULT res; BYTE dev; + DWORD sec; + uint32_t addr; + int count, nr; + BYTE buffer[_MAX_SS]; - (void) cmdtp; (void) flag; + static DWORD sec_last; + static uint32_t addr_last; + + (void) cmdtp; if (argc < 2) return CMD_RET_USAGE; - dev = (BYTE) strtoul(argv[1], 0, 10); - printf_P(PSTR("rc=%.2x\n"), disk_ioctl(dev, CTRL_SYNC, 0)); + dev = (BYTE) strtoul(argv[1], NULL, 10); + sec = sec_last; + addr = addr_last; + count = 1; + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* If another parameter, it is the sector to dump. */ + if (argc > 2) + sec = strtoul(argv[2], 0, 10); + if (argc > 3) + count = strtoul(argv[3], 0, 10); + if (argc > 4) + addr = strtoul(argv[4], 0, 16); + } - return CMD_RET_SUCCESS; + for (nr = 0; nr < count;) { + nr++; + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return CMD_RET_FAILURE; + } + z80_read_block(buffer, addr /*+ base*/, _MAX_SS); + z80_bus_cmd(Release); + + res = disk_write(dev, buffer, sec, 1); + if (res != RES_OK) + break; + sec++; addr += _MAX_SS; + } + + printf_P(PSTR("%d sector(s) written, rc=%.2x.\n"), nr, res); + + sec_last = sec; + addr_last = addr; + + return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS; } -command_ret_t do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +/* + * Disk ioctl + * dcs - CTRL_SYNC + * + */ +static +command_ret_t do_ioctl_sync(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - (void) cmdtp; (void) flag; - (void) argc; (void) argv; + BYTE dev; - printf_P(_USE_LFN ? PSTR("LFN Enabled") : PSTR("LFN Disabled")); - printf_P(PSTR(", Code page: %u\n"), _CODE_PAGE); + (void) cmdtp; (void) flag; - for (FRESULT i=0; i<19; i++) - put_rc(i); + if (argc < 2) + return CMD_RET_USAGE; + dev = (BYTE) strtoul(argv[1], 0, 10); + printf_P(PSTR("rc=%.2x\n"), disk_ioctl(dev, CTRL_SYNC, 0)); return CMD_RET_SUCCESS; } -extern command_ret_t do_echo(cmd_tbl_t *, int, int, char * const []); - static command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); cmd_tbl_t cmd_sd_sub[] = { CMD_TBL_ITEM( - dd, CONFIG_SYS_MAXARGS, 1, do_dd, - "Dump sector", - "" -), -CMD_TBL_ITEM( - di, 2, 1, do_di, + init, 2, 1, do_init, "Initialize disk", "" ), CMD_TBL_ITEM( - ds, 2, 1, do_ds, + status, 2, 1, do_status, "Disk status", "" ), CMD_TBL_ITEM( - dcs, 2, 1, do_dcs, - "Device control: SYNC", + dump, CONFIG_SYS_MAXARGS, 1, do_dump, + "Dump sector", "" ), CMD_TBL_ITEM( - echo, CONFIG_SYS_MAXARGS, 1, do_echo, - "sane as echo (simple test)", "" + read, 2, 1, do_read, + "read disk sector(s) into meomory", + "drive [sector [count [memaddr]]]" +), +CMD_TBL_ITEM( + write, 2, 1, do_write, + "write sector(s) from meomory to disk", + "drive [sector [count [memaddr]]]" ), CMD_TBL_ITEM( - test, CONFIG_SYS_MAXARGS, 1, do_test, - "print some compiled in parameters", "" + sync, 2, 1, do_ioctl_sync, + "Device control: SYNC", + "" ), + CMD_TBL_ITEM( help, CONFIG_SYS_MAXARGS, 1, do_help, "print sub command description/usage",