+.NOTPARALLEL: blink-ram blink-flash
KERNEL=/local/src/linux-2.6-aiko-64
KINC=$(KERNEL)/drivers/usb/serial
KERNEL_OBJS=cccp.o
LIBUSB_OBJS=cp-usb.o
-OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o \
- ccdbg-hex.o ccdbg-io.o ccdbg-memory.o \
+SRCS=ccdbg.c ccdbg-command.c ccdbg-debug.c ccdbg-flash.c \
+ ccdbg-hex.c ccdbg-io.c ccdbg-memory.c \
$(LIBUSB_OBJS)
+
+OBJS=$(SRCS:.c=.o)
+
INCS=ccdbg.h cccp.h
PROG=ccdbg
-LOAD=blink
+LOAD=blinks
all: $(PROG) $(LOAD)
clean:
rm -f $(PROG) $(OBJS)
+ make -f Makefile.blink clean
$(OBJS): $(INCS)
-blink: blink.c Makefile.blink
- make -f Makefile.blink
+blinks: blink.c Makefile.blink
+ make -j1 -f Makefile.blink
+.NOTPARALLEL:
CC=sdcc
NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
--nolabelopt --nooverlay --peep-asm
CFLAGS=--model-large $(DEBUG) --less-pedantic --xram-size 4096\
--stack-auto --no-peep --int-long-reent --float-reent
-LDFLAGS=-L/usr/share/sdcc/lib/large \
- --code-loc 0xf000 --xram-loc 0xf400
+LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx
+LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400
+
+LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000
SRC=blink.c
-OBJ=$(SRC:.c=.rel)
+ADB=$(SRC:.c=.adb)
+ASM=$(SRC:.c=.asm)
+LNK=$(SRC:.c=.lnk)
+LST=$(SRC:.c=.lst)
+REL=$(SRC:.c=.rel)
+RST=$(SRC:.c=.rst)
+SYM=$(SRC:.c=.sym)
+
+PROGS=blink-flash blink-ram
+PCDB=$(PROGS:=.cdb)
+PLNK=$(PROGS:=.lnk)
+PMAP=$(PROGS:=.map)
+PMEM=$(PROGS:=.mem)
%.rel : %.c
$(CC) -c $(CFLAGS) -o$*.rel $<
-blink: $(OBJ)
- $(CC) $(LDFLAGS) $(CFLAGS) -o$@ $(OBJ)
+all: $(PROGS)
+
+blink-ram: $(REL)
+ $(CC) $(LDFLAGS_RAM) $(CFLAGS) -oblink $(REL)
+ mv blink $@
+
+blink-flash: $(REL)
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -oblink $(REL)
+ mv blink $@
+clean:
+ rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+ rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM)
sfr at 0xFD P0DIR;
sfr at 0xFE P1DIR;
-sfr at 0xFE P2DIR;
+sfr at 0xFF P2DIR;
sfr at 0x8F P0INP;
sfr at 0xF6 P1INP;
sfr at 0xF7 P2INP;
nop \
_endasm;
+#if 0
void
delay (int n)
{
delay(8);
}
+#define _ dit();
+#define ___ dah();
+#define C charspace();
+#define W wordspace();
+
+#endif
+
main ()
{
+#if 0
/* Set p1_1 to output */
P1DIR = 0x02;
P1INP = 0x00;
P2INP = 0x00;
for (;;) {
- dah(); dit(); dah(); dit(); charspace ();
- dah(); dah(); dit(); dah(); wordspace();
+ ___ _ ___ _ C ___ ___ _ ___ W /* cq */
+ ___ _ _ C _ W /* de */
+ ___ _ ___ C ___ _ _ C /* kd */
+ ___ ___ _ _ _ C _ _ _ C /* 7s */
+ ___ ___ _ ___ C ___ ___ _ W /* qg */
}
+#else
+ P1DIR = 0x02;
+ for (;;);
+#endif
}
return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0);
}
-uint8_t
+uint16_t
ccdbg_get_pc(struct ccdbg *dbg)
{
return ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0);
return status;
}
+static uint8_t jump_mem[] = {
+ 3, LJMP, 0xf0, 0x00,
+#define PC_HIGH 2
+#define PC_LOW 3
+ 0
+};
+
+uint8_t
+ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc)
+{
+ jump_mem[PC_HIGH] = pc >> 8;
+ jump_mem[PC_LOW] = pc & 0xff;
+ return ccdbg_execute(dbg, jump_mem);
+}
+
+uint8_t
+ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image)
+{
+ uint16_t pc;
+ uint8_t status;
+
+ if (image->address < 0xf000) {
+ fprintf(stderr, "Cannot execute program starting at 0x%04x\n", image->address);
+ return -1;
+ }
+ ccdbg_write_hex_image(dbg, image, 0);
+ ccdbg_set_pc(dbg, image->address);
+ pc = ccdbg_get_pc(dbg);
+ printf ("pc starts at 0x%04x\n", pc);
+ status = ccdbg_resume(dbg);
+ printf ("resume status: 0x%02x\n", status);
+ return 0;
+}
+
--- /dev/null
+/*
+ * 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"
+
+/* From SWRA124 section 3.1.6 */
+
+static uint8_t flash_page[] = {
+
+ MOV_direct_data, P1DIR, 0x02,
+ MOV_direct_data, P1, 0xFF,
+
+ MOV_direct_data, FADDRH, 0,
+#define FLASH_ADDR_HIGH 8
+
+ MOV_direct_data, FADDRL, 0,
+#define FLASH_ADDR_LOW 11
+
+ MOV_DPTR_data16, 0, 0,
+#define RAM_ADDR_HIGH 13
+#define RAM_ADDR_LOW 14
+
+ MOV_Rn_data(7), 0,
+#define FLASH_WORDS_HIGH 16
+
+ MOV_Rn_data(6), 0,
+#define FLASH_WORDS_LOW 18
+
+ MOV_direct_data, FWT, 0x20,
+#define FLASH_TIMING 21
+
+ MOV_direct_data, FCTL, FCTL_ERASE,
+/* eraseWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_BUSY_BIT), 0xfb,
+
+ MOV_direct_data, P1, 0xfd,
+
+ MOV_direct_data, FCTL, FCTL_WRITE,
+/* writeLoop: */
+ MOV_Rn_data(5), 2,
+/* writeWordLoop: */
+ MOVX_A_atDPTR,
+ INC_DPTR,
+ MOV_direct_A, FWDATA,
+ DJNZ_Rn_rel(5), 0xfa, /* writeWordLoop */
+/* writeWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_SWBSY_BIT), 0xfb, /* writeWaitLoop */
+ DJNZ_Rn_rel(6), 0xf1, /* writeLoop */
+ DJNZ_Rn_rel(7), 0xef, /* writeLoop */
+
+ MOV_direct_data, P1DIR, 0x00,
+ MOV_direct_data, P1, 0xFF,
+ TRAP,
+};
+
+#define FLASH_RAM 0xf000
+
+static uint8_t flash_erase_page[] = {
+ 3, MOV_direct_data, FADDRH, 0,
+#define ERASE_PAGE_HIGH 3
+
+ 3, MOV_direct_data, FADDRL, 0,
+#define ERASE_PAGE_LOW 7
+
+ 3, MOV_direct_data, FWT, 0x2A,
+ 3, MOV_direct_data, FCTL, FCTL_ERASE,
+ 0
+};
+
+static uint8_t flash_read_control[] = {
+ 2, MOV_A_direct, FCTL,
+ 0
+};
+
+static uint8_t flash_control_clear[] = {
+ 3, MOV_direct_data, FCTL, 0,
+ 2, MOV_A_direct, FCTL,
+ 0
+};
+
+static uint8_t
+ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)
+{
+ uint16_t page_addr = addr >> 1;
+ uint8_t status;
+ uint8_t old[0x10], new[0x10];
+ int i;
+
+ ccdbg_read_memory(dbg, addr, old, 0x10);
+ flash_erase_page[ERASE_PAGE_HIGH] = page_addr >> 8;
+ flash_erase_page[ERASE_PAGE_LOW] = page_addr & 0xff;
+ status = ccdbg_execute(dbg, flash_erase_page);
+ printf("erase status 0x%02x\n", status);
+ do {
+ status = ccdbg_execute(dbg, flash_read_control);
+ printf("fctl 0x%02x\n", status);
+ } while (status & FCTL_BUSY);
+ ccdbg_read_memory(dbg, addr, new, 0x10);
+ for (i = 0; i < 0x10; i++)
+ printf("0x%02x -> 0x%02x\n", old[i], new[i]);
+ status = ccdbg_execute(dbg, flash_control_clear);
+ printf("clear fctl 0x%02x\n", status);
+ return 0;
+}
+
+static uint8_t flash_write[] = {
+ MOV_direct_data, P1DIR, 0x02,
+ MOV_direct_data, P1, 0xFD,
+
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_BUSY_BIT), 0xf1,
+
+ MOV_direct_data, FCTL, 0x20,
+
+ MOV_direct_data, FADDRH, 0,
+#define WRITE_PAGE_HIGH 16
+
+ MOV_direct_data, FADDRL, 0,
+#define WRITE_PAGE_LOW 19
+
+ MOV_direct_data, FCTL, FCTL_WRITE,
+ MOV_direct_data, FWDATA, 0,
+#define WRITE_BYTE_0 25
+ MOV_direct_data, FWDATA, 0,
+#define WRITE_BYTE_1 28
+ MOV_A_direct, FCTL,
+ JB, ACC(FCTL_SWBSY_BIT), 0xf1,
+
+ MOV_direct_data, P1, 0xFF,
+ TRAP,
+};
+
+static uint8_t
+ccdbg_clock_init(struct ccdbg *dbg)
+{
+ static uint8_t set_clkcon_fast[] = {
+ 3, MOV_direct_data, CLKCON, 0x00,
+ 0
+ };
+
+ static uint8_t get_sleep[] = {
+ 2, MOV_A_direct, SLEEP,
+ 0
+ };
+
+ uint8_t status;
+
+ ccdbg_execute(dbg, set_clkcon_fast);
+ do {
+ status = ccdbg_execute(dbg, get_sleep);
+ } while (!(status & 0x40));
+ return 0;
+}
+
+static uint8_t
+ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])
+{
+ uint16_t page_addr = addr >> 1;
+ uint8_t check[2];
+ uint8_t status;
+ int i;
+
+ flash_write[WRITE_PAGE_HIGH] = page_addr >> 8;
+ flash_write[WRITE_PAGE_LOW] = page_addr & 0xff;
+ flash_write[WRITE_BYTE_0] = data[0];
+ flash_write[WRITE_BYTE_1] = data[1];
+ printf("upload flash write\n");
+ ccdbg_write_memory(dbg, 0xf000, flash_write, sizeof(flash_write));
+ ccdbg_set_pc(dbg, 0xf000);
+ ccdbg_resume(dbg);
+ for (;;) {
+ status = ccdbg_read_status(dbg);
+ printf("waiting for write 0x%02x\n", status);
+ if ((status & CC_STATUS_CPU_HALTED) != 0)
+ break;
+ sleep (1);
+ }
+ status = ccdbg_execute(dbg, flash_control_clear);
+ printf("clear fctl 0x%02x\n", status);
+ ccdbg_read_memory(dbg, addr, check, 2);
+ for (i = 0; i < 2; i++)
+ printf("0x%02x : 0x%02x\n", data[i], check[i]);
+ return 0;
+}
+
+#define TIMERS_OFF 0x08
+#define DMA_PAUSE 0x04
+#define TIMER_SUSPEND 0x02
+#define SEL_FLASH_INFO_PAGE 0x01
+
+static uint8_t
+ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)
+{
+ uint8_t config;
+ uint8_t bytes[2];
+ uint8_t old[1], new[1];
+
+ config = ccdbg_rd_config(dbg);
+ ccdbg_wr_config(dbg, config|SEL_FLASH_INFO_PAGE);
+ bytes[0] = lock;
+ bytes[1] = 0;
+ ccdbg_flash_erase_page(dbg, 0);
+ ccdbg_read_memory(dbg, 0, old, 1);
+ ccdbg_flash_write_word(dbg, 0, bytes);
+ ccdbg_read_memory(dbg, 0, new, 1);
+ printf ("flash lock 0x%02x -> 0x%02x\n", old[0], new[0]);
+ ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE);
+ return 0;
+}
+
+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;
+ uint16_t flash_word_addr;
+ uint16_t flash_words;
+ uint16_t ram_addr;
+ uint16_t pc;
+ uint8_t status;
+
+ ccdbg_clock_init(dbg);
+ if (image->address + image->length > 0x8000) {
+ fprintf(stderr, "cannot flash image from 0x%04x to 0x%04x\n",
+ image->address, image->address + image->length);
+ return 1;
+ }
+ flash_word_addr = image->address >> 1;
+ if (flash_word_addr & 0x1ff) {
+ fprintf(stderr, "flash image must start on page boundary\n");
+ return 1;
+ }
+ ram_addr = 0xf000;
+ offset = ram_addr - image->address;
+
+#if 0
+ printf("Downloading flash to check\n");
+ test_image = ccdbg_read_hex_image(dbg, image->address, image->length);
+ if (!ccdbg_hex_image_equal(image, test_image)) {
+ int i;
+ fprintf(stderr, "Image not loaded\n");
+ for (i = 0;i < 0x10; i++)
+ printf ("0x%02x : 0x%02x\n", image->data[i], test_image->data[i]);
+ return 1;
+ }
+ 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;
+}
return;
for (i = 0; i < hex->nrecord; i++)
ccdbg_hex_free(hex->records[i]);
- free (hex);
+ free(hex);
}
static int
int srecord = 1;
int done = 0;
- hex = calloc (1, sizeof (struct hex_file) + sizeof (struct hex_record *));
+ hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1);
input.name = name;
input.line = 1;
input.file = file;
return NULL;
}
+struct hex_image *
+ccdbg_hex_image_create(struct hex_file *hex)
+{
+ struct hex_image *image;
+ struct hex_record *first, *last, *record;
+ int i;
+ uint32_t base, bound;
+ uint32_t offset;
+
+ 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);
+ if (!image)
+ return NULL;
+ image->address = base;
+ image->length = bound - base;
+ memset(image->data, 0xff, image->length);
+ for (i = 0; i < hex->nrecord - 1; i++) {
+ record = hex->records[i];
+ offset = record->address - base;
+ memcpy(image->data + offset, record->data, record->length);
+ }
+ 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 timespec req, rem;
req.tv_sec = (CC_CLOCK_US / 2) / 1000000;
req.tv_nsec = ((CC_CLOCK_US / 2) % 1000000) * 1000;
-// nanosleep(&req, &rem);
+ nanosleep(&req, &rem);
}
struct ccdbg *
* Read and write arbitrary memory through the debug port
*/
-#define MOV_dptr_data16 0x90
-
static uint8_t memory_init[] = {
- 3, MOV_dptr_data16, 0, 0,
+ 3, MOV_DPTR_data16, 0, 0,
#define HIGH_START 2
#define LOW_START 3
0,
};
-#define MOV_a_data 0x74
-#define MOVX_atdptr_a 0xf0
-#define MOVX_a_atdptr 0xe0
-#define INC_dptr 0xa3
static uint8_t write8[] = {
- 2, MOV_a_data, 0,
+ 2, MOV_A_data, 0,
#define DATA_BYTE 2
- 1, MOVX_atdptr_a,
- 1, INC_dptr,
+ 1, MOVX_atDPTR_A,
+ 1, INC_DPTR,
0
};
static uint8_t read8[] = {
- 1, MOVX_a_atdptr,
- 1, INC_dptr,
+ 1, MOVX_A_atDPTR,
+ 1, INC_DPTR,
0,
};
uint8_t
ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
{
+ int i, nl = 0;
memory_init[HIGH_START] = addr >> 8;
memory_init[LOW_START] = addr;
(void) ccdbg_execute(dbg, memory_init);
- while (nbytes-- > 0) {
+ for (i = 0; i < nbytes; i++) {
write8[DATA_BYTE] = *bytes++;
ccdbg_execute(dbg, write8);
+ if ((i & 0xf) == 0xf) { printf ("."); fflush(stdout); nl = 1; }
+ if ((i & 0xff) == 0xff) { printf ("\n"); nl = 0; }
}
+ if (nl) printf ("\n");
return 0;
}
uint8_t
ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
{
+ int i, nl = 0;
memory_init[HIGH_START] = addr >> 8;
memory_init[LOW_START] = addr;
(void) ccdbg_execute(dbg, memory_init);
- while (nbytes-- > 0)
+ for (i = 0; i < nbytes; i++) {
*bytes++ = ccdbg_execute(dbg, read8);
+ if ((i & 0xf) == 0xf) { printf ("."); fflush(stdout); nl = 1; }
+ if ((i & 0xff) == 0xff) { printf ("\n"); nl = 0; }
+ }
+ if (nl) printf ("\n");
return 0;
}
uint8_t
-ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex)
+ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset)
{
- int i;
- struct hex_record *record;
-
- for (i = 0; i < hex->nrecord; i++) {
- record = hex->records[i];
- if (record->type == HEX_RECORD_EOF)
- break;
- printf("Write %d bytes at 0x%04x\n",
- record->length, record->address);
- ccdbg_write_memory(dbg, record->address,
- record->data, record->length);
- }
+ ccdbg_write_memory(dbg, image->address + offset, image->data, image->length);
return 0;
}
+
+struct hex_image *
+ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length)
+{
+ struct hex_image *image;
+
+ image = calloc(sizeof(struct hex_image) + length, 1);
+ image->address = address;
+ image->length = length;
+ memset(image->data, 0xff, length);
+ ccdbg_read_memory(dbg, address, image->data, length);
+ return image;
+}
#include "ccdbg.h"
-#define MOV_direct_data 0x75
-#define LJMP 0x02
-#define MOV_Rn_data(n) (0x78 | (n))
-#define DJNZ_Rn_rel(n) (0xd8 | (n))
-
-#if 0
+#if 1
static uint8_t instructions[] = {
3, MOV_direct_data, 0xfe, 0x02,
3, MOV_direct_data, 0x90, 0xff,
static uint8_t mem_instr[] = {
MOV_direct_data, 0xfe, 0x02,
+ MOV_Rn_data(0), 0x00,
+ MOV_Rn_data(1), 0x00,
MOV_direct_data, 0x90, 0xff,
MOV_Rn_data(2), 0x10,
- MOV_Rn_data(0), 0xff,
- MOV_Rn_data(1), 0xff,
DJNZ_Rn_rel(1), 0xfe,
- DJNZ_Rn_rel(0), 0xfa,
- DJNZ_Rn_rel(2), 0xf6,
+ DJNZ_Rn_rel(0), 0xfc,
+ DJNZ_Rn_rel(2), 0xfa,
MOV_direct_data, 0x90, 0xfd,
MOV_Rn_data(2), 0x10,
- MOV_Rn_data(0), 0xff,
- MOV_Rn_data(1), 0xff,
DJNZ_Rn_rel(1), 0xfe,
- DJNZ_Rn_rel(0), 0xfa,
- DJNZ_Rn_rel(2), 0xf6,
- LJMP, 0xf0, 0x03
+ DJNZ_Rn_rel(0), 0xfc,
+ DJNZ_Rn_rel(2), 0xfa,
+ SJMP, 0xe7,
};
-static uint8_t jump_mem[] = {
- 3, LJMP, 0xf0, 0x00,
- 0
-};
+static struct hex_image *
+make_hex_image(uint16_t addr, uint8_t *data, uint16_t length)
+{
+ struct hex_image *image;
+
+ image = malloc(sizeof (struct hex_image) + length);
+ image->address = addr;
+ image->length = length;
+ memcpy(image->data, data, length);
+ return image;
+}
int
main (int argc, char **argv)
uint8_t status;
uint16_t chip_id;
uint16_t pc;
- uint8_t memory[0x10];
- int i;
struct hex_file *hex;
+ struct hex_image *image;
dbg = ccdbg_open("/dev/ttyUSB0");
if (!dbg)
#if 0
ccdbg_manual(dbg, stdin);
#endif
+#if 1
hex = ccdbg_hex_file_read(stdin, "<stdin>");
if (!hex)
exit (1);
+ image = ccdbg_hex_image_create(hex);
+ ccdbg_hex_file_free(hex);
+#else
+ image = make_hex_image(0xf000, mem_instr, sizeof (mem_instr));
+#endif
+
ccdbg_reset(dbg);
ccdbg_debug_mode(dbg);
- status = ccdbg_read_status(dbg);
- printf("Status: 0x%02x\n", status);
- chip_id = ccdbg_get_chip_id(dbg);
- printf("Chip id: 0x%04x\n", chip_id);
- status = ccdbg_halt(dbg);
- printf ("halt status: 0x%02x\n", status);
+ ccdbg_halt(dbg);
- ccdbg_write_hex(dbg, hex);
- ccdbg_hex_file_free(hex);
- for (i = 0; i < sizeof (memory); i++)
- printf (" %02x", memory[i]);
- printf ("\n");
- ccdbg_execute(dbg, jump_mem);
- pc = ccdbg_get_pc(dbg);
- printf ("pc starts at 0x%04x\n", pc);
- status = ccdbg_resume(dbg);
- printf ("resume status: 0x%02x\n", status);
+#if 1
+ if (!image) {
+ fprintf(stderr, "image create failed\n");
+ exit (1);
+ }
+ if (image->address == 0xf000) {
+ printf("Loading code to execute from RAM\n");
+ ccdbg_execute_hex_image(dbg, image);
+ } 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);
+ ccdbg_hex_image_free(image);
+ ccdbg_close(dbg);
+ exit(1);
+ }
+#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));
/* painfully slow for now */
#define CC_CLOCK_US (50)
+#define MOV_direct_data 0x75
+#define LJMP 0x02
+#define MOV_Rn_data(n) (0x78 | (n))
+#define DJNZ_Rn_rel(n) (0xd8 | (n))
+#define MOV_A_direct 0xe5
+#define MOV_direct_A 0xf5
+#define MOV_DPTR_data16 0x90
+#define MOV_A_data 0x74
+#define MOVX_atDPTR_A 0xf0
+#define MOVX_A_atDPTR 0xe0
+#define INC_DPTR 0xa3
+#define TRAP 0xa5
+
+#define SJMP 0x80
+
+#define FWT 0xAB
+#define FADDRL 0xAC
+#define FADDRH 0xAD
+#define FCTL 0xAE
+# define FCTL_BUSY 0x80
+# define FCTL_BUSY_BIT 7
+# define FCTL_SWBSY 0x40
+# define FCTL_SWBSY_BIT 6
+# define FCTL_CONTRD 0x10
+# define FCTL_WRITE 0x02
+# define FCTL_ERASE 0x01
+#define FWDATA 0xAF
+
+#define CLKCON 0xC6
+#define CLKCON_OSC32K 0x80
+#define CLKCON_OSC 0x40
+#define CLKCON_TICKSPD 0x38
+#define CLKCON_CLKSPD 0x07
+
+#define P0 0x80
+#define P1 0x90
+#define P2 0xA0
+#define P0DIR 0xFD
+#define P1DIR 0xFE
+#define P2DIR 0xFF
+
+#define SLEEP 0xBE
+
+#define JB 0x20
+
+#define ACC(bit) (0xE0 | (bit))
+
struct ccdbg {
usb_dev_handle *usb_dev;
uint8_t gpio;
int clock;
};
+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 {
+ uint16_t address;
+ uint16_t length;
+ uint8_t data[0];
+};
+
+#define HEX_RECORD_NORMAL 0x00
+#define HEX_RECORD_EOF 0x01
+#define HEX_RECORD_EXTENDED_ADDRESS 0x02
+
#include "cccp.h"
#define CC_CHIP_ERASE 0x14
uint8_t
ccdbg_rd_config(struct ccdbg *dbg);
-uint8_t
+uint16_t
ccdbg_get_pc(struct ccdbg *dbg);
uint8_t
uint8_t
ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);
+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-debug.c */
void
ccdbg_debug(int level, char *format, ...);
void
ccdbg_clear_debug(int level);
-/* ccdbg-hex.c */
-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];
-};
-
-#define HEX_RECORD_NORMAL 0x00
-#define HEX_RECORD_EOF 0x01
-#define HEX_RECORD_EXTENDED_ADDRESS 0x02
+/* 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);
+
+int
+ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b);
+
/* ccdbg-io.c */
void
ccdbg_half_clock(struct ccdbg *dbg);
ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
uint8_t
-ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex);
+ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset);
+
+struct hex_image *
+ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length);
/* cp-usb.c */
void