summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-12-19 14:19:29 -0800
committerKeith Packard <keithp@keithp.com>2008-12-19 14:19:29 -0800
commitb4d1127ef007843c643b778b3b2f6b915b1d5d9a (patch)
treed1d9eaf5a85c1345671fbf3dd49bd5be3a48ad0d
parent55995515b9d4fc1e193039eab697c5d03db417c2 (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.blink20
-rw-r--r--blink.c59
-rw-r--r--ccdbg-flash.c118
-rw-r--r--ccdbg-hex.c12
-rw-r--r--ccdbg-memory.c6
-rw-r--r--ccdbg.c27
-rw-r--r--ccdbg.h3
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:
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 <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);
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
@@ -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 *