1 /*
2 *
3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
38 /* Create an ascii hex i2c data file */
40 #include <stdio.h>
41 #include <malloc.h>
43 unsigned onesComplementAdd (unsigned value1, unsigned value2)
44 {
45 unsigned result;
47 result = (unsigned)value1 + (unsigned)value2;
49 result = (result >> 16) + (result & 0xFFFF); /* add in carry */
50 result += (result >> 16); /* maybe one more */
51 result = (result & 0xffff);
52 return (unsigned)result;
54 } /* end of beth_ones_complement_add() */
57 int asciiByte (unsigned char c)
58 {
59 if ((c >= '0') && (c <= '9'))
60 return (1);
62 if ((c >= 'A') && (c <= 'F'))
63 return (1);
65 return (0);
66 }
68 int toNum (unsigned char c)
69 {
70 if ((c >= '0') && (c <= '9'))
71 return (c - '0');
73 return (c - 'A' + 10);
75 }
78 void stripLine (FILE *s)
79 {
80 char iline[132];
82 fgets (iline, 131, s);
84 }
86 /* Read a .b file. */
87 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
88 {
89 unsigned char x, y;
90 int byteCount = 0;
92 /* Strip the 1st two lines */
93 stripLine (s);
94 stripLine (s);
96 for (;;) {
98 /* read the 1st ascii char */
99 do {
100 x = fgetc (s);
101 if (x == (unsigned char)EOF)
102 return (byteCount);
104 } while (!asciiByte(x));
106 /* Read the next ascii char */
107 y = fgetc (s);
108 if (y == (unsigned char)EOF)
109 return (byteCount);
110 if (asciiByte(y))
111 data[byteCount++] = (toNum(x) << 4) | toNum (y);
113 if (byteCount >= maxSize) {
114 fprintf (stderr, "Max input array size exceeded\n");
115 return (-1);
116 }
118 }
121 }
124 int copyBlock (unsigned char *source, int idx, int maxSize, unsigned char *dest, int count)
125 {
126 int i;
128 for (i = 0; i < count; i++) {
129 if (idx >= maxSize)
130 break;
131 dest[i] = source[idx++];
132 }
134 return (i);
136 }
138 void blockCheckSum (unsigned char *block, int blockSize)
139 {
140 unsigned checksum = 0;
141 unsigned value;
142 int i;
144 if (blockSize & 0x0001) {
145 fprintf (stderr, "program requires an even blocksize\n");
146 exit (-1);
147 }
149 for (i = 0; i < blockSize; i += 2) {
150 value = (block[i] << 8) | block[i+1];
151 checksum = onesComplementAdd (checksum, value);
152 }
154 /* Put the checksum into the block starting at byte 2. Use big endian */
155 checksum = ~checksum;
156 block[3] = checksum & 0xff;
157 block[2] = (checksum >> 8) & 0xff;
159 }
161 #define SIZE 0x20000 /* max array size */
163 int main (int argc, char *argv[])
164 {
165 FILE *strin;
166 FILE *strout;
168 unsigned char *dataSet1;
169 unsigned char *dataSet2;
171 unsigned char block[128];
172 unsigned blockSize;
174 unsigned pIn;
175 unsigned pOut;
177 int inSize;
178 int i;
180 /* Arg check */
181 if (argc != 3) {
182 fprintf (stderr, "usage: %s infile outfile\n", argv[0]);
183 return (-1);
184 }
186 /* Open the input file */
187 strin = fopen (argv[1], "r");
188 if (strin == NULL) {
189 fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
190 return (-1);
191 }
193 /* Allocate the two data set memories */
194 dataSet1 = malloc (SIZE * sizeof (unsigned char));
195 dataSet2 = malloc (SIZE * sizeof (unsigned char));
196 if ((dataSet1 == NULL) || (dataSet2 == NULL)) {
197 fprintf (stderr, "%s: Malloc failure\n", argv[0]);
198 return (-1);
199 }
201 /* Read the data into the byte stream */
202 if ((inSize = readBFile (strin, dataSet1, SIZE)) < 0)
203 return (inSize);
204 fclose (strin);
206 /* Perform the i2c block formatting. The block size will be fixed at 128 bytes,
207 * 2 bytes of length, 2 bytes checksum, 124 bytes of data. */
208 pIn = 0;
209 pOut = 0;
211 do {
213 /* Copy the block, leave 4 bytes at the top */
214 blockSize = copyBlock (dataSet1, pIn, inSize, &block[4], 124);
215 pIn += blockSize; /* advance to next data in source */
217 if (blockSize) {
218 blockSize += 4; /* Add room for the header - big endian */
219 block[1] = blockSize & 0xff;
220 block[0] = (blockSize >> 8) & 0xff;
221 block[2] = block[3] = 0;
223 /* Checksum the block */
224 blockCheckSum (block, blockSize);
226 /* Copy the results to the destination block */
227 if ((pOut + blockSize) >= SIZE) {
228 fprintf (stderr, "%s: destination array size exceeded\n", argv[0]);
229 return (-1);
230 }
231 for (i = 0; i < blockSize; i++)
232 dataSet2[pOut++] = block[i];
233 }
235 } while (blockSize == 128);
238 /* Copy the resulting data set into the output file in ccs format */
239 strout = fopen (argv[2], "w");
240 if (strout == NULL) {
241 fprintf (stderr, "%s: Could not open %s for writing\n", argv[0], argv[2]);
242 return (-1);
243 }
246 /* Write the two line header */
247 fprintf (strout, "%c\n$A000000\n", (unsigned char)2);
249 /* Write out the data */
250 for (i = 0; i < pOut; i++) {
251 if ( ((i+1)%24) )
252 fprintf (strout, "%02X ", dataSet2[i]);
253 else
254 fprintf (strout, "%02X\n", dataSet2[i]);
255 }
257 /* Write the close character */
258 fprintf (strout, "\n%c", (unsigned char)3);
260 fclose (strout);
262 return (0);
264 }