From 0ffe4ef870b0e564789a1990aeab5b6651868e5b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 27 Nov 2008 12:33:40 -0800 Subject: [PATCH 1/1] cc1111 debug port access through cp2103 serial chip --- Makefile | 17 ++++++ cccp.c | 68 ++++++++++++++++++++++++ cccp.h | 35 +++++++++++++ ccdbg-command.c | 43 +++++++++++++++ ccdbg-io.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ ccdbg.h | 80 ++++++++++++++++++++++++++++ 6 files changed, 378 insertions(+) create mode 100644 Makefile create mode 100644 cccp.c create mode 100644 cccp.h create mode 100644 ccdbg-command.c create mode 100644 ccdbg-io.c create mode 100644 ccdbg.h diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..54fd11f4 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +KERNEL=/local/src/linux-2.6-aiko-64 +KINC=$(KERNEL)/drivers/usb/serial + +CFLAGS=-g -I$(KINC) + +OBJS=ccdbg-command.o ccdbg-io.o cccp.o +INCS=ccdbg.h cccp.h + +PROG=ccdbg + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +$(OBJS): $(INCS) diff --git a/cccp.c b/cccp.c new file mode 100644 index 00000000..aff75e85 --- /dev/null +++ b/cccp.c @@ -0,0 +1,68 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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" + +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); + ret = ioctl(dbg->fd, CP2101_IOCTL_GPIOSET, &set); + if (ret < 0) + perror("CP2101_IOCTL_GPIOSET"); +} + +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; + } + return get & mask; +} + +void +cccp_init(struct ccdbg *dbg) +{ + /* set all of the GPIOs to a known state */ + cccp_write(dbg, 0xf, 0xf); + dbg->clock = 1; +} + +void +cccp_fini(struct ccdbg *dbg) +{ + /* set all of the GPIOs to a known state */ + cccp_write(dbg, 0xf, 0xf); + dbg->clock = 1; +} diff --git a/cccp.h b/cccp.h new file mode 100644 index 00000000..e71aa08e --- /dev/null +++ b/cccp.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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. + */ + +/* + * Interface for using a CP2103 to talk to a CC1111 + */ + +#ifndef _CCCP_H_ +#define _CCCP_H_ + +void +cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); + +uint8_t +cccp_read(struct ccdbg *dbg, uint8_t mask); + +void +cccp_init(struct ccdbg *dbg); + +#endif /* _CCCP_H_ */ diff --git a/ccdbg-command.c b/ccdbg-command.c new file mode 100644 index 00000000..3e42d48e --- /dev/null +++ b/ccdbg-command.c @@ -0,0 +1,43 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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" + +void +ccdbg_reset(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); + cccp_write(dbg, CC_RESET_N, CC_RESET_N); +} + +uint8_t +ccdbg_read_status(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0); +} + +uint8_t +ccdbg_rd_config(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0); +} diff --git a/ccdbg-io.c b/ccdbg-io.c new file mode 100644 index 00000000..2019885d --- /dev/null +++ b/ccdbg-io.c @@ -0,0 +1,135 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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" + +void +ccdbg_quarter_clock(struct ccdbg *dbg) +{ + usleep(CC_CLOCK_US / 4); +} + +struct ccdbg * +ccdbg_open(char *file) +{ + struct ccdbg *dbg; + + dbg = calloc(sizeof (struct ccdbg), 1); + if (!dbg) { + perror("calloc"); + return NULL; + } + dbg->fd = open(file, 2); + if (dbg->fd < 0) { + perror(file); + free(dbg); + return NULL; + } + cccp_init(dbg); + return dbg; +} + +void +ccdbg_clock_1_0(struct ccdbg *dbg) +{ + ccdbg_quarter_clock(dbg); + assert(dbg->clock == 1); + cccp_write(dbg, CC_CLOCK, 0); + dbg->clock = 0; + ccdbg_quarter_clock(dbg); +} + +void +ccdbg_clock_0_1(struct ccdbg *dbg) +{ + ccdbg_quarter_clock(dbg); + assert(dbg->clock == 0); + cccp_write(dbg, CC_CLOCK, CC_CLOCK); + dbg->clock = 1; + ccdbg_quarter_clock(dbg); +} + +/* + * By convention, every macro function is entered with dbg->clock == 1 + */ + +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); +} + +void +ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte) +{ + int bit; + + for (bit = 7; bit >= 0; bit--) + ccdbg_write_bit(dbg, (byte >> bit) & 1); +} + +uint8_t +ccdbg_read_bit(struct ccdbg *dbg) +{ + uint8_t data; + + ccdbg_clock_1_0(dbg); + data = cccp_read(dbg, CC_DATA); + ccdbg_clock_0_1(dbg); + return data ? 1 : 0; +} + +uint8_t +ccdbg_read_byte(struct ccdbg *dbg) +{ + int bit; + uint8_t byte = 0; + + for (bit = 7; bit >= 0; bit--) + byte |= ccdbg_read_bit(dbg) << bit; + return byte; +} + +void +ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + int i; + ccdbg_write_byte(dbg, cmd); + for (i = 0; i < len; i++) + ccdbg_write_byte(dbg, data[i]); +} + +uint8_t +ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + ccdbg_cmd_write(dbg, cmd, data, len); + return ccdbg_read_byte(dbg); +} + +uint16_t +ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + uint8_t byte1, byte0; + ccdbg_cmd_write(dbg, cmd, data, len); + byte1 = ccdbg_read_byte(dbg); + byte0 = ccdbg_read_byte(dbg); + return (byte1 << 8) | byte0; +} + diff --git a/ccdbg.h b/ccdbg.h new file mode 100644 index 00000000..8f937bd4 --- /dev/null +++ b/ccdbg.h @@ -0,0 +1,80 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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. + */ + +#ifndef _CCDBG_H_ +#define _CCDBG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CC_DATA CP2101_GPIO_MASK(0) +#define CC_CLOCK CP2101_GPIO_MASK(1) +#define CC_RESET_N CP2101_GPIO_MASK(2) + +/* painfully slow for now */ +#define CC_CLOCK_US (2 * 1000) + +struct ccdbg { + int fd; + uint8_t debug_data; + int clock; +}; + +#include "cccp.h" + +#define CC_CHIP_ERASE 0x14 + +#define CC_WR_CONFIG 0x1d +#define CC_RD_CONFIG 0x24 +# define CC_CONFIG_TIMERS_OFF (1 << 3) +# define CC_CONFIG_DMA_PAUSE (1 << 2) +# define CC_CONFIG_TIMER_SUSPEND (1 << 1) +# define CC_SET_FLASH_INFO_PAGE (1 << 0) + +#define CC_GET_PC 0x28 +#define CC_READ_STATUS 0x34 +# define CC_STATUS_CHIP_ERASE_DONE (1 << 7) +# define CC_STATUS_PCON_IDLE (1 << 6) +# define CC_STATUS_CPU_HALTED (1 << 5) +# define CC_STATUS_POWER_MODE_0 (1 << 4) +# define CC_STATUS_HALT_STATUS (1 << 3) +# define CC_STATUS_DEBUG_LOCKED (1 << 2) +# define CC_STATUS_OSCILLATOR_STABLE (1 << 1) +# define CC_STATUS_STACK_OVERFLOW (1 << 0) + +#define CC_SET_HW_BRKPNT 0x3b +# define CC_HW_BRKPNT_N(n) ((n) << 3) +# define CC_HW_BRKPNT_N_MASK (0x3 << 3) +# define CC_HW_BRKPNT_ENABLE (1 << 2) + +#define CC_HALT 0x44 +#define CC_RESUME 0x4c +#define CC_DEBUG_INSTR(n) (0x54|(n)) +#define CC_STEP_INSTR 0x5c +#define CC_STEP_REPLACE (0x64|(n)) +#define CC_GET_CHIP_ID 0x68 + +#endif /* _CCDBG_H_ */ -- 2.30.2