make default port name easier to configure and setup for my device on iMac
[flashkit-mdc.git] / flashkit.c
index 5d8a587..00819c4 100644 (file)
@@ -406,17 +406,23 @@ static void read_info(int fd)
 
 static uint32_t get_block_addr(uint32_t addr, uint32_t blk_offset)
 {
-       uint32_t i;
+       uint32_t i, base, faddr;
 
        assert(info.region_cnt);
+       assert(info.size);
+
+       // get a flash address to allow mapper hardware
+       faddr = addr & (info.size - 1);
+       base = addr & ~(info.size - 1);
+
        for (i = 0; i < info.region_cnt; i++) {
-               if (info.region[i].start <= addr
-                   && addr < info.region[i].start + info.region[i].size)
+               if (info.region[i].start <= faddr
+                   && faddr < info.region[i].start + info.region[i].size)
                {
-                       uint32_t blk = (addr - info.region[i].start)
+                       uint32_t blk = (faddr - info.region[i].start)
                                        / info.region[i].block_size
                                        + blk_offset;
-                       return info.region[i].start
+                       return base + info.region[i].start
                                + blk * info.region[i].block_size;
                }
        }
@@ -440,19 +446,42 @@ static void print_progress(uint32_t done, uint32_t total)
                fputc('\n', stdout);
 }
 
+static FILE *open_prep_read(const char *fname, long *size)
+{
+       FILE *f = fopen(fname, "rb");
+       if (!f) {
+               fprintf(stderr, "fopen %s: ", fname);
+               perror("");
+               exit(1);
+       }
+       if (*size <= 0) {
+               fseek(f, 0, SEEK_END);
+               *size = ftell(f);
+               fseek(f, 0, SEEK_SET);
+       }
+       if (*size <= 0) {
+               fprintf(stderr, "size of %s is %ld\n", fname, *size);
+               exit(1);
+       }
+       return f;
+}
+
+static const char *portname = "/dev/cu.usbserial-AL0254JM";
+
 static void usage(const char *argv0)
 {
        printf("usage:\n"
                "%s [options]\n"
-               "  -d <ttydevice>      (default /dev/ttyUSB0)\n"
+               "  -d <ttydevice>      (default %s)\n"
                "  -r <file> [size]    dump the cart (default 4MB)\n"
-               "  -w <file> [size]    flash the cart (file size)\n"
+               "  -w <file> [size]    program the flash (def. file size)\n"
+               "  -s <file> [size]    simple write (SRAM, etc, def. file size)\n"
                "  -e <size>           erase (rounds to block size)\n"
-               "  -a <start_address>  cart start address (default 0)\n"
+               "  -a <start_address>  read/write start address (default 0)\n"
                "  -8                  8bit flash\n"
                "  -v                  verify written data\n"
                "  -i                  get info about the flash chip\n"
-               , argv0);
+               , argv0, portname);
        exit(1);
 }
 
@@ -477,11 +506,12 @@ static uint8_t g_block2[0x10000];
 
 int main(int argc, char *argv[])
 {
-       const char *portname = "/dev/ttyUSB0";
        const char *fname_w = NULL;
        const char *fname_r = NULL;
+       const char *fname_ws = NULL;
        long size_w = 0;
        long size_r = 0;
+       long size_ws = 0;
        long size_e = 0;
        long size_v = 0;
        long len, address_in = 0;
@@ -491,6 +521,7 @@ int main(int argc, char *argv[])
        int write_step = 2;
        FILE *f_w = NULL;
        FILE *f_r = NULL;
+       FILE *f_ws = NULL;
        uint8_t id[2] = { 0, 0 };
        uint8_t cmd;
        uint16_t rv;
@@ -523,6 +554,15 @@ int main(int argc, char *argv[])
                        }
                        continue;
                }
+               if (!strcmp(argv[arg], "-s")) {
+                       fname_ws = getarg(argc, argv, ++arg);
+                       if (arg + 1 < argc && argv[arg + 1][0] != '-') {
+                               size_ws = strtol(argv[++arg], NULL, 0);
+                               if (size_ws <= 0)
+                                       invarg(argc, argv, arg);
+                       }
+                       continue;
+               }
                if (!strcmp(argv[arg], "-a")) {
                        address_in = strtol(getarg(argc, argv, ++arg), NULL, 0);
                        if (address_in < 0 || (address_in & 1))
@@ -555,22 +595,7 @@ int main(int argc, char *argv[])
                size_r = 0x400000;
 
        if (fname_w) {
-               f_w = fopen(fname_w, "rb");
-               if (!f_w) {
-                       fprintf(stderr, "fopen %s: ", fname_w);
-                       perror("");
-                       return 1;
-               }
-               if (size_w <= 0) {
-                       fseek(f_w, 0, SEEK_END);
-                       size_w = ftell(f_w);
-                       fseek(f_w, 0, SEEK_SET);
-               }
-               if (size_w <= 0) {
-                       fprintf(stderr, "size of %s is %ld\n",
-                               fname_w, size_w);
-                       return 1;
-               }
+               f_w = open_prep_read(fname_w, &size_w);
                if (size_e < size_w)
                        size_e = size_w;
                if (do_verify)
@@ -584,6 +609,9 @@ int main(int argc, char *argv[])
                return 1;
        }
 
+       if (fname_ws)
+               f_ws = open_prep_read(fname_ws, &size_ws);
+
        setup(fd);
 
        cmd = CMD_RD | PAR_SINGE | PAR_DEV_ID;
@@ -624,7 +652,7 @@ int main(int argc, char *argv[])
        if (f_w != NULL) {
                uint8_t b[2];
                set_delay(fd, 0);
-               printf("writing %ld bytes:\n", size_w);
+               printf("flashing %ld bytes:\n", size_w);
                for (a = 0; a < size_w; a += write_step) {
                        ssize_t r;
 
@@ -648,6 +676,27 @@ int main(int argc, char *argv[])
                rewind(f_w);
                set_delay(fd, 1);
        }
+       if (f_ws != NULL) {
+               printf("writing %ld bytes:\n", size_ws);
+               for (a = 0; a < size_ws; a += write_step) {
+                       uint16_t b = 0xffff;
+                       ssize_t r;
+
+                       len = min(size_ws - a, write_step);
+                       r = fread(&b, 1, len, f_ws);
+                       if (r != len) {
+                               perror("\nfread");
+                               return 1;
+                       }
+                       if (write_step == 2)
+                               b = htons(b);
+                       io->write_bus(fd, address_in + a, b);
+
+                       if (!(a & 0x3ff))
+                               print_progress(a, size_ws);
+               }
+               print_progress(a, size_ws);
+       }
 
        if (fname_r || size_v) {
                long blks, blks_v, done, verify_diff = 0;