nand flash addition
[keystone-rtos/ibl.git] / src / util / btoccs / b2i2c.c
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)
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;
124 #define SIZE    0x10000   /* max array size */
126 int main (int argc, char *argv[])
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);
231