summaryrefslogtreecommitdiffstats
blob: 54e2a95e1491aa1d35bc14e56b3a0f6e482790a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* Create an ascii hex i2c data file */

#include <stdio.h>
#include <malloc.h>

unsigned onesComplementAdd (unsigned value1, unsigned value2)
{
  unsigned result;

  result = (unsigned)value1 + (unsigned)value2;

  result = (result >> 16) + (result & 0xFFFF); /* add in carry   */
  result += (result >> 16);                    /* maybe one more */
  result = (result & 0xffff);
  return (unsigned)result;

} /* end of beth_ones_complement_add() */


int asciiByte (unsigned char c)
{
  if ((c >= '0') && (c <= '9'))
    return (1);

  if ((c >= 'A') && (c <= 'F'))
    return (1);

  return (0);
}

int toNum (unsigned char c)
{
  if ((c >= '0') && (c <= '9'))
    return (c - '0');

  return (c - 'A' + 10);

}


void  stripLine (FILE *s)
{
  char iline[132];

  fgets (iline, 131, s);

}

/* Read a .b file. */
unsigned long readBFile (FILE *s, unsigned char *data, unsigned long maxSize)
{
  unsigned char x, y;
  unsigned long byteCount = 0;

  /* Strip the 1st two lines */
  stripLine (s);
  stripLine (s);

  for (;;) {

    /* read the 1st ascii char */
    do  {
      x = fgetc (s);
      if (x == (unsigned char)EOF)
        return (byteCount);

    } while (!asciiByte(x));

    /* Read the next ascii char */
    y = fgetc (s);
    if (y == (unsigned char)EOF)
      return (byteCount);
    if (asciiByte(y))
      data[byteCount++] = (toNum(x) << 4) | toNum (y);

    if (byteCount >= maxSize)  {
      fprintf (stderr, "Max input array size exceeded\n");
      return (-1);
    }
  }
}


int copyBlock (unsigned char *source, unsigned long idx, unsigned long maxSize,
               unsigned char *dest, unsigned long count)
{
  unsigned long i;

  for (i = 0; i < count; i++)  {
    if (idx >= maxSize)
      break;

    dest[i] = source[idx++];
  }

  return (i);

}

void blockCheckSum (unsigned char *block, unsigned long blockSize)
{
  unsigned checksum = 0;
  unsigned value;
  unsigned long i;

  if (blockSize & 0x0001)  {
    fprintf (stderr, "program requires an even blocksize\n");
    exit (-1);
  }

  for (i = 0; i < blockSize; i += 2) {
    value = (block[i] << 8) | block[i+1];
    checksum = onesComplementAdd (checksum, value);
  }

  /* Put the checksum into the block starting at byte 2. Use big endian */
  checksum = ~checksum;
  block[3] = checksum & 0xff;
  block[2] = (checksum >> 8) & 0xff;

}

#define SIZE    (1024 * 1024 * 2)   /* max array size 2MB */

int main (int argc, char *argv[])
{
  FILE *strin;
  FILE *strout;

  unsigned char *dataSet1;
  unsigned char *dataSet2;

  unsigned char block[128];
  unsigned blockSize;

  unsigned long pIn;
  unsigned long pOut;

  unsigned long inSize;
  unsigned long i;

  /* Arg check */
  if (argc != 3)  {
    fprintf (stderr, "usage: %s infile outfile\n", argv[0]);
    return (-1);
  }

  /* Open the input file */
  strin = fopen (argv[1], "r");
  if (strin == NULL)  {
    fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
    return (-1);
  }

  /* Allocate the two data set memories */
  dataSet1 = malloc (SIZE * sizeof (unsigned char));
  dataSet2 = malloc (SIZE * sizeof (unsigned char));
  if ((dataSet1 == NULL) || (dataSet2 == NULL))  {
    fprintf (stderr, "%s: Malloc failure\n", argv[0]);
    return (-1);
  }

  /* Read the data into the byte stream */
  if ((inSize = readBFile (strin, dataSet1, SIZE)) < 0)
    return (inSize);
  fclose (strin);

  /* Perform the i2c block formatting. The block size will be fixed at 128 bytes,
   * 2 bytes of length, 2 bytes checksum, 124 bytes of data. */
  pIn = 0;
  pOut = 0;

  do  {

    /* Copy the block, leave 4 bytes at the top */
    blockSize = copyBlock (dataSet1, pIn, inSize, &block[4], 124);
    pIn += blockSize; /* advance to next data in source */

    if (blockSize)  {
      blockSize += 4;   /* Add room for the header - big endian */
      block[1] = blockSize & 0xff;
      block[0] = (blockSize >> 8) & 0xff;
      block[2] = block[3] = 0;

      /* Checksum the block */
      blockCheckSum (block, blockSize);

      /* Copy the results to the destination block */
      if ((pOut + blockSize) >= SIZE)  {
        fprintf (stderr, "%s: destination array size exceeded\n", argv[0]);
        return (-1);
      }
      for (i = 0; i < blockSize; i++)
        dataSet2[pOut++] = block[i];
    }

  } while (blockSize == 128);


  /* Copy the resulting data set into the output file in ccs format */
  strout = fopen (argv[2], "w");
  if (strout == NULL)  {
    fprintf (stderr, "%s: Could not open %s for writing\n", argv[0], argv[2]);
    return (-1);
  }


  /* Write the two line header */
  fprintf (strout, "%c\n$A000000\n", (unsigned char)2);

  /* Write out the data */
  for (i = 0; i < pOut; i++)  {
    if ( ((i+1)%24) )
      fprintf (strout, "%02X ", dataSet2[i]);
    else
      fprintf (strout, "%02X\n", dataSet2[i]);
  }

  /* Write the close character */
  fprintf (strout, "\n%c", (unsigned char)3);

  fclose (strout);

  return (0);

}