Add ability to read/write arbitrary memory. Write LED blinker program.
authorKeith Packard <keithp@keithp.com>
Thu, 18 Dec 2008 08:18:50 +0000 (00:18 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 18 Dec 2008 08:18:50 +0000 (00:18 -0800)
Signed-off-by: Keith Packard <keithp@keithp.com>
Makefile
ccdbg-command.c
ccdbg-io.c
ccdbg-memory.c [new file with mode: 0644]
ccdbg.c
ccdbg.h

index 965032e41130a3c97fe3e96e44fc553751c101a2..2fd8ec6dfac8d97c56cb164bc66d6d57cfd2d83e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,9 @@ LIBS=-lusb
 KERNEL_OBJS=cccp.o
 LIBUSB_OBJS=cp-usb.o
 
-OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o ccdbg-io.o $(LIBUSB_OBJS)
+OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o \
+       ccdbg-io.o ccdbg-memory.o \
+       $(LIBUSB_OBJS)
 INCS=ccdbg.h cccp.h
 
 PROG=ccdbg
index 415010f823d439b54e56cb7d83e13d6d69e1d215..50dd1fd4500612e3fe002b666e18b9a04b8b104a 100644 (file)
@@ -123,3 +123,26 @@ ccdbg_get_chip_id(struct ccdbg *dbg)
 {
        return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0);
 }
+
+/*
+ * Execute a sequence of instructions
+ */
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst)
+{
+       uint8_t status = 0;
+       while(inst[0] != 0) {
+               uint8_t len = inst[0];
+               int i;
+               ccdbg_debug(CC_DEBUG_INSTRUCTIONS, "\t%02x", inst[1]);
+               for (i = 0; i < len - 1; i++)
+                       ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " %02x", inst[i+2]);
+               status = ccdbg_debug_instr(dbg, inst+1, len);
+               for (; i < 3; i++)
+                       ccdbg_debug(CC_DEBUG_INSTRUCTIONS, "   ");
+               ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " -> %02x\n", status);
+               inst += len + 1;
+       }
+       return status;
+}
+
index c69fc0d816751172b190393a96de95bbc047f83d..765bde845cabedcd643fe270b5b3c0363063f3e7 100644 (file)
  */
 
 #include "ccdbg.h"
-
-void
-ccdbg_quarter_clock(struct ccdbg *dbg)
-{
-       usleep(CC_CLOCK_US / 4);
-}
+#include <time.h>
 
 void
 ccdbg_half_clock(struct ccdbg *dbg)
 {
-       usleep(CC_CLOCK_US / 2);
+       struct timespec req, rem;
+       req.tv_sec = (CC_CLOCK_US / 2) / 1000000;
+       req.tv_nsec = ((CC_CLOCK_US / 2) % 1000000) * 1000;
+//     nanosleep(&req, &rem);
 }
 
 struct ccdbg *
