lpc111x-isp/lpc111x.c |
31 | 31 | #define HOST_RX TGT_TX |
32 | 32 | #define HOST_TX TGT_RX |
33 | 33 | |
34 | | #define MAX_BUF 10000 |
| 34 | #define MAX_BUF 10000 /* receive buffer */ |
| 35 | #define MAX_RECORD 45 /* data bytes per uuencoded record */ |
35 | 36 | #define AUTOBAUD_TRIES 10 |
36 | 37 | #define SYNC "Synchronized" |
37 | 38 | |
... | ... | |
47 | 48 | const uint8_t *end = s+len; |
48 | 49 | |
49 | 50 | if (label) |
50 | | printf("%s ", label); |
| 51 | fprintf(stderr, "%s ", label); |
51 | 52 | for (end = s+len; s != end; s++) { |
52 | 53 | if (*s >= ' ' && *s <= '~') |
53 | | printf("%c", *s); |
| 54 | fprintf(stderr, "%c", *s); |
54 | 55 | else if (*s == 10) |
55 | | printf("\\n"); |
| 56 | fprintf(stderr, "\\n"); |
56 | 57 | else if (*s == 13) |
57 | | printf("\\r"); |
| 58 | fprintf(stderr, "\\r"); |
58 | 59 | else |
59 | | printf("\\%02o", *s); |
| 60 | fprintf(stderr, "\\%02o", *s); |
60 | 61 | } |
61 | | printf("\n"); |
| 62 | fprintf(stderr, "\n"); |
62 | 63 | } |
63 | 64 | |
64 | 65 | |
... | ... | |
127 | 128 | fprintf(stderr, "\\r without \\n\n"); |
128 | 129 | exit(1); |
129 | 130 | } |
130 | | if (*s == '\n' && !s[1]) |
| 131 | if (*s == '\n' && s+1 == rx_buf+got) |
131 | 132 | break; |
132 | 133 | *t++ = *s; |
133 | 134 | } |
... | ... | |
256 | 257 | } |
257 | 258 | |
258 | 259 | |
| 260 | /* ----- Flash dump -------------------------------------------------------- */ |
| 261 | |
| 262 | |
| 263 | /* AN11229 */ |
| 264 | |
| 265 | |
| 266 | static uint8_t uudchar(char c) |
| 267 | { |
| 268 | if (c <= 0x20 && c > 0x60) { |
| 269 | fprintf(stderr, "invalid UU character '%c'\n", c); |
| 270 | exit(1); |
| 271 | } |
| 272 | return c == 0x60 ? 0 : c-32; |
| 273 | } |
| 274 | |
| 275 | |
| 276 | static int uudecode(const char *s, uint8_t *buf) |
| 277 | { |
| 278 | int len, uu_len; |
| 279 | const char *nl; |
| 280 | const uint8_t *end; |
| 281 | |
| 282 | len = *s-32; |
| 283 | if (len < 0 || len > MAX_RECORD) { |
| 284 | fprintf(stderr, "invalid UU length (%d)\n", len); |
| 285 | exit(1); |
| 286 | } |
| 287 | nl = strchr(++s, '\n'); |
| 288 | if (!nl) { |
| 289 | fprintf(stderr, "no \\n at end of UU record\n"); |
| 290 | exit(1); |
| 291 | } |
| 292 | uu_len = nl-s; |
| 293 | if (uu_len & 3) { |
| 294 | fprintf(stderr, "UU length %d not a multiple of 4\n", uu_len); |
| 295 | exit(1); |
| 296 | } |
| 297 | if ((len+2)/3 != uu_len/4) { |
| 298 | fprintf(stderr, "UU length %d vs. %d bytes (\"%.*s\")\n", |
| 299 | uu_len, len, nl-s+1, s-1); |
| 300 | exit(1); |
| 301 | } |
| 302 | |
| 303 | end = buf+len; |
| 304 | while (buf != end) { |
| 305 | unsigned tmp = uudchar(s[0]) << 18 | uudchar(s[1]) << 12 | |
| 306 | uudchar(s[2]) << 6 | uudchar(s[3]); |
| 307 | |
| 308 | *buf++ = tmp >> 16; |
| 309 | if (buf != end) |
| 310 | *buf++ = tmp >> 8; |
| 311 | if (buf != end) |
| 312 | *buf++ = tmp; |
| 313 | s += 4; |
| 314 | } |
| 315 | return len; |
| 316 | } |
| 317 | |
| 318 | |
| 319 | static void dump(void) |
| 320 | { |
| 321 | int addr = 0, end; |
| 322 | unsigned sum = 0, check; |
| 323 | const char *res, *nl; |
| 324 | int got, wrote, i; |
| 325 | |
| 326 | end = device->flash_kb << 10; |
| 327 | res = dialog_rc(100, "R 0 %u", end); |
| 328 | while (addr != end) { |
| 329 | while (1) { |
| 330 | uint8_t buf[MAX_RECORD]; |
| 331 | |
| 332 | nl = strchr(res, '\n'); |
| 333 | if (!nl) |
| 334 | break; |
| 335 | got = uudecode(res, buf); |
| 336 | for (i = 0; i != got; i++) |
| 337 | sum += buf[i]; |
| 338 | wrote = fwrite(buf, 1, got, stdout); |
| 339 | if (wrote != got) { |
| 340 | perror("fwrite"); |
| 341 | exit(1); |
| 342 | } |
| 343 | addr += got; |
| 344 | res = nl+1; |
| 345 | } |
| 346 | if (sscanf(res, "%u", &check) != 1) { |
| 347 | fprintf(stderr, "can't parse checksum \"%s\"\n", res); |
| 348 | exit(1); |
| 349 | } |
| 350 | if (check != sum) { |
| 351 | fprintf(stderr, "checksum error: got %u received %u\n", |
| 352 | sum, check); |
| 353 | exit(1); |
| 354 | } |
| 355 | res = dialog(100, "OK"); |
| 356 | sum = 0; |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | |
259 | 361 | /* ----- ISP session ------------------------------------------------------- */ |
260 | 362 | |
261 | 363 | |
... | ... | |
347 | 449 | |
348 | 450 | identify(); |
349 | 451 | |
| 452 | dump(); |
| 453 | |
350 | 454 | return 0; |
351 | 455 | } |