converter.c

00001 #include <unistd.h>
00002 #include <getopt.h>
00003 #include <string.h>
00004 #include <inttypes.h>
00005 
00006 #include "converter.h"
00007 
00008 #include <stdio.h>
00009 
00010 extern int cdi_programmer(conf_opts_t *conf, char *filename);
00011 
00012 void usage(char *prg_name)
00013 {
00014         printf("\nUsage: %s -f ihex file\n", prg_name);
00015         printf("General options:\n");
00016         printf("        -V/--version    Get converter version\n");
00017 }
00018 
00019 conf_opts_t conf_opts;
00020 
00021 static int option_index = 0;
00022 
00023 int do_exit = 0;
00024 
00025 #define OPTIONS_STRING "Vhf:"
00026 /* long option list */
00027 static struct option long_options[] =
00028 {
00029   {"version", 0, NULL, 'V'},
00030   {"file", 1, NULL, 'f'},
00031   {"help", 0, NULL, 'h'},
00032   {0, 0, 0, 0}
00033 };
00034 
00035 int parse_opts(int count, char* param[])
00036 {
00037         int opt;
00038         int error=0;
00039         
00040         conf_opts.target_type = UNDEFINED;
00041   while ((opt = getopt_long(count, param, OPTIONS_STRING,
00042                             long_options, &option_index)) != -1)
00043   {
00044     switch(opt)
00045                 {
00046                         case 'V':
00047                                 conf_opts.target_type = VERSION;
00048                                 break;
00049 
00050                         case 'h':
00051                                 conf_opts.target_type = UNDEFINED;
00052                                 break;
00053 
00054                 case 'f':
00055                                 strcpy(conf_opts.ihex_file, optarg);
00056                                 conf_opts.target_type = CONVERT;
00057                                 break;
00058                 }
00059         }
00060 
00061         if (!error && (conf_opts.target_type == CONVERT) )
00062         {
00063                 printf("File: %s.\n", conf_opts.ihex_file);
00064         }
00065         
00066         return error;
00067 }
00068 
00069 int main(int argc, char *argv[])
00070 {
00071         int error = 0;
00072         
00073         conf_opts.target_type = 0;
00074                 
00075 
00076         if ( (argc < 1) || (error = parse_opts(argc, argv)) )
00077         {
00078                 usage(argv[0]);
00079                 if (error < 0) return error;
00080                 else return 0;
00081         }
00082         
00083         if(conf_opts.target_type == CONVERT)
00084         {       /*Convert*/
00085                 int pages;
00086                 int sdcc_file = 0;
00087                 
00088                 FILE *ihex = 0; 
00089                 unsigned char check = 0;
00090                 unsigned long ext_addr=0;
00091                 unsigned short int addr=0;
00092                 unsigned char page_buffer[128*1024];
00093                 unsigned char page_table[64];
00094                 unsigned char buffer[256];
00095                 int i;
00096                 int retval = 0;
00097                 
00098                 bzero(buffer, sizeof(buffer));
00099 
00100                 /*initialize page data*/
00101                 memset(page_table, 0, 64);
00102                 memset(page_buffer, 0xFF, sizeof(page_buffer));
00103                 pages = 0;
00104                 
00105                 ihex = fopen(conf_opts.ihex_file, "rb");
00106                 if (ihex == 0)
00107                 {
00108                         printf("Can't open file.\n");
00109                         return -1;
00110                 }
00111                 error = 0;
00112                 while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) )
00113                 {       
00114                         unsigned char data_len = 0;
00115                         
00116                         if (memcmp(&buffer[7], "00", 2) == 0)
00117                         {       /*Data record*/
00118                                 i=0;
00119                                 sscanf((char *)&buffer[1], "%2hhx", &data_len);
00120                                 sscanf((char *)&(buffer[3]),"%4hx", &addr);
00121                                 while(i<data_len)
00122                                 {
00123                                         uint32_t absolute_address = ext_addr+addr+i;
00124 
00125                                         if (page_table[absolute_address/2048] == 0) 
00126                                         {
00127                                                 page_table[absolute_address/2048] = 1;
00128                                                 pages++;
00129                                         }
00130                                         sscanf((char *)&buffer[2*i+9], "%2hhx", &page_buffer[absolute_address]);
00131                                         i++;
00132                                 }
00133                         }
00134                         else if (memcmp(&buffer[7], "01", 2) == 0)
00135                         {       /*end file*/
00136                                 printf("\nFile read complete.\n");
00137                                 break;
00138                         }
00139                         else if (memcmp(&buffer[7], "04", 2) == 0)
00140                         {
00141                                 sscanf((char *)&(buffer[3]),"%4hx", &addr);
00142                                 sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
00143                                 printf("\rExtended page address: 0x%8.8lX\r", ext_addr*0x8000 );
00144                                 
00145                                 if (ext_addr >= 0x0002) sdcc_file = 1;
00146                                 
00147                                 if (ext_addr) ext_addr--;
00148                                 ext_addr *= 0x8000;
00149                         }
00150                 }
00151                 fclose(ihex);
00152                 if (retval == -1)
00153                 {
00154                         printf("Read error\n");
00155                 }
00156                 if (sdcc_file == 0)
00157                 {
00158                         printf("Not a SDCC banked file.\n");
00159                         return 0;
00160                 }
00161                 printf("Writing %d pages.\n", pages);
00162                 {       /*cut off extension*/
00163                         char *ptr = strrchr(conf_opts.ihex_file, '.');
00164                         if (ptr != NULL)
00165                         {
00166                                 *ptr = 0;
00167                         }
00168                 }
00169                 strcat(conf_opts.ihex_file, "_linear.hex");
00170                 printf("Output file: %s.\n", conf_opts.ihex_file);
00171                 ihex = fopen(conf_opts.ihex_file, "wb");
00172                 ext_addr=0;
00173                 addr = 0;
00174                 if (pages)
00175                 {
00176                         int j;
00177                         error = 0;
00178                         for (i=0; i<64; i++)
00179                         {
00180                                 addr = (i & 0x1F) * 2048;
00181                                 if ( ((i / 32) * 0x10000) != ext_addr)
00182                                 {       /*write out ext addr*/
00183                                         printf("Ext: %4.4X\n", ((i / 32) * 0x10000));
00184                                         ext_addr = (i / 32) * 0x10000;
00185                                         fprintf(ihex, ":02000004%4.4X%2.2X\r\n", 
00186                                                                                  (int)(ext_addr>>16), (int)(0xFA-(ext_addr>>16)));
00187                                 }
00188                                                                 
00189                                 if (page_table[i] != 0)
00190                                 {
00191                                         printf("%4.4X", addr & 0xF800);
00192                                         for (j=0; j<2048; j++)
00193                                         {
00194                                                 addr =(i & 0x1F) * 2048 + j;
00195                                                 if ((j & 0x1F) == 0)
00196                                                 {
00197                                                         check = 0;
00198                                                         check -= 0x20;
00199                                                         check -= (uint8_t) (addr >> 8);
00200                                                         check -= (uint8_t) (addr);
00201                                                         fprintf(ihex, ":20%4.4X00", (int) addr);
00202                                                 }
00203                                                 fprintf(ihex, "%2.2X", page_buffer[ext_addr+addr]);
00204                                                 check -= page_buffer[ext_addr+addr];
00205                                                 if ((j & 0x1F) == 0x1F)
00206                                                 {
00207                                                                 fprintf(ihex, "%2.2X\r\n", check);                                                              
00208                                                 }
00209                                         }
00210                                 }
00211                                 if ((i & 0x07) == 0x07) printf("\n");
00212                                 else printf(" ");
00213                         }
00214                         fprintf(ihex, ":00000001FF\r\n");
00215                         printf("Write complete.\n");
00216                 }
00217                 fclose(ihex);
00218         }
00219         else if(conf_opts.target_type == UNDEFINED)
00220         {
00221                 usage(argv[0]);
00222         }
00223         else
00224         {
00225                 printf("\nSensinode hex file converter "CONVERTER_VERSION "\n");
00226         }
00227         return error;
00228 }

Generated on Mon Apr 11 14:23:37 2011 for Contiki 2.5 by  doxygen 1.6.1