1 /* Create an ascii hex i2c data file */
3 #include <stdio.h>
4 #include <malloc.h>
6 unsigned onesComplementAdd (unsigned value1, unsigned value2)
7 {
8 unsigned result;
10 result = (unsigned)value1 + (unsigned)value2;
12 result = (result >> 16) + (result & 0xFFFF); /* add in carry */
13 result += (result >> 16); /* maybe one more */
14 result = (result & 0xffff);
15 return (unsigned)result;
17 } /* end of beth_ones_complement_add() */
20 int asciiByte (unsigned char c)
21 {
22 if ((c >= '0') && (c <= '9'))
23 return (1);
25 if ((c >= 'A') && (c <= 'F'))
26 return (1);
28 return (0);
29 }
31 int toNum (unsigned char c)
32 {
33 if ((c >= '0') && (c <= '9'))
34 return (c - '0');
36 return (c - 'A' + 10);
38 }
41 void stripLine (FILE *s)
42 {
43 char iline[132];
45 fgets (iline, 131, s);
47 }
49 /* Read a .b file. */
50 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
51 {
52 unsigned char x, y;
53 int byteCount = 0;
55 /* Strip the 1st two lines */
56 stripLine (s);
57 stripLine (s);
59 for (;;) {
61 /* read the 1st ascii char */
62 do {
63 x = fgetc (s);
64 if (x == (unsigned char)EOF)
65 return (byteCount);
67 } while (!asciiByte(x));
69 /* Read the next ascii char */
70 y = fgetc (s);
71 if (y == (unsigned char)EOF)
72 return (byteCount);
73 if (asciiByte(y))
74 data[byteCount++] = (toNum(x) << 4) | toNum (y);
76 if (byteCount >= maxSize) {
77 fprintf (stderr, "Max input array size exceeded\n");
78 return (-1);
79 }
81 }
84 }
87 int copyBlock (unsigned char *source, int idx, int maxSize, unsigned char *dest, int count)
88 {
89 int i;
91 for (i = 0; i < count; i++) {
92 if (idx >= maxSize)
93 break;
94 dest[i] = source[idx++];
95 }
97 return (i);
99 }
101 void blockCheckSum (unsigned char *block, int blockSize)
102 {
103 unsigned checksum = 0;
104 unsigned value;
105 int i;
107 if (blockSize & 0x0001) {
108 fprintf (stderr, "program requires an even blocksize\n");
109 exit (-1);
110 }
112 for (i = 0; i < blockSize; i += 2) {
113 value = (block[i] << 8) | block[i+1];
114 checksum = onesComplementAdd (checksum, value);
115 }
117 /* Put the checksum into the block starting at byte 2. Use big endian */
118 checksum = ~checksum;
119 block[3] = checksum & 0xff;
120 block[2] = (checksum >> 8) & 0xff;
122 }
124 #define SIZE 0x10000 /* max array size */
126 int main (int argc, char *argv[])
127 {
128 FILE *strin;
129 FILE *strout;
131 unsigned char *dataSet1;
132 unsigned char *dataSet2;
134 unsigned char block[128];
135 unsigned blockSize;
137 unsigned pIn;
138 unsigned pOut;
140 int inSize;
141 int i;
143 /* Arg check */
144 if (argc != 3) {
145 fprintf (stderr, "usage: %s infile outfile\n", argv[0]);
146 return (-1);
147 }
149 /* Open the input file */
150 strin = fopen (argv[1], "r");
151 if (strin == NULL) {
152 fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
153 return (-1);
154 }
156 /* Allocate the two data set memories */
157 dataSet1 = malloc (SIZE * sizeof (unsigned char));
158 dataSet2 = malloc (SIZE * sizeof (unsigned char));
159 if ((dataSet1 == NULL) || (dataSet2 == NULL)) {
160 fprintf (stderr, "%s: Malloc failure\n", argv[0]);
161 return (-1);
162 }
164 /* Read the data into the byte stream */
165 if ((inSize = readBFile (strin, dataSet1, SIZE)) < 0)
166 return (inSize);
167 fclose (strin);
169 /* Perform the i2c block formatting. The block size will be fixed at 128 bytes,
170 * 2 bytes of length, 2 bytes checksum, 124 bytes of data. */
171 pIn = 0;
172 pOut = 0;
174 do {
176 /* Copy the block, leave 4 bytes at the top */
177 blockSize = copyBlock (dataSet1, pIn, inSize, &block[4], 124);
178 pIn += blockSize; /* advance to next data in source */
180 if (blockSize) {
181 blockSize += 4; /* Add room for the header - big endian */
182 block[1] = blockSize & 0xff;
183 block[0] = (blockSize >> 8) & 0xff;
184 block[2] = block[3] = 0;
186 /* Checksum the block */
187 blockCheckSum (block, blockSize);
189 /* Copy the results to the destination block */
190 if ((pOut + blockSize) >= SIZE) {
191 fprintf (stderr, "%s: destination array size exceeded\n", argv[0]);
192 return (-1);
193 }
194 for (i = 0; i < blockSize; i++)
195 dataSet2[pOut++] = block[i];
196 }
198 } while (blockSize == 128);
201 /* Copy the resulting data set into the output file in ccs format */
202 strout = fopen (argv[2], "w");
203 if (strout == NULL) {
204 fprintf (stderr, "%s: Could not open %s for writing\n", argv[0], argv[2]);
205 return (-1);
206 }
209 /* Write the two line header */
210 fprintf (strout, "%c\n$A000000\n", (unsigned char)2);
212 /* Write out the data */
213 for (i = 0; i < pOut; i++) {
214 if ( ((i+1)%24) )
215 fprintf (strout, "%02X ", dataSet2[i]);
216 else
217 fprintf (strout, "%02X\n", dataSet2[i]);
218 }
220 /* Write the close character */
221 fprintf (strout, "\n%c", (unsigned char)3);
223 fclose (strout);
225 return (0);
227 }