Random hacking
authorKeith Packard <keithp@keithp.com>
Sat, 29 Nov 2008 06:57:07 +0000 (22:57 -0800)
committerKeith Packard <keithp@keithp.com>
Sat, 29 Nov 2008 06:57:07 +0000 (22:57 -0800)
cccp.c
cccp.h
ccdbg-command.c
ccdbg-io.c
ccdbg.c
ccdbg.h

diff --git a/cccp.c b/cccp.c
index e5ee766aaea3ade46c77039eb2507f55bdbc40ff..99a0d81f1a11a895d470d558d7fdfe6caa8ac585 100644 (file)
--- a/cccp.c
+++ b/cccp.c
 
 #include "ccdbg.h"
 
 
 #include "ccdbg.h"
 
-void
-cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value)
+static void
+say(char *name, uint8_t bits)
+{
+       printf("%s: ", name);
+       if (bits & CC_RESET_N)
+               printf ("R ");
+       else
+               printf (". ");
+       if (bits & CC_CLOCK)
+               printf ("C ");
+       else
+               printf (". ");
+       if (bits & CC_DATA)
+               printf ("D\n");
+       else
+               printf (".\n");
+}
+
+static void
+_cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value)
 {
        uint16_t        set;
        int             ret;
 
        set = (mask) | (value << 8);
        dbg->debug_data = (dbg->debug_data & ~mask) | (value & mask);
 {
        uint16_t        set;
        int             ret;
 
        set = (mask) | (value << 8);
        dbg->debug_data = (dbg->debug_data & ~mask) | (value & mask);
-       printf (" -> %02x\n", dbg->debug_data);
        ret = ioctl(dbg->fd, CP2101_IOCTL_GPIOSET, &set);
        if (ret < 0)
                perror("CP2101_IOCTL_GPIOSET");
 }
 
        ret = ioctl(dbg->fd, CP2101_IOCTL_GPIOSET, &set);
        if (ret < 0)
                perror("CP2101_IOCTL_GPIOSET");
 }
 
+void
+cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value)
+{
+       _cccp_write(dbg, mask, value);
+//     say("w", dbg->debug_data);
+}
+
+uint8_t
+cccp_read_all(struct ccdbg *dbg)
+{
+       int ret;
+       uint8_t get;
+       ret = ioctl(dbg->fd, CP2101_IOCTL_GPIOGET, &get);
+       if (ret < 0) {
+               perror("CP2101_IOCTL_GPIOGET");
+               get = 0;
+       }
+       return get;
+}
+
 uint8_t
 cccp_read(struct ccdbg *dbg, uint8_t mask)
 {
        uint8_t         pull_up;
 uint8_t
 cccp_read(struct ccdbg *dbg, uint8_t mask)
 {
        uint8_t         pull_up;
-       int             ret;
        uint8_t         get;
 
        /* tri-state the bits of interest */
        pull_up = (~dbg->debug_data) & mask;
        uint8_t         get;
 
        /* tri-state the bits of interest */
        pull_up = (~dbg->debug_data) & mask;
-       if (pull_up) {
-               cccp_write(dbg, pull_up, pull_up);
-       }
-       ret = ioctl(dbg->fd, CP2101_IOCTL_GPIOGET, &get);
-       if (ret < 0) {
-               perror("CP2101_IOCTL_GPIOGET");
-               get = 0;
-       }
-       printf (" <- %02x\n", get);
+       if (pull_up)
+               _cccp_write(dbg, pull_up, pull_up);
+       get = cccp_read_all(dbg);
+       say("\t\tr", get);
        return get & mask;
 }
 
        return get & mask;
 }
 
@@ -58,7 +89,6 @@ cccp_init(struct ccdbg *dbg)
 {
        /* set all of the GPIOs to a known state */
        cccp_write(dbg, 0xf, 0xf);
 {
        /* set all of the GPIOs to a known state */
        cccp_write(dbg, 0xf, 0xf);
-       dbg->clock = 1;
 }
 
 void
 }
 
 void
diff --git a/cccp.h b/cccp.h
index ed952b016b702b643ad561e5746de1666397b10d..eecdbb495e1f4f1945a85fa33228aa8cc65e9631 100644 (file)
--- a/cccp.h
+++ b/cccp.h
@@ -26,6 +26,9 @@
 void
 cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);
 
 void
 cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);
 
+uint8_t
+cccp_read_all(struct ccdbg *dbg);
+
 uint8_t
 cccp_read(struct ccdbg *dbg, uint8_t mask);
 
 uint8_t
 cccp_read(struct ccdbg *dbg, uint8_t mask);
 
index 3e42d48e2dd8066bd890c4e80482b75ef9d81845..a0a12d9dba740185016192fe8b5a167372c18618 100644 (file)
 #include "ccdbg.h"
 
 void
 #include "ccdbg.h"
 
 void
