]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Sd card commands: read sector, write sector
authorLeo C <erbl259-lmu@yahoo.de>
Tue, 25 Nov 2014 09:57:14 +0000 (10:57 +0100)
committerLeo C <erbl259-lmu@yahoo.de>
Tue, 25 Nov 2014 09:57:14 +0000 (10:57 +0100)
avr/cmd_sd.c

index 55acf2f89c26ac590c1f8b1825c6c441b7b5a7b6..a0c6f52b985c7e3b869488c7f1dff2b7616ac038 100644 (file)
@@ -1,9 +1,10 @@
 #include "common.h"
 #include <stdlib.h>
 
+#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 <pd#> [<sector>] - Dump sector
+ * di <pd#> - 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 <pd#> - Initialize disk
+ * ds <pd#> - 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 <pd#> - Show disk status
+ * dump <pd#> [<sector> [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 <pd#> - CTRL_SYNC
+ * write <pd#> <sector> <memaddr> [<n>] - 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 <pd#> - 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",