Contiki 2.5
converter.c
1 #include <unistd.h>
2 #include <getopt.h>
3 #include <string.h>
4 #include <inttypes.h>
5 
6 #include "converter.h"
7 
8 #include <stdio.h>
9 
10 extern int cdi_programmer(conf_opts_t *conf, char *filename);
11 
12 void usage(char *prg_name)
13 {
14  printf("\nUsage: %s -f ihex file\n", prg_name);
15  printf("General options:\n");
16  printf(" -V/--version Get converter version\n");
17 }
18 
19 conf_opts_t conf_opts;
20 
21 static int option_index = 0;
22 
23 int do_exit = 0;
24 
25 #define OPTIONS_STRING "Vhf:"
26 /* long option list */
27 static struct option long_options[] =
28 {
29  {"version", 0, NULL, 'V'},
30  {"file", 1, NULL, 'f'},
31  {"help", 0, NULL, 'h'},
32  {0, 0, 0, 0}
33 };
34 
35 int parse_opts(int count, char* param[])
36 {
37  int opt;
38  int error=0;
39 
40  conf_opts.target_type = UNDEFINED;
41  while ((opt = getopt_long(count, param, OPTIONS_STRING,
42  long_options, &option_index)) != -1)
43  {
44  switch(opt)
45  {
46  case 'V':
47  conf_opts.target_type = VERSION;
48  break;
49 
50  case 'h':
51  conf_opts.target_type = UNDEFINED;
52  break;
53 
54  case 'f':
55  strcpy(conf_opts.ihex_file, optarg);
56  conf_opts.target_type = CONVERT;
57  break;
58  }
59  }
60 
61  if (!error && (conf_opts.target_type == CONVERT) )
62  {
63  printf("File: %s.\n", conf_opts.ihex_file);
64  }
65 
66  return error;
67 }
68 
69 int main(int argc, char *argv[])
70 {
71  int error = 0;
72 
73  conf_opts.target_type = 0;
74 
75 
76  if ( (argc < 1) || (error = parse_opts(argc, argv)) )
77  {
78  usage(argv[0]);
79  if (error < 0) return error;
80  else return 0;
81  }
82 
83  if(conf_opts.target_type == CONVERT)
84  { /*Convert*/
85  int pages;
86  int sdcc_file = 0;
87 
88  FILE *ihex = 0;
89  unsigned char check = 0;
90  unsigned long ext_addr=0;
91  unsigned short int addr=0;
92  unsigned char page_buffer[128*1024];
93  unsigned char page_table[64];
94  unsigned char buffer[256];
95  int i;
96  int retval = 0;
97 
98  bzero(buffer, sizeof(buffer));
99 
100  /*initialize page data*/
101  memset(page_table, 0, 64);
102  memset(page_buffer, 0xFF, sizeof(page_buffer));
103  pages = 0;
104 
105  ihex = fopen(conf_opts.ihex_file, "rb");
106  if (ihex == 0)
107  {
108  printf("Can't open file.\n");
109  return -1;
110  }
111  error = 0;
112  while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) )
113  {
114  unsigned char data_len = 0;
115 
116  if (memcmp(&buffer[7], "00", 2) == 0)
117  { /*Data record*/
118  i=0;
119  sscanf((char *)&buffer[1], "%2hhx", &data_len);
120  sscanf((char *)&(buffer[3]),"%4hx", &addr);
121  while(i<data_len)
122  {
123  uint32_t absolute_address = ext_addr+addr+i;
124 
125  if (page_table[absolute_address/2048] == 0)
126  {
127  page_table[absolute_address/2048] = 1;
128  pages++;
129  }
130  sscanf((char *)&buffer[2*i+9], "%2hhx", &page_buffer[absolute_address]);
131  i++;
132  }
133  }
134  else if (memcmp(&buffer[7], "01", 2) == 0)
135  { /*end file*/
136  printf("\nFile read complete.\n");
137  break;
138  }
139  else if (memcmp(&buffer[7], "04", 2) == 0)
140  {
141  sscanf((char *)&(buffer[3]),"%4hx", &addr);
142  sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
143  printf("\rExtended page address: 0x%8.8lX\r", ext_addr*0x8000 );
144 
145  if (ext_addr >= 0x0002) sdcc_file = 1;
146 
147  if (ext_addr) ext_addr--;
148  ext_addr *= 0x8000;
149  }
150  }
151  fclose(ihex);
152  if (retval == -1)
153  {
154  printf("Read error\n");
155  }
156  if (sdcc_file == 0)
157  {
158  printf("Not a SDCC banked file.\n");
159  return 0;
160  }
161  printf("Writing %d pages.\n", pages);
162  { /*cut off extension*/
163  char *ptr = strrchr(conf_opts.ihex_file, '.');
164  if (ptr != NULL)
165  {
166  *ptr = 0;
167  }
168  }
169  strcat(conf_opts.ihex_file, "_linear.hex");
170  printf("Output file: %s.\n", conf_opts.ihex_file);
171  ihex = fopen(conf_opts.ihex_file, "wb");
172  ext_addr=0;
173  addr = 0;
174  if (pages)
175  {
176  int j;
177  error = 0;
178  for (i=0; i<64; i++)
179  {
180  addr = (i & 0x1F) * 2048;
181  if ( ((i / 32) * 0x10000) != ext_addr)
182  { /*write out ext addr*/
183  printf("Ext: %4.4X\n", ((i / 32) * 0x10000));
184  ext_addr = (i / 32) * 0x10000;
185  fprintf(ihex, ":02000004%4.4X%2.2X\r\n",
186  (int)(ext_addr>>16), (int)(0xFA-(ext_addr>>16)));
187  }
188 
189  if (page_table[i] != 0)
190  {
191  printf("%4.4X", addr & 0xF800);
192  for (j=0; j<2048; j++)
193  {
194  addr =(i & 0x1F) * 2048 + j;
195  if ((j & 0x1F) == 0)
196  {
197  check = 0;
198  check -= 0x20;
199  check -= (uint8_t) (addr >> 8);
200  check -= (uint8_t) (addr);
201  fprintf(ihex, ":20%4.4X00", (int) addr);
202  }
203  fprintf(ihex, "%2.2X", page_buffer[ext_addr+addr]);
204  check -= page_buffer[ext_addr+addr];
205  if ((j & 0x1F) == 0x1F)
206  {
207  fprintf(ihex, "%2.2X\r\n", check);
208  }
209  }
210  }
211  if ((i & 0x07) == 0x07) printf("\n");
212  else printf(" ");
213  }
214  fprintf(ihex, ":00000001FF\r\n");
215  printf("Write complete.\n");
216  }
217  fclose(ihex);
218  }
219  else if(conf_opts.target_type == UNDEFINED)
220  {
221  usage(argv[0]);
222  }
223  else
224  {
225  printf("\nSensinode hex file converter "CONVERTER_VERSION "\n");
226  }
227  return error;
228 }