comparison helpers/srec4ram.c @ 92:40b08f6cb2b8

srec4ram helper utility written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 02 Oct 2016 19:32:00 +0000
parents
children
comparison
equal deleted inserted replaced
91:a1ed3269da48 92:40b08f6cb2b8
1 /*
2 * This ad hoc utility is used as part of building RAM-loadable
3 * firmware images for targets with large RAM. It reads the ramimage.m0
4 * S-record file produced by TI's hex470 post-linker and re-emits it
5 * in another SREC form that is suitable for feeding to fc-xram.
6 */
7
8 #include <sys/types.h>
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <strings.h>
14
15 char *infname;
16 FILE *inf, *outf;
17 char srecbuf[80];
18 u_char srecbin[40], srecout[40];
19 int lineno;
20
21 decode_hex_byte(s)
22 char *s;
23 {
24 register int u, l;
25
26 if (!isxdigit(s[0]) || !isxdigit(s[1]))
27 return(-1);
28 if (isdigit(s[0]))
29 u = s[0] - '0';
30 else if (isupper(s[0]))
31 u = s[0] - 'A' + 10;
32 else
33 u = s[0] - 'a' + 10;
34 if (isdigit(s[1]))
35 l = s[1] - '0';
36 else if (isupper(s[1]))
37 l = s[1] - 'A' + 10;
38 else
39 l = s[1] - 'a' + 10;
40 return((u << 4) | l);
41 }
42
43 srec2bin()
44 {
45 register int i, l, b;
46
47 l = decode_hex_byte(srecbuf + 2);
48 if (l < 1) {
49 fprintf(stderr, "%s line %d: S-record length octet is bad\n",
50 infname, lineno);
51 exit(1);
52 }
53 srecbin[0] = l;
54 if (l > 35) {
55 fprintf(stderr,
56 "%s line %d: S-record is longer than expected\n",
57 infname, lineno);
58 exit(1);
59 }
60 for (i = 1; i <= l; i++) {
61 b = decode_hex_byte(srecbuf + i*2 + 2);
62 if (b < 0) {
63 fprintf(stderr, "%s line %d: hex decode error\n",
64 infname, lineno);
65 exit(1);
66 }
67 srecbin[i] = b;
68 }
69 return(0);
70 }
71
72 srec_cksum()
73 {
74 u_char accum;
75 register int i, len;
76
77 len = srecbin[0] + 1;
78 accum = 0;
79 for (i = 0; i < len; i++)
80 accum += srecbin[i];
81 if (accum != 0xFF) {
82 fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno);
83 exit(1);
84 }
85 return(0);
86 }
87
88 emit_output_srec(type, buf)
89 u_char *buf;
90 {
91 int i;
92 u_char accum = 0;
93
94 putc('S', outf);
95 putc(type, outf);
96 for (i = 0; i < buf[0]; i++) {
97 fprintf(outf, "%02X", buf[i]);
98 accum += buf[i];
99 }
100 fprintf(outf, "%02X\n", ~accum & 0xFF);
101 return 0;
102 }
103
104 transform_s3()
105 {
106 int datalen;
107 u_char *sp, *dp;
108 int i;
109
110 if (srecbin[0] < 6) {
111 fprintf(stderr,
112 "%s line %d: S3 record is too short\n",
113 infname, lineno);
114 exit(1);
115 }
116 datalen = srecbin[0] - 5;
117 if (datalen & 1) {
118 fprintf(stderr, "%s line %d: odd data length\n",
119 infname, lineno);
120 exit(1);
121 }
122 sp = srecbin;
123 dp = srecout;
124 for (i = 0; i < 5; i++)
125 *dp++ = *sp++;
126 for (i = 0; i < datalen; i += 2) {
127 dp[0] = sp[1];
128 dp[1] = sp[0];
129 sp += 2;
130 dp += 2;
131 }
132 return 0;
133 }
134
135 generate_vectors_record()
136 {
137 u_char *dp;
138 u_long addr;
139 int i;
140
141 srecout[0] = 28 + 5;
142 srecout[1] = 0x00;
143 srecout[2] = 0x80;
144 srecout[3] = 0x00;
145 srecout[4] = 0x00;
146 dp = srecout + 5;
147 for (i = 0; i < 7; i++) {
148 addr = 0x01004000 + i * 4;
149 *dp++ = addr;
150 *dp++ = addr >> 8;
151 *dp++ = addr >> 16;
152 *dp++ = addr >> 24;
153 }
154 emit_output_srec('3', srecout);
155 return 0;
156 }
157
158 generate_jump_record()
159 {
160 srecout[0] = 5;
161 srecout[1] = 0x01;
162 srecout[2] = 0x00;
163 srecout[3] = 0x40;
164 srecout[4] = 0x58;
165 emit_output_srec('7', srecout);
166 return 0;
167 }
168
169 main(argc, argv)
170 char **argv;
171 {
172 if (argc < 2 || argc > 3) {
173 fprintf(stderr, "usage: %s input.m0 [output.srec]\n", argv[0]);
174 exit(1);
175 }
176 infname = argv[1];
177 inf = fopen(infname, "r");
178 if (!inf) {
179 perror(infname);
180 exit(1);
181 }
182 if (argc > 2) {
183 outf = fopen(argv[2], "w");
184 if (!outf) {
185 perror(argv[2]);
186 exit(1);
187 }
188 } else
189 outf = stdout;
190 for (lineno = 1; ; lineno++) {
191 if (!fgets(srecbuf, sizeof srecbuf, inf)) {
192 fprintf(stderr, "%s: premature EOF\n", infname);
193 exit(1);
194 }
195 if (srecbuf[0] != 'S') {
196 fprintf(stderr, "%s line %d: not an S-record\n",
197 infname, lineno);
198 exit(1);
199 }
200 srec2bin();
201 srec_cksum();
202 switch (srecbuf[1]) {
203 case '0':
204 emit_output_srec('0', srecbin);
205 continue;
206 case '3':
207 transform_s3();
208 emit_output_srec('3', srecout);
209 continue;
210 case '7':
211 break;
212 default:
213 fprintf(stderr, "%s line %d: unexpected S%c record\n",
214 infname, lineno, srecbuf[1]);
215 exit(1);
216 }
217 break;
218 }
219 generate_vectors_record();
220 generate_jump_record();
221 exit(0);
222 }