/*****************************************************************************/

/*
 *	ihex2hdr.c  --  Convert Intel HEX files to C header files.
 *
 *	Copyright (C) 1999-2001
 *          Thomas Sailer (t.sailer@alumni.ethz.ch)
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Please note that the GPL allows you to use the driver, NOT the radio.
 *  In order to use the radio, you need a license from the communications
 *  authority of your country.
 *
 *
 *  History:
 *   0.1  18.06.99  Created
 *
 */

/*****************************************************************************/

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <stdlib.h>

/* --------------------------------------------------------------------- */

static int hexdigit(const char *s)
{
	if (*s >= '0' && *s <= '9')
		return *s - '0';
	if (*s >= 'A' && *s <= 'F')
		return *s - 'A' + 10;
	if (*s >= 'a' && *s <= 'f')
		return *s - 'a' + 10;
	return -1;
}

static int hexbyte(const char *s)
{
	int a, b;

	a = hexdigit(s);
	b = hexdigit(s+1);
	if (a == -1 || b == -1)
		return -1;
	return (a << 4) | b;
}

/* --------------------------------------------------------------------- */

int main(int argc, char *argv[])
{
	FILE *fin, *fout;
	time_t tm;
	unsigned char mem[0x2000] = { 0, };
	unsigned char buf[640];
	unsigned u, s, sz = 0;
	int i;

	time(&tm);
	if (argc < 4) {
		fprintf(stderr, "usage: ihex2hdr file.ihx file.h fname\n");
		exit(1);
	}
	if (!(fin = fopen(argv[1], "r"))) {
		fprintf(stderr, "cannot open file \"%s\" error %s\n", argv[1], strerror(errno));
		exit(1);
	}
	if (!(fout = fopen(argv[2], "w"))) {
		fprintf(stderr, "cannot create file \"%s\" error %s\n", argv[2], strerror(errno));
		exit(1);
	}
	while (fgets(buf, sizeof(buf), fin)) {
		if (buf[0] != ':') {
			fprintf(stderr, "invalid intel hex line \"%s\"\n", buf);
			continue;
		}
		for (u = s = 0; u < ((unsigned int)buf[0])+5; u++) {
			i = hexbyte(buf+1+2*u);
			if (i == -1)
				goto nextline;
			buf[u] = i;
			s += i;
		}
		if ((s & 0xff) != 0) {
			fprintf(stderr, "checksum error in line length %u address 0x%02X%02X checksum %u\n",
				buf[0], buf[1], buf[2], s & 0xff);
			continue;
		}
		if (buf[3] != 0)
			break;
		if (buf[0] == 0)
			continue;
		u = buf[2] | (((unsigned int)buf[1]) << 8);  /* address */
		if (u + buf[0] > sz)
			sz = u + buf[0];
		if (sz > sizeof(mem)) {
			fprintf(stderr, "input hex file overflows memory table\n");
			exit(1);
		}
		memcpy(mem+u, buf+4, buf[0]);
	nextline:
	}
	fclose(fin);
	strftime(buf, sizeof(buf), "%Y%m%d", localtime(&tm));
	fprintf(fout, "/*****************************************************************************/\n"
		"\n"
		"/*\n"
		" *      %s  --  Anchorchips Firmware.\n"
		" *\n"
		" *      Copyright (C) 1999  Thomas Sailer (sailer@ife.ee.ethz.ch)\n"
		" *\n"
		" *      This program is free software; you can redistribute it and/or modify\n"
		" *      it under the terms of the GNU General Public License as published by\n"
		" *      the Free Software Foundation; either version 2 of the License, or\n"
		" *      (at your option) any later version.\n"
		" *\n"
		" *      This program is distributed in the hope that it will be useful,\n"
		" *      but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
		" *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
		" *      GNU General Public License for more details.\n"
		" *\n"
		" *      You should have received a copy of the GNU General Public License\n"
		" *      along with this program; if not, write to the Free Software\n"
		" *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
		" *\n"
		" *  Please note that the GPL allows you to use the driver, NOT the radio.\n"
		" *  In order to use the radio, you need a license from the communications\n"
		" *  authority of your country.\n"
		" *\n"
		" */\n"
		"\n"
		"/*****************************************************************************/\n"
		"/* automatically generated, do not edit */\n"
		"\n"
		"#define %s_DATE \"%s\"\n"
		"\n"
		"/* firmware */\n"
		"static const unsigned char %s[] = {", argv[2], argv[3], buf, argv[3]);
	for (u = 0; u < sz; u++) {
		if (!(u & 15))
			fprintf(fout, "\n\t");
		fprintf(fout, "0x%02x", mem[u]);
		if (u >= sz-1)
			break;
		fprintf(fout, ", ");
	}
	fprintf(fout, "\n};\n");
	fclose(fout);
	exit(0);
}
