diff options
| author | Keith Packard <keithp@keithp.com> | 2008-12-19 14:19:29 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2008-12-19 14:19:29 -0800 | 
| commit | b4d1127ef007843c643b778b3b2f6b915b1d5d9a (patch) | |
| tree | d1d9eaf5a85c1345671fbf3dd49bd5be3a48ad0d | |
| parent | 55995515b9d4fc1e193039eab697c5d03db417c2 (diff) | |
Flash multiple pages. Eliminate off-by-one error in hex_image length.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | Makefile.blink | 20 | ||||
| -rw-r--r-- | blink.c | 59 | ||||
| -rw-r--r-- | ccdbg-flash.c | 118 | ||||
| -rw-r--r-- | ccdbg-hex.c | 12 | ||||
| -rw-r--r-- | ccdbg-memory.c | 6 | ||||
| -rw-r--r-- | ccdbg.c | 27 | ||||
| -rw-r--r-- | ccdbg.h | 3 | 
7 files changed, 145 insertions, 100 deletions
diff --git a/Makefile.blink b/Makefile.blink index b23f0d69..e153c978 100644 --- a/Makefile.blink +++ b/Makefile.blink @@ -4,13 +4,17 @@ NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \  	--nolabelopt --nooverlay --peep-asm  DEBUG=--debug -CFLAGS=--model-large $(DEBUG) --less-pedantic --xram-size 4096\ -	--stack-auto --no-peep --int-long-reent --float-reent +CFLAGS=--model-large $(DEBUG) --less-pedantic \ +	--no-peep --int-long-reent --float-reent \ +	--no-pack-iram \ +	--data-loc 0x30 \  LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx -LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + -LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000  SRC=blink.c  ADB=$(SRC:.c=.adb) @@ -32,12 +36,12 @@ PMEM=$(PROGS:=.mem)  all: $(PROGS) -blink-ram: $(REL) -	$(CC) $(LDFLAGS_RAM) $(CFLAGS) -oblink $(REL) +blink-ram: $(REL) Makefile.blink +	$(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink $(REL)  	mv blink $@ -blink-flash: $(REL) -	$(CC) $(LDFLAGS_FLASH) $(CFLAGS) -oblink $(REL) +blink-flash: $(REL) Makefile.blink +	$(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink $(REL)  	mv blink $@  clean: @@ -1,13 +1,31 @@ +/* + * 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. + */  sfr at 0x80 P0;  sfr at 0x90 P1;  sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; -#define PERCFG	SFR(0xF1) -#define ADCCFG	SFR(0xF2) -#define P0SEL	SFR(0xF3) -#define P1SEL	SFR(0xF4) -#define P2SEL	SFR(0xF5) +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL;  sfr at 0xFD P0DIR;  sfr at 0xFE P1DIR; @@ -16,25 +34,22 @@ sfr at 0x8F P0INP;  sfr at 0xF6 P1INP;  sfr at 0xF7 P2INP; -#define P0IFG	SFR(0x89) -#define P1IFG	SFR(0x8A) -#define P2IFG	SFR(0x8B) +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; -#define nop()	_asm \ -		nop \ -		_endasm; +#define nop()	_asm nop _endasm; -#if 0  void -delay (int n) +delay (unsigned char n)  { -	int i, j, k; +	unsigned char i = 0, j = 0; -	for (k = 0; k < n; k++) { -		for (j = 0; j < 50; j++) -			for (i = 0; i < 1000; i++) +	n <<= 1; +	while (--n != 0) +		while (--j != 0) +			while (--i != 0)  				nop(); -	}  }  void @@ -68,11 +83,9 @@ wordspace () {  #define C charspace();  #define W wordspace(); -#endif -  main ()  { -#if 0 +	CLKCON = 0;  	/* Set p1_1 to output */  	P1DIR = 0x02;  	P1INP = 0x00; @@ -84,8 +97,4 @@ main ()  		___ ___ _ _ _ C	_ _ _ C		/* 7s */  		___ ___ _ ___ C	___ ___ _ W	/* qg */  	} -#else -	P1DIR = 0x02; -	for (;;); -#endif  } diff --git a/ccdbg-flash.c b/ccdbg-flash.c index ee4e8589..aa2c5187 100644 --- a/ccdbg-flash.c +++ b/ccdbg-flash.c @@ -72,6 +72,7 @@ static uint8_t flash_page[] = {  #define FLASH_RAM	0xf000 +#if 0  static uint8_t	flash_erase_page[] = {  	3,	MOV_direct_data, FADDRH, 0,  #define ERASE_PAGE_HIGH	3 @@ -88,13 +89,17 @@ static uint8_t	flash_read_control[] = {  	2,	MOV_A_direct,	FCTL,  	0  }; +#endif +#if 0  static uint8_t	flash_control_clear[] = {  	3,	MOV_direct_data,	FCTL, 0,  	2,	MOV_A_direct,		FCTL,  	0  }; +#endif +#if 0  static uint8_t  ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)  { @@ -119,7 +124,9 @@ ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)  	printf("clear fctl 0x%02x\n", status);  	return 0;  } +#endif +#if 0  static uint8_t flash_write[] = {  	MOV_direct_data, P1DIR, 0x02,  	MOV_direct_data, P1,	0xFD, @@ -146,6 +153,7 @@ static uint8_t flash_write[] = {  	MOV_direct_data, P1,	0xFF,  	TRAP,  }; +#endif  static uint8_t  ccdbg_clock_init(struct ccdbg *dbg) @@ -169,6 +177,7 @@ ccdbg_clock_init(struct ccdbg *dbg)  	return 0;  } +#if 0  static uint8_t  ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])  { @@ -199,12 +208,14 @@ ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])  		printf("0x%02x : 0x%02x\n", data[i], check[i]);  	return 0;  } +#endif  #define TIMERS_OFF		0x08  #define DMA_PAUSE		0x04  #define TIMER_SUSPEND		0x02  #define SEL_FLASH_INFO_PAGE	0x01 +#if 0  static uint8_t  ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)  { @@ -224,12 +235,12 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)  	ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE);  	return 0;  } +#endif  uint8_t  ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)  {  	uint16_t offset; -	struct hex_image *test_image;  	uint16_t flash_prog;  	uint16_t flash_len;  	uint8_t	fwt; @@ -238,6 +249,8 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)  	uint16_t ram_addr;  	uint16_t pc;  	uint8_t status; +	uint16_t remain, this_time, start; +	uint8_t verify[0x400];  	ccdbg_clock_init(dbg);  	if (image->address + image->length > 0x8000) { @@ -245,16 +258,71 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)  			image->address, image->address + image->length);  		return 1;  	} -	flash_word_addr = image->address >> 1; -	if (flash_word_addr & 0x1ff) { +	if (image->address & 0x3ff) {  		fprintf(stderr, "flash image must start on page boundary\n");  		return 1;  	}  	ram_addr = 0xf000; -	offset = ram_addr - image->address; -#if 0 +	 +	flash_prog = 0xf400; + +	fwt = 0x20; + +	flash_page[FLASH_TIMING] = fwt; +	printf("Upload %d flash program bytes to 0x%04x\n", +	       sizeof (flash_page), flash_prog); +	ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); +	 +	remain = image->length; +	start = 0; +	while (remain) { +		this_time = remain; +		if (this_time > 0x400) +			this_time = 0x400; + +		offset = ram_addr - (image->address + start); + +		printf("Upload %d bytes at 0x%04x\n", this_time, ram_addr); +		ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); + +		printf("Verify %d bytes\n", image->length); +		ccdbg_read_memory(dbg, ram_addr, verify, this_time); +		if (memcmp (image->data + start, verify, this_time) != 0) { +			fprintf(stderr, "image verify failed\n"); +			return 1; +		} +		 +		flash_word_addr = (image->address + start) >> 1; +		flash_len = this_time + (this_time & 1); +		flash_words = flash_len >> 1; + +		ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8); +		ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff); + +		ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8); +		ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff); + +		ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words >> 8); +		ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words & 0xff); + +		ccdbg_set_pc(dbg, flash_prog); +		pc = ccdbg_get_pc(dbg); +		printf("Starting flash program at 0x%04x\n", pc); +		status = ccdbg_resume(dbg); +		printf("resume status is 0x%02x\n", status); +		do { +			status = ccdbg_read_status(dbg); +			printf("chip status is 0x%02x\n", status); +			sleep(1); +		} while ((status & CC_STATUS_CPU_HALTED) == 0); +		 +		remain -= this_time; +		start += this_time; +	} +#if 1  	printf("Downloading flash to check\n"); +	struct hex_image *test_image;  	test_image = ccdbg_read_hex_image(dbg, image->address, image->length);  	if (!ccdbg_hex_image_equal(image, test_image)) {  		int i; @@ -265,45 +333,5 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)  	}  	return 0;  #endif -	 -	printf("Upload %d bytes at 0x%04x\n", image->length, ram_addr); -	ccdbg_write_hex_image(dbg, image, offset); -	printf("Verify %d bytes\n", image->length); -	test_image = ccdbg_read_hex_image(dbg, ram_addr, image->length); -	if (!ccdbg_hex_image_equal(image, test_image)) { -		ccdbg_hex_image_free(test_image); -		fprintf(stderr, "image verify failed\n"); -		return 1; -	} -	ccdbg_hex_image_free(test_image); -	flash_len = image->length + (image->length & 1); -	flash_words = flash_len >> 1; -	flash_prog = ram_addr + flash_len; - -	fwt = 0x20; -	flash_page[FLASH_ADDR_HIGH] = flash_word_addr >> 8; -	flash_page[FLASH_ADDR_LOW] = flash_word_addr & 0xff; - -	flash_page[RAM_ADDR_HIGH] = ram_addr >> 8; -	flash_page[RAM_ADDR_LOW] = ram_addr & 0xff; - -	flash_page[FLASH_WORDS_HIGH] = flash_words >> 8; -	flash_page[FLASH_WORDS_LOW] = flash_words & 0xff; - -	flash_page[FLASH_TIMING] = fwt; -	 -	printf("Upload %d flash program bytes to 0x%04x\n", -	       sizeof (flash_prog), flash_prog); -	ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); -	ccdbg_set_pc(dbg, flash_prog); -	pc = ccdbg_get_pc(dbg); -	printf("Starting flash program at 0x%04x\n", pc); -	status = ccdbg_resume(dbg); -	printf("resume status is 0x%02x\n", status); -	do { -		status = ccdbg_read_status(dbg); -		printf("chip status is 0x%02x\n", status); -		sleep(1); -	} while ((status & CC_STATUS_CPU_HALTED) == 0);  	return 0;  } diff --git a/ccdbg-hex.c b/ccdbg-hex.c index ff155ff3..86478da0 100644 --- a/ccdbg-hex.c +++ b/ccdbg-hex.c @@ -119,6 +119,8 @@ ccdbg_hex_read_record(struct hex_input *input)  			ccdbg_hex_error(input, "Unexpected EOF");  			goto bail;  		} +		if (c == ' ') +			continue;  		if (c == '\n')  			input->line++;  		switch (state) { @@ -290,17 +292,19 @@ ccdbg_hex_image_create(struct hex_file *hex)  	int i;  	uint32_t base, bound;  	uint32_t offset; +	int length;  	first = hex->records[0];  	last = hex->records[hex->nrecord - 2];	/* skip EOF */  	base = (uint32_t) first->address; -	bound = (uint32_t) last->address + (uint32_t) last->length - 1; -	image = calloc(sizeof(struct hex_image) + bound - base, 1); +	bound = (uint32_t) last->address + (uint32_t) last->length; +	length = bound - base; +	image = calloc(sizeof(struct hex_image) + length, 1);  	if (!image)  		return NULL;  	image->address = base; -	image->length = bound - base; -	memset(image->data, 0xff, image->length); +	image->length = length; +	memset(image->data, 0xff, length);  	for (i = 0; i < hex->nrecord - 1; i++) {  		record = hex->records[i];  		offset = record->address - base; diff --git a/ccdbg-memory.c b/ccdbg-memory.c index ec173225..105295db 100644 --- a/ccdbg-memory.c +++ b/ccdbg-memory.c @@ -78,6 +78,12 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)  }  uint8_t +ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) +{ +	return ccdbg_write_memory(dbg, addr, &byte, 1); +} + +uint8_t  ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset)  {  	ccdbg_write_memory(dbg, image->address + offset, image->data, image->length); @@ -18,7 +18,7 @@  #include "ccdbg.h" -#if 1 +#if 0  static uint8_t instructions[] = {  	3, MOV_direct_data, 0xfe, 0x02,  	3, MOV_direct_data, 0x90, 0xff, @@ -26,6 +26,7 @@ static uint8_t instructions[] = {  };  #endif +#if 0  static uint8_t mem_instr[] = {  	MOV_direct_data, 0xfe, 0x02,  	MOV_Rn_data(0), 0x00, @@ -42,7 +43,9 @@ static uint8_t mem_instr[] = {  	DJNZ_Rn_rel(2), 0xfa,  	SJMP, 0xe7,  }; +#endif +#if 0  static struct hex_image *  make_hex_image(uint16_t addr, uint8_t *data, uint16_t length)  { @@ -54,13 +57,13 @@ make_hex_image(uint16_t addr, uint8_t *data, uint16_t length)  	memcpy(image->data, data, length);  	return image;  } +#endif  int  main (int argc, char **argv)  {  	struct ccdbg	*dbg;  	uint8_t		status; -	uint16_t	chip_id;  	uint16_t	pc;  	struct hex_file	*hex;  	struct hex_image *image; @@ -81,9 +84,7 @@ main (int argc, char **argv)  	image = make_hex_image(0xf000, mem_instr, sizeof (mem_instr));  #endif -	ccdbg_reset(dbg);  	ccdbg_debug_mode(dbg); -	ccdbg_halt(dbg);  #if 1  	if (!image) { @@ -91,13 +92,11 @@ main (int argc, char **argv)  		exit (1);  	}  	if (image->address == 0xf000) { -		printf("Loading code to execute from RAM\n"); -		ccdbg_execute_hex_image(dbg, image); +		printf("Loading %d bytes to execute from RAM\n", image->length); +		ccdbg_write_hex_image(dbg, image, 0);  	} else if (image->address == 0x0000) {  		printf("Loading code to execute from FLASH\n");  		ccdbg_flash_hex_image(dbg, image); -		ccdbg_set_pc(dbg, 0); -		ccdbg_resume(dbg);  	} else {  		printf("Cannot load code to 0x%04x\n",  		       image->address); @@ -105,17 +104,9 @@ main (int argc, char **argv)  		ccdbg_close(dbg);  		exit(1);  	} +	ccdbg_set_pc(dbg, image->address);  #endif -	for (;;) { -		pc = ccdbg_get_pc(dbg); -		status = ccdbg_read_status(dbg); -		printf("pc: 0x%04x.  status: 0x%02x\n", pc, status); -	} -#if 0 -/*	ccdbg_execute(dbg, instructions); */ -	ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr)); -	ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory)); -#endif +	ccdbg_resume(dbg);  	ccdbg_close(dbg);  	exit (0);  } @@ -327,6 +327,9 @@ uint8_t  ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);  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);  struct hex_image *  | 
