#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);
- printf (" -> %02x\n", dbg->debug_data);
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;
- int ret;
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;
}
{
/* set all of the GPIOs to a known state */
cccp_write(dbg, 0xf, 0xf);
- dbg->clock = 1;
}
void
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);
#include "ccdbg.h"
void
-ccdbg_reset(struct ccdbg *dbg)
+ccdbg_debug_mode(struct ccdbg *dbg)
{
/* 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);
}
{
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);
+}
+
usleep(CC_CLOCK_US / 4);
}
+void
+ccdbg_half_clock(struct ccdbg *dbg)
+{
+ usleep(CC_CLOCK_US / 2);
+}
+
struct ccdbg *
ccdbg_open(char *file)
{
return NULL;
}
cccp_init(dbg);
+ cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+ dbg->clock = 1;
return dbg;
}
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
{
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);
- ccdbg_clock_0_1(dbg);
return data ? 1 : 0;
}
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);
- 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;
+ int i;
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;
}
#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;
+ uint16_t chip_id;
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);
+ chip_id = ccdbg_get_chip_id(dbg);
+ printf("Chip id: 0x%04x\n", chip_id);
+#endif
+ _ccdbg_reset(dbg);
ccdbg_close(dbg);
exit (0);
}
#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;
#define CC_GET_CHIP_ID 0x68
/* ccdbg-command.c */
+void
+ccdbg_debug_mode(struct ccdbg *dbg);
+
void
ccdbg_reset(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);
+void
+ccdbg_half_clock(struct ccdbg *dbg);
+
struct ccdbg *
ccdbg_open(char *file);