-ccdbg_reset(struct ccdbg *dbg)
+ccdbg_debug_mode(struct ccdbg *dbg)
 {
        /* force two rising clocks while holding RESET_N low */
 {
        /* force two rising clocks while holding RESET_N low */
-       ccdbg_clock_1_0(dbg);
-       cccp_write(dbg, CC_RESET_N, 0);
-       ccdbg_clock_0_1(dbg);
-       ccdbg_clock_1_0(dbg);
-       ccdbg_clock_0_1(dbg);
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_RESET_N|CC_CLOCK, 0); ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, CC_CLOCK);     ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, 0);            ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, CC_CLOCK);     ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_RESET_N, CC_RESET_N); ccdbg_half_clock(dbg);
+}
+
+void
+ccdbg_reset(struct ccdbg *dbg)
+{
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_RESET_N, 0);         ccdbg_half_clock(dbg);
        cccp_write(dbg, CC_RESET_N, CC_RESET_N);
 }
 
        cccp_write(dbg, CC_RESET_N, CC_RESET_N);
 }
 
@@ -41,3 +49,10 @@ ccdbg_rd_config(struct ccdbg *dbg)
 {
        return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0);
 }
 {
        return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0);
 }
+
+uint16_t
+ccdbg_get_chip_id(struct ccdbg *dbg)
+{
+       return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0);
+}
+
index e72ffbf08ca9a6a6be91270a17b76227a7e6a67e..9586faa38bfcf0b7ed96d2784529a719f069ceb2 100644 (file)
@@ -24,6 +24,12 @@ ccdbg_quarter_clock(struct ccdbg *dbg)
        usleep(CC_CLOCK_US / 4);
 }
 
        usleep(CC_CLOCK_US / 4);
 }
 
+void
+ccdbg_half_clock(struct ccdbg *dbg)
+{
+       usleep(CC_CLOCK_US / 2);
+}
+
 struct ccdbg *
 ccdbg_open(char *file)
 {
 struct ccdbg *
 ccdbg_open(char *file)
 {
@@ -41,6 +47,8 @@ ccdbg_open(char *file)
                return NULL;
        }
        cccp_init(dbg);
                return NULL;
        }
        cccp_init(dbg);
+       cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+       dbg->clock = 1;
        return dbg;
 }
 
        return dbg;
 }
 
@@ -79,9 +87,17 @@ ccdbg_clock_0_1(struct ccdbg *dbg)
 void
 ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit)
 {
 void
 ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit)
 {
-       ccdbg_clock_1_0(dbg);
-       cccp_write(dbg, CC_DATA, bit ? CC_DATA : 0);
-       ccdbg_clock_0_1(dbg);
+       uint8_t data;
+
+       assert(dbg->clock == 1);
+       data = CC_CLOCK;
+       if (bit)
+               data |= CC_DATA;
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_DATA|CC_CLOCK, data);
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, 0);
+//     printf ("%d", bit);
 }
 
 void
 }
 
 void
@@ -98,9 +114,11 @@ ccdbg_read_bit(struct ccdbg *dbg)
 {
        uint8_t data;
 
 {
        uint8_t data;
 
-       ccdbg_clock_1_0(dbg);
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+       ccdbg_half_clock(dbg);
+       cccp_write(dbg, CC_CLOCK, 0);
        data = cccp_read(dbg, CC_DATA);
        data = cccp_read(dbg, CC_DATA);
-       ccdbg_clock_0_1(dbg);
        return data ? 1 : 0;
 }
 
        return data ? 1 : 0;
 }
 
@@ -127,17 +145,22 @@ ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
 uint8_t
 ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
 {
 uint8_t
 ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
 {
+       uint8_t ret;
        ccdbg_cmd_write(dbg, cmd, data, len);
        ccdbg_cmd_write(dbg, cmd, data, len);
-       return ccdbg_read_byte(dbg);
+       ret = ccdbg_read_byte(dbg);
+       return ret;
 }
 
 uint16_t
 ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
 {
        uint8_t byte1, byte0;
 }
 
 uint16_t
 ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
 {
        uint8_t byte1, byte0;
+       int     i;
        ccdbg_cmd_write(dbg, cmd, data, len);
        byte1 = ccdbg_read_byte(dbg); 
        byte0 = ccdbg_read_byte(dbg);
        ccdbg_cmd_write(dbg, cmd, data, len);
        byte1 = ccdbg_read_byte(dbg); 
        byte0 = ccdbg_read_byte(dbg);
+       for (i = 0; i < 4; i++)
+               (void) ccdbg_read_byte(dbg);
        return (byte1 << 8) | byte0;
 }
 
        return (byte1 << 8) | byte0;
 }
 
diff --git a/ccdbg.c b/ccdbg.c
index a2b5946db62ec0ad8e4d7fd14a9ff0e18a492c22..64cb768f4447f1fbb2e798005739489de590b565 100644 (file)
--- a/ccdbg.c
+++ b/ccdbg.c
 
 #include "ccdbg.h"
 
 
 #include "ccdbg.h"
 
