• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * S-records dump routine -- dumps S-records on the console
3  */
4 
5 #include <string.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <minmax.h>
9 #include "upload_backend.h"
10 
11 /* Write a single S-record */
write_srecord(unsigned int len,unsigned int alen,uint32_t addr,uint8_t type,const void * data)12 static int write_srecord(unsigned int len,  unsigned int alen,
13                          uint32_t addr, uint8_t type, const void *data)
14 {
15     char buf[2+2+8+255*2+2+2];
16     char *p = buf;
17     uint8_t csum;
18     const uint8_t *dptr = data;
19     unsigned int i;
20 
21     switch (alen) {
22     case 2:
23         addr &= 0xffff;
24         break;
25     case 3:
26         addr &= 0xffffff;
27         break;
28     case 4:
29         break;
30     }
31 
32     csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
33     for (i = 0; i < len; i++)
34         csum += dptr[i];
35     csum = 0xff-csum;
36 
37     p += sprintf(p, "S%c%02X%0*X", type, len+alen+1, alen*2, addr);
38     for (i = 0; i < len; i++)
39         p += sprintf(p, "%02X", dptr[i]);
40     p += sprintf(p, "%02X\n", csum);
41 
42     fputs(buf, stdout);
43     return 0;
44 }
45 
upload_srec_write(struct upload_backend * be)46 static int upload_srec_write(struct upload_backend *be)
47 {
48     char name[33];
49     const char *buf;
50     size_t len, chunk, offset, hdrlen;
51 
52     buf = be->outbuf;
53     len = be->zbytes;
54 
55     putchar('\n');
56 
57     hdrlen = snprintf(name, sizeof name, "%.32s",
58 		      be->argv[0] ? be->argv[0] : "");
59 
60     /* Write head record */
61     write_srecord(hdrlen, 2, 0, '0', name);
62 
63     /* Write data records */
64     offset = 0;
65     while (len) {
66 	chunk = min(len, (size_t)32);
67 
68 	write_srecord(chunk, 4, offset, '3', buf);
69 	buf += chunk;
70 	len -= chunk;
71 	offset += chunk;
72     }
73 
74     /* Write termination record */
75     write_srecord(0, 4, 0, '7', NULL);
76 
77     return 0;
78 }
79 
80 struct upload_backend upload_srec = {
81     .name       = "srec",
82     .helpmsg    = "[filename]",
83     .minargs    = 0,
84     .write      = upload_srec_write,
85 };
86