804ab646de502239de5f3a5de601f9a5316eb826
[keystone-rtos/ibl.git] / src / util / btoccs / b2i2c.c
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   }
124 int copyBlock (unsigned char *source, int idx, int maxSize, unsigned char *dest, int count)
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);
138 void blockCheckSum (unsigned char *block, int blockSize)
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;
161 #define SIZE    0x20000   /* max array size */
163 int main (int argc, char *argv[])
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);
268