+static uint8_t
+get_bit(char *line, int i, char on, uint8_t bit)
+{
+       if (line[i] == on)
+               return bit;
+       if (line[i] == '.')
+               return 0;
+       fprintf(stderr, "bad line %s\n", line);
+       exit (1);
+}
+
+static char
+is_bit(uint8_t get, char on, uint8_t bit)
+{
+       if (get&bit)
+               return on;
+       else
+               return '.';
+}
+
+static uint8_t
+ccdbg_write_read(struct ccdbg *dbg, uint8_t set)
+{
+       uint8_t get;
+
+       cccp_write(dbg, CC_DATA|CC_CLOCK|CC_RESET_N, set);
+       get = cccp_read_all(dbg);
+       printf("%c %c %c -> %c %c %c\n",
+              is_bit(set, 'C', CC_CLOCK),
+              is_bit(set, 'D', CC_DATA),
+              is_bit(set, 'R', CC_RESET_N),
+              is_bit(get, 'C', CC_CLOCK),
+              is_bit(get, 'D', CC_DATA),
+              is_bit(get, 'R', CC_RESET_N));
+       ccdbg_half_clock(dbg);
+       return get;
+}
+
+static void
+_ccdbg_debug_mode(struct ccdbg *dbg)
+{
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
+       ccdbg_write_read(dbg,          CC_DATA           );
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA           );
+       ccdbg_write_read(dbg,          CC_DATA           );
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA           );
+       ccdbg_write_read(dbg,          CC_DATA|CC_RESET_N);
+}
+
+static void
+_ccdbg_reset(struct ccdbg *dbg)
+{
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA           );
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA           );
+       ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
+}
+
+static void
+ccdbg_manual(struct ccdbg *dbg, FILE *input)
+{
+       char    line[80];
+       uint8_t set;
+
+       while (fgets(line, sizeof line, input)) {
+               if (line[0] == '#' || line[0] == '\n') {
+                       printf ("%s", line);
+                       continue;
+               }
+               set = 0;
+               set |= get_bit(line, 0, 'C', CC_CLOCK);
+               set |= get_bit(line, 2, 'D', CC_DATA);
+               set |= get_bit(line, 4, 'R', CC_RESET_N);
+               ccdbg_write_read(dbg, set);
+       }
+}
+
 int
 main (int argc, char **argv)
 {
        struct ccdbg    *dbg;
        uint8_t         status;
 int
 main (int argc, char **argv)
 {
        struct ccdbg    *dbg;
        uint8_t         status;
+       uint16_t        chip_id;
 
        dbg = ccdbg_open("/dev/ttyUSB0");
        if (!dbg)
                exit (1);
 
        dbg = ccdbg_open("/dev/ttyUSB0");
        if (!dbg)
                exit (1);
-       ccdbg_reset(dbg);
+       ccdbg_manual(dbg, stdin);
+#if 0  
+       ccdbg_debug_mode(dbg);
        status = ccdbg_read_status(dbg);
        printf("Status: 0x%02x\n", status);
        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);
+#endif
+       _ccdbg_reset(dbg);
        ccdbg_close(dbg);
        exit (0);
 }
        ccdbg_close(dbg);
        exit (0);
 }
diff --git a/ccdbg.h b/ccdbg.h
index 32283c0d8e09527c74f6df6814555d3538c34d67..2085cbe05098def39ea9ce2407cf4f08bb9730f9 100644 (file)
--- a/ccdbg.h
+++ b/ccdbg.h
@@ -37,7 +37,7 @@
 #define CC_RESET_N     CP2101_GPIO_MASK(2)
 
 /* painfully slow for now */
 #define CC_RESET_N     CP2101_GPIO_MASK(2)
 
 /* painfully slow for now */
-#define CC_CLOCK_US    (1000 * 1000)
+#define CC_CLOCK_US    (1 * 1000)
 
 struct ccdbg {
        int     fd;
 
 struct ccdbg {
        int     fd;
@@ -80,6 +80,9 @@ struct ccdbg {
 #define CC_GET_CHIP_ID         0x68
 
 /* ccdbg-command.c */
 #define CC_GET_CHIP_ID         0x68
 
 /* ccdbg-command.c */
+void
+ccdbg_debug_mode(struct ccdbg *dbg);
+
 void
 ccdbg_reset(struct ccdbg *dbg);
 
 void
 ccdbg_reset(struct ccdbg *dbg);
 
@@ -89,10 +92,16 @@ ccdbg_read_status(struct ccdbg *dbg);
 uint8_t
 ccdbg_rd_config(struct ccdbg *dbg);
 
 uint8_t
 ccdbg_rd_config(struct ccdbg *dbg);
 
+uint16_t
+ccdbg_get_chip_id(struct ccdbg *dbg);
+
 /* ccdbg-io.c */
 void
 ccdbg_quarter_clock(struct ccdbg *dbg);
 
 /* ccdbg-io.c */
 void
 ccdbg_quarter_clock(struct ccdbg *dbg);
 
+void
+ccdbg_half_clock(struct ccdbg *dbg);
+
 struct ccdbg *
 ccdbg_open(char *file);
 
 struct ccdbg *
 ccdbg_open(char *file);