diff --git a/lpc111x-isp/lpc111x.c b/lpc111x-isp/lpc111x.c index 9173639..b836996 100644 --- a/lpc111x-isp/lpc111x.c +++ b/lpc111x-isp/lpc111x.c @@ -40,6 +40,7 @@ #define TRACE_FATAL (verbose > 0) static int verbose = 0; +static int quiet = 0; /* ----- Debugging and tracing --------------------------------------------- */ @@ -72,7 +73,7 @@ static void trace_out(const void *s, int len) } -static void trace_in(const uint8_t *s, int len) +static void trace_in(const void *s, int len) { trace("<<<", s, len); } @@ -142,6 +143,44 @@ static int dialog(void *buf, int buf_len, int idle, const char *cmd, ...) } +static unsigned dialog_rc(char *buf, int buf_len, int idle, + const char *cmd, ...) +{ + char *rx_buf = alloca(buf_len+4); + va_list ap; + const char *p, *end; + int got; + unsigned rc; + + va_start(ap, cmd); + got = vdialog(rx_buf, buf_len+4, idle, cmd, ap); + va_end(ap); + + p = memchr(rx_buf, '\r', buf_len+4); + if (!p || p-rx_buf == got || p[1] != '\n' || + sscanf(rx_buf, "%u", &rc) != 1) { + if (!TRACE_PROGRESS) + trace_in(rx_buf, got); + fprintf(stderr, "invalid status\n"); + exit(1); + } + + /* @@@ check that the tail really fits */ + + for (end = rx_buf+got; p != end; p++) { + if (*p == '\r') + continue; + if (*p == '\n' && p+1 == end) + break; + *buf++ = *p; + } + + *buf = 0; + + return rc; +} + + static int autobaud(void) { uint8_t reply[100]; @@ -178,6 +217,48 @@ static int autobaud(void) } +/* ----- Devices database -------------------------------------------------- */ + + +static const struct device { + const char *name; + unsigned id; + int flash_kb; +} devices[] = { + { "LPC1112FHxxx/202", 0x2524902b, 16 }, + { NULL, } +}, *device = NULL; + + +static void identify(void) +{ + char reply[1000]; + unsigned rc, id; + + rc = dialog_rc(reply, sizeof(reply), 100, "J"); + if (rc) { + fprintf(stderr, "J: rc %u\n", rc); + exit(1); + } + if (sscanf(reply, "%u", &id) != 1) { + fprintf(stderr, "J: cannot parse ID \"%s\"\n", reply); + exit(1); + } + + for (device = devices; device->name; device++) + if (device->id == id) { + if (!quiet) + fprintf(stderr, "%s (0x%04x %04x) %d kB\n", + device->name, id >> 16, id & 0xffff, + device->flash_kb); + return; + } + + fprintf(stderr, "unknown device 0x%04x %04x\n", id >> 16, id & 0xffff); + exit(1); +} + + /* ----- ISP session ------------------------------------------------------- */ @@ -233,7 +314,8 @@ static void start_isp(void) static void usage(const char *name) { fprintf(stderr, -"usage: %s [-v ...]\n\n" +"usage: %s [-q] [-v ...]\n\n" +" -q suppress basic progress messages\n" " -v increase verbosity level (nothing; errors; retry; progress; echo)\n" , name); exit(1); @@ -242,11 +324,13 @@ static void usage(const char *name) int main(int argc, char **argv) { - uint8_t reply[1000]; - int c, got; + int c; - while ((c = getopt(argc, argv, "v")) != EOF) + while ((c = getopt(argc, argv, "qv")) != EOF) switch (c) { + case 'q': + quiet = 1; + break; case 'v': verbose++; break; @@ -263,8 +347,7 @@ int main(int argc, char **argv) start_isp(); - got = dialog(reply, sizeof(reply), 100, "J"); - trace_in(reply, got); + identify(); return 0; }