diff --git a/ccdbg-memory.c b/ccdbg-memory.c
new file mode 100644 (file)
index 0000000..ffc0967
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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"
+
+/*
+ * 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,
+#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,
+#define DATA_BYTE      2
+       1,      MOVX_atdptr_a,
+       1,      INC_dptr,
+       0
+};
+
+static uint8_t read8[] = {
+       1,      MOVX_a_atdptr,
+       1,      INC_dptr,
+       0,
+};
+
+uint8_t
+ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+       memory_init[HIGH_START] = addr >> 8;
+       memory_init[LOW_START] = addr;
+       (void) ccdbg_execute(dbg, memory_init);
+       while (nbytes-- > 0) {
+               write8[DATA_BYTE] = *bytes++;
+               ccdbg_execute(dbg, write8);
+       }
+       return 0;
+}
+
+uint8_t
+ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+       memory_init[HIGH_START] = addr >> 8;
+       memory_init[LOW_START] = addr;
+       (void) ccdbg_execute(dbg, memory_init);
+       while (nbytes-- > 0)
+               *bytes++ = ccdbg_execute(dbg, read8);
+       return 0;
+}
diff --git a/ccdbg.c b/ccdbg.c
index b682372a96ba5a1d4615908aaf202add8a1a7488..a35481438bc4db6b8897d95429a219df4d87679e 100644 (file)
--- a/ccdbg.c
+++ b/ccdbg.c
 
 #include "ccdbg.h"
 
-#define MOV    0x75
+#define MOV_direct_data                0x75
+#define LJMP                   0x02
+#define MOV_Rn_data(n)         (0x78 | (n))
+#define DJNZ_Rn_rel(n)         (0xd8 | (n))
 
+#if 0
 static uint8_t instructions[] = {
-       3, MOV, 0xfe, 0x02,
-       3, MOV, 0x90, 0xff,
+       3, MOV_direct_data, 0xfe, 0x02,
+       3, MOV_direct_data, 0x90, 0xff,
        0
 };
+#endif
 
-static void
-ccdbg_instructions(struct ccdbg *dbg, uint8_t *inst)
-{
-       while(inst[0] != 0) {
-               uint8_t len = inst[0];
-               uint8_t status;
-               status = ccdbg_debug_instr(dbg, inst+1, len);
-               printf ("inst status 0x%02x\n", status);
-               inst += len + 1;
-       }
-}
+static uint8_t mem_instr[] = {
+       MOV_direct_data, 0xfe, 0x02,
+       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,
+       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
+};
+
+static uint8_t jump_mem[] = {
+       3, LJMP, 0xf0, 0x00,
+       0
+};
 
 int
 main (int argc, char **argv)
@@ -44,6 +61,9 @@ main (int argc, char **argv)
        struct ccdbg    *dbg;
        uint8_t         status;
        uint16_t        chip_id;
+       uint16_t        pc;
+       uint8_t         memory[0x10];
+       int             i;
 
        dbg = ccdbg_open("/dev/ttyUSB0");
        if (!dbg)
@@ -52,6 +72,7 @@ main (int argc, char **argv)
        ccdbg_manual(dbg, stdin);
 #endif
 #if 1
+       ccdbg_reset(dbg);
        ccdbg_debug_mode(dbg);
        status = ccdbg_read_status(dbg);
        printf("Status: 0x%02x\n", status);
@@ -59,7 +80,17 @@ main (int argc, char **argv)
        printf("Chip id: 0x%04x\n", chip_id);
        status = ccdbg_halt(dbg);
        printf ("halt status: 0x%02x\n", status);
-       ccdbg_instructions(dbg, instructions);
+/*     ccdbg_execute(dbg, instructions); */
+       ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr));
+       ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory));
+       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);
 #endif
        ccdbg_close(dbg);
        exit (0);
diff --git a/ccdbg.h b/ccdbg.h
index 7d9940c30bb49b80312d323cf3b314ffac41aaf5..0f07e2e90a35a5b162409064e3fecac13940a436 100644 (file)
--- a/ccdbg.h
+++ b/ccdbg.h
@@ -93,6 +93,7 @@ struct ccdbg {
 
 #define CC_DEBUG_BITBANG       0x00000001
 #define CC_DEBUG_COMMAND       0x00000002
+#define CC_DEBUG_INSTRUCTIONS  0x00000004
 
 /* ccdbg-command.c */
 void
@@ -137,7 +138,8 @@ ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes);
 uint16_t
 ccdbg_get_chip_id(struct ccdbg *dbg);
 
-
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);
        
 /* ccdbg-debug.c */
 void
@@ -150,9 +152,6 @@ void
 ccdbg_clear_debug(int level);
 
 /* ccdbg-io.c */
-void
-ccdbg_quarter_clock(struct ccdbg *dbg);
-
 void
 ccdbg_half_clock(struct ccdbg *dbg);
 
@@ -224,6 +223,13 @@ ccdbg_print(char *format, uint8_t mask, uint8_t set);
 void
 ccdbg_manual(struct ccdbg *dbg, FILE *input);
 
+/* ccdbg-memory.c */
+uint8_t
+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);
+
 /* cp-usb.c */
 void
 cp_usb_init(struct ccdbg *dbg);