Flash multiple pages. Eliminate off-by-one error in hex_image length.
authorKeith Packard <keithp@keithp.com>
Fri, 19 Dec 2008 22:19:29 +0000 (14:19 -0800)
committerKeith Packard <keithp@keithp.com>
Fri, 19 Dec 2008 22:19:29 +0000 (14:19 -0800)
Signed-off-by: Keith Packard <keithp@keithp.com>
Makefile.blink
blink.c
ccdbg-flash.c
ccdbg-hex.c
ccdbg-memory.c
ccdbg.c
ccdbg.h

index b23f0d69cb77e5d430c93810415a71fbb4801422..e153c97899cb135edea3bf033c33b79e9b9a7b1d 100644 (file)
@@ -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 a5906f6dd52796a690550c45dce159587b88e0bb..907c82b83c5d1f8dda2be1195eae9f75e399c829 100644 (file)
--- 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
 }
index ee4e858915d3712773e62cfe97d1e30128908674..aa2c5187f917a9d99e75966e07c2362fec4a5f9f 100644 (file)
@@ -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;
 }
index ff155ff3f8fcbc0d6967b03d0408d95ad800593e..86478da07b8c5f262c6adfb675cccf6aa11f2528 100644 (file)
@@ -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;
index ec1732251322b5816b4be9768c147d7ba65ec0f0..105295db7c8dc238606a84f859ba1c4b5f76bb31 100644 (file)
@@ -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 4533fd0caeee643c553471cbf31a8ab744715837..c144a06afa7cac350fcd543308ee2e5dc041843c 100644 (file)
--- 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 d5ef894096a44c0d0c8cf92b15be764f5ccad7b7..3bb5722fb326465e8402ff1d318fd1923e6da37d 100644 (file)
--- 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);