diff options
| author | Bdale Garbee <bdale@gag.com> | 2013-12-19 01:38:40 -0700 | 
|---|---|---|
| committer | Bdale Garbee <bdale@gag.com> | 2013-12-19 01:38:40 -0700 | 
| commit | 575bbaf976c5840fd0e308549c45a466fdec1352 (patch) | |
| tree | 11bfb498348bf7687bffc24699c4b1a998988ee4 /ao-tools/lib | |
| parent | b825116df173b77e2cab217a7b76112c742f9279 (diff) | |
| parent | bc3610d8cecbfed40c62d4dcb93fc9a4d2a7c9e3 (diff) | |
Merge branch 'branch-1.3' into debian
Conflicts:
	ChangeLog
	altoslib/AltosRecordMM.java
	altosui/Makefile.am
	altosui/altos-windows.nsi.in
	configure.ac
	debian/changelog
	debian/control
	doc/Makefile
	doc/altusmetrum.xsl
	doc/release-notes-1.2.1.xsl
	doc/release-notes-1.2.xsl
Diffstat (limited to 'ao-tools/lib')
| -rw-r--r-- | ao-tools/lib/Makefile.am | 14 | ||||
| -rw-r--r-- | ao-tools/lib/ao-editaltos.c | 153 | ||||
| -rw-r--r-- | ao-tools/lib/ao-editaltos.h | 50 | ||||
| -rw-r--r-- | ao-tools/lib/ao-elf.c | 325 | ||||
| -rw-r--r-- | ao-tools/lib/ao-elf.h | 28 | ||||
| -rw-r--r-- | ao-tools/lib/ao-hex.c | 626 | ||||
| -rw-r--r-- | ao-tools/lib/ao-hex.h | 82 | ||||
| -rw-r--r-- | ao-tools/lib/ao-selfload.c | 158 | ||||
| -rw-r--r-- | ao-tools/lib/ao-selfload.h | 37 | ||||
| -rw-r--r-- | ao-tools/lib/ao-verbose.c | 36 | ||||
| -rw-r--r-- | ao-tools/lib/ao-verbose.h | 32 | ||||
| -rw-r--r-- | ao-tools/lib/cc-mega.c | 160 | ||||
| -rw-r--r-- | ao-tools/lib/cc-telemetry.h | 69 | ||||
| -rw-r--r-- | ao-tools/lib/cc.h | 3 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg-command.c | 2 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg-flash.c | 2 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg-hex.c | 381 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg-memory.c | 8 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg-rom.c | 8 | ||||
| -rw-r--r-- | ao-tools/lib/ccdbg.h | 56 | 
20 files changed, 1787 insertions, 443 deletions
diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index 1f8f2e42..a03a976c 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -11,7 +11,6 @@ libao_tools_a_SOURCES = \  	ccdbg-debug.h \  	ccdbg-flash.c \  	ccdbg.h \ -	ccdbg-hex.c \  	ccdbg-io.c \  	ccdbg-manual.c \  	ccdbg-memory.c \ @@ -21,6 +20,7 @@ libao_tools_a_SOURCES = \  	cc-convert.c \  	cc-dsp.c \  	cc-integrate.c \ +	cc-mega.c \  	cc-period.c \  	cc-process.c \  	cc-usb.c \ @@ -39,4 +39,14 @@ libao_tools_a_SOURCES = \  	i0.c \  	chbevl.c \  	mconf.h \ -	cephes.h +	cephes.h \ +	ao-hex.c \ +	ao-hex.h \ +	ao-editaltos.c \ +	ao-editaltos.h \ +	ao-elf.c \ +	ao-elf.h \ +	ao-selfload.c \ +	ao-selfload.h \ +	ao-verbose.c \ +	ao-verbose.h diff --git a/ao-tools/lib/ao-editaltos.c b/ao-tools/lib/ao-editaltos.c new file mode 100644 index 00000000..a8b64098 --- /dev/null +++ b/ao-tools/lib/ao-editaltos.c @@ -0,0 +1,153 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <string.h> +#include <stdlib.h> +#include "ao-editaltos.h" + +struct ao_sym ao_symbols[] = { + +	{ 0, 0,	"ao_romconfig_version",	1 }, +	{ 0, 0,	"ao_romconfig_check",	1 }, +	{ 0, 0,	"ao_serial_number", 1 }, +	{ 0, 0,	"ao_radio_cal", 0 }, +	{ 0, 0,	"ao_usb_descriptors", 0 }, +}; + +#define NUM_SYMBOLS		5 + +int ao_num_symbols = NUM_SYMBOLS; + +/* + * Edit the to-be-written memory block + */ +static bool +rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) +{ +	int 		i; + +	if (address < load->address || load->address + load->length < address + length) +		return false; + +	printf("rewrite %04x:", address); +	for (i = 0; i < length; i++) +		printf (" %02x", load->data[address - load->address + i]); +	printf(" ->"); +	for (i = 0; i < length; i++) +		printf (" %02x", data[i]); +	printf("\n"); +	memcpy(load->data + address - load->address, data, length); +	return true; +} + +/* + * Find the symbols needed to correctly load the program + */ + +bool +ao_editaltos_find_symbols(struct ao_sym *file_symbols, int num_file_symbols, +			  struct ao_sym *symbols, int num_symbols) +{ +	int	f, s; + +	for (f = 0; f < num_file_symbols; f++) { +		for (s = 0; s < num_symbols; s++) { +			if (strcmp(symbols[s].name, file_symbols[f].name) == 0) { +				symbols[s].addr = file_symbols[f].addr; +				symbols[s].found = true; +			} +		} +	} +	for (s = 0; s < num_symbols; s++) +		if (!symbols[s].found && symbols[s].required) +			return false; +	return true; +} + +bool +ao_editaltos(struct ao_hex_image *image, +	     uint16_t serial, +	     uint32_t cal) +{ +	uint8_t			*serial_ucs2; +	int			serial_ucs2_len; +	uint8_t			serial_int[2]; +	unsigned int		s; +	int			i; +	int			string_num; +	uint8_t			cal_int[4]; + +	/* Write the config values into the flash image +	 */ + +	serial_int[0] = serial & 0xff; +	serial_int[1] = (serial >> 8) & 0xff; + +	if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { +		fprintf(stderr, "Cannot rewrite serial integer at %08x\n", +			AO_SERIAL_NUMBER); +		return false; +	} + +	if (AO_USB_DESCRIPTORS) { +		uint32_t	usb_descriptors = AO_USB_DESCRIPTORS - image->address; +		string_num = 0; + +		while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) { +			if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) { +				++string_num; +				if (string_num == 4) +					break; +			} +			usb_descriptors += image->data[usb_descriptors]; +		} +		if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) { +			fprintf(stderr, "Cannot rewrite serial string at %08x\n", AO_USB_DESCRIPTORS); +			return false; +		} + +		serial_ucs2_len = image->data[usb_descriptors] - 2; +		serial_ucs2 = malloc(serial_ucs2_len); +		if (!serial_ucs2) { +			fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); +			return false; +		} +		s = serial; +		for (i = serial_ucs2_len / 2; i; i--) { +			serial_ucs2[i * 2 - 1] = 0; +			serial_ucs2[i * 2 - 2] = (s % 10) + '0'; +			s /= 10; +		} +		if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len)) { +			fprintf (stderr, "Cannot rewrite USB descriptor at %08x\n", AO_USB_DESCRIPTORS); +			return false; +		} +	} + +	if (cal && AO_RADIO_CAL) { +		cal_int[0] = cal & 0xff; +		cal_int[1] = (cal >> 8) & 0xff; +		cal_int[2] = (cal >> 16) & 0xff; +		cal_int[3] = (cal >> 24) & 0xff; + +		if (!rewrite(image, AO_RADIO_CAL, cal_int, sizeof (cal_int))) { +			fprintf(stderr, "Cannot rewrite radio calibration at %08x\n", AO_RADIO_CAL); +			return false; +		} +	} +	return true; +} diff --git a/ao-tools/lib/ao-editaltos.h b/ao-tools/lib/ao-editaltos.h new file mode 100644 index 00000000..74530435 --- /dev/null +++ b/ao-tools/lib/ao-editaltos.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_EDITALTOS_H_ +#define _AO_EDITALTOS_H_ + +#include <stdint.h> +#include <stdbool.h> +#include "ao-hex.h" + +extern struct ao_sym ao_symbols[]; +extern int ao_num_symbols; + +#define AO_USB_DESC_STRING		3 + +#define AO_ROMCONFIG_VERSION	(ao_symbols[0].addr) +#define AO_ROMCONFIG_CHECK	(ao_symbols[1].addr) +#define AO_SERIAL_NUMBER	(ao_symbols[2].addr) +#define AO_RADIO_CAL		(ao_symbols[3].addr) +#define AO_USB_DESCRIPTORS	(ao_symbols[4].addr) + +struct ao_editaltos_funcs { +	uint16_t	(*get_uint16)(void *closure, uint32_t addr); +	uint32_t	(*get_uint32)(void *closure, uint32_t addr); +}; + +bool +ao_editaltos_find_symbols(struct ao_sym *file_symbols, int num_file_symbols, +			  struct ao_sym *symbols, int num_symbols); + +bool +ao_editaltos(struct ao_hex_image *image, +	     uint16_t serial, +	     uint32_t radio_cal); + +#endif /* _AO_EDITALTOS_H_ */ diff --git a/ao-tools/lib/ao-elf.c b/ao-tools/lib/ao-elf.c new file mode 100644 index 00000000..99b37210 --- /dev/null +++ b/ao-tools/lib/ao-elf.c @@ -0,0 +1,325 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <err.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "ao-elf.h" +#include "ao-hex.h" +#include "ao-verbose.h" + +/* + * Look through the Elf file for symbols that can be adjusted before + * the image is written to the device + */ +static struct ao_sym * +load_symbols (Elf *e, int *num_symbolsp) +{ +	Elf_Scn 	*scn; +	Elf_Data	*symbol_data = NULL; +	GElf_Shdr	shdr; +	GElf_Sym       	sym; +	int		i, symbol_count; +	char		*symbol_name; +	size_t		shstrndx; +	struct ao_sym	*symbols = NULL; +	struct ao_sym	*symbol; +	int		num_symbols = 0; +	int		size_symbols = 0; + +	if (elf_getshdrstrndx(e, &shstrndx) < 0) +		return false; + +	/* +	 * Find the symbols +	 */ + +	scn = NULL; +	while ((scn = elf_nextscn(e, scn)) != NULL) { + +		if (gelf_getshdr(scn, &shdr) != &shdr) +			return false; + +		if (shdr.sh_type == SHT_SYMTAB) { +			symbol_data = elf_getdata(scn, NULL); +			symbol_count = shdr.sh_size / shdr.sh_entsize; +			break; +		} +	} + +	if (!symbol_data) +		return NULL; + +	for (i = 0; i < symbol_count; i++) { +		gelf_getsym(symbol_data, i, &sym); + +		symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); +		if (!symbol_name[0]) +			continue; + +		if (num_symbols == size_symbols) { +			struct ao_sym	*new_symbols; +			int		new_size; + +			if (!size_symbols) +				new_size = 16; +			else +				new_size = size_symbols * 2; +			new_symbols = realloc(symbols, new_size * sizeof (struct ao_sym)); +			if (!new_symbols) +				goto bail; + +			symbols = new_symbols; +			size_symbols = new_size; +		} +		symbol = &symbols[num_symbols]; +		memset(symbol, 0, sizeof (struct ao_sym)); +		symbol->name = strdup(symbol_name); +		if (!symbol->name) +			goto bail; +		symbol->addr = sym.st_value; +		ao_printf(AO_VERBOSE_EXE, "Add symbol %s: %08x\n", symbol->name, symbol->addr); +		num_symbols++; +	} +	*num_symbolsp = num_symbols; +	return symbols; +bail: +	for (i = 0; i < num_symbols; i++) +		free(symbols[i].name); +	free(symbols); +	return NULL; +} + +static uint32_t +round4(uint32_t a) { +	return (a + 3) & ~3; +} + +static struct ao_hex_image * +new_load (uint32_t addr, uint32_t len) +{ +	struct ao_hex_image *new; + +	len = round4(len); +	new = calloc (1, sizeof (struct ao_hex_image) + len); +	if (!new) +		abort(); + +	new->address = addr; +	new->length = len; +	return new; +} + +static void +load_paste(struct ao_hex_image *into, struct ao_hex_image *from) +{ +	if (from->address < into->address || into->address + into->length < from->address + from->length) +		abort(); + +	memcpy(into->data + from->address - into->address, from->data, from->length); +} + +/* + * Make a new load structure large enough to hold the old one and + * the new data + */ +static struct ao_hex_image * +expand_load(struct ao_hex_image *from, uint32_t address, uint32_t length) +{ +	struct ao_hex_image	*new; + +	if (from) { +		uint32_t	from_last = from->address + from->length; +		uint32_t	last = address + length; + +		if (address > from->address) +			address = from->address; +		if (last < from_last) +			last = from_last; + +		length = last - address; + +		if (address == from->address && length == from->length) +			return from; +	} +	new = new_load(address, length); +	if (from) { +		load_paste(new, from); +		free (from); +	} +	return new; +} + +/* + * Create a new load structure with data from the existing one + * and the new data + */ +static struct ao_hex_image * +load_write(struct ao_hex_image *from, uint32_t address, uint32_t length, void *data) +{ +	struct ao_hex_image	*new; + +	new = expand_load(from, address, length); +	memcpy(new->data + address - new->address, data, length); +	return new; +} + +/* + * Construct a large in-memory block for all + * of the loaded sections of the program + */ +static struct ao_hex_image * +get_load(Elf *e) +{ +	Elf_Scn 	*scn; +	size_t		shstrndx; +	GElf_Shdr	shdr; +	Elf_Data	*data; +	size_t		nphdr; +	size_t		p; +	GElf_Phdr	phdr; +	GElf_Addr	sh_paddr; +	struct ao_hex_image	*load = NULL; +#if 0 +	char		*section_name; +#endif +	size_t		nshdr; +	size_t		s; +	 +	if (elf_getshdrstrndx(e, &shstrndx) < 0) +		return 0; + +	if (elf_getphdrnum(e, &nphdr) < 0) +		return 0; + +	if (elf_getshdrnum(e, &nshdr) < 0) +		return 0; + +	/* +	 * As far as I can tell, all of the phdr sections should +	 * be flashed to memory +	 */ +	for (p = 0; p < nphdr; p++) { + +		/* Find this phdr */ +		gelf_getphdr(e, p, &phdr); + +		if (phdr.p_type != PT_LOAD) +			continue; + +		/* Get the associated file section */ + +#if 0 +		fprintf (stderr, "offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", +			 (uint32_t) phdr.p_offset, +			 (uint32_t) phdr.p_vaddr, +			 (uint32_t) phdr.p_paddr, +			 (uint32_t) phdr.p_filesz, +			 (uint32_t) phdr.p_memsz); +#endif +		 +		for (s = 0; s < nshdr; s++) { +			scn = elf_getscn(e, s); + +			if (!scn) { +				fprintf (stderr, "getscn failed\n"); +				abort(); +			} +			if (gelf_getshdr(scn, &shdr) != &shdr) { +				fprintf (stderr, "gelf_getshdr failed\n"); +				abort(); +			} + +#if 0 +			section_name = elf_strptr(e, shstrndx, shdr.sh_name); +#endif + +			if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { +					 +				if (shdr.sh_size == 0) +					continue; + +				sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + +#if 0 +				fprintf (stderr, "\tsize %08x rom %08x exec %08x %s\n", +					 (uint32_t) shdr.sh_size, +					 (uint32_t) sh_paddr, +					 (uint32_t) shdr.sh_addr, +					 section_name); +#endif + +				data = elf_getdata(scn, NULL); + +				/* Write the section data into the memory block */ +				load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); +			} +		} +	} +	return load; +} + +/* + * Open the specified ELF file and + * check for the symbols we need + */ + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_sym **symbols, int *num_symbols) +{ +	int		fd; +	Elf		*e; +	size_t		shstrndx; +	struct ao_hex_image	*image; + +	if (elf_version(EV_CURRENT) == EV_NONE) +		return NULL; + +	fd = open(name, O_RDONLY, 0); + +	if (fd < 0) +		return NULL; + +	e = elf_begin(fd, ELF_C_READ, NULL); + +	if (!e) +		return NULL; + +	if (elf_kind(e) != ELF_K_ELF) +		return NULL; + +	if (elf_getshdrstrndx(e, &shstrndx) != 0) +		return NULL; + +	if (symbols) +		*symbols = load_symbols(e, num_symbols); + +	image = get_load(e); +	if (!image) { +		fprintf (stderr, "Cannot create memory image from file\n"); +		return NULL; +	} + +	return image; +} diff --git a/ao-tools/lib/ao-elf.h b/ao-tools/lib/ao-elf.h new file mode 100644 index 00000000..0f79d142 --- /dev/null +++ b/ao-tools/lib/ao-elf.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ELF_H_ +#define _AO_ELF_H_ + +#include <stdbool.h> +#include <gelf.h> +#include "ao-hex.h" + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_sym **symbols, int *num_symbols); + +#endif /* _AO_ELF_H_ */ diff --git a/ao-tools/lib/ao-hex.c b/ao-tools/lib/ao-hex.c new file mode 100644 index 00000000..5cfc63c1 --- /dev/null +++ b/ao-tools/lib/ao-hex.c @@ -0,0 +1,626 @@ +/* + * Copyright © 2008 Keith Packard <keithp@keithp.com> + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <stdarg.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include "ao-hex.h" +#include "ao-verbose.h" + +struct ao_hex_input { +	FILE	*file; +	int	line; +	char	*name; +}; + +enum ao_hex_read_state { +	read_marker, +	read_length, +	read_address, +	read_type, +	read_data, +	read_checksum, +	read_newline, +	read_white, +	read_done, +}; + + +static void +ao_hex_error(struct ao_hex_input *input, char *format, ...) +{ +	va_list ap; + +	va_start(ap, format); +	fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); +	vfprintf(stderr, format, ap); +	fprintf(stderr, "\n"); +	va_end(ap); +} + +static void +ao_hex_free(struct ao_hex_record *record) +{ +	if (!record) return; +	free(record); +} + +static struct ao_hex_record * +ao_hex_alloc(uint8_t length) +{ +	struct ao_hex_record *record; + +	record = calloc(1, sizeof(struct ao_hex_record) + length); +	record->length = length; +	return record; +} + +static int +ishex(char c) +{ +	return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); +} + +static int +fromhex(char c) +{ +	if (isdigit(c)) +		return c - '0'; +	if ('a' <= c && c <= 'f') +		return c - 'a' + 10; +	if ('A' <= c && c <= 'F') +		return c - 'A' + 10; +	abort(); +	return 0; +} + +static uint8_t +ao_hex_checksum(struct ao_hex_record *record) +{ +	uint8_t	checksum = 0; +	int i; + +	checksum += record->length; +	checksum += record->address >> 8; +	checksum += record->address & 0xff; +	checksum += record->type; +	for (i = 0; i < record->length; i++) +		checksum += record->data[i]; +	return -checksum; +} + +static struct ao_hex_record * +ao_hex_read_record(struct ao_hex_input *input) +{ +	struct ao_hex_record *record = NULL; +	enum ao_hex_read_state state = read_marker; +	char c; +	int nhexbytes; +	uint32_t hex; +	uint32_t ndata; +	uint8_t checksum; + +	while (state != read_done) { +		c = getc(input->file); +		if (c == EOF && state != read_white && state != read_marker) { +			ao_hex_error(input, "Unexpected EOF"); +			goto bail; +		} +		if (c == ' ') +			continue; +		if (c == '\n') +			input->line++; +		switch (state) { +		case read_marker: +			if (c == EOF) +				return NULL; +			if (c != ':') { +				ao_hex_error(input, "Missing ':'"); +				goto bail; +			} +			state = read_length; +			nhexbytes = 2; +			hex = 0; +			break; +		case read_length: +		case read_address: +		case read_type: +		case read_data: +		case read_checksum: +			if (!ishex(c)) { +				ao_hex_error(input, "Non-hex char '%c'", +						c); +				goto bail; +			} +			hex = hex << 4 | fromhex(c); +			--nhexbytes; +			if (nhexbytes != 0) +				break; + +			switch (state) { +			case read_length: +				record = ao_hex_alloc(hex); +				if (!record) { +					ao_hex_error(input, "Out of memory"); +					goto bail; +				} +				state = read_address; +				nhexbytes = 4; +				break; +			case read_address: +				record->address = hex; +				state = read_type; +				nhexbytes = 2; +				break; +			case read_type: +				record->type = hex; +				state = read_data; +				nhexbytes = 2; +				ndata = 0; +				break; +			case read_data: +				record->data[ndata] = hex; +				ndata++; +				nhexbytes = 2; +				break; +			case read_checksum: +				record->checksum = hex; +				state = read_newline; +				break; +			default: +				break; +			} +			if (state == read_data) +				if (ndata == record->length) { +					nhexbytes = 2; +					state = read_checksum; +				} +			hex = 0; +			break; +		case read_newline: +			if (c != '\n' && c != '\r') { +				ao_hex_error(input, "Missing newline"); +				goto bail; +			} +			state = read_white; +			break; +		case read_white: +			if (!isspace(c)) { +				if (c == '\n') +					input->line--; +				if (c != EOF) +					ungetc(c, input->file); +				state = read_done; +			} +			break; +		case read_done: +			break; +		} +	} +	checksum = ao_hex_checksum(record); +	if (checksum != record->checksum) { +		ao_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", +				record->checksum, checksum); +		goto bail; +	} +	return record; + +bail: +	ao_hex_free(record); +	return NULL; +} + +void +ao_hex_file_free(struct ao_hex_file *hex) +{ +	int	i; + +	if (!hex) +		return; +	for (i = 0; i < hex->nrecord; i++) +		ao_hex_free(hex->records[i]); +	free(hex); +} + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name) +{ +	struct ao_hex_input input; +	struct ao_hex_file	*hex = NULL, *newhex; +	struct ao_hex_record *record; +	int srecord = 1; +	int done = 0; + +	hex = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *), 1); +	if (!hex) +		return NULL; +	input.name = name; +	input.line = 1; +	input.file = file; +	while (!done) { +		record = ao_hex_read_record(&input); +		if (!record) { +			if (feof(input.file)) { +				done = 1; +				break; +			} else +				goto bail; +		} +		if (hex->nrecord == srecord) { +			srecord *= 2; +			newhex = realloc(hex, +					 sizeof (struct ao_hex_file) + +					 srecord * sizeof (struct ao_hex_record *)); +			if (!newhex) +				goto bail; +			hex = newhex; +		} +		hex->records[hex->nrecord++] = record; +	} +	return hex; + +bail: +	ao_hex_file_free(hex); +	return NULL; +} + +static struct ao_sym * +load_symbols(struct ao_hex_file *hex, +	     int *num_symbolsp) +{ +	uint32_t		extended_addr; +	uint32_t		addr; +	int			i; +	struct ao_hex_record	*record; +	struct ao_sym		*symbols = NULL; +	struct ao_sym		*symbol; +	int			num_symbols = 0; +	int			size_symbols = 0; +	 +	extended_addr = 0; +	for (i = 0; i < hex->nrecord; i++) { +		record = hex->records[i]; +		switch (record->type) { +		case AO_HEX_RECORD_NORMAL: +			addr = extended_addr + record->address; +			break; +		case AO_HEX_RECORD_EOF: +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_4: +			if (record->length != 2) +				goto bail; +			extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_8: +			if (record->length != 2) +				goto bail; +			extended_addr = (record->data[0] << 24) | (record->data[1] << 16); +			break; +		case AO_HEX_RECORD_SYMBOL: +			addr = extended_addr + record->address; +			if (num_symbols == size_symbols) { +				struct ao_sym	*new_symbols; +				int		new_size; + +				if (!size_symbols) +					new_size = 16; +				else +					new_size = size_symbols * 2; +				new_symbols = realloc(symbols, new_size * sizeof (struct ao_sym)); +				if (!new_symbols) +					goto bail; + +				symbols = new_symbols; +				size_symbols = new_size; +			} +			symbol = &symbols[num_symbols]; +			memset(symbol, 0, sizeof (struct ao_sym)); +			symbol->name = calloc(record->length + 1, 1); +			if (!symbol->name) +				goto bail; +			memcpy(symbol->name, record->data, record->length); +			symbol->addr = addr; +			ao_printf(AO_VERBOSE_EXE, "Add symbol %s: %08x\n", symbol->name, symbol->addr); +			num_symbols++; +			break; +		} +	} +	*num_symbolsp = num_symbols; +	return symbols; +bail: +	for (i = 0; i < num_symbols; i++) +		free(symbols[i].name); +	free(symbols); +	return NULL; +} + +static void +ao_hex_record_set_checksum(struct ao_hex_record *record) +{ +	uint8_t	cksum = 0; +	int i; + +	cksum += record->length; +	cksum += record->address >> 8; +	cksum += record->address; +	cksum += record->type; +	for (i = 0; i < record->length; i++) +		cksum += record->data[i]; + +	record->checksum = -cksum; +} + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex) +{ +	struct ao_hex_image *image; +	struct ao_hex_record *record; +	int i; +	uint32_t addr; +	uint32_t base, bound; +	uint32_t offset; +	uint32_t extended_addr; + +	int length; + +	/* Find the address bounds of the file +	 */ +	base = 0xffffffff; +	bound = 0x0; +	extended_addr = 0; +	for (i = 0; i < hex->nrecord; i++) { +		uint32_t r_bound; +		record = hex->records[i]; +		switch (record->type) { +		case AO_HEX_RECORD_NORMAL: +			addr = extended_addr + record->address; +			r_bound = addr + record->length; +			if (addr < base) +				base = addr; +			if (r_bound > bound) +				bound = r_bound; +			break; +		case AO_HEX_RECORD_EOF: +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_4: +			if (record->length != 2) +				return NULL; +			extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_8: +			if (record->length != 2) +				return NULL; +			extended_addr = (record->data[0] << 24) | (record->data[1] << 16); +			break; +		case AO_HEX_RECORD_SYMBOL: +			break; +		} +	} +	length = bound - base; +	image = calloc(sizeof(struct ao_hex_image) + length, 1); +	if (!image) +		return NULL; +	image->address = base; +	image->length = length; +	memset(image->data, 0xff, length); +	extended_addr = 0; +	for (i = 0; i < hex->nrecord; i++) { +		record = hex->records[i]; +		switch (record->type) { +		case AO_HEX_RECORD_NORMAL: +			addr = extended_addr + record->address; +			offset = addr - base; +			memcpy(image->data + offset, record->data, record->length); +			break; +		case AO_HEX_RECORD_EOF: +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_4: +			extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; +			break; +		case AO_HEX_RECORD_EXTENDED_ADDRESS_8: +			extended_addr = (record->data[0] << 24) | (record->data[1] << 16); +			break; +		case AO_HEX_RECORD_SYMBOL: +			break; +		} +	} +	return image; +} + +void +ao_hex_image_free(struct ao_hex_image *image) +{ +	free(image); +} + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b) +{ +	if (a->length != b->length) +		return 0; +	if (memcmp(a->data, b->data, a->length) != 0) +		return 0; +	return 1; +} + +struct ao_hex_image * +ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbolsp) +{ +	FILE			*file; +	struct ao_hex_file	*hex_file; +	struct ao_hex_image	*hex_image; + +	file = fopen (filename, "r"); +	if (!file) +		return NULL; +	 +	hex_file = ao_hex_file_read(file, filename); +	fclose(file); +	if (!hex_file) +		return NULL; +	hex_image = ao_hex_image_create(hex_file); +	if (!hex_image) +		return NULL; + +	if (symbols) +		*symbols = load_symbols(hex_file, num_symbolsp); + +	ao_hex_file_free(hex_file); +	return hex_image; +} + +#define BYTES_PER_RECORD	32 + +static struct ao_hex_file * +ao_hex_file_create(struct ao_hex_image *image, struct ao_sym *symbols, int num_symbols) +{ +	/* split data into n-byte-sized chunks */ +	uint32_t		data_records = (image->length + BYTES_PER_RECORD-1) / BYTES_PER_RECORD; +	/* extended address and data for each block, EOF, address and data for each symbol */ +	uint32_t		total_records = data_records * 2 + 1 + num_symbols * 2; +	uint32_t		offset; +	uint32_t		address; +	uint32_t		length; +	char			*name; +	struct ao_hex_file	*hex_file; +	int			nrecord = 0; +	int			s; +	struct ao_hex_record	*record; + +	hex_file = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *) * total_records, 1); +	if (!hex_file) +		return NULL; + +	/* Add the data +	 */ +	for (offset = 0; offset < image->length; offset += BYTES_PER_RECORD) { +		uint32_t		address = image->address + offset; +		uint32_t		length = image->length - offset; + +		if (length > BYTES_PER_RECORD) +			length = BYTES_PER_RECORD; + +		record = calloc(sizeof (struct ao_hex_record) + 2, 1); +		record->type = AO_HEX_RECORD_EXTENDED_ADDRESS_8; +		record->address = 0; +		record->length = 2; +		record->data[0] = address >> 24; +		record->data[1] = address >> 16; +		ao_hex_record_set_checksum(record); + +		hex_file->records[nrecord++] = record; + +		record = calloc(sizeof (struct ao_hex_record) + length, 1); +		record->type = AO_HEX_RECORD_NORMAL; +		record->address = address; +		record->length = length; +		memcpy(record->data, image->data + offset, length); +		ao_hex_record_set_checksum(record); + +		hex_file->records[nrecord++] = record; +	} + +	/* Stick an EOF after the data +	 */ +	record = calloc(sizeof (struct ao_hex_record), 1); +	record->type = AO_HEX_RECORD_EOF; +	record->address = 0; +	record->length = 0; +	record->data[0] = 0; +	record->data[1] = 0; +	ao_hex_record_set_checksum(record); + +	hex_file->records[nrecord++] = record; +	 +	/* Add the symbols +	 */ + +	for (s = 0; s < num_symbols; s++) { + +		name = symbols[s].name; +		address = symbols[s].addr; +		length = strlen (name); + +		record = calloc(sizeof (struct ao_hex_record) + 2, 1); +		record->type = AO_HEX_RECORD_EXTENDED_ADDRESS_8; +		record->address = 0; +		record->length = 2; +		record->data[0] = address >> 24; +		record->data[1] = address >> 16; +		ao_hex_record_set_checksum(record); + +		hex_file->records[nrecord++] = record; + +		record = calloc(sizeof (struct ao_hex_record) + length, 1); +		record->type = AO_HEX_RECORD_SYMBOL; +		record->address = address; +		record->length = length; +		memcpy(record->data, name, length); +		ao_hex_record_set_checksum(record); + +		hex_file->records[nrecord++] = record; +	} + +	hex_file->nrecord = nrecord; +	return hex_file; +} + +static bool +ao_hex_write_record(FILE *file, struct ao_hex_record *record) +{ +	int	i; + +	fputc(':', file); +	fprintf(file, "%02x", record->length); +	fprintf(file, "%04x", record->address); +	fprintf(file, "%02x", record->type); +	for (i = 0; i < record->length; i++) +		fprintf(file, "%02x", record->data[i]); +	fprintf(file, "%02x", record->checksum); +	fputc('\n', file); +	return true; +} + +bool +ao_hex_save(FILE *file, struct ao_hex_image *image, +	    struct ao_sym *symbols, int num_symbols) +{ +	struct ao_hex_file	*hex_file; +	int			i; +	bool			ret = false; + +	hex_file = ao_hex_file_create(image, symbols, num_symbols); +	if (!hex_file) +		goto create_failed; + +	for (i = 0; i < hex_file->nrecord; i++) { +		if (!ao_hex_write_record(file, hex_file->records[i])) +			goto write_failed; +	} +	ret = true; +	 +	if (fflush(file) != 0) +		ret = false; +write_failed: +	ao_hex_file_free(hex_file); +create_failed: +	return ret; +} diff --git a/ao-tools/lib/ao-hex.h b/ao-tools/lib/ao-hex.h new file mode 100644 index 00000000..98497460 --- /dev/null +++ b/ao-tools/lib/ao-hex.h @@ -0,0 +1,82 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_HEX_H_ +#define _AO_HEX_H_ + +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> + +#define AO_HEX_RECORD_NORMAL			0x00 +#define AO_HEX_RECORD_EOF			0x01 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_4	0x02 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_8	0x04 +#define AO_HEX_RECORD_SYMBOL			0xfe + +/* Intel hex file format data + */ +struct ao_hex_record { +	uint8_t	length; +	uint16_t address; +	uint8_t type; +	uint8_t checksum; +	uint8_t data[0]; +}; + +struct ao_hex_file { +	int			nrecord; +	struct ao_hex_record	*records[0]; +}; + +struct ao_hex_image { +	uint32_t	address; +	uint32_t	length; +	uint8_t		data[0]; +}; + +struct ao_sym { +	unsigned	addr; +	unsigned	default_addr; +	char		*name; +	bool		required; +	bool		found; +}; + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name); + +void +ao_hex_file_free(struct ao_hex_file *hex); + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex); + +void +ao_hex_image_free(struct ao_hex_image *image); + +struct ao_hex_image * +ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbols); + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b); + +bool +ao_hex_save(FILE *file, struct ao_hex_image *image, +	    struct ao_sym *symbols, int num_symbols); + +#endif /* _AO_HEX_H_ */ diff --git a/ao-tools/lib/ao-selfload.c b/ao-tools/lib/ao-selfload.c new file mode 100644 index 00000000..41e45adc --- /dev/null +++ b/ao-tools/lib/ao-selfload.c @@ -0,0 +1,158 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <sysexits.h> +#include <unistd.h> +#include <string.h> +#include "ao-hex.h" +#include "ao-selfload.h" +#include "ao-verbose.h" + +#define TRACE(...) ao_printf(AO_VERBOSE_SELF, __VA_ARGS__) + +static void +ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ +	int			byte; +	cc_usb_sync(cc); +	cc_usb_printf(cc, "R %x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		block[byte] = cc_usb_getchar(cc); +	} +	TRACE ("\nread %08x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		TRACE (" %02x", block[byte]); +		if ((byte & 0xf) == 0xf) +			TRACE ("\n"); +	} +} + +static void +ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ +	int			byte; +	cc_usb_sync(cc); +	cc_usb_printf(cc, "W %x\n", address); +	TRACE ("write %08x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		TRACE (" %02x", block[byte]); +		if ((byte & 0xf) == 0xf) +			TRACE ("\n"); +	} +	for (byte = 0; byte < 0x100; byte++) { +		cc_usb_printf(cc, "%c", block[byte]); +	} +} + +struct ao_hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) +{ +	struct ao_hex_image	*image; +	int			pages; +	int			page; +	uint32_t		base = address & ~0xff; +	uint32_t		bound = (address + length + 0xff) & ~0xff; + +	image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); +	image->address = base; +	image->length = bound - base; +	pages = image->length / 0x100; +	for (page = 0; page < pages; page++) +		ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100); +	return image; +} + +bool +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) +{ +	uint8_t		block[256]; +	uint8_t		check[256]; +	uint32_t	base, bound, length, address; +	uint32_t	pages; +	uint32_t	page; + +	base = image->address & ~0xff; +	bound = (image->address + image->length + 0xff) & ~0xff; + +	address = base; +	length = bound - base; + +	pages = length / 0x100; +	printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout); +	for (page = 0; page < pages; page++) { +		uint32_t	start, stop; +		address = base + page * 0x100; + +		if (address < image->address || address + 0x100 > image->address + image->length) { +			ao_self_block_read(cc, address, block); +		} +		start = address; +		stop = address + 0x100; +		if (start < image->address) +			start = image->address; +		if (stop > image->address + image->length) +			stop = image->address + image->length; +		memcpy(block + start - address, image->data + start - image->address, stop - start); +		ao_self_block_write(cc, address, block); +		ao_self_block_read(cc, address, check); +		if (memcmp(block, check, 0x100) != 0) { +			fprintf(stderr, "Block at 0x%08x doesn't match\n", address); +			return 0; +		} +		putchar('.'); fflush(stdout); +	} +	printf("done\n"); +	cc_usb_printf(cc,"a\n"); +	return 1; +} + +/* + * Read a 16-bit value from the USB target + */ + +uint16_t +ao_self_get_uint16(struct cc_usb *cc, uint32_t addr) +{ +	struct ao_hex_image	*hex = ao_self_read(cc, addr, 2); +	uint16_t		v; +	uint8_t			*data; + +	if (!hex) +		return 0; +	data = hex->data + addr - hex->address; +	v = data[0] | (data[1] << 8); +	free(hex); +	return v; +} + +uint32_t +ao_self_get_uint32(struct cc_usb *cc, uint32_t addr) +{ +	struct ao_hex_image	*hex = ao_self_read(cc, addr, 4); +	uint32_t		v; +	uint8_t			*data; + +	if (!hex) +		return 0; +	data = hex->data + addr - hex->address; +	v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); +	free(hex); +	return v; +} diff --git a/ao-tools/lib/ao-selfload.h b/ao-tools/lib/ao-selfload.h new file mode 100644 index 00000000..a001a404 --- /dev/null +++ b/ao-tools/lib/ao-selfload.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_SELFLOAD_H_ +#define _AO_SELFLOAD_H_ + +#include <stdbool.h> +#include "ao-hex.h" +#include "cc-usb.h" + +struct ao_hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); + +bool +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image); + +uint16_t +ao_self_get_uint16(struct cc_usb *cc, uint32_t addr); + +uint32_t +ao_self_get_uint32(struct cc_usb *cc, uint32_t addr); + +#endif /* _AO_SELFLOAD_H_ */ diff --git a/ao-tools/lib/ao-verbose.c b/ao-tools/lib/ao-verbose.c new file mode 100644 index 00000000..a1678ed1 --- /dev/null +++ b/ao-tools/lib/ao-verbose.c @@ -0,0 +1,36 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao-verbose.h" +#include <stdio.h> + +uint32_t	ao_verbose; + +void +ao_printf(uint32_t verbose, const char *format, ...) +{ +	va_list	args; + +	if (!(ao_verbose & verbose)) +		return; + +	va_start(args, format); +	vprintf(format, args); +	va_end(args); +} + + diff --git a/ao-tools/lib/ao-verbose.h b/ao-tools/lib/ao-verbose.h new file mode 100644 index 00000000..26c2fe41 --- /dev/null +++ b/ao-tools/lib/ao-verbose.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_VERBOSE_H_ +#define _AO_VERBOSE_H_ + +#include <stdint.h> +#include <stdarg.h> + +uint32_t	ao_verbose; + +#define AO_VERBOSE_EXE	1 +#define AO_VERBOSE_SELF	2 + +void +ao_printf(uint32_t verbose, const char *format, ...); + +#endif /* _AO_VERBOSE_H_ */ diff --git a/ao-tools/lib/cc-mega.c b/ao-tools/lib/cc-mega.c new file mode 100644 index 00000000..3aa24a6d --- /dev/null +++ b/ao-tools/lib/cc-mega.c @@ -0,0 +1,160 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "cc.h" +#include <string.h> +#include <ctype.h> + +static const char * +parse_hex(const char *data, int *result) +{ +	char	d[12]; +	int 	x; +	int	i; + +	while (isspace (*data)) +		data++; +	for (i = 0; i < sizeof (d) - 1 && isxdigit(*data); i++) +		d[i] = *data++; +	d[i] = '\0'; +	if (sscanf(d, "%x", &x) != 1) +		return NULL; +	*result = x; +	return data; +} + +static const char * +parse_uint16(const char *data, uint16_t *result) +{ +	int	x; +	data = parse_hex(data, &x); +	*result =x; +	return data; +} + +static const char * +parse_uint8(const char *data, uint8_t *result) +{ +	int	x; +	data = parse_hex(data, &x); +	*result =x; +	return data; +} + +static int +parse_eeprom(const char *input_line, struct ao_log_mega *l) { +	const char	*line; +	int	b; + +	if (input_line[1] != ' ') +		return 0; +	if (!isupper(input_line[0])) +		return 0; + +	l->type = input_line[0]; +	l->is_config = 0; +	line = input_line + 2; + +	line = parse_uint16(line, &l->tick); +	for (b = 0; b < 28; b++) { +		if (!line) +			return 0; +		line = parse_uint8(line, &l->u.bytes[b]); +	} +	return 1; +} + +#define YUP(t) do {				\ +		l->u.config_int.kind = (t);	\ +		l->is_config = 1;		\ +		return 1;			\ +	} while (0); + +static int +parse_config(const char *input_line, struct ao_log_mega *l) { +	if (sscanf (input_line, "Config version: %d.%d", +		    &l->u.config_int.data[0], +		    &l->u.config_int.data[1])) +		YUP(AO_CONFIG_CONFIG); +	if (sscanf (input_line, "Main deploy: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MAIN); +	if (sscanf (input_line, "Apogee delay: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_APOGEE); +	if (sscanf (input_line, "Apogee lockout: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_LOCKOUT); +	if (sscanf (input_line, "Frequency: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_FREQUENCY); +	if (sscanf (input_line, "Radio enable:  %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_RADIO_ENABLE); +	if (sscanf (input_line, "Accel cal +1g: %d -1g: %d", +		    &l->u.config_int.data[0], +		    &l->u.config_int.data[1])) +		YUP(AO_CONFIG_ACCEL_CAL); +	if (sscanf (input_line, "Radio cal: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_RADIO_CAL); +	if (sscanf (input_line, "Max flight log: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MAX_LOG); +	if (sscanf (input_line, "Ignite mode: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_IGNITE_MODE); +	if (sscanf (input_line, "Pad orientation: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_PAD_ORIENTATION); +	if (sscanf (input_line, "serial-number %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_SERIAL_NUMBER); +	if (sscanf (input_line, "log-format %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_LOG_FORMAT); +	if (sscanf (input_line, "ms5607 reserved: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_RESERVED); +	if (sscanf (input_line, "ms5607 sens: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_SENS); +	if (sscanf (input_line, "ms5607 off: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_OFF); +	if (sscanf (input_line, "ms5607 tcs: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_TCS); +	if (sscanf (input_line, "ms5607 tco: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_TCO); +	if (sscanf (input_line, "ms5607 tref: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_TREF); +	if (sscanf (input_line, "ms5607 tempsens: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_TEMPSENS); +	if (sscanf (input_line, "ms5607 crc: %d", +		    &l->u.config_int.data[0])) +		YUP(AO_CONFIG_MS5607_CRC); +	return 0; +} + +int +cc_mega_parse(const char *input_line, struct ao_log_mega *l) { +	return parse_eeprom(input_line, l) || parse_config(input_line, l); +} diff --git a/ao-tools/lib/cc-telemetry.h b/ao-tools/lib/cc-telemetry.h index 9a5be49f..c28aceb8 100644 --- a/ao-tools/lib/cc-telemetry.h +++ b/ao-tools/lib/cc-telemetry.h @@ -201,6 +201,72 @@ struct ao_telemetry_mega_data {  	/* 32 */  }; +#define AO_TELEMETRY_METRUM_SENSOR	0x0A + +struct ao_telemetry_metrum_sensor { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	uint8_t         state;          /*  5 flight state */ +	int16_t		accel;		/*  6 Z axis */ + +	int32_t		pres;		/*  8 Pa * 10 */ +	int16_t		temp;		/* 12 °C * 100 */ + +	int16_t         acceleration;   /* 14 m/s² * 16 */ +	int16_t         speed;          /* 16 m/s * 16 */ +	int16_t         height;         /* 18 m */ + +	int16_t		v_batt;		/* 20 battery voltage */ +	int16_t		sense_a;	/* 22 apogee continuity sense */ +	int16_t		sense_m;	/* 24 main continuity sense */ + +	uint8_t		pad[6];		/* 26 */ +	/* 32 */ +}; +	 +#define AO_TELEMETRY_METRUM_DATA	0x0B + +struct ao_telemetry_metrum_data { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	int32_t		ground_pres;	/* 8 average pres on pad */ +	int16_t		ground_accel;	/* 12 average accel on pad */ +	int16_t		accel_plus_g;	/* 14 accel calibration at +1g */ +	int16_t		accel_minus_g;	/* 16 accel calibration at -1g */ + +	uint8_t		pad[14];	/* 18 */ +	/* 32 */ +}; + +#define AO_TELEMETRY_MINI		0x10 + +struct ao_telemetry_mini { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	uint8_t         state;          /*  5 flight state */ +	int16_t		v_batt;		/*  6 battery voltage */ +	int16_t		sense_a;	/*  8 apogee continuity */ +	int16_t		sense_m;	/* 10 main continuity */ + +	int32_t		pres;		/* 12 Pa * 10 */ +	int16_t		temp;		/* 16 °C * 100 */ + +	int16_t         acceleration;   /* 18 m/s² * 16 */ +	int16_t         speed;          /* 20 m/s * 16 */ +	int16_t         height;         /* 22 m */ + +	int32_t		ground_pres;	/* 24 average pres on pad */ + +	int32_t		pad28;		/* 28 */ +	/* 32 */ +}; +  /* #define AO_SEND_ALL_BARO */  #define AO_TELEMETRY_BARO		0x80 @@ -234,6 +300,9 @@ union ao_telemetry_all {  	struct ao_telemetry_companion		companion;  	struct ao_telemetry_mega_sensor		mega_sensor;  	struct ao_telemetry_mega_data		mega_data; +	struct ao_telemetry_metrum_sensor	metrum_sensor; +	struct ao_telemetry_metrum_data		metrum_data; +	struct ao_telemetry_mini		mini;  	struct ao_telemetry_baro		baro;  }; diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index 625540bb..c07f8cd0 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -306,7 +306,8 @@ struct ao_log_mega {  			int16_t		v_pbatt;	/* 6 */  			int16_t		n_sense;	/* 8 */  			int16_t		sense[10];	/* 10 */ -		} volt;					/* 30 */ +			uint16_t	pyro;		/* 30 */ +		} volt;					/* 32 */  		/* AO_LOG_GPS_TIME */  		struct {  			int32_t		latitude;	/* 4 */ diff --git a/ao-tools/lib/ccdbg-command.c b/ao-tools/lib/ccdbg-command.c index a1002879..55c912b2 100644 --- a/ao-tools/lib/ccdbg-command.c +++ b/ao-tools/lib/ccdbg-command.c @@ -157,7 +157,7 @@ ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc)  }  uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image)  {  	uint16_t pc;  	uint8_t status; diff --git a/ao-tools/lib/ccdbg-flash.c b/ao-tools/lib/ccdbg-flash.c index 1b46870b..44eb952b 100644 --- a/ao-tools/lib/ccdbg-flash.c +++ b/ao-tools/lib/ccdbg-flash.c @@ -238,7 +238,7 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)  #endif  uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image)  {  	uint16_t flash_prog;  	uint16_t flash_len; diff --git a/ao-tools/lib/ccdbg-hex.c b/ao-tools/lib/ccdbg-hex.c deleted file mode 100644 index 184b4e3b..00000000 --- a/ao-tools/lib/ccdbg-hex.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include <stdarg.h> -#include <ctype.h> - -struct hex_input { -	FILE	*file; -	int	line; -	char	*name; -}; - -enum hex_read_state { -	read_marker, -	read_length, -	read_address, -	read_type, -	read_data, -	read_checksum, -	read_newline, -	read_white, -	read_done, -}; - - -static void -ccdbg_hex_error(struct hex_input *input, char *format, ...) -{ -	va_list ap; - -	va_start(ap, format); -	fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); -	vfprintf(stderr, format, ap); -	fprintf(stderr, "\n"); -	va_end(ap); -} - -static void -ccdbg_hex_free(struct hex_record *record) -{ -	if (!record) return; -	free(record); -} - -static struct hex_record * -ccdbg_hex_alloc(uint8_t length) -{ -	struct hex_record *record; - -	record = calloc(1, sizeof(struct hex_record) + length); -	record->length = length; -	return record; -} - -static int -ishex(char c) -{ -	return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); -} - -static int -fromhex(char c) -{ -	if (isdigit(c)) -		return c - '0'; -	if ('a' <= c && c <= 'f') -		return c - 'a' + 10; -	if ('A' <= c && c <= 'F') -		return c - 'A' + 10; -	abort(); -	return 0; -} - -static uint8_t -ccdbg_hex_checksum(struct hex_record *record) -{ -	uint8_t	checksum = 0; -	int i; - -	checksum += record->length; -	checksum += record->address >> 8; -	checksum += record->address & 0xff; -	checksum += record->type; -	for (i = 0; i < record->length; i++) -		checksum += record->data[i]; -	return -checksum; -} - -static struct hex_record * -ccdbg_hex_read_record(struct hex_input *input) -{ -	struct hex_record *record = NULL; -	enum hex_read_state state = read_marker; -	char c; -	int nhexbytes; -	uint32_t hex; -	uint32_t ndata; -	uint8_t checksum; - -	while (state != read_done) { -		c = getc(input->file); -		if (c == EOF && state != read_white) { -			ccdbg_hex_error(input, "Unexpected EOF"); -			goto bail; -		} -		if (c == ' ') -			continue; -		if (c == '\n') -			input->line++; -		switch (state) { -		case read_marker: -			if (c != ':') { -				ccdbg_hex_error(input, "Missing ':'"); -				goto bail; -			} -			state = read_length; -			nhexbytes = 2; -			hex = 0; -			break; -		case read_length: -		case read_address: -		case read_type: -		case read_data: -		case read_checksum: -			if (!ishex(c)) { -				ccdbg_hex_error(input, "Non-hex char '%c'", -						c); -				goto bail; -			} -			hex = hex << 4 | fromhex(c); -			--nhexbytes; -			if (nhexbytes != 0) -				break; - -			switch (state) { -			case read_length: -				record = ccdbg_hex_alloc(hex); -				if (!record) { -					ccdbg_hex_error(input, "Out of memory"); -					goto bail; -				} -				state = read_address; -				nhexbytes = 4; -				break; -			case read_address: -				record->address = hex; -				state = read_type; -				nhexbytes = 2; -				break; -			case read_type: -				record->type = hex; -				state = read_data; -				nhexbytes = 2; -				ndata = 0; -				break; -			case read_data: -				record->data[ndata] = hex; -				ndata++; -				nhexbytes = 2; -				break; -			case read_checksum: -				record->checksum = hex; -				state = read_newline; -				break; -			default: -				break; -			} -			if (state == read_data) -				if (ndata == record->length) { -					nhexbytes = 2; -					state = read_checksum; -				} -			hex = 0; -			break; -		case read_newline: -			if (c != '\n' && c != '\r') { -				ccdbg_hex_error(input, "Missing newline"); -				goto bail; -			} -			state = read_white; -			break; -		case read_white: -			if (!isspace(c)) { -				if (c == '\n') -					input->line--; -				if (c != EOF) -					ungetc(c, input->file); -				state = read_done; -			} -			break; -		case read_done: -			break; -		} -	} -	checksum = ccdbg_hex_checksum(record); -	if (checksum != record->checksum) { -		ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", -				record->checksum, checksum); -		goto bail; -	} -	return record; - -bail: -	ccdbg_hex_free(record); -	return NULL; -} - -void -ccdbg_hex_file_free(struct hex_file *hex) -{ -	int	i; - -	if (!hex) -		return; -	for (i = 0; i < hex->nrecord; i++) -		ccdbg_hex_free(hex->records[i]); -	free(hex); -} - -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name) -{ -	struct hex_input input; -	struct hex_file	*hex = NULL, *newhex; -	struct hex_record *record; -	int srecord = 1; -	int done = 0; - -	hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); -	input.name = name; -	input.line = 1; -	input.file = file; -	while (!done) { -		record = ccdbg_hex_read_record(&input); -		if (!record) -			goto bail; -		if (hex->nrecord == srecord) { -			srecord *= 2; -			newhex = realloc(hex, -					 sizeof (struct hex_file) + -					 srecord * sizeof (struct hex_record *)); -			if (!newhex) -				goto bail; -			hex = newhex; -		} -		hex->records[hex->nrecord++] = record; -		if (record->type == HEX_RECORD_EOF) -			done = 1; -	} -	return hex; - -bail: -	ccdbg_hex_file_free(hex); -	return NULL; -} - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex) -{ -	struct hex_image *image; -	struct hex_record *record; -	int i; -	uint32_t addr; -	uint32_t base, bound; -	uint32_t offset; -	uint32_t extended_addr; - -	int length; - -	base = 0xffffffff; -	bound = 0x0; -	extended_addr = 0; -	for (i = 0; i < hex->nrecord; i++) { -		uint32_t r_bound; -		record = hex->records[i]; -		switch (record->type) { -		case 0: -			addr = extended_addr + record->address; -			r_bound = addr + record->length; -			if (addr < base) -				base = addr; -			if (r_bound > bound) -				bound = r_bound; -			break; -		case 1: -			break; -		case 2: -			if (record->length != 2) -				return NULL; -			extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; -			break; -		case 4: -			if (record->length != 2) -				return NULL; -			extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; -			break; -		} - -	} -	length = bound - base; -	image = calloc(sizeof(struct hex_image) + length, 1); -	if (!image) -		return NULL; -	image->address = base; -	image->length = length; -	memset(image->data, 0xff, length); -	extended_addr = 0; -	for (i = 0; i < hex->nrecord; i++) { -		record = hex->records[i]; -		switch (record->type) { -		case 0: -			addr = extended_addr + record->address; -			offset = addr - base; -			memcpy(image->data + offset, record->data, record->length); -			break; -		case 1: -			break; -		case 2: -			extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; -			break; -		case 4: -			extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; -			break; -		} -	} -	return image; -} - -void -ccdbg_hex_image_free(struct hex_image *image) -{ -	free(image); -} - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) -{ -	if (a->length != b->length) -		return 0; -	if (memcmp(a->data, b->data, a->length) != 0) -		return 0; -	return 1; -} - -struct hex_image * -ccdbg_hex_load(char *filename) -{ -	FILE *file; -	struct hex_file	*hex_file; -	struct hex_image *hex_image; - -	file = fopen (filename, "r"); -	if (!file) -		return 0; -	 -	hex_file = ccdbg_hex_file_read(file, filename); -	fclose(file); -	if (!hex_file) -		return 0; -	hex_image = ccdbg_hex_image_create(hex_file); -	if (!hex_image) -		return 0; -	ccdbg_hex_file_free(hex_file); -	return hex_image; -} diff --git a/ao-tools/lib/ccdbg-memory.c b/ao-tools/lib/ccdbg-memory.c index 554ac637..04059e2e 100644 --- a/ao-tools/lib/ccdbg-memory.c +++ b/ao-tools/lib/ccdbg-memory.c @@ -117,18 +117,18 @@ ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte)  }  uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset)  {  	ccdbg_write_memory(dbg, image->address + offset, image->data, image->length);  	return 0;  } -struct hex_image * +struct ao_hex_image *  ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length)  { -	struct hex_image *image; +	struct ao_hex_image *image; -	image = calloc(sizeof(struct hex_image) + length, 1); +	image = calloc(sizeof(struct ao_hex_image) + length, 1);  	image->address = address;  	image->length = length;  	memset(image->data, 0xff, length); diff --git a/ao-tools/lib/ccdbg-rom.c b/ao-tools/lib/ccdbg-rom.c index 71bed220..6e8e7378 100644 --- a/ao-tools/lib/ccdbg-rom.c +++ b/ao-tools/lib/ccdbg-rom.c @@ -19,10 +19,10 @@  #include "ccdbg.h"  uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom)  {  	if (dbg->rom) -		ccdbg_hex_image_free(dbg->rom); +		ao_hex_image_free(dbg->rom);  	dbg->rom = rom;  	return 0;  } @@ -30,7 +30,7 @@ ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom)  uint8_t  ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes)  { -	struct hex_image *rom = dbg->rom; +	struct ao_hex_image *rom = dbg->rom;  	if (!rom)  		return 0;  	if (addr < rom->address || rom->address + rom->length < addr + nbytes) @@ -42,7 +42,7 @@ uint8_t  ccdbg_rom_replace_xmem(struct ccdbg *dbg,  		       uint16_t addr, uint8_t *bytes, int nbytes)  { -	struct hex_image *rom = dbg->rom; +	struct ao_hex_image *rom = dbg->rom;  	if (!rom)  		return 0; diff --git a/ao-tools/lib/ccdbg.h b/ao-tools/lib/ccdbg.h index a27ff5d1..b17f289d 100644 --- a/ao-tools/lib/ccdbg.h +++ b/ao-tools/lib/ccdbg.h @@ -33,6 +33,7 @@  #include "ccdbg-debug.h"  #include "cc-bitbang.h"  #include "cc-usb.h" +#include "ao-hex.h"  /* 8051 instructions   */ @@ -103,29 +104,9 @@  struct ccdbg {  	struct cc_bitbang	*bb;  	struct cc_usb		*usb; -	struct hex_image	*rom; +	struct ao_hex_image	*rom;  }; -/* Intel hex file format data - */ -struct hex_record { -	uint8_t	length; -	uint16_t address; -	uint8_t type; -	uint8_t checksum; -	uint8_t data[0]; -}; - -struct hex_file { -	int			nrecord; -	struct hex_record	*records[0]; -}; - -struct hex_image { -	uint32_t	address; -	uint32_t	length; -	uint8_t		data[0]; -};  #define CC_STATE_ACC	0x1  #define CC_STATE_PSW	0x2 @@ -139,10 +120,6 @@ struct ccstate {  	uint8_t		sfr[CC_STATE_NSFR];  }; -#define HEX_RECORD_NORMAL		0x00 -#define HEX_RECORD_EOF			0x01 -#define HEX_RECORD_EXTENDED_ADDRESS	0x02 -  /* CC1111 debug port commands   */  #define CC_CHIP_ERASE		0x14 @@ -234,30 +211,11 @@ uint8_t  ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc);  uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image); +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image);  /* ccdbg-flash.c */  uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image); - -/* ccdbg-hex.c */ -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name); - -void -ccdbg_hex_file_free(struct hex_file *hex); - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex); - -void -ccdbg_hex_image_free(struct hex_image *image); - -struct hex_image * -ccdbg_hex_load(char *filename); - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image);  /* ccdbg-io.c */  struct ccdbg * @@ -304,9 +262,9 @@ uint8_t  ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte);  uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset); +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset); -struct hex_image * +struct ao_hex_image *  ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length);  uint8_t @@ -317,7 +275,7 @@ ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);  /* ccdbg-rom.c */  uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom); +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom);  uint8_t  ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes);  | 
