#include "common.h" #include #include "diskio.h" #include "ff.h" #include "command.h" #include "print-utils.h" static const FLASH char * const FLASH rc_names[] = { FSTR("OK"), FSTR("DISK_ERR"), FSTR("INT_ERR"), FSTR("NOT_READY"), FSTR("NO_FILE"), FSTR("NO_PATH"), FSTR("INVALID_NAME"), FSTR("DENIED"), FSTR("EXIST"), FSTR("INVALID_OBJECT"), FSTR("WRITE_PROTECTED"), FSTR("INVALID_DRIVE"), FSTR("NOT_ENABLED"), FSTR("NO_FILE_SYSTEM"), FSTR("MKFS_ABORTED"), FSTR("TIMEOUT"), FSTR("LOCKED"), FSTR("NOT_ENOUGH_CORE"), FSTR("TOO_MANY_OPEN_FILES") }; static void put_rc (FRESULT rc) { #if 0 printf_P(PSTR("rc=%u FR_%S\n"), rc, rc_names[rc]); #else printf_P(PSTR("rc=%u FR_"), rc); my_puts_P(rc_names[rc]); printf_P(PSTR("\n")); #endif } #define BUFF_SIZE 1024 BYTE Buff[BUFF_SIZE]; /* Working buffer */ static DWORD last_sect; /* * dd [] - Dump sector * */ command_ret_t do_dd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { FRESULT res; BYTE dev; unsigned long sec; (void) cmdtp; (void) flag; if (argc < 2) return CMD_RET_USAGE; dev = (BYTE) strtoul(argv[1], 0, 10); if (argc > 2) sec = strtoul(argv[2], 0, 10); else sec = last_sect; res = disk_read(dev, Buff, sec, 1); 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 * */ command_ret_t do_di(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { FRESULT res; BYTE dev; (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); } printf_P(PSTR("rc=%.2x\n"), res); if (res) { return CMD_RET_FAILURE; } return CMD_RET_SUCCESS; } /* * ds - Show disk status * */ command_ret_t do_ds(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { BYTE dev; union { unsigned long lval; unsigned char cval; } dat; (void) cmdtp; (void) flag; if (argc < 2) return CMD_RET_USAGE; dev = (BYTE) strtoul(argv[1], 0, 10); if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.lval) == RES_OK) printf_P(PSTR("Drive size: %lu sectors\n"), dat.lval); if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.lval) == RES_OK) printf_P(PSTR("Erase block: %lu sectors\n"), dat.lval); if (disk_ioctl(dev, MMC_GET_TYPE, &dat.cval) == RES_OK) printf_P(PSTR("Card type: %u\n"), dat.cval); if (disk_ioctl(dev, MMC_GET_CSD, Buff) == RES_OK) dump_ram((uint32_t) (size_t) Buff, 0, 16, "CSD:"); if (disk_ioctl(dev, MMC_GET_CID, Buff) == RES_OK) dump_ram((uint32_t) (size_t) Buff, 0, 16, "CID:"); if (disk_ioctl(dev, MMC_GET_OCR, Buff) == RES_OK) dump_ram((uint32_t) (size_t) Buff, 0, 4, "OCR:"); if (disk_ioctl(dev, MMC_GET_SDSTAT, Buff) == RES_OK) dump_ram((uint32_t) (size_t) Buff, 0, 64, "SD Status:"); if (disk_ioctl(dev, ATA_GET_MODEL, Buff) == RES_OK) { Buff[40] = '\0'; printf_P(PSTR("Model: %s\n"), Buff); } if (disk_ioctl(dev, ATA_GET_SN, Buff) == RES_OK) { Buff[20] = '\0'; printf_P(PSTR("S/N: %s\n"), Buff); } return CMD_RET_SUCCESS; } /* * Disk ioctl * dcs - CTRL_SYNC * */ command_ret_t do_dcs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { BYTE dev; (void) cmdtp; (void) flag; 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; } command_ret_t do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { (void) cmdtp; (void) flag; (void) argc; (void) argv; printf_P(_USE_LFN ? PSTR("LFN Enabled") : PSTR("LFN Disabled")); printf_P(PSTR(", Code page: %u\n"), _CODE_PAGE); for (FRESULT i=0; i<19; i++) put_rc(i); 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, "Initialize disk", "" ), CMD_TBL_ITEM( ds, 2, 1, do_ds, "Disk status", "" ), CMD_TBL_ITEM( dcs, 2, 1, do_dcs, "Device control: SYNC", "" ), CMD_TBL_ITEM( echo, CONFIG_SYS_MAXARGS, 1, do_echo, "sane as echo (simple test)", "" ), CMD_TBL_ITEM( test, CONFIG_SYS_MAXARGS, 1, do_test, "print some compiled in parameters", "" ), CMD_TBL_ITEM( help, CONFIG_SYS_MAXARGS, 1, do_help, "print sub command description/usage", "\n" " - print brief description of all sub commands\n" "sd help command ...\n" " - print detailed usage of sub cmd 'command'" ), /* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */ {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help, FSTR("alias for 'help'"), #ifdef CONFIG_SYS_LONGHELP FSTR(""), #endif /* CONFIG_SYS_LONGHELP */ #ifdef CONFIG_AUTO_COMPLETE 0, #endif }, }; static command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return _do_help(cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub), cmdtp, flag, argc, argv); } command_ret_t do_sd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { cmd_tbl_t *cp; if (argc < 2) return CMD_RET_USAGE; /* drop initial "sd" arg */ argc--; argv++; cp = find_cmd_tbl(argv[0], cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub)); if (cp) return cp->cmd(cmdtp, flag, argc, argv); return CMD_RET_USAGE; }