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

lpc111x-isp/lpc111x.c: read and dump (to stdout) the entire Flash

This commit is contained in:
Werner Almesberger 2012-12-29 22:52:33 -03:00
parent b2f131003d
commit 5246f5fbc6

View File

@ -31,7 +31,8 @@
#define HOST_RX TGT_TX #define HOST_RX TGT_TX
#define HOST_TX TGT_RX #define HOST_TX TGT_RX
#define MAX_BUF 10000 #define MAX_BUF 10000 /* receive buffer */
#define MAX_RECORD 45 /* data bytes per uuencoded record */
#define AUTOBAUD_TRIES 10 #define AUTOBAUD_TRIES 10
#define SYNC "Synchronized" #define SYNC "Synchronized"
@ -47,18 +48,18 @@ static void trace(const char *label, const uint8_t *s, int len)
const uint8_t *end = s+len; const uint8_t *end = s+len;
if (label) if (label)
printf("%s ", label); fprintf(stderr, "%s ", label);
for (end = s+len; s != end; s++) { for (end = s+len; s != end; s++) {
if (*s >= ' ' && *s <= '~') if (*s >= ' ' && *s <= '~')
printf("%c", *s); fprintf(stderr, "%c", *s);
else if (*s == 10) else if (*s == 10)
printf("\\n"); fprintf(stderr, "\\n");
else if (*s == 13) else if (*s == 13)
printf("\\r"); fprintf(stderr, "\\r");
else else
printf("\\%02o", *s); fprintf(stderr, "\\%02o", *s);
} }
printf("\n"); fprintf(stderr, "\n");
} }
@ -127,7 +128,7 @@ static const char *dialog_fixed(int idle, const char *msg)
fprintf(stderr, "\\r without \\n\n"); fprintf(stderr, "\\r without \\n\n");
exit(1); exit(1);
} }
if (*s == '\n' && !s[1]) if (*s == '\n' && s+1 == rx_buf+got)
break; break;
*t++ = *s; *t++ = *s;
} }
@ -256,6 +257,107 @@ static void identify(void)
} }
/* ----- Flash dump -------------------------------------------------------- */
/* AN11229 */
static uint8_t uudchar(char c)
{
if (c <= 0x20 && c > 0x60) {
fprintf(stderr, "invalid UU character '%c'\n", c);
exit(1);
}
return c == 0x60 ? 0 : c-32;
}
static int uudecode(const char *s, uint8_t *buf)
{
int len, uu_len;
const char *nl;
const uint8_t *end;
len = *s-32;
if (len < 0 || len > MAX_RECORD) {
fprintf(stderr, "invalid UU length (%d)\n", len);
exit(1);
}
nl = strchr(++s, '\n');
if (!nl) {
fprintf(stderr, "no \\n at end of UU record\n");
exit(1);
}
uu_len = nl-s;
if (uu_len & 3) {
fprintf(stderr, "UU length %d not a multiple of 4\n", uu_len);
exit(1);
}
if ((len+2)/3 != uu_len/4) {
fprintf(stderr, "UU length %d vs. %d bytes (\"%.*s\")\n",
uu_len, len, nl-s+1, s-1);
exit(1);
}
end = buf+len;
while (buf != end) {
unsigned tmp = uudchar(s[0]) << 18 | uudchar(s[1]) << 12 |
uudchar(s[2]) << 6 | uudchar(s[3]);
*buf++ = tmp >> 16;
if (buf != end)
*buf++ = tmp >> 8;
if (buf != end)
*buf++ = tmp;
s += 4;
}
return len;
}
static void dump(void)
{
int addr = 0, end;
unsigned sum = 0, check;
const char *res, *nl;
int got, wrote, i;
end = device->flash_kb << 10;
res = dialog_rc(100, "R 0 %u", end);
while (addr != end) {
while (1) {
uint8_t buf[MAX_RECORD];
nl = strchr(res, '\n');
if (!nl)
break;
got = uudecode(res, buf);
for (i = 0; i != got; i++)
sum += buf[i];
wrote = fwrite(buf, 1, got, stdout);
if (wrote != got) {
perror("fwrite");
exit(1);
}
addr += got;
res = nl+1;
}
if (sscanf(res, "%u", &check) != 1) {
fprintf(stderr, "can't parse checksum \"%s\"\n", res);
exit(1);
}
if (check != sum) {
fprintf(stderr, "checksum error: got %u received %u\n",
sum, check);
exit(1);
}
res = dialog(100, "OK");
sum = 0;
}
}
/* ----- ISP session ------------------------------------------------------- */ /* ----- ISP session ------------------------------------------------------- */
@ -347,5 +449,7 @@ int main(int argc, char **argv)
identify(); identify();
dump();
return 0; return 0;
} }