diff --git a/lpc111x-isp/lpc111x.c b/lpc111x-isp/lpc111x.c index b836996..3f28ba5 100644 --- a/lpc111x-isp/lpc111x.c +++ b/lpc111x-isp/lpc111x.c @@ -31,14 +31,10 @@ #define HOST_RX TGT_TX #define HOST_TX TGT_RX +#define MAX_BUF 10000 #define AUTOBAUD_TRIES 10 #define SYNC "Synchronized" -#define TRACE_ECHO (verbose > 3) -#define TRACE_PROGRESS (verbose > 2) -#define TRACE_RETRY (verbose > 1) -#define TRACE_FATAL (verbose > 0) - static int verbose = 0; static int quiet = 0; @@ -56,14 +52,13 @@ static void trace(const char *label, const uint8_t *s, int len) if (*s >= ' ' && *s <= '~') printf("%c", *s); else if (*s == 10) - printf(s+1 == end ? "\n" : "\\n"); + printf("\\n"); else if (*s == 13) - ; + printf("\\r"); else printf("\\%02o", *s); } - if (len && end[-1] != '\n') - printf("...\n"); + printf("\n"); } @@ -82,102 +77,109 @@ static void trace_in(const void *s, int len) /* ----- Dialog functions -------------------------------------------------- */ -static int dialog_fixed(void *buf, int buf_len, int idle, const char *msg) +static const char *dialog_fixed(int idle, const char *msg) { + static char *res = NULL; int msg_len = strlen(msg); char *tx_buf = alloca(msg_len+3); - uint8_t *rx_buf = alloca(msg_len+2+buf_len); + char *rx_buf = alloca(MAX_BUF); + char *s, *t; int got; memcpy(tx_buf, msg, msg_len); memcpy(tx_buf+msg_len, "\r\n", 2); - if (TRACE_PROGRESS) + if (verbose) trace_out(tx_buf, msg_len+2); - got = swuart_trx(tx_buf, msg_len+2, rx_buf, msg_len+2+buf_len, - idle, idle); + got = swuart_trx(tx_buf, msg_len+2, rx_buf, MAX_BUF, idle, idle); + if (verbose) + trace_in(rx_buf, got); if (got < msg_len+2) { - if (TRACE_FATAL) - trace_in(rx_buf, got); fprintf(stderr, "response too short for echo\n"); exit(1); } if (memcmp(rx_buf, msg, msg_len) || rx_buf[msg_len] != '\r' || rx_buf[msg_len+1] != '\n') { - if (TRACE_FATAL) - trace_in(rx_buf, got); fprintf(stderr, "echo mismatch\n"); exit(1); } - if (TRACE_ECHO) - trace_in(rx_buf, msg_len+2); + if (memchr(rx_buf, 0, got)) { + fprintf(stderr, "NUL in response\n"); + exit(1); + } + rx_buf += msg_len+2; got -= msg_len+2; - memcpy(buf, rx_buf+msg_len+2, got); - return got; + res = realloc(res, got+1); + if (!res) { + perror("realloc"); + exit(1); + } + + t = res; + for (s = rx_buf; s != rx_buf+got; s++) { + if (*s == '\r') { + if (s+1 != rx_buf+got && s[1] == '\n') + continue; + fprintf(stderr, "\\r without \\n\n"); + exit(1); + } + if (*s == '\n' && !s[1]) + break; + *t++ = *s; + } + *t = 0; + + return res; } -static int vdialog(void *buf, int buf_len, int idle, - const char *cmd, va_list ap) +static const char *vdialog(int idle, const char *cmd, va_list ap) { char *msg; vasprintf(&msg, cmd, ap); - return dialog_fixed(buf, buf_len, idle, msg); + return dialog_fixed(idle, msg); } -static int dialog(void *buf, int buf_len, int idle, const char *cmd, ...) +static const char *dialog(int idle, const char *cmd, ...) { va_list ap; - int res; + const char *res; va_start(ap, cmd); - res = vdialog(buf, buf_len, idle, cmd, ap); + res = vdialog(idle, cmd, ap); va_end(ap); return res; } -static unsigned dialog_rc(char *buf, int buf_len, int idle, - const char *cmd, ...) +static const char *dialog_rc(int idle, const char *cmd, ...) { - char *rx_buf = alloca(buf_len+4); va_list ap; - const char *p, *end; - int got; + const char *res, *p; unsigned rc; va_start(ap, cmd); - got = vdialog(rx_buf, buf_len+4, idle, cmd, ap); + res = vdialog(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); + p = strchr(res, '\n'); + if (!p || sscanf(res, "%u", &rc) != 1) { 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; + if (rc != 0) { + fprintf(stderr, "rc %d\n", rc); + exit(1); } - *buf = 0; - - return rc; + return p+1; } @@ -185,6 +187,7 @@ static int autobaud(void) { uint8_t reply[100]; int i, got; + const char *res; for (i = 0; i != AUTOBAUD_TRIES; i++) { CLR(TGT_nRESET); @@ -194,24 +197,13 @@ static int autobaud(void) usleep(5*1000); /* UM 26.3.1 pg 408 says max 3 ms */ got = swuart_trx("?", 1, reply, sizeof(reply), 1000, 100); - - if (got != strlen(SYNC)+2 || memcmp(reply, SYNC "\r\n", got)) { - if (TRACE_RETRY) - trace_in(reply, got); + if (got != strlen(SYNC)+2 || memcmp(reply, SYNC "\r\n", got)) continue; - } - if (TRACE_PROGRESS) - trace_in(reply, got); - got = dialog(reply, sizeof(reply), 100, SYNC); + res = dialog(100, SYNC); - if (got == 4 && !memcmp(reply, "OK\r\n", 4)) { - if (TRACE_PROGRESS) - trace_in(reply, got); + if (!strcmp(res, "OK")) return 1; - } - if (TRACE_RETRY) - trace_in(reply, got); } return 0; } @@ -232,16 +224,12 @@ static const struct device { static void identify(void) { - char reply[1000]; - unsigned rc, id; + const char *res; + unsigned 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); + res = dialog_rc(100, "J"); + if (sscanf(res, "%u", &id) != 1) { + fprintf(stderr, "J: cannot parse ID \"%s\"\n", res); exit(1); } @@ -270,8 +258,7 @@ static void at_exit(void) static void start_isp(void) { - uint8_t reply[1000]; - int got; + const char *res; if (ubb_open(0) < 0) { perror("ubb_open"); @@ -296,15 +283,11 @@ static void start_isp(void) exit(1); } - got = dialog(reply, sizeof(reply), 100, "12000"); - if (got != 4 || memcmp(reply, "OK\r\n", 4)) { - if (TRACE_FATAL) - trace_in(reply, got); + res = dialog(100, "12000"); + if (strcmp(res, "OK")) { fprintf(stderr, "cannot set clock rate\n"); exit(1); } - if (TRACE_PROGRESS) - trace_in(reply, got); } @@ -316,7 +299,7 @@ static void usage(const char *name) fprintf(stderr, "usage: %s [-q] [-v ...]\n\n" " -q suppress basic progress messages\n" -" -v increase verbosity level (nothing; errors; retry; progress; echo)\n" +" -v increase verbosity level\n" , name); exit(1); }