diff --git a/cpu/cc2430/converter/Makefile b/cpu/cc2430/converter/Makefile new file mode 100644 index 000000000..7d58f8eeb --- /dev/null +++ b/cpu/cc2430/converter/Makefile @@ -0,0 +1,39 @@ +EXE_MAKE=$(notdir $(shell which "make.exe" 2>/dev/null)) +ifeq "$(EXE_MAKE)" "make.exe" +PLATFORM=windows +else +PLATFORM=linux +endif + +OBJECTS = ihex.o converter.o +SUBDIRS = + +CFLAGS = -Wall -D_REENTRANT -I. +LDFLAGS = -L. -D_REENTRANT -lpthread +ifeq "$(PLATFORM)" "linux" +SUFFIX= +else +SUFFIX=.exe +endif + +TARGET = converter$(SUFFIX) + +all: binary + +binary: $(TARGET) + strip $(TARGET) + +$(TARGET): $(OBJECTS) + gcc -o $(TARGET) $(OBJECTS) $(LDFLAGS) + +.c.o: + gcc -c -o $(<:.c=.o) -O2 -Wall $(CFLAGS) $< + +platform-test: + @echo $(PLATFORM) + +old-strip: + if [ -x $(TARGET).exe ]; then $(PLATFORM)strip $(TARGET).exe; else $(PLATFORM)strip $(TARGET); fi + +clean: + rm -f $(TARGET) $(OBJECTS) diff --git a/cpu/cc2430/converter/converter b/cpu/cc2430/converter/converter new file mode 100755 index 000000000..9b47ea14a Binary files /dev/null and b/cpu/cc2430/converter/converter differ diff --git a/cpu/cc2430/converter/converter.c b/cpu/cc2430/converter/converter.c new file mode 100644 index 000000000..7ce442bae --- /dev/null +++ b/cpu/cc2430/converter/converter.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include + +#include "converter.h" + +#include + +extern int cdi_programmer(conf_opts_t *conf, char *filename); + +void usage(char *prg_name) +{ + printf("\nUsage: %s -f ihex file\n", prg_name); + printf("General options:\n"); + printf(" -V/--version Get converter version\n"); +} + +conf_opts_t conf_opts; + +static int option_index = 0; + +int do_exit = 0; + +#define OPTIONS_STRING "Vhf:" +/* long option list */ +static struct option long_options[] = +{ + {"version", 0, NULL, 'V'}, + {"file", 1, NULL, 'f'}, + {"help", 0, NULL, 'h'}, + {0, 0, 0, 0} +}; + +int parse_opts(int count, char* param[]) +{ + int opt; + int error=0; + + conf_opts.target_type = UNDEFINED; + while ((opt = getopt_long(count, param, OPTIONS_STRING, + long_options, &option_index)) != -1) + { + switch(opt) + { + case 'V': + conf_opts.target_type = VERSION; + break; + + case 'h': + conf_opts.target_type = UNDEFINED; + break; + + case 'f': + strcpy(conf_opts.ihex_file, optarg); + conf_opts.target_type = CONVERT; + break; + } + } + + if (!error && (conf_opts.target_type == CONVERT) ) + { + printf("File: %s.\n", conf_opts.ihex_file); + } + + return error; +} + +int main(int argc, char *argv[]) +{ + int error = 0; + + conf_opts.target_type = 0; + + + if ( (argc < 1) || (error = parse_opts(argc, argv)) ) + { + usage(argv[0]); + if (error < 0) return error; + else return 0; + } + + if(conf_opts.target_type == CONVERT) + { /*Convert*/ + int pages; + int sdcc_file = 0; + + FILE *ihex = 0; + unsigned char check = 0; + unsigned long ext_addr=0; + unsigned short int addr=0; + unsigned char page_buffer[128*1024]; + unsigned char page_table[64]; + unsigned char buffer[256]; + int i; + int retval = 0; + + bzero(buffer, sizeof(buffer)); + + /*initialize page data*/ + memset(page_table, 0, 64); + memset(page_buffer, 0xFF, sizeof(page_buffer)); + pages = 0; + + ihex = fopen(conf_opts.ihex_file, "rb"); + if (ihex == 0) + { + printf("Can't open file.\n"); + return -1; + } + error = 0; + while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) ) + { + unsigned char data_len = 0; + + if (memcmp(&buffer[7], "00", 2) == 0) + { /*Data record*/ + i=0; + sscanf((char *)&buffer[1], "%2hhx", &data_len); + sscanf((char *)&(buffer[3]),"%4hx", &addr); + while(i= 0x0002) sdcc_file = 1; + + if (ext_addr) ext_addr--; + ext_addr *= 0x8000; + } + } + fclose(ihex); + if (retval == -1) + { + printf("Read error\n"); + } + if (sdcc_file == 0) + { + printf("Not a SDCC banked file.\n"); + return 0; + } + printf("Writing %d pages.\n", pages); + { /*cut off extension*/ + char *ptr = strrchr(conf_opts.ihex_file, '.'); + if (ptr != NULL) + { + *ptr = 0; + } + } + strcat(conf_opts.ihex_file, "_linear.hex"); + printf("Output file: %s.\n", conf_opts.ihex_file); + ihex = fopen(conf_opts.ihex_file, "wb"); + ext_addr=0; + addr = 0; + if (pages) + { + int j; + error = 0; + for (i=0; i<64; i++) + { + addr = (i & 0x1F) * 2048; + if ( ((i / 32) * 0x10000) != ext_addr) + { /*write out ext addr*/ + printf("Ext: %4.4X\n", ((i / 32) * 0x10000)); + ext_addr = (i / 32) * 0x10000; + fprintf(ihex, ":02000004%4.4X%2.2X\r\n", + (int)(ext_addr>>16), (int)(0xFA-(ext_addr>>16))); + } + + if (page_table[i] != 0) + { + printf("%4.4X", addr & 0xF800); + for (j=0; j<2048; j++) + { + addr =(i & 0x1F) * 2048 + j; + if ((j & 0x1F) == 0) + { + check = 0; + check -= 0x20; + check -= (uint8_t) (addr >> 8); + check -= (uint8_t) (addr); + fprintf(ihex, ":20%4.4X00", (int) addr); + } + fprintf(ihex, "%2.2X", page_buffer[ext_addr+addr]); + check -= page_buffer[ext_addr+addr]; + if ((j & 0x1F) == 0x1F) + { + fprintf(ihex, "%2.2X\r\n", check); + } + } + } + if ((i & 0x07) == 0x07) printf("\n"); + else printf(" "); + } + fprintf(ihex, ":00000001FF\r\n"); + printf("Write complete.\n"); + } + fclose(ihex); + } + else if(conf_opts.target_type == UNDEFINED) + { + usage(argv[0]); + } + else + { + printf("\nSensinode hex file converter "CONVERTER_VERSION "\n"); + } + return error; +} diff --git a/cpu/cc2430/converter/converter.h b/cpu/cc2430/converter/converter.h new file mode 100644 index 000000000..8457b1809 --- /dev/null +++ b/cpu/cc2430/converter/converter.h @@ -0,0 +1,13 @@ +#ifndef CONVERTER_H +#define CONVERTER_H + +#define CONVERTER_VERSION "v1.3" + +typedef struct { + int target_type; + char ihex_file[128]; +}conf_opts_t; + +enum target { UNDEFINED, VERSION, CONVERT }; + +#endif diff --git a/cpu/cc2430/converter/converter.o b/cpu/cc2430/converter/converter.o new file mode 100644 index 000000000..fa67f8fe1 Binary files /dev/null and b/cpu/cc2430/converter/converter.o differ diff --git a/cpu/cc2430/converter/ihex.c b/cpu/cc2430/converter/ihex.c new file mode 100644 index 000000000..fbed240b2 --- /dev/null +++ b/cpu/cc2430/converter/ihex.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#include + +int hexfile_parse(char *line, unsigned int *type, unsigned int *addr, unsigned char *buffer) +{ + unsigned int row_len = 0; + unsigned int row_index = 7; + unsigned int i; + int tmp; + + uint8_t cksum = 0; + int retval = 0; + + retval = sscanf(line, ":%2x%4x%2x", &row_len, addr, type); + + cksum += row_len; + cksum += *addr >> 8; + cksum += *addr & 0xFF; + cksum += *type; + + i = 0; + if (retval == 3) + { + while(i < row_len) + { + + if (sscanf(&line[row_index], "%2x", &tmp) == 1) + { + cksum += tmp; + buffer[i++] = (unsigned char) tmp; + row_index += 2; + } + else return -1; + } + if (sscanf(&line[row_index], "%2x", &tmp) == 1) + { + if ((cksum + (uint8_t) tmp) == 0) return row_len; + } + } + return -1; +} + +int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes) +{ + uint8_t cksum = 0; + uint8_t i = 0; + char tmp[8]; + + sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type); + cksum -= bytes; + cksum -= address >> 8; + cksum -= address & 0xFF; + cksum -= type; + + for (i=0; i