From: Keith Packard Date: Fri, 19 Dec 2008 22:19:29 +0000 (-0800) Subject: Flash multiple pages. Eliminate off-by-one error in hex_image length. X-Git-Tag: 0.5~58^2~93 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=b4d1127ef007843c643b778b3b2f6b915b1d5d9a;ds=sidebyside Flash multiple pages. Eliminate off-by-one error in hex_image length. Signed-off-by: Keith Packard --- 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: diff --git a/blink.c b/blink.c index a5906f6d..907c82b8 100644 --- a/blink.c +++ b/blink.c @@ -1,13 +1,31 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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 @@ -77,6 +77,12 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) return 0; } +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) { diff --git a/ccdbg.c b/ccdbg.c index 4533fd0c..c144a06a 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -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); } diff --git a/ccdbg.h b/ccdbg.h index d5ef8940..3bb5722f 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -326,6 +326,9 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) 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);