1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-11-23 23:20:38 +02:00

lpc111x-isp/lpc111x.c: flesh out device identification

This commit is contained in:
Werner Almesberger 2012-12-29 06:27:04 -03:00
parent 0553fed424
commit 90d39d3fdd

View File

@ -40,6 +40,7 @@
#define TRACE_FATAL (verbose > 0) #define TRACE_FATAL (verbose > 0)
static int verbose = 0; static int verbose = 0;
static int quiet = 0;
/* ----- Debugging and tracing --------------------------------------------- */ /* ----- 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); 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) static int autobaud(void)
{ {
uint8_t reply[100]; 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 ------------------------------------------------------- */ /* ----- ISP session ------------------------------------------------------- */
@ -233,7 +314,8 @@ static void start_isp(void)
static void usage(const char *name) static void usage(const char *name)
{ {
fprintf(stderr, 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" " -v increase verbosity level (nothing; errors; retry; progress; echo)\n"
, name); , name);
exit(1); exit(1);
@ -242,11 +324,13 @@ static void usage(const char *name)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
uint8_t reply[1000]; int c;
int c, got;
while ((c = getopt(argc, argv, "v")) != EOF) while ((c = getopt(argc, argv, "qv")) != EOF)
switch (c) { switch (c) {
case 'q':
quiet = 1;
break;
case 'v': case 'v':
verbose++; verbose++;
break; break;
@ -263,8 +347,7 @@ int main(int argc, char **argv)
start_isp(); start_isp();
got = dialog(reply, sizeof(reply), 100, "J"); identify();
trace_in(reply, got);
return 0; return 0;
} }