From 0ffe4ef870b0e564789a1990aeab5b6651868e5b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 27 Nov 2008 12:33:40 -0800 Subject: 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_ */ -- cgit v1.2.3 From 01cb2799875e086ee6096627c058ee235bbc33d5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 27 Nov 2008 17:07:15 -0800 Subject: Add prototypes, add stub mainline, add .gitignore --- .gitignore | 2 ++ Makefile | 6 ++++-- cccp.c | 2 ++ cccp.h | 3 +++ ccdbg-io.c | 8 ++++++++ ccdbg.c | 35 +++++++++++++++++++++++++++++++++++ ccdbg.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 ccdbg.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fe255c6f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ccdbg +*.o diff --git a/Makefile b/Makefile index 54fd11f4..8e80e65c 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,11 @@ KERNEL=/local/src/linux-2.6-aiko-64 KINC=$(KERNEL)/drivers/usb/serial -CFLAGS=-g -I$(KINC) +WARN=-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes\ + -Wmissing-declarations -Wnested-externs -fno-strict-aliasing +CFLAGS=-g -I$(KINC) $(WARN) -OBJS=ccdbg-command.o ccdbg-io.o cccp.o +OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o cccp.o INCS=ccdbg.h cccp.h PROG=ccdbg diff --git a/cccp.c b/cccp.c index aff75e85..e5ee766a 100644 --- a/cccp.c +++ b/cccp.c @@ -26,6 +26,7 @@ cccp_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) 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"); @@ -48,6 +49,7 @@ cccp_read(struct ccdbg *dbg, uint8_t mask) perror("CP2101_IOCTL_GPIOGET"); get = 0; } + printf (" <- %02x\n", get); return get & mask; } diff --git a/cccp.h b/cccp.h index e71aa08e..ed952b01 100644 --- a/cccp.h +++ b/cccp.h @@ -32,4 +32,7 @@ cccp_read(struct ccdbg *dbg, uint8_t mask); void cccp_init(struct ccdbg *dbg); +void +cccp_fini(struct ccdbg *dbg); + #endif /* _CCCP_H_ */ diff --git a/ccdbg-io.c b/ccdbg-io.c index 2019885d..e72ffbf0 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -44,6 +44,14 @@ ccdbg_open(char *file) return dbg; } +void +ccdbg_close(struct ccdbg *dbg) +{ + cccp_fini(dbg); + close (dbg->fd); + free (dbg); +} + void ccdbg_clock_1_0(struct ccdbg *dbg) { diff --git a/ccdbg.c b/ccdbg.c new file mode 100644 index 00000000..a2b5946d --- /dev/null +++ b/ccdbg.c @@ -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. + */ + +#include "ccdbg.h" + +int +main (int argc, char **argv) +{ + struct ccdbg *dbg; + uint8_t status; + + dbg = ccdbg_open("/dev/ttyUSB0"); + if (!dbg) + exit (1); + ccdbg_reset(dbg); + status = ccdbg_read_status(dbg); + printf("Status: 0x%02x\n", status); + ccdbg_close(dbg); + exit (0); +} diff --git a/ccdbg.h b/ccdbg.h index 8f937bd4..32283c0d 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #include #define CC_DATA CP2101_GPIO_MASK(0) @@ -35,7 +37,7 @@ #define CC_RESET_N CP2101_GPIO_MASK(2) /* painfully slow for now */ -#define CC_CLOCK_US (2 * 1000) +#define CC_CLOCK_US (1000 * 1000) struct ccdbg { int fd; @@ -77,4 +79,51 @@ struct ccdbg { #define CC_STEP_REPLACE (0x64|(n)) #define CC_GET_CHIP_ID 0x68 +/* ccdbg-command.c */ +void +ccdbg_reset(struct ccdbg *dbg); + +uint8_t +ccdbg_read_status(struct ccdbg *dbg); + +uint8_t +ccdbg_rd_config(struct ccdbg *dbg); + +/* ccdbg-io.c */ +void +ccdbg_quarter_clock(struct ccdbg *dbg); + +struct ccdbg * +ccdbg_open(char *file); + +void +ccdbg_close(struct ccdbg *dbg); + +void +ccdbg_clock_1_0(struct ccdbg *dbg); + +void +ccdbg_clock_0_1(struct ccdbg *dbg); + +void +ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit); + +void +ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte); + +uint8_t +ccdbg_read_bit(struct ccdbg *dbg); + +uint8_t +ccdbg_read_byte(struct ccdbg *dbg); + +void +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); + +uint16_t +ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); + #endif /* _CCDBG_H_ */ -- cgit v1.2.3 From 39801e6e9fb9388072ee414a447f74095a6ac960 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 28 Nov 2008 22:57:07 -0800 Subject: Random hacking --- cccp.c | 58 ++++++++++++++++++++++++++++---------- cccp.h | 3 ++ ccdbg-command.c | 27 ++++++++++++++---- ccdbg-io.c | 35 +++++++++++++++++++---- ccdbg.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ccdbg.h | 11 +++++++- 6 files changed, 192 insertions(+), 28 deletions(-) diff --git a/cccp.c b/cccp.c index e5ee766a..99a0d81f 100644 --- a/cccp.c +++ b/cccp.c @@ -18,38 +18,69 @@ #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; } @@ -58,7 +89,6 @@ cccp_init(struct ccdbg *dbg) { /* set all of the GPIOs to a known state */ cccp_write(dbg, 0xf, 0xf); - dbg->clock = 1; } void diff --git a/cccp.h b/cccp.h index ed952b01..eecdbb49 100644 --- a/cccp.h +++ b/cccp.h @@ -26,6 +26,9 @@ 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); diff --git a/ccdbg-command.c b/ccdbg-command.c index 3e42d48e..a0a12d9d 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -19,14 +19,22 @@ #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); } @@ -41,3 +49,10 @@ ccdbg_rd_config(struct ccdbg *dbg) { 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); +} + diff --git a/ccdbg-io.c b/ccdbg-io.c index e72ffbf0..9586faa3 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -24,6 +24,12 @@ ccdbg_quarter_clock(struct ccdbg *dbg) usleep(CC_CLOCK_US / 4); } +void +ccdbg_half_clock(struct ccdbg *dbg) +{ + usleep(CC_CLOCK_US / 2); +} + struct ccdbg * ccdbg_open(char *file) { @@ -41,6 +47,8 @@ ccdbg_open(char *file) return NULL; } cccp_init(dbg); + cccp_write(dbg, CC_CLOCK, CC_CLOCK); + dbg->clock = 1; return dbg; } @@ -79,9 +87,17 @@ ccdbg_clock_0_1(struct ccdbg *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 @@ -98,9 +114,11 @@ ccdbg_read_bit(struct ccdbg *dbg) { 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; } @@ -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 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; } diff --git a/ccdbg.c b/ccdbg.c index a2b5946d..64cb768f 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,18 +18,102 @@ #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); } diff --git a/ccdbg.h b/ccdbg.h index 32283c0d..2085cbe0 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -37,7 +37,7 @@ #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; @@ -80,6 +80,9 @@ struct ccdbg { #define CC_GET_CHIP_ID 0x68 /* ccdbg-command.c */ +void +ccdbg_debug_mode(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); +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); -- cgit v1.2.3 From 3709ec3205cfb152b6568f3ea505c67fe7504c2a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Dec 2008 16:32:12 -0800 Subject: Add libusb support and lots more examples --- 1101 | 131 +++++++++++++++++++++ Makefile | 8 +- ccdbg-command.c | 14 +-- ccdbg-io.c | 46 ++++++-- ccdbg.c | 140 ++++++++++++++++++++++- ccdbg.h | 35 +++++- chip_id | 114 ++++++++++++++++++ cp-usb.c | 140 +++++++++++++++++++++++ debug_mode | 11 ++ get_pc | 71 ++++++++++++ get_status | 71 ++++++++++++ half_phase | 71 ++++++++++++ in | 146 ++++++++++++++++++++++++ p1_1 | 349 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ read_status | 71 ++++++++++++ reset | 5 + wr_config | 116 +++++++++++++++++++ 17 files changed, 1516 insertions(+), 23 deletions(-) create mode 100644 1101 create mode 100644 chip_id create mode 100644 cp-usb.c create mode 100644 debug_mode create mode 100644 get_pc create mode 100644 get_status create mode 100644 half_phase create mode 100644 in create mode 100644 p1_1 create mode 100644 read_status create mode 100644 reset create mode 100644 wr_config diff --git a/1101 b/1101 new file mode 100644 index 00000000..b5e9b3c4 --- /dev/null +++ b/1101 @@ -0,0 +1,131 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# 1101 with zeros +# + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R + +# try sending READ_STATUS + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + + +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/Makefile b/Makefile index 8e80e65c..27a389e2 100644 --- a/Makefile +++ b/Makefile @@ -4,14 +4,18 @@ KINC=$(KERNEL)/drivers/usb/serial WARN=-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes\ -Wmissing-declarations -Wnested-externs -fno-strict-aliasing CFLAGS=-g -I$(KINC) $(WARN) +LIBS=-lusb -OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o cccp.o +KERNEL_OBJS=cccp.o +LIBUSB_OBJS=cp-usb.o + +OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o $(LIBUSB_OBJS) INCS=ccdbg.h cccp.h PROG=ccdbg $(PROG): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) clean: rm -f $(PROG) $(OBJS) diff --git a/ccdbg-command.c b/ccdbg-command.c index a0a12d9d..f79d3621 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -23,19 +23,19 @@ ccdbg_debug_mode(struct ccdbg *dbg) { /* force two rising clocks while holding RESET_N low */ 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); + ccdbg_write(dbg, CC_RESET_N|CC_CLOCK, 0); ccdbg_half_clock(dbg); + ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg); + ccdbg_write(dbg, CC_CLOCK, 0); ccdbg_half_clock(dbg); + ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg); + ccdbg_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); + ccdbg_write(dbg, CC_RESET_N, 0); ccdbg_half_clock(dbg); + ccdbg_write(dbg, CC_RESET_N, CC_RESET_N); } uint8_t diff --git a/ccdbg-io.c b/ccdbg-io.c index 9586faa3..2cd42e27 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -40,6 +40,8 @@ ccdbg_open(char *file) perror("calloc"); return NULL; } + dbg->clock = 1; +#ifdef USE_KERNEL dbg->fd = open(file, 2); if (dbg->fd < 0) { perror(file); @@ -48,6 +50,9 @@ ccdbg_open(char *file) } cccp_init(dbg); cccp_write(dbg, CC_CLOCK, CC_CLOCK); +#else + cp_usb_init(dbg); +#endif dbg->clock = 1; return dbg; } @@ -55,17 +60,42 @@ ccdbg_open(char *file) void ccdbg_close(struct ccdbg *dbg) { +#if USE_KERNEL cccp_fini(dbg); close (dbg->fd); +#else + cp_usb_fini(dbg); +#endif free (dbg); } +int +ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ +#if USE_KERNEL + return cccp_write(dbg, mask, value); +#else + cp_usb_write(dbg, mask, value); + return 0; +#endif +} + +uint8_t +ccdbg_read(struct ccdbg *dbg) +{ +#if USE_KERNEL + return cccp_read_all(dbg); +#else + return cp_usb_read(dbg); +#endif +} + void ccdbg_clock_1_0(struct ccdbg *dbg) { ccdbg_quarter_clock(dbg); assert(dbg->clock == 1); - cccp_write(dbg, CC_CLOCK, 0); + ccdbg_write(dbg, CC_CLOCK, 0); dbg->clock = 0; ccdbg_quarter_clock(dbg); } @@ -75,7 +105,7 @@ ccdbg_clock_0_1(struct ccdbg *dbg) { ccdbg_quarter_clock(dbg); assert(dbg->clock == 0); - cccp_write(dbg, CC_CLOCK, CC_CLOCK); + ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); dbg->clock = 1; ccdbg_quarter_clock(dbg); } @@ -94,9 +124,9 @@ ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit) if (bit) data |= CC_DATA; ccdbg_half_clock(dbg); - cccp_write(dbg, CC_DATA|CC_CLOCK, data); + ccdbg_write(dbg, CC_DATA|CC_CLOCK, data); ccdbg_half_clock(dbg); - cccp_write(dbg, CC_CLOCK, 0); + ccdbg_write(dbg, CC_CLOCK, 0); // printf ("%d", bit); } @@ -115,11 +145,11 @@ ccdbg_read_bit(struct ccdbg *dbg) uint8_t data; ccdbg_half_clock(dbg); - cccp_write(dbg, CC_CLOCK, CC_CLOCK); + ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg); - cccp_write(dbg, CC_CLOCK, 0); - data = cccp_read(dbg, CC_DATA); - return data ? 1 : 0; + ccdbg_write(dbg, CC_CLOCK, 0); + data = ccdbg_read(dbg); + return (data & CC_DATA) ? 1 : 0; } uint8_t diff --git a/ccdbg.c b/ccdbg.c index 64cb768f..39fc1016 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -43,8 +43,8 @@ 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); + ccdbg_write(dbg, CC_DATA|CC_CLOCK|CC_RESET_N, set); + get = ccdbg_read(dbg); printf("%c %c %c -> %c %c %c\n", is_bit(set, 'C', CC_CLOCK), is_bit(set, 'D', CC_DATA), @@ -59,6 +59,9 @@ ccdbg_write_read(struct ccdbg *dbg, uint8_t set) static void _ccdbg_debug_mode(struct ccdbg *dbg) { + printf ("#\n"); + printf ("# Debug mode\n"); + printf ("#\n"); 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 ); @@ -76,6 +79,131 @@ _ccdbg_reset(struct ccdbg *dbg) ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N); } +static void +_ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) +{ + if (bit) bit = CC_DATA; + ccdbg_write_read(dbg, CC_CLOCK|bit|CC_RESET_N); + ccdbg_write_read(dbg, bit|CC_RESET_N); +} + +static void +_ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) +{ + int bit; + printf ("#\n"); + printf ("# Send Byte 0x%02x\n", byte); + printf ("#\n"); + for (bit = 7; bit >= 0; bit--) { + _ccdbg_send_bit(dbg, (byte >> bit) & 1); + if (bit == 3) + printf ("\n"); + } +} + +static void +_ccdbg_send_bits(struct ccdbg *dbg, int n, uint32_t bits) +{ + int bit; + printf ("#\n"); + printf ("# Send %d bits 0x%08x\n", n, bits); + printf ("#\n"); + for (bit = n - 1; bit >= 0; bit--) { + _ccdbg_send_bit(dbg, (bits >> bit) & 1); + if ((bit & 3) == 3) + printf ("\n"); + } +} + +static void +_ccdbg_print_bits(int n, uint32_t bits) +{ + int bit; + + for (bit = n - 1; bit >= 0; bit--) + printf ("%d", (bits >> bit) & 1); +} + +static uint32_t +_ccdbg_read_bits(struct ccdbg *dbg, int bits) +{ + int bit; + uint32_t val = 0; + uint8_t get; + + printf ("#\n"); + printf ("# Read %d bits\n", bits); + printf ("#\n"); + for (bit = 0; bit < bits; bit++) { + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N); + get = ccdbg_write_read(dbg, CC_DATA|CC_RESET_N); + val <<= 1; + if (get & CC_DATA) + val |= 1; + if ((bit & 3) == 3) + printf ("\n"); + } + printf ("#\n"); + printf ("# Read "); _ccdbg_print_bits(bits, val); printf ("\n"); + printf ("#\n"); + return val; +} + +static int +_ccdbg_check_bits(uint32_t bits, uint8_t match) +{ + int bit; + + for (bit = 0; bit < 24; bit++) + if (((bits >> bit) & 0xff) == match) + return 1; + return 0; +} + +static uint32_t +_ccdbg_play(struct ccdbg *dbg, int num_sync, uint32_t sync) +{ + uint32_t bits; + _ccdbg_debug_mode(dbg); + _ccdbg_send_bits(dbg, num_sync, sync); + _ccdbg_send_byte(dbg, CC_GET_CHIP_ID); + bits = _ccdbg_read_bits(dbg, 16); + _ccdbg_send_byte(dbg, CC_GET_CHIP_ID); + bits = _ccdbg_read_bits(dbg, 16); +// _ccdbg_send_byte(dbg, CC_READ_STATUS); + _ccdbg_reset(dbg); + if (_ccdbg_check_bits(bits, 0x11)) { + printf("#\n#match with %d bits 0x%08x\n#\n", num_sync, sync); + return 1; + } + return 0; +} + +static int +_ccdbg_play_num(struct ccdbg *dbg, int num) +{ + uint32_t sync; + uint32_t max; + + printf ("#\n#play %d\n#\n", num); + max = (1 << num); + for (sync = 0; sync < max; sync++) + if (_ccdbg_play(dbg, num, sync)) + return 1; + return 0; +} + +static int +_ccdbg_play_many(struct ccdbg *dbg, int max) +{ + int num; + + for (num = 0; num < max; num++) + if (_ccdbg_play_num(dbg, num)) + return 1; + return 0; +} + static void ccdbg_manual(struct ccdbg *dbg, FILE *input) { @@ -105,15 +233,19 @@ main (int argc, char **argv) dbg = ccdbg_open("/dev/ttyUSB0"); if (!dbg) exit (1); - ccdbg_manual(dbg, stdin); #if 0 + _ccdbg_play(dbg, 0, 0); + _ccdbg_play_many(dbg, 8); +#endif + 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); +#endif ccdbg_close(dbg); exit (0); } diff --git a/ccdbg.h b/ccdbg.h index 2085cbe0..19cf8fa3 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -30,17 +30,29 @@ #include #include #include +#undef USE_KERNEL +#ifdef USE_KERNEL #include - #define CC_DATA CP2101_GPIO_MASK(0) #define CC_CLOCK CP2101_GPIO_MASK(1) #define CC_RESET_N CP2101_GPIO_MASK(2) +#else +#define CC_CLOCK 0x1 +#define CC_DATA 0x2 +#define CC_RESET_N 0x4 +#include +#endif + /* painfully slow for now */ -#define CC_CLOCK_US (1 * 1000) +#define CC_CLOCK_US (100 * 1000) struct ccdbg { + usb_dev_handle *usb_dev; + uint8_t gpio; +#ifdef USE_KERNEL int fd; +#endif uint8_t debug_data; int clock; }; @@ -102,6 +114,12 @@ ccdbg_quarter_clock(struct ccdbg *dbg); void ccdbg_half_clock(struct ccdbg *dbg); +int +ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); + +uint8_t +ccdbg_read(struct ccdbg *dbg); + struct ccdbg * ccdbg_open(char *file); @@ -135,4 +153,17 @@ ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); uint16_t ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); +/* cp-usb.c */ +void +cp_usb_init(struct ccdbg *dbg); + +void +cp_usb_fini(struct ccdbg *dbg); + +void +cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); + +uint8_t +cp_usb_read(struct ccdbg *dbg); + #endif /* _CCDBG_H_ */ diff --git a/chip_id b/chip_id new file mode 100644 index 00000000..4343cec2 --- /dev/null +++ b/chip_id @@ -0,0 +1,114 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_CHIP_ID + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# start reading again + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/cp-usb.c b/cp-usb.c new file mode 100644 index 00000000..3822e8cd --- /dev/null +++ b/cp-usb.c @@ -0,0 +1,140 @@ +/* + * 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" +#include + +#define CP2101_UART 0x00 +#define UART_ENABLE 0x0001 +#define UART_DISABLE 0x0000 +#define REQTYPE_HOST_TO_DEVICE 0x41 +#define REQTYPE_DEVICE_TO_HOST 0xc1 + +static int +cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get) +{ + return usb_control_msg(dbg->usb_dev, /* dev */ + 0xc0, /* request */ + 0xff, /* requesttype */ + 0x00c2, /* value */ + 0, /* index */ + (char *) gpio_get, /* bytes */ + 1, /* size */ + 300); /* timeout */ +} + +static int +cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ + uint16_t gpio_set = ((uint16_t) value << 8) | mask; + + return usb_control_msg(dbg->usb_dev, /* dev */ + 0x40, /* request */ + 0xff, /* requesttype */ + 0x37e1, /* value */ + gpio_set, /* index */ + NULL, /* bytes */ + 0, /* size */ + 300); /* timeout */ +} + +static int +cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable) +{ + return usb_control_msg(dbg->usb_dev, + CP2101_UART, + REQTYPE_HOST_TO_DEVICE, + enable, + 0, + NULL, + 0, + 300); +} + +void +cp_usb_init(struct ccdbg *dbg) +{ + usb_dev_handle *dev_handle; + struct usb_device *dev; + struct usb_bus *bus, *busses; + int interface; + int ret; + uint8_t gpio; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + busses = usb_get_busses(); + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == 0x10c4 && + dev->descriptor.idProduct == 0xea60) + break; + } + if (dev) + break; + } + if (!dev){ + perror("No CP2103 found\n"); + exit(1); + } + interface = 0; + dev_handle = usb_open(dev); + usb_detach_kernel_driver_np(dev_handle, interface); + usb_claim_interface(dev_handle, interface); + dbg->usb_dev = dev_handle; + ret = cp_usb_uart_enable_disable(dbg, UART_DISABLE); + dbg->gpio = 0xf; + ret = cp_usb_gpio_set(dbg, 0xf, dbg->gpio); + ret = cp_usb_gpio_get(dbg, &gpio); +} + +void +cp_usb_fini(struct ccdbg *dbg) +{ + cp_usb_uart_enable_disable(dbg, UART_DISABLE); + usb_close(dbg->usb_dev); +} + +void +cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ + uint8_t new_gpio; + int ret; + + new_gpio = (dbg->gpio & ~mask) | (value & mask); + if (new_gpio != dbg->gpio) { + ret = cp_usb_gpio_set(dbg, new_gpio ^ dbg->gpio, new_gpio); + if (ret < 0) + perror("gpio_set"); + dbg->gpio = new_gpio; + } +} + +uint8_t +cp_usb_read(struct ccdbg *dbg) +{ + int ret; + uint8_t gpio; + + ret = cp_usb_gpio_get(dbg, &gpio); + if (ret < 0) + perror("gpio_set"); + return gpio; +} diff --git a/debug_mode b/debug_mode new file mode 100644 index 00000000..fe25bfef --- /dev/null +++ b/debug_mode @@ -0,0 +1,11 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# + +C D R +. D . +C D . +. D . +C D . +. D R + diff --git a/get_pc b/get_pc new file mode 100644 index 00000000..13bcba15 --- /dev/null +++ b/get_pc @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/get_status b/get_status new file mode 100644 index 00000000..3ca4a303 --- /dev/null +++ b/get_status @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/half_phase b/half_phase new file mode 100644 index 00000000..3ca4a303 --- /dev/null +++ b/half_phase @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/in b/in new file mode 100644 index 00000000..93341e32 --- /dev/null +++ b/in @@ -0,0 +1,146 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D . + +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R + +# +# Ok, we're in debug mode now +# + +# +# GET_CHIP_ID + +#C . R 0 +#. . R +#C D R 1 +#. D R +#C D R 1 +#. D R +#C . R 0 +#. . R +# +#C D R 1 +#. D R +#C . R 0 +#. . R +#C . R 0 +#. . R +#C . R 0 +#. . R +# +## +## Read the chip id +## +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/p1_1 b/p1_1 new file mode 100644 index 00000000..05ded5cb --- /dev/null +++ b/p1_1 @@ -0,0 +1,349 @@ +# +# Halt 0x44 +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0xfe, 0x02 + +# 0x75 0x02 0xfe + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0xfe +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R + +# 0x02 +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +# status byte + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0x90, 0xfd +# 0x75 0xfd 0x90 + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0x90 +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# 0xff +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# status byte + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0x90, 0xfd +# 0x75 0xfd 0x90 + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0x90 +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# 0xfd +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# status byte + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + diff --git a/read_status b/read_status new file mode 100644 index 00000000..3ca4a303 --- /dev/null +++ b/read_status @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/reset b/reset new file mode 100644 index 00000000..a32c8bec --- /dev/null +++ b/reset @@ -0,0 +1,5 @@ +# reset +C D R +C D R +C D R +C D R diff --git a/wr_config b/wr_config new file mode 100644 index 00000000..1ee31623 --- /dev/null +++ b/wr_config @@ -0,0 +1,116 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# WR_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + + +# +# RD_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R -- cgit v1.2.3 From 4f38974a9941cddaba27c17c5a46f923db386c94 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Dec 2008 16:32:27 -0800 Subject: Add another example --- rd_config | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 rd_config diff --git a/rd_config b/rd_config new file mode 100644 index 00000000..9bb1cbe9 --- /dev/null +++ b/rd_config @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# RD_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R -- cgit v1.2.3 From e64b4dbf15e9ee1cb0de002985de7575e83d46e9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 8 Dec 2008 17:25:28 -0800 Subject: Add support for input-only lines (-) --- ccdbg.c | 102 ++++++++++++--------- ccdbg.h | 2 +- chip_id | 107 +++++++--------------- get_status | 292 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- p1_1 | 123 +++++++++++++------------- rd_config | 18 ---- 6 files changed, 428 insertions(+), 216 deletions(-) diff --git a/ccdbg.c b/ccdbg.c index 39fc1016..6462739a 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,40 +18,55 @@ #include "ccdbg.h" -static uint8_t -get_bit(char *line, int i, char on, uint8_t bit) +static void +get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks) { - if (line[i] == on) - return bit; - if (line[i] == '.') - return 0; + if (line[i] == on) { + *bits |= bit; + *masks |= bit; + return; + } + if (line[i] == '.') { + *masks |= bit; + return; + } + if (line[i] == '-') { + return; + } fprintf(stderr, "bad line %s\n", line); exit (1); } static char -is_bit(uint8_t get, char on, uint8_t bit) +is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) { - if (get&bit) - return on; - else - return '.'; + if (mask&bit) { + if (get&bit) + return on; + else + return '.'; + } else + return '-'; } static uint8_t -ccdbg_write_read(struct ccdbg *dbg, uint8_t set) -{ - uint8_t get; - - ccdbg_write(dbg, CC_DATA|CC_CLOCK|CC_RESET_N, set); - get = ccdbg_read(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_write_read(struct ccdbg *dbg, uint8_t set, uint8_t mask) +{ + uint8_t get = set; + + if (mask != (CC_DATA|CC_CLOCK|CC_RESET_N)) + get = ccdbg_read(dbg); + ccdbg_write(dbg, mask, set); + printf ("%c %c %c", + is_bit(set, mask, 'C', CC_CLOCK), + is_bit(set, mask, 'D', CC_DATA), + is_bit(set, mask, 'R', CC_RESET_N)); + if (mask != (CC_DATA|CC_CLOCK|CC_RESET_N)) + printf(" -> %c %c %c", + is_bit(get, 0xf, 'C', CC_CLOCK), + is_bit(get, 0xf, 'D', CC_DATA), + is_bit(get, 0xf, 'R', CC_RESET_N)); + printf("\n"); ccdbg_half_clock(dbg); return get; } @@ -62,29 +77,29 @@ _ccdbg_debug_mode(struct ccdbg *dbg) printf ("#\n"); printf ("# Debug mode\n"); printf ("#\n"); - 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); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_DATA|CC_RESET_N, CC_CLOCK|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); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); } static void _ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) { if (bit) bit = CC_DATA; - ccdbg_write_read(dbg, CC_CLOCK|bit|CC_RESET_N); - ccdbg_write_read(dbg, bit|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|bit|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, bit|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); } static void @@ -135,8 +150,8 @@ _ccdbg_read_bits(struct ccdbg *dbg, int bits) printf ("# Read %d bits\n", bits); printf ("#\n"); for (bit = 0; bit < bits; bit++) { - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N); - get = ccdbg_write_read(dbg, CC_DATA|CC_RESET_N); + ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_RESET_N); + get = ccdbg_write_read(dbg, CC_DATA|CC_RESET_N, CC_CLOCK|CC_RESET_N); val <<= 1; if (get & CC_DATA) val |= 1; @@ -208,7 +223,7 @@ static void ccdbg_manual(struct ccdbg *dbg, FILE *input) { char line[80]; - uint8_t set; + uint8_t set, mask; while (fgets(line, sizeof line, input)) { if (line[0] == '#' || line[0] == '\n') { @@ -216,10 +231,11 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) 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); + mask = 0; + get_bit(line, 0, 'C', CC_CLOCK, &set, &mask); + get_bit(line, 2, 'D', CC_DATA, &set, &mask); + get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); + ccdbg_write_read(dbg, set, mask); } } diff --git a/ccdbg.h b/ccdbg.h index 19cf8fa3..90d6d25b 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -45,7 +45,7 @@ /* painfully slow for now */ -#define CC_CLOCK_US (100 * 1000) +#define CC_CLOCK_US (100) struct ccdbg { usb_dev_handle *usb_dev; diff --git a/chip_id b/chip_id index 4343cec2..6e54a374 100644 --- a/chip_id +++ b/chip_id @@ -33,82 +33,37 @@ C . R 0 # start reading again C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R diff --git a/get_status b/get_status index 3ca4a303..1d4ff03d 100644 --- a/get_status +++ b/get_status @@ -9,20 +9,61 @@ C D . . D R # -# GET_STATUS +# Halt 0x44 # C . R 0 . . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + C . R 0 . . R C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# Resume 0x4c +# + +C . R 0 +. . R C D R 1 . D R - C . R 0 . . R +C . R 0 +. . R + +C D R 1 +. D R C D R 1 . D R C . R 0 @@ -30,42 +71,259 @@ C . R 0 C . R 0 . . R +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + # -# Now read for a while +# READ_STATUS # -C D R -. D R -C D R -. D R -C D R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 . D R -C D R +C D R 1 . D R -C D R +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 . D R -C D R +C D R 1 . D R -C D R + +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 . D R -C D R +C D R 1 . D R -C D R + +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# Halt 0x44 +# + +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R -C D R +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 . D R -C D R +C D R 1 . D R -C D R + +C . R 0 +. . R +C D R 1 . D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + diff --git a/p1_1 b/p1_1 index 05ded5cb..2deeaad7 100644 --- a/p1_1 +++ b/p1_1 @@ -23,22 +23,22 @@ C . R 0 # status byte C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R # # DEBUG_INSTR @@ -126,22 +126,22 @@ C . R 0 # status byte C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R # # DEBUG_INSTR @@ -228,22 +228,22 @@ C D R 1 # status byte C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R # # DEBUG_INSTR @@ -330,20 +330,21 @@ C D R 1 # status byte C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R +C D R diff --git a/rd_config b/rd_config index 9bb1cbe9..7f8686fe 100644 --- a/rd_config +++ b/rd_config @@ -51,21 +51,3 @@ C D R . D R C D R . D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R -- cgit v1.2.3 From 584e28bac8af38de433767e017977ed1adddeb36 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 Dec 2008 12:32:15 -0800 Subject: Clean up sample debug files Signed-off-by: Keith Packard --- 1101 | 131 ------------------------------------------------------------ ccdbg.h | 4 +- chip_id | 2 + p1_1 | 10 +++++ read_status | 48 ++++++++-------------- 5 files changed, 30 insertions(+), 165 deletions(-) delete mode 100644 1101 diff --git a/1101 b/1101 deleted file mode 100644 index b5e9b3c4..00000000 --- a/1101 +++ /dev/null @@ -1,131 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# 1101 with zeros -# - -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R - -# try sending READ_STATUS - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - - -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R diff --git a/ccdbg.h b/ccdbg.h index 90d6d25b..8ccd4770 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -33,8 +33,8 @@ #undef USE_KERNEL #ifdef USE_KERNEL #include -#define CC_DATA CP2101_GPIO_MASK(0) -#define CC_CLOCK CP2101_GPIO_MASK(1) +#define CC_CLOCK CP2101_GPIO_MASK(0) +#define CC_DATA CP2101_GPIO_MASK(1) #define CC_RESET_N CP2101_GPIO_MASK(2) #else #define CC_CLOCK 0x1 diff --git a/chip_id b/chip_id index 6e54a374..b3ecf314 100644 --- a/chip_id +++ b/chip_id @@ -67,3 +67,5 @@ C - R . - R C - R . - R + +C D R diff --git a/p1_1 b/p1_1 index 2deeaad7..08d8ab50 100644 --- a/p1_1 +++ b/p1_1 @@ -1,3 +1,13 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + # # Halt 0x44 # diff --git a/read_status b/read_status index 3ca4a303..3ae46058 100644 --- a/read_status +++ b/read_status @@ -9,7 +9,7 @@ C D . . D R # -# GET_STATUS +# READ_STATUS # C . R 0 @@ -35,37 +35,21 @@ C . R 0 # C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R -- cgit v1.2.3 From 5df84df7cd6a31527dcfd11030f00ef9d8abf170 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 Dec 2008 22:24:59 -0800 Subject: Clean up bitbanging layer. Add debug printfs. Signed-off-by: Keith Packard --- Makefile | 2 +- ccdbg-command.c | 27 ++++--- ccdbg-debug.c | 47 ++++++++++++ ccdbg-io.c | 133 ++++++++++++++++++-------------- ccdbg.c | 231 +------------------------------------------------------- ccdbg.h | 44 ++++++++++- rd_config | 30 ++++---- 7 files changed, 204 insertions(+), 310 deletions(-) create mode 100644 ccdbg-debug.c diff --git a/Makefile b/Makefile index 27a389e2..965032e4 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ LIBS=-lusb KERNEL_OBJS=cccp.o LIBUSB_OBJS=cp-usb.o -OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o $(LIBUSB_OBJS) +OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o ccdbg-io.o $(LIBUSB_OBJS) INCS=ccdbg.h cccp.h PROG=ccdbg diff --git a/ccdbg-command.c b/ccdbg-command.c index f79d3621..099afc55 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -22,20 +22,29 @@ void ccdbg_debug_mode(struct ccdbg *dbg) { /* force two rising clocks while holding RESET_N low */ - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_RESET_N|CC_CLOCK, 0); ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, 0); ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_RESET_N, CC_RESET_N); ccdbg_half_clock(dbg); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); } void ccdbg_reset(struct ccdbg *dbg) { - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_RESET_N, 0); ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_RESET_N, CC_RESET_N); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); } uint8_t diff --git a/ccdbg-debug.c b/ccdbg-debug.c new file mode 100644 index 00000000..2e67bc8d --- /dev/null +++ b/ccdbg-debug.c @@ -0,0 +1,47 @@ +/* + * 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" +#include + +int +ccdbg_level = 0; + +void +ccdbg_add_debug(int level) +{ + ccdbg_level |= level; +} + +void +ccdbg_clear_debug(int level) +{ + ccdbg_level &= ~level; +} + +void +ccdbg_debug(int level, char *format, ...) +{ + va_list ap; + + if (ccdbg_level & level) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + } +} diff --git a/ccdbg-io.c b/ccdbg-io.c index 2cd42e27..c69fc0d8 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -89,108 +89,125 @@ ccdbg_read(struct ccdbg *dbg) return cp_usb_read(dbg); #endif } - + +static char +is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) +{ + if (mask&bit) { + if (get&bit) + return on; + else + return '.'; + } else + return '-'; +} void -ccdbg_clock_1_0(struct ccdbg *dbg) +ccdbg_print(char *format, uint8_t mask, uint8_t set) { - ccdbg_quarter_clock(dbg); - assert(dbg->clock == 1); - ccdbg_write(dbg, CC_CLOCK, 0); - dbg->clock = 0; - ccdbg_quarter_clock(dbg); + ccdbg_debug (CC_DEBUG_BITBANG, format, + is_bit(set, mask, 'C', CC_CLOCK), + is_bit(set, mask, 'D', CC_DATA), + is_bit(set, mask, 'R', CC_RESET_N)); } void -ccdbg_clock_0_1(struct ccdbg *dbg) +ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set) { - ccdbg_quarter_clock(dbg); - assert(dbg->clock == 0); - ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); - dbg->clock = 1; - ccdbg_quarter_clock(dbg); + ccdbg_write(dbg, mask, set); + ccdbg_print("%c %c %c\n", mask, set); + ccdbg_half_clock(dbg); } -/* - * By convention, every macro function is entered with dbg->clock == 1 - */ - void -ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit) +ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) { - uint8_t data; - - assert(dbg->clock == 1); - data = CC_CLOCK; - if (bit) - data |= CC_DATA; - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_DATA|CC_CLOCK, data); - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, 0); -// printf ("%d", bit); + if (bit) bit = CC_DATA; + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N); } void -ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte) +ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) { - int bit; + int bit; + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte); + for (bit = 7; bit >= 0; bit--) { + ccdbg_send_bit(dbg, (byte >> bit) & 1); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + } +} - for (bit = 7; bit >= 0; bit--) - ccdbg_write_bit(dbg, (byte >> bit) & 1); +void +ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) +{ + while (nbytes--) + ccdbg_send_byte(dbg, *bytes++); } uint8_t -ccdbg_read_bit(struct ccdbg *dbg) +ccdbg_recv_bit(struct ccdbg *dbg, int first) { - uint8_t data; + uint8_t mask = first ? CC_DATA : 0; + uint8_t read; - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); - ccdbg_half_clock(dbg); - ccdbg_write(dbg, CC_CLOCK, 0); - data = ccdbg_read(dbg); - return (data & CC_DATA) ? 1 : 0; + ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + read = ccdbg_read(dbg); + ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); + return (read & CC_DATA) ? 1 : 0; } uint8_t -ccdbg_read_byte(struct ccdbg *dbg) +ccdbg_recv_byte(struct ccdbg *dbg, int first) { + uint8_t byte = 0; int bit; - uint8_t byte = 0; - for (bit = 7; bit >= 0; bit--) - byte |= ccdbg_read_bit(dbg) << bit; + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); + for (bit = 0; bit < 8; bit++) { + byte = byte << 1; + byte |= ccdbg_recv_bit(dbg, first); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + first = 0; + } + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); return byte; } +void +ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) +{ + int first = 1; + while (nbytes--) { + *bytes++ = ccdbg_recv_byte(dbg, first); + first = 0; + } +} + void ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) { int i; - ccdbg_write_byte(dbg, cmd); + ccdbg_send_byte(dbg, cmd); for (i = 0; i < len; i++) - ccdbg_write_byte(dbg, data[i]); + ccdbg_send_byte(dbg, data[i]); } uint8_t ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) { - uint8_t ret; + uint8_t byte[1]; ccdbg_cmd_write(dbg, cmd, data, len); - ret = ccdbg_read_byte(dbg); - return ret; + ccdbg_recv_bytes(dbg, byte, 1); + return byte[0]; } uint16_t ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) { - uint8_t byte1, byte0; - int i; + uint8_t byte[2]; 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; + ccdbg_recv_bytes(dbg, byte, 2); + return (byte[0] << 8) | byte[1]; } - diff --git a/ccdbg.c b/ccdbg.c index 6462739a..3fcf7053 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,227 +18,6 @@ #include "ccdbg.h" -static void -get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks) -{ - if (line[i] == on) { - *bits |= bit; - *masks |= bit; - return; - } - if (line[i] == '.') { - *masks |= bit; - return; - } - if (line[i] == '-') { - return; - } - fprintf(stderr, "bad line %s\n", line); - exit (1); -} - -static char -is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) -{ - if (mask&bit) { - if (get&bit) - return on; - else - return '.'; - } else - return '-'; -} - -static uint8_t -ccdbg_write_read(struct ccdbg *dbg, uint8_t set, uint8_t mask) -{ - uint8_t get = set; - - if (mask != (CC_DATA|CC_CLOCK|CC_RESET_N)) - get = ccdbg_read(dbg); - ccdbg_write(dbg, mask, set); - printf ("%c %c %c", - is_bit(set, mask, 'C', CC_CLOCK), - is_bit(set, mask, 'D', CC_DATA), - is_bit(set, mask, 'R', CC_RESET_N)); - if (mask != (CC_DATA|CC_CLOCK|CC_RESET_N)) - printf(" -> %c %c %c", - is_bit(get, 0xf, 'C', CC_CLOCK), - is_bit(get, 0xf, 'D', CC_DATA), - is_bit(get, 0xf, 'R', CC_RESET_N)); - printf("\n"); - ccdbg_half_clock(dbg); - return get; -} - -static void -_ccdbg_debug_mode(struct ccdbg *dbg) -{ - printf ("#\n"); - printf ("# Debug mode\n"); - printf ("#\n"); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); -} - -static void -_ccdbg_reset(struct ccdbg *dbg) -{ - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA , CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); -} - -static void -_ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) -{ - if (bit) bit = CC_DATA; - ccdbg_write_read(dbg, CC_CLOCK|bit|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_write_read(dbg, bit|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); -} - -static void -_ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) -{ - int bit; - printf ("#\n"); - printf ("# Send Byte 0x%02x\n", byte); - printf ("#\n"); - for (bit = 7; bit >= 0; bit--) { - _ccdbg_send_bit(dbg, (byte >> bit) & 1); - if (bit == 3) - printf ("\n"); - } -} - -static void -_ccdbg_send_bits(struct ccdbg *dbg, int n, uint32_t bits) -{ - int bit; - printf ("#\n"); - printf ("# Send %d bits 0x%08x\n", n, bits); - printf ("#\n"); - for (bit = n - 1; bit >= 0; bit--) { - _ccdbg_send_bit(dbg, (bits >> bit) & 1); - if ((bit & 3) == 3) - printf ("\n"); - } -} - -static void -_ccdbg_print_bits(int n, uint32_t bits) -{ - int bit; - - for (bit = n - 1; bit >= 0; bit--) - printf ("%d", (bits >> bit) & 1); -} - -static uint32_t -_ccdbg_read_bits(struct ccdbg *dbg, int bits) -{ - int bit; - uint32_t val = 0; - uint8_t get; - - printf ("#\n"); - printf ("# Read %d bits\n", bits); - printf ("#\n"); - for (bit = 0; bit < bits; bit++) { - ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_RESET_N); - get = ccdbg_write_read(dbg, CC_DATA|CC_RESET_N, CC_CLOCK|CC_RESET_N); - val <<= 1; - if (get & CC_DATA) - val |= 1; - if ((bit & 3) == 3) - printf ("\n"); - } - printf ("#\n"); - printf ("# Read "); _ccdbg_print_bits(bits, val); printf ("\n"); - printf ("#\n"); - return val; -} - -static int -_ccdbg_check_bits(uint32_t bits, uint8_t match) -{ - int bit; - - for (bit = 0; bit < 24; bit++) - if (((bits >> bit) & 0xff) == match) - return 1; - return 0; -} - -static uint32_t -_ccdbg_play(struct ccdbg *dbg, int num_sync, uint32_t sync) -{ - uint32_t bits; - _ccdbg_debug_mode(dbg); - _ccdbg_send_bits(dbg, num_sync, sync); - _ccdbg_send_byte(dbg, CC_GET_CHIP_ID); - bits = _ccdbg_read_bits(dbg, 16); - _ccdbg_send_byte(dbg, CC_GET_CHIP_ID); - bits = _ccdbg_read_bits(dbg, 16); -// _ccdbg_send_byte(dbg, CC_READ_STATUS); - _ccdbg_reset(dbg); - if (_ccdbg_check_bits(bits, 0x11)) { - printf("#\n#match with %d bits 0x%08x\n#\n", num_sync, sync); - return 1; - } - return 0; -} - -static int -_ccdbg_play_num(struct ccdbg *dbg, int num) -{ - uint32_t sync; - uint32_t max; - - printf ("#\n#play %d\n#\n", num); - max = (1 << num); - for (sync = 0; sync < max; sync++) - if (_ccdbg_play(dbg, num, sync)) - return 1; - return 0; -} - -static int -_ccdbg_play_many(struct ccdbg *dbg, int max) -{ - int num; - - for (num = 0; num < max; num++) - if (_ccdbg_play_num(dbg, num)) - return 1; - return 0; -} - -static void -ccdbg_manual(struct ccdbg *dbg, FILE *input) -{ - char line[80]; - uint8_t set, mask; - - while (fgets(line, sizeof line, input)) { - if (line[0] == '#' || line[0] == '\n') { - printf ("%s", line); - continue; - } - set = 0; - mask = 0; - get_bit(line, 0, 'C', CC_CLOCK, &set, &mask); - get_bit(line, 2, 'D', CC_DATA, &set, &mask); - get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); - ccdbg_write_read(dbg, set, mask); - } -} - int main (int argc, char **argv) { @@ -249,18 +28,16 @@ main (int argc, char **argv) dbg = ccdbg_open("/dev/ttyUSB0"); if (!dbg) exit (1); -#if 0 - _ccdbg_play(dbg, 0, 0); - _ccdbg_play_many(dbg, 8); -#endif - ccdbg_manual(dbg, stdin); #if 0 + ccdbg_manual(dbg, stdin); +#endif +#if 1 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); - _ccdbg_reset(dbg); + ccdbg_reset(dbg); #endif ccdbg_close(dbg); exit (0); diff --git a/ccdbg.h b/ccdbg.h index 8ccd4770..a0ef1c86 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -45,7 +45,7 @@ /* painfully slow for now */ -#define CC_CLOCK_US (100) +#define CC_CLOCK_US (1000) struct ccdbg { usb_dev_handle *usb_dev; @@ -91,6 +91,9 @@ struct ccdbg { #define CC_STEP_REPLACE (0x64|(n)) #define CC_GET_CHIP_ID 0x68 +#define CC_DEBUG_BITBANG 0x00000001 +#define CC_DEBUG_COMMAND 0x00000002 + /* ccdbg-command.c */ void ccdbg_debug_mode(struct ccdbg *dbg); @@ -107,6 +110,16 @@ ccdbg_rd_config(struct ccdbg *dbg); uint16_t ccdbg_get_chip_id(struct ccdbg *dbg); +/* ccdbg-debug.c */ +void +ccdbg_debug(int level, char *format, ...); + +void +ccdbg_add_debug(int level); + +void +ccdbg_clear_debug(int level); + /* ccdbg-io.c */ void ccdbg_quarter_clock(struct ccdbg *dbg); @@ -153,6 +166,35 @@ ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); uint16_t ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); +void +ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set); + +void +ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit); + +void +ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte); + +void +ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); + +uint8_t +ccdbg_recv_bit(struct ccdbg *dbg, int first); + +uint8_t +ccdbg_recv_byte(struct ccdbg *dbg, int first); + +void +ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); + +void +ccdbg_print(char *format, uint8_t mask, uint8_t set); + +/* ccdbg-manual.c */ + +void +ccdbg_manual(struct ccdbg *dbg, FILE *input); + /* cp-usb.c */ void cp_usb_init(struct ccdbg *dbg); diff --git a/rd_config b/rd_config index 7f8686fe..e2d43f10 100644 --- a/rd_config +++ b/rd_config @@ -35,19 +35,21 @@ C . R 0 # C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R -- cgit v1.2.3 From fa168f963f8b00144d12aa2770e9c0917cfae123 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 Dec 2008 23:12:59 -0800 Subject: Fill out ccdbg-command to support all debug commands. Signed-off-by: Keith Packard --- ccdbg-command.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- ccdbg.c | 24 +++++++++++++++++++++- ccdbg.h | 33 +++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 6 deletions(-) diff --git a/ccdbg-command.c b/ccdbg-command.c index 099afc55..415010f8 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -48,9 +48,15 @@ ccdbg_reset(struct ccdbg *dbg) } uint8_t -ccdbg_read_status(struct ccdbg *dbg) +ccdbg_chip_erase(struct ccdbg *dbg) { - return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0); + return ccdbg_cmd_write_read8(dbg, CC_CHIP_ERASE, NULL, 0); +} + +uint8_t +ccdbg_wr_config(struct ccdbg *dbg, uint8_t config) +{ + return ccdbg_cmd_write_read8(dbg, CC_WR_CONFIG, &config, 1); } uint8_t @@ -59,9 +65,61 @@ ccdbg_rd_config(struct ccdbg *dbg) return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0); } +uint8_t +ccdbg_get_pc(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); +} + +uint8_t +ccdbg_read_status(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0); +} + +uint8_t +ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr) +{ + uint8_t data[3]; + + data[0] = (number << 3) | (enable << 2); + data[1] = (addr >> 8); + data[2] = addr; + return ccdbg_cmd_write_read8(dbg, CC_SET_HW_BRKPNT, data, 3); +} + +uint8_t +ccdbg_halt(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_HALT, NULL, 0); +} + +uint8_t +ccdbg_resume(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_RESUME, NULL, 0); +} + +uint8_t +ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes) +{ + return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes); +} + +uint8_t +ccdbg_step_instr(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_STEP_INSTR, NULL, 0); +} + +uint8_t +ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes) +{ + return ccdbg_cmd_write_read8(dbg, CC_STEP_REPLACE(nbytes), instr, nbytes); +} + uint16_t ccdbg_get_chip_id(struct ccdbg *dbg) { return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0); } - diff --git a/ccdbg.c b/ccdbg.c index 3fcf7053..b682372a 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,6 +18,26 @@ #include "ccdbg.h" +#define MOV 0x75 + +static uint8_t instructions[] = { + 3, MOV, 0xfe, 0x02, + 3, MOV, 0x90, 0xff, + 0 +}; + +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; + } +} + int main (int argc, char **argv) { @@ -37,7 +57,9 @@ main (int argc, char **argv) printf("Status: 0x%02x\n", status); chip_id = ccdbg_get_chip_id(dbg); printf("Chip id: 0x%04x\n", chip_id); - ccdbg_reset(dbg); + status = ccdbg_halt(dbg); + printf ("halt status: 0x%02x\n", status); + ccdbg_instructions(dbg, instructions); #endif ccdbg_close(dbg); exit (0); diff --git a/ccdbg.h b/ccdbg.h index a0ef1c86..fc0cdd3c 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -88,7 +88,7 @@ struct ccdbg { #define CC_RESUME 0x4c #define CC_DEBUG_INSTR(n) (0x54|(n)) #define CC_STEP_INSTR 0x5c -#define CC_STEP_REPLACE (0x64|(n)) +#define CC_STEP_REPLACE(n) (0x64|(n)) #define CC_GET_CHIP_ID 0x68 #define CC_DEBUG_BITBANG 0x00000001 @@ -102,14 +102,43 @@ void ccdbg_reset(struct ccdbg *dbg); uint8_t -ccdbg_read_status(struct ccdbg *dbg); +ccdbg_chip_erase(struct ccdbg *dbg); + +uint8_t +ccdbg_wr_config(struct ccdbg *dbg, uint8_t config); uint8_t ccdbg_rd_config(struct ccdbg *dbg); +uint8_t +ccdbg_get_pc(struct ccdbg *dbg); + +uint8_t +ccdbg_read_status(struct ccdbg *dbg); + +uint8_t +ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr); + +uint8_t +ccdbg_halt(struct ccdbg *dbg); + +uint8_t +ccdbg_resume(struct ccdbg *dbg); + +uint8_t +ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes); + +uint8_t +ccdbg_step_instr(struct ccdbg *dbg); + +uint8_t +ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes); + uint16_t ccdbg_get_chip_id(struct ccdbg *dbg); + + /* ccdbg-debug.c */ void ccdbg_debug(int level, char *format, ...); -- cgit v1.2.3 From aec3bbce84a5ceb92060a4b3889379f2af2404ac Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 Dec 2008 23:15:19 -0800 Subject: reduce clock to 50us Signed-off-by: Keith Packard --- ccdbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccdbg.h b/ccdbg.h index fc0cdd3c..7d9940c3 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -45,7 +45,7 @@ /* painfully slow for now */ -#define CC_CLOCK_US (1000) +#define CC_CLOCK_US (50) struct ccdbg { usb_dev_handle *usb_dev; -- cgit v1.2.3 From 8c879bf51c14a5928135d59211facd72f6a32808 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 Dec 2008 23:15:47 -0800 Subject: Move manual bit-banging debug code to separate file Signed-off-by: Keith Packard --- ccdbg-manual.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ccdbg-manual.c diff --git a/ccdbg-manual.c b/ccdbg-manual.c new file mode 100644 index 00000000..b83dc450 --- /dev/null +++ b/ccdbg-manual.c @@ -0,0 +1,70 @@ +/* + * 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" + +/* + * Manual bit-banging to debug the low level protocol + */ + +static void +get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks) +{ + if (line[i] == on) { + *bits |= bit; + *masks |= bit; + return; + } + if (line[i] == '.') { + *masks |= bit; + return; + } + if (line[i] == '-') { + return; + } + fprintf(stderr, "bad line %s\n", line); + exit (1); +} + +void +ccdbg_manual(struct ccdbg *dbg, FILE *input) +{ + char line[80]; + uint8_t set, mask; + + while (fgets(line, sizeof line, input)) { + if (line[0] == '#' || line[0] == '\n') { + printf ("%s", line); + continue; + } + set = 0; + mask = 0; + get_bit(line, 0, 'C', CC_CLOCK, &set, &mask); + get_bit(line, 2, 'D', CC_DATA, &set, &mask); + get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); + if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { + uint8_t read; + read = ccdbg_read(dbg); + ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); + if ((set & CC_CLOCK) == 0) + printf ("\t%d", (read&CC_DATA) ? 1 : 0); + printf ("\n"); + } + ccdbg_send(dbg, mask, set); + } +} -- cgit v1.2.3 From 807e2adacb025af77bb53c03209e9c8e0d7a5f95 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Dec 2008 00:18:50 -0800 Subject: Add ability to read/write arbitrary memory. Write LED blinker program. Signed-off-by: Keith Packard --- Makefile | 4 ++- ccdbg-command.c | 23 ++++++++++++++++++ ccdbg-io.c | 12 ++++----- ccdbg-memory.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ccdbg.c | 61 ++++++++++++++++++++++++++++++++++------------ ccdbg.h | 14 ++++++++--- 6 files changed, 162 insertions(+), 27 deletions(-) create mode 100644 ccdbg-memory.c diff --git a/Makefile b/Makefile index 965032e4..2fd8ec6d 100644 --- 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 diff --git a/ccdbg-command.c b/ccdbg-command.c index 415010f8..50dd1fd4 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -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; +} + diff --git a/ccdbg-io.c b/ccdbg-io.c index c69fc0d8..765bde84 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -17,17 +17,15 @@ */ #include "ccdbg.h" - -void -ccdbg_quarter_clock(struct ccdbg *dbg) -{ - usleep(CC_CLOCK_US / 4); -} +#include 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 index 00000000..ffc09679 --- /dev/null +++ b/ccdbg-memory.c @@ -0,0 +1,75 @@ +/* + * 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" + +/* + * 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 b682372a..a3548143 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,25 +18,42 @@ #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 7d9940c3..0f07e2e9 100644 --- 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); -- cgit v1.2.3 From dc03adc179669d41e3551d74b3c5a60db41ff217 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Dec 2008 12:07:06 -0800 Subject: Add ability to load Intel HEX files. Add sample sdcc LED blinker. Signed-off-by: Keith Packard --- Makefile | 9 +- Makefile.blink | 20 ++++ blink.c | 44 +++++++++ ccdbg-hex.c | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ccdbg-memory.c | 18 ++++ ccdbg.c | 15 ++- ccdbg.h | 27 ++++++ 7 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 Makefile.blink create mode 100644 blink.c create mode 100644 ccdbg-hex.c diff --git a/Makefile b/Makefile index 2fd8ec6d..801068cd 100644 --- a/Makefile +++ b/Makefile @@ -10,12 +10,16 @@ KERNEL_OBJS=cccp.o LIBUSB_OBJS=cp-usb.o OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o \ - ccdbg-io.o ccdbg-memory.o \ + ccdbg-hex.o ccdbg-io.o ccdbg-memory.o \ $(LIBUSB_OBJS) INCS=ccdbg.h cccp.h PROG=ccdbg +LOAD=blink + +all: $(PROG) $(LOAD) + $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) @@ -23,3 +27,6 @@ clean: rm -f $(PROG) $(OBJS) $(OBJS): $(INCS) + +blink: blink.c Makefile.blink + make -f Makefile.blink diff --git a/Makefile.blink b/Makefile.blink new file mode 100644 index 00000000..37c3c672 --- /dev/null +++ b/Makefile.blink @@ -0,0 +1,20 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +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 + +SRC=blink.c +OBJ=$(SRC:.c=.rel) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +blink: $(OBJ) + $(CC) $(LDFLAGS) $(CFLAGS) -o$@ $(OBJ) + diff --git a/blink.c b/blink.c new file mode 100644 index 00000000..fcbc04d0 --- /dev/null +++ b/blink.c @@ -0,0 +1,44 @@ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; + +#define PERCFG SFR(0xF1) +#define ADCCFG SFR(0xF2) +#define P0SEL SFR(0xF3) +#define P1SEL SFR(0xF4) +#define P2SEL SFR(0xF5) + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFE P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +#define P0IFG SFR(0x89) +#define P1IFG SFR(0x8A) +#define P2IFG SFR(0x8B) + +#define nop() _asm \ + nop \ + _endasm; + +main () +{ + int i, j; + /* Set p1_1 to output */ + P1DIR = 0x02; + P1INP = 0x00; + P2INP = 0x00; + for (;;) { + P1 = 0xff; + for (j = 0; j < 100; j++) + for (i = 0; i < 1000; i++) + nop(); + P1 = 0xfd; + for (j = 0; j < 100; j++) + for (i = 0; i < 1000; i++) + nop(); + } +} diff --git a/ccdbg-hex.c b/ccdbg-hex.c new file mode 100644 index 00000000..d9d27cdf --- /dev/null +++ b/ccdbg-hex.c @@ -0,0 +1,284 @@ +/* + * 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" +#include +#include + +struct hex_input { + FILE *file; + int line; + char *name; +}; + +enum hex_read_state { + read_marker, + read_length, + read_address, + read_type, + read_data, + read_checksum, + read_newline, + read_white, + read_done, +}; + + +static void +ccdbg_hex_error(struct hex_input *input, char *format, ...) +{ + va_list ap; + + va_start(ap, format); + fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void +ccdbg_hex_free(struct hex_record *record) +{ + if (!record) return; + free(record); +} + +static struct hex_record * +ccdbg_hex_alloc(uint8_t length) +{ + struct hex_record *record; + + record = calloc(1, sizeof(struct hex_record) + length); + record->length = length; + return record; +} + +static int +ishex(char c) +{ + return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); +} + +static int +fromhex(char c) +{ + if (isdigit(c)) + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + abort(); + return 0; +} + +static uint8_t +ccdbg_hex_checksum(struct hex_record *record) +{ + uint8_t checksum = 0; + int i; + + checksum += record->length; + checksum += record->address >> 8; + checksum += record->address & 0xff; + checksum += record->type; + for (i = 0; i < record->length; i++) + checksum += record->data[i]; + return -checksum; +} + +static struct hex_record * +ccdbg_hex_read_record(struct hex_input *input) +{ + struct hex_record *record = NULL; + enum hex_read_state state = read_marker; + char c; + int nhexbytes; + uint32_t hex; + uint32_t ndata; + uint8_t checksum; + + while (state != read_done) { + c = getc(input->file); + if (c == EOF && state != read_white) { + ccdbg_hex_error(input, "Unexpected EOF"); + goto bail; + } + if (c == '\n') + input->line++; + switch (state) { + case read_marker: + if (c != ':') { + ccdbg_hex_error(input, "Missing ':'"); + goto bail; + } + state = read_length; + nhexbytes = 2; + hex = 0; + break; + case read_length: + case read_address: + case read_type: + case read_data: + case read_checksum: + if (!ishex(c)) { + ccdbg_hex_error(input, "Non-hex char '%c'", + c); + goto bail; + } + hex = hex << 4 | fromhex(c); + --nhexbytes; + if (nhexbytes != 0) + break; + + switch (state) { + case read_length: + record = ccdbg_hex_alloc(hex); + if (!record) { + ccdbg_hex_error(input, "Out of memory"); + goto bail; + } + state = read_address; + nhexbytes = 4; + break; + case read_address: + record->address = hex; + state = read_type; + nhexbytes = 2; + break; + case read_type: + record->type = hex; + state = read_data; + nhexbytes = 2; + ndata = 0; + break; + case read_data: + record->data[ndata] = hex; + ndata++; + nhexbytes = 2; + break; + case read_checksum: + record->checksum = hex; + state = read_newline; + break; + default: + break; + } + if (state == read_data) + if (ndata == record->length) { + nhexbytes = 2; + state = read_checksum; + } + hex = 0; + break; + case read_newline: + if (c != '\n' && c != '\r') { + ccdbg_hex_error(input, "Missing newline"); + goto bail; + } + state = read_white; + break; + case read_white: + if (!isspace(c)) { + if (c == '\n') + input->line--; + if (c != EOF) + ungetc(c, input->file); + state = read_done; + } + break; + case read_done: + break; + } + } + checksum = ccdbg_hex_checksum(record); + if (checksum != record->checksum) { + ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", + record->checksum, checksum); + goto bail; + } + return record; + +bail: + ccdbg_hex_free(record); + return NULL; +} + +void +ccdbg_hex_file_free(struct hex_file *hex) +{ + int i; + + if (!hex) + return; + for (i = 0; i < hex->nrecord; i++) + ccdbg_hex_free(hex->records[i]); + free (hex); +} + +static int +ccdbg_hex_record_compar(const void *av, const void *bv) +{ + const struct hex_record *a = *(struct hex_record **) av; + const struct hex_record *b = *(struct hex_record **) bv; + + return (int) a->address - (int) b->address; +} + +struct hex_file * +ccdbg_hex_file_read(FILE *file, char *name) +{ + struct hex_input input; + struct hex_file *hex = NULL, *newhex; + struct hex_record *record; + int srecord = 1; + int done = 0; + + hex = calloc (1, sizeof (struct hex_file) + sizeof (struct hex_record *)); + input.name = name; + input.line = 1; + input.file = file; + while (!done) { + record = ccdbg_hex_read_record(&input); + if (!record) + goto bail; + if (hex->nrecord == srecord) { + srecord *= 2; + newhex = realloc(hex, + sizeof (struct hex_file) + + srecord * sizeof (struct hex_record *)); + if (!newhex) + goto bail; + hex = newhex; + } + hex->records[hex->nrecord++] = record; + if (record->type == HEX_RECORD_EOF) + done = 1; + } + /* + * Sort them into increasing addresses, except for EOF + */ + qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), + ccdbg_hex_record_compar); + return hex; + +bail: + ccdbg_hex_file_free(hex); + return NULL; +} + diff --git a/ccdbg-memory.c b/ccdbg-memory.c index ffc09679..fa953d17 100644 --- a/ccdbg-memory.c +++ b/ccdbg-memory.c @@ -73,3 +73,21 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) *bytes++ = ccdbg_execute(dbg, read8); return 0; } + +uint8_t +ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex) +{ + 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); + } + return 0; +} diff --git a/ccdbg.c b/ccdbg.c index a3548143..3a34d0e9 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -64,6 +64,7 @@ main (int argc, char **argv) uint16_t pc; uint8_t memory[0x10]; int i; + struct hex_file *hex; dbg = ccdbg_open("/dev/ttyUSB0"); if (!dbg) @@ -71,7 +72,9 @@ main (int argc, char **argv) #if 0 ccdbg_manual(dbg, stdin); #endif -#if 1 + hex = ccdbg_hex_file_read(stdin, ""); + if (!hex) + exit (1); ccdbg_reset(dbg); ccdbg_debug_mode(dbg); status = ccdbg_read_status(dbg); @@ -80,9 +83,9 @@ 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_execute(dbg, instructions); */ - ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr)); - ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory)); + + ccdbg_write_hex(dbg, hex); + ccdbg_hex_file_free(hex); for (i = 0; i < sizeof (memory); i++) printf (" %02x", memory[i]); printf ("\n"); @@ -91,6 +94,10 @@ main (int argc, char **argv) printf ("pc starts at 0x%04x\n", pc); status = ccdbg_resume(dbg); printf ("resume status: 0x%02x\n", status); +#if 0 +/* ccdbg_execute(dbg, instructions); */ + ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr)); + ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory)); #endif ccdbg_close(dbg); exit (0); diff --git a/ccdbg.h b/ccdbg.h index 0f07e2e9..05abc97f 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -151,6 +151,30 @@ ccdbg_add_debug(int level); 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 + +struct hex_file * +ccdbg_hex_file_read(FILE *file, char *name); + +void +ccdbg_hex_file_free(struct hex_file *hex); + /* ccdbg-io.c */ void ccdbg_half_clock(struct ccdbg *dbg); @@ -230,6 +254,9 @@ 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); +uint8_t +ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex); + /* cp-usb.c */ void cp_usb_init(struct ccdbg *dbg); -- cgit v1.2.3 From 3779cc8b32cac3640f42bd0400d4199ddae965a1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Dec 2008 12:17:41 -0800 Subject: cq Signed-off-by: Keith Packard --- blink.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/blink.c b/blink.c index fcbc04d0..f8cf7827 100644 --- a/blink.c +++ b/blink.c @@ -24,21 +24,52 @@ sfr at 0xF7 P2INP; nop \ _endasm; +void +delay (int n) +{ + int i, j, k; + + for (k = 0; k < n; k++) { + for (j = 0; j < 100; j++) + for (i = 0; i < 1000; i++) + nop(); + } +} + +void +dit() { + P1 = 0xff; + delay(1); + P1 = 0xfd; + delay(1); +} + +void +dah () { + P1 = 0xff; + delay(3); + P1 = 0xfd; + delay(1); +} + +void +charspace () { + delay(2); +} + +void +wordspace () { + delay(8); +} + main () { - int i, j; /* Set p1_1 to output */ P1DIR = 0x02; P1INP = 0x00; P2INP = 0x00; for (;;) { - P1 = 0xff; - for (j = 0; j < 100; j++) - for (i = 0; i < 1000; i++) - nop(); - P1 = 0xfd; - for (j = 0; j < 100; j++) - for (i = 0; i < 1000; i++) - nop(); + dah(); dit(); dah(); dit(); charspace (); + dah(); dah(); dit(); dah(); wordspace(); } } -- cgit v1.2.3 From 0bc52385b8f86f9ca1c450ad106e6d8afe3bc153 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Dec 2008 12:37:32 -0800 Subject: faster Signed-off-by: Keith Packard --- blink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blink.c b/blink.c index f8cf7827..1f8a5192 100644 --- a/blink.c +++ b/blink.c @@ -30,7 +30,7 @@ delay (int n) int i, j, k; for (k = 0; k < n; k++) { - for (j = 0; j < 100; j++) + for (j = 0; j < 50; j++) for (i = 0; i < 1000; i++) nop(); } -- cgit v1.2.3 From 55995515b9d4fc1e193039eab697c5d03db417c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 11:04:16 -0800 Subject: Add flash writing code. Signed-off-by: Keith Packard --- Makefile | 15 ++- Makefile.blink | 35 ++++++- blink.c | 22 +++- ccdbg-command.c | 36 ++++++- ccdbg-flash.c | 309 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ccdbg-hex.c | 46 ++++++++- ccdbg-io.c | 2 +- ccdbg-memory.c | 59 ++++++----- ccdbg.c | 91 ++++++++++------- ccdbg.h | 113 +++++++++++++++++---- 10 files changed, 628 insertions(+), 100 deletions(-) create mode 100644 ccdbg-flash.c diff --git a/Makefile b/Makefile index 801068cd..d3bafe2c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +.NOTPARALLEL: blink-ram blink-flash KERNEL=/local/src/linux-2.6-aiko-64 KINC=$(KERNEL)/drivers/usb/serial @@ -9,14 +10,17 @@ LIBS=-lusb 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) @@ -25,8 +29,9 @@ $(PROG): $(OBJS) 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 diff --git a/Makefile.blink b/Makefile.blink index 37c3c672..b23f0d69 100644 --- a/Makefile.blink +++ b/Makefile.blink @@ -1,3 +1,4 @@ +.NOTPARALLEL: CC=sdcc NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ --nolabelopt --nooverlay --peep-asm @@ -6,15 +7,39 @@ DEBUG=--debug 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) diff --git a/blink.c b/blink.c index 1f8a5192..a5906f6d 100644 --- a/blink.c +++ b/blink.c @@ -11,7 +11,7 @@ sfr at 0xA0 P2; 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; @@ -24,6 +24,7 @@ sfr at 0xF7 P2INP; nop \ _endasm; +#if 0 void delay (int n) { @@ -62,14 +63,29 @@ wordspace () { 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 } diff --git a/ccdbg-command.c b/ccdbg-command.c index 50dd1fd4..38c006cb 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -65,7 +65,7 @@ ccdbg_rd_config(struct ccdbg *dbg) 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); @@ -146,3 +146,37 @@ ccdbg_execute(struct ccdbg *dbg, uint8_t *inst) 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; +} + diff --git a/ccdbg-flash.c b/ccdbg-flash.c new file mode 100644 index 00000000..ee4e8589 --- /dev/null +++ b/ccdbg-flash.c @@ -0,0 +1,309 @@ +/* + * 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" + +/* 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; +} diff --git a/ccdbg-hex.c b/ccdbg-hex.c index d9d27cdf..ff155ff3 100644 --- a/ccdbg-hex.c +++ b/ccdbg-hex.c @@ -228,7 +228,7 @@ ccdbg_hex_file_free(struct hex_file *hex) return; for (i = 0; i < hex->nrecord; i++) ccdbg_hex_free(hex->records[i]); - free (hex); + free(hex); } static int @@ -249,7 +249,7 @@ ccdbg_hex_file_read(FILE *file, char *name) 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; @@ -282,3 +282,45 @@ bail: 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; +} diff --git a/ccdbg-io.c b/ccdbg-io.c index 765bde84..b78e3aad 100644 --- a/ccdbg-io.c +++ b/ccdbg-io.c @@ -25,7 +25,7 @@ ccdbg_half_clock(struct ccdbg *dbg) 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 * diff --git a/ccdbg-memory.c b/ccdbg-memory.c index fa953d17..ec173225 100644 --- a/ccdbg-memory.c +++ b/ccdbg-memory.c @@ -22,72 +22,77 @@ * 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; +} diff --git a/ccdbg.c b/ccdbg.c index 3a34d0e9..4533fd0c 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,12 +18,7 @@ #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, @@ -33,27 +28,32 @@ static uint8_t instructions[] = { 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) @@ -62,9 +62,8 @@ 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) @@ -72,28 +71,46 @@ main (int argc, char **argv) #if 0 ccdbg_manual(dbg, stdin); #endif +#if 1 hex = ccdbg_hex_file_read(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)); diff --git a/ccdbg.h b/ccdbg.h index 05abc97f..d5ef8940 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -47,6 +47,53 @@ /* 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; @@ -57,6 +104,29 @@ struct ccdbg { 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 @@ -111,7 +181,7 @@ ccdbg_wr_config(struct ccdbg *dbg, uint8_t config); uint8_t ccdbg_rd_config(struct ccdbg *dbg); -uint8_t +uint16_t ccdbg_get_pc(struct ccdbg *dbg); uint8_t @@ -141,6 +211,12 @@ ccdbg_get_chip_id(struct ccdbg *dbg); 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, ...); @@ -151,30 +227,26 @@ ccdbg_add_debug(int level); 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); @@ -255,7 +327,10 @@ uint8_t 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 -- cgit v1.2.3 From b4d1127ef007843c643b778b3b2f6b915b1d5d9a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 14:19:29 -0800 Subject: Flash multiple pages. Eliminate off-by-one error in hex_image length. Signed-off-by: Keith Packard --- Makefile.blink | 20 ++++++---- blink.c | 59 +++++++++++++++++------------ ccdbg-flash.c | 118 +++++++++++++++++++++++++++++++++++---------------------- ccdbg-hex.c | 12 ++++-- ccdbg-memory.c | 6 +++ ccdbg.c | 27 +++++-------- ccdbg.h | 3 ++ 7 files changed, 145 insertions(+), 100 deletions(-) diff --git a/Makefile.blink b/Makefile.blink index b23f0d69..e153c978 100644 --- a/Makefile.blink +++ b/Makefile.blink @@ -4,13 +4,17 @@ NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ --nolabelopt --nooverlay --peep-asm DEBUG=--debug -CFLAGS=--model-large $(DEBUG) --less-pedantic --xram-size 4096\ - --stack-auto --no-peep --int-long-reent --float-reent +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --no-pack-iram \ + --data-loc 0x30 \ LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx -LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + -LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 SRC=blink.c ADB=$(SRC:.c=.adb) @@ -32,12 +36,12 @@ PMEM=$(PROGS:=.mem) all: $(PROGS) -blink-ram: $(REL) - $(CC) $(LDFLAGS_RAM) $(CFLAGS) -oblink $(REL) +blink-ram: $(REL) Makefile.blink + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink $(REL) mv blink $@ -blink-flash: $(REL) - $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -oblink $(REL) +blink-flash: $(REL) Makefile.blink + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink $(REL) mv blink $@ clean: diff --git a/blink.c b/blink.c index a5906f6d..907c82b8 100644 --- a/blink.c +++ b/blink.c @@ -1,13 +1,31 @@ +/* + * 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. + */ sfr at 0x80 P0; sfr at 0x90 P1; sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; -#define PERCFG SFR(0xF1) -#define ADCCFG SFR(0xF2) -#define P0SEL SFR(0xF3) -#define P1SEL SFR(0xF4) -#define P2SEL SFR(0xF5) +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; sfr at 0xFD P0DIR; sfr at 0xFE P1DIR; @@ -16,25 +34,22 @@ sfr at 0x8F P0INP; sfr at 0xF6 P1INP; sfr at 0xF7 P2INP; -#define P0IFG SFR(0x89) -#define P1IFG SFR(0x8A) -#define P2IFG SFR(0x8B) +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; -#define nop() _asm \ - nop \ - _endasm; +#define nop() _asm nop _endasm; -#if 0 void -delay (int n) +delay (unsigned char n) { - int i, j, k; + unsigned char i = 0, j = 0; - for (k = 0; k < n; k++) { - for (j = 0; j < 50; j++) - for (i = 0; i < 1000; i++) + n <<= 1; + while (--n != 0) + while (--j != 0) + while (--i != 0) nop(); - } } void @@ -68,11 +83,9 @@ wordspace () { #define C charspace(); #define W wordspace(); -#endif - main () { -#if 0 + CLKCON = 0; /* Set p1_1 to output */ P1DIR = 0x02; P1INP = 0x00; @@ -84,8 +97,4 @@ main () ___ ___ _ _ _ C _ _ _ C /* 7s */ ___ ___ _ ___ C ___ ___ _ W /* qg */ } -#else - P1DIR = 0x02; - for (;;); -#endif } diff --git a/ccdbg-flash.c b/ccdbg-flash.c index ee4e8589..aa2c5187 100644 --- a/ccdbg-flash.c +++ b/ccdbg-flash.c @@ -72,6 +72,7 @@ static uint8_t flash_page[] = { #define FLASH_RAM 0xf000 +#if 0 static uint8_t flash_erase_page[] = { 3, MOV_direct_data, FADDRH, 0, #define ERASE_PAGE_HIGH 3 @@ -88,13 +89,17 @@ static uint8_t flash_read_control[] = { 2, MOV_A_direct, FCTL, 0 }; +#endif +#if 0 static uint8_t flash_control_clear[] = { 3, MOV_direct_data, FCTL, 0, 2, MOV_A_direct, FCTL, 0 }; +#endif +#if 0 static uint8_t ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr) { @@ -119,7 +124,9 @@ ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr) printf("clear fctl 0x%02x\n", status); return 0; } +#endif +#if 0 static uint8_t flash_write[] = { MOV_direct_data, P1DIR, 0x02, MOV_direct_data, P1, 0xFD, @@ -146,6 +153,7 @@ static uint8_t flash_write[] = { MOV_direct_data, P1, 0xFF, TRAP, }; +#endif static uint8_t ccdbg_clock_init(struct ccdbg *dbg) @@ -169,6 +177,7 @@ ccdbg_clock_init(struct ccdbg *dbg) return 0; } +#if 0 static uint8_t ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2]) { @@ -199,12 +208,14 @@ ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2]) printf("0x%02x : 0x%02x\n", data[i], check[i]); return 0; } +#endif #define TIMERS_OFF 0x08 #define DMA_PAUSE 0x04 #define TIMER_SUSPEND 0x02 #define SEL_FLASH_INFO_PAGE 0x01 +#if 0 static uint8_t ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) { @@ -224,12 +235,12 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE); return 0; } +#endif 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; @@ -238,6 +249,8 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) uint16_t ram_addr; uint16_t pc; uint8_t status; + uint16_t remain, this_time, start; + uint8_t verify[0x400]; ccdbg_clock_init(dbg); if (image->address + image->length > 0x8000) { @@ -245,16 +258,71 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) image->address, image->address + image->length); return 1; } - flash_word_addr = image->address >> 1; - if (flash_word_addr & 0x1ff) { + if (image->address & 0x3ff) { fprintf(stderr, "flash image must start on page boundary\n"); return 1; } ram_addr = 0xf000; - offset = ram_addr - image->address; -#if 0 + + flash_prog = 0xf400; + + fwt = 0x20; + + flash_page[FLASH_TIMING] = fwt; + printf("Upload %d flash program bytes to 0x%04x\n", + sizeof (flash_page), flash_prog); + ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); + + remain = image->length; + start = 0; + while (remain) { + this_time = remain; + if (this_time > 0x400) + this_time = 0x400; + + offset = ram_addr - (image->address + start); + + printf("Upload %d bytes at 0x%04x\n", this_time, ram_addr); + ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); + + printf("Verify %d bytes\n", image->length); + ccdbg_read_memory(dbg, ram_addr, verify, this_time); + if (memcmp (image->data + start, verify, this_time) != 0) { + fprintf(stderr, "image verify failed\n"); + return 1; + } + + flash_word_addr = (image->address + start) >> 1; + flash_len = this_time + (this_time & 1); + flash_words = flash_len >> 1; + + ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8); + ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff); + + ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8); + ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff); + + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words >> 8); + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words & 0xff); + + 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); + + remain -= this_time; + start += this_time; + } +#if 1 printf("Downloading flash to check\n"); + struct hex_image *test_image; test_image = ccdbg_read_hex_image(dbg, image->address, image->length); if (!ccdbg_hex_image_equal(image, test_image)) { int i; @@ -265,45 +333,5 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) } 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; } diff --git a/ccdbg-hex.c b/ccdbg-hex.c index ff155ff3..86478da0 100644 --- a/ccdbg-hex.c +++ b/ccdbg-hex.c @@ -119,6 +119,8 @@ ccdbg_hex_read_record(struct hex_input *input) ccdbg_hex_error(input, "Unexpected EOF"); goto bail; } + if (c == ' ') + continue; if (c == '\n') input->line++; switch (state) { @@ -290,17 +292,19 @@ ccdbg_hex_image_create(struct hex_file *hex) int i; uint32_t base, bound; uint32_t offset; + int length; 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); + bound = (uint32_t) last->address + (uint32_t) last->length; + length = bound - base; + image = calloc(sizeof(struct hex_image) + length, 1); if (!image) return NULL; image->address = base; - image->length = bound - base; - memset(image->data, 0xff, image->length); + image->length = length; + memset(image->data, 0xff, length); for (i = 0; i < hex->nrecord - 1; i++) { record = hex->records[i]; offset = record->address - base; diff --git a/ccdbg-memory.c b/ccdbg-memory.c index ec173225..105295db 100644 --- a/ccdbg-memory.c +++ b/ccdbg-memory.c @@ -77,6 +77,12 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) return 0; } +uint8_t +ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) +{ + return ccdbg_write_memory(dbg, addr, &byte, 1); +} + uint8_t ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) { diff --git a/ccdbg.c b/ccdbg.c index 4533fd0c..c144a06a 100644 --- a/ccdbg.c +++ b/ccdbg.c @@ -18,7 +18,7 @@ #include "ccdbg.h" -#if 1 +#if 0 static uint8_t instructions[] = { 3, MOV_direct_data, 0xfe, 0x02, 3, MOV_direct_data, 0x90, 0xff, @@ -26,6 +26,7 @@ static uint8_t instructions[] = { }; #endif +#if 0 static uint8_t mem_instr[] = { MOV_direct_data, 0xfe, 0x02, MOV_Rn_data(0), 0x00, @@ -42,7 +43,9 @@ static uint8_t mem_instr[] = { DJNZ_Rn_rel(2), 0xfa, SJMP, 0xe7, }; +#endif +#if 0 static struct hex_image * make_hex_image(uint16_t addr, uint8_t *data, uint16_t length) { @@ -54,13 +57,13 @@ make_hex_image(uint16_t addr, uint8_t *data, uint16_t length) memcpy(image->data, data, length); return image; } +#endif int main (int argc, char **argv) { struct ccdbg *dbg; uint8_t status; - uint16_t chip_id; uint16_t pc; struct hex_file *hex; struct hex_image *image; @@ -81,9 +84,7 @@ main (int argc, char **argv) image = make_hex_image(0xf000, mem_instr, sizeof (mem_instr)); #endif - ccdbg_reset(dbg); ccdbg_debug_mode(dbg); - ccdbg_halt(dbg); #if 1 if (!image) { @@ -91,13 +92,11 @@ main (int argc, char **argv) exit (1); } if (image->address == 0xf000) { - printf("Loading code to execute from RAM\n"); - ccdbg_execute_hex_image(dbg, image); + printf("Loading %d bytes to execute from RAM\n", image->length); + ccdbg_write_hex_image(dbg, image, 0); } 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); @@ -105,17 +104,9 @@ main (int argc, char **argv) ccdbg_close(dbg); exit(1); } + ccdbg_set_pc(dbg, image->address); #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)); - ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory)); -#endif + ccdbg_resume(dbg); ccdbg_close(dbg); exit (0); } diff --git a/ccdbg.h b/ccdbg.h index d5ef8940..3bb5722f 100644 --- a/ccdbg.h +++ b/ccdbg.h @@ -326,6 +326,9 @@ 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); +uint8_t +ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte); + uint8_t ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset); -- cgit v1.2.3 From d32e6658c3e489b62ba3cf6d22e3ab177b9b8a3a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 14:37:29 -0800 Subject: Add blink-tiny flash and ram versions --- blink-tiny | 5 +++++ blink-tiny-ram | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 blink-tiny create mode 100644 blink-tiny-ram diff --git a/blink-tiny b/blink-tiny new file mode 100644 index 00000000..fd075e57 --- /dev/null +++ b/blink-tiny @@ -0,0 +1,5 @@ +:03 0000 00 75 FE 02 88 +:03 0003 00 75 90 FF F6 +:02 0006 00 80 FE 7A +:02 0008 00 80 FE 78 +:00 0000 01 FF diff --git a/blink-tiny-ram b/blink-tiny-ram new file mode 100644 index 00000000..018716d5 --- /dev/null +++ b/blink-tiny-ram @@ -0,0 +1,4 @@ +:03 F000 00 75 FE 02 98 +:03 F003 00 75 90 FF 06 +:02 F006 00 80 FE 8A +:00000001FF -- cgit v1.2.3 From 4ecfc33f16aa36b315519e6f279da65374b67aba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 14:37:53 -0800 Subject: Add cc1111 isr stub example --- isr.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 isr.c diff --git a/isr.c b/isr.c new file mode 100644 index 00000000..43aedc29 --- /dev/null +++ b/isr.c @@ -0,0 +1,90 @@ +/* + * 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. + */ + +void rftxrx_isr (void) __interrupt(0) __using(1) +{ +} + +void adc_isr (void) __interrupt(1) __using(1) +{ +} + +void urx0_isr (void) __interrupt(2) __using(1) +{ +} + +void urx1_isr (void) __interrupt(3) __using(1) +{ +} + +void enc_isr (void) __interrupt(4) __using(1) +{ +} + +void st_isr (void) __interrupt(5) __using(1) +{ +} + +void usb_isr (void) __interrupt(6) __using(1) +{ +} + +void utx0_isr (void) __interrupt(7) __using(1) +{ +} + +void dma_isr (void) __interrupt(8) __using(1) +{ +} + +void t1_isr (void) __interrupt(9) __using(1) +{ +} + +void t2_isr (void) __interrupt(10) __using(1) +{ +} + +void t3_isr (void) __interrupt(11) __using(1) +{ +} + +void t4_isr (void) __interrupt(12) __using(1) +{ +} + +void p0int_isr (void) __interrupt(13) __using(1) +{ +} + +void utx1_isr (void) __interrupt(14) __using(1) +{ +} + +void p1int_isr (void) __interrupt(15) __using(1) +{ +} + +void rf_isr (void) __interrupt(16) __using(1) +{ +} + +void wdt_isr (void) __interrupt(17) __using(1) +{ +} + -- cgit v1.2.3 From 52fb5f795adfd7f62e5b6dbe65877d14361cfdae Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 14:39:57 -0800 Subject: ignore more stuff --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index fe255c6f..b0438116 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,15 @@ ccdbg +blink-flash +blink-ram *.o +tags +*.adb +*.asm +*.cdb +*.lnk +*.lst +*.map +*.mem +*.rel +*.rst +*.sym -- cgit v1.2.3 From 82e2d7ebed6682062dc400478c736bd6c91195c9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 19:04:26 -0800 Subject: Clean up makefiles, move ihx files to .ihx --- Makefile | 4 ++-- Makefile.blink | 26 +++++++++++--------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index d3bafe2c..10cd8888 100644 --- a/Makefile +++ b/Makefile @@ -29,9 +29,9 @@ $(PROG): $(OBJS) clean: rm -f $(PROG) $(OBJS) - make -f Makefile.blink clean + +make -f Makefile.blink clean $(OBJS): $(INCS) blinks: blink.c Makefile.blink - make -j1 -f Makefile.blink + +make -f Makefile.blink diff --git a/Makefile.blink b/Makefile.blink index e153c978..9cda7805 100644 --- a/Makefile.blink +++ b/Makefile.blink @@ -1,4 +1,3 @@ -.NOTPARALLEL: CC=sdcc NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ --nolabelopt --nooverlay --peep-asm @@ -14,8 +13,6 @@ LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 - - SRC=blink.c ADB=$(SRC:.c=.adb) ASM=$(SRC:.c=.asm) @@ -25,25 +22,24 @@ 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) +PROGS=blink-flash.ihx blink-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) %.rel : %.c $(CC) -c $(CFLAGS) -o$*.rel $< all: $(PROGS) -blink-ram: $(REL) Makefile.blink - $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink $(REL) - mv blink $@ +blink-ram.ihx: $(REL) Makefile.blink + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL) -blink-flash: $(REL) Makefile.blink - $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink $(REL) - mv blink $@ +blink-flash.ihx: $(REL) Makefile.blink + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL) clean: rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) - rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) -- cgit v1.2.3 From cc8db276bc4f2fd7eb00168a5c0689a8457a5c6f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 19:07:37 -0800 Subject: Move blink example to subdir Signed-off-by: Keith Packard --- Makefile | 6 ++-- Makefile.blink | 45 -------------------------- blink.c | 100 --------------------------------------------------------- blink/Makefile | 44 +++++++++++++++++++++++++ blink/blink.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 148 deletions(-) delete mode 100644 Makefile.blink delete mode 100644 blink.c create mode 100644 blink/Makefile create mode 100644 blink/blink.c diff --git a/Makefile b/Makefile index 10cd8888..9603dc22 100644 --- a/Makefile +++ b/Makefile @@ -29,9 +29,9 @@ $(PROG): $(OBJS) clean: rm -f $(PROG) $(OBJS) - +make -f Makefile.blink clean + +make -C blink clean $(OBJS): $(INCS) -blinks: blink.c Makefile.blink - +make -f Makefile.blink +blinks: + +make -C blink diff --git a/Makefile.blink b/Makefile.blink deleted file mode 100644 index 9cda7805..00000000 --- a/Makefile.blink +++ /dev/null @@ -1,45 +0,0 @@ -CC=sdcc -NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ - --nolabelopt --nooverlay --peep-asm -DEBUG=--debug - -CFLAGS=--model-large $(DEBUG) --less-pedantic \ - --no-peep --int-long-reent --float-reent \ - --no-pack-iram \ - --data-loc 0x30 \ - -LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx -LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 - -LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 - -SRC=blink.c -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.ihx blink-ram.ihx -PCDB=$(PROGS:.ihx=.cdb) -PLNK=$(PROGS:.ihx=.lnk) -PMAP=$(PROGS:.ihx=.map) -PMEM=$(PROGS:.ihx=.mem) -PAOM=$(PROGS:.ihx=) - -%.rel : %.c - $(CC) -c $(CFLAGS) -o$*.rel $< - -all: $(PROGS) - -blink-ram.ihx: $(REL) Makefile.blink - $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL) - -blink-flash.ihx: $(REL) Makefile.blink - $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL) - -clean: - rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) - rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/blink.c b/blink.c deleted file mode 100644 index 907c82b8..00000000 --- a/blink.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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. - */ - -sfr at 0x80 P0; -sfr at 0x90 P1; -sfr at 0xA0 P2; -sfr at 0xC6 CLKCON; - -sfr at 0xF1 PERCFG; -sfr at 0xF2 ADCCFG; -sfr at 0xF3 P0SEL; -sfr at 0xF4 P1SEL; -sfr at 0xF5 P2SEL; - -sfr at 0xFD P0DIR; -sfr at 0xFE P1DIR; -sfr at 0xFF P2DIR; -sfr at 0x8F P0INP; -sfr at 0xF6 P1INP; -sfr at 0xF7 P2INP; - -sfr at 0x89 P0IFG; -sfr at 0x8A P1IFG; -sfr at 0x8B P2IFG; - -#define nop() _asm nop _endasm; - -void -delay (unsigned char n) -{ - unsigned char i = 0, j = 0; - - n <<= 1; - while (--n != 0) - while (--j != 0) - while (--i != 0) - nop(); -} - -void -dit() { - P1 = 0xff; - delay(1); - P1 = 0xfd; - delay(1); -} - -void -dah () { - P1 = 0xff; - delay(3); - P1 = 0xfd; - delay(1); -} - -void -charspace () { - delay(2); -} - -void -wordspace () { - delay(8); -} - -#define _ dit(); -#define ___ dah(); -#define C charspace(); -#define W wordspace(); - -main () -{ - CLKCON = 0; - /* Set p1_1 to output */ - P1DIR = 0x02; - P1INP = 0x00; - P2INP = 0x00; - for (;;) { - ___ _ ___ _ C ___ ___ _ ___ W /* cq */ - ___ _ _ C _ W /* de */ - ___ _ ___ C ___ _ _ C /* kd */ - ___ ___ _ _ _ C _ _ _ C /* 7s */ - ___ ___ _ ___ C ___ ___ _ W /* qg */ - } -} diff --git a/blink/Makefile b/blink/Makefile new file mode 100644 index 00000000..1f18f529 --- /dev/null +++ b/blink/Makefile @@ -0,0 +1,44 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=blink.c +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.ihx blink-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +blink-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL) + +blink-flash.ihx: blink-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/blink/blink.c b/blink/blink.c new file mode 100644 index 00000000..907c82b8 --- /dev/null +++ b/blink/blink.c @@ -0,0 +1,100 @@ +/* + * 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. + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0, j = 0; + + n <<= 1; + while (--n != 0) + while (--j != 0) + while (--i != 0) + nop(); +} + +void +dit() { + P1 = 0xff; + delay(1); + P1 = 0xfd; + delay(1); +} + +void +dah () { + P1 = 0xff; + delay(3); + P1 = 0xfd; + delay(1); +} + +void +charspace () { + delay(2); +} + +void +wordspace () { + delay(8); +} + +#define _ dit(); +#define ___ dah(); +#define C charspace(); +#define W wordspace(); + +main () +{ + CLKCON = 0; + /* Set p1_1 to output */ + P1DIR = 0x02; + P1INP = 0x00; + P2INP = 0x00; + for (;;) { + ___ _ ___ _ C ___ ___ _ ___ W /* cq */ + ___ _ _ C _ W /* de */ + ___ _ ___ C ___ _ _ C /* kd */ + ___ ___ _ _ _ C _ _ _ C /* 7s */ + ___ ___ _ ___ C ___ ___ _ W /* qg */ + } +} -- cgit v1.2.3 From ab909db28307cfbf7ee8d692506bb79d7ffd627a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 19:08:13 -0800 Subject: Ignore .ihx files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b0438116..4db91cd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ ccdbg +*.ihx blink-flash blink-ram *.o -- cgit v1.2.3 From 9025eb792861930e6af918d2727c4f5d97a69936 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 21:11:45 -0800 Subject: Autotools. Signed-off-by: Keith Packard --- AUTHORS | 2 + COPYING | 341 +++++++++++++++++++++++++++++++++++++++++++++++ ChangeLog | 0 INSTALL | 236 +++++++++++++++++++++++++++++++++ Makefile | 37 ------ Makefile.am | 1 + NEWS | 0 README | 0 autogen.sh | 12 ++ blink-tiny | 5 - blink-tiny-ram | 4 - blink/Makefile | 44 ------ blink/blink.c | 100 -------------- cccp.c | 100 -------------- cccp.h | 41 ------ ccdbg-command.c | 182 ------------------------- ccdbg-debug.c | 47 ------- ccdbg-flash.c | 337 ---------------------------------------------- ccdbg-hex.c | 330 --------------------------------------------- ccdbg-io.c | 211 ----------------------------- ccdbg-manual.c | 70 ---------- ccdbg-memory.c | 104 --------------- ccdbg.c | 112 ---------------- ccdbg.h | 351 ------------------------------------------------ ccload/Makefile.am | 10 ++ ccload/ccload.c | 78 +++++++++++ chip_id | 71 ---------- cp-usb.c | 140 -------------------- debug_mode | 11 -- get_pc | 71 ---------- get_status | 329 --------------------------------------------- half_phase | 71 ---------- in | 146 -------------------- isr.c | 90 ------------- lib/Makefile.am | 14 ++ lib/cccp.c | 100 ++++++++++++++ lib/cccp.h | 41 ++++++ lib/ccdbg-command.c | 182 +++++++++++++++++++++++++ lib/ccdbg-debug.c | 47 +++++++ lib/ccdbg-flash.c | 337 ++++++++++++++++++++++++++++++++++++++++++++++ lib/ccdbg-hex.c | 330 +++++++++++++++++++++++++++++++++++++++++++++ lib/ccdbg-io.c | 211 +++++++++++++++++++++++++++++ lib/ccdbg-manual.c | 70 ++++++++++ lib/ccdbg-memory.c | 104 +++++++++++++++ lib/ccdbg.h | 351 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/cp-usb.c | 140 ++++++++++++++++++++ p1_1 | 360 -------------------------------------------------- rd_config | 55 -------- read_status | 55 -------- reset | 5 - target/blink/Makefile | 44 ++++++ target/blink/blink.c | 100 ++++++++++++++ target/isr.c | 90 +++++++++++++ tests/blink-tiny | 5 + tests/blink-tiny-ram | 4 + tests/chip_id | 71 ++++++++++ tests/debug_mode | 11 ++ tests/get_pc | 71 ++++++++++ tests/get_status | 329 +++++++++++++++++++++++++++++++++++++++++++++ tests/half_phase | 71 ++++++++++ tests/in | 146 ++++++++++++++++++++ tests/p1_1 | 360 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/rd_config | 55 ++++++++ tests/read_status | 55 ++++++++ tests/reset | 5 + tests/wr_config | 116 ++++++++++++++++ wr_config | 116 ---------------- 67 files changed, 4140 insertions(+), 3595 deletions(-) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL delete mode 100644 Makefile create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh delete mode 100644 blink-tiny delete mode 100644 blink-tiny-ram delete mode 100644 blink/Makefile delete mode 100644 blink/blink.c delete mode 100644 cccp.c delete mode 100644 cccp.h delete mode 100644 ccdbg-command.c delete mode 100644 ccdbg-debug.c delete mode 100644 ccdbg-flash.c delete mode 100644 ccdbg-hex.c delete mode 100644 ccdbg-io.c delete mode 100644 ccdbg-manual.c delete mode 100644 ccdbg-memory.c delete mode 100644 ccdbg.c delete mode 100644 ccdbg.h create mode 100644 ccload/Makefile.am create mode 100644 ccload/ccload.c delete mode 100644 chip_id delete mode 100644 cp-usb.c delete mode 100644 debug_mode delete mode 100644 get_pc delete mode 100644 get_status delete mode 100644 half_phase delete mode 100644 in delete mode 100644 isr.c create mode 100644 lib/Makefile.am create mode 100644 lib/cccp.c create mode 100644 lib/cccp.h create mode 100644 lib/ccdbg-command.c create mode 100644 lib/ccdbg-debug.c create mode 100644 lib/ccdbg-flash.c create mode 100644 lib/ccdbg-hex.c create mode 100644 lib/ccdbg-io.c create mode 100644 lib/ccdbg-manual.c create mode 100644 lib/ccdbg-memory.c create mode 100644 lib/ccdbg.h create mode 100644 lib/cp-usb.c delete mode 100644 p1_1 delete mode 100644 rd_config delete mode 100644 read_status delete mode 100644 reset create mode 100644 target/blink/Makefile create mode 100644 target/blink/blink.c create mode 100644 target/isr.c create mode 100644 tests/blink-tiny create mode 100644 tests/blink-tiny-ram create mode 100644 tests/chip_id create mode 100644 tests/debug_mode create mode 100644 tests/get_pc create mode 100644 tests/get_status create mode 100644 tests/half_phase create mode 100644 tests/in create mode 100644 tests/p1_1 create mode 100644 tests/rd_config create mode 100644 tests/read_status create mode 100644 tests/reset create mode 100644 tests/wr_config delete mode 100644 wr_config diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..a5b6500c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Keith Packard +Bdale Garbee diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..10828e06 --- /dev/null +++ b/COPYING @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..23e5f25d --- /dev/null +++ b/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile b/Makefile deleted file mode 100644 index 9603dc22..00000000 --- a/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -.NOTPARALLEL: blink-ram blink-flash -KERNEL=/local/src/linux-2.6-aiko-64 -KINC=$(KERNEL)/drivers/usb/serial - -WARN=-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes\ - -Wmissing-declarations -Wnested-externs -fno-strict-aliasing -CFLAGS=-g -I$(KINC) $(WARN) -LIBS=-lusb - -KERNEL_OBJS=cccp.o -LIBUSB_OBJS=cp-usb.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=blinks - -all: $(PROG) $(LOAD) - -$(PROG): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) - -clean: - rm -f $(PROG) $(OBJS) - +make -C blink clean - -$(OBJS): $(INCS) - -blinks: - +make -C blink diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..71aee980 --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=lib ccload target/blink diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/README b/README new file mode 100644 index 00000000..e69de29b diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..4e8b11ba --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf --force -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/blink-tiny b/blink-tiny deleted file mode 100644 index fd075e57..00000000 --- a/blink-tiny +++ /dev/null @@ -1,5 +0,0 @@ -:03 0000 00 75 FE 02 88 -:03 0003 00 75 90 FF F6 -:02 0006 00 80 FE 7A -:02 0008 00 80 FE 78 -:00 0000 01 FF diff --git a/blink-tiny-ram b/blink-tiny-ram deleted file mode 100644 index 018716d5..00000000 --- a/blink-tiny-ram +++ /dev/null @@ -1,4 +0,0 @@ -:03 F000 00 75 FE 02 98 -:03 F003 00 75 90 FF 06 -:02 F006 00 80 FE 8A -:00000001FF diff --git a/blink/Makefile b/blink/Makefile deleted file mode 100644 index 1f18f529..00000000 --- a/blink/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -CC=sdcc -NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ - --nolabelopt --nooverlay --peep-asm -DEBUG=--debug - -CFLAGS=--model-large $(DEBUG) --less-pedantic \ - --no-peep --int-long-reent --float-reent \ - --data-loc 0x30 - -LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx -LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 - -LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 - -SRC=blink.c -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.ihx blink-ram.ihx -PCDB=$(PROGS:.ihx=.cdb) -PLNK=$(PROGS:.ihx=.lnk) -PMAP=$(PROGS:.ihx=.map) -PMEM=$(PROGS:.ihx=.mem) -PAOM=$(PROGS:.ihx=) - -%.rel : %.c - $(CC) -c $(CFLAGS) -o$*.rel $< - -all: $(PROGS) - -blink-ram.ihx: $(REL) Makefile - $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL) - $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL) - -blink-flash.ihx: blink-ram.ihx - -clean: - rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) - rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/blink/blink.c b/blink/blink.c deleted file mode 100644 index 907c82b8..00000000 --- a/blink/blink.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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. - */ - -sfr at 0x80 P0; -sfr at 0x90 P1; -sfr at 0xA0 P2; -sfr at 0xC6 CLKCON; - -sfr at 0xF1 PERCFG; -sfr at 0xF2 ADCCFG; -sfr at 0xF3 P0SEL; -sfr at 0xF4 P1SEL; -sfr at 0xF5 P2SEL; - -sfr at 0xFD P0DIR; -sfr at 0xFE P1DIR; -sfr at 0xFF P2DIR; -sfr at 0x8F P0INP; -sfr at 0xF6 P1INP; -sfr at 0xF7 P2INP; - -sfr at 0x89 P0IFG; -sfr at 0x8A P1IFG; -sfr at 0x8B P2IFG; - -#define nop() _asm nop _endasm; - -void -delay (unsigned char n) -{ - unsigned char i = 0, j = 0; - - n <<= 1; - while (--n != 0) - while (--j != 0) - while (--i != 0) - nop(); -} - -void -dit() { - P1 = 0xff; - delay(1); - P1 = 0xfd; - delay(1); -} - -void -dah () { - P1 = 0xff; - delay(3); - P1 = 0xfd; - delay(1); -} - -void -charspace () { - delay(2); -} - -void -wordspace () { - delay(8); -} - -#define _ dit(); -#define ___ dah(); -#define C charspace(); -#define W wordspace(); - -main () -{ - CLKCON = 0; - /* Set p1_1 to output */ - P1DIR = 0x02; - P1INP = 0x00; - P2INP = 0x00; - for (;;) { - ___ _ ___ _ C ___ ___ _ ___ W /* cq */ - ___ _ _ C _ W /* de */ - ___ _ ___ C ___ _ _ C /* kd */ - ___ ___ _ _ _ C _ _ _ C /* 7s */ - ___ ___ _ ___ C ___ ___ _ W /* qg */ - } -} diff --git a/cccp.c b/cccp.c deleted file mode 100644 index 99a0d81f..00000000 --- a/cccp.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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" - -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); - 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 get; - - /* tri-state the bits of interest */ - pull_up = (~dbg->debug_data) & mask; - if (pull_up) - _cccp_write(dbg, pull_up, pull_up); - get = cccp_read_all(dbg); - say("\t\tr", get); - return get & mask; -} - -void -cccp_init(struct ccdbg *dbg) -{ - /* set all of the GPIOs to a known state */ - cccp_write(dbg, 0xf, 0xf); -} - -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 deleted file mode 100644 index eecdbb49..00000000 --- a/cccp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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_all(struct ccdbg *dbg); - -uint8_t -cccp_read(struct ccdbg *dbg, uint8_t mask); - -void -cccp_init(struct ccdbg *dbg); - -void -cccp_fini(struct ccdbg *dbg); - -#endif /* _CCCP_H_ */ diff --git a/ccdbg-command.c b/ccdbg-command.c deleted file mode 100644 index 38c006cb..00000000 --- a/ccdbg-command.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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_debug_mode(struct ccdbg *dbg) -{ - /* force two rising clocks while holding RESET_N low */ - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); -} - -void -ccdbg_reset(struct ccdbg *dbg) -{ - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); -} - -uint8_t -ccdbg_chip_erase(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_CHIP_ERASE, NULL, 0); -} - -uint8_t -ccdbg_wr_config(struct ccdbg *dbg, uint8_t config) -{ - return ccdbg_cmd_write_read8(dbg, CC_WR_CONFIG, &config, 1); -} - -uint8_t -ccdbg_rd_config(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0); -} - -uint16_t -ccdbg_get_pc(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); -} - -uint8_t -ccdbg_read_status(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0); -} - -uint8_t -ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr) -{ - uint8_t data[3]; - - data[0] = (number << 3) | (enable << 2); - data[1] = (addr >> 8); - data[2] = addr; - return ccdbg_cmd_write_read8(dbg, CC_SET_HW_BRKPNT, data, 3); -} - -uint8_t -ccdbg_halt(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_HALT, NULL, 0); -} - -uint8_t -ccdbg_resume(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_RESUME, NULL, 0); -} - -uint8_t -ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes) -{ - return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes); -} - -uint8_t -ccdbg_step_instr(struct ccdbg *dbg) -{ - return ccdbg_cmd_write_read8(dbg, CC_STEP_INSTR, NULL, 0); -} - -uint8_t -ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes) -{ - return ccdbg_cmd_write_read8(dbg, CC_STEP_REPLACE(nbytes), instr, nbytes); -} - -uint16_t -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; -} - -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; -} - diff --git a/ccdbg-debug.c b/ccdbg-debug.c deleted file mode 100644 index 2e67bc8d..00000000 --- a/ccdbg-debug.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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" -#include - -int -ccdbg_level = 0; - -void -ccdbg_add_debug(int level) -{ - ccdbg_level |= level; -} - -void -ccdbg_clear_debug(int level) -{ - ccdbg_level &= ~level; -} - -void -ccdbg_debug(int level, char *format, ...) -{ - va_list ap; - - if (ccdbg_level & level) { - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - } -} diff --git a/ccdbg-flash.c b/ccdbg-flash.c deleted file mode 100644 index aa2c5187..00000000 --- a/ccdbg-flash.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * 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" - -/* 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 - -#if 0 -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 -}; -#endif - -#if 0 -static uint8_t flash_control_clear[] = { - 3, MOV_direct_data, FCTL, 0, - 2, MOV_A_direct, FCTL, - 0 -}; -#endif - -#if 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; -} -#endif - -#if 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, -}; -#endif - -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; -} - -#if 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; -} -#endif - -#define TIMERS_OFF 0x08 -#define DMA_PAUSE 0x04 -#define TIMER_SUSPEND 0x02 -#define SEL_FLASH_INFO_PAGE 0x01 - -#if 0 -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; -} -#endif - -uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) -{ - uint16_t offset; - 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; - uint16_t remain, this_time, start; - uint8_t verify[0x400]; - - 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; - } - if (image->address & 0x3ff) { - fprintf(stderr, "flash image must start on page boundary\n"); - return 1; - } - ram_addr = 0xf000; - - - flash_prog = 0xf400; - - fwt = 0x20; - - flash_page[FLASH_TIMING] = fwt; - printf("Upload %d flash program bytes to 0x%04x\n", - sizeof (flash_page), flash_prog); - ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); - - remain = image->length; - start = 0; - while (remain) { - this_time = remain; - if (this_time > 0x400) - this_time = 0x400; - - offset = ram_addr - (image->address + start); - - printf("Upload %d bytes at 0x%04x\n", this_time, ram_addr); - ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); - - printf("Verify %d bytes\n", image->length); - ccdbg_read_memory(dbg, ram_addr, verify, this_time); - if (memcmp (image->data + start, verify, this_time) != 0) { - fprintf(stderr, "image verify failed\n"); - return 1; - } - - flash_word_addr = (image->address + start) >> 1; - flash_len = this_time + (this_time & 1); - flash_words = flash_len >> 1; - - ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8); - ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff); - - ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8); - ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff); - - ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words >> 8); - ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words & 0xff); - - 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); - - remain -= this_time; - start += this_time; - } -#if 1 - printf("Downloading flash to check\n"); - struct hex_image *test_image; - 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 - return 0; -} diff --git a/ccdbg-hex.c b/ccdbg-hex.c deleted file mode 100644 index 86478da0..00000000 --- a/ccdbg-hex.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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" -#include -#include - -struct hex_input { - FILE *file; - int line; - char *name; -}; - -enum hex_read_state { - read_marker, - read_length, - read_address, - read_type, - read_data, - read_checksum, - read_newline, - read_white, - read_done, -}; - - -static void -ccdbg_hex_error(struct hex_input *input, char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -static void -ccdbg_hex_free(struct hex_record *record) -{ - if (!record) return; - free(record); -} - -static struct hex_record * -ccdbg_hex_alloc(uint8_t length) -{ - struct hex_record *record; - - record = calloc(1, sizeof(struct hex_record) + length); - record->length = length; - return record; -} - -static int -ishex(char c) -{ - return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); -} - -static int -fromhex(char c) -{ - if (isdigit(c)) - return c - '0'; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - abort(); - return 0; -} - -static uint8_t -ccdbg_hex_checksum(struct hex_record *record) -{ - uint8_t checksum = 0; - int i; - - checksum += record->length; - checksum += record->address >> 8; - checksum += record->address & 0xff; - checksum += record->type; - for (i = 0; i < record->length; i++) - checksum += record->data[i]; - return -checksum; -} - -static struct hex_record * -ccdbg_hex_read_record(struct hex_input *input) -{ - struct hex_record *record = NULL; - enum hex_read_state state = read_marker; - char c; - int nhexbytes; - uint32_t hex; - uint32_t ndata; - uint8_t checksum; - - while (state != read_done) { - c = getc(input->file); - if (c == EOF && state != read_white) { - ccdbg_hex_error(input, "Unexpected EOF"); - goto bail; - } - if (c == ' ') - continue; - if (c == '\n') - input->line++; - switch (state) { - case read_marker: - if (c != ':') { - ccdbg_hex_error(input, "Missing ':'"); - goto bail; - } - state = read_length; - nhexbytes = 2; - hex = 0; - break; - case read_length: - case read_address: - case read_type: - case read_data: - case read_checksum: - if (!ishex(c)) { - ccdbg_hex_error(input, "Non-hex char '%c'", - c); - goto bail; - } - hex = hex << 4 | fromhex(c); - --nhexbytes; - if (nhexbytes != 0) - break; - - switch (state) { - case read_length: - record = ccdbg_hex_alloc(hex); - if (!record) { - ccdbg_hex_error(input, "Out of memory"); - goto bail; - } - state = read_address; - nhexbytes = 4; - break; - case read_address: - record->address = hex; - state = read_type; - nhexbytes = 2; - break; - case read_type: - record->type = hex; - state = read_data; - nhexbytes = 2; - ndata = 0; - break; - case read_data: - record->data[ndata] = hex; - ndata++; - nhexbytes = 2; - break; - case read_checksum: - record->checksum = hex; - state = read_newline; - break; - default: - break; - } - if (state == read_data) - if (ndata == record->length) { - nhexbytes = 2; - state = read_checksum; - } - hex = 0; - break; - case read_newline: - if (c != '\n' && c != '\r') { - ccdbg_hex_error(input, "Missing newline"); - goto bail; - } - state = read_white; - break; - case read_white: - if (!isspace(c)) { - if (c == '\n') - input->line--; - if (c != EOF) - ungetc(c, input->file); - state = read_done; - } - break; - case read_done: - break; - } - } - checksum = ccdbg_hex_checksum(record); - if (checksum != record->checksum) { - ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", - record->checksum, checksum); - goto bail; - } - return record; - -bail: - ccdbg_hex_free(record); - return NULL; -} - -void -ccdbg_hex_file_free(struct hex_file *hex) -{ - int i; - - if (!hex) - return; - for (i = 0; i < hex->nrecord; i++) - ccdbg_hex_free(hex->records[i]); - free(hex); -} - -static int -ccdbg_hex_record_compar(const void *av, const void *bv) -{ - const struct hex_record *a = *(struct hex_record **) av; - const struct hex_record *b = *(struct hex_record **) bv; - - return (int) a->address - (int) b->address; -} - -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name) -{ - struct hex_input input; - struct hex_file *hex = NULL, *newhex; - struct hex_record *record; - int srecord = 1; - int done = 0; - - hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); - input.name = name; - input.line = 1; - input.file = file; - while (!done) { - record = ccdbg_hex_read_record(&input); - if (!record) - goto bail; - if (hex->nrecord == srecord) { - srecord *= 2; - newhex = realloc(hex, - sizeof (struct hex_file) + - srecord * sizeof (struct hex_record *)); - if (!newhex) - goto bail; - hex = newhex; - } - hex->records[hex->nrecord++] = record; - if (record->type == HEX_RECORD_EOF) - done = 1; - } - /* - * Sort them into increasing addresses, except for EOF - */ - qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), - ccdbg_hex_record_compar); - return hex; - -bail: - ccdbg_hex_file_free(hex); - 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; - int length; - - 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; - length = bound - base; - image = calloc(sizeof(struct hex_image) + length, 1); - if (!image) - return NULL; - image->address = base; - image->length = length; - memset(image->data, 0xff, 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; -} diff --git a/ccdbg-io.c b/ccdbg-io.c deleted file mode 100644 index b78e3aad..00000000 --- a/ccdbg-io.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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" -#include - -void -ccdbg_half_clock(struct ccdbg *dbg) -{ - 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 * -ccdbg_open(char *file) -{ - struct ccdbg *dbg; - - dbg = calloc(sizeof (struct ccdbg), 1); - if (!dbg) { - perror("calloc"); - return NULL; - } - dbg->clock = 1; -#ifdef USE_KERNEL - dbg->fd = open(file, 2); - if (dbg->fd < 0) { - perror(file); - free(dbg); - return NULL; - } - cccp_init(dbg); - cccp_write(dbg, CC_CLOCK, CC_CLOCK); -#else - cp_usb_init(dbg); -#endif - dbg->clock = 1; - return dbg; -} - -void -ccdbg_close(struct ccdbg *dbg) -{ -#if USE_KERNEL - cccp_fini(dbg); - close (dbg->fd); -#else - cp_usb_fini(dbg); -#endif - free (dbg); -} - -int -ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) -{ -#if USE_KERNEL - return cccp_write(dbg, mask, value); -#else - cp_usb_write(dbg, mask, value); - return 0; -#endif -} - -uint8_t -ccdbg_read(struct ccdbg *dbg) -{ -#if USE_KERNEL - return cccp_read_all(dbg); -#else - return cp_usb_read(dbg); -#endif -} - -static char -is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) -{ - if (mask&bit) { - if (get&bit) - return on; - else - return '.'; - } else - return '-'; -} -void -ccdbg_print(char *format, uint8_t mask, uint8_t set) -{ - ccdbg_debug (CC_DEBUG_BITBANG, format, - is_bit(set, mask, 'C', CC_CLOCK), - is_bit(set, mask, 'D', CC_DATA), - is_bit(set, mask, 'R', CC_RESET_N)); -} - -void -ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set) -{ - ccdbg_write(dbg, mask, set); - ccdbg_print("%c %c %c\n", mask, set); - ccdbg_half_clock(dbg); -} - -void -ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) -{ - if (bit) bit = CC_DATA; - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N); -} - -void -ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) -{ - int bit; - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte); - for (bit = 7; bit >= 0; bit--) { - ccdbg_send_bit(dbg, (byte >> bit) & 1); - if (bit == 3) - ccdbg_debug(CC_DEBUG_BITBANG, "\n"); - } -} - -void -ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) -{ - while (nbytes--) - ccdbg_send_byte(dbg, *bytes++); -} - -uint8_t -ccdbg_recv_bit(struct ccdbg *dbg, int first) -{ - uint8_t mask = first ? CC_DATA : 0; - uint8_t read; - - ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - read = ccdbg_read(dbg); - ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); - return (read & CC_DATA) ? 1 : 0; -} - -uint8_t -ccdbg_recv_byte(struct ccdbg *dbg, int first) -{ - uint8_t byte = 0; - int bit; - - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); - for (bit = 0; bit < 8; bit++) { - byte = byte << 1; - byte |= ccdbg_recv_bit(dbg, first); - if (bit == 3) - ccdbg_debug(CC_DEBUG_BITBANG, "\n"); - first = 0; - } - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); - return byte; -} - -void -ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) -{ - int first = 1; - while (nbytes--) { - *bytes++ = ccdbg_recv_byte(dbg, first); - first = 0; - } -} - -void -ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) -{ - int i; - ccdbg_send_byte(dbg, cmd); - for (i = 0; i < len; i++) - ccdbg_send_byte(dbg, data[i]); -} - -uint8_t -ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) -{ - uint8_t byte[1]; - ccdbg_cmd_write(dbg, cmd, data, len); - ccdbg_recv_bytes(dbg, byte, 1); - return byte[0]; -} - -uint16_t -ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) -{ - uint8_t byte[2]; - ccdbg_cmd_write(dbg, cmd, data, len); - ccdbg_recv_bytes(dbg, byte, 2); - return (byte[0] << 8) | byte[1]; -} diff --git a/ccdbg-manual.c b/ccdbg-manual.c deleted file mode 100644 index b83dc450..00000000 --- a/ccdbg-manual.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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" - -/* - * Manual bit-banging to debug the low level protocol - */ - -static void -get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks) -{ - if (line[i] == on) { - *bits |= bit; - *masks |= bit; - return; - } - if (line[i] == '.') { - *masks |= bit; - return; - } - if (line[i] == '-') { - return; - } - fprintf(stderr, "bad line %s\n", line); - exit (1); -} - -void -ccdbg_manual(struct ccdbg *dbg, FILE *input) -{ - char line[80]; - uint8_t set, mask; - - while (fgets(line, sizeof line, input)) { - if (line[0] == '#' || line[0] == '\n') { - printf ("%s", line); - continue; - } - set = 0; - mask = 0; - get_bit(line, 0, 'C', CC_CLOCK, &set, &mask); - get_bit(line, 2, 'D', CC_DATA, &set, &mask); - get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); - if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { - uint8_t read; - read = ccdbg_read(dbg); - ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); - if ((set & CC_CLOCK) == 0) - printf ("\t%d", (read&CC_DATA) ? 1 : 0); - printf ("\n"); - } - ccdbg_send(dbg, mask, set); - } -} diff --git a/ccdbg-memory.c b/ccdbg-memory.c deleted file mode 100644 index 105295db..00000000 --- a/ccdbg-memory.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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" - -/* - * Read and write arbitrary memory through the debug port - */ - -static uint8_t memory_init[] = { - 3, MOV_DPTR_data16, 0, 0, -#define HIGH_START 2 -#define LOW_START 3 - 0, -}; - - -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) -{ - int i, nl = 0; - memory_init[HIGH_START] = addr >> 8; - memory_init[LOW_START] = addr; - (void) ccdbg_execute(dbg, memory_init); - 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); - 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_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) -{ - return ccdbg_write_memory(dbg, addr, &byte, 1); -} - -uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) -{ - 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; -} diff --git a/ccdbg.c b/ccdbg.c deleted file mode 100644 index c144a06a..00000000 --- a/ccdbg.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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" - -#if 0 -static uint8_t instructions[] = { - 3, MOV_direct_data, 0xfe, 0x02, - 3, MOV_direct_data, 0x90, 0xff, - 0 -}; -#endif - -#if 0 -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, - DJNZ_Rn_rel(1), 0xfe, - DJNZ_Rn_rel(0), 0xfc, - DJNZ_Rn_rel(2), 0xfa, - MOV_direct_data, 0x90, 0xfd, - MOV_Rn_data(2), 0x10, - DJNZ_Rn_rel(1), 0xfe, - DJNZ_Rn_rel(0), 0xfc, - DJNZ_Rn_rel(2), 0xfa, - SJMP, 0xe7, -}; -#endif - -#if 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; -} -#endif - -int -main (int argc, char **argv) -{ - struct ccdbg *dbg; - uint8_t status; - uint16_t pc; - struct hex_file *hex; - struct hex_image *image; - - dbg = ccdbg_open("/dev/ttyUSB0"); - if (!dbg) - exit (1); -#if 0 - ccdbg_manual(dbg, stdin); -#endif -#if 1 - hex = ccdbg_hex_file_read(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_debug_mode(dbg); - -#if 1 - if (!image) { - fprintf(stderr, "image create failed\n"); - exit (1); - } - if (image->address == 0xf000) { - printf("Loading %d bytes to execute from RAM\n", image->length); - ccdbg_write_hex_image(dbg, image, 0); - } else if (image->address == 0x0000) { - printf("Loading code to execute from FLASH\n"); - ccdbg_flash_hex_image(dbg, image); - } else { - printf("Cannot load code to 0x%04x\n", - image->address); - ccdbg_hex_image_free(image); - ccdbg_close(dbg); - exit(1); - } - ccdbg_set_pc(dbg, image->address); -#endif - ccdbg_resume(dbg); - ccdbg_close(dbg); - exit (0); -} diff --git a/ccdbg.h b/ccdbg.h deleted file mode 100644 index 3bb5722f..00000000 --- a/ccdbg.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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 -#include -#undef USE_KERNEL -#ifdef USE_KERNEL -#include -#define CC_CLOCK CP2101_GPIO_MASK(0) -#define CC_DATA CP2101_GPIO_MASK(1) -#define CC_RESET_N CP2101_GPIO_MASK(2) -#else -#define CC_CLOCK 0x1 -#define CC_DATA 0x2 -#define CC_RESET_N 0x4 -#include -#endif - - -/* 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; -#ifdef USE_KERNEL - int fd; -#endif - uint8_t debug_data; - 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 - -#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(n) (0x64|(n)) -#define CC_GET_CHIP_ID 0x68 - -#define CC_DEBUG_BITBANG 0x00000001 -#define CC_DEBUG_COMMAND 0x00000002 -#define CC_DEBUG_INSTRUCTIONS 0x00000004 - -/* ccdbg-command.c */ -void -ccdbg_debug_mode(struct ccdbg *dbg); - -void -ccdbg_reset(struct ccdbg *dbg); - -uint8_t -ccdbg_chip_erase(struct ccdbg *dbg); - -uint8_t -ccdbg_wr_config(struct ccdbg *dbg, uint8_t config); - -uint8_t -ccdbg_rd_config(struct ccdbg *dbg); - -uint16_t -ccdbg_get_pc(struct ccdbg *dbg); - -uint8_t -ccdbg_read_status(struct ccdbg *dbg); - -uint8_t -ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr); - -uint8_t -ccdbg_halt(struct ccdbg *dbg); - -uint8_t -ccdbg_resume(struct ccdbg *dbg); - -uint8_t -ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes); - -uint8_t -ccdbg_step_instr(struct ccdbg *dbg); - -uint8_t -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); - -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_add_debug(int level); - -void -ccdbg_clear_debug(int level); - -/* 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); - -int -ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); - -uint8_t -ccdbg_read(struct ccdbg *dbg); - -struct ccdbg * -ccdbg_open(char *file); - -void -ccdbg_close(struct ccdbg *dbg); - -void -ccdbg_clock_1_0(struct ccdbg *dbg); - -void -ccdbg_clock_0_1(struct ccdbg *dbg); - -void -ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit); - -void -ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte); - -uint8_t -ccdbg_read_bit(struct ccdbg *dbg); - -uint8_t -ccdbg_read_byte(struct ccdbg *dbg); - -void -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); - -uint16_t -ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); - -void -ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set); - -void -ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit); - -void -ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte); - -void -ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); - -uint8_t -ccdbg_recv_bit(struct ccdbg *dbg, int first); - -uint8_t -ccdbg_recv_byte(struct ccdbg *dbg, int first); - -void -ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); - -void -ccdbg_print(char *format, uint8_t mask, uint8_t set); - -/* ccdbg-manual.c */ - -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); - -uint8_t -ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte); - -uint8_t -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 -cp_usb_init(struct ccdbg *dbg); - -void -cp_usb_fini(struct ccdbg *dbg); - -void -cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); - -uint8_t -cp_usb_read(struct ccdbg *dbg); - -#endif /* _CCDBG_H_ */ diff --git a/ccload/Makefile.am b/ccload/Makefile.am new file mode 100644 index 00000000..f54f4aaa --- /dev/null +++ b/ccload/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS=ccload + +AM_CFLAGS=-I$(top_srcdir)/lib +CCLOAD_LIBS=../lib/libcc.a + +ccload_DEPENDENCIES = $(CCLOAD_LIBS) + +ccload_LDADD=$(CCLOAD_LIBS) $(USB_LIBS) + +ccload_SOURCES = ccload.c diff --git a/ccload/ccload.c b/ccload/ccload.c new file mode 100644 index 00000000..b4bb1443 --- /dev/null +++ b/ccload/ccload.c @@ -0,0 +1,78 @@ +/* + * 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" + +int +main (int argc, char **argv) +{ + struct ccdbg *dbg; + uint8_t status; + uint16_t pc; + struct hex_file *hex; + struct hex_image *image; + char *filename; + FILE *file; + + filename = argv[1]; + if (filename == NULL) { + fprintf(stderr, "usage: %s \n", argv[0]); + exit(1); + } + file = fopen(filename, "r"); + if (!file) { + perror(filename); + exit(1); + } + hex = ccdbg_hex_file_read(file, filename); + fclose(file); + if (!hex) + exit (1); + image = ccdbg_hex_image_create(hex); + if (!image) { + fprintf(stderr, "image create failed\n"); + exit (1); + } + + ccdbg_hex_file_free(hex); + dbg = ccdbg_open(); + if (!dbg) + exit (1); + + ccdbg_debug_mode(dbg); + ccdbg_halt(dbg); + if (image->address == 0xf000) { + printf("Loading %d bytes to execute from RAM\n", + image->length); + ccdbg_write_hex_image(dbg, image, 0); + } else if (image->address == 0x0000) { + printf("Loading %d bytes to execute from FLASH\n", + image->length); + ccdbg_flash_hex_image(dbg, image); + } else { + printf("Cannot load code to 0x%04x\n", + image->address); + ccdbg_hex_image_free(image); + ccdbg_close(dbg); + exit(1); + } + ccdbg_set_pc(dbg, image->address); + ccdbg_resume(dbg); + ccdbg_close(dbg); + exit (0); +} diff --git a/chip_id b/chip_id deleted file mode 100644 index b3ecf314..00000000 --- a/chip_id +++ /dev/null @@ -1,71 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# GET_CHIP_ID - -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C . R 0 -. . R - -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# -# start reading again - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C D R diff --git a/cp-usb.c b/cp-usb.c deleted file mode 100644 index 3822e8cd..00000000 --- a/cp-usb.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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" -#include - -#define CP2101_UART 0x00 -#define UART_ENABLE 0x0001 -#define UART_DISABLE 0x0000 -#define REQTYPE_HOST_TO_DEVICE 0x41 -#define REQTYPE_DEVICE_TO_HOST 0xc1 - -static int -cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get) -{ - return usb_control_msg(dbg->usb_dev, /* dev */ - 0xc0, /* request */ - 0xff, /* requesttype */ - 0x00c2, /* value */ - 0, /* index */ - (char *) gpio_get, /* bytes */ - 1, /* size */ - 300); /* timeout */ -} - -static int -cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value) -{ - uint16_t gpio_set = ((uint16_t) value << 8) | mask; - - return usb_control_msg(dbg->usb_dev, /* dev */ - 0x40, /* request */ - 0xff, /* requesttype */ - 0x37e1, /* value */ - gpio_set, /* index */ - NULL, /* bytes */ - 0, /* size */ - 300); /* timeout */ -} - -static int -cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable) -{ - return usb_control_msg(dbg->usb_dev, - CP2101_UART, - REQTYPE_HOST_TO_DEVICE, - enable, - 0, - NULL, - 0, - 300); -} - -void -cp_usb_init(struct ccdbg *dbg) -{ - usb_dev_handle *dev_handle; - struct usb_device *dev; - struct usb_bus *bus, *busses; - int interface; - int ret; - uint8_t gpio; - - usb_init(); - usb_find_busses(); - usb_find_devices(); - - busses = usb_get_busses(); - for (bus = busses; bus; bus = bus->next) { - for (dev = bus->devices; dev; dev = dev->next) { - if (dev->descriptor.idVendor == 0x10c4 && - dev->descriptor.idProduct == 0xea60) - break; - } - if (dev) - break; - } - if (!dev){ - perror("No CP2103 found\n"); - exit(1); - } - interface = 0; - dev_handle = usb_open(dev); - usb_detach_kernel_driver_np(dev_handle, interface); - usb_claim_interface(dev_handle, interface); - dbg->usb_dev = dev_handle; - ret = cp_usb_uart_enable_disable(dbg, UART_DISABLE); - dbg->gpio = 0xf; - ret = cp_usb_gpio_set(dbg, 0xf, dbg->gpio); - ret = cp_usb_gpio_get(dbg, &gpio); -} - -void -cp_usb_fini(struct ccdbg *dbg) -{ - cp_usb_uart_enable_disable(dbg, UART_DISABLE); - usb_close(dbg->usb_dev); -} - -void -cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) -{ - uint8_t new_gpio; - int ret; - - new_gpio = (dbg->gpio & ~mask) | (value & mask); - if (new_gpio != dbg->gpio) { - ret = cp_usb_gpio_set(dbg, new_gpio ^ dbg->gpio, new_gpio); - if (ret < 0) - perror("gpio_set"); - dbg->gpio = new_gpio; - } -} - -uint8_t -cp_usb_read(struct ccdbg *dbg) -{ - int ret; - uint8_t gpio; - - ret = cp_usb_gpio_get(dbg, &gpio); - if (ret < 0) - perror("gpio_set"); - return gpio; -} diff --git a/debug_mode b/debug_mode deleted file mode 100644 index fe25bfef..00000000 --- a/debug_mode +++ /dev/null @@ -1,11 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# - -C D R -. D . -C D . -. D . -C D . -. D R - diff --git a/get_pc b/get_pc deleted file mode 100644 index 13bcba15..00000000 --- a/get_pc +++ /dev/null @@ -1,71 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# GET_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R - -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R diff --git a/get_status b/get_status deleted file mode 100644 index 1d4ff03d..00000000 --- a/get_status +++ /dev/null @@ -1,329 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# Halt 0x44 -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# Resume 0x4c -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -C D R 1 -. D R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# READ_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# status -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# READ_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# status -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# READ_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# status -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# Halt 0x44 -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# READ_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# status -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - diff --git a/half_phase b/half_phase deleted file mode 100644 index 3ca4a303..00000000 --- a/half_phase +++ /dev/null @@ -1,71 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# GET_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R diff --git a/in b/in deleted file mode 100644 index 93341e32..00000000 --- a/in +++ /dev/null @@ -1,146 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D . - -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R - -# -# Ok, we're in debug mode now -# - -# -# GET_CHIP_ID - -#C . R 0 -#. . R -#C D R 1 -#. D R -#C D R 1 -#. D R -#C . R 0 -#. . R -# -#C D R 1 -#. D R -#C . R 0 -#. . R -#C . R 0 -#. . R -#C . R 0 -#. . R -# -## -## Read the chip id -## -# -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -# -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -# -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -# -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -#C D R -#. D R -# - -# -# GET_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R diff --git a/isr.c b/isr.c deleted file mode 100644 index 43aedc29..00000000 --- a/isr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ - -void rftxrx_isr (void) __interrupt(0) __using(1) -{ -} - -void adc_isr (void) __interrupt(1) __using(1) -{ -} - -void urx0_isr (void) __interrupt(2) __using(1) -{ -} - -void urx1_isr (void) __interrupt(3) __using(1) -{ -} - -void enc_isr (void) __interrupt(4) __using(1) -{ -} - -void st_isr (void) __interrupt(5) __using(1) -{ -} - -void usb_isr (void) __interrupt(6) __using(1) -{ -} - -void utx0_isr (void) __interrupt(7) __using(1) -{ -} - -void dma_isr (void) __interrupt(8) __using(1) -{ -} - -void t1_isr (void) __interrupt(9) __using(1) -{ -} - -void t2_isr (void) __interrupt(10) __using(1) -{ -} - -void t3_isr (void) __interrupt(11) __using(1) -{ -} - -void t4_isr (void) __interrupt(12) __using(1) -{ -} - -void p0int_isr (void) __interrupt(13) __using(1) -{ -} - -void utx1_isr (void) __interrupt(14) __using(1) -{ -} - -void p1int_isr (void) __interrupt(15) __using(1) -{ -} - -void rf_isr (void) __interrupt(16) __using(1) -{ -} - -void wdt_isr (void) __interrupt(17) __using(1) -{ -} - diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 00000000..a5e5932b --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libcc.a + +AM_CFLAGS=$(WARN_CFLAGS) + +libcc_a_SOURCES = \ + ccdbg-command.c \ + ccdbg-debug.c \ + ccdbg-flash.c \ + ccdbg.h \ + ccdbg-hex.c \ + ccdbg-io.c \ + ccdbg-manual.c \ + ccdbg-memory.c \ + cp-usb.c diff --git a/lib/cccp.c b/lib/cccp.c new file mode 100644 index 00000000..99a0d81f --- /dev/null +++ b/lib/cccp.c @@ -0,0 +1,100 @@ +/* + * 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" + +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); + 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 get; + + /* tri-state the bits of interest */ + pull_up = (~dbg->debug_data) & mask; + if (pull_up) + _cccp_write(dbg, pull_up, pull_up); + get = cccp_read_all(dbg); + say("\t\tr", get); + return get & mask; +} + +void +cccp_init(struct ccdbg *dbg) +{ + /* set all of the GPIOs to a known state */ + cccp_write(dbg, 0xf, 0xf); +} + +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/lib/cccp.h b/lib/cccp.h new file mode 100644 index 00000000..eecdbb49 --- /dev/null +++ b/lib/cccp.h @@ -0,0 +1,41 @@ +/* + * 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_all(struct ccdbg *dbg); + +uint8_t +cccp_read(struct ccdbg *dbg, uint8_t mask); + +void +cccp_init(struct ccdbg *dbg); + +void +cccp_fini(struct ccdbg *dbg); + +#endif /* _CCCP_H_ */ diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c new file mode 100644 index 00000000..38c006cb --- /dev/null +++ b/lib/ccdbg-command.c @@ -0,0 +1,182 @@ +/* + * 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_debug_mode(struct ccdbg *dbg) +{ + /* force two rising clocks while holding RESET_N low */ + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); +} + +void +ccdbg_reset(struct ccdbg *dbg) +{ + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); +} + +uint8_t +ccdbg_chip_erase(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_CHIP_ERASE, NULL, 0); +} + +uint8_t +ccdbg_wr_config(struct ccdbg *dbg, uint8_t config) +{ + return ccdbg_cmd_write_read8(dbg, CC_WR_CONFIG, &config, 1); +} + +uint8_t +ccdbg_rd_config(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_RD_CONFIG, NULL, 0); +} + +uint16_t +ccdbg_get_pc(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); +} + +uint8_t +ccdbg_read_status(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_READ_STATUS, NULL, 0); +} + +uint8_t +ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr) +{ + uint8_t data[3]; + + data[0] = (number << 3) | (enable << 2); + data[1] = (addr >> 8); + data[2] = addr; + return ccdbg_cmd_write_read8(dbg, CC_SET_HW_BRKPNT, data, 3); +} + +uint8_t +ccdbg_halt(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_HALT, NULL, 0); +} + +uint8_t +ccdbg_resume(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_RESUME, NULL, 0); +} + +uint8_t +ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes) +{ + return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes); +} + +uint8_t +ccdbg_step_instr(struct ccdbg *dbg) +{ + return ccdbg_cmd_write_read8(dbg, CC_STEP_INSTR, NULL, 0); +} + +uint8_t +ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes) +{ + return ccdbg_cmd_write_read8(dbg, CC_STEP_REPLACE(nbytes), instr, nbytes); +} + +uint16_t +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; +} + +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; +} + diff --git a/lib/ccdbg-debug.c b/lib/ccdbg-debug.c new file mode 100644 index 00000000..2e67bc8d --- /dev/null +++ b/lib/ccdbg-debug.c @@ -0,0 +1,47 @@ +/* + * 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" +#include + +int +ccdbg_level = 0; + +void +ccdbg_add_debug(int level) +{ + ccdbg_level |= level; +} + +void +ccdbg_clear_debug(int level) +{ + ccdbg_level &= ~level; +} + +void +ccdbg_debug(int level, char *format, ...) +{ + va_list ap; + + if (ccdbg_level & level) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + } +} diff --git a/lib/ccdbg-flash.c b/lib/ccdbg-flash.c new file mode 100644 index 00000000..aa2c5187 --- /dev/null +++ b/lib/ccdbg-flash.c @@ -0,0 +1,337 @@ +/* + * 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" + +/* 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 + +#if 0 +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 +}; +#endif + +#if 0 +static uint8_t flash_control_clear[] = { + 3, MOV_direct_data, FCTL, 0, + 2, MOV_A_direct, FCTL, + 0 +}; +#endif + +#if 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; +} +#endif + +#if 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, +}; +#endif + +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; +} + +#if 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; +} +#endif + +#define TIMERS_OFF 0x08 +#define DMA_PAUSE 0x04 +#define TIMER_SUSPEND 0x02 +#define SEL_FLASH_INFO_PAGE 0x01 + +#if 0 +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; +} +#endif + +uint8_t +ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) +{ + uint16_t offset; + 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; + uint16_t remain, this_time, start; + uint8_t verify[0x400]; + + 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; + } + if (image->address & 0x3ff) { + fprintf(stderr, "flash image must start on page boundary\n"); + return 1; + } + ram_addr = 0xf000; + + + flash_prog = 0xf400; + + fwt = 0x20; + + flash_page[FLASH_TIMING] = fwt; + printf("Upload %d flash program bytes to 0x%04x\n", + sizeof (flash_page), flash_prog); + ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); + + remain = image->length; + start = 0; + while (remain) { + this_time = remain; + if (this_time > 0x400) + this_time = 0x400; + + offset = ram_addr - (image->address + start); + + printf("Upload %d bytes at 0x%04x\n", this_time, ram_addr); + ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); + + printf("Verify %d bytes\n", image->length); + ccdbg_read_memory(dbg, ram_addr, verify, this_time); + if (memcmp (image->data + start, verify, this_time) != 0) { + fprintf(stderr, "image verify failed\n"); + return 1; + } + + flash_word_addr = (image->address + start) >> 1; + flash_len = this_time + (this_time & 1); + flash_words = flash_len >> 1; + + ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8); + ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff); + + ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8); + ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff); + + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words >> 8); + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words & 0xff); + + 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); + + remain -= this_time; + start += this_time; + } +#if 1 + printf("Downloading flash to check\n"); + struct hex_image *test_image; + 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 + return 0; +} diff --git a/lib/ccdbg-hex.c b/lib/ccdbg-hex.c new file mode 100644 index 00000000..86478da0 --- /dev/null +++ b/lib/ccdbg-hex.c @@ -0,0 +1,330 @@ +/* + * 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" +#include +#include + +struct hex_input { + FILE *file; + int line; + char *name; +}; + +enum hex_read_state { + read_marker, + read_length, + read_address, + read_type, + read_data, + read_checksum, + read_newline, + read_white, + read_done, +}; + + +static void +ccdbg_hex_error(struct hex_input *input, char *format, ...) +{ + va_list ap; + + va_start(ap, format); + fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void +ccdbg_hex_free(struct hex_record *record) +{ + if (!record) return; + free(record); +} + +static struct hex_record * +ccdbg_hex_alloc(uint8_t length) +{ + struct hex_record *record; + + record = calloc(1, sizeof(struct hex_record) + length); + record->length = length; + return record; +} + +static int +ishex(char c) +{ + return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); +} + +static int +fromhex(char c) +{ + if (isdigit(c)) + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + abort(); + return 0; +} + +static uint8_t +ccdbg_hex_checksum(struct hex_record *record) +{ + uint8_t checksum = 0; + int i; + + checksum += record->length; + checksum += record->address >> 8; + checksum += record->address & 0xff; + checksum += record->type; + for (i = 0; i < record->length; i++) + checksum += record->data[i]; + return -checksum; +} + +static struct hex_record * +ccdbg_hex_read_record(struct hex_input *input) +{ + struct hex_record *record = NULL; + enum hex_read_state state = read_marker; + char c; + int nhexbytes; + uint32_t hex; + uint32_t ndata; + uint8_t checksum; + + while (state != read_done) { + c = getc(input->file); + if (c == EOF && state != read_white) { + ccdbg_hex_error(input, "Unexpected EOF"); + goto bail; + } + if (c == ' ') + continue; + if (c == '\n') + input->line++; + switch (state) { + case read_marker: + if (c != ':') { + ccdbg_hex_error(input, "Missing ':'"); + goto bail; + } + state = read_length; + nhexbytes = 2; + hex = 0; + break; + case read_length: + case read_address: + case read_type: + case read_data: + case read_checksum: + if (!ishex(c)) { + ccdbg_hex_error(input, "Non-hex char '%c'", + c); + goto bail; + } + hex = hex << 4 | fromhex(c); + --nhexbytes; + if (nhexbytes != 0) + break; + + switch (state) { + case read_length: + record = ccdbg_hex_alloc(hex); + if (!record) { + ccdbg_hex_error(input, "Out of memory"); + goto bail; + } + state = read_address; + nhexbytes = 4; + break; + case read_address: + record->address = hex; + state = read_type; + nhexbytes = 2; + break; + case read_type: + record->type = hex; + state = read_data; + nhexbytes = 2; + ndata = 0; + break; + case read_data: + record->data[ndata] = hex; + ndata++; + nhexbytes = 2; + break; + case read_checksum: + record->checksum = hex; + state = read_newline; + break; + default: + break; + } + if (state == read_data) + if (ndata == record->length) { + nhexbytes = 2; + state = read_checksum; + } + hex = 0; + break; + case read_newline: + if (c != '\n' && c != '\r') { + ccdbg_hex_error(input, "Missing newline"); + goto bail; + } + state = read_white; + break; + case read_white: + if (!isspace(c)) { + if (c == '\n') + input->line--; + if (c != EOF) + ungetc(c, input->file); + state = read_done; + } + break; + case read_done: + break; + } + } + checksum = ccdbg_hex_checksum(record); + if (checksum != record->checksum) { + ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", + record->checksum, checksum); + goto bail; + } + return record; + +bail: + ccdbg_hex_free(record); + return NULL; +} + +void +ccdbg_hex_file_free(struct hex_file *hex) +{ + int i; + + if (!hex) + return; + for (i = 0; i < hex->nrecord; i++) + ccdbg_hex_free(hex->records[i]); + free(hex); +} + +static int +ccdbg_hex_record_compar(const void *av, const void *bv) +{ + const struct hex_record *a = *(struct hex_record **) av; + const struct hex_record *b = *(struct hex_record **) bv; + + return (int) a->address - (int) b->address; +} + +struct hex_file * +ccdbg_hex_file_read(FILE *file, char *name) +{ + struct hex_input input; + struct hex_file *hex = NULL, *newhex; + struct hex_record *record; + int srecord = 1; + int done = 0; + + hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); + input.name = name; + input.line = 1; + input.file = file; + while (!done) { + record = ccdbg_hex_read_record(&input); + if (!record) + goto bail; + if (hex->nrecord == srecord) { + srecord *= 2; + newhex = realloc(hex, + sizeof (struct hex_file) + + srecord * sizeof (struct hex_record *)); + if (!newhex) + goto bail; + hex = newhex; + } + hex->records[hex->nrecord++] = record; + if (record->type == HEX_RECORD_EOF) + done = 1; + } + /* + * Sort them into increasing addresses, except for EOF + */ + qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), + ccdbg_hex_record_compar); + return hex; + +bail: + ccdbg_hex_file_free(hex); + 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; + int length; + + 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; + length = bound - base; + image = calloc(sizeof(struct hex_image) + length, 1); + if (!image) + return NULL; + image->address = base; + image->length = length; + memset(image->data, 0xff, 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; +} diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c new file mode 100644 index 00000000..29476785 --- /dev/null +++ b/lib/ccdbg-io.c @@ -0,0 +1,211 @@ +/* + * 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" +#include + +void +ccdbg_half_clock(struct ccdbg *dbg) +{ + 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 * +ccdbg_open(void) +{ + struct ccdbg *dbg; + + dbg = calloc(sizeof (struct ccdbg), 1); + if (!dbg) { + perror("calloc"); + return NULL; + } + dbg->clock = 1; +#ifdef USE_KERNEL + dbg->fd = open("/dev/ttyUSB0", 2); + if (dbg->fd < 0) { + perror(file); + free(dbg); + return NULL; + } + cccp_init(dbg); + cccp_write(dbg, CC_CLOCK, CC_CLOCK); +#else + cp_usb_init(dbg); +#endif + dbg->clock = 1; + return dbg; +} + +void +ccdbg_close(struct ccdbg *dbg) +{ +#if USE_KERNEL + cccp_fini(dbg); + close (dbg->fd); +#else + cp_usb_fini(dbg); +#endif + free (dbg); +} + +int +ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ +#if USE_KERNEL + return cccp_write(dbg, mask, value); +#else + cp_usb_write(dbg, mask, value); + return 0; +#endif +} + +uint8_t +ccdbg_read(struct ccdbg *dbg) +{ +#if USE_KERNEL + return cccp_read_all(dbg); +#else + return cp_usb_read(dbg); +#endif +} + +static char +is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) +{ + if (mask&bit) { + if (get&bit) + return on; + else + return '.'; + } else + return '-'; +} +void +ccdbg_print(char *format, uint8_t mask, uint8_t set) +{ + ccdbg_debug (CC_DEBUG_BITBANG, format, + is_bit(set, mask, 'C', CC_CLOCK), + is_bit(set, mask, 'D', CC_DATA), + is_bit(set, mask, 'R', CC_RESET_N)); +} + +void +ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set) +{ + ccdbg_write(dbg, mask, set); + ccdbg_print("%c %c %c\n", mask, set); + ccdbg_half_clock(dbg); +} + +void +ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) +{ + if (bit) bit = CC_DATA; + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N); + ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N); +} + +void +ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) +{ + int bit; + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte); + for (bit = 7; bit >= 0; bit--) { + ccdbg_send_bit(dbg, (byte >> bit) & 1); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + } +} + +void +ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) +{ + while (nbytes--) + ccdbg_send_byte(dbg, *bytes++); +} + +uint8_t +ccdbg_recv_bit(struct ccdbg *dbg, int first) +{ + uint8_t mask = first ? CC_DATA : 0; + uint8_t read; + + ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + read = ccdbg_read(dbg); + ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); + return (read & CC_DATA) ? 1 : 0; +} + +uint8_t +ccdbg_recv_byte(struct ccdbg *dbg, int first) +{ + uint8_t byte = 0; + int bit; + + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); + for (bit = 0; bit < 8; bit++) { + byte = byte << 1; + byte |= ccdbg_recv_bit(dbg, first); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + first = 0; + } + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); + return byte; +} + +void +ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) +{ + int first = 1; + while (nbytes--) { + *bytes++ = ccdbg_recv_byte(dbg, first); + first = 0; + } +} + +void +ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + int i; + ccdbg_send_byte(dbg, cmd); + for (i = 0; i < len; i++) + ccdbg_send_byte(dbg, data[i]); +} + +uint8_t +ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + uint8_t byte[1]; + ccdbg_cmd_write(dbg, cmd, data, len); + ccdbg_recv_bytes(dbg, byte, 1); + return byte[0]; +} + +uint16_t +ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) +{ + uint8_t byte[2]; + ccdbg_cmd_write(dbg, cmd, data, len); + ccdbg_recv_bytes(dbg, byte, 2); + return (byte[0] << 8) | byte[1]; +} diff --git a/lib/ccdbg-manual.c b/lib/ccdbg-manual.c new file mode 100644 index 00000000..b83dc450 --- /dev/null +++ b/lib/ccdbg-manual.c @@ -0,0 +1,70 @@ +/* + * 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" + +/* + * Manual bit-banging to debug the low level protocol + */ + +static void +get_bit(char *line, int i, char on, uint8_t bit, uint8_t *bits, uint8_t *masks) +{ + if (line[i] == on) { + *bits |= bit; + *masks |= bit; + return; + } + if (line[i] == '.') { + *masks |= bit; + return; + } + if (line[i] == '-') { + return; + } + fprintf(stderr, "bad line %s\n", line); + exit (1); +} + +void +ccdbg_manual(struct ccdbg *dbg, FILE *input) +{ + char line[80]; + uint8_t set, mask; + + while (fgets(line, sizeof line, input)) { + if (line[0] == '#' || line[0] == '\n') { + printf ("%s", line); + continue; + } + set = 0; + mask = 0; + get_bit(line, 0, 'C', CC_CLOCK, &set, &mask); + get_bit(line, 2, 'D', CC_DATA, &set, &mask); + get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); + if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { + uint8_t read; + read = ccdbg_read(dbg); + ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); + if ((set & CC_CLOCK) == 0) + printf ("\t%d", (read&CC_DATA) ? 1 : 0); + printf ("\n"); + } + ccdbg_send(dbg, mask, set); + } +} diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c new file mode 100644 index 00000000..105295db --- /dev/null +++ b/lib/ccdbg-memory.c @@ -0,0 +1,104 @@ +/* + * 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" + +/* + * Read and write arbitrary memory through the debug port + */ + +static uint8_t memory_init[] = { + 3, MOV_DPTR_data16, 0, 0, +#define HIGH_START 2 +#define LOW_START 3 + 0, +}; + + +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) +{ + int i, nl = 0; + memory_init[HIGH_START] = addr >> 8; + memory_init[LOW_START] = addr; + (void) ccdbg_execute(dbg, memory_init); + 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); + 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_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) +{ + return ccdbg_write_memory(dbg, addr, &byte, 1); +} + +uint8_t +ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) +{ + 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; +} diff --git a/lib/ccdbg.h b/lib/ccdbg.h new file mode 100644 index 00000000..b74d13ca --- /dev/null +++ b/lib/ccdbg.h @@ -0,0 +1,351 @@ +/* + * 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 +#include +#undef USE_KERNEL +#ifdef USE_KERNEL +#include +#define CC_CLOCK CP2101_GPIO_MASK(0) +#define CC_DATA CP2101_GPIO_MASK(1) +#define CC_RESET_N CP2101_GPIO_MASK(2) +#else +#define CC_CLOCK 0x1 +#define CC_DATA 0x2 +#define CC_RESET_N 0x4 +#include +#endif + + +/* 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; +#ifdef USE_KERNEL + int fd; +#endif + uint8_t debug_data; + 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 + +#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(n) (0x64|(n)) +#define CC_GET_CHIP_ID 0x68 + +#define CC_DEBUG_BITBANG 0x00000001 +#define CC_DEBUG_COMMAND 0x00000002 +#define CC_DEBUG_INSTRUCTIONS 0x00000004 + +/* ccdbg-command.c */ +void +ccdbg_debug_mode(struct ccdbg *dbg); + +void +ccdbg_reset(struct ccdbg *dbg); + +uint8_t +ccdbg_chip_erase(struct ccdbg *dbg); + +uint8_t +ccdbg_wr_config(struct ccdbg *dbg, uint8_t config); + +uint8_t +ccdbg_rd_config(struct ccdbg *dbg); + +uint16_t +ccdbg_get_pc(struct ccdbg *dbg); + +uint8_t +ccdbg_read_status(struct ccdbg *dbg); + +uint8_t +ccdbg_set_hw_brkpnt(struct ccdbg *dbg, uint8_t number, uint8_t enable, uint16_t addr); + +uint8_t +ccdbg_halt(struct ccdbg *dbg); + +uint8_t +ccdbg_resume(struct ccdbg *dbg); + +uint8_t +ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes); + +uint8_t +ccdbg_step_instr(struct ccdbg *dbg); + +uint8_t +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); + +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_add_debug(int level); + +void +ccdbg_clear_debug(int level); + +/* 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); + +int +ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); + +uint8_t +ccdbg_read(struct ccdbg *dbg); + +struct ccdbg * +ccdbg_open(void); + +void +ccdbg_close(struct ccdbg *dbg); + +void +ccdbg_clock_1_0(struct ccdbg *dbg); + +void +ccdbg_clock_0_1(struct ccdbg *dbg); + +void +ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit); + +void +ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte); + +uint8_t +ccdbg_read_bit(struct ccdbg *dbg); + +uint8_t +ccdbg_read_byte(struct ccdbg *dbg); + +void +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); + +uint16_t +ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); + +void +ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set); + +void +ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit); + +void +ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte); + +void +ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); + +uint8_t +ccdbg_recv_bit(struct ccdbg *dbg, int first); + +uint8_t +ccdbg_recv_byte(struct ccdbg *dbg, int first); + +void +ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); + +void +ccdbg_print(char *format, uint8_t mask, uint8_t set); + +/* ccdbg-manual.c */ + +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); + +uint8_t +ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte); + +uint8_t +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 +cp_usb_init(struct ccdbg *dbg); + +void +cp_usb_fini(struct ccdbg *dbg); + +void +cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); + +uint8_t +cp_usb_read(struct ccdbg *dbg); + +#endif /* _CCDBG_H_ */ diff --git a/lib/cp-usb.c b/lib/cp-usb.c new file mode 100644 index 00000000..61b684a2 --- /dev/null +++ b/lib/cp-usb.c @@ -0,0 +1,140 @@ +/* + * 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" +#include + +#define CP2101_UART 0x00 +#define UART_ENABLE 0x0001 +#define UART_DISABLE 0x0000 +#define REQTYPE_HOST_TO_DEVICE 0x41 +#define REQTYPE_DEVICE_TO_HOST 0xc1 + +static int +cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get) +{ + return usb_control_msg(dbg->usb_dev, /* dev */ + 0xc0, /* request */ + 0xff, /* requesttype */ + 0x00c2, /* value */ + 0, /* index */ + (char *) gpio_get, /* bytes */ + 1, /* size */ + 300); /* timeout */ +} + +static int +cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ + uint16_t gpio_set = ((uint16_t) value << 8) | mask; + + return usb_control_msg(dbg->usb_dev, /* dev */ + 0x40, /* request */ + 0xff, /* requesttype */ + 0x37e1, /* value */ + gpio_set, /* index */ + NULL, /* bytes */ + 0, /* size */ + 300); /* timeout */ +} + +static int +cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable) +{ + return usb_control_msg(dbg->usb_dev, + CP2101_UART, + REQTYPE_HOST_TO_DEVICE, + enable, + 0, + NULL, + 0, + 300); +} + +void +cp_usb_init(struct ccdbg *dbg) +{ + usb_dev_handle *dev_handle; + struct usb_device *dev = NULL; + struct usb_bus *bus, *busses; + int interface; + int ret; + uint8_t gpio; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + busses = usb_get_busses(); + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == 0x10c4 && + dev->descriptor.idProduct == 0xea60) + break; + } + if (dev) + break; + } + if (!dev){ + perror("No CP2103 found"); + exit(1); + } + interface = 0; + dev_handle = usb_open(dev); + usb_detach_kernel_driver_np(dev_handle, interface); + usb_claim_interface(dev_handle, interface); + dbg->usb_dev = dev_handle; + ret = cp_usb_uart_enable_disable(dbg, UART_DISABLE); + dbg->gpio = 0xf; + ret = cp_usb_gpio_set(dbg, 0xf, dbg->gpio); + ret = cp_usb_gpio_get(dbg, &gpio); +} + +void +cp_usb_fini(struct ccdbg *dbg) +{ + cp_usb_uart_enable_disable(dbg, UART_DISABLE); + usb_close(dbg->usb_dev); +} + +void +cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) +{ + uint8_t new_gpio; + int ret; + + new_gpio = (dbg->gpio & ~mask) | (value & mask); + if (new_gpio != dbg->gpio) { + ret = cp_usb_gpio_set(dbg, new_gpio ^ dbg->gpio, new_gpio); + if (ret < 0) + perror("gpio_set"); + dbg->gpio = new_gpio; + } +} + +uint8_t +cp_usb_read(struct ccdbg *dbg) +{ + int ret; + uint8_t gpio; + + ret = cp_usb_gpio_get(dbg, &gpio); + if (ret < 0) + perror("gpio_set"); + return gpio; +} diff --git a/p1_1 b/p1_1 deleted file mode 100644 index 08d8ab50..00000000 --- a/p1_1 +++ /dev/null @@ -1,360 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# Halt 0x44 -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# DEBUG_INSTR -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -# MOV 0xfe, 0x02 - -# 0x75 0x02 0xfe - -# 0x75 -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -# 0xfe -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R -C . R 0 -. . R - -# 0x02 -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# DEBUG_INSTR -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -# MOV 0x90, 0xfd -# 0x75 0xfd 0x90 - -# 0x75 -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -# 0x90 -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# 0xff -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -# -# DEBUG_INSTR -# - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -# MOV 0x90, 0xfd -# 0x75 0xfd 0x90 - -# 0x75 -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -# 0x90 -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# 0xfd -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R -C D R 1 -. D R - -C D R 1 -. D R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -# status byte - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C D R diff --git a/rd_config b/rd_config deleted file mode 100644 index e2d43f10..00000000 --- a/rd_config +++ /dev/null @@ -1,55 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# RD_CONFIG -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C D R diff --git a/read_status b/read_status deleted file mode 100644 index 3ae46058..00000000 --- a/read_status +++ /dev/null @@ -1,55 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# READ_STATUS -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C D R 1 -. D R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C - R -. - R -C - R -. - R -C - R -. - R -C - R -. - R - -C D R diff --git a/reset b/reset deleted file mode 100644 index a32c8bec..00000000 --- a/reset +++ /dev/null @@ -1,5 +0,0 @@ -# reset -C D R -C D R -C D R -C D R diff --git a/target/blink/Makefile b/target/blink/Makefile new file mode 100644 index 00000000..1f18f529 --- /dev/null +++ b/target/blink/Makefile @@ -0,0 +1,44 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=blink.c +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.ihx blink-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +blink-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o blink-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o blink-flash.ihx $(REL) + +blink-flash.ihx: blink-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/target/blink/blink.c b/target/blink/blink.c new file mode 100644 index 00000000..907c82b8 --- /dev/null +++ b/target/blink/blink.c @@ -0,0 +1,100 @@ +/* + * 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. + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0, j = 0; + + n <<= 1; + while (--n != 0) + while (--j != 0) + while (--i != 0) + nop(); +} + +void +dit() { + P1 = 0xff; + delay(1); + P1 = 0xfd; + delay(1); +} + +void +dah () { + P1 = 0xff; + delay(3); + P1 = 0xfd; + delay(1); +} + +void +charspace () { + delay(2); +} + +void +wordspace () { + delay(8); +} + +#define _ dit(); +#define ___ dah(); +#define C charspace(); +#define W wordspace(); + +main () +{ + CLKCON = 0; + /* Set p1_1 to output */ + P1DIR = 0x02; + P1INP = 0x00; + P2INP = 0x00; + for (;;) { + ___ _ ___ _ C ___ ___ _ ___ W /* cq */ + ___ _ _ C _ W /* de */ + ___ _ ___ C ___ _ _ C /* kd */ + ___ ___ _ _ _ C _ _ _ C /* 7s */ + ___ ___ _ ___ C ___ ___ _ W /* qg */ + } +} diff --git a/target/isr.c b/target/isr.c new file mode 100644 index 00000000..43aedc29 --- /dev/null +++ b/target/isr.c @@ -0,0 +1,90 @@ +/* + * 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. + */ + +void rftxrx_isr (void) __interrupt(0) __using(1) +{ +} + +void adc_isr (void) __interrupt(1) __using(1) +{ +} + +void urx0_isr (void) __interrupt(2) __using(1) +{ +} + +void urx1_isr (void) __interrupt(3) __using(1) +{ +} + +void enc_isr (void) __interrupt(4) __using(1) +{ +} + +void st_isr (void) __interrupt(5) __using(1) +{ +} + +void usb_isr (void) __interrupt(6) __using(1) +{ +} + +void utx0_isr (void) __interrupt(7) __using(1) +{ +} + +void dma_isr (void) __interrupt(8) __using(1) +{ +} + +void t1_isr (void) __interrupt(9) __using(1) +{ +} + +void t2_isr (void) __interrupt(10) __using(1) +{ +} + +void t3_isr (void) __interrupt(11) __using(1) +{ +} + +void t4_isr (void) __interrupt(12) __using(1) +{ +} + +void p0int_isr (void) __interrupt(13) __using(1) +{ +} + +void utx1_isr (void) __interrupt(14) __using(1) +{ +} + +void p1int_isr (void) __interrupt(15) __using(1) +{ +} + +void rf_isr (void) __interrupt(16) __using(1) +{ +} + +void wdt_isr (void) __interrupt(17) __using(1) +{ +} + diff --git a/tests/blink-tiny b/tests/blink-tiny new file mode 100644 index 00000000..fd075e57 --- /dev/null +++ b/tests/blink-tiny @@ -0,0 +1,5 @@ +:03 0000 00 75 FE 02 88 +:03 0003 00 75 90 FF F6 +:02 0006 00 80 FE 7A +:02 0008 00 80 FE 78 +:00 0000 01 FF diff --git a/tests/blink-tiny-ram b/tests/blink-tiny-ram new file mode 100644 index 00000000..018716d5 --- /dev/null +++ b/tests/blink-tiny-ram @@ -0,0 +1,4 @@ +:03 F000 00 75 FE 02 98 +:03 F003 00 75 90 FF 06 +:02 F006 00 80 FE 8A +:00000001FF diff --git a/tests/chip_id b/tests/chip_id new file mode 100644 index 00000000..b3ecf314 --- /dev/null +++ b/tests/chip_id @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_CHIP_ID + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# start reading again + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C D R diff --git a/tests/debug_mode b/tests/debug_mode new file mode 100644 index 00000000..fe25bfef --- /dev/null +++ b/tests/debug_mode @@ -0,0 +1,11 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# + +C D R +. D . +C D . +. D . +C D . +. D R + diff --git a/tests/get_pc b/tests/get_pc new file mode 100644 index 00000000..13bcba15 --- /dev/null +++ b/tests/get_pc @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/tests/get_status b/tests/get_status new file mode 100644 index 00000000..1d4ff03d --- /dev/null +++ b/tests/get_status @@ -0,0 +1,329 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# Halt 0x44 +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# Resume 0x4c +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# Halt 0x44 +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# status +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + diff --git a/tests/half_phase b/tests/half_phase new file mode 100644 index 00000000..3ca4a303 --- /dev/null +++ b/tests/half_phase @@ -0,0 +1,71 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/tests/in b/tests/in new file mode 100644 index 00000000..93341e32 --- /dev/null +++ b/tests/in @@ -0,0 +1,146 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D . + +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R + +# +# Ok, we're in debug mode now +# + +# +# GET_CHIP_ID + +#C . R 0 +#. . R +#C D R 1 +#. D R +#C D R 1 +#. D R +#C . R 0 +#. . R +# +#C D R 1 +#. D R +#C . R 0 +#. . R +#C . R 0 +#. . R +#C . R 0 +#. . R +# +## +## Read the chip id +## +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +#C D R +#. D R +# + +# +# GET_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/tests/p1_1 b/tests/p1_1 new file mode 100644 index 00000000..08d8ab50 --- /dev/null +++ b/tests/p1_1 @@ -0,0 +1,360 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# Halt 0x44 +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0xfe, 0x02 + +# 0x75 0x02 0xfe + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0xfe +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R + +# 0x02 +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0x90, 0xfd +# 0x75 0xfd 0x90 + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0x90 +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# 0xff +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +# +# DEBUG_INSTR +# + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +# MOV 0x90, 0xfd +# 0x75 0xfd 0x90 + +# 0x75 +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# 0x90 +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# 0xfd +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +# status byte + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C D R diff --git a/tests/rd_config b/tests/rd_config new file mode 100644 index 00000000..e2d43f10 --- /dev/null +++ b/tests/rd_config @@ -0,0 +1,55 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# RD_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C D R diff --git a/tests/read_status b/tests/read_status new file mode 100644 index 00000000..3ae46058 --- /dev/null +++ b/tests/read_status @@ -0,0 +1,55 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# READ_STATUS +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C D R 1 +. D R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C - R +. - R +C - R +. - R +C - R +. - R +C - R +. - R + +C D R diff --git a/tests/reset b/tests/reset new file mode 100644 index 00000000..a32c8bec --- /dev/null +++ b/tests/reset @@ -0,0 +1,5 @@ +# reset +C D R +C D R +C D R +C D R diff --git a/tests/wr_config b/tests/wr_config new file mode 100644 index 00000000..1ee31623 --- /dev/null +++ b/tests/wr_config @@ -0,0 +1,116 @@ +# +# Debug mode - drive RESET_N low for two clock cycles +# +C D R +. D . +C D . +. D . +C D . +. D R + +# +# WR_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R + +C D R 1 +. D R +C D R 1 +. D R +C . R 0 +. . R +C D R 1 +. D R + +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + + +# +# RD_CONFIG +# + +C . R 0 +. . R +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R + +C . R 0 +. . R +C D R 1 +. D R +C . R 0 +. . R +C . R 0 +. . R + +# +# Now read for a while +# + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R + +C D R +. D R +C D R +. D R +C D R +. D R +C D R +. D R diff --git a/wr_config b/wr_config deleted file mode 100644 index 1ee31623..00000000 --- a/wr_config +++ /dev/null @@ -1,116 +0,0 @@ -# -# Debug mode - drive RESET_N low for two clock cycles -# -C D R -. D . -C D . -. D . -C D . -. D R - -# -# WR_CONFIG -# - -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R - -C D R 1 -. D R -C D R 1 -. D R -C . R 0 -. . R -C D R 1 -. D R - -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - - -# -# RD_CONFIG -# - -C . R 0 -. . R -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R - -C . R 0 -. . R -C D R 1 -. D R -C . R 0 -. . R -C . R 0 -. . R - -# -# Now read for a while -# - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R - -C D R -. D R -C D R -. D R -C D R -. D R -C D R -. D R -- cgit v1.2.3 From 30f23f23a6db3d12fdc9c088cf6ab47c5e5077fb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Dec 2008 21:13:04 -0800 Subject: Clean up autotools stuff. Signed-off-by: Keith Packard --- .gitignore | 32 +++++++++-------- ccload/.gitignore | 1 + configure.ac | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ target/blink/.gitignore | 13 +++++++ 4 files changed, 127 insertions(+), 14 deletions(-) create mode 100644 ccload/.gitignore create mode 100644 configure.ac create mode 100644 target/blink/.gitignore diff --git a/.gitignore b/.gitignore index 4db91cd2..93d05b7f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,20 @@ -ccdbg -*.ihx -blink-flash -blink-ram *.o +*.a +.deps tags -*.adb -*.asm -*.cdb -*.lnk -*.lst -*.map -*.mem -*.rel -*.rst -*.sym +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.h +config.h.in +config.h.in~ +config.log +config.status +configure +depcomp +install-sh +Makefile.in +missing +stamp-h1 + diff --git a/ccload/.gitignore b/ccload/.gitignore new file mode 100644 index 00000000..3899747a --- /dev/null +++ b/ccload/.gitignore @@ -0,0 +1 @@ +ccload diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..6182d71c --- /dev/null +++ b/configure.ac @@ -0,0 +1,95 @@ +dnl +dnl Copyright © 2008 Keith Packard +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +dnl +dnl Process this file with autoconf to create configure. + +AC_INIT(COPYING) + +AM_INIT_AUTOMAKE(cctools, 0.1) +AM_MAINTAINER_MODE + +dnl ========================================================================== + +AM_CONFIG_HEADER(config.h) + +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_RANLIB + +WARN_CFLAGS="" +if test "x$GCC" = "xyes"; then + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs -fno-strict-aliasing" + AC_DEFINE_UNQUOTED(HAVE_WARNING_CPP_DIRECTIVE,1, + [Can use #warning in C files]) +fi +AC_SUBST(WARN_CFLAGS) + +dnl ========================================================================== + +AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes) + +dnl ========================================================================== + +# Setup for compiling build tools (fc-glyphname, etc) +AC_MSG_CHECKING([for a C compiler for build tools]) +if test $cross_compiling = yes; then + AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc) +else + CC_FOR_BUILD=$CC +fi +AC_MSG_RESULT([$CC_FOR_BUILD]) +AC_SUBST(CC_FOR_BUILD) + +AC_MSG_CHECKING([for suffix of executable build tools]) +if test $cross_compiling = yes; then + cat >conftest.c <<\_______EOF +int +main () +{ + exit (0); +} +_______EOF + for i in .exe ""; do + compile="$CC_FOR_BUILD conftest.c -o conftest$i" + if AC_TRY_EVAL(compile); then + if (./conftest) 2>&AC_FD_CC; then + EXEEXT_FOR_BUILD=$i + break + fi + fi + done + rm -f conftest* + if test "${EXEEXT_FOR_BUILD+set}" != set; then + AC_MSG_ERROR([Cannot determine suffix of executable build tools]) + fi +else + EXEEXT_FOR_BUILD=$EXEEXT +fi +AC_MSG_RESULT([$EXEEXT_FOR_BUILD]) +AC_SUBST(EXEEXT_FOR_BUILD) + +USB_LIBS="-lusb" +AC_SUBST(USB_LIBS) + +AC_OUTPUT([ +Makefile +lib/Makefile +ccload/Makefile +]) diff --git a/target/blink/.gitignore b/target/blink/.gitignore new file mode 100644 index 00000000..40f72de9 --- /dev/null +++ b/target/blink/.gitignore @@ -0,0 +1,13 @@ +*.ihx +*.adb +*.asm +*.cdb +*.lnk +*.lst +*.map +*.mem +*.rel +*.rst +*.sym +blink-flash +blink-ram -- cgit v1.2.3 From f7d49868aeae80d515b12a7e339628f1296754a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 20 Dec 2008 23:30:06 -0800 Subject: Cleanup work; separating out the cp interface to be more abstract. Signed-off-by: Keith Packard --- lib/cccp.c | 12 +++++ lib/ccdbg-command.c | 4 +- lib/ccdbg-flash.c | 34 +++++++------- lib/ccdbg-io.c | 34 +++----------- lib/ccdbg.h | 131 +++++++++++++++++++++++----------------------------- lib/cp-usb.c | 70 +++++++++++++++++----------- 6 files changed, 137 insertions(+), 148 deletions(-) diff --git a/lib/cccp.c b/lib/cccp.c index 99a0d81f..34e866e8 100644 --- a/lib/cccp.c +++ b/lib/cccp.c @@ -98,3 +98,15 @@ cccp_fini(struct ccdbg *dbg) cccp_write(dbg, 0xf, 0xf); dbg->clock = 1; } + +cccp_open() +{ + dbg->fd = open("/dev/ttyUSB0", 2); + if (dbg->fd < 0) { + perror(file); + free(dbg); + return NULL; + } + cccp_init(dbg); + cccp_write(dbg, CC_CLOCK, CC_CLOCK); +} diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c index 38c006cb..30f5094d 100644 --- a/lib/ccdbg-command.c +++ b/lib/ccdbg-command.c @@ -174,9 +174,9 @@ ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image) 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); + ccdbg_debug(CC_DEBUG_EXECUTE, "pc starts at 0x%04x\n", pc); status = ccdbg_resume(dbg); - printf ("resume status: 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_EXECUTE, "resume status: 0x%02x\n", status); return 0; } diff --git a/lib/ccdbg-flash.c b/lib/ccdbg-flash.c index aa2c5187..f950dd1b 100644 --- a/lib/ccdbg-flash.c +++ b/lib/ccdbg-flash.c @@ -112,16 +112,16 @@ ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr) 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); + ccdbg_debug(CC_DEBUG_FLASH, "erase status 0x%02x\n", status); do { status = ccdbg_execute(dbg, flash_read_control); - printf("fctl 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_FLASH, "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]); + ccdbg_debug(CC_DEBUG_FLASH, "0x%02x -> 0x%02x\n", old[i], new[i]); status = ccdbg_execute(dbg, flash_control_clear); - printf("clear fctl 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status); return 0; } #endif @@ -190,22 +190,22 @@ ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2]) 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_debug(CC_DEBUG_FLASH, "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); + ccdbg_debug(CC_DEBUG_FLASH, "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_debug(CC_DEBUG_FLASH, "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]); + ccdbg_debug(CC_DEBUG_FLASH, "0x%02x : 0x%02x\n", data[i], check[i]); return 0; } #endif @@ -231,7 +231,7 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) 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_debug(CC_DEBUG_FLASH, "flash lock 0x%02x -> 0x%02x\n", old[0], new[0]); ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE); return 0; } @@ -270,7 +270,7 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) fwt = 0x20; flash_page[FLASH_TIMING] = fwt; - printf("Upload %d flash program bytes to 0x%04x\n", + ccdbg_debug(CC_DEBUG_FLASH, "Upload %d flash program bytes to 0x%04x\n", sizeof (flash_page), flash_prog); ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page)); @@ -283,10 +283,10 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) offset = ram_addr - (image->address + start); - printf("Upload %d bytes at 0x%04x\n", this_time, ram_addr); + ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr); ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); - printf("Verify %d bytes\n", image->length); + ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes\n", image->length); ccdbg_read_memory(dbg, ram_addr, verify, this_time); if (memcmp (image->data + start, verify, this_time) != 0) { fprintf(stderr, "image verify failed\n"); @@ -308,12 +308,12 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) ccdbg_set_pc(dbg, flash_prog); pc = ccdbg_get_pc(dbg); - printf("Starting flash program at 0x%04x\n", pc); + ccdbg_debug(CC_DEBUG_FLASH, "Starting flash program at 0x%04x\n", pc); status = ccdbg_resume(dbg); - printf("resume status is 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_FLASH, "resume status is 0x%02x\n", status); do { status = ccdbg_read_status(dbg); - printf("chip status is 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_FLASH, "chip status is 0x%02x\n", status); sleep(1); } while ((status & CC_STATUS_CPU_HALTED) == 0); @@ -321,14 +321,14 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) start += this_time; } #if 1 - printf("Downloading flash to check\n"); + ccdbg_debug(CC_DEBUG_FLASH, "Downloading flash to check\n"); struct hex_image *test_image; 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]); + ccdbg_debug(CC_DEBUG_FLASH, "0x%02x : 0x%02x\n", image->data[i], test_image->data[i]); return 1; } return 0; diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index 29476785..6999dbec 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -38,54 +38,32 @@ ccdbg_open(void) perror("calloc"); return NULL; } - dbg->clock = 1; -#ifdef USE_KERNEL - dbg->fd = open("/dev/ttyUSB0", 2); - if (dbg->fd < 0) { - perror(file); - free(dbg); + dbg->cp = cp_usb_open (); + if (!dbg->cp) { + free (dbg); return NULL; } - cccp_init(dbg); - cccp_write(dbg, CC_CLOCK, CC_CLOCK); -#else - cp_usb_init(dbg); -#endif - dbg->clock = 1; return dbg; } void ccdbg_close(struct ccdbg *dbg) { -#if USE_KERNEL - cccp_fini(dbg); - close (dbg->fd); -#else - cp_usb_fini(dbg); -#endif + cp_usb_close(dbg->cp); free (dbg); } int ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) { -#if USE_KERNEL - return cccp_write(dbg, mask, value); -#else - cp_usb_write(dbg, mask, value); + cp_usb_write(dbg->cp, mask, value); return 0; -#endif } uint8_t ccdbg_read(struct ccdbg *dbg) { -#if USE_KERNEL - return cccp_read_all(dbg); -#else - return cp_usb_read(dbg); -#endif + return cp_usb_read(dbg->cp); } static char diff --git a/lib/ccdbg.h b/lib/ccdbg.h index b74d13ca..4d4a648d 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -30,23 +30,14 @@ #include #include #include -#undef USE_KERNEL -#ifdef USE_KERNEL -#include -#define CC_CLOCK CP2101_GPIO_MASK(0) -#define CC_DATA CP2101_GPIO_MASK(1) -#define CC_RESET_N CP2101_GPIO_MASK(2) -#else +#include "cp-usb.h" #define CC_CLOCK 0x1 #define CC_DATA 0x2 #define CC_RESET_N 0x4 -#include -#endif - - -/* painfully slow for now */ -#define CC_CLOCK_US (50) +#define CC_CLOCK_US (40) +/* 8051 instructions + */ #define MOV_direct_data 0x75 #define LJMP 0x02 #define MOV_Rn_data(n) (0x78 | (n)) @@ -54,56 +45,57 @@ #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)) +#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 JB 0x20 + +/* 8051 special function registers + */ + +/* flash controller */ +#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 SLEEP 0xBE + +/* clock controller */ +#define CLKCON 0xC6 +#define CLKCON_OSC32K 0x80 +#define CLKCON_OSC 0x40 +#define CLKCON_TICKSPD 0x38 +#define CLKCON_CLKSPD 0x07 + +/* I/O pins */ +#define P0 0x80 +#define P1 0x90 +#define P2 0xA0 +#define P0DIR 0xFD +#define P1DIR 0xFE +#define P2DIR 0xFF + +/* Bit-addressable accumulator */ +#define ACC(bit) (0xE0 | (bit)) struct ccdbg { - usb_dev_handle *usb_dev; - uint8_t gpio; -#ifdef USE_KERNEL - int fd; -#endif - uint8_t debug_data; - int clock; + struct cp_usb *cp; }; +/* Intel hex file format data + */ struct hex_record { uint8_t length; uint16_t address; @@ -127,8 +119,8 @@ struct hex_image { #define HEX_RECORD_EOF 0x01 #define HEX_RECORD_EXTENDED_ADDRESS 0x02 -#include "cccp.h" - +/* CC1111 debug port commands + */ #define CC_CHIP_ERASE 0x14 #define CC_WR_CONFIG 0x1d @@ -161,9 +153,13 @@ struct hex_image { #define CC_STEP_REPLACE(n) (0x64|(n)) #define CC_GET_CHIP_ID 0x68 +/* Debug levels + */ #define CC_DEBUG_BITBANG 0x00000001 #define CC_DEBUG_COMMAND 0x00000002 #define CC_DEBUG_INSTRUCTIONS 0x00000004 +#define CC_DEBUG_EXECUTE 0x00000008 +#define CC_DEBUG_FLASH 0x00000010 /* ccdbg-command.c */ void @@ -335,17 +331,4 @@ ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offse struct hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length); -/* cp-usb.c */ -void -cp_usb_init(struct ccdbg *dbg); - -void -cp_usb_fini(struct ccdbg *dbg); - -void -cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); - -uint8_t -cp_usb_read(struct ccdbg *dbg); - #endif /* _CCDBG_H_ */ diff --git a/lib/cp-usb.c b/lib/cp-usb.c index 61b684a2..6ab9092c 100644 --- a/lib/cp-usb.c +++ b/lib/cp-usb.c @@ -16,8 +16,20 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ccdbg.h" -#include +/* + * libusb interface to the GPIO pins on a CP2103. + * + * Various magic constants came from the cp210x driver published by silabs. + */ + +#include "cp-usb.h" +#include +#include + +struct cp_usb { + usb_dev_handle *usb_dev; + uint8_t gpio; +}; #define CP2101_UART 0x00 #define UART_ENABLE 0x0001 @@ -26,9 +38,9 @@ #define REQTYPE_DEVICE_TO_HOST 0xc1 static int -cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get) +cp_usb_gpio_get(struct cp_usb *cp, uint8_t *gpio_get) { - return usb_control_msg(dbg->usb_dev, /* dev */ + return usb_control_msg(cp->usb_dev, /* dev */ 0xc0, /* request */ 0xff, /* requesttype */ 0x00c2, /* value */ @@ -39,11 +51,11 @@ cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get) } static int -cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value) +cp_usb_gpio_set(struct cp_usb *cp, uint8_t mask, uint8_t value) { uint16_t gpio_set = ((uint16_t) value << 8) | mask; - return usb_control_msg(dbg->usb_dev, /* dev */ + return usb_control_msg(cp->usb_dev, /* dev */ 0x40, /* request */ 0xff, /* requesttype */ 0x37e1, /* value */ @@ -54,9 +66,9 @@ cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value) } static int -cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable) +cp_usb_uart_enable_disable(struct cp_usb *cp, uint16_t enable) { - return usb_control_msg(dbg->usb_dev, + return usb_control_msg(cp->usb_dev, CP2101_UART, REQTYPE_HOST_TO_DEVICE, enable, @@ -66,9 +78,10 @@ cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable) 300); } -void -cp_usb_init(struct ccdbg *dbg) +struct cp_usb * +cp_usb_open(void) { + struct cp_usb *cp; usb_dev_handle *dev_handle; struct usb_device *dev = NULL; struct usb_bus *bus, *busses; @@ -92,49 +105,52 @@ cp_usb_init(struct ccdbg *dbg) } if (!dev){ perror("No CP2103 found"); - exit(1); + return NULL; } + cp = calloc(sizeof(struct cp_usb), 1); interface = 0; dev_handle = usb_open(dev); usb_detach_kernel_driver_np(dev_handle, interface); usb_claim_interface(dev_handle, interface); - dbg->usb_dev = dev_handle; - ret = cp_usb_uart_enable_disable(dbg, UART_DISABLE); - dbg->gpio = 0xf; - ret = cp_usb_gpio_set(dbg, 0xf, dbg->gpio); - ret = cp_usb_gpio_get(dbg, &gpio); + cp->usb_dev = dev_handle; + ret = cp_usb_uart_enable_disable(cp, UART_DISABLE); + cp->gpio = 0xf; + ret = cp_usb_gpio_set(cp, 0xf, cp->gpio); + ret = cp_usb_gpio_get(cp, &gpio); + return cp; } void -cp_usb_fini(struct ccdbg *dbg) +cp_usb_close(struct cp_usb *cp) { - cp_usb_uart_enable_disable(dbg, UART_DISABLE); - usb_close(dbg->usb_dev); + cp_usb_uart_enable_disable(cp, UART_DISABLE); + usb_close(cp->usb_dev); + free(cp); } void -cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) +cp_usb_write(struct cp_usb *cp, uint8_t mask, uint8_t value) { uint8_t new_gpio; int ret; - new_gpio = (dbg->gpio & ~mask) | (value & mask); - if (new_gpio != dbg->gpio) { - ret = cp_usb_gpio_set(dbg, new_gpio ^ dbg->gpio, new_gpio); + new_gpio = (cp->gpio & ~mask) | (value & mask); + if (new_gpio != cp->gpio) { + ret = cp_usb_gpio_set(cp, new_gpio ^ cp->gpio, new_gpio); if (ret < 0) perror("gpio_set"); - dbg->gpio = new_gpio; + cp->gpio = new_gpio; } } uint8_t -cp_usb_read(struct ccdbg *dbg) +cp_usb_read(struct cp_usb *cp) { int ret; uint8_t gpio; - ret = cp_usb_gpio_get(dbg, &gpio); + ret = cp_usb_gpio_get(cp, &gpio); if (ret < 0) - perror("gpio_set"); + perror("gpio_get"); return gpio; } -- cgit v1.2.3 From e75918f3667a5c8ad294bec4acef6fe81682edf6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Dec 2008 23:33:35 -0800 Subject: Add preliminary version of s51, a UI clone of the 8051 emulator. sdcdb provides source-level debugging using the 8051 emulator, s51. By emulating that emulator a the UI level, we should be able to get source debugging right on our target platform. This is just the preliminary structure for the program with most commands not yet implemented. --- lib/cp-usb.h | 36 +++++++++ s51/Makefile.am | 10 +++ s51/commands | 61 ++++++++++++++ s51/s51-command.c | 171 ++++++++++++++++++++++++++++++++++++++++ s51/s51-main.c | 143 +++++++++++++++++++++++++++++++++ s51/s51-parse.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ s51/s51.h | 78 ++++++++++++++++++ 7 files changed, 731 insertions(+) create mode 100644 lib/cp-usb.h create mode 100644 s51/Makefile.am create mode 100644 s51/commands create mode 100644 s51/s51-command.c create mode 100644 s51/s51-main.c create mode 100644 s51/s51-parse.c create mode 100644 s51/s51.h diff --git a/lib/cp-usb.h b/lib/cp-usb.h new file mode 100644 index 00000000..3e5f25ff --- /dev/null +++ b/lib/cp-usb.h @@ -0,0 +1,36 @@ +/* + * 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 _CP_USB_H_ +#define _CP_USB_H_ +#include + +struct cp_usb * +cp_usb_open(void); + +void +cp_usb_close(struct cp_usb *cp); + +void +cp_usb_write(struct cp_usb *cp, uint8_t mask, uint8_t value); + +uint8_t +cp_usb_read(struct cp_usb *cp); + + +#endif diff --git a/s51/Makefile.am b/s51/Makefile.am new file mode 100644 index 00000000..cfa183d4 --- /dev/null +++ b/s51/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS=s51 + +AM_CFLAGS=-I$(top_srcdir)/lib +S51_LIBS=../lib/libcc.a + +s51_DEPENDENCIES = $(S51_LIBS) + +s51_LDADD=$(S51_LIBS) $(USB_LIBS) + +s51_SOURCES = s51-parse.c s51-command.c s51-main.c diff --git a/s51/commands b/s51/commands new file mode 100644 index 00000000..77a98493 --- /dev/null +++ b/s51/commands @@ -0,0 +1,61 @@ +Listens on port 9756 for a command stream. + +Dump commands: + di - dump imem + ds - dump sprs + dx - dump xaddr + + Returns a string of hex pairs, each preceded by a space, + with 8 pairs per line + +Memory access commands: + set mem + dump + + is one of: + + xram - external ram or external stack + rom - code space + iram - internal ram or stack + sfr - special function register + + + dump + set bit + + bit addressable space + +Set PC: + + pc + + Sets PC to specified address + + pc + + Returns current PC + +Breakpoints + + break + clear + +Load a file + + file "" + +Execution control: + + run - run starting at + run - set temporary bp at + run - continue + next - step over calls(?) + step - step one instruction + + reset - reset the simulator + res - synonym? + +Error messages: + + start with "Error:" + diff --git a/s51/s51-command.c b/s51/s51-command.c new file mode 100644 index 00000000..8a5d4c08 --- /dev/null +++ b/s51/s51-command.c @@ -0,0 +1,171 @@ +/* + * 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 "s51.h" + +static enum command_result +parse_int(char *value, int *result) +{ + char *endptr; + + *result = strtol(value, &endptr, 0); + if (endptr == value) + return command_syntax; + return command_proceed; +} + +static enum command_result +parse_uint16(char *value, uint16_t *uint16) +{ + int v; + enum command_result result; + + result = parse_int(value, &v); + if (result != command_proceed) + return command_error; + if (v < 0 || v > 0xffff) + return command_error; + *uint16 = v; + return command_proceed; +} + +enum command_result +command_quit (FILE *output, int argc, char **argv) +{ + exit(0); + return command_error; +} + +enum command_result +command_di (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_ds (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_dx (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_set (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_dump (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_pc (FILE *output, int argc, char **argv) +{ + uint16_t pc; + if (argv[1]) { + enum command_result result; + + result = parse_uint16(argv[1], &pc); + if (result != command_proceed) + return result; + ccdbg_set_pc(s51_dbg, pc); + } else { + pc = ccdbg_get_pc(s51_dbg); + printf (" 0x%04x\n", pc); + } + return command_proceed; +} + +enum command_result +command_break (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_clear (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_run (FILE *output, int argc, char **argv) +{ + uint16_t start, end; + enum command_result result; + + if (argv[1]) { + result = parse_uint16(argv[1], &start); + if (result != command_proceed) + return result; + if (argv[2]) { + result = parse_uint16(argv[2], &end); + if (result != command_proceed) + return result; + } + ccdbg_set_pc(s51_dbg, start); + } + else + start = ccdbg_get_pc(s51_dbg); + fprintf(output, "Resume at 0x%04x\n", start); + ccdbg_resume(s51_dbg); + return command_proceed; +} + +enum command_result +command_next (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_step (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_load (FILE *output, int argc, char **argv) +{ + return command_error; +} + +enum command_result +command_halt (FILE *output, int argc, char **argv) +{ + uint16_t pc; + ccdbg_halt(s51_dbg); + pc = ccdbg_get_pc(s51_dbg); + fprintf(output, "Halted at 0x%04x\n", pc); + return command_proceed; +} + +enum command_result +command_reset (FILE *output, int argc, char **argv) +{ + ccdbg_debug_mode(s51_dbg); + return command_proceed; +} diff --git a/s51/s51-main.c b/s51/s51-main.c new file mode 100644 index 00000000..e8bf2d7d --- /dev/null +++ b/s51/s51-main.c @@ -0,0 +1,143 @@ +/* + * 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 "s51.h" +#include +#include +#include +#include + +static int s51_port = 0; +static char *cpu = "8051"; +static double freq = 11059200; +char *s51_prompt = "> "; +struct ccdbg *s51_dbg; + +static void +usage(void) +{ + fprintf(stderr, "You're doing it wrong.\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + int flags, opt; + FILE *console_in = stdin; + FILE *console_out = stdout; + char *endptr; + + while ((opt = getopt(argc, argv, "PVvHht:X:c:Z:s:S:p:")) != -1) { + switch (opt) { + case 't': + cpu = optarg; + break; + case 'X': + freq = strtod(optarg, &endptr); + if (endptr == optarg) + usage(); + if (endptr[0] != '\0') { + if (!strcmp(endptr, "k")) + freq *= 1000; + else if (!strcmp(endptr, "M") ) + freq *= 1000000; + else + usage (); + } + break; + case 'c': + break; + case 'Z': + s51_port = strtol(optarg, &endptr, 0); + if (endptr == optarg || strlen(endptr) != 0) + usage(); + break; + case 's': + break; + case 'S': + break; + case 'p': + s51_prompt = optarg; + break; + case 'P': + s51_prompt = NULL; + break; + case 'V': + break; + case 'v': + break; + case 'H': + exit (0); + break; + case 'h': + usage (); + break; + } + } + if (s51_port) { + int l, r, one = 1; + int s; + struct sockaddr_in in; + + l = socket(AF_INET, SOCK_STREAM, 0); + if (l < 0) { + perror ("socket"); + exit(1); + } + in.sin_family = AF_INET; + in.sin_port = htons(s51_port); + in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + r = bind(l, (struct sockaddr *) &in, sizeof (in)); + if (r) { + perror("bind"); + exit(1); + } + r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int)); + if (r) { + perror("setsockopt"); + exit(1); + } + r = listen(l, 5); + if (r) { + perror("listen"); + exit(1); + } + for (;;) { + struct sockaddr_in client_addr; + socklen_t client_len = sizeof (struct sockaddr_in); + FILE *client; + + s = accept(r, (struct sockaddr *) + &client_addr, &client_len); + if (s < 0) { + perror("accept"); + exit(1); + } + client = fdopen(s, "rw"); + if (!client) { + perror("fdopen"); + exit(1); + } + command_read(client, client); + fclose(client); + } + } else + command_read(console_in, console_out); + exit(0); +} diff --git a/s51/s51-parse.c b/s51/s51-parse.c new file mode 100644 index 00000000..ba0d611c --- /dev/null +++ b/s51/s51-parse.c @@ -0,0 +1,232 @@ +/* + * 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 "s51.h" + +struct command_function { + char *name; + char *alias; + enum command_result (*func)(FILE *output, int argc, char **argv); + char *usage; + char *help; +}; + +static struct command_function functions[] = { + { "help", "?", command_help, "help", "Print this list\n" }, + { "quit", "q", command_quit, "[q]uit", "Quit\n" }, + { "di", "di", command_di, "di ", + "Dump imem\n" }, + { "ds", "ds", command_ds, "ds ", + "Dump sprs\n" }, + { "dx", "dx", command_dx, "dx ", + "Dump xaddr\n" }, + { "set", "t", command_set, "se[t] mem ", + "Set mem {xram|rom|iram|sfr} \n" + "set bit \n" }, + { "dump", "d", command_dump, "[d]ump ", + "Dump {xram|rom|iram|sfr} \n" }, + { "pc", "p", command_pc, "[p]c [addr]", + "Get or set pc value\n" }, + { "break", "b", command_break,"[b]reak ", + "Set break point\n" }, + { "clear", "c", command_clear,"[c]lear ", + "Clear break point\n" }, + { "run", "r", command_run, "[r]un [start] [stop]", + "Run with optional start and temp breakpoint addresses\n" }, + { "next", "n", command_next, "[n]ext", + "Step over one instruction, past any call\n" }, + { "step", "s", command_step, "[s]tep", + "Single step\n" }, + { "load", "l", command_load, "[l]oad ", + "Load a hex file into memory or flash" }, + { "halt", "h", command_halt, "[h]alt", + "Halt the processor\n" }, + { "reset","res",command_reset, "[res]et", + "Reset the CPU\n" }, +}; + +#define NUM_FUNCTIONS (sizeof functions / sizeof functions[0]) + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +static int +string_to_int(char *s, int *v) +{ + char *endptr; + + if (isdigit(s[0]) || s[0] == '-' || s[0] == '+') { + *v = strtol(s, &endptr, 0); + if (endptr == s) + return FALSE; + } else if (*s == '\'') { + s++; + if (*s == '\\') { + s++; + switch (*s) { + case 'n': + *v = '\n'; + break; + case 't': + *v = '\t'; + break; + default: + *v = (int) *s; + break; + } + } else + *v = (int) *s; + s++; + if (*s != '\'') + return FALSE; + } + else + return FALSE; + return TRUE; +} + +static struct command_function * +command_string_to_function(char *name) +{ + int i; + for (i = 0; i < NUM_FUNCTIONS; i++) + if (!strcmp(name, functions[i].name) || + !strcmp(name, functions[i].alias)) + return &functions[i]; + return NULL; +} + +static int +command_split_into_words(char *line, char **argv) +{ + char quotechar; + int argc; + + argc = 0; + while (*line) { + while (isspace(*line)) + line++; + if (!*line) + break; + if (*line == '"') { + quotechar = *line++; + *argv++ = line; + argc++; + while (*line && *line != quotechar) + line++; + if (*line) + *line++ = '\0'; + } else { + *argv++ = line; + argc++; + while (*line && !isspace(*line)) + line++; + if (*line) + *line++ = '\0'; + } + } + *argv = 0; + return argc; +} + +enum command_result +command_help(FILE *output, int argc, char **argv) +{ + int i; + struct command_function *func; + + if (argc == 1) { + for (i = 0; i < NUM_FUNCTIONS; i++) + fprintf(output, "%-10s%s\n", functions[i].name, + functions[i].usage); + } else { + for (i = 1; i < argc; i++) { + func = command_string_to_function(argv[i]); + if (!func) { + fprintf(output, "%-10s unknown command\n", argv[i]); + return command_syntax; + } + fprintf(output, "%-10s %s\n%s", func->name, + func->usage, func->help); + } + } + return command_debug; +} + +static void +command_syntax_error(FILE *output, int argc, char **argv) +{ + fprintf(output, "Syntax error in:"); + while (*argv) + fprintf(output, " %s", *argv++); + fprintf(output, "\n"); +} + +void +command_read (FILE *input, FILE *output) +{ + int argc; + char line[1024]; + char *argv[20]; + enum command_result result; + struct command_function *func; + + s51_dbg = ccdbg_open (); + if (!s51_dbg) { + perror("ccdbg_open"); + exit(1); + } + ccdbg_debug_mode(s51_dbg); + fprintf(output, "Welcome to the non-simulated processor\n"); + for (;;) { + if (s51_prompt) + fprintf(output, "%s", s51_prompt); + else + putc('\0', output); + fflush(output); + if (!fgets (line, sizeof line, input)) + break; + argc = command_split_into_words(line, argv); + if (argc > 0) { + func = command_string_to_function(argv[0]); + if (!func) + command_syntax_error(output, argc, argv); + else + { + result = (*func->func)(output, argc, argv); + switch (result) { + case command_syntax: + command_syntax_error(output, argc, argv); + break; + case command_error: + fprintf(output, "Error\n"); + break; + case command_proceed: + break; + default: + break; + } + } + } + } + ccdbg_close(s51_dbg); + fprintf(output, "...\n"); +} + diff --git a/s51/s51.h b/s51/s51.h new file mode 100644 index 00000000..b916acb6 --- /dev/null +++ b/s51/s51.h @@ -0,0 +1,78 @@ +/* + * 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 + +extern char *s51_prompt; + +extern struct ccdbg *s51_dbg; + +enum command_result { + command_proceed, command_debug, command_syntax, command_error +}; + +enum command_result +command_quit (FILE *output, int argc, char **argv); + +enum command_result +command_help (FILE *output, int argc, char **argv); + +enum command_result +command_di (FILE *output, int argc, char **argv); + +enum command_result +command_ds (FILE *output, int argc, char **argv); + +enum command_result +command_dx (FILE *output, int argc, char **argv); + +enum command_result +command_set (FILE *output, int argc, char **argv); + +enum command_result +command_dump (FILE *output, int argc, char **argv); + +enum command_result +command_pc (FILE *output, int argc, char **argv); + +enum command_result +command_break (FILE *output, int argc, char **argv); + +enum command_result +command_clear (FILE *output, int argc, char **argv); + +enum command_result +command_run (FILE *output, int argc, char **argv); + +enum command_result +command_next (FILE *output, int argc, char **argv); + +enum command_result +command_step (FILE *output, int argc, char **argv); + +enum command_result +command_load (FILE *output, int argc, char **argv); + +enum command_result +command_halt (FILE *output, int argc, char **argv); + +enum command_result +command_reset (FILE *output, int argc, char **argv); + +void +command_read (FILE *input, FILE *output); -- cgit v1.2.3 From 55eba4fa08b022197106245d36a70f575a070b0a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Dec 2008 19:10:27 -0800 Subject: Make read_memory debug output use ccdbg_debug. This makes it default to not being presented, which makes s51 much happier Signed-off-by: Keith Packard --- lib/ccdbg-debug.c | 6 ++++++ lib/ccdbg-io.c | 1 + lib/ccdbg-memory.c | 28 ++++++++++++++++++++++------ lib/ccdbg.h | 4 ++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/ccdbg-debug.c b/lib/ccdbg-debug.c index 2e67bc8d..8f6f9e11 100644 --- a/lib/ccdbg-debug.c +++ b/lib/ccdbg-debug.c @@ -45,3 +45,9 @@ ccdbg_debug(int level, char *format, ...) va_end(ap); } } + +void +ccdbg_flush(void) +{ + fflush(stdout); +} diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index 6999dbec..5ecea769 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -129,6 +129,7 @@ ccdbg_recv_bit(struct ccdbg *dbg, int first) ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); read = ccdbg_read(dbg); + ccdbg_print("#\t%c %c %c\n", CC_DATA, read); ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); return (read & CC_DATA) ? 1 : 0; } diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c index 105295db..3406a1b1 100644 --- a/lib/ccdbg-memory.c +++ b/lib/ccdbg-memory.c @@ -54,10 +54,18 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) 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 ((i & 0xf) == 0xf) { + ccdbg_debug(CC_DEBUG_MEMORY, "."); + ccdbg_flush(); + nl = 1; + } + if ((i & 0xff) == 0xff) { + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); + nl = 0; + } } - if (nl) printf ("\n"); + if (nl) + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; } @@ -70,10 +78,18 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) (void) ccdbg_execute(dbg, memory_init); 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 ((i & 0xf) == 0xf) { + ccdbg_debug(CC_DEBUG_MEMORY, "."); + ccdbg_flush(); + nl = 1; + } + if ((i & 0xff) == 0xff) { + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); + nl = 0; + } } - if (nl) printf ("\n"); + if (nl) + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; } diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 4d4a648d..e0e58104 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -160,6 +160,7 @@ struct hex_image { #define CC_DEBUG_INSTRUCTIONS 0x00000004 #define CC_DEBUG_EXECUTE 0x00000008 #define CC_DEBUG_FLASH 0x00000010 +#define CC_DEBUG_MEMORY 0x00000020 /* ccdbg-command.c */ void @@ -223,6 +224,9 @@ ccdbg_add_debug(int level); void ccdbg_clear_debug(int level); +void +ccdbg_flush(void); + /* ccdbg-flash.c */ uint8_t ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image); -- cgit v1.2.3 From 4c4093c3fdd309123fdd068c0e1ff4947104492d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Dec 2008 19:11:56 -0800 Subject: Add more commands to s51 assembly-language debugger Signed-off-by: Keith Packard --- Makefile.am | 2 +- configure.ac | 1 + s51/.gitignore | 1 + s51/s51-command.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- s51/s51-main.c | 27 ++++--- s51/s51-parse.c | 2 + s51/s51.h | 6 ++ 7 files changed, 234 insertions(+), 21 deletions(-) create mode 100644 s51/.gitignore diff --git a/Makefile.am b/Makefile.am index 71aee980..11b0b700 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ccload target/blink +SUBDIRS=lib ccload s51 target/blink diff --git a/configure.ac b/configure.ac index 6182d71c..a14c802b 100644 --- a/configure.ac +++ b/configure.ac @@ -92,4 +92,5 @@ AC_OUTPUT([ Makefile lib/Makefile ccload/Makefile +s51/Makefile ]) diff --git a/s51/.gitignore b/s51/.gitignore new file mode 100644 index 00000000..cb909cf0 --- /dev/null +++ b/s51/.gitignore @@ -0,0 +1 @@ +s51 diff --git a/s51/s51-command.c b/s51/s51-command.c index 8a5d4c08..278bca25 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -51,22 +51,85 @@ command_quit (FILE *output, int argc, char **argv) return command_error; } +static void +dump_bytes(FILE *output, uint8_t *memory, int length, uint16_t start) +{ + int group, i; + + for (group = 0; group < length; group += 8) { + fprintf(output, "0x%04x ", start + group); + for (i = group; i < length && i < group + 8; i++) + fprintf(output, "%02x ", memory[i]); + for (; i < group + 8; i++) + fprintf(output, " "); + for (i = group; i < length && i < group + 8; i++) { + if (isascii(memory[i]) && isprint(memory[i])) + fprintf(output, "%c", memory[i]); + else + fprintf(output, "."); + } + fprintf(output, "\n"); + } +} + enum command_result command_di (FILE *output, int argc, char **argv) { - return command_error; + uint16_t start, end; + uint8_t memory[65536]; + uint8_t status; + int length; + + if (argc != 3) + return command_error; + if (parse_uint16(argv[1], &start) != command_proceed) + return command_error; + if (parse_uint16(argv[2], &end) != command_proceed) + return command_error; + length = (int) end - (int) start + 1; + status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length); + dump_bytes(output, memory, length, start); + return command_proceed; } enum command_result command_ds (FILE *output, int argc, char **argv) { - return command_error; + uint16_t start, end; + uint8_t memory[65536]; + uint8_t status; + int length; + + if (argc != 3) + return command_error; + if (parse_uint16(argv[1], &start) != command_proceed) + return command_error; + if (parse_uint16(argv[2], &end) != command_proceed) + return command_error; + length = (int) end - (int) start + 1; + status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length); + dump_bytes(output, memory, length, start); + return command_proceed; } enum command_result command_dx (FILE *output, int argc, char **argv) { - return command_error; + uint16_t start, end; + uint8_t memory[65536]; + uint8_t status; + int length; + + if (argc != 3) + return command_error; + if (parse_uint16(argv[1], &start) != command_proceed) + return command_error; + if (parse_uint16(argv[2], &end) != command_proceed) + return command_error; + length = (int) end - (int) start + 1; + status = ccdbg_read_memory(s51_dbg, start, memory, length); + dump_bytes(output, memory, length, start); + return command_proceed; } enum command_result @@ -87,7 +150,6 @@ command_pc (FILE *output, int argc, char **argv) uint16_t pc; if (argv[1]) { enum command_result result; - result = parse_uint16(argv[1], &pc); if (result != command_proceed) return result; @@ -99,16 +161,104 @@ command_pc (FILE *output, int argc, char **argv) return command_proceed; } +struct cc_break { + int enabled; + int temporary; + uint16_t address; +}; + +#define CC_NUM_BREAKPOINTS 4 + +static struct cc_break breakpoints[CC_NUM_BREAKPOINTS]; + +enum command_result +set_breakpoint(FILE *output, uint16_t address, int temporary) +{ + int b; + uint8_t status; + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) { + if (breakpoints[b].enabled == 0) + break; + if (breakpoints[b].address == address) + break; + } + if (b == CC_NUM_BREAKPOINTS) { + fprintf(output, "Error: too many breakpoints requested\n"); + return command_proceed; + } + if (breakpoints[b].enabled == 0) { + breakpoints[b].address = address; + status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, address); + fprintf(output, "set_hw_brkpnt status 0x%02x\n", status); + } + ++breakpoints[b].enabled; + fprintf(output, "Breakpoint %d at 0x%04x\n", b, address); + breakpoints[b].temporary += temporary; + return command_proceed; +} + +enum command_result +clear_breakpoint(FILE *output, uint16_t address, int temporary) +{ + int b; + uint8_t status; + + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) { + if (breakpoints[b].enabled != 0 && + ((breakpoints[b].temporary != 0) == (temporary != 0)) && + breakpoints[b].address == address) + break; + } + if (b == CC_NUM_BREAKPOINTS) { + fprintf(output, "Error: no matching breakpoint found\n"); + return command_proceed; + } + --breakpoints[b].enabled; + --breakpoints[b].temporary; + if (breakpoints[b].enabled == 0) { + breakpoints[b].address = -1; + ccdbg_set_hw_brkpnt(s51_dbg, b, 0, address); + fprintf(output, "set_hw_brkpnt status 0x%02x\n", status); + } + return command_proceed; +} + enum command_result command_break (FILE *output, int argc, char **argv) { - return command_error; + int b; + uint16_t address; + enum command_result result; + + if (argc == 1) { + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) + if (breakpoints[b].enabled) + fprintf(output, "Breakpoint %d 0x%04x\n", + b, breakpoints[b].address); + return command_proceed; + } + if (argc != 2) + return command_error; + result = parse_uint16(argv[1], &address); + if (result != command_proceed) + return result; + + return set_breakpoint(output, address, 0); } enum command_result command_clear (FILE *output, int argc, char **argv) { - return command_error; + int b; + uint16_t address; + enum command_result result; + + if (argc != 2) + return command_error; + result = parse_uint16(argv[1], &address); + if (result != command_proceed) + return result; + return clear_breakpoint(output, address, 0); } enum command_result @@ -132,19 +282,29 @@ command_run (FILE *output, int argc, char **argv) start = ccdbg_get_pc(s51_dbg); fprintf(output, "Resume at 0x%04x\n", start); ccdbg_resume(s51_dbg); +// cc_wait(s51_dbg); return command_proceed; } enum command_result command_next (FILE *output, int argc, char **argv) { - return command_error; + return command_step(output, argc, argv); } enum command_result command_step (FILE *output, int argc, char **argv) { - return command_error; + uint16_t pc; + uint8_t opcode; + uint8_t a; + + a = ccdbg_step_instr(s51_dbg); + fprintf(output, " ACC= 0x%02x\n", a); + pc = ccdbg_get_pc(s51_dbg); + ccdbg_read_memory(s51_dbg, pc, &opcode, 1); + fprintf(output, " ? 0x%04x %02x\n", pc, opcode); + return command_proceed; } enum command_result @@ -169,3 +329,43 @@ command_reset (FILE *output, int argc, char **argv) ccdbg_debug_mode(s51_dbg); return command_proceed; } + +enum command_result +command_status(FILE *output, int argc, char **argv) +{ + uint8_t status; + + status = ccdbg_read_status(s51_dbg); + if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0) + fprintf(output, "\tChip erase in progress\n"); + if (status & CC_STATUS_PCON_IDLE) + fprintf(output, "\tCPU is idle (clock gated)\n"); + if (status & CC_STATUS_CPU_HALTED) + fprintf(output, "\tCPU halted\n"); + else + fprintf(output, "\tCPU running\n"); + if ((status & CC_STATUS_POWER_MODE_0) == 0) + fprintf(output, "\tPower Mode 1-3 selected\n"); + if (status & CC_STATUS_HALT_STATUS) + fprintf(output, "\tHalted by software or hw breakpoint\n"); + else + fprintf(output, "\tHalted by debug command\n"); + if (status & CC_STATUS_DEBUG_LOCKED) + fprintf(output, "\tDebug interface is locked\n"); + if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0) + fprintf(output, "\tOscillators are not stable\n"); + if (status & CC_STATUS_STACK_OVERFLOW) + fprintf(output, "\tStack overflow\n"); + return command_proceed; +} + +uint8_t cc_wait(struct ccdbg *dbg) +{ + uint8_t status; + for(;;) { + status = ccdbg_read_status(dbg); + if (status & CC_STATUS_CPU_HALTED) + break; + } + return status; +} diff --git a/s51/s51-main.c b/s51/s51-main.c index e8bf2d7d..9a5ca7c2 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -43,7 +43,7 @@ main(int argc, char **argv) FILE *console_out = stdout; char *endptr; - while ((opt = getopt(argc, argv, "PVvHht:X:c:Z:s:S:p:")) != -1) { + while ((opt = getopt(argc, argv, "PVvHht:X:c:r:Z:s:S:p:")) != -1) { switch (opt) { case 't': cpu = optarg; @@ -63,6 +63,7 @@ main(int argc, char **argv) break; case 'c': break; + case 'r': case 'Z': s51_port = strtol(optarg, &endptr, 0); if (endptr == optarg || strlen(endptr) != 0) @@ -100,6 +101,11 @@ main(int argc, char **argv) perror ("socket"); exit(1); } + r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int)); + if (r) { + perror("setsockopt"); + exit(1); + } in.sin_family = AF_INET; in.sin_port = htons(s51_port); in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -108,11 +114,6 @@ main(int argc, char **argv) perror("bind"); exit(1); } - r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int)); - if (r) { - perror("setsockopt"); - exit(1); - } r = listen(l, 5); if (r) { perror("listen"); @@ -121,21 +122,23 @@ main(int argc, char **argv) for (;;) { struct sockaddr_in client_addr; socklen_t client_len = sizeof (struct sockaddr_in); - FILE *client; + FILE *client_in, *client_out; - s = accept(r, (struct sockaddr *) + s = accept(l, (struct sockaddr *) &client_addr, &client_len); if (s < 0) { perror("accept"); exit(1); } - client = fdopen(s, "rw"); - if (!client) { + client_in = fdopen(s, "r"); + client_out = fdopen(s, "w"); + if (!client_in || !client_out) { perror("fdopen"); exit(1); } - command_read(client, client); - fclose(client); + command_read(client_in, client_out); + fclose(client_in); + fclose(client_out); } } else command_read(console_in, console_out); diff --git a/s51/s51-parse.c b/s51/s51-parse.c index ba0d611c..56a63e24 100644 --- a/s51/s51-parse.c +++ b/s51/s51-parse.c @@ -58,6 +58,8 @@ static struct command_function functions[] = { "Halt the processor\n" }, { "reset","res",command_reset, "[res]et", "Reset the CPU\n" }, + { "status","status",command_status, "status", + "Display CC1111 debug status\n" }, }; #define NUM_FUNCTIONS (sizeof functions / sizeof functions[0]) diff --git a/s51/s51.h b/s51/s51.h index b916acb6..3ca4734c 100644 --- a/s51/s51.h +++ b/s51/s51.h @@ -74,5 +74,11 @@ command_halt (FILE *output, int argc, char **argv); enum command_result command_reset (FILE *output, int argc, char **argv); +enum command_result +command_status (FILE *output, int argc, char **argv); + +uint8_t +cc_wait(struct ccdbg *dbg); + void command_read (FILE *input, FILE *output); -- cgit v1.2.3 From d2d9cfd74fd66836c913c02276e09136d83b35dc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 26 Dec 2008 17:58:48 -0800 Subject: s51: add breakpoints and the ability to block awaiting a breakpoint. Signed-off-by: Keith Packard --- s51/s51-command.c | 287 +++++++++++++++++++++++++++++++++++++----------------- s51/s51-main.c | 97 +++++++++++++++--- s51/s51-parse.c | 51 +++++----- s51/s51.h | 59 ++++++----- 4 files changed, 347 insertions(+), 147 deletions(-) diff --git a/s51/s51-command.c b/s51/s51-command.c index 278bca25..7538a94a 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -26,7 +26,7 @@ parse_int(char *value, int *result) *result = strtol(value, &endptr, 0); if (endptr == value) return command_syntax; - return command_proceed; + return command_success; } static enum command_result @@ -36,44 +36,44 @@ parse_uint16(char *value, uint16_t *uint16) enum command_result result; result = parse_int(value, &v); - if (result != command_proceed) + if (result != command_success) return command_error; if (v < 0 || v > 0xffff) return command_error; *uint16 = v; - return command_proceed; + return command_success; } enum command_result -command_quit (FILE *output, int argc, char **argv) +command_quit (int argc, char **argv) { exit(0); return command_error; } static void -dump_bytes(FILE *output, uint8_t *memory, int length, uint16_t start) +dump_bytes(uint8_t *memory, int length, uint16_t start) { int group, i; for (group = 0; group < length; group += 8) { - fprintf(output, "0x%04x ", start + group); + s51_printf("0x%04x ", start + group); for (i = group; i < length && i < group + 8; i++) - fprintf(output, "%02x ", memory[i]); + s51_printf("%02x ", memory[i]); for (; i < group + 8; i++) - fprintf(output, " "); + s51_printf(" "); for (i = group; i < length && i < group + 8; i++) { if (isascii(memory[i]) && isprint(memory[i])) - fprintf(output, "%c", memory[i]); + s51_printf("%c", memory[i]); else - fprintf(output, "."); + s51_printf("."); } - fprintf(output, "\n"); + s51_printf("\n"); } } enum command_result -command_di (FILE *output, int argc, char **argv) +command_di (int argc, char **argv) { uint16_t start, end; uint8_t memory[65536]; @@ -82,18 +82,18 @@ command_di (FILE *output, int argc, char **argv) if (argc != 3) return command_error; - if (parse_uint16(argv[1], &start) != command_proceed) + if (parse_uint16(argv[1], &start) != command_success) return command_error; - if (parse_uint16(argv[2], &end) != command_proceed) + if (parse_uint16(argv[2], &end) != command_success) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length); - dump_bytes(output, memory, length, start); - return command_proceed; + dump_bytes(memory, length, start); + return command_success; } enum command_result -command_ds (FILE *output, int argc, char **argv) +command_ds (int argc, char **argv) { uint16_t start, end; uint8_t memory[65536]; @@ -102,18 +102,18 @@ command_ds (FILE *output, int argc, char **argv) if (argc != 3) return command_error; - if (parse_uint16(argv[1], &start) != command_proceed) + if (parse_uint16(argv[1], &start) != command_success) return command_error; - if (parse_uint16(argv[2], &end) != command_proceed) + if (parse_uint16(argv[2], &end) != command_success) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length); - dump_bytes(output, memory, length, start); - return command_proceed; + dump_bytes(memory, length, start); + return command_success; } enum command_result -command_dx (FILE *output, int argc, char **argv) +command_dx (int argc, char **argv) { uint16_t start, end; uint8_t memory[65536]; @@ -122,43 +122,52 @@ command_dx (FILE *output, int argc, char **argv) if (argc != 3) return command_error; - if (parse_uint16(argv[1], &start) != command_proceed) + if (parse_uint16(argv[1], &start) != command_success) return command_error; - if (parse_uint16(argv[2], &end) != command_proceed) + if (parse_uint16(argv[2], &end) != command_success) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_memory(s51_dbg, start, memory, length); - dump_bytes(output, memory, length, start); - return command_proceed; + dump_bytes(memory, length, start); + return command_success; } enum command_result -command_set (FILE *output, int argc, char **argv) +command_set (int argc, char **argv) { return command_error; } enum command_result -command_dump (FILE *output, int argc, char **argv) +command_dump (int argc, char **argv) { return command_error; } enum command_result -command_pc (FILE *output, int argc, char **argv) +command_file (int argc, char **argv) +{ + if (argc != 2) + return command_error; + s51_printf("some words read from %s\n", argv[1]); + return command_success; +} + +enum command_result +command_pc (int argc, char **argv) { uint16_t pc; if (argv[1]) { enum command_result result; result = parse_uint16(argv[1], &pc); - if (result != command_proceed) + if (result != command_success) return result; ccdbg_set_pc(s51_dbg, pc); } else { pc = ccdbg_get_pc(s51_dbg); - printf (" 0x%04x\n", pc); + s51_printf(" 0x%04x 00\n", pc); } - return command_proceed; + return command_success; } struct cc_break { @@ -171,8 +180,28 @@ struct cc_break { static struct cc_break breakpoints[CC_NUM_BREAKPOINTS]; +static void +disable_breakpoint(int b) +{ + uint8_t status; + + status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address); + if (status != 0x00 && status != 0xff) + s51_printf("disable_breakpoint status 0x%02x\n", status); +} + +static void +enable_breakpoint(int b) +{ + uint8_t status; + + status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address); + if (status != 0xff) + s51_printf("enable_breakpoint status 0x%02x\n", status); +} + enum command_result -set_breakpoint(FILE *output, uint16_t address, int temporary) +set_breakpoint(uint16_t address, int temporary) { int b; uint8_t status; @@ -183,22 +212,21 @@ set_breakpoint(FILE *output, uint16_t address, int temporary) break; } if (b == CC_NUM_BREAKPOINTS) { - fprintf(output, "Error: too many breakpoints requested\n"); - return command_proceed; + s51_printf("Error: too many breakpoints requested\n"); + return command_success; } if (breakpoints[b].enabled == 0) { breakpoints[b].address = address; - status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, address); - fprintf(output, "set_hw_brkpnt status 0x%02x\n", status); + enable_breakpoint(b); } ++breakpoints[b].enabled; - fprintf(output, "Breakpoint %d at 0x%04x\n", b, address); + s51_printf("Breakpoint %d at 0x%04x\n", b, address); breakpoints[b].temporary += temporary; - return command_proceed; + return command_success; } enum command_result -clear_breakpoint(FILE *output, uint16_t address, int temporary) +clear_breakpoint(uint16_t address, int temporary) { int b; uint8_t status; @@ -210,21 +238,35 @@ clear_breakpoint(FILE *output, uint16_t address, int temporary) break; } if (b == CC_NUM_BREAKPOINTS) { - fprintf(output, "Error: no matching breakpoint found\n"); - return command_proceed; + s51_printf("Error: no matching breakpoint found\n"); + return command_success; } --breakpoints[b].enabled; - --breakpoints[b].temporary; + breakpoints[b].temporary -= temporary; if (breakpoints[b].enabled == 0) { + disable_breakpoint(b); breakpoints[b].address = -1; - ccdbg_set_hw_brkpnt(s51_dbg, b, 0, address); - fprintf(output, "set_hw_brkpnt status 0x%02x\n", status); } - return command_proceed; + return command_success; +} + + +int +find_breakpoint(uint16_t address) +{ + int b; + + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) + if (breakpoints[b].enabled && breakpoints[b].address == address) + break; + if (b == CC_NUM_BREAKPOINTS) + return -1; + if (breakpoints[b].temporary) + clear_breakpoint(address, 1); } enum command_result -command_break (FILE *output, int argc, char **argv) +command_break (int argc, char **argv) { int b; uint16_t address; @@ -233,21 +275,21 @@ command_break (FILE *output, int argc, char **argv) if (argc == 1) { for (b = 0; b < CC_NUM_BREAKPOINTS; b++) if (breakpoints[b].enabled) - fprintf(output, "Breakpoint %d 0x%04x\n", + s51_printf("Breakpoint %d 0x%04x\n", b, breakpoints[b].address); - return command_proceed; + return command_success; } if (argc != 2) return command_error; result = parse_uint16(argv[1], &address); - if (result != command_proceed) + if (result != command_success) return result; - return set_breakpoint(output, address, 0); + return set_breakpoint(address, 0); } enum command_result -command_clear (FILE *output, int argc, char **argv) +command_clear (int argc, char **argv) { int b; uint16_t address; @@ -256,116 +298,179 @@ command_clear (FILE *output, int argc, char **argv) if (argc != 2) return command_error; result = parse_uint16(argv[1], &address); - if (result != command_proceed) + if (result != command_success) return result; - return clear_breakpoint(output, address, 0); + return clear_breakpoint(address, 0); +} + +void +cc_stopped(uint8_t status) +{ + uint16_t pc; + int b; + int code; + char *reason; + + pc = ccdbg_get_pc(s51_dbg); + if (status & CC_STATUS_CPU_HALTED) { + if ((status & CC_STATUS_HALT_STATUS) != 0) { + pc = pc - 1; + code = 104; + reason = "Breakpoint"; + ccdbg_set_pc(s51_dbg, pc); + } else { + code = 105; + reason = "Interrupt"; + } + s51_printf("Stop at 0x%04x: (%d) %s\n", + pc, code, reason); + } +} + +uint8_t +cc_step(uint16_t pc) +{ + int b; + uint8_t status; + + b = find_breakpoint(pc); + if (b != -1) + disable_breakpoint(b); + status = ccdbg_step_instr(s51_dbg); + if (b != -1) + enable_breakpoint(b); + return status; } enum command_result -command_run (FILE *output, int argc, char **argv) +command_run (int argc, char **argv) { uint16_t start, end; enum command_result result; + uint16_t pc; + uint8_t status; + int b; if (argv[1]) { result = parse_uint16(argv[1], &start); - if (result != command_proceed) + if (result != command_success) return result; if (argv[2]) { result = parse_uint16(argv[2], &end); - if (result != command_proceed) + if (result != command_success) return result; } ccdbg_set_pc(s51_dbg, start); } else start = ccdbg_get_pc(s51_dbg); - fprintf(output, "Resume at 0x%04x\n", start); + s51_printf("Resume at 0x%04x\n", start); + pc = start; + b = find_breakpoint(pc); + if (b != -1) { + cc_step(pc); + pc = ccdbg_get_pc(s51_dbg); + if (find_breakpoint(pc) != -1) { + status = ccdbg_read_status(s51_dbg); + cc_stopped(status); + return command_success; + } + } ccdbg_resume(s51_dbg); -// cc_wait(s51_dbg); - return command_proceed; + result = cc_wait(); + return result; } enum command_result -command_next (FILE *output, int argc, char **argv) +command_next (int argc, char **argv) { - return command_step(output, argc, argv); + return command_step(argc, argv); } enum command_result -command_step (FILE *output, int argc, char **argv) +command_step (int argc, char **argv) { uint16_t pc; uint8_t opcode; uint8_t a; - a = ccdbg_step_instr(s51_dbg); - fprintf(output, " ACC= 0x%02x\n", a); + a = cc_step(ccdbg_get_pc(s51_dbg)); + s51_printf(" ACC= 0x%02x\n", a); pc = ccdbg_get_pc(s51_dbg); ccdbg_read_memory(s51_dbg, pc, &opcode, 1); - fprintf(output, " ? 0x%04x %02x\n", pc, opcode); - return command_proceed; + s51_printf(" ? 0x%04x %02x\n", pc, opcode); + return command_success; } enum command_result -command_load (FILE *output, int argc, char **argv) +command_load (int argc, char **argv) { return command_error; } enum command_result -command_halt (FILE *output, int argc, char **argv) +command_halt (int argc, char **argv) { uint16_t pc; ccdbg_halt(s51_dbg); pc = ccdbg_get_pc(s51_dbg); - fprintf(output, "Halted at 0x%04x\n", pc); - return command_proceed; + s51_printf("Halted at 0x%04x\n", pc); + return command_success; } enum command_result -command_reset (FILE *output, int argc, char **argv) +command_reset (int argc, char **argv) { ccdbg_debug_mode(s51_dbg); - return command_proceed; + return command_success; } enum command_result -command_status(FILE *output, int argc, char **argv) +command_status(int argc, char **argv) { uint8_t status; status = ccdbg_read_status(s51_dbg); if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0) - fprintf(output, "\tChip erase in progress\n"); + s51_printf("\tChip erase in progress\n"); if (status & CC_STATUS_PCON_IDLE) - fprintf(output, "\tCPU is idle (clock gated)\n"); + s51_printf("\tCPU is idle (clock gated)\n"); if (status & CC_STATUS_CPU_HALTED) - fprintf(output, "\tCPU halted\n"); + s51_printf("\tCPU halted\n"); else - fprintf(output, "\tCPU running\n"); + s51_printf("\tCPU running\n"); if ((status & CC_STATUS_POWER_MODE_0) == 0) - fprintf(output, "\tPower Mode 1-3 selected\n"); + s51_printf("\tPower Mode 1-3 selected\n"); if (status & CC_STATUS_HALT_STATUS) - fprintf(output, "\tHalted by software or hw breakpoint\n"); + s51_printf("\tHalted by software or hw breakpoint\n"); else - fprintf(output, "\tHalted by debug command\n"); + s51_printf("\tHalted by debug command\n"); if (status & CC_STATUS_DEBUG_LOCKED) - fprintf(output, "\tDebug interface is locked\n"); + s51_printf("\tDebug interface is locked\n"); if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0) - fprintf(output, "\tOscillators are not stable\n"); + s51_printf("\tOscillators are not stable\n"); if (status & CC_STATUS_STACK_OVERFLOW) - fprintf(output, "\tStack overflow\n"); - return command_proceed; + s51_printf("\tStack overflow\n"); + return command_success; } -uint8_t cc_wait(struct ccdbg *dbg) +enum command_result +cc_wait(void) { - uint8_t status; for(;;) { - status = ccdbg_read_status(dbg); - if (status & CC_STATUS_CPU_HALTED) - break; + uint8_t status; + status = ccdbg_read_status(s51_dbg); + if (status & CC_STATUS_CPU_HALTED) { + cc_stopped(status); + return command_success; + } + if (s51_interrupted || s51_check_input()) { + + ccdbg_halt(s51_dbg); + status = ccdbg_read_status(s51_dbg); + cc_stopped(status); + return command_interrupt; + } } - return status; } + diff --git a/s51/s51-main.c b/s51/s51-main.c index 9a5ca7c2..28a774d2 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -21,12 +21,19 @@ #include #include #include +#include +#include +#include static int s51_port = 0; static char *cpu = "8051"; static double freq = 11059200; char *s51_prompt = "> "; struct ccdbg *s51_dbg; +int s51_interrupted = 0; + +static FILE *s51_input; +static FILE *s51_output; static void usage(void) @@ -35,13 +42,17 @@ usage(void) exit(1); } +void s51_sigint() +{ + s51_interrupted = 1; +} + int main(int argc, char **argv) { int flags, opt; - FILE *console_in = stdin; - FILE *console_out = stdout; char *endptr; + struct sigvec vec, ovec; while ((opt = getopt(argc, argv, "PVvHht:X:c:r:Z:s:S:p:")) != -1) { switch (opt) { @@ -122,7 +133,6 @@ main(int argc, char **argv) for (;;) { struct sockaddr_in client_addr; socklen_t client_len = sizeof (struct sockaddr_in); - FILE *client_in, *client_out; s = accept(l, (struct sockaddr *) &client_addr, &client_len); @@ -130,17 +140,82 @@ main(int argc, char **argv) perror("accept"); exit(1); } - client_in = fdopen(s, "r"); - client_out = fdopen(s, "w"); - if (!client_in || !client_out) { + s51_input = fdopen(s, "r"); + s51_output = fdopen(s, "w"); + if (!s51_input || !s51_output) { perror("fdopen"); exit(1); } - command_read(client_in, client_out); - fclose(client_in); - fclose(client_out); + vec.sv_handler = s51_sigint; + vec.sv_mask = 0; + vec.sv_flags = 0; + sigvec(SIGINT, &vec, &ovec); + command_read(); + sigvec(SIGINT, &ovec, NULL); + fclose(s51_input); + fclose(s51_output); } - } else - command_read(console_in, console_out); + } else { + s51_input = stdin; + s51_output = stdout; + vec.sv_handler = s51_sigint; + vec.sv_mask = 0; + vec.sv_flags = 0; + sigvec(SIGINT, &vec, &ovec); + command_read(); + } exit(0); } + +void +s51_printf(char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(s51_output, format, ap); + if (s51_port) + vfprintf(stdout, format, ap); + va_end(ap); +} + +void +s51_putc(int c) +{ + putc(c, s51_output); +} + +int +s51_read_line(char *line, int len) +{ + int ret; + if (s51_prompt) + s51_printf("%s", s51_prompt); + else + s51_putc('\0'); + fflush(s51_output); + ret = fgets(line, len, s51_input) != NULL; + if (s51_port) + printf("> %s", line); + fflush(stdout); + return ret; +} + +int +s51_check_input(void) +{ + struct pollfd input; + int r; + int c; + + input.fd = fileno(s51_input); + input.events = POLLIN; + r = poll(&input, 1, 0); + if (r > 0) { + char line[256]; + (void) s51_read_line(line, sizeof (line)); + return 1; + } + return 0; +} + diff --git a/s51/s51-parse.c b/s51/s51-parse.c index 56a63e24..d0bfb45b 100644 --- a/s51/s51-parse.c +++ b/s51/s51-parse.c @@ -21,7 +21,7 @@ struct command_function { char *name; char *alias; - enum command_result (*func)(FILE *output, int argc, char **argv); + enum command_result (*func)(int argc, char **argv); char *usage; char *help; }; @@ -40,6 +40,8 @@ static struct command_function functions[] = { "set bit \n" }, { "dump", "d", command_dump, "[d]ump ", "Dump {xram|rom|iram|sfr} \n" }, + { "file", "file", command_file, "file ", + "Pretend to load executable from \n" }, { "pc", "p", command_pc, "[p]c [addr]", "Get or set pc value\n" }, { "break", "b", command_break,"[b]reak ", @@ -149,23 +151,23 @@ command_split_into_words(char *line, char **argv) } enum command_result -command_help(FILE *output, int argc, char **argv) +command_help(int argc, char **argv) { int i; struct command_function *func; if (argc == 1) { for (i = 0; i < NUM_FUNCTIONS; i++) - fprintf(output, "%-10s%s\n", functions[i].name, + s51_printf("%-10s%s\n", functions[i].name, functions[i].usage); } else { for (i = 1; i < argc; i++) { func = command_string_to_function(argv[i]); if (!func) { - fprintf(output, "%-10s unknown command\n", argv[i]); + s51_printf("%-10s unknown command\n", argv[i]); return command_syntax; } - fprintf(output, "%-10s %s\n%s", func->name, + s51_printf("%-10s %s\n%s", func->name, func->usage, func->help); } } @@ -173,16 +175,16 @@ command_help(FILE *output, int argc, char **argv) } static void -command_syntax_error(FILE *output, int argc, char **argv) +command_syntax_error(int argc, char **argv) { - fprintf(output, "Syntax error in:"); + s51_printf("Syntax error in:"); while (*argv) - fprintf(output, " %s", *argv++); - fprintf(output, "\n"); + s51_printf(" %s", *argv++); + s51_printf("\n"); } void -command_read (FILE *input, FILE *output) +command_read (void) { int argc; char line[1024]; @@ -196,31 +198,34 @@ command_read (FILE *input, FILE *output) exit(1); } ccdbg_debug_mode(s51_dbg); - fprintf(output, "Welcome to the non-simulated processor\n"); + ccdbg_halt(s51_dbg); + s51_printf("Welcome to the non-simulated processor\n"); for (;;) { - if (s51_prompt) - fprintf(output, "%s", s51_prompt); - else - putc('\0', output); - fflush(output); - if (!fgets (line, sizeof line, input)) + if (s51_read_line (line, sizeof line) == 0) break; + s51_interrupted = 0; argc = command_split_into_words(line, argv); if (argc > 0) { func = command_string_to_function(argv[0]); if (!func) - command_syntax_error(output, argc, argv); + command_syntax_error(argc, argv); else { - result = (*func->func)(output, argc, argv); + result = (*func->func)(argc, argv); + if (s51_interrupted) + result = command_interrupt; switch (result) { case command_syntax: - command_syntax_error(output, argc, argv); + command_syntax_error(argc, argv); break; case command_error: - fprintf(output, "Error\n"); + s51_printf("Error\n"); break; - case command_proceed: + case command_success: + break; + case command_interrupt: + ccdbg_halt(s51_dbg); + s51_printf("Interrupted\n"); break; default: break; @@ -229,6 +234,6 @@ command_read (FILE *input, FILE *output) } } ccdbg_close(s51_dbg); - fprintf(output, "...\n"); + s51_printf("...\n"); } diff --git a/s51/s51.h b/s51/s51.h index 3ca4734c..7c96e2a6 100644 --- a/s51/s51.h +++ b/s51/s51.h @@ -19,66 +19,81 @@ #include extern char *s51_prompt; - extern struct ccdbg *s51_dbg; +extern int s51_interrupted; enum command_result { - command_proceed, command_debug, command_syntax, command_error + command_success, command_debug, command_syntax, command_interrupt, command_error, }; enum command_result -command_quit (FILE *output, int argc, char **argv); +command_quit (int argc, char **argv); + +enum command_result +command_help (int argc, char **argv); + +enum command_result +command_di (int argc, char **argv); enum command_result -command_help (FILE *output, int argc, char **argv); +command_ds (int argc, char **argv); enum command_result -command_di (FILE *output, int argc, char **argv); +command_dx (int argc, char **argv); enum command_result -command_ds (FILE *output, int argc, char **argv); +command_set (int argc, char **argv); enum command_result -command_dx (FILE *output, int argc, char **argv); +command_dump (int argc, char **argv); enum command_result -command_set (FILE *output, int argc, char **argv); +command_file (int argc, char **argv); enum command_result -command_dump (FILE *output, int argc, char **argv); +command_pc (int argc, char **argv); enum command_result -command_pc (FILE *output, int argc, char **argv); +command_break (int argc, char **argv); enum command_result -command_break (FILE *output, int argc, char **argv); +command_clear (int argc, char **argv); enum command_result -command_clear (FILE *output, int argc, char **argv); +command_run (int argc, char **argv); enum command_result -command_run (FILE *output, int argc, char **argv); +command_next (int argc, char **argv); enum command_result -command_next (FILE *output, int argc, char **argv); +command_step (int argc, char **argv); enum command_result -command_step (FILE *output, int argc, char **argv); +command_load (int argc, char **argv); enum command_result -command_load (FILE *output, int argc, char **argv); +command_halt (int argc, char **argv); enum command_result -command_halt (FILE *output, int argc, char **argv); +command_reset (int argc, char **argv); enum command_result -command_reset (FILE *output, int argc, char **argv); +command_status (int argc, char **argv); enum command_result -command_status (FILE *output, int argc, char **argv); +cc_wait(void); -uint8_t -cc_wait(struct ccdbg *dbg); +void +command_read (void); + +void +s51_printf(char *format, ...); void -command_read (FILE *input, FILE *output); +s51_putc(int c); + +int +s51_check_input(void); + +int +s51_read_line(char *line, int len); -- cgit v1.2.3 From 1264c3676e95427bba5d01e05c303d036a7f9eca Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 26 Dec 2008 23:05:04 -0800 Subject: Switch to libusb-1.0 and use async interface. The async libusb interface offers substantial performance benefits by not making each command wait for the reply. This makes talking over this interface almost reasonable. Signed-off-by: Keith Packard --- ccload/Makefile.am | 4 +- configure.ac | 4 ++ lib/Makefile.am | 5 +- lib/ccdbg-command.c | 2 + lib/ccdbg-debug.h | 44 +++++++++++++ lib/ccdbg-io.c | 70 ++++++++++++++++----- lib/ccdbg-manual.c | 2 +- lib/ccdbg.h | 48 ++++++-------- lib/cp-usb-async.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/cp-usb-async.h | 38 ++++++++++++ s51/Makefile.am | 4 +- 11 files changed, 344 insertions(+), 53 deletions(-) create mode 100644 lib/ccdbg-debug.h create mode 100644 lib/cp-usb-async.c create mode 100644 lib/cp-usb-async.h diff --git a/ccload/Makefile.am b/ccload/Makefile.am index f54f4aaa..3a754b23 100644 --- a/ccload/Makefile.am +++ b/ccload/Makefile.am @@ -1,10 +1,10 @@ bin_PROGRAMS=ccload -AM_CFLAGS=-I$(top_srcdir)/lib +AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) CCLOAD_LIBS=../lib/libcc.a ccload_DEPENDENCIES = $(CCLOAD_LIBS) -ccload_LDADD=$(CCLOAD_LIBS) $(USB_LIBS) +ccload_LDADD=$(CCLOAD_LIBS) $(LIBUSB_LIBS) ccload_SOURCES = ccload.c diff --git a/configure.ac b/configure.ac index a14c802b..3ae80522 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,9 @@ AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_RANLIB +PKG_PROG_PKG_CONFIG +CFLAGS="-g" WARN_CFLAGS="" if test "x$GCC" = "xyes"; then WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ @@ -57,6 +59,8 @@ fi AC_MSG_RESULT([$CC_FOR_BUILD]) AC_SUBST(CC_FOR_BUILD) +PKG_CHECK_MODULES([LIBUSB], [libusb-1.0]) + AC_MSG_CHECKING([for suffix of executable build tools]) if test $cross_compiling = yes; then cat >conftest.c <<\_______EOF diff --git a/lib/Makefile.am b/lib/Makefile.am index a5e5932b..16f5b921 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,6 +1,6 @@ noinst_LIBRARIES = libcc.a -AM_CFLAGS=$(WARN_CFLAGS) +AM_CFLAGS=$(WARN_CFLAGS) $(LIBUSB_CFLAGS) libcc_a_SOURCES = \ ccdbg-command.c \ @@ -11,4 +11,5 @@ libcc_a_SOURCES = \ ccdbg-io.c \ ccdbg-manual.c \ ccdbg-memory.c \ - cp-usb.c + cp-usb.c \ + cp-usb-async.c diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c index 30f5094d..2b29fdee 100644 --- a/lib/ccdbg-command.c +++ b/lib/ccdbg-command.c @@ -31,6 +31,7 @@ ccdbg_debug_mode(struct ccdbg *dbg) ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); + ccdbg_sync_io(dbg); } void @@ -45,6 +46,7 @@ ccdbg_reset(struct ccdbg *dbg) ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + ccdbg_sync_io(dbg); } uint8_t diff --git a/lib/ccdbg-debug.h b/lib/ccdbg-debug.h new file mode 100644 index 00000000..a09148d3 --- /dev/null +++ b/lib/ccdbg-debug.h @@ -0,0 +1,44 @@ +/* + * 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_DEBUG_H_ +#define _CCDBG_DEBUG_H_ +/* Debug levels + */ +#define CC_DEBUG_BITBANG 0x00000001 +#define CC_DEBUG_COMMAND 0x00000002 +#define CC_DEBUG_INSTRUCTIONS 0x00000004 +#define CC_DEBUG_EXECUTE 0x00000008 +#define CC_DEBUG_FLASH 0x00000010 +#define CC_DEBUG_MEMORY 0x00000020 +#define CC_DEBUG_USB_ASYNC 0x00000040 + +/* ccdbg-debug.c */ +void +ccdbg_debug(int level, char *format, ...); + +void +ccdbg_add_debug(int level); + +void +ccdbg_clear_debug(int level); + +void +ccdbg_flush(void); + +#endif /* _CCDBG_DEBUG_H_ */ diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index 5ecea769..53ea7583 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -18,6 +18,11 @@ #include "ccdbg.h" #include +#ifdef CP_USB_ASYNC +#include "cp-usb-async.h" +#else +#include "cp-usb.h" +#endif void ccdbg_half_clock(struct ccdbg *dbg) @@ -38,32 +43,60 @@ ccdbg_open(void) perror("calloc"); return NULL; } +#ifdef CP_USB_ASYNC + dbg->cp_async = cp_usb_async_open(); + if (!dbg->cp_async) { + free (dbg); + return NULL; + } +#else dbg->cp = cp_usb_open (); if (!dbg->cp) { free (dbg); return NULL; } +#endif return dbg; } void ccdbg_close(struct ccdbg *dbg) { +#ifdef CP_USB_ASYNC + cp_usb_async_close(dbg->cp_async); +#else cp_usb_close(dbg->cp); +#endif free (dbg); } int ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) { +#ifdef CP_USB_ASYNC + cp_usb_async_write(dbg->cp_async, mask, value); +#else cp_usb_write(dbg->cp, mask, value); +#endif return 0; } -uint8_t -ccdbg_read(struct ccdbg *dbg) +void +ccdbg_read(struct ccdbg *dbg, uint8_t *valuep) +{ +#ifdef CP_USB_ASYNC + cp_usb_async_read(dbg->cp_async, valuep); +#else + *valuep = cp_usb_read(dbg->cp); +#endif +} + +void +ccdbg_sync_io(struct ccdbg *dbg) { - return cp_usb_read(dbg->cp); +#ifdef CP_USB_ASYNC + cp_usb_async_sync(dbg->cp_async); +#endif } static char @@ -112,6 +145,7 @@ ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) if (bit == 3) ccdbg_debug(CC_DEBUG_BITBANG, "\n"); } + ccdbg_sync_io(dbg); } void @@ -121,43 +155,47 @@ ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) ccdbg_send_byte(dbg, *bytes++); } -uint8_t -ccdbg_recv_bit(struct ccdbg *dbg, int first) +void +ccdbg_recv_bit(struct ccdbg *dbg, int first, uint8_t *bit) { uint8_t mask = first ? CC_DATA : 0; - uint8_t read; ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - read = ccdbg_read(dbg); - ccdbg_print("#\t%c %c %c\n", CC_DATA, read); + ccdbg_read(dbg, bit); ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); - return (read & CC_DATA) ? 1 : 0; } -uint8_t -ccdbg_recv_byte(struct ccdbg *dbg, int first) +void +ccdbg_recv_byte(struct ccdbg *dbg, int first, uint8_t *bytep) { uint8_t byte = 0; + uint8_t bits[8]; int bit; ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); + for (bit = 0; bit < 8; bit++) { + ccdbg_recv_bit(dbg, first, &bits[bit]); + first = 0; + } + ccdbg_sync_io(dbg); for (bit = 0; bit < 8; bit++) { byte = byte << 1; - byte |= ccdbg_recv_bit(dbg, first); + byte |= (bits[bit] & CC_DATA) ? 1 : 0; + ccdbg_print("#\t%c %c %c\n", CC_DATA, bits[bit]); if (bit == 3) ccdbg_debug(CC_DEBUG_BITBANG, "\n"); - first = 0; } ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); - return byte; + *bytep = byte; } void ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) { + int i; int first = 1; - while (nbytes--) { - *bytes++ = ccdbg_recv_byte(dbg, first); + for (i = 0; i < nbytes; i++) { + ccdbg_recv_byte(dbg, first, &bytes[i]); first = 0; } } diff --git a/lib/ccdbg-manual.c b/lib/ccdbg-manual.c index b83dc450..b48f8bb1 100644 --- a/lib/ccdbg-manual.c +++ b/lib/ccdbg-manual.c @@ -59,7 +59,7 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { uint8_t read; - read = ccdbg_read(dbg); + ccdbg_read(dbg, &read); ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); if ((set & CC_CLOCK) == 0) printf ("\t%d", (read&CC_DATA) ? 1 : 0); diff --git a/lib/ccdbg.h b/lib/ccdbg.h index e0e58104..834092b2 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -30,11 +30,12 @@ #include #include #include -#include "cp-usb.h" +#include "ccdbg-debug.h" + #define CC_CLOCK 0x1 #define CC_DATA 0x2 #define CC_RESET_N 0x4 -#define CC_CLOCK_US (40) +#define CC_CLOCK_US (0) /* 8051 instructions */ @@ -90,8 +91,14 @@ /* Bit-addressable accumulator */ #define ACC(bit) (0xE0 | (bit)) +#define CP_USB_ASYNC + struct ccdbg { +#ifdef CP_USB_ASYNC + struct cp_usb_async *cp_async; +#else struct cp_usb *cp; +#endif }; /* Intel hex file format data @@ -153,15 +160,6 @@ struct hex_image { #define CC_STEP_REPLACE(n) (0x64|(n)) #define CC_GET_CHIP_ID 0x68 -/* Debug levels - */ -#define CC_DEBUG_BITBANG 0x00000001 -#define CC_DEBUG_COMMAND 0x00000002 -#define CC_DEBUG_INSTRUCTIONS 0x00000004 -#define CC_DEBUG_EXECUTE 0x00000008 -#define CC_DEBUG_FLASH 0x00000010 -#define CC_DEBUG_MEMORY 0x00000020 - /* ccdbg-command.c */ void ccdbg_debug_mode(struct ccdbg *dbg); @@ -214,19 +212,6 @@ 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_add_debug(int level); - -void -ccdbg_clear_debug(int level); - -void -ccdbg_flush(void); - /* ccdbg-flash.c */ uint8_t ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image); @@ -254,8 +239,8 @@ ccdbg_half_clock(struct ccdbg *dbg); int ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); -uint8_t -ccdbg_read(struct ccdbg *dbg); +void +ccdbg_read(struct ccdbg *dbg, uint8_t *valuep); struct ccdbg * ccdbg_open(void); @@ -302,15 +287,18 @@ ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte); void ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); -uint8_t -ccdbg_recv_bit(struct ccdbg *dbg, int first); +void +ccdbg_recv_bit(struct ccdbg *dbg, int first, uint8_t *bit); -uint8_t -ccdbg_recv_byte(struct ccdbg *dbg, int first); +void +ccdbg_recv_byte(struct ccdbg *dbg, int first, uint8_t *byte); void ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); +void +ccdbg_sync_io(struct ccdbg *dbg); + void ccdbg_print(char *format, uint8_t mask, uint8_t set); diff --git a/lib/cp-usb-async.c b/lib/cp-usb-async.c new file mode 100644 index 00000000..3f5f76ab --- /dev/null +++ b/lib/cp-usb-async.c @@ -0,0 +1,176 @@ +/* + * 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 +#include +#include +#include +#include "cp-usb-async.h" +#include "ccdbg-debug.h" + +#define MAX_OUTSTANDING 256 +#define CP_TIMEOUT 1000 /* ms */ + +struct cp_usb_packet { + struct libusb_transfer *transfer; + enum { packet_read, packet_write } direction; + unsigned char data[9]; + uint8_t *valuep; +}; + +struct cp_usb_async { + libusb_context *ctx; + libusb_device_handle *handle; + struct cp_usb_packet packet[MAX_OUTSTANDING]; + int p, ack; +}; + +struct cp_usb_async * +cp_usb_async_open(void) +{ + struct cp_usb_async *cp; + int ret; + + cp = calloc(sizeof (struct cp_usb_async), 1); + if (!cp) + return NULL; + ret = libusb_init(&cp->ctx); + if (ret) { + free(cp); + return NULL; + } + cp->handle = libusb_open_device_with_vid_pid(cp->ctx, + 0x10c4, 0xea60); + if (!cp->handle) { + libusb_exit(cp->ctx); + free(cp); + return NULL; + } + return cp; +} + +void +cp_usb_async_close(struct cp_usb_async *cp) +{ + libusb_close(cp->handle); + libusb_exit(cp->ctx); + free(cp); +} + +static void +cp_usb_async_transfer_callback(struct libusb_transfer *transfer) +{ + struct cp_usb_async *cp = transfer->user_data; + int p; + + for (p = 0; p < cp->p; p++) + if (cp->packet[p].transfer == transfer) + break; + if (p == cp->p) { + fprintf(stderr, "unknown transfer\n"); + return; + } + switch (cp->packet[p].direction) { + case packet_read: + ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack read %d 0x%02x\n", + p, cp->packet[p].data[8]); + *cp->packet[p].valuep = cp->packet[p].data[8]; + break; + case packet_write: + ccdbg_debug(CC_DEBUG_USB_ASYNC, "ack write %d\n", p); + break; + } + if (p > cp->ack) + cp->ack = p; +} + +void +cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value) +{ + int p; + uint16_t gpio_set = ((uint16_t) value << 8) | mask; + int ret; + + if (cp->p == MAX_OUTSTANDING) + cp_usb_async_sync(cp); + p = cp->p; + if (!cp->packet[p].transfer) + cp->packet[p].transfer = libusb_alloc_transfer(0); + cp->packet[p].direction = packet_write; + libusb_fill_control_setup(cp->packet[p].data, + 0x40, /* request */ + 0xff, /* request type */ + 0x37e1, /* value */ + gpio_set, /* index */ + 0); /* length */ + + libusb_fill_control_transfer(cp->packet[p].transfer, + cp->handle, + cp->packet[p].data, + cp_usb_async_transfer_callback, + cp, + CP_TIMEOUT); + ccdbg_debug(CC_DEBUG_USB_ASYNC, "Write packet %d 0x%x 0x%x\n", p, mask, value); + ret = libusb_submit_transfer(cp->packet[p].transfer); + if (ret) + fprintf(stderr, "libusb_submit_transfer failed %d\n", ret); + cp->p++; +} + +void +cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep) +{ + int p; + int ret; + + if (cp->p == MAX_OUTSTANDING) + cp_usb_async_sync(cp); + p = cp->p; + if (!cp->packet[p].transfer) + cp->packet[p].transfer = libusb_alloc_transfer(0); + cp->packet[p].valuep = valuep; + cp->packet[p].direction = packet_read; + libusb_fill_control_setup(cp->packet[p].data, + 0xc0, /* request */ + 0xff, /* request type */ + 0x00c2, /* value */ + 0, /* index */ + 1); /* length */ + + libusb_fill_control_transfer(cp->packet[p].transfer, + cp->handle, + cp->packet[p].data, + cp_usb_async_transfer_callback, + cp, + CP_TIMEOUT); + ccdbg_debug(CC_DEBUG_USB_ASYNC, "Read packet %d\n", p); + ret = libusb_submit_transfer(cp->packet[p].transfer); + if (ret) + fprintf(stderr, "libusb_submit_transfer failed %d\n", ret); + cp->p++; +} + +void +cp_usb_async_sync(struct cp_usb_async *cp) +{ + while (cp->ack < cp->p - 1) { + libusb_handle_events(cp->ctx); + } + cp->p = 0; + cp->ack = 0; +} diff --git a/lib/cp-usb-async.h b/lib/cp-usb-async.h new file mode 100644 index 00000000..976a320e --- /dev/null +++ b/lib/cp-usb-async.h @@ -0,0 +1,38 @@ +/* + * 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 _CP_USB_ASYNC_H_ +#define _CP_USB_ASYNC_H_ +#include + +struct cp_usb_async * +cp_usb_async_open(void); + +void +cp_usb_async_close(struct cp_usb_async *cp); + +void +cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value); + +void +cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep); + +void +cp_usb_async_sync(struct cp_usb_async *cp); + +#endif diff --git a/s51/Makefile.am b/s51/Makefile.am index cfa183d4..fa6fc692 100644 --- a/s51/Makefile.am +++ b/s51/Makefile.am @@ -1,10 +1,10 @@ bin_PROGRAMS=s51 -AM_CFLAGS=-I$(top_srcdir)/lib +AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) S51_LIBS=../lib/libcc.a s51_DEPENDENCIES = $(S51_LIBS) -s51_LDADD=$(S51_LIBS) $(USB_LIBS) +s51_LDADD=$(S51_LIBS) $(LIBUSB_LIBS) s51_SOURCES = s51-parse.c s51-command.c s51-main.c -- cgit v1.2.3 From 1405838160b69e2cda456e21502a1d03b3aa7548 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 27 Dec 2008 11:25:58 -0800 Subject: s51: get start address from ihx file. re-enable breakpoints after reset. Use the start of the ihx file when asked to run from 0x0, this lets sdcdb run programs from ram. The reset command clears all hw breakpoints, so reset them afterwards. Signed-off-by: Keith Packard --- s51/s51-command.c | 39 ++++++++++++++++++++++++++++++++++++--- s51/s51-main.c | 4 ++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/s51/s51-command.c b/s51/s51-command.c index 7538a94a..b4f853be 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -18,6 +18,8 @@ #include "s51.h" +static uint16_t start_address; + static enum command_result parse_int(char *value, int *result) { @@ -147,9 +149,23 @@ command_dump (int argc, char **argv) enum command_result command_file (int argc, char **argv) { + struct hex_file *hex; + FILE *file; + if (argc != 2) return command_error; - s51_printf("some words read from %s\n", argv[1]); + file = fopen (argv[1], "r"); + if (!file) + return command_error; + hex = ccdbg_hex_file_read(file, argv[1]); + fclose(file); + if (!hex) + return command_error; + if (hex->nrecord == 0) { + ccdbg_hex_file_free(hex); + return command_error; + } + start_address = hex->records[0]->address; return command_success; } @@ -200,6 +216,15 @@ enable_breakpoint(int b) s51_printf("enable_breakpoint status 0x%02x\n", status); } +static void +enable_breakpoints(void) +{ + int b; + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) + if (breakpoints[b].enabled) + enable_breakpoint(b); +} + enum command_result set_breakpoint(uint16_t address, int temporary) { @@ -261,8 +286,7 @@ find_breakpoint(uint16_t address) break; if (b == CC_NUM_BREAKPOINTS) return -1; - if (breakpoints[b].temporary) - clear_breakpoint(address, 1); + return b; } enum command_result @@ -317,6 +341,9 @@ cc_stopped(uint8_t status) pc = pc - 1; code = 104; reason = "Breakpoint"; + b = find_breakpoint(pc); + if (b != -1 && breakpoints[b].temporary) + clear_breakpoint(pc, 1); ccdbg_set_pc(s51_dbg, pc); } else { code = 105; @@ -360,6 +387,10 @@ command_run (int argc, char **argv) if (result != command_success) return result; } + if (start_address && start == 0) { + start = start_address; + s51_printf("Starting at 0x%04x\n", start); + } ccdbg_set_pc(s51_dbg, start); } else @@ -422,6 +453,8 @@ enum command_result command_reset (int argc, char **argv) { ccdbg_debug_mode(s51_dbg); + ccdbg_halt(s51_dbg); + enable_breakpoints(); return command_success; } diff --git a/s51/s51-main.c b/s51/s51-main.c index 28a774d2..27ed571a 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -174,8 +174,10 @@ s51_printf(char *format, ...) va_start(ap, format); vfprintf(s51_output, format, ap); +#if 1 if (s51_port) vfprintf(stdout, format, ap); +#endif va_end(ap); } @@ -195,8 +197,10 @@ s51_read_line(char *line, int len) s51_putc('\0'); fflush(s51_output); ret = fgets(line, len, s51_input) != NULL; +#if 1 if (s51_port) printf("> %s", line); +#endif fflush(stdout); return ret; } -- cgit v1.2.3 From 23aca1fcbc169184e32d4ec19f28dd4fd4cfda36 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 28 Dec 2008 00:09:30 -0800 Subject: Save/restore regs when reading/writing memory. Add SFR access. The DPL and ACC registers are used by the memory access code, so they need to be saved and restored. Stuff them up high in ram for now; this should probably be fixed to pull them back to the host instead. Special SFR access is required as not all SFRs are visible in the unified address space. Signed-off-by: Keith Packard --- lib/ccdbg-memory.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/ccdbg.h | 14 +++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c index 3406a1b1..d74726fb 100644 --- a/lib/ccdbg-memory.c +++ b/lib/ccdbg-memory.c @@ -23,9 +23,14 @@ */ static uint8_t memory_init[] = { + 2, MOV_direct_A, 0x7f, + 3, MOV_direct1_direct2, 0x7e, SFR_DPL0, + 3, MOV_direct1_direct2, 0x7d, SFR_DPH0, + 3, MOV_direct1_direct2, 0x7c, SFR_DPL1, + 3, MOV_direct1_direct2, 0x7b, SFR_DPH1, 3, MOV_DPTR_data16, 0, 0, -#define HIGH_START 2 -#define LOW_START 3 +#define HIGH_START 21 +#define LOW_START 22 0, }; @@ -44,6 +49,15 @@ static uint8_t read8[] = { 0, }; +static uint8_t memory_fini[] = { + 2, MOV_A_direct, 0x7f, + 3, MOV_direct1_direct2, SFR_DPL0, 0x7e, + 3, MOV_direct1_direct2, SFR_DPH0, 0x7d, + 3, MOV_direct1_direct2, SFR_DPL1, 0x7c, + 3, MOV_direct1_direct2, SFR_DPH1, 0x7b, + 0, +}; + uint8_t ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) { @@ -64,6 +78,7 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) nl = 0; } } + (void) ccdbg_execute(dbg, memory_fini); if (nl) ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; @@ -88,6 +103,7 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) nl = 0; } } + (void) ccdbg_execute(dbg, memory_fini); if (nl) ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; @@ -118,3 +134,52 @@ ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length) ccdbg_read_memory(dbg, address, image->data, length); return image; } + +static uint8_t sfr_init[] = { + 2, MOV_direct_A, 0x7f, + 0, +}; + +static uint8_t sfr_fini[] = { + 2, MOV_A_direct, 0x7f, + 0, +}; + +static uint8_t sfr_read[] = { + 2, MOV_A_direct, 0, +#define SFR_READ_ADDR 2 + 0, +}; + +static uint8_t sfr_write[] = { + 3, MOV_direct_data, 0, 0, +#define SFR_WRITE_ADDR 2 +#define SFR_WRITE_DATA 3 + 0, +}; + +uint8_t +ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes) +{ + int i; + (void) ccdbg_execute(dbg, sfr_init); + for (i = 0; i < nbytes; i++) { + sfr_read[SFR_READ_ADDR] = addr + i; + *bytes++ = ccdbg_execute(dbg, sfr_read); + } + (void) ccdbg_execute(dbg, sfr_fini); + return 0; +} + +uint8_t +ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes) +{ + int i; + + for (i = 0; i < nbytes; i++) { + sfr_write[SFR_WRITE_ADDR] = addr + i; + sfr_write[SFR_WRITE_DATA] = *bytes++; + ccdbg_execute(dbg, sfr_write); + } + return 0; +} diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 834092b2..203b5aeb 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -44,6 +44,7 @@ #define MOV_Rn_data(n) (0x78 | (n)) #define DJNZ_Rn_rel(n) (0xd8 | (n)) #define MOV_A_direct 0xe5 +#define MOV_direct1_direct2 0x85 #define MOV_direct_A 0xf5 #define MOV_DPTR_data16 0x90 #define MOV_A_data 0x74 @@ -57,6 +58,13 @@ /* 8051 special function registers */ +#define SFR_P0 0x80 +#define SFR_SP 0x81 +#define SFR_DPL0 0x82 +#define SFR_DPH0 0x83 +#define SFR_DPL1 0x84 +#define SFR_DPH1 0x85 + /* flash controller */ #define FWT 0xAB #define FADDRL 0xAC @@ -323,4 +331,10 @@ ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offse struct hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length); +uint8_t +ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); + +uint8_t +ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); + #endif /* _CCDBG_H_ */ -- cgit v1.2.3 From e0697186a2f9b6139636ff5d5c162879c85caf9c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 28 Dec 2008 00:11:13 -0800 Subject: Use SFR access funcs. Support 'dump' command. Add -m (monitor) flag. Not all SFRs are visible in the unified address space, so the SFR-specific accessors are required. The dump command is the same as the various 'd*' commands, but also supports dumping program memory. The new -m (monitor) flag watches the command stream between s51 and sdcdb. Signed-off-by: Keith Packard --- s51/s51-command.c | 34 +++++++++++++++++++++++++++++----- s51/s51-main.c | 14 +++++++------- s51/s51.h | 1 + 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/s51/s51-command.c b/s51/s51-command.c index b4f853be..25328f1e 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -46,6 +46,21 @@ parse_uint16(char *value, uint16_t *uint16) return command_success; } +static enum command_result +parse_uint8(char *value, uint8_t *uint8) +{ + int v; + enum command_result result; + + result = parse_int(value, &v); + if (result != command_success) + return command_error; + if (v < 0 || v > 0xff) + return command_error; + *uint8 = v; + return command_success; +} + enum command_result command_quit (int argc, char **argv) { @@ -97,19 +112,19 @@ command_di (int argc, char **argv) enum command_result command_ds (int argc, char **argv) { - uint16_t start, end; - uint8_t memory[65536]; + uint8_t start, end; + uint8_t memory[0x100]; uint8_t status; int length; if (argc != 3) return command_error; - if (parse_uint16(argv[1], &start) != command_success) + if (parse_uint8(argv[1], &start) != command_success) return command_error; - if (parse_uint16(argv[2], &end) != command_success) + if (parse_uint8(argv[2], &end) != command_success) return command_error; length = (int) end - (int) start + 1; - status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length); + status = ccdbg_read_sfr(s51_dbg, start, memory, length); dump_bytes(memory, length, start); return command_success; } @@ -143,6 +158,15 @@ command_set (int argc, char **argv) enum command_result command_dump (int argc, char **argv) { + if (argv[1]) { + if (strcmp(argv[1], "rom") == 0 || + strcmp(argv[1], "xram") == 0) + return command_dx(argc-1, argv+1); + if (strcmp(argv[1], "iram") == 0) + return command_di(argc-1, argv+1); + if (strcmp(argv[1], "sfr") == 0) + return command_ds(argc-1, argv+1); + } return command_error; } diff --git a/s51/s51-main.c b/s51/s51-main.c index 27ed571a..eef55157 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -31,6 +31,7 @@ static double freq = 11059200; char *s51_prompt = "> "; struct ccdbg *s51_dbg; int s51_interrupted = 0; +int s51_monitor = 0; static FILE *s51_input; static FILE *s51_output; @@ -54,7 +55,7 @@ main(int argc, char **argv) char *endptr; struct sigvec vec, ovec; - while ((opt = getopt(argc, argv, "PVvHht:X:c:r:Z:s:S:p:")) != -1) { + while ((opt = getopt(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:")) != -1) { switch (opt) { case 't': cpu = optarg; @@ -100,6 +101,9 @@ main(int argc, char **argv) case 'h': usage (); break; + case 'm': + s51_monitor = 1; + break; } } if (s51_port) { @@ -174,10 +178,8 @@ s51_printf(char *format, ...) va_start(ap, format); vfprintf(s51_output, format, ap); -#if 1 - if (s51_port) + if (s51_monitor) vfprintf(stdout, format, ap); -#endif va_end(ap); } @@ -197,10 +199,8 @@ s51_read_line(char *line, int len) s51_putc('\0'); fflush(s51_output); ret = fgets(line, len, s51_input) != NULL; -#if 1 - if (s51_port) + if (s51_monitor) printf("> %s", line); -#endif fflush(stdout); return ret; } diff --git a/s51/s51.h b/s51/s51.h index 7c96e2a6..eab61452 100644 --- a/s51/s51.h +++ b/s51/s51.h @@ -21,6 +21,7 @@ extern char *s51_prompt; extern struct ccdbg *s51_dbg; extern int s51_interrupted; +extern int s51_monitor; enum command_result { command_success, command_debug, command_syntax, command_interrupt, command_error, -- cgit v1.2.3 From ea366058aa467a8a7caf17e7014758f3741ea7f7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Dec 2008 12:35:11 -0800 Subject: Fix flashing less than a full page of data. Verify page at a time. The 8051 flashing code requires special help with counts with non-zero low byte. Also, instead of verifying the entire flash contents at the end, verify each page as it goes. Signed-off-by: Keith Packard --- ccload/ccload.c | 2 ++ lib/ccdbg-flash.c | 61 ++++++++++++++++++++++++++++++++------------------- target/blink/Makefile | 2 ++ 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/ccload/ccload.c b/ccload/ccload.c index b4bb1443..3e220914 100644 --- a/ccload/ccload.c +++ b/ccload/ccload.c @@ -54,6 +54,8 @@ main (int argc, char **argv) if (!dbg) exit (1); + ccdbg_add_debug(CC_DEBUG_FLASH); + ccdbg_debug_mode(dbg); ccdbg_halt(dbg); if (image->address == 0xf000) { diff --git a/lib/ccdbg-flash.c b/lib/ccdbg-flash.c index f950dd1b..8b3390c7 100644 --- a/lib/ccdbg-flash.c +++ b/lib/ccdbg-flash.c @@ -244,13 +244,16 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) uint16_t flash_prog; uint16_t flash_len; uint8_t fwt; + uint16_t flash_addr; uint16_t flash_word_addr; uint16_t flash_words; + uint8_t flash_words_high, flash_words_low; uint16_t ram_addr; uint16_t pc; uint8_t status; uint16_t remain, this_time, start; uint8_t verify[0x400]; + int times; ccdbg_clock_init(dbg); if (image->address + image->length > 0x8000) { @@ -286,52 +289,64 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr); ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); - ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes\n", image->length); + ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time); ccdbg_read_memory(dbg, ram_addr, verify, this_time); if (memcmp (image->data + start, verify, this_time) != 0) { - fprintf(stderr, "image verify failed\n"); + fprintf(stderr, "ram verify failed\n"); return 1; } - flash_word_addr = (image->address + start) >> 1; + flash_addr = image->address + start; + flash_word_addr = flash_addr >> 1; flash_len = this_time + (this_time & 1); flash_words = flash_len >> 1; + flash_words_low = flash_words & 0xff; + flash_words_high = flash_words >> 8; + + /* The flash code above is lame */ + if (flash_words_low) + flash_words_high++; + ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_HIGH, flash_word_addr >> 8); ccdbg_write_uint8(dbg, flash_prog + FLASH_ADDR_LOW, flash_word_addr & 0xff); ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_HIGH, ram_addr >> 8); ccdbg_write_uint8(dbg, flash_prog + RAM_ADDR_LOW, ram_addr & 0xff); - ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words >> 8); - ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words & 0xff); + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_HIGH, flash_words_high); + ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words_low); ccdbg_set_pc(dbg, flash_prog); pc = ccdbg_get_pc(dbg); - ccdbg_debug(CC_DEBUG_FLASH, "Starting flash program at 0x%04x\n", pc); + ccdbg_debug(CC_DEBUG_FLASH, "Flashing %d bytes at 0x%04x\n", + this_time, flash_addr); status = ccdbg_resume(dbg); - ccdbg_debug(CC_DEBUG_FLASH, "resume status is 0x%02x\n", status); - do { + for (times = 0; times < 10; times++) { status = ccdbg_read_status(dbg); ccdbg_debug(CC_DEBUG_FLASH, "chip status is 0x%02x\n", status); - sleep(1); - } while ((status & CC_STATUS_CPU_HALTED) == 0); + if ((status & CC_STATUS_CPU_HALTED) != 0) + break; + } + if (times == 10) { + fprintf(stderr, "flash page timed out\n"); + return 1; + } + ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in flash\n", this_time); + ccdbg_read_memory(dbg, flash_addr, verify, this_time); + if (memcmp (image->data + start, verify, this_time) != 0) { + int i; + fprintf(stderr, "flash verify failed\n"); + for (i = 0; i < this_time; i++) { + if (image->data[start + i] != verify[i]) + fprintf(stderr, "0x%04x: 0x%02x != 0x%02x\n", + start + i, image->data[start+i], verify[i]); + } + return 1; + } remain -= this_time; start += this_time; } -#if 1 - ccdbg_debug(CC_DEBUG_FLASH, "Downloading flash to check\n"); - struct hex_image *test_image; - 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++) - ccdbg_debug(CC_DEBUG_FLASH, "0x%02x : 0x%02x\n", image->data[i], test_image->data[i]); - return 1; - } - return 0; -#endif return 0; } diff --git a/target/blink/Makefile b/target/blink/Makefile index 1f18f529..4c9b4102 100644 --- a/target/blink/Makefile +++ b/target/blink/Makefile @@ -42,3 +42,5 @@ blink-flash.ihx: blink-ram.ihx clean: rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: -- cgit v1.2.3 From 6c2a65c743a4ffae96ed27dbc38c1bf9242ed1df Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 30 Dec 2008 22:35:53 -0800 Subject: Save/restore registers to host during memory operations. Cache ROM data. Because the debug port uses instructions for most operations, the debug code will clobber registers used by the running program. Save and restore these to avoid corrupting application data. If the ROM file is known, use that to return data instead of fetching it from the target to improve performance. Signed-off-by: Keith Packard --- lib/Makefile.am | 2 + lib/ccdbg-debug.c | 5 ++- lib/ccdbg-debug.h | 2 +- lib/ccdbg-flash.c | 8 +++- lib/ccdbg-memory.c | 54 +++++++++------------- lib/ccdbg-rom.c | 63 ++++++++++++++++++++++++++ lib/ccdbg-state.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ccdbg.h | 43 ++++++++++++++++++ s51/s51-command.c | 74 ++++++++++++++++++++++++++++--- s51/s51-parse.c | 71 +++++++++++++++-------------- s51/s51.h | 23 ++++++++++ 11 files changed, 396 insertions(+), 77 deletions(-) create mode 100644 lib/ccdbg-rom.c create mode 100644 lib/ccdbg-state.c diff --git a/lib/Makefile.am b/lib/Makefile.am index 16f5b921..ba6f9725 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -11,5 +11,7 @@ libcc_a_SOURCES = \ ccdbg-io.c \ ccdbg-manual.c \ ccdbg-memory.c \ + ccdbg-rom.c \ + ccdbg-state.c \ cp-usb.c \ cp-usb-async.c diff --git a/lib/ccdbg-debug.c b/lib/ccdbg-debug.c index 8f6f9e11..847361c7 100644 --- a/lib/ccdbg-debug.c +++ b/lib/ccdbg-debug.c @@ -47,7 +47,8 @@ ccdbg_debug(int level, char *format, ...) } void -ccdbg_flush(void) +ccdbg_flush(int level) { - fflush(stdout); + if (ccdbg_level & level) + fflush(stdout); } diff --git a/lib/ccdbg-debug.h b/lib/ccdbg-debug.h index a09148d3..0b5b44c1 100644 --- a/lib/ccdbg-debug.h +++ b/lib/ccdbg-debug.h @@ -39,6 +39,6 @@ void ccdbg_clear_debug(int level); void -ccdbg_flush(void); +ccdbg_flush(int level); #endif /* _CCDBG_DEBUG_H_ */ diff --git a/lib/ccdbg-flash.c b/lib/ccdbg-flash.c index 8b3390c7..8a586a21 100644 --- a/lib/ccdbg-flash.c +++ b/lib/ccdbg-flash.c @@ -288,13 +288,14 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr); ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); - +#if 0 ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time); ccdbg_read_memory(dbg, ram_addr, verify, this_time); if (memcmp (image->data + start, verify, this_time) != 0) { fprintf(stderr, "ram verify failed\n"); return 1; } +#endif flash_addr = image->address + start; flash_word_addr = flash_addr >> 1; @@ -324,10 +325,13 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) status = ccdbg_resume(dbg); for (times = 0; times < 10; times++) { status = ccdbg_read_status(dbg); - ccdbg_debug(CC_DEBUG_FLASH, "chip status is 0x%02x\n", status); + ccdbg_debug(CC_DEBUG_FLASH, "."); + ccdbg_flush(CC_DEBUG_FLASH); if ((status & CC_STATUS_CPU_HALTED) != 0) break; + usleep(10000); } + ccdbg_debug(CC_DEBUG_FLASH, "\n"); if (times == 10) { fprintf(stderr, "flash page timed out\n"); return 1; diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c index d74726fb..20a24799 100644 --- a/lib/ccdbg-memory.c +++ b/lib/ccdbg-memory.c @@ -23,14 +23,9 @@ */ static uint8_t memory_init[] = { - 2, MOV_direct_A, 0x7f, - 3, MOV_direct1_direct2, 0x7e, SFR_DPL0, - 3, MOV_direct1_direct2, 0x7d, SFR_DPH0, - 3, MOV_direct1_direct2, 0x7c, SFR_DPL1, - 3, MOV_direct1_direct2, 0x7b, SFR_DPH1, 3, MOV_DPTR_data16, 0, 0, -#define HIGH_START 21 -#define LOW_START 22 +#define HIGH_START 2 +#define LOW_START 3 0, }; @@ -49,19 +44,13 @@ static uint8_t read8[] = { 0, }; -static uint8_t memory_fini[] = { - 2, MOV_A_direct, 0x7f, - 3, MOV_direct1_direct2, SFR_DPL0, 0x7e, - 3, MOV_direct1_direct2, SFR_DPH0, 0x7d, - 3, MOV_direct1_direct2, SFR_DPL1, 0x7c, - 3, MOV_direct1_direct2, SFR_DPH1, 0x7b, - 0, -}; - uint8_t ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) { int i, nl = 0; + struct ccstate state; + + ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP); memory_init[HIGH_START] = addr >> 8; memory_init[LOW_START] = addr; (void) ccdbg_execute(dbg, memory_init); @@ -70,7 +59,7 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) ccdbg_execute(dbg, write8); if ((i & 0xf) == 0xf) { ccdbg_debug(CC_DEBUG_MEMORY, "."); - ccdbg_flush(); + ccdbg_flush(CC_DEBUG_MEMORY); nl = 1; } if ((i & 0xff) == 0xff) { @@ -78,7 +67,7 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) nl = 0; } } - (void) ccdbg_execute(dbg, memory_fini); + ccdbg_state_restore(dbg, &state); if (nl) ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; @@ -88,6 +77,13 @@ uint8_t ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) { int i, nl = 0; + struct ccstate state; + + if (ccdbg_rom_contains(dbg, addr, nbytes)) { + ccdbg_rom_replace_xmem(dbg, addr, bytes, nbytes); + return 0; + } + ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP); memory_init[HIGH_START] = addr >> 8; memory_init[LOW_START] = addr; (void) ccdbg_execute(dbg, memory_init); @@ -95,7 +91,7 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) *bytes++ = ccdbg_execute(dbg, read8); if ((i & 0xf) == 0xf) { ccdbg_debug(CC_DEBUG_MEMORY, "."); - ccdbg_flush(); + ccdbg_flush(CC_DEBUG_MEMORY); nl = 1; } if ((i & 0xff) == 0xff) { @@ -103,7 +99,8 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) nl = 0; } } - (void) ccdbg_execute(dbg, memory_fini); + ccdbg_state_replace_xmem(dbg, &state, addr, bytes, nbytes); + ccdbg_state_restore(dbg, &state); if (nl) ccdbg_debug(CC_DEBUG_MEMORY, "\n"); return 0; @@ -135,16 +132,6 @@ ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length) return image; } -static uint8_t sfr_init[] = { - 2, MOV_direct_A, 0x7f, - 0, -}; - -static uint8_t sfr_fini[] = { - 2, MOV_A_direct, 0x7f, - 0, -}; - static uint8_t sfr_read[] = { 2, MOV_A_direct, 0, #define SFR_READ_ADDR 2 @@ -162,12 +149,15 @@ uint8_t ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes) { int i; - (void) ccdbg_execute(dbg, sfr_init); + struct ccstate state; + + ccdbg_state_save(dbg, &state, CC_STATE_ACC); for (i = 0; i < nbytes; i++) { sfr_read[SFR_READ_ADDR] = addr + i; *bytes++ = ccdbg_execute(dbg, sfr_read); } - (void) ccdbg_execute(dbg, sfr_fini); + ccdbg_state_replace_sfr(dbg, &state, addr, bytes, nbytes); + ccdbg_state_restore(dbg, &state); return 0; } diff --git a/lib/ccdbg-rom.c b/lib/ccdbg-rom.c new file mode 100644 index 00000000..4559b4e7 --- /dev/null +++ b/lib/ccdbg-rom.c @@ -0,0 +1,63 @@ +/* + * 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" + +uint8_t +ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) +{ + if (dbg->rom) + ccdbg_hex_image_free(dbg->rom); + dbg->rom = rom; + return 0; +} + +uint8_t +ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes) +{ + struct hex_image *rom = dbg->rom; + if (!rom) + return 0; + if (addr < rom->address || rom->address + rom->length < addr + nbytes) + return 0; + return 1; +} + +uint8_t +ccdbg_rom_replace_xmem(struct ccdbg *dbg, + uint16_t addr, uint8_t *bytes, int nbytes) +{ + struct hex_image *rom = dbg->rom; + if (!rom) + return 0; + + if (rom->address < addr + nbytes && addr < rom->address + rom->length) { + int start, stop; + + start = addr; + if (addr < rom->address) + start = rom->address; + stop = addr + nbytes; + if (rom->address + rom->length < stop) + stop = rom->address + rom->length; + memcpy(bytes + start - addr, rom->data + start - rom->address, + stop - start); + return 1; + } + return 0; +} diff --git a/lib/ccdbg-state.c b/lib/ccdbg-state.c new file mode 100644 index 00000000..9aca8d2e --- /dev/null +++ b/lib/ccdbg-state.c @@ -0,0 +1,128 @@ +/* + * 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" + +static uint8_t save_acc[] = { + 1, NOP, + 0 +}; + +static uint8_t save_sfr[] = { + 2, MOV_A_direct, 0, +#define SAVE_SFR_ADDR 2 + 0, +}; + +struct sfr_state { + uint8_t address; + uint16_t mask; + char *name; +}; + +static struct sfr_state sfrs[CC_STATE_NSFR] = { + { SFR_DPL0, CC_STATE_DP, "dpl0" }, + { SFR_DPH0, CC_STATE_DP, "dph0" }, + { SFR_DPL1, CC_STATE_DP, "dpl1" }, + { SFR_DPH1, CC_STATE_DP, "dph1" }, + { PSW(0), CC_STATE_PSW, "psw" }, +}; + +uint8_t +ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask) +{ + int i; + + mask |= CC_STATE_ACC; + if (mask & CC_STATE_ACC) + state->acc = ccdbg_execute(dbg, save_acc); + for (i = 0; i < CC_STATE_NSFR; i++) { + if (sfrs[i].mask & mask) { + save_sfr[SAVE_SFR_ADDR] = sfrs[i].address; + state->sfr[i] = ccdbg_execute(dbg, save_sfr); + } + } + state->mask = mask; + return 0; +} + +static uint8_t restore_sfr[] = { + 3, MOV_direct_data, 0, 0, +#define RESTORE_SFR_ADDR 2 +#define RESTORE_SFR_DATA 3 + 0 +}; + +static uint8_t restore_acc[] = { + 2, MOV_A_data, 0, +#define RESTORE_ACC_DATA 2 + 0 +}; + +uint8_t +ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state) +{ + int i; + for (i = CC_STATE_NSFR - 1; i >= 0; i--) { + if (sfrs[i].mask & state->mask) { + restore_sfr[RESTORE_SFR_ADDR] = sfrs[i].address; + restore_sfr[RESTORE_SFR_DATA] = state->sfr[i]; + ccdbg_execute(dbg, restore_sfr); + } + } + if (state->mask & CC_STATE_ACC) { + restore_acc[RESTORE_ACC_DATA] = state->acc; + ccdbg_execute(dbg, restore_acc); + } + state->mask = 0; + return 0; +} + +static void +ccdbg_state_replace(uint16_t sfr_addr, uint8_t sfr, char *name, + uint16_t addr, uint8_t *bytes, int nbytes) +{ + sfr_addr += 0xdf00; + + if (addr <= sfr_addr && sfr_addr < addr + nbytes) { + fprintf(stderr, "replacing %s at 0x%04x - read 0x%02x saved 0x%02x\n", + name, sfr_addr, bytes[sfr_addr - addr], sfr); + bytes[sfr_addr - addr] = sfr; + } +} + +void +ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state, + uint16_t addr, uint8_t *bytes, int nbytes) +{ + int i; + if (state->mask & CC_STATE_ACC) + ccdbg_state_replace(ACC(0), state->acc, "acc", + addr, bytes, nbytes); + for (i = 0; i < CC_STATE_NSFR; i++) + if (state->mask & sfrs[i].mask) + ccdbg_state_replace(sfrs[i].address, state->sfr[i], + sfrs[i].name, addr, bytes, nbytes); +} + +void +ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state, + uint8_t addr, uint8_t *bytes, int nbytes) +{ + ccdbg_state_replace_xmem(dbg, state, (uint16_t) addr + 0xdf00, bytes, nbytes); +} diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 203b5aeb..241c4eec 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -39,6 +39,7 @@ /* 8051 instructions */ +#define NOP 0x00 #define MOV_direct_data 0x75 #define LJMP 0x02 #define MOV_Rn_data(n) (0x78 | (n)) @@ -99,6 +100,9 @@ /* Bit-addressable accumulator */ #define ACC(bit) (0xE0 | (bit)) +/* Bit-addressable status word */ +#define PSW(bit) (0xD0 | (bit)) + #define CP_USB_ASYNC struct ccdbg { @@ -107,6 +111,7 @@ struct ccdbg { #else struct cp_usb *cp; #endif + struct hex_image *rom; }; /* Intel hex file format data @@ -130,6 +135,18 @@ struct hex_image { uint8_t data[0]; }; +#define CC_STATE_ACC 0x1 +#define CC_STATE_PSW 0x2 +#define CC_STATE_DP 0x4 + +#define CC_STATE_NSFR 5 + +struct ccstate { + uint16_t mask; + uint8_t acc; + uint8_t sfr[CC_STATE_NSFR]; +}; + #define HEX_RECORD_NORMAL 0x00 #define HEX_RECORD_EOF 0x01 #define HEX_RECORD_EXTENDED_ADDRESS 0x02 @@ -337,4 +354,30 @@ ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); uint8_t ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); +/* ccdbg-rom.c */ +uint8_t +ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom); + +uint8_t +ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes); + +uint8_t +ccdbg_rom_replace_xmem(struct ccdbg *dbg, + uint16_t addrp, uint8_t *bytesp, int nbytes); + +/* ccdbg-state.c */ +uint8_t +ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask); + +uint8_t +ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state); + +void +ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state, + uint16_t addr, uint8_t *bytes, int nbytes); + +void +ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state, + uint8_t addr, uint8_t *bytes, int nbytes); + #endif /* _CCDBG_H_ */ diff --git a/s51/s51-command.c b/s51/s51-command.c index 25328f1e..63d142f4 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -69,12 +69,12 @@ command_quit (int argc, char **argv) } static void -dump_bytes(uint8_t *memory, int length, uint16_t start) +dump_bytes(uint8_t *memory, int length, uint16_t start, char *format) { int group, i; for (group = 0; group < length; group += 8) { - s51_printf("0x%04x ", start + group); + s51_printf(format, start + group); for (i = group; i < length && i < group + 8; i++) s51_printf("%02x ", memory[i]); for (; i < group + 8; i++) @@ -105,7 +105,7 @@ command_di (int argc, char **argv) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length); - dump_bytes(memory, length, start); + dump_bytes(memory, length, start, "0x%02x "); return command_success; } @@ -125,7 +125,7 @@ command_ds (int argc, char **argv) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_sfr(s51_dbg, start, memory, length); - dump_bytes(memory, length, start); + dump_bytes(memory, length, start, "0x%02x "); return command_success; } @@ -145,7 +145,7 @@ command_dx (int argc, char **argv) return command_error; length = (int) end - (int) start + 1; status = ccdbg_read_memory(s51_dbg, start, memory, length); - dump_bytes(memory, length, start); + dump_bytes(memory, length, start, "0x%04x "); return command_success; } @@ -174,6 +174,7 @@ enum command_result command_file (int argc, char **argv) { struct hex_file *hex; + struct hex_image *image; FILE *file; if (argc != 2) @@ -189,7 +190,10 @@ command_file (int argc, char **argv) ccdbg_hex_file_free(hex); return command_error; } - start_address = hex->records[0]->address; + image = ccdbg_hex_image_create(hex); + ccdbg_hex_file_free(hex); + start_address = image->address; + ccdbg_set_rom(s51_dbg, image); return command_success; } @@ -473,6 +477,12 @@ command_halt (int argc, char **argv) return command_success; } +enum command_result +command_stop (int argc, char **argv) +{ + return command_success; +} + enum command_result command_reset (int argc, char **argv) { @@ -511,6 +521,58 @@ command_status(int argc, char **argv) return command_success; } +static enum command_result +info_breakpoints(int argc, char **argv) +{ + int b; + uint16_t address; + enum command_result result; + + if (argc == 1) { + s51_printf("Num Type Disp Hit Cnt Address What\n"); + for (b = 0; b < CC_NUM_BREAKPOINTS; b++) + if (breakpoints[b].enabled) { + s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n", + b, + breakpoints[b].temporary ? "del " : "keep", + breakpoints[b].address); + } + return command_success; + } + +} + +static enum command_result +info_help(int argc, char **argv); + +static struct command_function infos[] = { + { "breakpoints", "b", info_breakpoints, "[b]reakpoints", + "List current breakpoints\n" }, + { "help", "?", info_help, "help", + "Print this list\n" }, + + { NULL, NULL, NULL, NULL, NULL }, +}; + +static enum command_result +info_help(int argc, char **argv) +{ + return command_function_help(infos, argc, argv); +} + +enum command_result +command_info(int argc, char **argv) +{ + struct command_function *func; + + if (argc < 2) + return command_error; + func = command_string_to_function(infos, argv[1]); + if (!func) + return command_syntax; + return (*func->func)(argc-1, argv+1); +} + enum command_result cc_wait(void) { diff --git a/s51/s51-parse.c b/s51/s51-parse.c index d0bfb45b..749d7bd8 100644 --- a/s51/s51-parse.c +++ b/s51/s51-parse.c @@ -18,14 +18,6 @@ #include "s51.h" -struct command_function { - char *name; - char *alias; - enum command_result (*func)(int argc, char **argv); - char *usage; - char *help; -}; - static struct command_function functions[] = { { "help", "?", command_help, "help", "Print this list\n" }, { "quit", "q", command_quit, "[q]uit", "Quit\n" }, @@ -50,6 +42,8 @@ static struct command_function functions[] = { "Clear break point\n" }, { "run", "r", command_run, "[r]un [start] [stop]", "Run with optional start and temp breakpoint addresses\n" }, + { "go", "g", command_run, "[g]o [start] [stop]", + "Run with optional start and temp breakpoint addresses\n" }, { "next", "n", command_next, "[n]ext", "Step over one instruction, past any call\n" }, { "step", "s", command_step, "[s]tep", @@ -62,10 +56,13 @@ static struct command_function functions[] = { "Reset the CPU\n" }, { "status","status",command_status, "status", "Display CC1111 debug status\n" }, + { "info", "i", command_info, "[i]info", + "Get information\n" }, + { "stop", "stop", command_stop, "stop", + "Ignored\n" }, + { NULL, NULL, NULL, NULL, NULL }, }; -#define NUM_FUNCTIONS (sizeof functions / sizeof functions[0]) - #ifndef FALSE #define FALSE 0 #define TRUE 1 @@ -106,17 +103,41 @@ string_to_int(char *s, int *v) return TRUE; } -static struct command_function * -command_string_to_function(char *name) +struct command_function * +command_string_to_function(struct command_function *functions, char *name) { int i; - for (i = 0; i < NUM_FUNCTIONS; i++) + for (i = 0; functions[i].name; i++) if (!strcmp(name, functions[i].name) || !strcmp(name, functions[i].alias)) return &functions[i]; return NULL; } +enum command_result +command_function_help(struct command_function *functions, int argc, char **argv) +{ + int i; + struct command_function *func; + + if (argc == 1) { + for (i = 0; functions[i].name; i++) + s51_printf("%-10s%s\n", functions[i].name, + functions[i].usage); + } else { + for (i = 1; i < argc; i++) { + func = command_string_to_function(functions, argv[i]); + if (!func) { + s51_printf("%-10s unknown command\n", argv[i]); + return command_syntax; + } + s51_printf("%-10s %s\n%s", func->name, + func->usage, func->help); + } + } + return command_debug; +} + static int command_split_into_words(char *line, char **argv) { @@ -153,28 +174,10 @@ command_split_into_words(char *line, char **argv) enum command_result command_help(int argc, char **argv) { - int i; - struct command_function *func; - - if (argc == 1) { - for (i = 0; i < NUM_FUNCTIONS; i++) - s51_printf("%-10s%s\n", functions[i].name, - functions[i].usage); - } else { - for (i = 1; i < argc; i++) { - func = command_string_to_function(argv[i]); - if (!func) { - s51_printf("%-10s unknown command\n", argv[i]); - return command_syntax; - } - s51_printf("%-10s %s\n%s", func->name, - func->usage, func->help); - } - } - return command_debug; + return command_function_help(functions, argc, argv); } -static void +void command_syntax_error(int argc, char **argv) { s51_printf("Syntax error in:"); @@ -206,7 +209,7 @@ command_read (void) s51_interrupted = 0; argc = command_split_into_words(line, argv); if (argc > 0) { - func = command_string_to_function(argv[0]); + func = command_string_to_function(functions, argv[0]); if (!func) command_syntax_error(argc, argv); else diff --git a/s51/s51.h b/s51/s51.h index eab61452..f4dcce66 100644 --- a/s51/s51.h +++ b/s51/s51.h @@ -27,12 +27,32 @@ enum command_result { command_success, command_debug, command_syntax, command_interrupt, command_error, }; +struct command_function { + char *name; + char *alias; + enum command_result (*func)(int argc, char **argv); + char *usage; + char *help; +}; + +struct command_function * +command_string_to_function(struct command_function *functions, char *name); + +enum command_result +command_function_help(struct command_function *functions, int argc, char **argv); + +void +command_syntax_error(int argc, char **argv); + enum command_result command_quit (int argc, char **argv); enum command_result command_help (int argc, char **argv); +enum command_result +command_stop (int argc, char **argv); + enum command_result command_di (int argc, char **argv); @@ -81,6 +101,9 @@ command_reset (int argc, char **argv); enum command_result command_status (int argc, char **argv); +enum command_result +command_info (int argc, char **argv); + enum command_result cc_wait(void); -- cgit v1.2.3 From 7c03937b36aac82b08f4ea0c6da33a994fe15ec7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 30 Dec 2008 22:40:13 -0800 Subject: Add simple and timer sample programs Signed-off-by: Keith Packard --- target/simple/Makefile | 44 ++++++++ target/simple/simple.c | 42 +++++++ target/timer/Makefile | 44 ++++++++ target/timer/cc1111.h | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ target/timer/timer.c | 55 +++++++++ 5 files changed, 479 insertions(+) create mode 100644 target/simple/Makefile create mode 100644 target/simple/simple.c create mode 100644 target/timer/Makefile create mode 100644 target/timer/cc1111.h create mode 100644 target/timer/timer.c diff --git a/target/simple/Makefile b/target/simple/Makefile new file mode 100644 index 00000000..c4432325 --- /dev/null +++ b/target/simple/Makefile @@ -0,0 +1,44 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=simple.c +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=simple-flash.ihx simple-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +simple-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o simple-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o simple-flash.ihx $(REL) + +simple-flash.ihx: simple-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/target/simple/simple.c b/target/simple/simple.c new file mode 100644 index 00000000..b7ea1019 --- /dev/null +++ b/target/simple/simple.c @@ -0,0 +1,42 @@ +/* + * 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. + */ + +sfr at 0x90 P1; +sfr at 0xC6 CLKCON; + +sfr at 0xFE P1DIR; +sfr at 0xF6 P1INP; + +void delay(int n) __reentrant +{ + while (n--) + _asm nop _endasm; +} +int +main (void) __reentrant +{ + long i; + CLKCON = 0; + /* Set p1_1 to output */ + P1DIR = 0x02; + for (;;) { + P1 ^= 0x2; + for (i = 0; i < 1000; i++) + delay(1000); + } +} diff --git a/target/timer/Makefile b/target/timer/Makefile new file mode 100644 index 00000000..99e06b8d --- /dev/null +++ b/target/timer/Makefile @@ -0,0 +1,44 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=timer.c +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=timer-flash.ihx timer-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +timer-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o timer-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o timer-flash.ihx $(REL) + +timer-flash.ihx: timer-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) diff --git a/target/timer/cc1111.h b/target/timer/cc1111.h new file mode 100644 index 00000000..7a531cc0 --- /dev/null +++ b/target/timer/cc1111.h @@ -0,0 +1,294 @@ +/*------------------------------------------------------------------------- + Register Declarations for the ChipCon CC1111 Processor Range + + 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. + + Adapted from the Cygnal C8051F12x config file which is: + + Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------*/ + +#ifndef _CC1111_H_ +#define _CC1111_H_ + + +/* BYTE Registers */ + +sfr at 0x80 P0 ; /* PORT 0 */ +sfr at 0x81 SP ; /* STACK POINTER */ +sfr at 0x82 DPL ; /* DATA POINTER - LOW BYTE */ +sfr at 0x83 DPH ; /* DATA POINTER - HIGH BYTE */ +sfr at 0x84 DPL1 ; /* DATA POINTER 1 - LOW BYTE */ +sfr at 0x85 DPH1 ; /* DATA POINTER 1 - HIGH BYTE */ +sfr at 0x86 U0CSR ; /* USART 0 Control and status */ +sfr at 0x87 PCON ; /* POWER CONTROL */ +sfr at 0x88 TCON ; /* TIMER CONTROL */ +sfr at 0x89 P0IFG ; /* TIMER MODE */ +sfr at 0x8A P1IFG ; /* TIMER 0 - LOW BYTE */ +sfr at 0x8B P2IFG ; /* TIMER 1 - LOW BYTE */ +sfr at 0x8C PICTL ; /* TIMER 0 - HIGH BYTE */ +sfr at 0x8D P1IEN ; /* TIMER 1 - HIGH BYTE */ + +sfr at 0x8F P0INP ; /* FLASH WRITE/ERASE CONTROL */ +sfr at 0x90 P1 ; /* PORT 1 */ +sfr at 0x91 RFIM ; /* UART 0 STATUS */ +sfr at 0x92 DPS ; /* */ +sfr at 0x93 MPAGE ; /* */ +sfr at 0x94 _SFR94_ ; /* */ +sfr at 0x95 ENDIAN ; /* */ +sfr at 0x96 _SFR96_ ; /* */ +sfr at 0x97 _SFR97_ ; /* */ +sfr at 0x98 S0CON ; /* UART 0 CONTROL */ +sfr at 0x99 _SFR99_ ; /* UART 0 BUFFER */ +sfr at 0x9A IEN2 ; /* SPI 0 CONFIGURATION */ +sfr at 0x9B S1CON ; /* SPI 0 DATA */ +sfr at 0x9C T2CT ; /* SPI 0 DATA */ +sfr at 0x9D T2PR ; /* SPI 0 CLOCK RATE CONTROL */ +sfr at 0x9E T2CTL ; /* SPI 0 CLOCK RATE CONTROL */ +sfr at 0x9F _SFR9F_ ; /* SPI 0 CLOCK RATE CONTROL */ +sfr at 0xA0 P2 ; /* PORT 2 */ +sfr at 0xA1 WORIRQ ; /* EMIF TIMING CONTROL */ +sfr at 0xA2 WORCTRL ; /* EMIF CONTROL */ +sfr at 0xA3 WOREVT0 ; /* EMIF CONFIGURATION */ +sfr at 0xA4 WOREVT1 ; /* EMIF CONFIGURATION */ +sfr at 0xA5 WORTIME0 ; /* EMIF CONFIGURATION */ +sfr at 0xA6 WORTIME1 ; /* EMIF CONFIGURATION */ +sfr at 0xA7 _SFRA7_ ; /* EMIF CONFIGURATION */ +sfr at 0xA8 IEN0 ; /* INTERRUPT ENABLE */ +sfr at 0xA9 IP0 ; /* UART 0 SLAVE ADDRESS */ +sfr at 0xAA _SFRAA_ ; /* */ +sfr at 0xAB FWT ; /* */ +sfr at 0xAC FADDRL ; /* */ +sfr at 0xAD FADDRH ; /* */ +sfr at 0xAE FCTL ; /* */ +sfr at 0xAF FWDATA ; /* */ +sfr at 0xB0 _SFRB0_ ; /* */ +sfr at 0xB1 ENCDI ; /* FLASH BANK SELECT */ +sfr at 0xB2 ENCDO ; /* */ +sfr at 0xB3 ENCCS ; /* */ +sfr at 0xB4 ADCCON1 ; /* */ +sfr at 0xB5 ADCCON2 ; /* */ +sfr at 0xB6 ADCCON3 ; /* */ +sfr at 0xB8 IEN1 ; /* INTERRUPT PRIORITY */ +sfr at 0xB9 IP1 ; /* */ +sfr at 0xBA ADCL ; /* */ +sfr at 0xBB ADCH ; /* */ +sfr at 0xBC RNDL ; /* */ +sfr at 0xBD RNDH ; /* */ +sfr at 0xBE SLEEP ; /* */ +sfr at 0xC0 IRCON ; /* */ +sfr at 0xC1 U0DBUF ; /* */ +sfr at 0xC2 U0BAUD ; /* */ +sfr at 0xC4 U0UCR ; /* */ +sfr at 0xC5 U0GCR ; /* */ +sfr at 0xC6 CLKCON ; /* */ +sfr at 0xC7 MEMCTR ; /* */ +sfr at 0xC9 WDCTL ; /* */ +sfr at 0xCA T3CNT ; /* */ +sfr at 0xCB T3CTL ; /* */ +sfr at 0xCC T3CCTL0 ; /* */ +sfr at 0xCD T3CC0 ; /* */ +sfr at 0xCE T3CCTL1 ; /* */ +sfr at 0xCF T3CC1 ; /* */ +sfr at 0xD0 PSW ; /* */ +sfr at 0xD1 DMAIRQ ; /* */ +sfr at 0xD2 DMA1CFGL ; /* */ +sfr at 0xD3 DMA1CFGH ; /* */ +sfr at 0xD4 DMA0CFGL ; /* */ +sfr at 0xD5 DMA0CFGH ; /* */ +sfr at 0xD6 DMAARM ; /* */ +sfr at 0xD7 DMAREQ ; /* */ +sfr at 0xD8 TIMIF ; /* */ +sfr at 0xD9 RFD ; /* */ +sfr at 0xDA T1CC0L ; /* */ +sfr at 0xDB T1CC0H ; /* */ +sfr at 0xDC T1CC1L ; /* */ +sfr at 0xDD T1CC1H ; /* */ +sfr at 0xDE T1CC2L ; /* */ +sfr at 0xDF T1CC2H ; /* */ +sfr at 0xE0 ACC ; /* ACCUMULATOR */ +sfr at 0xE1 RFST ; /* */ +sfr at 0xE2 T1CNTL ; /* */ +sfr at 0xE3 T1CNTH ; /* */ +sfr at 0xE4 T1CTL ; /* */ +sfr at 0xE5 T1CCTL0 ; /* */ +sfr at 0xE6 T1CCTL1 ; /* */ +sfr at 0xE7 T1CCTL2 ; /* */ +sfr at 0xE8 IRCON2 ; /* */ +sfr at 0xE9 RFIF ; /* */ +sfr at 0xEA T4CNT ; /* */ +sfr at 0xEB T4CTL ; /* */ +sfr at 0xEC T4CCTL0 ; /* */ +sfr at 0xED T4CC0 ; /* */ +sfr at 0xEE T4CCTL1 ; /* */ +sfr at 0xEF T4CC1 ; /* */ +sfr at 0xF0 B ; /* */ +sfr at 0xF1 PERCFG ; /* */ +sfr at 0xF2 ADCCFG ; /* */ +sfr at 0xF3 P0SEL ; /* */ +sfr at 0xF4 P1SEL ; /* */ +sfr at 0xF5 P2SEL ; /* */ +sfr at 0xF6 P1INP ; /* */ +sfr at 0xF7 P2INP ; /* */ +sfr at 0xF8 U1CSR ; /* */ +sfr at 0xF9 U1DBUF ; /* */ +sfr at 0xFA U1BAUD ; /* */ +sfr at 0xFB U1UCR ; /* */ +sfr at 0xFC U1GCR ; /* */ +sfr at 0xFD P0DIR ; /* */ +sfr at 0xFE P1DIR ; /* */ +sfr at 0xFF P2DIR ; /* */ + +/* BIT Registers */ + +/* P0 0x80 */ +sbit at 0x80 P0_0 ; +sbit at 0x81 P0_1 ; +sbit at 0x82 P0_2 ; +sbit at 0x83 P0_3 ; +sbit at 0x84 P0_4 ; +sbit at 0x85 P0_5 ; +sbit at 0x86 P0_6 ; +sbit at 0x87 P0_7 ; + +/* TCON 0x88 */ +sbit at 0x89 RFTXRXIF; /* */ +sbit at 0x8B URX0IF ; /* */ +sbit at 0x8D ADCIF ; /* */ +sbit at 0x8F URX1IF ; /* */ +sbit at 0x8F I2SRXIF ; /* */ + +/* SCON0 0x98 */ +sbit at 0x98 ENCIF_0 ; /* UART 0 RX INTERRUPT FLAG */ +sbit at 0x99 ENCIF_1 ; /* UART 0 RX INTERRUPT FLAG */ + +/* IEN0 0xA8 */ +sbit at 0xA8 RFTXRXIE; /* RF TX/RX done interrupt enable */ +sbit at 0xA9 ADCIE ; /* ADC interrupt enable */ +sbit at 0xAA URX0IE ; /* USART0 RX interrupt enable */ +sbit at 0xAB URX1IE ; /* USART1 RX interrupt enable */ +sbit at 0xAB I2SRXIE ; /* I2S RX interrupt enable */ +sbit at 0xAC ENCIE ; /* AES interrupt enable */ +sbit at 0xAD STIE ; /* Sleep Timer interrupt enable */ +sbit at 0xAF EA ; /* GLOBAL INTERRUPT ENABLE */ + +/* IEN1 0xB8 */ +sbit at 0xB8 DMAIE ; /* DMA transfer interrupt enable */ +sbit at 0xB9 T1IE ; /* Timer 1 interrupt enable */ +sbit at 0xBA T2IE ; /* Timer 2 interrupt enable */ +sbit at 0xBB T3IE ; /* Timer 3 interrupt enable */ +sbit at 0xBC T4IE ; /* Timer 4 interrupt enable */ +sbit at 0xBD P0IE ; /* Port 0 interrupt enable */ + +/* IRCON 0xC0 */ +sbit at 0xC0 DMAIF ; /* */ +sbit at 0xC1 T1IF ; /* */ +sbit at 0xC2 T2IF ; /* */ +sbit at 0xC3 T3IF ; /* */ +sbit at 0xC4 T4IF ; /* */ +sbit at 0xC5 P0IF ; /* */ +sbit at 0xC7 STIF ; /* */ + +/* PSW 0xD0 */ +sbit at 0xD0 P ; /* ACCUMULATOR PARITY FLAG */ +sbit at 0xD1 F1 ; /* USER FLAG 1 */ +sbit at 0xD2 OV ; /* OVERFLOW FLAG */ +sbit at 0xD3 RS0 ; /* REGISTER BANK SELECT 0 */ +sbit at 0xD4 RS1 ; /* REGISTER BANK SELECT 1 */ +sbit at 0xD5 F0 ; /* USER FLAG 0 */ +sbit at 0xD6 AC ; /* AUXILIARY CARRY FLAG */ +sbit at 0xD7 CY ; /* CARRY FLAG */ + +/* TIMIF D8H */ +sbit at 0xD8 T3OVFIF ; /* */ +sbit at 0xD9 T3CH0IF ; /* */ +sbit at 0xDA T3CH1IF ; /* */ +sbit at 0xDB T4OVFIF ; /* */ +sbit at 0xDC T4CH0IF ; /* */ +sbit at 0xDD T4CH1IF ; /* */ +sbit at 0xDE OVFIM ; /* */ + +/* IRCON2 E8H */ +sbit at 0xE8 P2IF ; /* */ +sbit at 0xE8 USBIF ; /* */ +sbit at 0xE9 UTX0IF ; /* */ +sbit at 0xEA UTX1IF ; /* */ +sbit at 0xEA I2STXIF ; /* */ +sbit at 0xEB P1IF ; /* */ +sbit at 0xEC WDTIF ; /* */ + +/* U1CSR F8H */ +sbit at 0xF8 U1_ACTIVE ; /* */ +sbit at 0xF9 U1_TX_BYTE ; /* */ +sbit at 0xFA U1_RX_BYTE ; /* */ +sbit at 0xFB U1_ERR ; /* */ +sbit at 0xFC U1_FE ; /* */ +sbit at 0xFD U1_SLAVE ; /* */ +sbit at 0xFE U1_RE ; /* */ +sbit at 0xFF U1_MODE ; /* */ + +#define T1CTL_MODE_SUSPENDED (0 << 0) +#define T1CTL_MODE_FREE (1 << 0) +#define T1CTL_MODE_MODULO (2 << 0) +#define T1CTL_MODE_UP_DOWN (3 << 0) +#define T1CTL_MODE_MASK (3 << 0) +#define T1CTL_DIV_1 (0 << 2) +#define T1CTL_DIV_8 (1 << 2) +#define T1CTL_DIV_32 (2 << 2) +#define T1CTL_DIV_128 (3 << 2) +#define T1CTL_DIV_MASK (3 << 2) +#define T1CTL_OVFIF (1 << 4) +#define T1CTL_CH0IF (1 << 5) +#define T1CTL_CH1IF (1 << 6) +#define T1CTL_CH2IF (1 << 7) + +#define T1CCTL_NO_CAPTURE (0 << 0) +#define T1CCTL_CAPTURE_RISING (1 << 0) +#define T1CCTL_CAPTURE_FALLING (2 << 0) +#define T1CCTL_CAPTURE_BOTH (3 << 0) +#define T1CCTL_CAPTURE_MASK (3 << 0) + +#define T1CCTL_MODE_CAPTURE (0 << 2) +#define T1CCTL_MODE_COMPARE (1 << 2) + +#define T1CTL_CMP_SET (0 << 3) +#define T1CTL_CMP_CLEAR (1 << 3) +#define T1CTL_CMP_TOGGLE (2 << 3) +#define T1CTL_CMP_SET_CLEAR (3 << 3) +#define T1CTL_CMP_CLEAR_SET (4 << 3) + +#define T1CTL_IM_DISABLED (0 << 6) +#define T1CTL_IM_ENABLED (1 << 6) + +#define T1CTL_CPSEL_NORMAL (0 << 7) +#define T1CTL_CPSEL_RF (1 << 7) + +#endif diff --git a/target/timer/timer.c b/target/timer/timer.c new file mode 100644 index 00000000..ae75d0a8 --- /dev/null +++ b/target/timer/timer.c @@ -0,0 +1,55 @@ +/* + * 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 "cc1111.h" + +unsigned char irqs; + +void timer1_isr(void) interrupt 9 __reentrant +{ + ++irqs; + if (irqs == 100) { + P1 ^= 0x2; + irqs = 0; + } +} + +int +main (void) __reentrant +{ + CLKCON = 0; + P1DIR = 0x2; + P1 = 0xff; + + T1CTL = 0; + + /* 30000 */ + T1CC0H = 0x75; + T1CC0L = 0x30; + T1CCTL0 = T1CCTL_MODE_COMPARE; + T1CCTL1 = 0; + T1CCTL2 = 0; + + /* clear timer value */ + T1CNTL = 0; + OVFIM = 1; + T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8; + T1IE = 1; + EA = 1; + for (;;); +} -- cgit v1.2.3 From 1ccfe0887c794397131ab1c986c25f66eea86a6c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 Jan 2009 21:43:44 -0800 Subject: Have S51 ignore SIGINT while running under sdcdb. This prevents keyboard interrupts from accidentally stopping s51. Signed-off-by: Keith Packard --- s51/s51-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s51/s51-main.c b/s51/s51-main.c index eef55157..96429988 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -150,7 +150,7 @@ main(int argc, char **argv) perror("fdopen"); exit(1); } - vec.sv_handler = s51_sigint; + vec.sv_handler = SIG_IGN; vec.sv_mask = 0; vec.sv_flags = 0; sigvec(SIGINT, &vec, &ovec); -- cgit v1.2.3 From eb09e61b0682eb2aeac8e1a34d58b897ba6db8e7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 Jan 2009 21:44:44 -0800 Subject: Use custom sdcc libraries (this needs to be configured...) Signed-off-by: Keith Packard --- target/simple/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/simple/Makefile b/target/simple/Makefile index c4432325..70c0f888 100644 --- a/target/simple/Makefile +++ b/target/simple/Makefile @@ -7,7 +7,7 @@ CFLAGS=--model-large $(DEBUG) --less-pedantic \ --no-peep --int-long-reent --float-reent \ --data-loc 0x30 -LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS=-L/local/share/sdcc/lib/large --out-fmt-ihx LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 -- cgit v1.2.3 From 60940b4be23962db79b8e914ec943d0636dd68ad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 Jan 2009 21:45:21 -0800 Subject: Expose ccdbg_set_clock API This allows applications to change the debug port clock rate on the fly. Signed-off-by: Keith Packard --- lib/ccdbg-io.c | 12 ++++++++++-- lib/ccdbg.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index 53ea7583..e5e85e43 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -24,12 +24,20 @@ #include "cp-usb.h" #endif +static uint32_t cc_clock_us = CC_CLOCK_US; + +void +ccdbg_set_clock(uint32_t us) +{ + cc_clock_us = us; +} + void ccdbg_half_clock(struct ccdbg *dbg) { struct timespec req, rem; - req.tv_sec = (CC_CLOCK_US / 2) / 1000000; - req.tv_nsec = ((CC_CLOCK_US / 2) % 1000000) * 1000; + req.tv_sec = (cc_clock_us / 2) / 1000000; + req.tv_nsec = ((cc_clock_us / 2) % 1000000) * 1000; nanosleep(&req, &rem); } diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 241c4eec..037d8ff5 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -258,6 +258,9 @@ int ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); /* ccdbg-io.c */ +void +ccdbg_set_clock(uint32_t us); + void ccdbg_half_clock(struct ccdbg *dbg); -- cgit v1.2.3 From 3cc8d11eb8d5d0b42141dd84a58d461287f59e3a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 Jan 2009 08:38:48 -0800 Subject: Support 'set' command The 'set' command modifies target memory and registers Signed-off-by: Keith Packard --- s51/s51-command.c | 30 +++++++++++++++++++++++++++++- s51/s51-parse.c | 4 ++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/s51/s51-command.c b/s51/s51-command.c index 63d142f4..034d5dce 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -152,7 +152,35 @@ command_dx (int argc, char **argv) enum command_result command_set (int argc, char **argv) { - return command_error; + uint16_t address; + uint8_t *data; + int len = argc - 3; + int i; + enum command_result ret = command_success; + + if (len < 0) + return command_error; + if (parse_uint16(argv[2], &address) != command_success) + return command_error; + if (len == 0) + return command_success; + data = malloc(len); + if (!data) + return command_error; + for (i = 0; i < len; i++) + if (parse_uint8(argv[i+3], &data[i]) != command_success) + return command_error; + + if (strcmp(argv[1], "xram") == 0) { + ccdbg_write_memory(s51_dbg, address, data, len); + } else if (strcmp(argv[1], "iram") == 0) { + ccdbg_write_memory(s51_dbg, address + 0xff00, data, len); + } else if (strcmp(argv[1], "sfr") == 0) { + ccdbg_write_sfr(s51_dbg, (uint8_t) address, data, len); + } else + ret = command_error; + free(data); + return ret; } enum command_result diff --git a/s51/s51-parse.c b/s51/s51-parse.c index 749d7bd8..aba45485 100644 --- a/s51/s51-parse.c +++ b/s51/s51-parse.c @@ -27,8 +27,8 @@ static struct command_function functions[] = { "Dump sprs\n" }, { "dx", "dx", command_dx, "dx ", "Dump xaddr\n" }, - { "set", "t", command_set, "se[t] mem ", - "Set mem {xram|rom|iram|sfr} \n" + { "set", "t", command_set, "se[t] mem
...", + "Set mem {xram|rom|iram|sfr}\n" "set bit \n" }, { "dump", "d", command_dump, "[d]ump ", "Dump {xram|rom|iram|sfr} \n" }, -- cgit v1.2.3 From f7d91bd23b8214e09deae0aafb516331e934c49b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 1 Mar 2009 18:43:03 -0800 Subject: Sometimes the link breaks and the GET_PC command returns garbage --- lib/ccdbg-command.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c index 2b29fdee..d99e8ff3 100644 --- a/lib/ccdbg-command.c +++ b/lib/ccdbg-command.c @@ -70,7 +70,14 @@ ccdbg_rd_config(struct ccdbg *dbg) uint16_t ccdbg_get_pc(struct ccdbg *dbg) { - return ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); + uint16_t pc1, pc2; + + pc1 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); + pc2 = ccdbg_cmd_write_read16(dbg, CC_GET_PC, NULL, 0); + if (pc1 != pc2) + fprintf (stderr, "Invalid pc %04x != %04x\n", + pc1, pc2); + return pc2; } uint8_t -- cgit v1.2.3 From fdee231ed097a4348aee78fbd4aa92826b80de03 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 1 Mar 2009 23:12:31 -0800 Subject: Add s51 manual. This documents (briefly) the s51 hex debugging interface program, including some simple commands to test the operation of the system interactively. Signed-off-by: Keith Packard --- s51/Makefile.am | 2 + s51/s51.1 | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 s51/s51.1 diff --git a/s51/Makefile.am b/s51/Makefile.am index fa6fc692..6213750c 100644 --- a/s51/Makefile.am +++ b/s51/Makefile.am @@ -3,6 +3,8 @@ bin_PROGRAMS=s51 AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) S51_LIBS=../lib/libcc.a +man_MANS = s51.1 + s51_DEPENDENCIES = $(S51_LIBS) s51_LDADD=$(S51_LIBS) $(LIBUSB_LIBS) diff --git a/s51/s51.1 b/s51/s51.1 new file mode 100644 index 00000000..f17f4810 --- /dev/null +++ b/s51/s51.1 @@ -0,0 +1,210 @@ +.\" +.\" Copyright © 2009 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. +.\" +.\" +.TH S51 1 "s51" "" +.SH NAME +s51 \- hex debugger for cc1111 processors +.SH SYNOPSIS +.B "s51" +[\-t \fIcpu-type\fP] +[\-X \fIfrequency\fP] +[\-c] +[\-r \fIlisten-port\fP] +[\-Z \fIlisten-port\fP] +[\-s] +[\-S] +[\-p \fIprompt\fP] +[\-V] +[\-v] +[\-H] +[\-h] +[\-m] +.SH DESCRIPTION +.I s51 +connects to a cc1111 processor through a cp1203-based USB-to-serial +converter board, using the GPIO pins available on that chip. It provides an +interface compatible with the 8051 emulator of the same name (s51), but +communicating with the real chip instead of an emulation. Using a modified +version of the SDCC debugger (sdcdb), you can control program execution +on the target machine at source-level. + +.SH OPTIONS +The command line options are designed to be compatible with the 8051 +emulator so that it can be used with sdcdb. As such, they're all one letter +long. +.IP "\-t \fIcpu-type\fP" +The 8051 emulator can operate as one of several different chips. Oddly, the +real hardware cannot, so this option is ignored. +.IP "\-X \fIfrequency\fP" +Similarly, the emulator can pretend to run at an arbitrary frequency +which the real hardware cannot do. Ignored. +.IP "\-c" +.IP "\-s" +.IP "\-S" +.IP "\-v" +.IP "\-V" +All ignored. +.IP "\-r \fIlisten-port\fP, -Z \fIlisten-port\fP" +The emulator and sdcdb communicate through a network socket. This option +switches the debugger from communicating through stdin/stdout to listening +on a specific network port instead. Once a connection is made, the debugger +continues on, using that network port for command input and output. The +debugger uses port 9756, and attempts to connect before launching s51, so if +s51 is listening on this port before sdcdb is started, sdcdb will end up +talking to the existing s51 instance. That's often useful for debugging s51 +itself. +.IP "\-p \fIprompt\fP" +This sets the command prompt to the specified string. +.IP "\-P" +This sets the command prompt to a single NUL character. This is for use by +sdcdb. +.IP "\-h" +This should print a usage message, but does nothing useful currently. +.IP "\-m" +This option is not present in the original 8051 emulator, and causes s51 to +dump all commands and replies that are received from and sent to sdcdb. +.SH COMMANDS +Once started, s51 connects to the cc1111 via the CP2103 using libusb2 and +then reads and executes commands, either from stdin, or the nework +connection to sdcdb. +.PP +Unlike the command line, s51 contains built-in help for each of these +commands, via the 'help' command. Most of the commands are available in a +long form and a single character short form. Below, the short form follows +the long form after a comma. +.IP "help, ? {command}" +Without arguments, prints a list of available commands. With an argument +prints more detail about the specific command +.IP "quit, q" +Terminates the application, without changing the state of the target +processor. +.IP "di [start] [end]" +Dumps imem (256 bytes of "internal" memory) from start to end (inclusive). +.IP "ds [start] [end]" +Dumps sprs from start to end (inclusive). Note that while most sprs are +visible in the global address space, some are not, so use this command +instead of "dx" to read them. +.IP "dx [start] [end]" +Dump external (global) memory from start to end (inclusive). +.IP "set, t [start] {data ...}" +Store to the memory space specified by prefix where prefix is one of "xram", +"rom", "iram", or "sfr". Store bytes starting at start. +.IP "dump, d [start] [end]" +Dump from the memory space specified by prefix, where prefix is one of +"xram", "rom", "iram" or "sfr". Dumps from start to end (inclusive). +.IP "file [filename]" +Specifies an intel-format hex file (ihx) that contains the contents of the +rom area loaded into the cc1111. This is used to respond to requests to dump +rom memory contents without getting them from the cc1111 (which is slow). +.IP "pc, p {address}" +If the address argument is given, this sets the program counter to the +specified value. Otherwise, the current program counter value is displayed. +.IP "break, b [address]" +Sets a breakpoint at the specified address. This uses the built-in hardware +breakpoint support in the cc1111. As a result, it supports no more than four +breakpoints at once. You must therefore use a modified version of sdcdb which +changes how program execution is controlled to work within this limit. +.IP "clear, c [address]" +Clear a breakpoint from the specified address. +.IP "run, r, go, g {start} {stop}" +Resumes execution of the program. If the start argument is present, then it +begins at that address, otherwise it continues running at the current pc. If +a stop argument is present, then a temporary breakpoint is set at that +address. This temporary breakpoint will be removed when execution hits it. +.IP "next, n" +Step one instruction. In the original s51 program this would ignore +subroutines, but as sdcdb doesn't require this functionality, it's not +available here. +.IP "step, s" +Step one instruction. +.IP "load, l [filename]" +This is not implemented, but it is supposed to load a hex file into flash. +Use the ccload program instead. +.IP "halt, h" +Halt the processor. This is the only command which can be sent while the +program is running. It is ignored at other times. +.IP "reset, res" +Reset the processor. This pulls the reset pin low and re-enables debug mode. +Check the cc1111 documentation to see precisely what this does. +.IP "status" +This dumps the cc1111 debug status register. +.IP "info, i breakpoints, b" +List the current breakpoints. +.IP "info, i help, ?" +List the things you can get info on. +.IP "stop" +This doesn't do anything and is present only to retain compatibility with +the original 8051 emulator. +.SH "BOARD BRINGUP DEBUGGING" +.PP While the original purpose for this program was to connect the source +debugger with the hardware, it can also be used as a low-level hex debugger +all on its own. In particular, all of the cc1111 peripherals can be +manipulated directly from the s51 command line. +.IP "Starting s51" +If the CP2103 is plugged in, and the CC1111 is connected correctly, the +'s51' command itself should connect to the device without trouble. Note that +the CP2103 must have the GPIO pins configured correctly as well. +.IP +$ s51 +.br +Welcome to the non-simulated processor +.br +> status +.br + CPU halted +.br + Halted by debug command +.br +> +.IP "Turning on LEDs" +Two of the cc1111 GPIO pins, P1_0 and P1_1 are capable of driving external +LEDs. To control these, set the Port 1 direction bits to make these output +pins and then change the Port 1 data to set them high or low: +.IP +> set sfr 0xfe 0x02 # set P1DIR to 0x2 +.br +> set sfr 0x90 0x02 # set P1_1 to high +.br +> set sfr 0x90 0x00 # set P1_1 to low +.IP "Reading the A/D converters" +The six A/D converter inputs can each be connected to any of the P0 pins, +ground, the A/D voltage refernece, an internal temperature sensor or VDD/3. +To read one of these values, select an A/D converter to use then start the +conversion process. The cc1111 manual has the table for selecting the input +on page 144. +.IP +To configure one of the P0 pins for use by the A/D unit, we program the +ADCCFG register, setting the bits in that which match the pins desired: +.IP +> set sfr 0xf2 0x3f # enable all 6 A/D inputs +.IP +To trigger a single conversion, we as the A/D unit to perform an 'extra' +conversion, which means to do a single conversion not a whole sequence of +conversions. This is controlled by the ADCCON3 register at 0xB6: +.IP +> set sfr 0xb6 0xb2 # sample P0_2 using 12 bits of precision +.br +> ds 0xba 0xbb # dump the ADC data low and high regs +.br +> set sfr 0xb6 0xbe # sample internal temperature sensor +.br +> ds 0xba 0xbb # dump the ADC data low and high regs +.SH "SEE ALSO" +sdcdb(1), ccload(1) +.SH AUTHOR +Keith Packard -- cgit v1.2.3 From 41289e6d8f1767547a33fea349866e928e44910f Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 2 Mar 2009 07:46:20 -0700 Subject: minor s51.1 formatting fixes Signed-off-by: Keith Packard --- s51/s51.1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/s51/s51.1 b/s51/s51.1 index f17f4810..c283950e 100644 --- a/s51/s51.1 +++ b/s51/s51.1 @@ -151,14 +151,15 @@ List the things you can get info on. This doesn't do anything and is present only to retain compatibility with the original 8051 emulator. .SH "BOARD BRINGUP DEBUGGING" -.PP While the original purpose for this program was to connect the source +.PP +While the original purpose for this program was to connect the source debugger with the hardware, it can also be used as a low-level hex debugger all on its own. In particular, all of the cc1111 peripherals can be manipulated directly from the s51 command line. .IP "Starting s51" If the CP2103 is plugged in, and the CC1111 is connected correctly, the -'s51' command itself should connect to the device without trouble. Note that -the CP2103 must have the GPIO pins configured correctly as well. +\'s51\' command itself should connect to the device without trouble. +Note that the CP2103 must have the GPIO pins configured correctly as well. .IP $ s51 .br @@ -193,7 +194,7 @@ ADCCFG register, setting the bits in that which match the pins desired: .IP > set sfr 0xf2 0x3f # enable all 6 A/D inputs .IP -To trigger a single conversion, we as the A/D unit to perform an 'extra' +To trigger a single conversion, we ask the A/D unit to perform an 'extra' conversion, which means to do a single conversion not a whole sequence of conversions. This is controlled by the ADCCON3 register at 0xB6: .IP -- cgit v1.2.3 From cc0495b7028f4b1189a00707d828a68534d1dea2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Mar 2009 22:52:35 -0800 Subject: Wait for a while when switching the RESET_N line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cc1111 manual suggests placing a 2.7kΩ resister and 1nF capacitor on the RESET_N line to filter out noise. This increases the time necessary to reset the chip to several microseconds which is longer than the interval between two USB packets. Flush the USB packet queue and sleep for a while after changing the value on the RESET_N line to make sure the chip sees the state change. Signed-off-by: Keith Packard --- lib/ccdbg-command.c | 6 ++++-- lib/ccdbg-io.c | 12 ++++++++++++ lib/ccdbg.h | 9 +++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c index d99e8ff3..74313bdf 100644 --- a/lib/ccdbg-command.c +++ b/lib/ccdbg-command.c @@ -27,11 +27,12 @@ ccdbg_debug_mode(struct ccdbg *dbg) ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + ccdbg_wait_reset(dbg); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); - ccdbg_sync_io(dbg); + ccdbg_wait_reset(dbg); } void @@ -42,11 +43,12 @@ ccdbg_reset(struct ccdbg *dbg) ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + ccdbg_wait_reset(dbg); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_sync_io(dbg); + ccdbg_wait_reset(dbg); } uint8_t diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index e5e85e43..3606c57c 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -25,6 +25,7 @@ #endif static uint32_t cc_clock_us = CC_CLOCK_US; +static uint32_t cc_reset_us = CC_RESET_US; void ccdbg_set_clock(uint32_t us) @@ -41,6 +42,17 @@ ccdbg_half_clock(struct ccdbg *dbg) nanosleep(&req, &rem); } +void +ccdbg_wait_reset(struct ccdbg *dbg) +{ + struct timespec req, rem; + + ccdbg_sync_io(dbg); + req.tv_sec = (cc_reset_us) / 1000000; + req.tv_nsec = ((cc_reset_us) % 1000000) * 1000; + nanosleep(&req, &rem); +} + struct ccdbg * ccdbg_open(void) { diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 037d8ff5..8bc9444a 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -37,6 +37,12 @@ #define CC_RESET_N 0x4 #define CC_CLOCK_US (0) +/* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground + * and a 2.7k resistor to the reset line. This takes about 6us + * to settle, so we'll wait longer than that after changing the reset line + */ +#define CC_RESET_US (12) + /* 8051 instructions */ #define NOP 0x00 @@ -264,6 +270,9 @@ ccdbg_set_clock(uint32_t us); void ccdbg_half_clock(struct ccdbg *dbg); +void +ccdbg_wait_reset(struct ccdbg *dbg); + int ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); -- cgit v1.2.3 From 5a338c8a7394d003355f96a8777b6fe83bb8493c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 14:48:35 -0800 Subject: Flip debug pins around to match telemetrum --- lib/ccdbg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ccdbg.h b/lib/ccdbg.h index 8bc9444a..dbb2a907 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -32,10 +32,10 @@ #include #include "ccdbg-debug.h" -#define CC_CLOCK 0x1 +#define CC_CLOCK 0x4 #define CC_DATA 0x2 -#define CC_RESET_N 0x4 -#define CC_CLOCK_US (0) +#define CC_RESET_N 0x1 +#define CC_CLOCK_US (1000) /* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground * and a 2.7k resistor to the reset line. This takes about 6us -- cgit v1.2.3 From 77d754afc2d14aaa4413c13ebe3777ef385f62a9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 14:48:49 -0800 Subject: Sync after manual bit reading --- lib/ccdbg-manual.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ccdbg-manual.c b/lib/ccdbg-manual.c index b48f8bb1..4bbf0879 100644 --- a/lib/ccdbg-manual.c +++ b/lib/ccdbg-manual.c @@ -60,6 +60,7 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { uint8_t read; ccdbg_read(dbg, &read); + ccdbg_sync_io(dbg); ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); if ((set & CC_CLOCK) == 0) printf ("\t%d", (read&CC_DATA) ? 1 : 0); -- cgit v1.2.3 From e63b5271bb54afc36e4b9891e51e053ff6011092 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 14:49:22 -0800 Subject: Add ccmanual --- Makefile.am | 2 +- ccmanual/Makefile.am | 10 ++++++++++ ccmanual/ccmanual.c | 33 +++++++++++++++++++++++++++++++++ configure.ac | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ccmanual/Makefile.am create mode 100644 ccmanual/ccmanual.c diff --git a/Makefile.am b/Makefile.am index 11b0b700..8a061ab7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ccload s51 target/blink +SUBDIRS=lib ccload s51 ccmanual target/blink diff --git a/ccmanual/Makefile.am b/ccmanual/Makefile.am new file mode 100644 index 00000000..4477ef8a --- /dev/null +++ b/ccmanual/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS=ccmanual + +AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) +CCMANUAL_LIBS=../lib/libcc.a + +ccmanual_DEPENDENCIES = $(CCMANUAL_LIBS) + +ccmanual_LDADD=$(CCMANUAL_LIBS) $(LIBUSB_LIBS) + +ccmanual_SOURCES = ccmanual.c diff --git a/ccmanual/ccmanual.c b/ccmanual/ccmanual.c new file mode 100644 index 00000000..402d9b13 --- /dev/null +++ b/ccmanual/ccmanual.c @@ -0,0 +1,33 @@ +/* + * Copyright © 2009 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" + +int +main (int argc, char **argv) +{ + struct ccdbg *dbg; + + dbg = ccdbg_open(); + if (!dbg) + exit (1); + + ccdbg_add_debug(CC_DEBUG_BITBANG); + + ccdbg_manual(dbg, stdin); +} diff --git a/configure.ac b/configure.ac index 3ae80522..516657ea 100644 --- a/configure.ac +++ b/configure.ac @@ -97,4 +97,5 @@ Makefile lib/Makefile ccload/Makefile s51/Makefile +ccmanual/Makefile ]) -- cgit v1.2.3 From ade11f88754b4ab0386ebf86afc5257e59238f62 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 21:04:38 -0800 Subject: Make manual bit flipping sync after every transaction --- lib/ccdbg-manual.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ccdbg-manual.c b/lib/ccdbg-manual.c index 4bbf0879..df79d88d 100644 --- a/lib/ccdbg-manual.c +++ b/lib/ccdbg-manual.c @@ -67,5 +67,6 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) printf ("\n"); } ccdbg_send(dbg, mask, set); + ccdbg_sync_io(dbg); } } -- cgit v1.2.3 From c8fd04e154bcfd65ae1200980bd8163caabd7fe4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 21:05:06 -0800 Subject: The debug port only works if reset is higher than clock. weird --- lib/ccdbg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ccdbg.h b/lib/ccdbg.h index dbb2a907..f6e216c4 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -32,9 +32,9 @@ #include #include "ccdbg-debug.h" -#define CC_CLOCK 0x4 +#define CC_CLOCK 0x1 #define CC_DATA 0x2 -#define CC_RESET_N 0x1 +#define CC_RESET_N 0x4 #define CC_CLOCK_US (1000) /* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground -- cgit v1.2.3 From 9fd63972758d6d5572f7bcaadec9b1c0e974a2e8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2009 21:05:40 -0800 Subject: Only flip changing bits in async mode --- lib/cp-usb-async.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/cp-usb-async.c b/lib/cp-usb-async.c index 3f5f76ab..1fe09aad 100644 --- a/lib/cp-usb-async.c +++ b/lib/cp-usb-async.c @@ -38,6 +38,8 @@ struct cp_usb_async { libusb_device_handle *handle; struct cp_usb_packet packet[MAX_OUTSTANDING]; int p, ack; + uint8_t value; + uint8_t set; }; struct cp_usb_async * @@ -56,11 +58,14 @@ cp_usb_async_open(void) } cp->handle = libusb_open_device_with_vid_pid(cp->ctx, 0x10c4, 0xea60); + cp->ack = -1; if (!cp->handle) { libusb_exit(cp->ctx); free(cp); return NULL; } + cp->value = 0; + cp->set = 0; return cp; } @@ -103,9 +108,16 @@ void cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value) { int p; - uint16_t gpio_set = ((uint16_t) value << 8) | mask; + uint16_t gpio_set; int ret; + if (cp->set) { + value = (cp->value & ~mask) | (value & mask); + mask = value ^ cp->value; + } + cp->set = 1; + cp->value = value; + gpio_set = ((uint16_t) value << 8) | mask; if (cp->p == MAX_OUTSTANDING) cp_usb_async_sync(cp); p = cp->p; @@ -172,5 +184,5 @@ cp_usb_async_sync(struct cp_usb_async *cp) libusb_handle_events(cp->ctx); } cp->p = 0; - cp->ack = 0; + cp->ack = -1; } -- cgit v1.2.3 From 04a316133af93b79bfbebb91f05eec1015ec2abc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Mar 2009 18:10:43 -0700 Subject: Bump debug speed back up --- lib/ccdbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ccdbg.h b/lib/ccdbg.h index f6e216c4..e0e12c8b 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -35,7 +35,7 @@ #define CC_CLOCK 0x1 #define CC_DATA 0x2 #define CC_RESET_N 0x4 -#define CC_CLOCK_US (1000) +#define CC_CLOCK_US (2) /* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground * and a 2.7k resistor to the reset line. This takes about 6us -- cgit v1.2.3 From 164b4e4749ad64ebbe26e84fd7b4fa1aa733dbe4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Mar 2009 18:11:20 -0700 Subject: sdcc gets the lib path correct based on the model --- target/blink/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/blink/Makefile b/target/blink/Makefile index 4c9b4102..d0112e62 100644 --- a/target/blink/Makefile +++ b/target/blink/Makefile @@ -7,7 +7,7 @@ CFLAGS=--model-large $(DEBUG) --less-pedantic \ --no-peep --int-long-reent --float-reent \ --data-loc 0x30 -LDFLAGS=-L/usr/share/sdcc/lib/large --out-fmt-ihx +LDFLAGS=--out-fmt-ihx LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 -- cgit v1.2.3 From 25b77d236c01258abfc03114c2fc9ea2d69ca6e7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Mar 2009 18:11:53 -0700 Subject: Add telemetrum beeper example --- target/beep/Makefile | 46 +++++++++++++++++++++++++++ target/beep/beep.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 target/beep/Makefile create mode 100644 target/beep/beep.c diff --git a/target/beep/Makefile b/target/beep/Makefile new file mode 100644 index 00000000..8f600b4a --- /dev/null +++ b/target/beep/Makefile @@ -0,0 +1,46 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=beep.c +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=beep-flash.ihx beep-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +beep-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o beep-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o beep-flash.ihx $(REL) + +beep-flash.ihx: beep-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/beep/beep.c b/target/beep/beep.c new file mode 100644 index 00000000..08422082 --- /dev/null +++ b/target/beep/beep.c @@ -0,0 +1,89 @@ +/* + * 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. + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + + n <<= 1; + while (--n != 0) + while (--i != 0) + nop(); +} + +void +tone (unsigned char n, unsigned char m) +{ + unsigned char i = 0; + while (--m != 0) { + while (--i != 0) { + P2 = 0xff; + delay(n); + P2 = 0xfe; + delay(n); + } + } +} + +void +high() { + tone(1, 2); +} + +void +low() { + tone(2, 1); +} + +main () +{ + CLKCON = 0; + /* Set p1_1 to output */ + P2DIR = 0x01; + P1INP = 0x00; + P2INP = 0x00; + for (;;) { + high(); + low(); + } +} -- cgit v1.2.3 From a0a27600ee2bf237e74eb83767a8d2e7c91df24f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Mar 2009 18:14:21 -0700 Subject: Correctly comment which bit the beep program uses --- target/beep/beep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/beep/beep.c b/target/beep/beep.c index 08422082..3dd31d54 100644 --- a/target/beep/beep.c +++ b/target/beep/beep.c @@ -78,7 +78,7 @@ low() { main () { CLKCON = 0; - /* Set p1_1 to output */ + /* Set P2_0 to output */ P2DIR = 0x01; P1INP = 0x00; P2INP = 0x00; -- cgit v1.2.3 From 4726317de811c20e8d6754762437b5c9cbb3a48c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Mar 2009 01:54:34 -0700 Subject: Add simple test program to light up the transmitter at 434.550MHz This starts a transmit sequence, but doesn't send any data so the transmitter just locks on. --- target/radio/Makefile | 46 +++++ target/radio/radio.c | 525 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 571 insertions(+) create mode 100644 target/radio/Makefile create mode 100644 target/radio/radio.c diff --git a/target/radio/Makefile b/target/radio/Makefile new file mode 100644 index 00000000..a26fa458 --- /dev/null +++ b/target/radio/Makefile @@ -0,0 +1,46 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=radio.c +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=radio-flash.ihx radio-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +radio-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o radio-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o radio-flash.ihx $(REL) + +radio-flash.ihx: radio-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/radio/radio.c b/target/radio/radio.c new file mode 100644 index 00000000..9f10fccd --- /dev/null +++ b/target/radio/radio.c @@ -0,0 +1,525 @@ +/* + * 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 + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sfr at 0xD9 RFD; +sfr at 0xE9 RFIF; +sfr at 0xE1 RFST; + +sfr at 0x88 TCON; + +sbit at 0x89 RFTXRXIF; + +#define TCON_RFTXRXIF (1 << 1) + +#define RFST_SFSTXON 0x00 +#define RFST_SCAL 0x01 +#define RFST_SRX 0x02 +#define RFST_STX 0x03 +#define RFST_SIDLE 0x04 + +__xdata __at (0xdf00) uint8_t RF[0x3c]; + +__xdata __at (0xdf2f) uint8_t RF_IOCFG2; +#define RF_IOCFG2_OFF 0x2f + +__xdata __at (0xdf30) uint8_t RF_IOCFG1; +#define RF_IOCFG1_OFF 0x30 + +__xdata __at (0xdf31) uint8_t RF_IOCFG0; +#define RF_IOCFG0_OFF 0x31 + +__xdata __at (0xdf00) uint8_t RF_SYNC1; +#define RF_SYNC1_OFF 0x00 + +__xdata __at (0xdf01) uint8_t RF_SYNC0; +#define RF_SYNC0_OFF 0x01 + +__xdata __at (0xdf02) uint8_t RF_PKTLEN; +#define RF_PKTLEN_OFF 0x02 + +__xdata __at (0xdf03) uint8_t RF_PKTCTRL1; +#define RF_PKTCTRL1_OFF 0x03 + +__xdata __at (0xdf04) uint8_t RF_PKTCTRL0; +#define RF_PKTCTRL0_OFF 0x04 + +__xdata __at (0xdf05) uint8_t RF_ADDR; +#define RF_ADDR_OFF 0x05 + +__xdata __at (0xdf06) uint8_t RF_CHANNR; +#define RF_CHANNR_OFF 0x06 + +__xdata __at (0xdf07) uint8_t RF_FSCTRL1; +#define RF_FSCTRL1_OFF 0x07 + +#define RF_FSCTRL1_FREQ_IF_SHIFT (0) + +__xdata __at (0xdf08) uint8_t RF_FSCTRL0; +#define RF_FSCTRL0_OFF 0x08 + +#define RF_FSCTRL0_FREQOFF_SHIFT (0) + +__xdata __at (0xdf09) uint8_t RF_FREQ2; +#define RF_FREQ2_OFF 0x09 + +__xdata __at (0xdf0a) uint8_t RF_FREQ1; +#define RF_FREQ1_OFF 0x0a + +__xdata __at (0xdf0b) uint8_t RF_FREQ0; +#define RF_FREQ0_OFF 0x0b + +__xdata __at (0xdf0c) uint8_t RF_MDMCFG4; +#define RF_MDMCFG4_OFF 0x0c + +#define RF_MDMCFG4_CHANBW_E_SHIFT 6 +#define RF_MDMCFG4_CHANBW_M_SHIFT 4 +#define RF_MDMCFG4_DRATE_E_SHIFT 0 + +__xdata __at (0xdf0d) uint8_t RF_MDMCFG3; +#define RF_MDMCFG3_OFF 0x0d + +#define RF_MDMCFG3_DRATE_M_SHIFT 0 + +__xdata __at (0xdf0e) uint8_t RF_MDMCFG2; +#define RF_MDMCFG2_OFF 0x0e + +#define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7) + +#define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4) +#define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4) +#define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4) +#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4) +#define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4) + +#define RF_MDMCFG2_MANCHESTER_EN (1 << 3) + +#define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0) +#define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0) +#define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0) +#define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0) +#define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0) +#define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0) +#define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0) +#define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0) +#define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0) + +__xdata __at (0xdf0f) uint8_t RF_MDMCFG1; +#define RF_MDMCFG1_OFF 0x0f + +#define RF_MDMCFG1_FEC_EN (1 << 7) + +#define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4) + +#define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0) +#define RF_MDMCFG1_CHANSPC_E_SHIFT (0) + +__xdata __at (0xdf10) uint8_t RF_MDMCFG0; +#define RF_MDMCFG0_OFF 0x10 + +#define RF_MDMCFG0_CHANSPC_M_SHIFT (0) + +__xdata __at (0xdf11) uint8_t RF_DEVIATN; +#define RF_DEVIATN_OFF 0x11 + +#define RF_DEVIATN_DEVIATION_E_SHIFT 4 +#define RF_DEVIATN_DEVIATION_M_SHIFT 0 + +__xdata __at (0xdf12) uint8_t RF_MCSM2; +#define RF_MCSM2_OFF 0x12 + +__xdata __at (0xdf13) uint8_t RF_MCSM1; +#define RF_MCSM1_OFF 0x13 + +__xdata __at (0xdf14) uint8_t RF_MCSM0; +#define RF_MCSM0_OFF 0x14 + +__xdata __at (0xdf15) uint8_t RF_FOCCFG; +#define RF_FOCCFG_OFF 0x15 + +__xdata __at (0xdf16) uint8_t RF_BSCFG; +#define RF_BSCFG_OFF 0x16 + +__xdata __at (0xdf17) uint8_t RF_AGCCTRL2; +#define RF_AGCCTRL2_OFF 0x17 + +__xdata __at (0xdf18) uint8_t RF_AGCCTRL1; +#define RF_AGCCTRL1_OFF 0x18 + +__xdata __at (0xdf19) uint8_t RF_AGCCTRL0; +#define RF_AGCCTRL0_OFF 0x19 + +__xdata __at (0xdf1a) uint8_t RF_FREND1; +#define RF_FREND1_OFF 0x1a + +#define RF_FREND1_LNA_CURRENT_SHIFT 6 +#define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4 +#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2 +#define RF_FREND1_MIX_CURRENT_SHIFT 0 + +__xdata __at (0xdf1b) uint8_t RF_FREND0; +#define RF_FREND0_OFF 0x1b + +#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4) +#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4 +#define RF_FREND0_PA_POWER_MASK (0x7) +#define RF_FREND0_PA_POWER_SHIFT 0 + +__xdata __at (0xdf1c) uint8_t RF_FSCAL3; +#define RF_FSCAL3_OFF 0x1c + +__xdata __at (0xdf1d) uint8_t RF_FSCAL2; +#define RF_FSCAL2_OFF 0x1d + +__xdata __at (0xdf1e) uint8_t RF_FSCAL1; +#define RF_FSCAL1_OFF 0x1e + +__xdata __at (0xdf1f) uint8_t RF_FSCAL0; +#define RF_FSCAL0_OFF 0x1f + +__xdata __at (0xdf23) uint8_t RF_TEST2; +#define RF_TEST2_OFF 0x23 + +#define RF_TEST2_NORMAL_MAGIC 0x88 +#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81 + +__xdata __at (0xdf24) uint8_t RF_TEST1; +#define RF_TEST1_OFF 0x24 + +#define RF_TEST1_TX_MAGIC 0x31 +#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35 + +__xdata __at (0xdf25) uint8_t RF_TEST0; +#define RF_TEST0_OFF 0x25 + +#define RF_TEST0_7_2_MASK (0xfc) +#define RF_TEST0_VCO_SEL_CAL_EN (1 << 1) +#define RF_TEST0_0_MASK (1) + +/* These are undocumented, and must be computed + * using the provided tool. + */ +__xdata __at (0xdf27) uint8_t RF_PA_TABLE7; +#define RF_PA_TABLE7_OFF 0x27 + +__xdata __at (0xdf28) uint8_t RF_PA_TABLE6; +#define RF_PA_TABLE6_OFF 0x28 + +__xdata __at (0xdf29) uint8_t RF_PA_TABLE5; +#define RF_PA_TABLE5_OFF 0x29 + +__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4; +#define RF_PA_TABLE4_OFF 0x2a + +__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3; +#define RF_PA_TABLE3_OFF 0x2b + +__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2; +#define RF_PA_TABLE2_OFF 0x2c + +__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1; +#define RF_PA_TABLE1_OFF 0x2d + +__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0; +#define RF_PA_TABLE0_OFF 0x2e + +__xdata __at (0xdf36) uint8_t RF_PARTNUM; +#define RF_PARTNUM_OFF 0x36 + +__xdata __at (0xdf37) uint8_t RF_VERSION; +#define RF_VERSION_OFF 0x37 + +__xdata __at (0xdf38) uint8_t RF_FREQEST; +#define RF_FREQEST_OFF 0x38 + +__xdata __at (0xdf39) uint8_t RF_LQI; +#define RF_LQI_OFF 0x39 + +#define RF_LQI_CRC_OK (1 << 7) +#define RF_LQI_LQI_EST_MASK (0x7f) + +__xdata __at (0xdf3a) uint8_t RF_RSSI; +#define RF_RSSI_OFF 0x3a + +__xdata __at (0xdf3b) uint8_t RF_MARCSTATE; +#define RF_MARCSTATE_OFF 0x3b + +#define RF_MARCSTATE_MASK 0x0f +#define RF_MARCSTATE_SLEEP 0x00 +#define RF_MARCSTATE_IDLE 0x01 +#define RF_MARCSTATE_VCOON_MC 0x03 +#define RF_MARCSTATE_REGON_MC 0x04 +#define RF_MARCSTATE_MANCAL 0x05 +#define RF_MARCSTATE_VCOON 0x06 +#define RF_MARCSTATE_REGON 0x07 +#define RF_MARCSTATE_STARTCAL 0x08 +#define RF_MARCSTATE_BWBOOST 0x09 +#define RF_MARCSTATE_FS_LOCK 0x0a +#define RF_MARCSTATE_IFADCON 0x0b +#define RF_MARCSTATE_ENDCAL 0x0c +#define RF_MARCSTATE_RX 0x0d +#define RF_MARCSTATE_RX_END 0x0e +#define RF_MARCSTATE_RX_RST 0x0f +#define RF_MARCSTATE_TXRX_SWITCH 0x10 +#define RF_MARCSTATE_RX_OVERFLOW 0x11 +#define RF_MARCSTATE_FSTXON 0x12 +#define RF_MARCSTATE_TX 0x13 +#define RF_MARCSTATE_TX_END 0x14 +#define RF_MARCSTATE_RXTX_SWITCH 0x15 +#define RF_MARCSTATE_TX_UNDERFLOW 0x16 + + +__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS; +#define RF_PKTSTATUS_OFF 0x3c + +#define RF_PKTSTATUS_CRC_OK (1 << 7) +#define RF_PKTSTATUS_CS (1 << 6) +#define RF_PKTSTATUS_PQT_REACHED (1 << 5) +#define RF_PKTSTATUS_CCA (1 << 4) +#define RF_PKTSTATUS_SFD (1 << 3) + +__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC; +#define RF_VCO_VC_DAC_OFF 0x3d + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + + n <<= 1; + while (--n != 0) + while (--i != 0) + nop(); +} + +void +tone (unsigned char n, unsigned char m) +{ + unsigned char i = 0; + while (--m != 0) { + i = 128; + while (--i != 0) { + P2 = 0xff; + delay(n); + P2 = 0xfe; + delay(n); + } + } +} + +void +high() { + tone(1, 2); +} + +void +low() { + tone(2, 1); +} + +/* Values from SmartRF® Studio for: + * + * Deviation: 20.507812 kHz + * Datarate: 38.360596 kBaud + * Modulation: GFSK + * RF Freq: 434.549927 MHz + * Channel: 99.975586 kHz + * Channel: 0 + * RX filter: 93.75 kHz + */ + +/* + * For 434.550MHz, the frequency value is: + * + * 434.550e6 / (24e6 / 2**16) = 1186611.2 + */ + +#define FREQ_CONTROL 1186611 + +/* + * For IF freq of 140.62kHz, the IF value is: + * + * 140.62e3 / (24e6 / 2**10) = 6 + */ + +#define IF_FREQ_CONTROL 6 + +/* + * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are + * + * BW = 24e6 / (8 * (4 + M) * 2 ** E) + * + * So, M = 0 and E = 3 + */ + +#define CHANBW_M 0 +#define CHANBW_E 3 + +/* + * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are: + * + * R = (256 + M) * 2** E * 24e6 / 2**28 + * + * So M is 163 and E is 10 + */ + +#define DRATE_E 10 +#define DRATE_M 163 + +#define PACKET_LEN 128 + +static __code uint8_t radio_setup[] = { + RF_PA_TABLE7_OFF, 0x60, + RF_PA_TABLE6_OFF, 0x60, + RF_PA_TABLE5_OFF, 0x60, + RF_PA_TABLE4_OFF, 0x60, + RF_PA_TABLE3_OFF, 0x60, + RF_PA_TABLE2_OFF, 0x60, + RF_PA_TABLE1_OFF, 0x60, + RF_PA_TABLE0_OFF, 0x60, + + RF_FREQ2_OFF, FREQ_CONTROL >> 16, + RF_FREQ1_OFF, FREQ_CONTROL >> 8, + RF_FREQ0_OFF, FREQ_CONTROL >> 0, + + RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT), + RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT), + + RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), + RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT), + RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF | + RF_MDMCFG2_MOD_FORMAT_GFSK | + RF_MDMCFG2_SYNC_MODE_NONE), + RF_MDMCFG1_OFF, (RF_MDMCFG1_NUM_PREAMBLE_4 | + (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), + RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT), + + RF_CHANNR_OFF, 0, + + RF_DEVIATN_OFF, ((3 << RF_DEVIATN_DEVIATION_E_SHIFT) | + (6 << RF_DEVIATN_DEVIATION_M_SHIFT)), + + /* SmartRF says set LODIV_BUF_CURRENT_TX to 0 + * And, we're not using power ramping, so use PA_POWER 0 + */ + RF_FREND0_OFF, ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) | + (0 << RF_FREND0_PA_POWER_SHIFT)), + + RF_FREND1_OFF, ((1 << RF_FREND1_LNA_CURRENT_SHIFT) | + (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) | + (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) | + (2 << RF_FREND1_MIX_CURRENT_SHIFT)), + RF_MCSM0_OFF, 0x18, + RF_FOCCFG_OFF, 0x16, + RF_BSCFG_OFF, 0x6C, + + RF_AGCCTRL2_OFF, 0x43, + RF_AGCCTRL1_OFF, 0x40, + RF_AGCCTRL0_OFF, 0x91, + + RF_FSCAL3_OFF, 0xE9, + RF_FSCAL2_OFF, 0x0A, + RF_FSCAL1_OFF, 0x00, + RF_FSCAL0_OFF, 0x1F, + + RF_TEST2_OFF, 0x88, + RF_TEST1_OFF, 0x31, + RF_TEST0_OFF, 0x09, + + /* default sync values */ + RF_SYNC1_OFF, 0xD3, + RF_SYNC0_OFF, 0x91, + + /* max packet length */ + RF_PKTLEN_OFF, PACKET_LEN, + + RF_PKTCTRL1_OFF, 0x04, + RF_PKTCTRL0_OFF, 0x00, + RF_ADDR_OFF, 0x00, + RF_MCSM2_OFF, 0x07, + RF_MCSM1_OFF, 0x30, + + RF_IOCFG2_OFF, 0x00, + RF_IOCFG1_OFF, 0x00, + RF_IOCFG0_OFF, 0x00, +}; + +void +radio_init() { + uint8_t i; + for (i = 0; i < sizeof (radio_setup); i += 2) + RF[radio_setup[i]] = radio_setup[i+1]; +} + +main () +{ + CLKCON = 0; + /* Set P2_0 to output */ + radio_init (); + delay(100); + RFST = RFST_SIDLE; + delay(100); + RFST = RFST_STX; + delay(100); + for (;;); +#if 0 + for (;;) { + uint8_t i; + for (i = 0; i < PACKET_LEN; i++) { + while (!RFTXRXIF); + RFTXRXIF = 0; + RFD = 0x55; + } + } +#endif +} -- cgit v1.2.3 From 6eeee64cf16ccc9218dbdde5426f25bda5e3407f Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Mar 2009 02:58:33 -0600 Subject: working beep at around 4khz --- COPYING | 7 +++--- INSTALL | 69 ++++++++++++++++++++++++------------------------------ Makefile.am | 2 +- target/beep/beep.c | 6 +++-- 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/COPYING b/COPYING index 10828e06..d60c31a9 100644 --- a/COPYING +++ b/COPYING @@ -1,9 +1,8 @@ - GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -306,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. @@ -314,7 +313,7 @@ Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. diff --git a/INSTALL b/INSTALL index 23e5f25d..54caf7c1 100644 --- a/INSTALL +++ b/INSTALL @@ -1,16 +1,13 @@ -Installation Instructions -************************* +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives + This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== -These are generic installation instructions. + These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -70,9 +67,9 @@ The simplest way to compile this package is: Compilers and Options ===================== -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here @@ -85,7 +82,7 @@ is an example: Compiling For Multiple Architectures ==================================== -You can compile the package for more than one kind of computer at the + You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the @@ -102,19 +99,19 @@ for another architecture. Installation Names ================== -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular +options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. @@ -125,7 +122,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= -Some packages pay attention to `--enable-FEATURE' options to + Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The @@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and Specifying the System Type ========================== -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: @@ -159,7 +156,7 @@ where SYSTEM can have one of these forms: need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will +use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a @@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'. Sharing Defaults ================ -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. @@ -181,7 +178,7 @@ A warning: not all `configure' scripts look for a site script. Defining Variables ================== -Variables not defined in a site shell script can be set in the + Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set @@ -189,18 +186,14 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: - - /bin/bash ./configure CONFIG_SHELL=/bin/bash - -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). `configure' Invocation ====================== -`configure' recognizes the following options to control how it operates. + `configure' recognizes the following options to control how it +operates. `--help' `-h' diff --git a/Makefile.am b/Makefile.am index 8a061ab7..5341ab33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ccload s51 ccmanual target/blink +SUBDIRS=lib ccload s51 ccmanual diff --git a/target/beep/beep.c b/target/beep/beep.c index 3dd31d54..09c915b7 100644 --- a/target/beep/beep.c +++ b/target/beep/beep.c @@ -46,9 +46,11 @@ delay (unsigned char n) unsigned char i = 0; n <<= 1; - while (--n != 0) + while (--n != 0) { + i = 211; while (--i != 0) nop(); + } } void @@ -84,6 +86,6 @@ main () P2INP = 0x00; for (;;) { high(); - low(); +/* low(); */ } } -- cgit v1.2.3 From f0c233f25a208a636833312b1766825815735304 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 15:41:55 -0700 Subject: Add bit-banging spi eeprom test program --- target/ee/Makefile | 46 +++++++++++ target/ee/ee.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 target/ee/Makefile create mode 100644 target/ee/ee.c diff --git a/target/ee/Makefile b/target/ee/Makefile new file mode 100644 index 00000000..4c9abd1f --- /dev/null +++ b/target/ee/Makefile @@ -0,0 +1,46 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=ee.c +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=ee-flash.ihx ee-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +ee-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o ee-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o ee-flash.ihx $(REL) + +ee-flash.ihx: ee-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/ee/ee.c b/target/ee/ee.c new file mode 100644 index 00000000..ab1b54e3 --- /dev/null +++ b/target/ee/ee.c @@ -0,0 +1,235 @@ +/* + * 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 + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +#define MOSI P1_5 +#define MISO P1_4 +#define SCK P1_3 +#define CS P1_2 + +#define DEBUG P1_1 + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +void +cs(uint8_t b) +{ + CS = b; + delay(1); +} + +void +out_bit(uint8_t b) +{ + MOSI = b; + SCK = 1; + delay(1); + SCK = 0; + delay(1); +} + +void +out_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + uint8_t b = (byte & 0x80) ? 1 : 0; + out_bit(b); + byte <<= 1; + } +} + +uint8_t +in_bit(void) +{ + uint8_t b; + SCK = 1; + delay(1); + b = MISO; + SCK = 0; + delay(1); + return b; +} + +uint8_t +in_byte(void) +{ + uint8_t byte = 0; + uint8_t s; + uint8_t b; + + for (s = 0; s < 8; s++) { + b = in_bit(); + byte = byte << 1; + byte |= s; + } + return byte; +} + +uint8_t +rdsr(void) +{ + uint8_t status; + cs(0); + out_byte(0x05); + status = in_byte(); + cs(1); + return status; +} + +void +wrsr(uint8_t status) +{ + cs(0); + out_byte(0x01); + out_byte(status); + cs(1); +} + +void +wren(void) +{ + cs(0); + out_byte(0x06); + cs(1); +} + +void +write(uint32_t addr, uint8_t *bytes, uint16_t len) +{ + wren(); + cs(0); + out_byte(0x02); + out_byte(addr >> 16); + out_byte(addr >> 8); + out_byte(addr); + while (len-- > 0) + out_byte(*bytes++); + cs(1); + for (;;) { + uint8_t status = rdsr(); + if ((status & (1 << 0)) == 0) + break; + } +} + +void +read(uint32_t addr, uint8_t *bytes, uint16_t len) +{ + cs(0); + out_byte(0x03); + out_byte(addr >> 16); + out_byte(addr >> 8); + out_byte(addr); + while (len-- > 0) + *bytes++ = in_byte(); + cs(1); +} + +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(2); + byte >>= 1; + } +} + +#define STRING "hi" +#define LENGTH 2 + +main () +{ + uint8_t status; + uint8_t buf[LENGTH]; + int i; + + CLKCON = 0; + + CS = 1; + SCK = 0; + P1DIR = ((1 << 5) | + (1 << 4) | + (1 << 3) | + (1 << 2) | + (1 << 1)); + status = rdsr(); + /* + * Turn off both block-protect bits + */ + status &= ~((1 << 3) | (1 << 2)); + /* + * Turn off write protect enable + */ + status &= ~(1 << 7); + wrsr(status); + write(0x0, STRING, LENGTH); + for (;;) { + read(0x0, buf, LENGTH); + for (i = 0; i < LENGTH; i++) + debug_byte(buf[i]); + } +} -- cgit v1.2.3 From fedd18b28ea54e1dabcd2f9e8cab3ae4ee0fd070 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 16:35:13 -0700 Subject: MISO needs to be an input --- target/ee/ee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index ab1b54e3..221d5979 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -212,7 +212,7 @@ main () CS = 1; SCK = 0; P1DIR = ((1 << 5) | - (1 << 4) | + (0 << 4) | (1 << 3) | (1 << 2) | (1 << 1)); -- cgit v1.2.3 From 3429016d1359ec650993d2fb0596184e3f717871 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 17:04:45 -0700 Subject: Adjust clock/data phase for spi test --- target/ee/ee.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index 221d5979..83dd57eb 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -73,6 +73,7 @@ delay (unsigned char n) void cs(uint8_t b) { + SCK = 0; CS = b; delay(1); } @@ -81,10 +82,10 @@ void out_bit(uint8_t b) { MOSI = b; + delay(1); SCK = 1; delay(1); SCK = 0; - delay(1); } void @@ -103,11 +104,12 @@ uint8_t in_bit(void) { uint8_t b; + + delay(1); SCK = 1; delay(1); b = MISO; SCK = 0; - delay(1); return b; } -- cgit v1.2.3 From 8131389ee5018c05b721146a98367150cf500fdf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 17:15:09 -0700 Subject: Oops, not merging in the bit read for SPI test --- target/ee/ee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index 83dd57eb..f105388b 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -123,7 +123,7 @@ in_byte(void) for (s = 0; s < 8; s++) { b = in_bit(); byte = byte << 1; - byte |= s; + byte |= b; } return byte; } -- cgit v1.2.3 From ef0eef68280e9b6ca5e3bb71062e23054340e1ed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 17:22:36 -0700 Subject: Change spi test string --- target/ee/ee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index f105388b..2ad040ab 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -200,7 +200,7 @@ debug_byte(uint8_t byte) } } -#define STRING "hi" +#define STRING "\360\252" #define LENGTH 2 main () -- cgit v1.2.3 From 7de3a43887485c3c6cf52960376ccde33fb33985 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 19:54:02 -0700 Subject: Add USART-based SPI test code --- target/ee/ee.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 203 insertions(+), 42 deletions(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index 2ad040ab..68b6e4cc 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -18,12 +18,31 @@ #include +/* + * Validate the SPI-connected EEPROM + */ + sfr at 0x80 P0; sfr at 0x90 P1; sfr at 0xA0 P2; sfr at 0xC6 CLKCON; sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + sfr at 0xF2 ADCCFG; sfr at 0xF3 P0SEL; sfr at 0xF4 P1SEL; @@ -49,6 +68,44 @@ sbit at 0x95 P1_5; sbit at 0x96 P1_6; sbit at 0x97 P1_7; +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + #define MOSI P1_5 #define MISO P1_4 #define SCK P1_3 @@ -56,6 +113,9 @@ sbit at 0x97 P1_7; #define DEBUG P1_1 +#define BITBANG 0 +#define USART 1 + #define nop() _asm nop _endasm; void @@ -70,8 +130,14 @@ delay (unsigned char n) nop(); } +#if BITBANG + +/* + * This version directly manipulates the GPIOs to synthesize SPI + */ + void -cs(uint8_t b) +bitbang_cs(uint8_t b) { SCK = 0; CS = b; @@ -79,7 +145,7 @@ cs(uint8_t b) } void -out_bit(uint8_t b) +bitbang_out_bit(uint8_t b) { MOSI = b; delay(1); @@ -89,19 +155,19 @@ out_bit(uint8_t b) } void -out_byte(uint8_t byte) +bitbang_out_byte(uint8_t byte) { uint8_t s; for (s = 0; s < 8; s++) { uint8_t b = (byte & 0x80) ? 1 : 0; - out_bit(b); + bitbang_out_bit(b); byte <<= 1; } } uint8_t -in_bit(void) +bitbang_in_bit(void) { uint8_t b; @@ -114,60 +180,160 @@ in_bit(void) } uint8_t -in_byte(void) +bitbang_in_byte(void) { uint8_t byte = 0; uint8_t s; uint8_t b; for (s = 0; s < 8; s++) { - b = in_bit(); + b = bitbang_in_bit(); byte = byte << 1; byte |= b; } return byte; } +void +bit_bang_init(void) +{ + CS = 1; + SCK = 0; + P1DIR = ((1 << 5) | + (0 << 4) | + (1 << 3) | + (1 << 2) | + (1 << 1)); +} + +#define spi_init() bitbang_init() +#define spi_out_byte(b) bitbang_out_byte(b) +#define spi_in_byte() bitbang_in_byte() +#define spi_cs(b) bitbang_cs(b) +#endif + +#if USART + +/* + * This version uses the USART in SPI mode + */ +void +usart_init(void) +{ + /* + * Configure our chip select line + */ + CS = 1; + P1DIR |= (1 << 2); + /* + * Configure the peripheral pin choices + * for both of the serial ports + * + * Note that telemetrum will use U1CFG_ALT_2 + * but that overlaps with SPI ALT_2, so until + * we can test that this works, we'll set this + * to ALT_1 + */ + PERCFG = (PERCFG_U1CFG_ALT_1 | + PERCFG_U0CFG_ALT_2); + + /* + * Make the SPI pins controlled by the SPI + * hardware + */ + P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3)); + + /* + * SPI in master mode + */ + U0CSR = (UxCSR_MODE_SPI | + UxCSR_MASTER); + + /* + * The cc1111 is limited to a 24/8 MHz SPI clock, + * while the 25LC1024 is limited to 20MHz. So, + * use the 3MHz clock (BAUD_E 17, BAUD_M 0) + */ + U0BAUD = 0; + U0GCR = (UxGCR_CPOL_NEGATIVE | + UxGCR_CPHA_FIRST_EDGE | + UxGCR_ORDER_MSB | + (17 << UxGCR_BAUD_E_SHIFT)); +} + +void +usart_cs(uint8_t b) +{ + CS = b; +} + +uint8_t +usart_in_out(uint8_t byte) +{ + U0DBUF = byte; + while ((U0CSR & UxCSR_TX_BYTE) == 0) + ; +} + +void +usart_out_byte(uint8_t byte) +{ + (void) usart_in_out(byte); +} + +uint8_t +usart_in_byte(void) +{ + return usart_in_out(0xff); +} + +#define spi_init() usart_init() +#define spi_out_byte(b) usart_out_byte(b) +#define spi_in_byte() usart_in_byte() +#define spi_cs(b) usart_cs(b) + +#endif + uint8_t rdsr(void) { uint8_t status; - cs(0); - out_byte(0x05); - status = in_byte(); - cs(1); + spi_cs(0); + spi_out_byte(0x05); + status = spi_in_byte(); + spi_cs(1); return status; } void wrsr(uint8_t status) { - cs(0); - out_byte(0x01); - out_byte(status); - cs(1); + spi_cs(0); + spi_out_byte(0x01); + spi_out_byte(status); + spi_cs(1); } void wren(void) { - cs(0); - out_byte(0x06); - cs(1); + spi_cs(0); + spi_out_byte(0x06); + spi_cs(1); } void write(uint32_t addr, uint8_t *bytes, uint16_t len) { wren(); - cs(0); - out_byte(0x02); - out_byte(addr >> 16); - out_byte(addr >> 8); - out_byte(addr); + spi_cs(0); + spi_out_byte(0x02); + spi_out_byte(addr >> 16); + spi_out_byte(addr >> 8); + spi_out_byte(addr); while (len-- > 0) - out_byte(*bytes++); - cs(1); + spi_out_byte(*bytes++); + spi_cs(1); for (;;) { uint8_t status = rdsr(); if ((status & (1 << 0)) == 0) @@ -178,14 +344,14 @@ write(uint32_t addr, uint8_t *bytes, uint16_t len) void read(uint32_t addr, uint8_t *bytes, uint16_t len) { - cs(0); - out_byte(0x03); - out_byte(addr >> 16); - out_byte(addr >> 8); - out_byte(addr); + spi_cs(0); + spi_out_byte(0x03); + spi_out_byte(addr >> 16); + spi_out_byte(addr >> 8); + spi_out_byte(addr); while (len-- > 0) - *bytes++ = in_byte(); - cs(1); + *bytes++ = spi_in_byte(); + spi_cs(1); } void @@ -195,7 +361,7 @@ debug_byte(uint8_t byte) for (s = 0; s < 8; s++) { DEBUG = byte & 1; - delay(2); + delay(5); byte >>= 1; } } @@ -211,13 +377,8 @@ main () CLKCON = 0; - CS = 1; - SCK = 0; - P1DIR = ((1 << 5) | - (0 << 4) | - (1 << 3) | - (1 << 2) | - (1 << 1)); + spi_init(); + status = rdsr(); /* * Turn off both block-protect bits @@ -228,10 +389,10 @@ main () */ status &= ~(1 << 7); wrsr(status); - write(0x0, STRING, LENGTH); +// write(0x0, STRING, LENGTH); for (;;) { read(0x0, buf, LENGTH); for (i = 0; i < LENGTH; i++) - debug_byte(buf[i]); + debug_byte(STRING[i]); } } -- cgit v1.2.3 From 91b3a6ae74184692f45702587c4d678b2799ad8c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 19:55:04 -0700 Subject: actually write and compare SPI test bits --- target/ee/ee.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ee/ee.c b/target/ee/ee.c index 68b6e4cc..d269d2aa 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -389,10 +389,10 @@ main () */ status &= ~(1 << 7); wrsr(status); -// write(0x0, STRING, LENGTH); + write(0x0, STRING, LENGTH); for (;;) { read(0x0, buf, LENGTH); for (i = 0; i < LENGTH; i++) - debug_byte(STRING[i]); + debug_byte(buf[i]); } } -- cgit v1.2.3 From 3ed3ff63e46767a256d30c5da5c52ae20089a91d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 20:04:58 -0700 Subject: Led the LED turn on --- target/ee/ee.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/ee/ee.c b/target/ee/ee.c index d269d2aa..6cf276a0 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -375,6 +375,7 @@ main () uint8_t buf[LENGTH]; int i; + P1DIR |= 2; CLKCON = 0; spi_init(); -- cgit v1.2.3 From de1ac6f99a1526fa840a52cfc10fa3edc0589bed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 22:12:51 -0700 Subject: Clear UxCSR_TX_BYTE after transmitting a byte --- target/ee/ee.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/ee/ee.c b/target/ee/ee.c index 6cf276a0..ed13d0ad 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -273,6 +273,7 @@ usart_in_out(uint8_t byte) U0DBUF = byte; while ((U0CSR & UxCSR_TX_BYTE) == 0) ; + U0CSR &= ~UxCSR_TX_BYTE; } void -- cgit v1.2.3 From e120269fc0f8e14ddf1755337b1d092173e16da2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 22:21:31 -0700 Subject: Actually return byte read from SPI --- target/ee/ee.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/ee/ee.c b/target/ee/ee.c index ed13d0ad..08d55137 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -274,6 +274,7 @@ usart_in_out(uint8_t byte) while ((U0CSR & UxCSR_TX_BYTE) == 0) ; U0CSR &= ~UxCSR_TX_BYTE; + return U0DBUF; } void -- cgit v1.2.3 From 8ecbd8734f0fb5588b2a8eb20720cfc6f43dfb47 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 22:37:38 -0700 Subject: Wait for xtal to stabilize after changing to 24MHz --- target/ee/ee.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target/ee/ee.c b/target/ee/ee.c index 08d55137..7cc47120 100644 --- a/target/ee/ee.c +++ b/target/ee/ee.c @@ -26,6 +26,10 @@ sfr at 0x80 P0; sfr at 0x90 P1; sfr at 0xA0 P2; sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) sfr at 0xF1 PERCFG; #define PERCFG_T1CFG_ALT_1 (0 << 6) @@ -379,6 +383,8 @@ main () P1DIR |= 2; CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; spi_init(); -- cgit v1.2.3 From c35de083ca3d4f362063b056a0fd74ffe629d168 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 23:11:48 -0700 Subject: Add serial test program --- target/serial/Makefile | 46 +++++++++ target/serial/serial.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 target/serial/Makefile create mode 100644 target/serial/serial.c diff --git a/target/serial/Makefile b/target/serial/Makefile new file mode 100644 index 00000000..3a1d81e8 --- /dev/null +++ b/target/serial/Makefile @@ -0,0 +1,46 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=serial.c +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=serial-flash.ihx serial-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +serial-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o serial-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o serial-flash.ihx $(REL) + +serial-flash.ihx: serial-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/serial/serial.c b/target/serial/serial.c new file mode 100644 index 00000000..5acd284f --- /dev/null +++ b/target/serial/serial.c @@ -0,0 +1,253 @@ +/* + * 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 + +/* + * Validate UART1 + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +# define UxUCR_FLUSH (1 << 7) +# define UxUCR_FLOW_DISABLE (0 << 6) +# define UxUCR_FLOW_ENABLE (1 << 6) +# define UxUCR_D9_EVEN_PARITY (0 << 5) +# define UxUCR_D9_ODD_PARITY (1 << 5) +# define UxUCR_BIT9_8_BITS (0 << 4) +# define UxUCR_BIT9_9_BITS (1 << 4) +# define UxUCR_PARITY_DISABLE (0 << 3) +# define UxUCR_PARITY_ENABLE (1 << 3) +# define UxUCR_SPB_1_STOP_BIT (0 << 2) +# define UxUCR_SPB_2_STOP_BITS (1 << 2) +# define UxUCR_STOP_LOW (0 << 1) +# define UXUCR_STOP_HIGH (1 << 1) +# define UxUCR_START_LOW (0 << 0) +# define UxUCR_START_HIGH (1 << 0) + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + +#define MOSI P1_5 +#define MISO P1_4 +#define SCK P1_3 +#define CS P1_2 + +#define DEBUG P1_1 + +#define USART 1 + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +/* + * This version uses the USART in SPI mode + */ +void +usart_init(void) +{ + P1DIR |= (1 << 2); + /* + * Configure the peripheral pin choices + * for both of the serial ports + * + * Note that telemetrum will use U1CFG_ALT_2 + * but that overlaps with SPI ALT_2, so until + * we can test that this works, we'll set this + * to ALT_1 + */ + PERCFG = (PERCFG_U1CFG_ALT_2 | + PERCFG_U0CFG_ALT_1); + + /* + * Make the UART pins controlled by the UART + * hardware + */ + P1SEL |= ((1 << 6) | (1 << 7)); + + /* + * UART mode with the receiver enabled + */ + U1CSR = (UxCSR_MODE_UART | + UxCSR_RE); + /* + * Pick a 38.4kbaud rate + */ + U1BAUD = 163; + U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */ +// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */ + /* + * Reasonable serial parameters + */ + U1UCR = (UxUCR_FLOW_DISABLE | + UxUCR_D9_EVEN_PARITY | + UxUCR_BIT9_8_BITS | + UxUCR_PARITY_DISABLE | + UxUCR_SPB_1_STOP_BIT | + UxUCR_STOP_LOW | + UxUCR_START_LOW); +} + + +uint8_t +usart_in_out(uint8_t byte) +{ + U1DBUF = byte; + while ((U1CSR & UxCSR_TX_BYTE) == 0) + ; + U1CSR &= ~UxCSR_TX_BYTE; + return U1DBUF; +} +void +usart_out_byte(uint8_t byte) +{ + U1CSR &= ~UxCSR_TX_BYTE; + U1DBUF = byte; + while ((U1CSR & UxCSR_TX_BYTE) == 0) + ; +} + +uint8_t +usart_in_byte(void) +{ + uint8_t b; + while ((U1CSR & UxCSR_RX_BYTE) == 0) + ; + b = U1DBUF; + U1CSR &= ~UxCSR_RX_BYTE; + return b; +} + +#define spi_init() usart_init() +#define spi_out_byte(b) usart_out_byte(b) +#define spi_in_byte() usart_in_byte() + +static char string[] = "hello world\r\n"; + +main () +{ + uint8_t i; + + P1DIR |= 2; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + + spi_init(); + + for (;;) { + for (i = 0; i < sizeof (string) - 1; i++) { + usart_out_byte(string[i]); + } + P1 ^= 2; + } +} -- cgit v1.2.3 From c41ceb9a488b2209d1d3c09967d1473ce608030f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 23:24:01 -0700 Subject: Change radio to -30dBm --- target/radio/radio.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/target/radio/radio.c b/target/radio/radio.c index 9f10fccd..ba693a77 100644 --- a/target/radio/radio.c +++ b/target/radio/radio.c @@ -416,15 +416,29 @@ low() { #define PACKET_LEN 128 +/* This are from the table for 433MHz */ + +#define RF_POWER_M30_DBM 0x12 +#define RF_POWER_M20_DBM 0x0e +#define RF_POWER_M15_DBM 0x1d +#define RF_POWER_M10_DBM 0x34 +#define RF_POWER_M5_DBM 0x2c +#define RF_POWER_0_DBM 0x60 +#define RF_POWER_5_DBM 0x84 +#define RF_POWER_7_DBM 0xc8 +#define RF_POWER_10_DBM 0xc0 + +#define RF_POWER RF_POWER_M30_DBM + static __code uint8_t radio_setup[] = { - RF_PA_TABLE7_OFF, 0x60, - RF_PA_TABLE6_OFF, 0x60, - RF_PA_TABLE5_OFF, 0x60, - RF_PA_TABLE4_OFF, 0x60, - RF_PA_TABLE3_OFF, 0x60, - RF_PA_TABLE2_OFF, 0x60, - RF_PA_TABLE1_OFF, 0x60, - RF_PA_TABLE0_OFF, 0x60, + RF_PA_TABLE7_OFF, RF_POWER, + RF_PA_TABLE6_OFF, RF_POWER, + RF_PA_TABLE5_OFF, RF_POWER, + RF_PA_TABLE4_OFF, RF_POWER, + RF_PA_TABLE3_OFF, RF_POWER, + RF_PA_TABLE2_OFF, RF_POWER, + RF_PA_TABLE1_OFF, RF_POWER, + RF_PA_TABLE0_OFF, RF_POWER, RF_FREQ2_OFF, FREQ_CONTROL >> 16, RF_FREQ1_OFF, FREQ_CONTROL >> 8, -- cgit v1.2.3 From 9e96107d5d1a9681b07c36bb5860c748bfe10ec0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Mar 2009 23:57:12 -0700 Subject: Stop high --- target/serial/serial.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 5acd284f..b0aead74 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -105,7 +105,7 @@ sfr at 0xfb U1UCR; # define UxUCR_SPB_1_STOP_BIT (0 << 2) # define UxUCR_SPB_2_STOP_BITS (1 << 2) # define UxUCR_STOP_LOW (0 << 1) -# define UXUCR_STOP_HIGH (1 << 1) +# define UxUCR_STOP_HIGH (1 << 1) # define UxUCR_START_LOW (0 << 0) # define UxUCR_START_HIGH (1 << 0) @@ -193,20 +193,10 @@ usart_init(void) UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | UxUCR_SPB_1_STOP_BIT | - UxUCR_STOP_LOW | + UxUCR_STOP_HIGH | UxUCR_START_LOW); } - -uint8_t -usart_in_out(uint8_t byte) -{ - U1DBUF = byte; - while ((U1CSR & UxCSR_TX_BYTE) == 0) - ; - U1CSR &= ~UxCSR_TX_BYTE; - return U1DBUF; -} void usart_out_byte(uint8_t byte) { -- cgit v1.2.3 From 62744c186792739c3bf5798c80ff87c69fbe2b65 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:03:45 -0700 Subject: Flip start/stop bits around --- target/serial/serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index b0aead74..6065d971 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -193,8 +193,8 @@ usart_init(void) UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | UxUCR_SPB_1_STOP_BIT | - UxUCR_STOP_HIGH | - UxUCR_START_LOW); + UxUCR_STOP_LOW | + UxUCR_START_HIGH); } void -- cgit v1.2.3 From 18edacdb1e6e429cc29a164e22ef2a566096b9d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:06:32 -0700 Subject: Make serial test simpler --- target/serial/serial.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 6065d971..6db81ae9 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -235,9 +235,8 @@ main () spi_init(); for (;;) { - for (i = 0; i < sizeof (string) - 1; i++) { - usart_out_byte(string[i]); - } + usart_out_byte('A'); + delay(5); P1 ^= 2; } } -- cgit v1.2.3 From 7b7617e376afe0df1d505375b76198358330370c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:09:47 -0700 Subject: Try serial polarity high/high --- target/serial/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 6db81ae9..ecf065a2 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -193,7 +193,7 @@ usart_init(void) UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | UxUCR_SPB_1_STOP_BIT | - UxUCR_STOP_LOW | + UxUCR_STOP_HIGH | UxUCR_START_HIGH); } -- cgit v1.2.3 From 50bdc2407c674a4770912d3a626f36820a7f1527 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:13:15 -0700 Subject: Flip serial TX code around a bit --- target/serial/serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index ecf065a2..d2be47fd 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -194,16 +194,16 @@ usart_init(void) UxUCR_PARITY_DISABLE | UxUCR_SPB_1_STOP_BIT | UxUCR_STOP_HIGH | - UxUCR_START_HIGH); + UxUCR_START_LOW); } void usart_out_byte(uint8_t byte) { - U1CSR &= ~UxCSR_TX_BYTE; U1DBUF = byte; while ((U1CSR & UxCSR_TX_BYTE) == 0) ; + U1CSR &= ~UxCSR_TX_BYTE; } uint8_t -- cgit v1.2.3 From 5049acd3d1ae42304513f667f55a2ddffa4c685a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:24:56 -0700 Subject: More random serial bit frobbing --- target/serial/serial.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index d2be47fd..589452c0 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -188,11 +188,12 @@ usart_init(void) /* * Reasonable serial parameters */ - U1UCR = (UxUCR_FLOW_DISABLE | - UxUCR_D9_EVEN_PARITY | + U1UCR = (UxUCR_FLUSH | + UxUCR_FLOW_DISABLE | + UxUCR_D9_ODD_PARITY | UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | - UxUCR_SPB_1_STOP_BIT | + UxUCR_SPB_2_STOP_BITS | UxUCR_STOP_HIGH | UxUCR_START_LOW); } -- cgit v1.2.3 From 006124529b243c7657a94312d2c868a82878d8bb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:29:29 -0700 Subject: Send more interesting text --- target/serial/serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 589452c0..42705d71 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -236,7 +236,8 @@ main () spi_init(); for (;;) { - usart_out_byte('A'); + for (i = 0; i < sizeof(string) - 1; i++) + usart_out_byte(string[i]); delay(5); P1 ^= 2; } -- cgit v1.2.3 From cfaf187e96ba98eb8dd934409a10bc70273fe68a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:36:35 -0700 Subject: Use UTX1IF to wait for serial TX complete --- target/serial/serial.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 42705d71..1050b9a6 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -79,6 +79,19 @@ sbit at 0x97 P1_7; sfr at 0x86 U0CSR; sfr at 0xF8 U1CSR; +/* + * IRCON2 + */ +sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ + +sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ +sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ +sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ +sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ +sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ +sbit at 0xEB P1IF; /* Port1 interrupt flag */ +sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */ + # define UxCSR_MODE_UART (1 << 7) # define UxCSR_MODE_SPI (0 << 7) # define UxCSR_RE (1 << 6) @@ -193,7 +206,7 @@ usart_init(void) UxUCR_D9_ODD_PARITY | UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | - UxUCR_SPB_2_STOP_BITS | + UxUCR_SPB_1_STOP_BIT | UxUCR_STOP_HIGH | UxUCR_START_LOW); } @@ -202,9 +215,8 @@ void usart_out_byte(uint8_t byte) { U1DBUF = byte; - while ((U1CSR & UxCSR_TX_BYTE) == 0) - ; - U1CSR &= ~UxCSR_TX_BYTE; + while (!UTX1IF); + UTX1IF = 0; } uint8_t -- cgit v1.2.3 From 019456a17d36f8f9f9b72cfbc980492175086d32 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:41:49 -0700 Subject: Add a per-char delay --- target/serial/serial.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 1050b9a6..1c352831 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -156,6 +156,7 @@ delay (unsigned char n) unsigned char i = 0; unsigned char j = 0; + n++; while (--n != 0) while (--i != 0) while (--j != 0) @@ -215,8 +216,10 @@ void usart_out_byte(uint8_t byte) { U1DBUF = byte; - while (!UTX1IF); + while (!UTX1IF) + ; UTX1IF = 0; + delay(1); } uint8_t @@ -230,10 +233,6 @@ usart_in_byte(void) return b; } -#define spi_init() usart_init() -#define spi_out_byte(b) usart_out_byte(b) -#define spi_in_byte() usart_in_byte() - static char string[] = "hello world\r\n"; main () @@ -245,7 +244,7 @@ main () while (!(SLEEP & SLEEP_XOSC_STB)) ; - spi_init(); + usart_init(); for (;;) { for (i = 0; i < sizeof(string) - 1; i++) -- cgit v1.2.3 From 029963cc94fbb47560118b5de73c537e2c14ed7c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:50:02 -0700 Subject: Eliminate array walking --- target/serial/serial.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index 1c352831..ebe7e2fc 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -207,7 +207,7 @@ usart_init(void) UxUCR_D9_ODD_PARITY | UxUCR_BIT9_8_BITS | UxUCR_PARITY_DISABLE | - UxUCR_SPB_1_STOP_BIT | + UxUCR_SPB_2_STOP_BITS | UxUCR_STOP_HIGH | UxUCR_START_LOW); } @@ -219,7 +219,15 @@ usart_out_byte(uint8_t byte) while (!UTX1IF) ; UTX1IF = 0; - delay(1); +} + +void +usart_out_string(uint8_t *string) +{ + uint8_t b; + + while (b = *string++) + usart_out_byte(b); } uint8_t @@ -233,12 +241,8 @@ usart_in_byte(void) return b; } -static char string[] = "hello world\r\n"; - main () { - uint8_t i; - P1DIR |= 2; CLKCON = 0; while (!(SLEEP & SLEEP_XOSC_STB)) @@ -247,8 +251,7 @@ main () usart_init(); for (;;) { - for (i = 0; i < sizeof(string) - 1; i++) - usart_out_byte(string[i]); + usart_out_string("hello world\r\n"); delay(5); P1 ^= 2; } -- cgit v1.2.3 From ffd43886dc902f3bb7407294018e3d62cac39480 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 00:55:11 -0700 Subject: Check serial input --- target/serial/serial.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/target/serial/serial.c b/target/serial/serial.c index ebe7e2fc..29390426 100644 --- a/target/serial/serial.c +++ b/target/serial/serial.c @@ -241,6 +241,18 @@ usart_in_byte(void) return b; } +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(5); + byte >>= 1; + } +} + main () { P1DIR |= 2; @@ -252,7 +264,7 @@ main () for (;;) { usart_out_string("hello world\r\n"); - delay(5); - P1 ^= 2; + debug_byte(usart_in_byte()); } + } -- cgit v1.2.3 From 9ce713fdd19bf1a51370dacba3670504356c5c11 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 01:02:07 -0700 Subject: Wait for xtal to stabilize --- target/radio/radio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/radio/radio.c b/target/radio/radio.c index ba693a77..d6c49eff 100644 --- a/target/radio/radio.c +++ b/target/radio/radio.c @@ -518,6 +518,8 @@ radio_init() { main () { CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; /* Set P2_0 to output */ radio_init (); delay(100); -- cgit v1.2.3 From 31d59b88baa2cd96dc6263d1c5877283f2cd8c36 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 01:03:08 -0700 Subject: Make radio test compile again --- target/radio/radio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/radio/radio.c b/target/radio/radio.c index d6c49eff..3ca7a010 100644 --- a/target/radio/radio.c +++ b/target/radio/radio.c @@ -46,6 +46,11 @@ sfr at 0xE1 RFST; sfr at 0x88 TCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + sbit at 0x89 RFTXRXIF; #define TCON_RFTXRXIF (1 << 1) -- cgit v1.2.3 From 7b3fdf5b42c9be9bebc1ceb7a52ff0f5a2a28fcd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 01:05:36 -0700 Subject: Back to 0dBm --- target/radio/radio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/radio/radio.c b/target/radio/radio.c index 3ca7a010..90bc47f3 100644 --- a/target/radio/radio.c +++ b/target/radio/radio.c @@ -433,7 +433,7 @@ low() { #define RF_POWER_7_DBM 0xc8 #define RF_POWER_10_DBM 0xc0 -#define RF_POWER RF_POWER_M30_DBM +#define RF_POWER RF_POWER_0_DBM static __code uint8_t radio_setup[] = { RF_PA_TABLE7_OFF, RF_POWER, -- cgit v1.2.3 From 61faf2b773300988fe27cfde5bc045be9950a1b0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 09:45:14 -0700 Subject: Add DMA example --- target/dma/Makefile | 46 +++++++ target/dma/dma.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+) create mode 100644 target/dma/Makefile create mode 100644 target/dma/dma.c diff --git a/target/dma/Makefile b/target/dma/Makefile new file mode 100644 index 00000000..9cb3e327 --- /dev/null +++ b/target/dma/Makefile @@ -0,0 +1,46 @@ +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=dma.c +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=dma-flash.ihx dma-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +dma-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o dma-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o dma-flash.ihx $(REL) + +dma-flash.ihx: dma-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/dma/dma.c b/target/dma/dma.c new file mode 100644 index 00000000..c35c39f6 --- /dev/null +++ b/target/dma/dma.c @@ -0,0 +1,361 @@ +/* + * 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 + +/* + * Test DMA + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +/* + * IRCON2 + */ +sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ + +sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ +sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ +sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ +sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ +sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ +sbit at 0xEB P1IF; /* Port1 interrupt flag */ +sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */ + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +# define UxUCR_FLUSH (1 << 7) +# define UxUCR_FLOW_DISABLE (0 << 6) +# define UxUCR_FLOW_ENABLE (1 << 6) +# define UxUCR_D9_EVEN_PARITY (0 << 5) +# define UxUCR_D9_ODD_PARITY (1 << 5) +# define UxUCR_BIT9_8_BITS (0 << 4) +# define UxUCR_BIT9_9_BITS (1 << 4) +# define UxUCR_PARITY_DISABLE (0 << 3) +# define UxUCR_PARITY_ENABLE (1 << 3) +# define UxUCR_SPB_1_STOP_BIT (0 << 2) +# define UxUCR_SPB_2_STOP_BITS (1 << 2) +# define UxUCR_STOP_LOW (0 << 1) +# define UxUCR_STOP_HIGH (1 << 1) +# define UxUCR_START_LOW (0 << 0) +# define UxUCR_START_HIGH (1 << 0) + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + +#define DEBUG P1_1 + + +# define DMA_LEN_HIGH_VLEN_MASK (7 << 5) +# define DMA_LEN_HIGH_VLEN_LEN (0 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) +# define DMA_LEN_HIGH_VLEN (2 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) +# define DMA_LEN_HIGH_MASK (0x1f) + +# define DMA_CFG0_WORDSIZE_8 (0 << 7) +# define DMA_CFG0_WORDSIZE_16 (1 << 7) +# define DMA_CFG0_TMODE_MASK (3 << 5) +# define DMA_CFG0_TMODE_SINGLE (0 << 5) +# define DMA_CFG0_TMODE_BLOCK (1 << 5) +# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) +# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) + +/* + * DMA triggers + */ +# define DMA_CFG0_TRIGGER_NONE 0 +# define DMA_CFG0_TRIGGER_PREV 1 +# define DMA_CFG0_TRIGGER_T1_CH0 2 +# define DMA_CFG0_TRIGGER_T1_CH1 3 +# define DMA_CFG0_TRIGGER_T1_CH2 4 +# define DMA_CFG0_TRIGGER_T2_OVFL 6 +# define DMA_CFG0_TRIGGER_T3_CH0 7 +# define DMA_CFG0_TRIGGER_T3_CH1 8 +# define DMA_CFG0_TRIGGER_T4_CH0 9 +# define DMA_CFG0_TRIGGER_T4_CH1 10 +# define DMA_CFG0_TRIGGER_IOC_0 12 +# define DMA_CFG0_TRIGGER_IOC_1 13 +# define DMA_CFG0_TRIGGER_URX0 14 +# define DMA_CFG0_TRIGGER_UTX0 15 +# define DMA_CFG0_TRIGGER_URX1 16 +# define DMA_CFG0_TRIGGER_UTX1 17 +# define DMA_CFG0_TRIGGER_FLASH 18 +# define DMA_CFG0_TRIGGER_RADIO 19 +# define DMA_CFG0_TRIGGER_ADC_CHALL 20 +# define DMA_CFG0_TRIGGER_ADC_CH0 21 +# define DMA_CFG0_TRIGGER_ADC_CH1 22 +# define DMA_CFG0_TRIGGER_ADC_CH2 23 +# define DMA_CFG0_TRIGGER_ADC_CH3 24 +# define DMA_CFG0_TRIGGER_ADC_CH4 25 +# define DMA_CFG0_TRIGGER_ADC_CH5 26 +# define DMA_CFG0_TRIGGER_ADC_CH6 27 +# define DMA_CFG0_TRIGGER_I2SRX 27 +# define DMA_CFG0_TRIGGER_ADC_CH7 28 +# define DMA_CFG0_TRIGGER_I2STX 28 +# define DMA_CFG0_TRIGGER_ENC_DW 29 +# define DMA_CFG0_TRIGGER_DNC_UP 30 + +# define DMA_CFG1_SRCINC_MASK (3 << 6) +# define DMA_CFG1_SRCINC_0 (0 << 6) +# define DMA_CFG1_SRCINC_1 (1 << 6) +# define DMA_CFG1_SRCINC_2 (2 << 6) +# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6) + +# define DMA_CFG1_DESTINC_MASK (3 << 4) +# define DMA_CFG1_DESTINC_0 (0 << 4) +# define DMA_CFG1_DESTINC_1 (1 << 4) +# define DMA_CFG1_DESTINC_2 (2 << 4) +# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4) + +# define DMA_CFG1_IRQMASK (1 << 3) +# define DMA_CFG1_M8 (1 << 2) + +# define DMA_CFG1_PRIORITY_MASK (3 << 0) +# define DMA_CFG1_PRIORITY_LOW (0 << 0) +# define DMA_CFG1_PRIORITY_NORMAL (1 << 0) +# define DMA_CFG1_PRIORITY_HIGH (2 << 0) + +/* + * DMAARM - DMA Channel Arm + */ + +sfr at 0xD6 DMAARM; + +# define DMAARM_ABORT (1 << 7) +# define DMAARM_DMAARM4 (1 << 4) +# define DMAARM_DMAARM3 (1 << 3) +# define DMAARM_DMAARM2 (1 << 2) +# define DMAARM_DMAARM1 (1 << 1) +# define DMAARM_DMAARM0 (1 << 0) + +/* + * DMAREQ - DMA Channel Start Request and Status + */ + +sfr at 0xD7 DMAREQ; + +# define DMAREQ_DMAREQ4 (1 << 4) +# define DMAREQ_DMAREQ3 (1 << 3) +# define DMAREQ_DMAREQ2 (1 << 2) +# define DMAREQ_DMAREQ1 (1 << 1) +# define DMAREQ_DMAREQ0 (1 << 0) + +/* + * DMA configuration 0 address + */ + +sfr at 0xD5 DMA0CFGH; +sfr at 0xD4 DMA0CFGL; + +/* + * DMA configuration 1-4 address + */ + +sfr at 0xD3 DMA1CFGH; +sfr at 0xD2 DMA1CFGL; + +/* + * DMAIRQ - DMA Interrupt Flag + */ + +sfr at 0xD1 DMAIRQ; + +# define DMAIRQ_DMAIF4 (1 << 4) +# define DMAIRQ_DMAIF3 (1 << 3) +# define DMAIRQ_DMAIF2 (1 << 2) +# define DMAIRQ_DMAIF1 (1 << 1) +# define DMAIRQ_DMAIF0 (1 << 0) + +struct cc_dma_channel { + uint8_t src_high; + uint8_t src_low; + uint8_t dst_high; + uint8_t dst_low; + uint8_t len_high; + uint8_t len_low; + uint8_t cfg0; + uint8_t cfg1; +}; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + n++; + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(5); + byte >>= 1; + } +} + +struct cc_dma_channel __xdata config; + +#define DMA_LEN 8 + +uint8_t __xdata dma_input[DMA_LEN]; +uint8_t __xdata dma_output[DMA_LEN]; + +#define ADDRH(a) (((uint16_t) (a)) >> 8) +#define ADDRL(a) (((uint16_t) (a))) + +void +dma_init(void) +{ + int i; + config.cfg0 = (DMA_CFG0_WORDSIZE_8 | + DMA_CFG0_TMODE_BLOCK | + DMA_CFG0_TRIGGER_NONE); + config.cfg1 = (DMA_CFG1_SRCINC_1 | + DMA_CFG1_DESTINC_1 | + DMA_CFG1_PRIORITY_NORMAL); + + config.src_high = ADDRH(dma_input); + config.src_low = ADDRL(dma_input); + config.dst_high = ADDRH(dma_output); + config.dst_low = ADDRL(dma_output); + config.len_high = 0; + config.len_low = DMA_LEN; + DMA0CFGH = ADDRH(&config); + DMA0CFGL = ADDRL(&config); + for (i = 0; i < DMA_LEN; i++) + dma_input[i] = i + 1; +} + +void +dma_run(void) +{ + DMAREQ |= 1; + DMAARM |= 1; + while (DMAARM & 1) + ; +} + +main () +{ + int i; + P1DIR |= 2; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + + dma_init(); + dma_run(); + for (;;) { + for (i = 0; i < DMA_LEN; i++) + debug_byte(dma_output[i]); + } +} -- cgit v1.2.3 From d9fd548db15232e3a8823815962b252c7a5e7cba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 10:04:50 -0700 Subject: Add ADC via DMA example --- target/adc/Makefile | 47 ++++++ target/adc/adc.c | 470 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 517 insertions(+) create mode 100644 target/adc/Makefile create mode 100644 target/adc/adc.c diff --git a/target/adc/Makefile b/target/adc/Makefile new file mode 100644 index 00000000..54c1211a --- /dev/null +++ b/target/adc/Makefile @@ -0,0 +1,47 @@ +PROG=adc +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=$(PROG).c +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=$(PROG)-flash.ihx $(PROG)-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +$(PROG)-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL) + +$(PROG)-flash.ihx: $(PROG)-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/adc/adc.c b/target/adc/adc.c new file mode 100644 index 00000000..d6d15e6a --- /dev/null +++ b/target/adc/adc.c @@ -0,0 +1,470 @@ +/* + * 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 + +/* + * Test ADC in DMA mode + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +/* + * IRCON2 + */ +sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ + +sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ +sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ +sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ +sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ +sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ +sbit at 0xEB P1IF; /* Port1 interrupt flag */ +sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */ + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +# define UxUCR_FLUSH (1 << 7) +# define UxUCR_FLOW_DISABLE (0 << 6) +# define UxUCR_FLOW_ENABLE (1 << 6) +# define UxUCR_D9_EVEN_PARITY (0 << 5) +# define UxUCR_D9_ODD_PARITY (1 << 5) +# define UxUCR_BIT9_8_BITS (0 << 4) +# define UxUCR_BIT9_9_BITS (1 << 4) +# define UxUCR_PARITY_DISABLE (0 << 3) +# define UxUCR_PARITY_ENABLE (1 << 3) +# define UxUCR_SPB_1_STOP_BIT (0 << 2) +# define UxUCR_SPB_2_STOP_BITS (1 << 2) +# define UxUCR_STOP_LOW (0 << 1) +# define UxUCR_STOP_HIGH (1 << 1) +# define UxUCR_START_LOW (0 << 0) +# define UxUCR_START_HIGH (1 << 0) + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + +#define DEBUG P1_1 + + +# define DMA_LEN_HIGH_VLEN_MASK (7 << 5) +# define DMA_LEN_HIGH_VLEN_LEN (0 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) +# define DMA_LEN_HIGH_VLEN (2 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) +# define DMA_LEN_HIGH_MASK (0x1f) + +# define DMA_CFG0_WORDSIZE_8 (0 << 7) +# define DMA_CFG0_WORDSIZE_16 (1 << 7) +# define DMA_CFG0_TMODE_MASK (3 << 5) +# define DMA_CFG0_TMODE_SINGLE (0 << 5) +# define DMA_CFG0_TMODE_BLOCK (1 << 5) +# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) +# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) + +/* + * DMA triggers + */ +# define DMA_CFG0_TRIGGER_NONE 0 +# define DMA_CFG0_TRIGGER_PREV 1 +# define DMA_CFG0_TRIGGER_T1_CH0 2 +# define DMA_CFG0_TRIGGER_T1_CH1 3 +# define DMA_CFG0_TRIGGER_T1_CH2 4 +# define DMA_CFG0_TRIGGER_T2_OVFL 6 +# define DMA_CFG0_TRIGGER_T3_CH0 7 +# define DMA_CFG0_TRIGGER_T3_CH1 8 +# define DMA_CFG0_TRIGGER_T4_CH0 9 +# define DMA_CFG0_TRIGGER_T4_CH1 10 +# define DMA_CFG0_TRIGGER_IOC_0 12 +# define DMA_CFG0_TRIGGER_IOC_1 13 +# define DMA_CFG0_TRIGGER_URX0 14 +# define DMA_CFG0_TRIGGER_UTX0 15 +# define DMA_CFG0_TRIGGER_URX1 16 +# define DMA_CFG0_TRIGGER_UTX1 17 +# define DMA_CFG0_TRIGGER_FLASH 18 +# define DMA_CFG0_TRIGGER_RADIO 19 +# define DMA_CFG0_TRIGGER_ADC_CHALL 20 +# define DMA_CFG0_TRIGGER_ADC_CH0 21 +# define DMA_CFG0_TRIGGER_ADC_CH1 22 +# define DMA_CFG0_TRIGGER_ADC_CH2 23 +# define DMA_CFG0_TRIGGER_ADC_CH3 24 +# define DMA_CFG0_TRIGGER_ADC_CH4 25 +# define DMA_CFG0_TRIGGER_ADC_CH5 26 +# define DMA_CFG0_TRIGGER_ADC_CH6 27 +# define DMA_CFG0_TRIGGER_I2SRX 27 +# define DMA_CFG0_TRIGGER_ADC_CH7 28 +# define DMA_CFG0_TRIGGER_I2STX 28 +# define DMA_CFG0_TRIGGER_ENC_DW 29 +# define DMA_CFG0_TRIGGER_DNC_UP 30 + +# define DMA_CFG1_SRCINC_MASK (3 << 6) +# define DMA_CFG1_SRCINC_0 (0 << 6) +# define DMA_CFG1_SRCINC_1 (1 << 6) +# define DMA_CFG1_SRCINC_2 (2 << 6) +# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6) + +# define DMA_CFG1_DESTINC_MASK (3 << 4) +# define DMA_CFG1_DESTINC_0 (0 << 4) +# define DMA_CFG1_DESTINC_1 (1 << 4) +# define DMA_CFG1_DESTINC_2 (2 << 4) +# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4) + +# define DMA_CFG1_IRQMASK (1 << 3) +# define DMA_CFG1_M8 (1 << 2) + +# define DMA_CFG1_PRIORITY_MASK (3 << 0) +# define DMA_CFG1_PRIORITY_LOW (0 << 0) +# define DMA_CFG1_PRIORITY_NORMAL (1 << 0) +# define DMA_CFG1_PRIORITY_HIGH (2 << 0) + +/* + * DMAARM - DMA Channel Arm + */ + +sfr at 0xD6 DMAARM; + +# define DMAARM_ABORT (1 << 7) +# define DMAARM_DMAARM4 (1 << 4) +# define DMAARM_DMAARM3 (1 << 3) +# define DMAARM_DMAARM2 (1 << 2) +# define DMAARM_DMAARM1 (1 << 1) +# define DMAARM_DMAARM0 (1 << 0) + +/* + * DMAREQ - DMA Channel Start Request and Status + */ + +sfr at 0xD7 DMAREQ; + +# define DMAREQ_DMAREQ4 (1 << 4) +# define DMAREQ_DMAREQ3 (1 << 3) +# define DMAREQ_DMAREQ2 (1 << 2) +# define DMAREQ_DMAREQ1 (1 << 1) +# define DMAREQ_DMAREQ0 (1 << 0) + +/* + * DMA configuration 0 address + */ + +sfr at 0xD5 DMA0CFGH; +sfr at 0xD4 DMA0CFGL; + +/* + * DMA configuration 1-4 address + */ + +sfr at 0xD3 DMA1CFGH; +sfr at 0xD2 DMA1CFGL; + +/* + * DMAIRQ - DMA Interrupt Flag + */ + +sfr at 0xD1 DMAIRQ; + +# define DMAIRQ_DMAIF4 (1 << 4) +# define DMAIRQ_DMAIF3 (1 << 3) +# define DMAIRQ_DMAIF2 (1 << 2) +# define DMAIRQ_DMAIF1 (1 << 1) +# define DMAIRQ_DMAIF0 (1 << 0) + +struct cc_dma_channel { + uint8_t src_high; + uint8_t src_low; + uint8_t dst_high; + uint8_t dst_low; + uint8_t len_high; + uint8_t len_low; + uint8_t cfg0; + uint8_t cfg1; +}; + +/* + * ADC Data register, low and high + */ +sfr at 0xBA ADCL; +sfr at 0xBB ADCH; +__xdata __at (0xDFBA) volatile uint16_t ADCXDATA; + +/* + * ADC Control Register 1 + */ +sfr at 0xB4 ADCCON1; + +# define ADCCON1_EOC (1 << 7) /* conversion complete */ +# define ADCCON1_ST (1 << 6) /* start conversion */ + +# define ADCCON1_STSEL_MASK (3 << 4) /* start select */ +# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */ +# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */ +# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */ +# define ADCCON1_STSEL_START (3 << 4) /* set start bit */ + +# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */ +# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */ +# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */ + +/* + * ADC Control Register 2 + */ +sfr at 0xB5 ADCCON2; + +# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */ +# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */ +# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */ +# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */ +# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */ + +# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */ +# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */ +# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */ +# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */ +# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */ + +# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */ +# define ADCCON2_SCH_SHIFT 0 +# define ADCCON2_SCH_AIN0 (0 << 0) +# define ADCCON2_SCH_AIN1 (1 << 0) +# define ADCCON2_SCH_AIN2 (2 << 0) +# define ADCCON2_SCH_AIN3 (3 << 0) +# define ADCCON2_SCH_AIN4 (4 << 0) +# define ADCCON2_SCH_AIN5 (5 << 0) +# define ADCCON2_SCH_AIN6 (6 << 0) +# define ADCCON2_SCH_AIN7 (7 << 0) +# define ADCCON2_SCH_AIN0_AIN1 (8 << 0) +# define ADCCON2_SCH_AIN2_AIN3 (9 << 0) +# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0) +# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0) +# define ADCCON2_SCH_GND (0xc << 0) +# define ADCCON2_SCH_VREF (0xd << 0) +# define ADCCON2_SCH_TEMP (0xe << 0) +# define ADCCON2_SCH_VDD_3 (0xf << 0) + + +/* + * ADC Control Register 3 + */ + +sfr at 0xB6 ADCCON3; + +# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */ +# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */ +# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */ +# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */ +# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */ +# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */ +# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */ +# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */ +# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */ +# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */ +# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */ +# define ADCCON3_ECH_SHIFT 0 +# define ADCCON3_ECH_AIN0 (0 << 0) +# define ADCCON3_ECH_AIN1 (1 << 0) +# define ADCCON3_ECH_AIN2 (2 << 0) +# define ADCCON3_ECH_AIN3 (3 << 0) +# define ADCCON3_ECH_AIN4 (4 << 0) +# define ADCCON3_ECH_AIN5 (5 << 0) +# define ADCCON3_ECH_AIN6 (6 << 0) +# define ADCCON3_ECH_AIN7 (7 << 0) +# define ADCCON3_ECH_AIN0_AIN1 (8 << 0) +# define ADCCON3_ECH_AIN2_AIN3 (9 << 0) +# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0) +# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0) +# define ADCCON3_ECH_GND (0xc << 0) +# define ADCCON3_ECH_VREF (0xd << 0) +# define ADCCON3_ECH_TEMP (0xe << 0) +# define ADCCON3_ECH_VDD_3 (0xf << 0) + +sfr at 0xF2 ADCCFG; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + n++; + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(5); + byte >>= 1; + } +} + +struct cc_dma_channel __xdata dma_config; + +#define ADC_LEN 6 + +uint16_t __xdata adc_output[ADC_LEN]; + +#define ADDRH(a) (((uint16_t) (a)) >> 8) +#define ADDRL(a) (((uint16_t) (a))) + +void +adc_init(void) +{ + dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 | + DMA_CFG0_TMODE_REPEATED_SINGLE | + DMA_CFG0_TRIGGER_ADC_CHALL); + dma_config.cfg1 = (DMA_CFG1_SRCINC_0 | + DMA_CFG1_DESTINC_2 | + DMA_CFG1_PRIORITY_NORMAL); + + dma_config.src_high = ADDRH(&ADCXDATA); + dma_config.src_low = ADDRL(&ADCXDATA); + dma_config.dst_high = ADDRH(adc_output); + dma_config.dst_low = ADDRL(adc_output); + dma_config.len_high = 0; + dma_config.len_low = ADC_LEN; + DMA0CFGH = ADDRH(&dma_config); + DMA0CFGL = ADDRL(&dma_config); + ADCCFG = ((1 << 0) | /* acceleration */ + (1 << 1) | /* pressure */ + (1 << 2) | /* temperature */ + (1 << 3) | /* battery voltage */ + (1 << 4) | /* drogue sense */ + (1 << 5)); /* main sense */ + + ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */ + ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */ + ADCCON2_SDIV_512 | /* 12 bit ADC results */ + ADCCON2_SCH_AIN5); /* sample all 6 inputs */ +} + +void +adc_run(void) +{ + DMAIRQ &= ~1; + DMAARM |= 1; + ADCCON1 |= ADCCON1_ST; + while ((DMAIRQ & 1) == 0) + ; +} + +main () +{ + int i; + P1DIR |= 2; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + while (P1 & 0x4) + ; + + adc_init(); + for (;;) { + adc_run(); + for (i = 0; i < ADC_LEN; i++) + debug_byte(adc_output[i]); + } +} -- cgit v1.2.3 From 2b93a70fdd9e47e8195855451aa19ecad5d8b068 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 10:50:14 -0700 Subject: Add adc to serial conversion --- target/adc-serial/Makefile | 47 ++++ target/adc-serial/adc_serial.c | 557 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 604 insertions(+) create mode 100644 target/adc-serial/Makefile create mode 100644 target/adc-serial/adc_serial.c diff --git a/target/adc-serial/Makefile b/target/adc-serial/Makefile new file mode 100644 index 00000000..9a8bf5c6 --- /dev/null +++ b/target/adc-serial/Makefile @@ -0,0 +1,47 @@ +PROG=adc_serial +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --stack-auto --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf800 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=$(PROG).c +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=$(PROG)-flash.ihx $(PROG)-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +$(PROG)-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL) + +$(PROG)-flash.ihx: $(PROG)-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c new file mode 100644 index 00000000..c141567a --- /dev/null +++ b/target/adc-serial/adc_serial.c @@ -0,0 +1,557 @@ +/* + * 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 + +/* + * Test ADC in DMA mode + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +/* + * IRCON2 + */ +sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ + +sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ +sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ +sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ +sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ +sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ +sbit at 0xEB P1IF; /* Port1 interrupt flag */ +sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */ + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +# define UxUCR_FLUSH (1 << 7) +# define UxUCR_FLOW_DISABLE (0 << 6) +# define UxUCR_FLOW_ENABLE (1 << 6) +# define UxUCR_D9_EVEN_PARITY (0 << 5) +# define UxUCR_D9_ODD_PARITY (1 << 5) +# define UxUCR_BIT9_8_BITS (0 << 4) +# define UxUCR_BIT9_9_BITS (1 << 4) +# define UxUCR_PARITY_DISABLE (0 << 3) +# define UxUCR_PARITY_ENABLE (1 << 3) +# define UxUCR_SPB_1_STOP_BIT (0 << 2) +# define UxUCR_SPB_2_STOP_BITS (1 << 2) +# define UxUCR_STOP_LOW (0 << 1) +# define UxUCR_STOP_HIGH (1 << 1) +# define UxUCR_START_LOW (0 << 0) +# define UxUCR_START_HIGH (1 << 0) + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + +#define DEBUG P1_1 + + +# define DMA_LEN_HIGH_VLEN_MASK (7 << 5) +# define DMA_LEN_HIGH_VLEN_LEN (0 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) +# define DMA_LEN_HIGH_VLEN (2 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) +# define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) +# define DMA_LEN_HIGH_MASK (0x1f) + +# define DMA_CFG0_WORDSIZE_8 (0 << 7) +# define DMA_CFG0_WORDSIZE_16 (1 << 7) +# define DMA_CFG0_TMODE_MASK (3 << 5) +# define DMA_CFG0_TMODE_SINGLE (0 << 5) +# define DMA_CFG0_TMODE_BLOCK (1 << 5) +# define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) +# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) + +/* + * DMA triggers + */ +# define DMA_CFG0_TRIGGER_NONE 0 +# define DMA_CFG0_TRIGGER_PREV 1 +# define DMA_CFG0_TRIGGER_T1_CH0 2 +# define DMA_CFG0_TRIGGER_T1_CH1 3 +# define DMA_CFG0_TRIGGER_T1_CH2 4 +# define DMA_CFG0_TRIGGER_T2_OVFL 6 +# define DMA_CFG0_TRIGGER_T3_CH0 7 +# define DMA_CFG0_TRIGGER_T3_CH1 8 +# define DMA_CFG0_TRIGGER_T4_CH0 9 +# define DMA_CFG0_TRIGGER_T4_CH1 10 +# define DMA_CFG0_TRIGGER_IOC_0 12 +# define DMA_CFG0_TRIGGER_IOC_1 13 +# define DMA_CFG0_TRIGGER_URX0 14 +# define DMA_CFG0_TRIGGER_UTX0 15 +# define DMA_CFG0_TRIGGER_URX1 16 +# define DMA_CFG0_TRIGGER_UTX1 17 +# define DMA_CFG0_TRIGGER_FLASH 18 +# define DMA_CFG0_TRIGGER_RADIO 19 +# define DMA_CFG0_TRIGGER_ADC_CHALL 20 +# define DMA_CFG0_TRIGGER_ADC_CH0 21 +# define DMA_CFG0_TRIGGER_ADC_CH1 22 +# define DMA_CFG0_TRIGGER_ADC_CH2 23 +# define DMA_CFG0_TRIGGER_ADC_CH3 24 +# define DMA_CFG0_TRIGGER_ADC_CH4 25 +# define DMA_CFG0_TRIGGER_ADC_CH5 26 +# define DMA_CFG0_TRIGGER_ADC_CH6 27 +# define DMA_CFG0_TRIGGER_I2SRX 27 +# define DMA_CFG0_TRIGGER_ADC_CH7 28 +# define DMA_CFG0_TRIGGER_I2STX 28 +# define DMA_CFG0_TRIGGER_ENC_DW 29 +# define DMA_CFG0_TRIGGER_DNC_UP 30 + +# define DMA_CFG1_SRCINC_MASK (3 << 6) +# define DMA_CFG1_SRCINC_0 (0 << 6) +# define DMA_CFG1_SRCINC_1 (1 << 6) +# define DMA_CFG1_SRCINC_2 (2 << 6) +# define DMA_CFG1_SRCINC_MINUS_1 (3 << 6) + +# define DMA_CFG1_DESTINC_MASK (3 << 4) +# define DMA_CFG1_DESTINC_0 (0 << 4) +# define DMA_CFG1_DESTINC_1 (1 << 4) +# define DMA_CFG1_DESTINC_2 (2 << 4) +# define DMA_CFG1_DESTINC_MINUS_1 (3 << 4) + +# define DMA_CFG1_IRQMASK (1 << 3) +# define DMA_CFG1_M8 (1 << 2) + +# define DMA_CFG1_PRIORITY_MASK (3 << 0) +# define DMA_CFG1_PRIORITY_LOW (0 << 0) +# define DMA_CFG1_PRIORITY_NORMAL (1 << 0) +# define DMA_CFG1_PRIORITY_HIGH (2 << 0) + +/* + * DMAARM - DMA Channel Arm + */ + +sfr at 0xD6 DMAARM; + +# define DMAARM_ABORT (1 << 7) +# define DMAARM_DMAARM4 (1 << 4) +# define DMAARM_DMAARM3 (1 << 3) +# define DMAARM_DMAARM2 (1 << 2) +# define DMAARM_DMAARM1 (1 << 1) +# define DMAARM_DMAARM0 (1 << 0) + +/* + * DMAREQ - DMA Channel Start Request and Status + */ + +sfr at 0xD7 DMAREQ; + +# define DMAREQ_DMAREQ4 (1 << 4) +# define DMAREQ_DMAREQ3 (1 << 3) +# define DMAREQ_DMAREQ2 (1 << 2) +# define DMAREQ_DMAREQ1 (1 << 1) +# define DMAREQ_DMAREQ0 (1 << 0) + +/* + * DMA configuration 0 address + */ + +sfr at 0xD5 DMA0CFGH; +sfr at 0xD4 DMA0CFGL; + +/* + * DMA configuration 1-4 address + */ + +sfr at 0xD3 DMA1CFGH; +sfr at 0xD2 DMA1CFGL; + +/* + * DMAIRQ - DMA Interrupt Flag + */ + +sfr at 0xD1 DMAIRQ; + +# define DMAIRQ_DMAIF4 (1 << 4) +# define DMAIRQ_DMAIF3 (1 << 3) +# define DMAIRQ_DMAIF2 (1 << 2) +# define DMAIRQ_DMAIF1 (1 << 1) +# define DMAIRQ_DMAIF0 (1 << 0) + +struct cc_dma_channel { + uint8_t src_high; + uint8_t src_low; + uint8_t dst_high; + uint8_t dst_low; + uint8_t len_high; + uint8_t len_low; + uint8_t cfg0; + uint8_t cfg1; +}; + +/* + * ADC Data register, low and high + */ +sfr at 0xBA ADCL; +sfr at 0xBB ADCH; +__xdata __at (0xDFBA) volatile uint16_t ADCXDATA; + +/* + * ADC Control Register 1 + */ +sfr at 0xB4 ADCCON1; + +# define ADCCON1_EOC (1 << 7) /* conversion complete */ +# define ADCCON1_ST (1 << 6) /* start conversion */ + +# define ADCCON1_STSEL_MASK (3 << 4) /* start select */ +# define ADCCON1_STSEL_EXTERNAL (0 << 4) /* P2_0 pin triggers */ +# define ADCCON1_STSEL_FULLSPEED (1 << 4) /* full speed, no waiting */ +# define ADCCON1_STSEL_TIMER1 (2 << 4) /* timer 1 channel 0 */ +# define ADCCON1_STSEL_START (3 << 4) /* set start bit */ + +# define ADCCON1_RCTRL_MASK (3 << 2) /* random number control */ +# define ADCCON1_RCTRL_COMPLETE (0 << 2) /* operation completed */ +# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2) /* Clock the LFSR once */ + +/* + * ADC Control Register 2 + */ +sfr at 0xB5 ADCCON2; + +# define ADCCON2_SREF_MASK (3 << 6) /* reference voltage */ +# define ADCCON2_SREF_1_25V (0 << 6) /* internal 1.25V */ +# define ADCCON2_SREF_EXTERNAL (1 << 6) /* external on AIN7 cc1110 */ +# define ADCCON2_SREF_VDD (2 << 6) /* VDD on the AVDD pin */ +# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6) /* external on AIN6-7 cc1110 */ + +# define ADCCON2_SDIV_MASK (3 << 4) /* decimation rate */ +# define ADCCON2_SDIV_64 (0 << 4) /* 7 bits */ +# define ADCCON2_SDIV_128 (1 << 4) /* 9 bits */ +# define ADCCON2_SDIV_256 (2 << 4) /* 10 bits */ +# define ADCCON2_SDIV_512 (3 << 4) /* 12 bits */ + +# define ADCCON2_SCH_MASK (0xf << 0) /* Sequence channel select */ +# define ADCCON2_SCH_SHIFT 0 +# define ADCCON2_SCH_AIN0 (0 << 0) +# define ADCCON2_SCH_AIN1 (1 << 0) +# define ADCCON2_SCH_AIN2 (2 << 0) +# define ADCCON2_SCH_AIN3 (3 << 0) +# define ADCCON2_SCH_AIN4 (4 << 0) +# define ADCCON2_SCH_AIN5 (5 << 0) +# define ADCCON2_SCH_AIN6 (6 << 0) +# define ADCCON2_SCH_AIN7 (7 << 0) +# define ADCCON2_SCH_AIN0_AIN1 (8 << 0) +# define ADCCON2_SCH_AIN2_AIN3 (9 << 0) +# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0) +# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0) +# define ADCCON2_SCH_GND (0xc << 0) +# define ADCCON2_SCH_VREF (0xd << 0) +# define ADCCON2_SCH_TEMP (0xe << 0) +# define ADCCON2_SCH_VDD_3 (0xf << 0) + + +/* + * ADC Control Register 3 + */ + +sfr at 0xB6 ADCCON3; + +# define ADCCON3_EREF_MASK (3 << 6) /* extra conversion reference */ +# define ADCCON3_EREF_1_25 (0 << 6) /* internal 1.25V */ +# define ADCCON3_EREF_EXTERNAL (1 << 6) /* external AIN7 cc1110 */ +# define ADCCON3_EREF_VDD (2 << 6) /* VDD on the AVDD pin */ +# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6) /* external AIN6-7 cc1110 */ +# define ADCCON2_EDIV_MASK (3 << 4) /* extral decimation */ +# define ADCCON2_EDIV_64 (0 << 4) /* 7 bits */ +# define ADCCON2_EDIV_128 (1 << 4) /* 9 bits */ +# define ADCCON2_EDIV_256 (2 << 4) /* 10 bits */ +# define ADCCON2_EDIV_512 (3 << 4) /* 12 bits */ +# define ADCCON3_ECH_MASK (0xf << 0) /* Sequence channel select */ +# define ADCCON3_ECH_SHIFT 0 +# define ADCCON3_ECH_AIN0 (0 << 0) +# define ADCCON3_ECH_AIN1 (1 << 0) +# define ADCCON3_ECH_AIN2 (2 << 0) +# define ADCCON3_ECH_AIN3 (3 << 0) +# define ADCCON3_ECH_AIN4 (4 << 0) +# define ADCCON3_ECH_AIN5 (5 << 0) +# define ADCCON3_ECH_AIN6 (6 << 0) +# define ADCCON3_ECH_AIN7 (7 << 0) +# define ADCCON3_ECH_AIN0_AIN1 (8 << 0) +# define ADCCON3_ECH_AIN2_AIN3 (9 << 0) +# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0) +# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0) +# define ADCCON3_ECH_GND (0xc << 0) +# define ADCCON3_ECH_VREF (0xd << 0) +# define ADCCON3_ECH_TEMP (0xe << 0) +# define ADCCON3_ECH_VDD_3 (0xf << 0) + +sfr at 0xF2 ADCCFG; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + n++; + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(5); + byte >>= 1; + } +} + +struct cc_dma_channel __xdata dma_config; + +#define ADC_LEN 6 + +uint16_t __xdata adc_output[ADC_LEN]; + +#define ADDRH(a) (((uint16_t) (a)) >> 8) +#define ADDRL(a) (((uint16_t) (a))) + +void +adc_init(void) +{ + dma_config.cfg0 = (DMA_CFG0_WORDSIZE_16 | + DMA_CFG0_TMODE_REPEATED_SINGLE | + DMA_CFG0_TRIGGER_ADC_CHALL); + dma_config.cfg1 = (DMA_CFG1_SRCINC_0 | + DMA_CFG1_DESTINC_2 | + DMA_CFG1_PRIORITY_NORMAL); + + dma_config.src_high = ADDRH(&ADCXDATA); + dma_config.src_low = ADDRL(&ADCXDATA); + dma_config.dst_high = ADDRH(adc_output); + dma_config.dst_low = ADDRL(adc_output); + dma_config.len_high = 0; + dma_config.len_low = ADC_LEN; + DMA0CFGH = ADDRH(&dma_config); + DMA0CFGL = ADDRL(&dma_config); + ADCCFG = ((1 << 0) | /* acceleration */ + (1 << 1) | /* pressure */ + (1 << 2) | /* temperature */ + (1 << 3) | /* battery voltage */ + (1 << 4) | /* drogue sense */ + (1 << 5)); /* main sense */ + + ADCCON1 = (ADCCON1_STSEL_START); /* ST bit triggers */ + ADCCON2 = (ADCCON2_SREF_VDD | /* reference voltage is VDD */ + ADCCON2_SDIV_512 | /* 12 bit ADC results */ + ADCCON2_SCH_AIN5); /* sample all 6 inputs */ +} + +void +adc_run(void) +{ + DMAIRQ &= ~1; + DMAARM |= 1; + ADCCON1 |= ADCCON1_ST; + while ((DMAIRQ & 1) == 0) + ; +} + +/* + * This version uses the USART in UART mode + */ +void +usart_init(void) +{ + P1DIR |= (1 << 2); + /* + * Configure the peripheral pin choices + * for both of the serial ports + * + * Note that telemetrum will use U1CFG_ALT_2 + * but that overlaps with SPI ALT_2, so until + * we can test that this works, we'll set this + * to ALT_1 + */ + PERCFG = (PERCFG_U1CFG_ALT_2 | + PERCFG_U0CFG_ALT_1); + + /* + * Make the UART pins controlled by the UART + * hardware + */ + P1SEL |= ((1 << 6) | (1 << 7)); + + /* + * UART mode with the receiver enabled + */ + U1CSR = (UxCSR_MODE_UART | + UxCSR_RE); + /* + * Pick a 38.4kbaud rate + */ + U1BAUD = 163; + U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */ +// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */ + /* + * Reasonable serial parameters + */ + U1UCR = (UxUCR_FLUSH | + UxUCR_FLOW_DISABLE | + UxUCR_D9_ODD_PARITY | + UxUCR_BIT9_8_BITS | + UxUCR_PARITY_DISABLE | + UxUCR_SPB_2_STOP_BITS | + UxUCR_STOP_HIGH | + UxUCR_START_LOW); +} + +void +usart_out_byte(uint8_t byte) +{ + U1DBUF = byte; + while (!UTX1IF) + ; + UTX1IF = 0; +} + +void +usart_out_string(uint8_t *string) +{ + uint8_t b; + + while (b = *string++) + usart_out_byte(b); +} + +uint8_t __xdata num_buffer[10]; +uint8_t __xdata * __xdata num_ptr; + +void +usart_out_number(uint16_t v) +{ + + num_ptr = num_buffer + 10; + *--num_ptr = '\0'; + do { + *--num_ptr = '0' + v % 10; + v /= 10; + } while (v); + usart_out_string(num_ptr); +} + +main () +{ + P1DIR |= 2; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + while (P1 & 0x4) + ; + + adc_init(); + usart_init(); + for (;;) { + adc_run(); + usart_out_string("drogue: "); + usart_out_number(adc_output[4]); + usart_out_string(" main: "); + usart_out_number(adc_output[5]); + usart_out_string("\r\n"); + delay(10); + } +} -- cgit v1.2.3 From f54a41e37d6897db2e24fbc82880076b78a0ae41 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 10:50:36 -0700 Subject: Remove poll for ti demo button --- target/adc-serial/adc_serial.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index c141567a..d10b3f79 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -540,8 +540,6 @@ main () CLKCON = 0; while (!(SLEEP & SLEEP_XOSC_STB)) ; - while (P1 & 0x4) - ; adc_init(); usart_init(); -- cgit v1.2.3 From 378227d869a3e8787c532c8c4e1563b44002c4b5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 10:55:17 -0700 Subject: Dump remaining inputs --- target/adc-serial/adc_serial.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index d10b3f79..349f3d7e 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -545,6 +545,14 @@ main () usart_init(); for (;;) { adc_run(); + usart_out_string("accel: "); + usart_out_number(adc_output[0]); + usart_out_string("pres: "); + usart_out_number(adc_output[1]); + usart_out_string("temp: "); + usart_out_number(adc_output[2]); + usart_out_string("batt: "); + usart_out_number(adc_output[3]); usart_out_string("drogue: "); usart_out_number(adc_output[4]); usart_out_string(" main: "); -- cgit v1.2.3 From 5577ca3762bfc000b0bc3782c73a8f95996a28a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 10:58:57 -0700 Subject: Inc only one on dest addr --- target/adc-serial/adc_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index 349f3d7e..b10d418e 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -417,7 +417,7 @@ adc_init(void) DMA_CFG0_TMODE_REPEATED_SINGLE | DMA_CFG0_TRIGGER_ADC_CHALL); dma_config.cfg1 = (DMA_CFG1_SRCINC_0 | - DMA_CFG1_DESTINC_2 | + DMA_CFG1_DESTINC_1 | DMA_CFG1_PRIORITY_NORMAL); dma_config.src_high = ADDRH(&ADCXDATA); -- cgit v1.2.3 From 50cc8e97e76d9b60c622962e1c74cf422dfb2c0f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 11:01:30 -0700 Subject: Add spacing for serial adc data --- target/adc-serial/adc_serial.c | 10 +++++----- target/adc/adc.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index b10d418e..b77dd713 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -547,15 +547,15 @@ main () adc_run(); usart_out_string("accel: "); usart_out_number(adc_output[0]); - usart_out_string("pres: "); + usart_out_string("\tpres: "); usart_out_number(adc_output[1]); - usart_out_string("temp: "); + usart_out_string("\ttemp: "); usart_out_number(adc_output[2]); - usart_out_string("batt: "); + usart_out_string("\tbatt: "); usart_out_number(adc_output[3]); - usart_out_string("drogue: "); + usart_out_string("\tdrogue: "); usart_out_number(adc_output[4]); - usart_out_string(" main: "); + usart_out_string("\tmain: "); usart_out_number(adc_output[5]); usart_out_string("\r\n"); delay(10); diff --git a/target/adc/adc.c b/target/adc/adc.c index d6d15e6a..bdc6c614 100644 --- a/target/adc/adc.c +++ b/target/adc/adc.c @@ -417,7 +417,7 @@ adc_init(void) DMA_CFG0_TMODE_REPEATED_SINGLE | DMA_CFG0_TRIGGER_ADC_CHALL); dma_config.cfg1 = (DMA_CFG1_SRCINC_0 | - DMA_CFG1_DESTINC_2 | + DMA_CFG1_DESTINC_1 | DMA_CFG1_PRIORITY_NORMAL); dma_config.src_high = ADDRH(&ADCXDATA); -- cgit v1.2.3 From d3732fd405af03c3752a84c4b78da7ef5ebd3744 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 11:14:03 -0700 Subject: Flip ADC bytes around --- target/adc-serial/adc_serial.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index b77dd713..fb58b4c2 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -405,7 +405,7 @@ struct cc_dma_channel __xdata dma_config; #define ADC_LEN 6 -uint16_t __xdata adc_output[ADC_LEN]; +uint8_t __xdata adc_output[ADC_LEN*2]; #define ADDRH(a) (((uint16_t) (a)) >> 8) #define ADDRL(a) (((uint16_t) (a))) @@ -531,9 +531,13 @@ usart_out_number(uint16_t v) *--num_ptr = '0' + v % 10; v /= 10; } while (v); + while (num_ptr != num_buffer) + *--num_ptr = ' '; usart_out_string(num_ptr); } +#define ADC(n) (((uint16_t) (adc_output[n<<1] << 8)) | (uint16_t) (adc_output[(n<<1)+1])) + main () { P1DIR |= 2; @@ -546,17 +550,17 @@ main () for (;;) { adc_run(); usart_out_string("accel: "); - usart_out_number(adc_output[0]); - usart_out_string("\tpres: "); - usart_out_number(adc_output[1]); - usart_out_string("\ttemp: "); - usart_out_number(adc_output[2]); - usart_out_string("\tbatt: "); - usart_out_number(adc_output[3]); - usart_out_string("\tdrogue: "); - usart_out_number(adc_output[4]); - usart_out_string("\tmain: "); - usart_out_number(adc_output[5]); + usart_out_number(ADC(0)); + usart_out_string("pres: "); + usart_out_number(ADC(1)); + usart_out_string("temp: "); + usart_out_number(ADC(2)); + usart_out_string("batt: "); + usart_out_number(ADC(3)); + usart_out_string("drogue: "); + usart_out_number(ADC(4)); + usart_out_string("main: "); + usart_out_number(ADC(5)); usart_out_string("\r\n"); delay(10); } -- cgit v1.2.3 From 66ee94ed10e3d79b24f45a5c63e58456d4d30343 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Mar 2009 11:37:48 -0700 Subject: Deal with MSB-outputing DMA engine --- target/adc-serial/adc_serial.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index fb58b4c2..9f722bb5 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -405,7 +405,15 @@ struct cc_dma_channel __xdata dma_config; #define ADC_LEN 6 -uint8_t __xdata adc_output[ADC_LEN*2]; +/* The DMA engine writes to XDATA in MSB order */ +struct dma_xdata16 { + uint8_t high; + uint8_t low; +}; + +struct dma_xdata16 adc_output[ADC_LEN]; + +#define DMA_XDATA16(a,n) ((uint16_t) ((a)[n].high << 8) | (uint16_t) (a[n].low)) #define ADDRH(a) (((uint16_t) (a)) >> 8) #define ADDRL(a) (((uint16_t) (a))) @@ -518,14 +526,16 @@ usart_out_string(uint8_t *string) usart_out_byte(b); } -uint8_t __xdata num_buffer[10]; +#define NUM_LEN 6 + +uint8_t __xdata num_buffer[NUM_LEN]; uint8_t __xdata * __xdata num_ptr; void usart_out_number(uint16_t v) { - num_ptr = num_buffer + 10; + num_ptr = num_buffer + NUM_LEN; *--num_ptr = '\0'; do { *--num_ptr = '0' + v % 10; @@ -533,10 +543,10 @@ usart_out_number(uint16_t v) } while (v); while (num_ptr != num_buffer) *--num_ptr = ' '; - usart_out_string(num_ptr); + usart_out_string(num_buffer); } -#define ADC(n) (((uint16_t) (adc_output[n<<1] << 8)) | (uint16_t) (adc_output[(n<<1)+1])) +#define ADC(n) DMA_XDATA16(adc_output,n) main () { @@ -551,15 +561,15 @@ main () adc_run(); usart_out_string("accel: "); usart_out_number(ADC(0)); - usart_out_string("pres: "); + usart_out_string(" pres: "); usart_out_number(ADC(1)); - usart_out_string("temp: "); + usart_out_string(" temp: "); usart_out_number(ADC(2)); - usart_out_string("batt: "); + usart_out_string(" batt: "); usart_out_number(ADC(3)); - usart_out_string("drogue: "); + usart_out_string(" drogue: "); usart_out_number(ADC(4)); - usart_out_string("main: "); + usart_out_string(" main: "); usart_out_number(ADC(5)); usart_out_string("\r\n"); delay(10); -- cgit v1.2.3 From 91607bebdd167ac632aca4b66e22cb0cabdf0d20 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Mar 2009 22:41:47 -0700 Subject: Add readline support to s51 --- s51/Makefile.am | 2 +- s51/s51-main.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/s51/Makefile.am b/s51/Makefile.am index 6213750c..4778d66b 100644 --- a/s51/Makefile.am +++ b/s51/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS=s51 AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) -S51_LIBS=../lib/libcc.a +S51_LIBS=../lib/libcc.a -lreadline man_MANS = s51.1 diff --git a/s51/s51-main.c b/s51/s51-main.c index 96429988..46b97b0c 100644 --- a/s51/s51-main.c +++ b/s51/s51-main.c @@ -189,19 +189,34 @@ s51_putc(int c) putc(c, s51_output); } +#include +#include + int s51_read_line(char *line, int len) { int ret; - if (s51_prompt) - s51_printf("%s", s51_prompt); - else - s51_putc('\0'); - fflush(s51_output); - ret = fgets(line, len, s51_input) != NULL; - if (s51_monitor) - printf("> %s", line); - fflush(stdout); + if (s51_output == stdout && s51_input == stdin && s51_prompt) { + char *r; + + r = readline(s51_prompt); + if (r == NULL) + return 0; + strncpy (line, r, len); + line[len-1] = '\0'; + add_history(r); + return 1; + } else { + if (s51_prompt) + s51_printf("%s", s51_prompt); + else + s51_putc('\0'); + fflush(s51_output); + ret = fgets(line, len, s51_input) != NULL; + if (s51_monitor) + printf("> %s", line); + fflush(stdout); + } return ret; } -- cgit v1.2.3 From 5fcfe854d29e1862d9a6adcbef3ef5119eb52fa3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 1 Apr 2009 00:06:45 -0700 Subject: Add timer-based beep test --- target/adc-serial/adc_serial.c | 3 +- target/beep-timer/Makefile | 47 ++++++++++ target/beep-timer/beep_timer.c | 204 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 target/beep-timer/Makefile create mode 100644 target/beep-timer/beep_timer.c diff --git a/target/adc-serial/adc_serial.c b/target/adc-serial/adc_serial.c index 9f722bb5..eba58744 100644 --- a/target/adc-serial/adc_serial.c +++ b/target/adc-serial/adc_serial.c @@ -550,12 +550,13 @@ usart_out_number(uint16_t v) main () { - P1DIR |= 2; + P1DIR = 3; CLKCON = 0; while (!(SLEEP & SLEEP_XOSC_STB)) ; adc_init(); + P1_0 = 1; usart_init(); for (;;) { adc_run(); diff --git a/target/beep-timer/Makefile b/target/beep-timer/Makefile new file mode 100644 index 00000000..008adbd5 --- /dev/null +++ b/target/beep-timer/Makefile @@ -0,0 +1,47 @@ +PROG=beep_timer +CC=sdcc +NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \ + --nolabelopt --nooverlay --peep-asm +DEBUG=--debug + +CFLAGS=--model-large $(DEBUG) --less-pedantic \ + --no-peep --int-long-reent --float-reent \ + --data-loc 0x30 + +LDFLAGS=--out-fmt-ihx +LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 + +LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 + +SRC=$(PROG).c +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=$(PROG)-flash.ihx $(PROG)-ram.ihx +PCDB=$(PROGS:.ihx=.cdb) +PLNK=$(PROGS:.ihx=.lnk) +PMAP=$(PROGS:.ihx=.map) +PMEM=$(PROGS:.ihx=.mem) +PAOM=$(PROGS:.ihx=) + +%.rel : %.c + $(CC) -c $(CFLAGS) -o$*.rel $< + +all: $(PROGS) + +$(PROG)-ram.ihx: $(REL) Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL) + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL) + +$(PROG)-flash.ihx: $(PROG)-ram.ihx + +clean: + rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) + rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM) + +install: diff --git a/target/beep-timer/beep_timer.c b/target/beep-timer/beep_timer.c new file mode 100644 index 00000000..53b95495 --- /dev/null +++ b/target/beep-timer/beep_timer.c @@ -0,0 +1,204 @@ +/* + * 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. + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +#define P2SEL_PRI3P1_USART0 (0 << 6) +#define P2SEL_PRI3P1_USART1 (1 << 6) +#define P2SEL_PRI2P1_USART1 (0 << 5) +#define P2SEL_PRI2P1_TIMER3 (1 << 5) +#define P2SEL_PRI1P1_TIMER1 (0 << 4) +#define P2SEL_PRI1P1_TIMER4 (1 << 4) +#define P2SEL_PRI0P1_USART0 (0 << 3) +#define P2SEL_PRI0P1_TIMER1 (1 << 3) +#define P2SEL_SELP2_4_GPIO (0 << 2) +#define P2SEL_SELP2_4_PERIPHERAL (1 << 2) +#define P2SEL_SELP2_3_GPIO (0 << 1) +#define P2SEL_SELP2_3_PERIPHERAL (1 << 1) +#define P2SEL_SELP2_0_GPIO (0 << 0) +#define P2SEL_SELP2_0_PERIPHERAL (1 << 0) + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +/* Timer count */ +sfr at 0xCA T3CNT; +sfr at 0xEA T4CNT; + +/* Timer control */ + +sfr at 0xCB T3CTL; +sfr at 0xEB T4CTL; + +#define TxCTL_DIV_1 (0 << 5) +#define TxCTL_DIV_2 (1 << 5) +#define TxCTL_DIV_4 (2 << 5) +#define TxCTL_DIV_8 (3 << 5) +#define TxCTL_DIV_16 (4 << 5) +#define TxCTL_DIV_32 (5 << 5) +#define TxCTL_DIV_64 (6 << 5) +#define TxCTL_DIV_128 (7 << 5) +#define TxCTL_START (1 << 4) +#define TxCTL_OVFIM (1 << 3) +#define TxCTL_CLR (1 << 2) +#define TxCTL_MODE_FREE (0 << 0) +#define TxCTL_MODE_DOWN (1 << 0) +#define TxCTL_MODE_MODULO (2 << 0) +#define TxCTL_MODE_UP_DOWN (3 << 0) + +/* Timer 4 channel 0 compare control */ + +sfr at 0xCC T3CCTL0; +sfr at 0xCE T3CCTL1; +sfr at 0xEC T4CCTL0; +sfr at 0xEE T4CCTL1; + +#define TxCCTLy_IM (1 << 6) +#define TxCCTLy_CMP_SET (0 << 3) +#define TxCCTLy_CMP_CLEAR (1 << 3) +#define TxCCTLy_CMP_TOGGLE (2 << 3) +#define TxCCTLy_CMP_SET_UP_CLEAR_DOWN (3 << 3) +#define TxCCTLy_CMP_CLEAR_UP_SET_DOWN (4 << 3) +#define TxCCTLy_CMP_SET_CLEAR_FF (5 << 3) +#define TxCCTLy_CMP_CLEAR_SET_00 (6 << 3) +#define TxCCTLy_CMP_MODE_ENABLE (1 << 2) + +/* Timer compare value */ +sfr at 0xCD T3CC0; +sfr at 0xCF T3CC1; +sfr at 0xED T4CC0; +sfr at 0xEF T4CC1; + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0, j = 0; + + n <<= 1; + while (--n != 0) + while (--j != 0) + while (--i != 0) + nop(); +} + +void +dit() { + T4CTL |= TxCTL_START; + delay(1); + T4CTL &= ~TxCTL_START; + delay(1); +} + +void +dah () { + T4CTL |= TxCTL_START; + delay(3); + T4CTL &= ~TxCTL_START; + delay(1); +} + +void +charspace () { + delay(2); +} + +void +wordspace () { + delay(8); +} + +#define _ dit(); +#define ___ dah(); +#define C charspace(); +#define W wordspace(); + +main () +{ + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + + /* Use timer 4 alternate config 2 */ + PERCFG = PERCFG_T4CFG_ALT_2; + /* Use P2_4 for timer 4 output */ + P2SEL = P2SEL_SELP2_0_PERIPHERAL; + + T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE; + T4CC0 = 125; + T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO; + + for (;;) { + ___ _ ___ _ C ___ ___ _ ___ W /* cq */ + ___ _ _ C _ W /* de */ + ___ _ ___ C ___ _ _ C /* kd */ + ___ ___ _ _ _ C _ _ _ C /* 7s */ + ___ ___ _ ___ C ___ ___ _ W /* qg */ + if (T4CC0 == 94) + T4CC0 = 125; + else + T4CC0 = 94; + } +} -- cgit v1.2.3 From 24edd56155ed0fa02fdd8f66fdc7aa5a1021bf7d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 1 Apr 2009 17:50:47 -0700 Subject: Reset cc1111 on s51 exit --- s51/s51-command.c | 1 + 1 file changed, 1 insertion(+) diff --git a/s51/s51-command.c b/s51/s51-command.c index 034d5dce..cc208abf 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -64,6 +64,7 @@ parse_uint8(char *value, uint8_t *uint8) enum command_result command_quit (int argc, char **argv) { + ccdbg_reset(s51_dbg); exit(0); return command_error; } -- cgit v1.2.3 From 2d9b8a83a2d9f495199033e43f519d26f27938fe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Apr 2009 11:31:49 -0700 Subject: Add support for a serial-connected custom debug dongle This uses the cc1111 board as a custom debug dongle with faster methods for communicating with the debug target. --- lib/Makefile.am | 4 + lib/cc-bitbang.c | 270 +++++++++++++++++++++++++++++++++++++++ lib/cc-bitbang.h | 94 ++++++++++++++ lib/cc-usb.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/cc-usb.h | 53 ++++++++ lib/ccdbg-command.c | 52 +++----- lib/ccdbg-debug.c | 9 ++ lib/ccdbg-io.c | 213 ++++++++----------------------- lib/ccdbg-manual.c | 15 ++- lib/ccdbg-memory.c | 4 + lib/ccdbg.h | 88 +++---------- lib/cp-usb.c | 1 + 12 files changed, 885 insertions(+), 273 deletions(-) create mode 100644 lib/cc-bitbang.c create mode 100644 lib/cc-bitbang.h create mode 100644 lib/cc-usb.c create mode 100644 lib/cc-usb.h diff --git a/lib/Makefile.am b/lib/Makefile.am index ba6f9725..4d9ded3a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,5 +13,9 @@ libcc_a_SOURCES = \ ccdbg-memory.c \ ccdbg-rom.c \ ccdbg-state.c \ + cc-usb.c \ + cc-usb.h \ + cc-bitbang.c \ + cc-bitbang.h \ cp-usb.c \ cp-usb-async.c diff --git a/lib/cc-bitbang.c b/lib/cc-bitbang.c new file mode 100644 index 00000000..a5d2d369 --- /dev/null +++ b/lib/cc-bitbang.c @@ -0,0 +1,270 @@ +/* + * Copyright © 2009 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 +#include +#include +#include "ccdbg-debug.h" +#include "cc-bitbang.h" + +#define CP_USB_ASYNC + +#ifdef CP_USB_ASYNC +#include "cp-usb-async.h" +#else +#include "cp-usb.h" +#endif + +struct cc_bitbang { +#ifdef CP_USB_ASYNC + struct cp_usb_async *cp_async; +#else + struct cp_usb *cp; +#endif +}; + +static uint32_t cc_clock_us = CC_CLOCK_US; +static uint32_t cc_reset_us = CC_RESET_US; + +void +cc_bitbang_set_clock(uint32_t us) +{ + cc_clock_us = us; +} + +void +cc_bitbang_half_clock(struct cc_bitbang *bb) +{ + struct timespec req, rem; + req.tv_sec = (cc_clock_us / 2) / 1000000; + req.tv_nsec = ((cc_clock_us / 2) % 1000000) * 1000; + nanosleep(&req, &rem); +} + +void +cc_bitbang_wait_reset(struct cc_bitbang *bb) +{ + struct timespec req, rem; + + cc_bitbang_sync(bb); + req.tv_sec = (cc_reset_us) / 1000000; + req.tv_nsec = ((cc_reset_us) % 1000000) * 1000; + nanosleep(&req, &rem); +} + +struct cc_bitbang * +cc_bitbang_open(void) +{ + struct cc_bitbang *bb; + + bb = calloc(sizeof (struct cc_bitbang), 1); + if (!bb) { + perror("calloc"); + return NULL; + } +#ifdef CP_USB_ASYNC + bb->cp_async = cp_usb_async_open(); + if (!bb->cp_async) { + free (bb); + return NULL; + } +#else + bb->cp = cp_usb_open (); + if (!bb->cp) { + free (bb); + return NULL; + } +#endif + return bb; +} + +void +cc_bitbang_close(struct cc_bitbang *bb) +{ +#ifdef CP_USB_ASYNC + cp_usb_async_close(bb->cp_async); +#else + cp_usb_close(bb->cp); +#endif + free (bb); +} + +void +cc_bitbang_debug_mode(struct cc_bitbang *bb) +{ + /* force two rising clocks while holding RESET_N low */ + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + cc_bitbang_wait_reset(bb); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); + cc_bitbang_wait_reset(bb); +} + +void +cc_bitbang_reset(struct cc_bitbang *bb) +{ + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n"); + ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_wait_reset(bb); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + cc_bitbang_wait_reset(bb); +} + +int +cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value) +{ +#ifdef CP_USB_ASYNC + cp_usb_async_write(bb->cp_async, mask, value); +#else + cp_usb_write(bb->cp, mask, value); +#endif + return 0; +} + +void +cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep) +{ +#ifdef CP_USB_ASYNC + cp_usb_async_read(bb->cp_async, valuep); +#else + *valuep = cp_usb_read(bb->cp); +#endif +} + +void +cc_bitbang_sync(struct cc_bitbang *bb) +{ +#ifdef CP_USB_ASYNC + cp_usb_async_sync(bb->cp_async); +#endif +} + +static char +is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) +{ + if (mask&bit) { + if (get&bit) + return on; + else + return '.'; + } else + return '-'; +} + +void +cc_bitbang_print(char *format, uint8_t mask, uint8_t set) +{ + ccdbg_debug (CC_DEBUG_BITBANG, format, + is_bit(set, mask, 'C', CC_CLOCK), + is_bit(set, mask, 'D', CC_DATA), + is_bit(set, mask, 'R', CC_RESET_N)); +} + +void +cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set) +{ + cc_bitbang_write(bb, mask, set); + cc_bitbang_print("%c %c %c\n", mask, set); + cc_bitbang_half_clock(bb); +} + +void +cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit) +{ + if (bit) bit = CC_DATA; + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N); + cc_bitbang_send(bb, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N); +} + +void +cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte) +{ + int bit; + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte); + for (bit = 7; bit >= 0; bit--) { + cc_bitbang_send_bit(bb, (byte >> bit) & 1); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + } + cc_bitbang_sync(bb); +} + +void +cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes) +{ + while (nbytes--) + cc_bitbang_send_byte(bb, *bytes++); +} + +void +cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit) +{ + uint8_t mask = first ? CC_DATA : 0; + + cc_bitbang_send(bb, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); + cc_bitbang_read(bb, bit); + cc_bitbang_send(bb, CC_CLOCK| CC_RESET_N, CC_RESET_N); +} + +void +cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep) +{ + uint8_t byte = 0; + uint8_t bits[8]; + int bit; + + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); + for (bit = 0; bit < 8; bit++) { + cc_bitbang_recv_bit(bb, first, &bits[bit]); + first = 0; + } + cc_bitbang_sync(bb); + for (bit = 0; bit < 8; bit++) { + byte = byte << 1; + byte |= (bits[bit] & CC_DATA) ? 1 : 0; + cc_bitbang_print("#\t%c %c %c\n", CC_DATA, bits[bit]); + if (bit == 3) + ccdbg_debug(CC_DEBUG_BITBANG, "\n"); + } + ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); + *bytep = byte; +} + +void +cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes) +{ + int i; + int first = 1; + for (i = 0; i < nbytes; i++) { + cc_bitbang_recv_byte(bb, first, &bytes[i]); + first = 0; + } +} + diff --git a/lib/cc-bitbang.h b/lib/cc-bitbang.h new file mode 100644 index 00000000..54b20e2c --- /dev/null +++ b/lib/cc-bitbang.h @@ -0,0 +1,94 @@ +/* + * Copyright © 2009 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 _CC_BITBANG_H_ +#define _CC_BITBANG_H_ + +#include + +#define CC_CLOCK 0x1 +#define CC_DATA 0x2 +#define CC_RESET_N 0x4 +#define CC_CLOCK_US (2) + +/* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground + * and a 2.7k resistor to the reset line. This takes about 6us + * to settle, so we'll wait longer than that after changing the reset line + */ +#define CC_RESET_US (12) + +struct cc_bitbang; + +void +cc_bitbang_set_clock(uint32_t us); + +void +cc_bitbang_half_clock(struct cc_bitbang *bb); + +void +cc_bitbang_wait_reset(struct cc_bitbang *bb); + +struct cc_bitbang * +cc_bitbang_open(void); + +void +cc_bitbang_close(struct cc_bitbang *bb); + +void +cc_bitbang_debug_mode(struct cc_bitbang *bb); + +void +cc_bitbang_reset(struct cc_bitbang *bb); + +int +cc_bitbang_write(struct cc_bitbang *bb, uint8_t mask, uint8_t value); + +void +cc_bitbang_read(struct cc_bitbang *bb, uint8_t *valuep); + +void +cc_bitbang_sync(struct cc_bitbang *bb); + +void +cc_bitbang_print(char *format, uint8_t mask, uint8_t set); + +void +cc_bitbang_print(char *format, uint8_t mask, uint8_t set); + +void +cc_bitbang_send(struct cc_bitbang *bb, uint8_t mask, uint8_t set); + +void +cc_bitbang_send_bit(struct cc_bitbang *bb, uint8_t bit); + +void +cc_bitbang_send_byte(struct cc_bitbang *bb, uint8_t byte); + +void +cc_bitbang_send_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes); + +void +cc_bitbang_recv_bit(struct cc_bitbang *bb, int first, uint8_t *bit); + +void +cc_bitbang_recv_byte(struct cc_bitbang *bb, int first, uint8_t *bytep); + +void +cc_bitbang_recv_bytes(struct cc_bitbang *bb, uint8_t *bytes, int nbytes); + +#endif /* _CC_BITBANG_H_ */ diff --git a/lib/cc-usb.c b/lib/cc-usb.c new file mode 100644 index 00000000..a85765af --- /dev/null +++ b/lib/cc-usb.c @@ -0,0 +1,355 @@ +/* + * Copyright © 2009 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ccdbg-debug.h" +#include "cc-usb.h" + + +#define CC_NUM_READ 16 +#define CC_BUF 1024 +#define DEFAULT_TTY "/dev/ttyACM0" + +struct cc_read { + uint8_t *buf; + int len; +}; + +struct cc_usb { + int fd; + uint8_t in_buf[CC_BUF]; + int in_count; + uint8_t out_buf[CC_BUF]; + int out_count; + struct cc_read read_buf[CC_NUM_READ]; + int read_count; +}; + +#define NOT_HEX 0xff + +static uint8_t +cc_hex_nibble(uint8_t c) +{ + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + return NOT_HEX; +} + +/* + * Take raw input bytes, parse them as hex + * and write them to the waiting buffer + */ +static void +cc_handle_in(struct cc_usb *cc) +{ + uint8_t h, l; + int in_pos; + int read_pos; + + in_pos = 0; + read_pos = 0; + while (read_pos < cc->read_count && in_pos < cc->in_count) { + /* + * Skip to next hex character + */ + while (in_pos < cc->in_count && + cc_hex_nibble(cc->in_buf[in_pos]) == NOT_HEX) + in_pos++; + /* + * Make sure we have two characters left + */ + if (cc->in_count - in_pos < 2) + break; + /* + * Parse hex number + */ + h = cc_hex_nibble(cc->in_buf[in_pos]); + l = cc_hex_nibble(cc->in_buf[in_pos+1]); + if (h == NOT_HEX || l == NOT_HEX) { + fprintf(stderr, "hex read error\n"); + break; + } + in_pos += 2; + /* + * Store hex number + */ + *cc->read_buf[read_pos].buf++ = (h << 4) | l; + if (--cc->read_buf[read_pos].len <= 0) + read_pos++; + } + + /* Move remaining bytes to the start of the input buffer */ + if (in_pos) { + memmove(cc->in_buf, cc->in_buf + in_pos, + cc->in_count - in_pos); + cc->in_count -= in_pos; + } + + /* Move pending reads to the start of the array */ + if (read_pos) { + memmove(cc->read_buf, cc->read_buf + read_pos, + (cc->read_count - read_pos) * sizeof (cc->read_buf[0])); + cc->read_count -= read_pos; + } + + /* Once we're done reading, flush any pending input */ + if (cc->read_count == 0) + cc->in_count = 0; +} + +static void +cc_usb_dbg(int indent, uint8_t *bytes, int len) +{ + int eol = 1; + int i; + uint8_t c; + while (len--) { + c = *bytes++; + if (eol) { + for (i = 0; i < indent; i++) + ccdbg_debug(CC_DEBUG_BITBANG, " "); + eol = 0; + } + switch (c) { + case '\r': + ccdbg_debug(CC_DEBUG_BITBANG, "^M"); + break; + case '\n': + eol = 1; + default: + ccdbg_debug(CC_DEBUG_BITBANG, "%c", c); + } + } +} + +/* + * Flush pending writes, fill pending reads + */ +void +cc_usb_sync(struct cc_usb *cc) +{ + int ret; + struct pollfd fds; + int timeout; + + fds.fd = cc->fd; + for (;;) { + if (cc->read_count || cc->out_count) + timeout = -1; + else + timeout = 0; + fds.events = 0; + if (cc->in_count < CC_BUF) + fds.events |= POLLIN; + if (cc->out_count) + fds.events |= POLLOUT; + ret = poll(&fds, 1, timeout); + if (ret == 0) + break; + if (ret < 0) { + perror("poll"); + break; + } + if (fds.revents & POLLIN) { + ret = read(cc->fd, cc->in_buf + cc->in_count, + CC_BUF - cc->in_count); + if (ret > 0) { + cc_usb_dbg(24, cc->in_buf + cc->in_count, ret); + cc->in_count += ret; + cc_handle_in(cc); + } + } + if (fds.revents & POLLOUT) { + ret = write(cc->fd, cc->out_buf, + cc->out_count); + if (ret > 0) { + cc_usb_dbg(0, cc->out_buf, ret); + memmove(cc->out_buf, + cc->out_buf + ret, + cc->out_count - ret); + cc->out_count -= ret; + } + } + } +} + +static void +cc_usb_printf(struct cc_usb *cc, char *format, ...) +{ + char buf[1024], *b; + va_list ap; + int ret, this_time; + + /* sprintf to a local buffer */ + va_start(ap, format); + ret = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + if (ret > sizeof(buf)) { + fprintf(stderr, "printf overflow for format %s\n", + format); + } + + /* flush local buffer to the wire */ + b = buf; + while (ret > 0) { + this_time = ret; + if (this_time > CC_BUF - cc->out_count) + this_time = CC_BUF - cc->out_count; + memcpy(cc->out_buf + cc->out_count, b, this_time); + cc->out_count += this_time; + ret -= this_time; + while (cc->out_count >= CC_BUF) + cc_usb_sync(cc); + } +} + +int +cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len) +{ + int this_len; + int ret = len; + + while (len) { + this_len = len; + if (this_len > 8) + this_len = 8; + len -= this_len; + cc_usb_printf(cc, "P"); + while (this_len--) + cc_usb_printf (cc, " %02x", (*bytes++) & 0xff); + cc_usb_printf(cc, "\n"); + } + return ret; +} + +static void +cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len) +{ + struct cc_read *read_buf; + while (cc->read_count >= CC_NUM_READ) + cc_usb_sync(cc); + read_buf = &cc->read_buf[cc->read_count++]; + read_buf->buf = buf; + read_buf->len = len; +} + +int +cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *buf, int len) +{ + cc_queue_read(cc, buf, len); + cc_usb_printf(cc, "G %x\n", len); + return len; +} + +int +cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len) +{ + cc_usb_printf(cc, "O %x %x\n", len, addr); + while (len--) + cc_usb_printf(cc, "%02x", *bytes++); + return 0; +} + +int +cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len) +{ + int i; + cc_queue_read(cc, bytes, len); + cc_usb_printf(cc, "I %x %x\n", len, addr); + cc_usb_sync(cc); + for (i = 0; i < len; i++) { + if ((i & 15) == 0) { + if (i) + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); + ccdbg_debug(CC_DEBUG_MEMORY, "\t%04x", addr + i); + } + ccdbg_debug(CC_DEBUG_MEMORY, " %02x", bytes[i]); + } + ccdbg_debug(CC_DEBUG_MEMORY, "\n"); + return 0; +} + +int +cc_usb_debug_mode(struct cc_usb *cc) +{ + cc_usb_sync(cc); + cc_usb_printf(cc, "D\n"); + return 1; +} + +int +cc_usb_reset(struct cc_usb *cc) +{ + cc_usb_sync(cc); + cc_usb_printf(cc, "R\n"); + return 1; +} + +static struct termios save_termios; + +struct cc_usb * +cc_usb_open(void) +{ + struct cc_usb *cc; + char *tty; + struct termios termios; + + tty = getenv("CCDBG_TTY"); + if (!tty) + tty = DEFAULT_TTY; + cc = calloc (sizeof (struct cc_usb), 1); + if (!cc) + return NULL; + cc->fd = open(tty, O_RDWR | O_NONBLOCK); + if (cc->fd < 0) { + perror(tty); + free (cc); + return NULL; + } + tcgetattr(cc->fd, &termios); + save_termios = termios; + cfmakeraw(&termios); + tcsetattr(cc->fd, TCSAFLUSH, &termios); + cc_usb_printf(cc, "E 0\n"); + cc_usb_sync(cc); + sleep(1); + cc_usb_sync(cc); + return cc; +} + +void +cc_usb_close(struct cc_usb *cc) +{ + tcsetattr(cc->fd, TCSAFLUSH, &save_termios); + close (cc->fd); + free (cc); +} + diff --git a/lib/cc-usb.h b/lib/cc-usb.h new file mode 100644 index 00000000..235e9918 --- /dev/null +++ b/lib/cc-usb.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2009 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 _CC_USB_H_ +#define _CC_USB_H_ + +#include + +struct cc_usb; + +struct cc_usb * +cc_usb_open(void); + +void +cc_usb_close(struct cc_usb *cc); + +int +cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len); + +int +cc_usb_recv_bytes(struct cc_usb *cc, uint8_t *bytes, int len); + +int +cc_usb_write_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len); + +int +cc_usb_read_memory(struct cc_usb *cc, uint16_t addr, uint8_t *bytes, int len); + +int +cc_usb_debug_mode(struct cc_usb *cc); + +int +cc_usb_reset(struct cc_usb *cc); + +void +cc_usb_sync(struct cc_usb *cc); + +#endif /* _CC_USB_H_ */ diff --git a/lib/ccdbg-command.c b/lib/ccdbg-command.c index 74313bdf..7d1ae067 100644 --- a/lib/ccdbg-command.c +++ b/lib/ccdbg-command.c @@ -18,39 +18,6 @@ #include "ccdbg.h" -void -ccdbg_debug_mode(struct ccdbg *dbg) -{ - /* force two rising clocks while holding RESET_N low */ - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "# Debug mode\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); - ccdbg_wait_reset(dbg); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_DATA|CC_RESET_N); - ccdbg_wait_reset(dbg); -} - -void -ccdbg_reset(struct ccdbg *dbg) -{ - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "# Reset\n"); - ccdbg_debug(CC_DEBUG_COMMAND, "#\n"); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_wait_reset(dbg); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA ); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_wait_reset(dbg); -} - uint8_t ccdbg_chip_erase(struct ccdbg *dbg) { @@ -117,6 +84,22 @@ ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes) return ccdbg_cmd_write_read8(dbg, CC_DEBUG_INSTR(nbytes), instr, nbytes); } +void +ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes) +{ + static uint8_t discard; + ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes), + instr, nbytes, &discard); +} + +void +ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes, + uint8_t *reply) +{ + return ccdbg_cmd_write_queue8(dbg, CC_DEBUG_INSTR(nbytes), + instr, nbytes, reply); +} + uint8_t ccdbg_step_instr(struct ccdbg *dbg) { @@ -148,12 +131,13 @@ ccdbg_execute(struct ccdbg *dbg, uint8_t *inst) 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); + ccdbg_debug_instr_queue(dbg, inst+1, len, &status); for (; i < 3; i++) ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " "); ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " -> %02x\n", status); inst += len + 1; } + ccdbg_sync(dbg); return status; } diff --git a/lib/ccdbg-debug.c b/lib/ccdbg-debug.c index 847361c7..6eb4e0c5 100644 --- a/lib/ccdbg-debug.c +++ b/lib/ccdbg-debug.c @@ -34,11 +34,20 @@ ccdbg_clear_debug(int level) ccdbg_level &= ~level; } +static int initialized; + void ccdbg_debug(int level, char *format, ...) { va_list ap; + if (!initialized) { + char *level; + initialized = 1; + level = getenv("CCDEBUG"); + if (level) + ccdbg_level |= strtoul(level, NULL, 0); + } if (ccdbg_level & level) { va_start(ap, format); vprintf(format, ap); diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index 3606c57c..acd44f10 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -18,41 +18,10 @@ #include "ccdbg.h" #include -#ifdef CP_USB_ASYNC -#include "cp-usb-async.h" -#else -#include "cp-usb.h" -#endif +#include "cc-usb.h" +#include "cc-bitbang.h" -static uint32_t cc_clock_us = CC_CLOCK_US; -static uint32_t cc_reset_us = CC_RESET_US; -void -ccdbg_set_clock(uint32_t us) -{ - cc_clock_us = us; -} - -void -ccdbg_half_clock(struct ccdbg *dbg) -{ - struct timespec req, rem; - req.tv_sec = (cc_clock_us / 2) / 1000000; - req.tv_nsec = ((cc_clock_us / 2) % 1000000) * 1000; - nanosleep(&req, &rem); -} - -void -ccdbg_wait_reset(struct ccdbg *dbg) -{ - struct timespec req, rem; - - ccdbg_sync_io(dbg); - req.tv_sec = (cc_reset_us) / 1000000; - req.tv_nsec = ((cc_reset_us) % 1000000) * 1000; - nanosleep(&req, &rem); -} - struct ccdbg * ccdbg_open(void) { @@ -63,170 +32,77 @@ ccdbg_open(void) perror("calloc"); return NULL; } -#ifdef CP_USB_ASYNC - dbg->cp_async = cp_usb_async_open(); - if (!dbg->cp_async) { - free (dbg); - return NULL; - } -#else - dbg->cp = cp_usb_open (); - if (!dbg->cp) { - free (dbg); - return NULL; + dbg->usb = cc_usb_open(); + if (!dbg->usb) { + dbg->bb = cc_bitbang_open(); + if (!dbg->bb) { + free(dbg); + return NULL; + } } -#endif return dbg; } void ccdbg_close(struct ccdbg *dbg) { -#ifdef CP_USB_ASYNC - cp_usb_async_close(dbg->cp_async); -#else - cp_usb_close(dbg->cp); -#endif + if (dbg->usb) + cc_usb_close(dbg->usb); + if (dbg->bb) + cc_bitbang_close(dbg->bb); free (dbg); } -int -ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value) -{ -#ifdef CP_USB_ASYNC - cp_usb_async_write(dbg->cp_async, mask, value); -#else - cp_usb_write(dbg->cp, mask, value); -#endif - return 0; -} - -void -ccdbg_read(struct ccdbg *dbg, uint8_t *valuep) -{ -#ifdef CP_USB_ASYNC - cp_usb_async_read(dbg->cp_async, valuep); -#else - *valuep = cp_usb_read(dbg->cp); -#endif -} - -void -ccdbg_sync_io(struct ccdbg *dbg) -{ -#ifdef CP_USB_ASYNC - cp_usb_async_sync(dbg->cp_async); -#endif -} - -static char -is_bit(uint8_t get, uint8_t mask, char on, uint8_t bit) -{ - if (mask&bit) { - if (get&bit) - return on; - else - return '.'; - } else - return '-'; -} -void -ccdbg_print(char *format, uint8_t mask, uint8_t set) -{ - ccdbg_debug (CC_DEBUG_BITBANG, format, - is_bit(set, mask, 'C', CC_CLOCK), - is_bit(set, mask, 'D', CC_DATA), - is_bit(set, mask, 'R', CC_RESET_N)); -} - void -ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set) +ccdbg_debug_mode(struct ccdbg *dbg) { - ccdbg_write(dbg, mask, set); - ccdbg_print("%c %c %c\n", mask, set); - ccdbg_half_clock(dbg); + if (dbg->usb) + cc_usb_debug_mode(dbg->usb); + else if (dbg->bb) + cc_bitbang_debug_mode(dbg->bb); } void -ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit) +ccdbg_reset(struct ccdbg *dbg) { - if (bit) bit = CC_DATA; - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, CC_CLOCK|bit|CC_RESET_N); - ccdbg_send(dbg, CC_CLOCK|CC_DATA|CC_RESET_N, bit|CC_RESET_N); -} - -void -ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte) -{ - int bit; - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Send Byte 0x%02x\n#\n", byte); - for (bit = 7; bit >= 0; bit--) { - ccdbg_send_bit(dbg, (byte >> bit) & 1); - if (bit == 3) - ccdbg_debug(CC_DEBUG_BITBANG, "\n"); - } - ccdbg_sync_io(dbg); + if (dbg->usb) + cc_usb_reset(dbg->usb); + else if (dbg->bb) + cc_bitbang_reset(dbg->bb); } void ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) { - while (nbytes--) - ccdbg_send_byte(dbg, *bytes++); -} - -void -ccdbg_recv_bit(struct ccdbg *dbg, int first, uint8_t *bit) -{ - uint8_t mask = first ? CC_DATA : 0; - - ccdbg_send(dbg, CC_CLOCK|mask|CC_RESET_N, CC_CLOCK|CC_DATA|CC_RESET_N); - ccdbg_read(dbg, bit); - ccdbg_send(dbg, CC_CLOCK| CC_RESET_N, CC_RESET_N); + if (dbg->usb) + cc_usb_send_bytes(dbg->usb, bytes, nbytes); + else if (dbg->bb) + cc_bitbang_send_bytes(dbg->bb, bytes, nbytes); } void -ccdbg_recv_byte(struct ccdbg *dbg, int first, uint8_t *bytep) +ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) { - uint8_t byte = 0; - uint8_t bits[8]; - int bit; - - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv byte\n#\n"); - for (bit = 0; bit < 8; bit++) { - ccdbg_recv_bit(dbg, first, &bits[bit]); - first = 0; - } - ccdbg_sync_io(dbg); - for (bit = 0; bit < 8; bit++) { - byte = byte << 1; - byte |= (bits[bit] & CC_DATA) ? 1 : 0; - ccdbg_print("#\t%c %c %c\n", CC_DATA, bits[bit]); - if (bit == 3) - ccdbg_debug(CC_DEBUG_BITBANG, "\n"); - } - ccdbg_debug(CC_DEBUG_BITBANG, "#\n# Recv 0x%02x\n#\n", byte); - *bytep = byte; + if (dbg->usb) + cc_usb_recv_bytes(dbg->usb, bytes, nbytes); + else if (dbg->bb) + cc_bitbang_recv_bytes(dbg->bb, bytes, nbytes); } void -ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) +ccdbg_sync(struct ccdbg *dbg) { - int i; - int first = 1; - for (i = 0; i < nbytes; i++) { - ccdbg_recv_byte(dbg, first, &bytes[i]); - first = 0; - } + if (dbg->usb) + cc_usb_sync(dbg->usb); + else if (dbg->bb) + cc_bitbang_sync(dbg->bb); } void ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) { - int i; - ccdbg_send_byte(dbg, cmd); - for (i = 0; i < len; i++) - ccdbg_send_byte(dbg, data[i]); + ccdbg_send_bytes(dbg, &cmd, 1); + ccdbg_send_bytes(dbg, data, len); } uint8_t @@ -235,6 +111,7 @@ ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) uint8_t byte[1]; ccdbg_cmd_write(dbg, cmd, data, len); ccdbg_recv_bytes(dbg, byte, 1); + ccdbg_sync(dbg); return byte[0]; } @@ -244,5 +121,15 @@ ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len) uint8_t byte[2]; ccdbg_cmd_write(dbg, cmd, data, len); ccdbg_recv_bytes(dbg, byte, 2); + ccdbg_sync(dbg); return (byte[0] << 8) | byte[1]; } + +void +ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd, + uint8_t *data, int len, + uint8_t *reply) +{ + ccdbg_cmd_write(dbg, cmd, data, len); + ccdbg_recv_bytes(dbg, reply, 1); +} diff --git a/lib/ccdbg-manual.c b/lib/ccdbg-manual.c index df79d88d..0e811b76 100644 --- a/lib/ccdbg-manual.c +++ b/lib/ccdbg-manual.c @@ -17,6 +17,7 @@ */ #include "ccdbg.h" +#include "cc-bitbang.h" /* * Manual bit-banging to debug the low level protocol @@ -47,6 +48,10 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) char line[80]; uint8_t set, mask; + if (dbg->bb == NULL) { + fprintf(stderr, "Must use bitbang API for manual mode\n"); + return; + } while (fgets(line, sizeof line, input)) { if (line[0] == '#' || line[0] == '\n') { printf ("%s", line); @@ -59,14 +64,14 @@ ccdbg_manual(struct ccdbg *dbg, FILE *input) get_bit(line, 4, 'R', CC_RESET_N, &set, &mask); if (mask != (CC_CLOCK|CC_DATA|CC_RESET_N)) { uint8_t read; - ccdbg_read(dbg, &read); - ccdbg_sync_io(dbg); - ccdbg_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); + cc_bitbang_read(dbg->bb, &read); + cc_bitbang_sync(dbg->bb); + cc_bitbang_print("\t%c %c %c", CC_CLOCK|CC_DATA|CC_RESET_N, read); if ((set & CC_CLOCK) == 0) printf ("\t%d", (read&CC_DATA) ? 1 : 0); printf ("\n"); } - ccdbg_send(dbg, mask, set); - ccdbg_sync_io(dbg); + cc_bitbang_send(dbg->bb, mask, set); + cc_bitbang_sync(dbg->bb); } } diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c index 20a24799..878c5f97 100644 --- a/lib/ccdbg-memory.c +++ b/lib/ccdbg-memory.c @@ -50,6 +50,8 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) int i, nl = 0; struct ccstate state; + if (dbg->usb) + return cc_usb_write_memory(dbg->usb, addr, bytes, nbytes); ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP); memory_init[HIGH_START] = addr >> 8; memory_init[LOW_START] = addr; @@ -83,6 +85,8 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) ccdbg_rom_replace_xmem(dbg, addr, bytes, nbytes); return 0; } + if (dbg->usb) + return cc_usb_read_memory(dbg->usb, addr, bytes, nbytes); ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP); memory_init[HIGH_START] = addr >> 8; memory_init[LOW_START] = addr; diff --git a/lib/ccdbg.h b/lib/ccdbg.h index e0e12c8b..fe0ea3a0 100644 --- a/lib/ccdbg.h +++ b/lib/ccdbg.h @@ -31,17 +31,8 @@ #include #include #include "ccdbg-debug.h" - -#define CC_CLOCK 0x1 -#define CC_DATA 0x2 -#define CC_RESET_N 0x4 -#define CC_CLOCK_US (2) - -/* Telemetrum has a 10k pull-up to 3.3v, a 0.001uF cap to ground - * and a 2.7k resistor to the reset line. This takes about 6us - * to settle, so we'll wait longer than that after changing the reset line - */ -#define CC_RESET_US (12) +#include "cc-bitbang.h" +#include "cc-usb.h" /* 8051 instructions */ @@ -109,15 +100,10 @@ /* Bit-addressable status word */ #define PSW(bit) (0xD0 | (bit)) -#define CP_USB_ASYNC - struct ccdbg { -#ifdef CP_USB_ASYNC - struct cp_usb_async *cp_async; -#else - struct cp_usb *cp; -#endif - struct hex_image *rom; + struct cc_bitbang *bb; + struct cc_usb *usb; + struct hex_image *rom; }; /* Intel hex file format data @@ -225,6 +211,13 @@ ccdbg_resume(struct ccdbg *dbg); uint8_t ccdbg_debug_instr(struct ccdbg *dbg, uint8_t *instr, int nbytes); +void +ccdbg_debug_instr_discard(struct ccdbg *dbg, uint8_t *instr, int nbytes); + +void +ccdbg_debug_instr_queue(struct ccdbg *dbg, uint8_t *instr, int nbytes, + uint8_t *reply); + uint8_t ccdbg_step_instr(struct ccdbg *dbg); @@ -264,80 +257,33 @@ int ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); /* ccdbg-io.c */ -void -ccdbg_set_clock(uint32_t us); - -void -ccdbg_half_clock(struct ccdbg *dbg); - -void -ccdbg_wait_reset(struct ccdbg *dbg); - -int -ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value); - -void -ccdbg_read(struct ccdbg *dbg, uint8_t *valuep); - struct ccdbg * ccdbg_open(void); void ccdbg_close(struct ccdbg *dbg); -void -ccdbg_clock_1_0(struct ccdbg *dbg); - -void -ccdbg_clock_0_1(struct ccdbg *dbg); - -void -ccdbg_write_bit(struct ccdbg *dbg, uint8_t bit); - -void -ccdbg_write_byte(struct ccdbg *dbg, uint8_t byte); - -uint8_t -ccdbg_read_bit(struct ccdbg *dbg); - -uint8_t -ccdbg_read_byte(struct ccdbg *dbg); - void 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); -uint16_t -ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); - void -ccdbg_send(struct ccdbg *dbg, uint8_t mask, uint8_t set); +ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd, + uint8_t *data, int len, uint8_t *reply); -void -ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit); - -void -ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte); +uint16_t +ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len); void ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); -void -ccdbg_recv_bit(struct ccdbg *dbg, int first, uint8_t *bit); - -void -ccdbg_recv_byte(struct ccdbg *dbg, int first, uint8_t *byte); - void ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); void -ccdbg_sync_io(struct ccdbg *dbg); - -void -ccdbg_print(char *format, uint8_t mask, uint8_t set); +ccdbg_sync(struct ccdbg *dbg); /* ccdbg-manual.c */ diff --git a/lib/cp-usb.c b/lib/cp-usb.c index 6ab9092c..d227b78c 100644 --- a/lib/cp-usb.c +++ b/lib/cp-usb.c @@ -25,6 +25,7 @@ #include "cp-usb.h" #include #include +#include struct cp_usb { usb_dev_handle *usb_dev; -- cgit v1.2.3 From ee110425fb814780476d1d3d8a257af126f41763 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Apr 2009 17:09:23 -0700 Subject: Bump buffer pointer as data is written to cc-usb --- lib/cc-usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cc-usb.c b/lib/cc-usb.c index a85765af..5da36fe9 100644 --- a/lib/cc-usb.c +++ b/lib/cc-usb.c @@ -226,6 +226,7 @@ cc_usb_printf(struct cc_usb *cc, char *format, ...) memcpy(cc->out_buf + cc->out_count, b, this_time); cc->out_count += this_time; ret -= this_time; + b += this_time; while (cc->out_count >= CC_BUF) cc_usb_sync(cc); } -- cgit v1.2.3 From 5221dc63cf3a059a32aca2bfa7828c215be814a1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 12 Apr 2009 12:38:58 -0700 Subject: Add ccdump --- INSTALL | 106 ++++++++++++++++++++++++++++------------------------- Makefile.am | 2 +- ccdump/Makefile.am | 10 +++++ ccdump/ccdump.c | 52 ++++++++++++++++++++++++++ configure.ac | 1 + lib/cc-usb.c | 4 +- lib/cc-usb.h | 6 +++ 7 files changed, 129 insertions(+), 52 deletions(-) create mode 100644 ccdump/Makefile.am create mode 100644 ccdump/ccdump.c diff --git a/INSTALL b/INSTALL index 54caf7c1..d3c5b40a 100644 --- a/INSTALL +++ b/INSTALL @@ -1,13 +1,19 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. +Installation Instructions +************************* - This file is free documentation; the Free Software Foundation gives +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== - These are generic installation instructions. +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -20,9 +26,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -32,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. @@ -64,54 +67,55 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. + 6. Often, you can also type `make uninstall' to remove the installed + files again. + Compilers and Options ===================== - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== - You can compile the package for more than one kind of computer at the +You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. Installation Names ================== - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular +options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. @@ -122,7 +126,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= - Some packages pay attention to `--enable-FEATURE' options to +Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The @@ -137,11 +141,11 @@ you can use the `configure' options `--x-includes=DIR' and Specifying the System Type ========================== - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: @@ -156,7 +160,7 @@ where SYSTEM can have one of these forms: need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will +use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a @@ -167,9 +171,9 @@ eventually be run) with `--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. @@ -178,7 +182,7 @@ A warning: not all `configure' scripts look for a site script. Defining Variables ================== - Variables not defined in a site shell script can be set in the +Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set @@ -186,14 +190,18 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -will cause the specified gcc to be used as the C compiler (unless it is +causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + `configure' Invocation ====================== - `configure' recognizes the following options to control how it -operates. +`configure' recognizes the following options to control how it operates. `--help' `-h' diff --git a/Makefile.am b/Makefile.am index 5341ab33..ee3d2924 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ccload s51 ccmanual +SUBDIRS=lib ccload s51 ccmanual ccdump diff --git a/ccdump/Makefile.am b/ccdump/Makefile.am new file mode 100644 index 00000000..976383f7 --- /dev/null +++ b/ccdump/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS=ccdump + +AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) +CCLOAD_LIBS=../lib/libcc.a + +ccdump_DEPENDENCIES = $(CCLOAD_LIBS) + +ccdump_LDADD=$(CCLOAD_LIBS) $(LIBUSB_LIBS) + +ccdump_SOURCES = ccdump.c diff --git a/ccdump/ccdump.c b/ccdump/ccdump.c new file mode 100644 index 00000000..5a5ce11c --- /dev/null +++ b/ccdump/ccdump.c @@ -0,0 +1,52 @@ +/* + * Copyright © 2009 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 +#include +#include "cc-usb.h" + +#define NUM_BLOCK 512 + +int +main (int argc, char **argv) +{ + struct cc_usb *cc; + int block; + uint8_t bytes[32 * (2 + 8)]; + uint8_t *b; + int i, j; + uint32_t addr; + + cc = cc_usb_open(); + for (block = 0; block < NUM_BLOCK; block++) { + cc_queue_read(cc, bytes, sizeof (bytes)); + cc_usb_printf(cc, "e %x\n", block); + cc_usb_sync(cc); + for (i = 0; i < 32; i++) { + b = bytes + (i * 10); + addr = block * 256 + i * 8; + printf ("%06x", addr); + for (j = 0; j < 8; j++) { + printf (" %02x", b[j+2]); + } + printf ("\n"); + } + } + cc_usb_close(cc); + exit (0); +} diff --git a/configure.ac b/configure.ac index 516657ea..1d4720a6 100644 --- a/configure.ac +++ b/configure.ac @@ -98,4 +98,5 @@ lib/Makefile ccload/Makefile s51/Makefile ccmanual/Makefile +ccdump/Makefile ]) diff --git a/lib/cc-usb.c b/lib/cc-usb.c index 5da36fe9..09b06bb5 100644 --- a/lib/cc-usb.c +++ b/lib/cc-usb.c @@ -201,7 +201,7 @@ cc_usb_sync(struct cc_usb *cc) } } -static void +void cc_usb_printf(struct cc_usb *cc, char *format, ...) { char buf[1024], *b; @@ -251,7 +251,7 @@ cc_usb_send_bytes(struct cc_usb *cc, uint8_t *bytes, int len) return ret; } -static void +void cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len) { struct cc_read *read_buf; diff --git a/lib/cc-usb.h b/lib/cc-usb.h index 235e9918..2adccb93 100644 --- a/lib/cc-usb.h +++ b/lib/cc-usb.h @@ -50,4 +50,10 @@ cc_usb_reset(struct cc_usb *cc); void cc_usb_sync(struct cc_usb *cc); +void +cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len); + +void +cc_usb_printf(struct cc_usb *cc, char *format, ...); + #endif /* _CC_USB_H_ */ -- cgit v1.2.3 From 11c526bdcbf4012e18fbfdc29ca8832870ca38f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 12 Apr 2009 21:47:32 -0700 Subject: Add load command to s51 --- s51/s51-command.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/s51/s51-command.c b/s51/s51-command.c index cc208abf..02ecdddd 100644 --- a/s51/s51-command.c +++ b/s51/s51-command.c @@ -493,7 +493,38 @@ command_step (int argc, char **argv) enum command_result command_load (int argc, char **argv) { - return command_error; + char *filename = argv[1]; + FILE *file; + struct hex_file *hex; + struct hex_image *image; + + if (!filename) + return command_error; + file = fopen(filename, "r"); + if (!file) { + perror(filename); + return command_error; + } + hex = ccdbg_hex_file_read(file, filename); + fclose(file); + if (!hex) { + return command_error; + } + image = ccdbg_hex_image_create(hex); + ccdbg_hex_file_free(hex); + if (!image) { + fprintf(stderr, "image create failed\n"); + return command_error; + } + if (image->address >= 0xf000) { + printf("Loading %d bytes to RAM at 0x%04x\n", + image->length, image->address); + ccdbg_write_hex_image(s51_dbg, image, 0); + } else { + fprintf(stderr, "Can only load to RAM\n"); + } + ccdbg_hex_image_free(image); + return command_success; } enum command_result -- cgit v1.2.3 From 543bedde83cbce5145668e72965e02d892187b59 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Apr 2009 20:38:14 -0700 Subject: Send data --- target/radio/radio.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/target/radio/radio.c b/target/radio/radio.c index 90bc47f3..bf893699 100644 --- a/target/radio/radio.c +++ b/target/radio/radio.c @@ -419,7 +419,7 @@ low() { #define DRATE_E 10 #define DRATE_M 163 -#define PACKET_LEN 128 +#define PACKET_LEN 255 /* This are from the table for 433MHz */ @@ -528,19 +528,17 @@ main () /* Set P2_0 to output */ radio_init (); delay(100); - RFST = RFST_SIDLE; - delay(100); - RFST = RFST_STX; - delay(100); - for (;;); -#if 0 + for (;;) { uint8_t i; - for (i = 0; i < PACKET_LEN; i++) { + RFST = RFST_SIDLE; + delay(100); + RFST = RFST_STX; + for (i = 0; i < PACKET_LEN - 1; i++) { while (!RFTXRXIF); RFTXRXIF = 0; RFD = 0x55; } + delay(100); } -#endif } -- cgit v1.2.3 From 26095fc0511ee0d5213f038986032f7c59964cf0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:10:47 -0700 Subject: Run-time selection between cp2103 and cc1111 --- lib/cc-usb.c | 4 +--- lib/cc-usb.h | 2 +- lib/ccdbg-io.c | 6 ++++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/cc-usb.c b/lib/cc-usb.c index 09b06bb5..9df2e312 100644 --- a/lib/cc-usb.c +++ b/lib/cc-usb.c @@ -317,13 +317,11 @@ cc_usb_reset(struct cc_usb *cc) static struct termios save_termios; struct cc_usb * -cc_usb_open(void) +cc_usb_open(char *tty) { struct cc_usb *cc; - char *tty; struct termios termios; - tty = getenv("CCDBG_TTY"); if (!tty) tty = DEFAULT_TTY; cc = calloc (sizeof (struct cc_usb), 1); diff --git a/lib/cc-usb.h b/lib/cc-usb.h index 2adccb93..d7acfbd2 100644 --- a/lib/cc-usb.h +++ b/lib/cc-usb.h @@ -24,7 +24,7 @@ struct cc_usb; struct cc_usb * -cc_usb_open(void); +cc_usb_open(char *tty); void cc_usb_close(struct cc_usb *cc); diff --git a/lib/ccdbg-io.c b/lib/ccdbg-io.c index acd44f10..9c6693cd 100644 --- a/lib/ccdbg-io.c +++ b/lib/ccdbg-io.c @@ -21,18 +21,20 @@ #include "cc-usb.h" #include "cc-bitbang.h" - struct ccdbg * ccdbg_open(void) { struct ccdbg *dbg; + char *tty; dbg = calloc(sizeof (struct ccdbg), 1); if (!dbg) { perror("calloc"); return NULL; } - dbg->usb = cc_usb_open(); + tty = getenv("CCDBG_TTY"); + if (!tty || tty[0] == '/') + dbg->usb = cc_usb_open(tty); if (!dbg->usb) { dbg->bb = cc_bitbang_open(); if (!dbg->bb) { -- cgit v1.2.3 From fafe55c3405964e0defdf25b6c00236f9aaefbc5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:11:11 -0700 Subject: Get env var for debug method selection --- ccdump/ccdump.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ccdump/ccdump.c b/ccdump/ccdump.c index 5a5ce11c..399732d9 100644 --- a/ccdump/ccdump.c +++ b/ccdump/ccdump.c @@ -31,8 +31,10 @@ main (int argc, char **argv) uint8_t *b; int i, j; uint32_t addr; + char *tty; - cc = cc_usb_open(); + tty = getenv("CCDBG_TTY"); + cc = cc_usb_open(tty); for (block = 0; block < NUM_BLOCK; block++) { cc_queue_read(cc, bytes, sizeof (bytes)); cc_usb_printf(cc, "e %x\n", block); -- cgit v1.2.3 From 04bc51c170c6f22bb5cc16867ce9a307818a7a00 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:11:31 -0700 Subject: Add separate xmit/recv programs to radio demo --- target/radio/Makefile | 18 +- target/radio/init.c | 205 +++++++++++++++++++ target/radio/radio.c | 544 -------------------------------------------------- target/radio/radio.h | 428 +++++++++++++++++++++++++++++++++++++++ target/radio/recv.c | 66 ++++++ target/radio/xmit.c | 47 +++++ 6 files changed, 758 insertions(+), 550 deletions(-) create mode 100644 target/radio/init.c delete mode 100644 target/radio/radio.c create mode 100644 target/radio/radio.h create mode 100644 target/radio/recv.c create mode 100644 target/radio/xmit.c diff --git a/target/radio/Makefile b/target/radio/Makefile index a26fa458..97706fef 100644 --- a/target/radio/Makefile +++ b/target/radio/Makefile @@ -12,7 +12,7 @@ LDFLAGS_RAM=$(LDFLAGS) --code-loc 0xf000 --xram-loc 0xf400 --xram-size 1024 LDFLAGS_FLASH=$(LDFLAGS) --code-loc 0x0000 --xram-loc 0xf000 --xram-size 1024 -SRC=radio.c +SRC=xmit.c recv.c init.c ADB=$(SRC:.c=.adb) ASM=$(SRC:.c=.asm) LNK=$(SRC:.c=.lnk) @@ -21,7 +21,7 @@ REL=$(SRC:.c=.rel) RST=$(SRC:.c=.rst) SYM=$(SRC:.c=.sym) -PROGS=radio-flash.ihx radio-ram.ihx +PROGS=xmit-flash.ihx xmit-ram.ihx recv-flash.ihx recv-ram.ihx PCDB=$(PROGS:.ihx=.cdb) PLNK=$(PROGS:.ihx=.lnk) PMAP=$(PROGS:.ihx=.map) @@ -33,11 +33,17 @@ PAOM=$(PROGS:.ihx=) all: $(PROGS) -radio-ram.ihx: $(REL) Makefile - $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o radio-ram.ihx $(REL) - $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o radio-flash.ihx $(REL) +xmit-ram.ihx: xmit.rel init.rel Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o xmit-ram.ihx xmit.rel init.rel + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o xmit-flash.ihx xmit.rel init.rel -radio-flash.ihx: radio-ram.ihx +xmit-flash.ihx: xmit-ram.ihx + +recv-ram.ihx: recv.rel init.rel Makefile + $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o recv-ram.ihx recv.rel init.rel + $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o recv-flash.ihx recv.rel init.rel + +recv-flash.ihx: recv-ram.ihx clean: rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM) diff --git a/target/radio/init.c b/target/radio/init.c new file mode 100644 index 00000000..61efb347 --- /dev/null +++ b/target/radio/init.c @@ -0,0 +1,205 @@ +/* + * Copyright © 2009 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; version 2 of the License. + * + * 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 "radio.h" + +/* Values from SmartRF® Studio for: + * + * Deviation: 20.507812 kHz + * Datarate: 38.360596 kBaud + * Modulation: GFSK + * RF Freq: 434.549927 MHz + * Channel: 99.975586 kHz + * Channel: 0 + * RX filter: 93.75 kHz + */ + +/* + * For 434.550MHz, the frequency value is: + * + * 434.550e6 / (24e6 / 2**16) = 1186611.2 + */ + +#define FREQ_CONTROL 1186611 + +/* + * For IF freq of 140.62kHz, the IF value is: + * + * 140.62e3 / (24e6 / 2**10) = 6 + */ + +#define IF_FREQ_CONTROL 6 + +/* + * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are + * + * BW = 24e6 / (8 * (4 + M) * 2 ** E) + * + * So, M = 0 and E = 3 + */ + +#define CHANBW_M 0 +#define CHANBW_E 3 + +/* + * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are: + * + * R = (256 + M) * 2** E * 24e6 / 2**28 + * + * So M is 163 and E is 10 + */ + +#define DRATE_E 10 +#define DRATE_M 163 + +/* + * For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are: + * + * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E + * + * So M is 6 and E is 3 + */ + +#define DEVIATION_M 6 +#define DEVIATION_E 3 + +#define PACKET_LEN 128 + +/* This are from the table for 433MHz */ + +#define RF_POWER_M30_DBM 0x12 +#define RF_POWER_M20_DBM 0x0e +#define RF_POWER_M15_DBM 0x1d +#define RF_POWER_M10_DBM 0x34 +#define RF_POWER_M5_DBM 0x2c +#define RF_POWER_0_DBM 0x60 +#define RF_POWER_5_DBM 0x84 +#define RF_POWER_7_DBM 0xc8 +#define RF_POWER_10_DBM 0xc0 + +#define RF_POWER RF_POWER_0_DBM + +static __code uint8_t radio_setup[] = { + RF_PA_TABLE7_OFF, RF_POWER, + RF_PA_TABLE6_OFF, RF_POWER, + RF_PA_TABLE5_OFF, RF_POWER, + RF_PA_TABLE4_OFF, RF_POWER, + RF_PA_TABLE3_OFF, RF_POWER, + RF_PA_TABLE2_OFF, RF_POWER, + RF_PA_TABLE1_OFF, RF_POWER, + RF_PA_TABLE0_OFF, RF_POWER, + + RF_FREQ2_OFF, FREQ_CONTROL >> 16, + RF_FREQ1_OFF, FREQ_CONTROL >> 8, + RF_FREQ0_OFF, FREQ_CONTROL >> 0, + + RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT), + RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT), + + RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), + RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT), + RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF | + RF_MDMCFG2_MOD_FORMAT_GFSK | + RF_MDMCFG2_SYNC_MODE_15_16_THRES), + RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_DIS | + RF_MDMCFG1_NUM_PREAMBLE_4 | + (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), + RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT), + + RF_CHANNR_OFF, 0, + + RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) | + (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)), + + /* SmartRF says set LODIV_BUF_CURRENT_TX to 0 + * And, we're not using power ramping, so use PA_POWER 0 + */ + RF_FREND0_OFF, ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) | + (0 << RF_FREND0_PA_POWER_SHIFT)), + + RF_FREND1_OFF, ((1 << RF_FREND1_LNA_CURRENT_SHIFT) | + (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) | + (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) | + (2 << RF_FREND1_MIX_CURRENT_SHIFT)), + + RF_FSCAL3_OFF, 0xE9, + RF_FSCAL2_OFF, 0x0A, + RF_FSCAL1_OFF, 0x00, + RF_FSCAL0_OFF, 0x1F, + + RF_TEST2_OFF, 0x88, + RF_TEST1_OFF, 0x31, + RF_TEST0_OFF, 0x09, + + /* default sync values */ + RF_SYNC1_OFF, 0xD3, + RF_SYNC0_OFF, 0x91, + + /* max packet length */ + RF_PKTLEN_OFF, PACKET_LEN, + + RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| + PKTCTRL1_APPEND_STATUS| + PKTCTRL1_ADR_CHK_NONE), + RF_PKTCTRL0_OFF, (RF_PKTCTRL0_PKT_FORMAT_NORMAL| + RF_PKTCTRL0_LENGTH_CONFIG_FIXED), + RF_ADDR_OFF, 0x00, + RF_MCSM2_OFF, (RF_MCSM2_RX_TIME_END_OF_PACKET), + RF_MCSM1_OFF, (RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING| + RF_MCSM1_RXOFF_MODE_IDLE| + RF_MCSM1_TXOFF_MODE_IDLE), + RF_MCSM0_OFF, (RF_MCSM0_FS_AUTOCAL_FROM_IDLE| + RF_MCSM0_MAGIC_3| + RF_MCSM0_CLOSE_IN_RX_18DB), + RF_FOCCFG_OFF, (RF_FOCCFG_FOC_PRE_K_3K, + RF_FOCCFG_FOC_POST_K_PRE_K, + RF_FOCCFG_FOC_LIMIT_BW_OVER_4), + RF_BSCFG_OFF, (RF_BSCFG_BS_PRE_K_2K| + RF_BSCFG_BS_PRE_KP_3KP| + RF_BSCFG_BS_POST_KI_PRE_KI| + RF_BSCFG_BS_POST_KP_PRE_KP| + RF_BSCFG_BS_LIMIT_0), + RF_AGCCTRL2_OFF, 0x43, + RF_AGCCTRL1_OFF, 0x40, + RF_AGCCTRL0_OFF, 0x91, + + RF_IOCFG2_OFF, 0x00, + RF_IOCFG1_OFF, 0x00, + RF_IOCFG0_OFF, 0x00, +}; + +void +radio_init(void) { + uint8_t i; + for (i = 0; i < sizeof (radio_setup); i += 2) + RF[radio_setup[i]] = radio_setup[i+1]; +} + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + + n <<= 1; + while (--n != 0) + while (--i != 0) + nop(); +} diff --git a/target/radio/radio.c b/target/radio/radio.c deleted file mode 100644 index bf893699..00000000 --- a/target/radio/radio.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * 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 - -sfr at 0x80 P0; -sfr at 0x90 P1; -sfr at 0xA0 P2; -sfr at 0xC6 CLKCON; - -sfr at 0xF1 PERCFG; -sfr at 0xF2 ADCCFG; -sfr at 0xF3 P0SEL; -sfr at 0xF4 P1SEL; -sfr at 0xF5 P2SEL; - -sfr at 0xFD P0DIR; -sfr at 0xFE P1DIR; -sfr at 0xFF P2DIR; -sfr at 0x8F P0INP; -sfr at 0xF6 P1INP; -sfr at 0xF7 P2INP; - -sfr at 0x89 P0IFG; -sfr at 0x8A P1IFG; -sfr at 0x8B P2IFG; - -sfr at 0xD9 RFD; -sfr at 0xE9 RFIF; -sfr at 0xE1 RFST; - -sfr at 0x88 TCON; - -sfr at 0xbe SLEEP; - -# define SLEEP_USB_EN (1 << 7) -# define SLEEP_XOSC_STB (1 << 6) - -sbit at 0x89 RFTXRXIF; - -#define TCON_RFTXRXIF (1 << 1) - -#define RFST_SFSTXON 0x00 -#define RFST_SCAL 0x01 -#define RFST_SRX 0x02 -#define RFST_STX 0x03 -#define RFST_SIDLE 0x04 - -__xdata __at (0xdf00) uint8_t RF[0x3c]; - -__xdata __at (0xdf2f) uint8_t RF_IOCFG2; -#define RF_IOCFG2_OFF 0x2f - -__xdata __at (0xdf30) uint8_t RF_IOCFG1; -#define RF_IOCFG1_OFF 0x30 - -__xdata __at (0xdf31) uint8_t RF_IOCFG0; -#define RF_IOCFG0_OFF 0x31 - -__xdata __at (0xdf00) uint8_t RF_SYNC1; -#define RF_SYNC1_OFF 0x00 - -__xdata __at (0xdf01) uint8_t RF_SYNC0; -#define RF_SYNC0_OFF 0x01 - -__xdata __at (0xdf02) uint8_t RF_PKTLEN; -#define RF_PKTLEN_OFF 0x02 - -__xdata __at (0xdf03) uint8_t RF_PKTCTRL1; -#define RF_PKTCTRL1_OFF 0x03 - -__xdata __at (0xdf04) uint8_t RF_PKTCTRL0; -#define RF_PKTCTRL0_OFF 0x04 - -__xdata __at (0xdf05) uint8_t RF_ADDR; -#define RF_ADDR_OFF 0x05 - -__xdata __at (0xdf06) uint8_t RF_CHANNR; -#define RF_CHANNR_OFF 0x06 - -__xdata __at (0xdf07) uint8_t RF_FSCTRL1; -#define RF_FSCTRL1_OFF 0x07 - -#define RF_FSCTRL1_FREQ_IF_SHIFT (0) - -__xdata __at (0xdf08) uint8_t RF_FSCTRL0; -#define RF_FSCTRL0_OFF 0x08 - -#define RF_FSCTRL0_FREQOFF_SHIFT (0) - -__xdata __at (0xdf09) uint8_t RF_FREQ2; -#define RF_FREQ2_OFF 0x09 - -__xdata __at (0xdf0a) uint8_t RF_FREQ1; -#define RF_FREQ1_OFF 0x0a - -__xdata __at (0xdf0b) uint8_t RF_FREQ0; -#define RF_FREQ0_OFF 0x0b - -__xdata __at (0xdf0c) uint8_t RF_MDMCFG4; -#define RF_MDMCFG4_OFF 0x0c - -#define RF_MDMCFG4_CHANBW_E_SHIFT 6 -#define RF_MDMCFG4_CHANBW_M_SHIFT 4 -#define RF_MDMCFG4_DRATE_E_SHIFT 0 - -__xdata __at (0xdf0d) uint8_t RF_MDMCFG3; -#define RF_MDMCFG3_OFF 0x0d - -#define RF_MDMCFG3_DRATE_M_SHIFT 0 - -__xdata __at (0xdf0e) uint8_t RF_MDMCFG2; -#define RF_MDMCFG2_OFF 0x0e - -#define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7) - -#define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4) -#define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4) -#define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4) -#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4) -#define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4) - -#define RF_MDMCFG2_MANCHESTER_EN (1 << 3) - -#define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0) -#define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0) -#define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0) -#define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0) -#define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0) -#define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0) -#define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0) -#define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0) -#define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0) - -__xdata __at (0xdf0f) uint8_t RF_MDMCFG1; -#define RF_MDMCFG1_OFF 0x0f - -#define RF_MDMCFG1_FEC_EN (1 << 7) - -#define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4) -#define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4) - -#define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0) -#define RF_MDMCFG1_CHANSPC_E_SHIFT (0) - -__xdata __at (0xdf10) uint8_t RF_MDMCFG0; -#define RF_MDMCFG0_OFF 0x10 - -#define RF_MDMCFG0_CHANSPC_M_SHIFT (0) - -__xdata __at (0xdf11) uint8_t RF_DEVIATN; -#define RF_DEVIATN_OFF 0x11 - -#define RF_DEVIATN_DEVIATION_E_SHIFT 4 -#define RF_DEVIATN_DEVIATION_M_SHIFT 0 - -__xdata __at (0xdf12) uint8_t RF_MCSM2; -#define RF_MCSM2_OFF 0x12 - -__xdata __at (0xdf13) uint8_t RF_MCSM1; -#define RF_MCSM1_OFF 0x13 - -__xdata __at (0xdf14) uint8_t RF_MCSM0; -#define RF_MCSM0_OFF 0x14 - -__xdata __at (0xdf15) uint8_t RF_FOCCFG; -#define RF_FOCCFG_OFF 0x15 - -__xdata __at (0xdf16) uint8_t RF_BSCFG; -#define RF_BSCFG_OFF 0x16 - -__xdata __at (0xdf17) uint8_t RF_AGCCTRL2; -#define RF_AGCCTRL2_OFF 0x17 - -__xdata __at (0xdf18) uint8_t RF_AGCCTRL1; -#define RF_AGCCTRL1_OFF 0x18 - -__xdata __at (0xdf19) uint8_t RF_AGCCTRL0; -#define RF_AGCCTRL0_OFF 0x19 - -__xdata __at (0xdf1a) uint8_t RF_FREND1; -#define RF_FREND1_OFF 0x1a - -#define RF_FREND1_LNA_CURRENT_SHIFT 6 -#define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4 -#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2 -#define RF_FREND1_MIX_CURRENT_SHIFT 0 - -__xdata __at (0xdf1b) uint8_t RF_FREND0; -#define RF_FREND0_OFF 0x1b - -#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4) -#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4 -#define RF_FREND0_PA_POWER_MASK (0x7) -#define RF_FREND0_PA_POWER_SHIFT 0 - -__xdata __at (0xdf1c) uint8_t RF_FSCAL3; -#define RF_FSCAL3_OFF 0x1c - -__xdata __at (0xdf1d) uint8_t RF_FSCAL2; -#define RF_FSCAL2_OFF 0x1d - -__xdata __at (0xdf1e) uint8_t RF_FSCAL1; -#define RF_FSCAL1_OFF 0x1e - -__xdata __at (0xdf1f) uint8_t RF_FSCAL0; -#define RF_FSCAL0_OFF 0x1f - -__xdata __at (0xdf23) uint8_t RF_TEST2; -#define RF_TEST2_OFF 0x23 - -#define RF_TEST2_NORMAL_MAGIC 0x88 -#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81 - -__xdata __at (0xdf24) uint8_t RF_TEST1; -#define RF_TEST1_OFF 0x24 - -#define RF_TEST1_TX_MAGIC 0x31 -#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35 - -__xdata __at (0xdf25) uint8_t RF_TEST0; -#define RF_TEST0_OFF 0x25 - -#define RF_TEST0_7_2_MASK (0xfc) -#define RF_TEST0_VCO_SEL_CAL_EN (1 << 1) -#define RF_TEST0_0_MASK (1) - -/* These are undocumented, and must be computed - * using the provided tool. - */ -__xdata __at (0xdf27) uint8_t RF_PA_TABLE7; -#define RF_PA_TABLE7_OFF 0x27 - -__xdata __at (0xdf28) uint8_t RF_PA_TABLE6; -#define RF_PA_TABLE6_OFF 0x28 - -__xdata __at (0xdf29) uint8_t RF_PA_TABLE5; -#define RF_PA_TABLE5_OFF 0x29 - -__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4; -#define RF_PA_TABLE4_OFF 0x2a - -__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3; -#define RF_PA_TABLE3_OFF 0x2b - -__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2; -#define RF_PA_TABLE2_OFF 0x2c - -__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1; -#define RF_PA_TABLE1_OFF 0x2d - -__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0; -#define RF_PA_TABLE0_OFF 0x2e - -__xdata __at (0xdf36) uint8_t RF_PARTNUM; -#define RF_PARTNUM_OFF 0x36 - -__xdata __at (0xdf37) uint8_t RF_VERSION; -#define RF_VERSION_OFF 0x37 - -__xdata __at (0xdf38) uint8_t RF_FREQEST; -#define RF_FREQEST_OFF 0x38 - -__xdata __at (0xdf39) uint8_t RF_LQI; -#define RF_LQI_OFF 0x39 - -#define RF_LQI_CRC_OK (1 << 7) -#define RF_LQI_LQI_EST_MASK (0x7f) - -__xdata __at (0xdf3a) uint8_t RF_RSSI; -#define RF_RSSI_OFF 0x3a - -__xdata __at (0xdf3b) uint8_t RF_MARCSTATE; -#define RF_MARCSTATE_OFF 0x3b - -#define RF_MARCSTATE_MASK 0x0f -#define RF_MARCSTATE_SLEEP 0x00 -#define RF_MARCSTATE_IDLE 0x01 -#define RF_MARCSTATE_VCOON_MC 0x03 -#define RF_MARCSTATE_REGON_MC 0x04 -#define RF_MARCSTATE_MANCAL 0x05 -#define RF_MARCSTATE_VCOON 0x06 -#define RF_MARCSTATE_REGON 0x07 -#define RF_MARCSTATE_STARTCAL 0x08 -#define RF_MARCSTATE_BWBOOST 0x09 -#define RF_MARCSTATE_FS_LOCK 0x0a -#define RF_MARCSTATE_IFADCON 0x0b -#define RF_MARCSTATE_ENDCAL 0x0c -#define RF_MARCSTATE_RX 0x0d -#define RF_MARCSTATE_RX_END 0x0e -#define RF_MARCSTATE_RX_RST 0x0f -#define RF_MARCSTATE_TXRX_SWITCH 0x10 -#define RF_MARCSTATE_RX_OVERFLOW 0x11 -#define RF_MARCSTATE_FSTXON 0x12 -#define RF_MARCSTATE_TX 0x13 -#define RF_MARCSTATE_TX_END 0x14 -#define RF_MARCSTATE_RXTX_SWITCH 0x15 -#define RF_MARCSTATE_TX_UNDERFLOW 0x16 - - -__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS; -#define RF_PKTSTATUS_OFF 0x3c - -#define RF_PKTSTATUS_CRC_OK (1 << 7) -#define RF_PKTSTATUS_CS (1 << 6) -#define RF_PKTSTATUS_PQT_REACHED (1 << 5) -#define RF_PKTSTATUS_CCA (1 << 4) -#define RF_PKTSTATUS_SFD (1 << 3) - -__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC; -#define RF_VCO_VC_DAC_OFF 0x3d - -#define nop() _asm nop _endasm; - -void -delay (unsigned char n) -{ - unsigned char i = 0; - - n <<= 1; - while (--n != 0) - while (--i != 0) - nop(); -} - -void -tone (unsigned char n, unsigned char m) -{ - unsigned char i = 0; - while (--m != 0) { - i = 128; - while (--i != 0) { - P2 = 0xff; - delay(n); - P2 = 0xfe; - delay(n); - } - } -} - -void -high() { - tone(1, 2); -} - -void -low() { - tone(2, 1); -} - -/* Values from SmartRF® Studio for: - * - * Deviation: 20.507812 kHz - * Datarate: 38.360596 kBaud - * Modulation: GFSK - * RF Freq: 434.549927 MHz - * Channel: 99.975586 kHz - * Channel: 0 - * RX filter: 93.75 kHz - */ - -/* - * For 434.550MHz, the frequency value is: - * - * 434.550e6 / (24e6 / 2**16) = 1186611.2 - */ - -#define FREQ_CONTROL 1186611 - -/* - * For IF freq of 140.62kHz, the IF value is: - * - * 140.62e3 / (24e6 / 2**10) = 6 - */ - -#define IF_FREQ_CONTROL 6 - -/* - * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are - * - * BW = 24e6 / (8 * (4 + M) * 2 ** E) - * - * So, M = 0 and E = 3 - */ - -#define CHANBW_M 0 -#define CHANBW_E 3 - -/* - * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are: - * - * R = (256 + M) * 2** E * 24e6 / 2**28 - * - * So M is 163 and E is 10 - */ - -#define DRATE_E 10 -#define DRATE_M 163 - -#define PACKET_LEN 255 - -/* This are from the table for 433MHz */ - -#define RF_POWER_M30_DBM 0x12 -#define RF_POWER_M20_DBM 0x0e -#define RF_POWER_M15_DBM 0x1d -#define RF_POWER_M10_DBM 0x34 -#define RF_POWER_M5_DBM 0x2c -#define RF_POWER_0_DBM 0x60 -#define RF_POWER_5_DBM 0x84 -#define RF_POWER_7_DBM 0xc8 -#define RF_POWER_10_DBM 0xc0 - -#define RF_POWER RF_POWER_0_DBM - -static __code uint8_t radio_setup[] = { - RF_PA_TABLE7_OFF, RF_POWER, - RF_PA_TABLE6_OFF, RF_POWER, - RF_PA_TABLE5_OFF, RF_POWER, - RF_PA_TABLE4_OFF, RF_POWER, - RF_PA_TABLE3_OFF, RF_POWER, - RF_PA_TABLE2_OFF, RF_POWER, - RF_PA_TABLE1_OFF, RF_POWER, - RF_PA_TABLE0_OFF, RF_POWER, - - RF_FREQ2_OFF, FREQ_CONTROL >> 16, - RF_FREQ1_OFF, FREQ_CONTROL >> 8, - RF_FREQ0_OFF, FREQ_CONTROL >> 0, - - RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT), - RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT), - - RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | - (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) | - (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)), - RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT), - RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF | - RF_MDMCFG2_MOD_FORMAT_GFSK | - RF_MDMCFG2_SYNC_MODE_NONE), - RF_MDMCFG1_OFF, (RF_MDMCFG1_NUM_PREAMBLE_4 | - (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), - RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT), - - RF_CHANNR_OFF, 0, - - RF_DEVIATN_OFF, ((3 << RF_DEVIATN_DEVIATION_E_SHIFT) | - (6 << RF_DEVIATN_DEVIATION_M_SHIFT)), - - /* SmartRF says set LODIV_BUF_CURRENT_TX to 0 - * And, we're not using power ramping, so use PA_POWER 0 - */ - RF_FREND0_OFF, ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) | - (0 << RF_FREND0_PA_POWER_SHIFT)), - - RF_FREND1_OFF, ((1 << RF_FREND1_LNA_CURRENT_SHIFT) | - (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) | - (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) | - (2 << RF_FREND1_MIX_CURRENT_SHIFT)), - RF_MCSM0_OFF, 0x18, - RF_FOCCFG_OFF, 0x16, - RF_BSCFG_OFF, 0x6C, - - RF_AGCCTRL2_OFF, 0x43, - RF_AGCCTRL1_OFF, 0x40, - RF_AGCCTRL0_OFF, 0x91, - - RF_FSCAL3_OFF, 0xE9, - RF_FSCAL2_OFF, 0x0A, - RF_FSCAL1_OFF, 0x00, - RF_FSCAL0_OFF, 0x1F, - - RF_TEST2_OFF, 0x88, - RF_TEST1_OFF, 0x31, - RF_TEST0_OFF, 0x09, - - /* default sync values */ - RF_SYNC1_OFF, 0xD3, - RF_SYNC0_OFF, 0x91, - - /* max packet length */ - RF_PKTLEN_OFF, PACKET_LEN, - - RF_PKTCTRL1_OFF, 0x04, - RF_PKTCTRL0_OFF, 0x00, - RF_ADDR_OFF, 0x00, - RF_MCSM2_OFF, 0x07, - RF_MCSM1_OFF, 0x30, - - RF_IOCFG2_OFF, 0x00, - RF_IOCFG1_OFF, 0x00, - RF_IOCFG0_OFF, 0x00, -}; - -void -radio_init() { - uint8_t i; - for (i = 0; i < sizeof (radio_setup); i += 2) - RF[radio_setup[i]] = radio_setup[i+1]; -} - -main () -{ - CLKCON = 0; - while (!(SLEEP & SLEEP_XOSC_STB)) - ; - /* Set P2_0 to output */ - radio_init (); - delay(100); - - for (;;) { - uint8_t i; - RFST = RFST_SIDLE; - delay(100); - RFST = RFST_STX; - for (i = 0; i < PACKET_LEN - 1; i++) { - while (!RFTXRXIF); - RFTXRXIF = 0; - RFD = 0x55; - } - delay(100); - } -} diff --git a/target/radio/radio.h b/target/radio/radio.h new file mode 100644 index 00000000..d501ad12 --- /dev/null +++ b/target/radio/radio.h @@ -0,0 +1,428 @@ +/* + * 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 + +sfr at 0x80 P0; +sfr at 0x90 P1; +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; + +sfr at 0xF1 PERCFG; +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sfr at 0xD9 RFD; +sfr at 0xE9 RFIF; +#define RFIF_IM_TXUNF (1 << 7) +#define RFIF_IM_RXOVF (1 << 6) +#define RFIF_IM_TIMEOUT (1 << 5) +#define RFIF_IM_DONE (1 << 4) +#define RFIF_IM_CS (1 << 3) +#define RFIF_IM_PQT (1 << 2) +#define RFIF_IM_CCA (1 << 1) +#define RFIF_IM_SFD (1 << 0) + +sfr at 0xE1 RFST; + +sfr at 0x88 TCON; + +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sbit at 0x89 RFTXRXIF; + +#define TCON_RFTXRXIF (1 << 1) + +#define RFST_SFSTXON 0x00 +#define RFST_SCAL 0x01 +#define RFST_SRX 0x02 +#define RFST_STX 0x03 +#define RFST_SIDLE 0x04 + +__xdata __at (0xdf00) uint8_t RF[0x3c]; + +__xdata __at (0xdf2f) uint8_t RF_IOCFG2; +#define RF_IOCFG2_OFF 0x2f + +__xdata __at (0xdf30) uint8_t RF_IOCFG1; +#define RF_IOCFG1_OFF 0x30 + +__xdata __at (0xdf31) uint8_t RF_IOCFG0; +#define RF_IOCFG0_OFF 0x31 + +__xdata __at (0xdf00) uint8_t RF_SYNC1; +#define RF_SYNC1_OFF 0x00 + +__xdata __at (0xdf01) uint8_t RF_SYNC0; +#define RF_SYNC0_OFF 0x01 + +__xdata __at (0xdf02) uint8_t RF_PKTLEN; +#define RF_PKTLEN_OFF 0x02 + +__xdata __at (0xdf03) uint8_t RF_PKTCTRL1; +#define RF_PKTCTRL1_OFF 0x03 +#define PKTCTRL1_PQT_MASK (0x7 << 5) +#define PKTCTRL1_PQT_SHIFT 5 +#define PKTCTRL1_APPEND_STATUS (1 << 2) +#define PKTCTRL1_ADR_CHK_NONE (0 << 0) +#define PKTCTRL1_ADR_CHK_NO_BROADCAST (1 << 0) +#define PKTCTRL1_ADR_CHK_00_BROADCAST (2 << 0) +#define PKTCTRL1_ADR_CHK_00_FF_BROADCAST (3 << 0) + +__xdata __at (0xdf04) uint8_t RF_PKTCTRL0; +#define RF_PKTCTRL0_OFF 0x04 +#define RF_PKTCTRL0_WHITE_DATA (1 << 6) +#define RF_PKTCTRL0_PKT_FORMAT_NORMAL (0 << 4) +#define RF_PKTCTRL0_PKT_FORMAT_RANDOM (2 << 4) +#define RF_PKTCTRL0_CRC_EN (1 << 2) +#define RF_PKTCTRL0_LENGTH_CONFIG_FIXED (0 << 0) +#define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE (1 << 0) + +__xdata __at (0xdf05) uint8_t RF_ADDR; +#define RF_ADDR_OFF 0x05 + +__xdata __at (0xdf06) uint8_t RF_CHANNR; +#define RF_CHANNR_OFF 0x06 + +__xdata __at (0xdf07) uint8_t RF_FSCTRL1; +#define RF_FSCTRL1_OFF 0x07 + +#define RF_FSCTRL1_FREQ_IF_SHIFT (0) + +__xdata __at (0xdf08) uint8_t RF_FSCTRL0; +#define RF_FSCTRL0_OFF 0x08 + +#define RF_FSCTRL0_FREQOFF_SHIFT (0) + +__xdata __at (0xdf09) uint8_t RF_FREQ2; +#define RF_FREQ2_OFF 0x09 + +__xdata __at (0xdf0a) uint8_t RF_FREQ1; +#define RF_FREQ1_OFF 0x0a + +__xdata __at (0xdf0b) uint8_t RF_FREQ0; +#define RF_FREQ0_OFF 0x0b + +__xdata __at (0xdf0c) uint8_t RF_MDMCFG4; +#define RF_MDMCFG4_OFF 0x0c + +#define RF_MDMCFG4_CHANBW_E_SHIFT 6 +#define RF_MDMCFG4_CHANBW_M_SHIFT 4 +#define RF_MDMCFG4_DRATE_E_SHIFT 0 + +__xdata __at (0xdf0d) uint8_t RF_MDMCFG3; +#define RF_MDMCFG3_OFF 0x0d + +#define RF_MDMCFG3_DRATE_M_SHIFT 0 + +__xdata __at (0xdf0e) uint8_t RF_MDMCFG2; +#define RF_MDMCFG2_OFF 0x0e + +#define RF_MDMCFG2_DEM_DCFILT_OFF (1 << 7) +#define RF_MDMCFG2_DEM_DCFILT_ON (0 << 7) + +#define RF_MDMCFG2_MOD_FORMAT_MASK (7 << 4) +#define RF_MDMCFG2_MOD_FORMAT_2_FSK (0 << 4) +#define RF_MDMCFG2_MOD_FORMAT_GFSK (1 << 4) +#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK (3 << 4) +#define RF_MDMCFG2_MOD_FORMAT_MSK (7 << 4) + +#define RF_MDMCFG2_MANCHESTER_EN (1 << 3) + +#define RF_MDMCFG2_SYNC_MODE_MASK (0x7 << 0) +#define RF_MDMCFG2_SYNC_MODE_NONE (0x0 << 0) +#define RF_MDMCFG2_SYNC_MODE_15_16 (0x1 << 0) +#define RF_MDMCFG2_SYNC_MODE_16_16 (0x2 << 0) +#define RF_MDMCFG2_SYNC_MODE_30_32 (0x3 << 0) +#define RF_MDMCFG2_SYNC_MODE_NONE_THRES (0x4 << 0) +#define RF_MDMCFG2_SYNC_MODE_15_16_THRES (0x5 << 0) +#define RF_MDMCFG2_SYNC_MODE_16_16_THRES (0x6 << 0) +#define RF_MDMCFG2_SYNC_MODE_30_32_THRES (0x7 << 0) + +__xdata __at (0xdf0f) uint8_t RF_MDMCFG1; +#define RF_MDMCFG1_OFF 0x0f + +#define RF_MDMCFG1_FEC_EN (1 << 7) +#define RF_MDMCFG1_FEC_DIS (0 << 7) + +#define RF_MDMCFG1_NUM_PREAMBLE_MASK (7 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_2 (0 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_3 (1 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_4 (2 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_6 (3 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_8 (4 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_12 (5 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_16 (6 << 4) +#define RF_MDMCFG1_NUM_PREAMBLE_24 (7 << 4) + +#define RF_MDMCFG1_CHANSPC_E_MASK (3 << 0) +#define RF_MDMCFG1_CHANSPC_E_SHIFT (0) + +__xdata __at (0xdf10) uint8_t RF_MDMCFG0; +#define RF_MDMCFG0_OFF 0x10 + +#define RF_MDMCFG0_CHANSPC_M_SHIFT (0) + +__xdata __at (0xdf11) uint8_t RF_DEVIATN; +#define RF_DEVIATN_OFF 0x11 + +#define RF_DEVIATN_DEVIATION_E_SHIFT 4 +#define RF_DEVIATN_DEVIATION_M_SHIFT 0 + +__xdata __at (0xdf12) uint8_t RF_MCSM2; +#define RF_MCSM2_OFF 0x12 +#define RF_MCSM2_RX_TIME_RSSI (1 << 4) +#define RF_MCSM2_RX_TIME_QUAL (1 << 3) +#define RF_MCSM2_RX_TIME_MASK (0x7) +#define RF_MCSM2_RX_TIME_SHIFT 0 +#define RF_MCSM2_RX_TIME_END_OF_PACKET (7) + +__xdata __at (0xdf13) uint8_t RF_MCSM1; +#define RF_MCSM1_OFF 0x13 +#define RF_MCSM1_CCA_MODE_ALWAYS (0 << 4) +#define RF_MCSM1_CCA_MODE_RSSI_BELOW (1 << 4) +#define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING (2 << 4) +#define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING (3 << 4) +#define RF_MCSM1_RXOFF_MODE_IDLE (0 << 2) +#define RF_MCSM1_RXOFF_MODE_FSTXON (1 << 2) +#define RF_MCSM1_RXOFF_MODE_TX (2 << 2) +#define RF_MCSM1_RXOFF_MODE_RX (3 << 2) +#define RF_MCSM1_TXOFF_MODE_IDLE (0 << 0) +#define RF_MCSM1_TXOFF_MODE_FSTXON (1 << 0) +#define RF_MCSM1_TXOFF_MODE_TX (2 << 0) +#define RF_MCSM1_TXOFF_MODE_RX (3 << 0) + +__xdata __at (0xdf14) uint8_t RF_MCSM0; +#define RF_MCSM0_OFF 0x14 +#define RF_MCSM0_FS_AUTOCAL_NEVER (0 << 4) +#define RF_MCSM0_FS_AUTOCAL_FROM_IDLE (1 << 4) +#define RF_MCSM0_FS_AUTOCAL_TO_IDLE (2 << 4) +#define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4 (3 << 4) +#define RF_MCSM0_MAGIC_3 (1 << 3) +#define RF_MCSM0_MAGIC_2 (1 << 2) +#define RF_MCSM0_CLOSE_IN_RX_0DB (0 << 0) +#define RF_MCSM0_CLOSE_IN_RX_6DB (1 << 0) +#define RF_MCSM0_CLOSE_IN_RX_12DB (2 << 0) +#define RF_MCSM0_CLOSE_IN_RX_18DB (3 << 0) + +__xdata __at (0xdf15) uint8_t RF_FOCCFG; +#define RF_FOCCFG_OFF 0x15 +#define RF_FOCCFG_FOC_BS_CS_GATE (1 << 5) +#define RF_FOCCFG_FOC_PRE_K_1K (0 << 3) +#define RF_FOCCFG_FOC_PRE_K_2K (1 << 3) +#define RF_FOCCFG_FOC_PRE_K_3K (2 << 3) +#define RF_FOCCFG_FOC_PRE_K_4K (3 << 3) +#define RF_FOCCFG_FOC_POST_K_PRE_K (0 << 2) +#define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2 (1 << 2) +#define RF_FOCCFG_FOC_LIMIT_0 (0 << 0) +#define RF_FOCCFG_FOC_LIMIT_BW_OVER_8 (1 << 0) +#define RF_FOCCFG_FOC_LIMIT_BW_OVER_4 (2 << 0) +#define RF_FOCCFG_FOC_LIMIT_BW_OVER_2 (3 << 0) + +__xdata __at (0xdf16) uint8_t RF_BSCFG; +#define RF_BSCFG_OFF 0x16 +#define RF_BSCFG_BS_PRE_K_1K (0 << 6) +#define RF_BSCFG_BS_PRE_K_2K (1 << 6) +#define RF_BSCFG_BS_PRE_K_3K (2 << 6) +#define RF_BSCFG_BS_PRE_K_4K (3 << 6) +#define RF_BSCFG_BS_PRE_KP_1KP (0 << 4) +#define RF_BSCFG_BS_PRE_KP_2KP (1 << 4) +#define RF_BSCFG_BS_PRE_KP_3KP (2 << 4) +#define RF_BSCFG_BS_PRE_KP_4KP (3 << 4) +#define RF_BSCFG_BS_POST_KI_PRE_KI (0 << 3) +#define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2 (1 << 3) +#define RF_BSCFG_BS_POST_KP_PRE_KP (0 << 2) +#define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2 (1 << 2) +#define RF_BSCFG_BS_LIMIT_0 (0 << 0) +#define RF_BSCFG_BS_LIMIT_3_125 (1 << 0) +#define RF_BSCFG_BS_LIMIT_6_25 (2 << 0) +#define RF_BSCFG_BS_LIMIT_12_5 (3 << 0) + +__xdata __at (0xdf17) uint8_t RF_AGCCTRL2; +#define RF_AGCCTRL2_OFF 0x17 + +__xdata __at (0xdf18) uint8_t RF_AGCCTRL1; +#define RF_AGCCTRL1_OFF 0x18 + +__xdata __at (0xdf19) uint8_t RF_AGCCTRL0; +#define RF_AGCCTRL0_OFF 0x19 + +__xdata __at (0xdf1a) uint8_t RF_FREND1; +#define RF_FREND1_OFF 0x1a + +#define RF_FREND1_LNA_CURRENT_SHIFT 6 +#define RF_FREND1_LNA2MIX_CURRENT_SHIFT 4 +#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT 2 +#define RF_FREND1_MIX_CURRENT_SHIFT 0 + +__xdata __at (0xdf1b) uint8_t RF_FREND0; +#define RF_FREND0_OFF 0x1b + +#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK (0x3 << 4) +#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT 4 +#define RF_FREND0_PA_POWER_MASK (0x7) +#define RF_FREND0_PA_POWER_SHIFT 0 + +__xdata __at (0xdf1c) uint8_t RF_FSCAL3; +#define RF_FSCAL3_OFF 0x1c + +__xdata __at (0xdf1d) uint8_t RF_FSCAL2; +#define RF_FSCAL2_OFF 0x1d + +__xdata __at (0xdf1e) uint8_t RF_FSCAL1; +#define RF_FSCAL1_OFF 0x1e + +__xdata __at (0xdf1f) uint8_t RF_FSCAL0; +#define RF_FSCAL0_OFF 0x1f + +__xdata __at (0xdf23) uint8_t RF_TEST2; +#define RF_TEST2_OFF 0x23 + +#define RF_TEST2_NORMAL_MAGIC 0x88 +#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81 + +__xdata __at (0xdf24) uint8_t RF_TEST1; +#define RF_TEST1_OFF 0x24 + +#define RF_TEST1_TX_MAGIC 0x31 +#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35 + +__xdata __at (0xdf25) uint8_t RF_TEST0; +#define RF_TEST0_OFF 0x25 + +#define RF_TEST0_7_2_MASK (0xfc) +#define RF_TEST0_VCO_SEL_CAL_EN (1 << 1) +#define RF_TEST0_0_MASK (1) + +/* These are undocumented, and must be computed + * using the provided tool. + */ +__xdata __at (0xdf27) uint8_t RF_PA_TABLE7; +#define RF_PA_TABLE7_OFF 0x27 + +__xdata __at (0xdf28) uint8_t RF_PA_TABLE6; +#define RF_PA_TABLE6_OFF 0x28 + +__xdata __at (0xdf29) uint8_t RF_PA_TABLE5; +#define RF_PA_TABLE5_OFF 0x29 + +__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4; +#define RF_PA_TABLE4_OFF 0x2a + +__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3; +#define RF_PA_TABLE3_OFF 0x2b + +__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2; +#define RF_PA_TABLE2_OFF 0x2c + +__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1; +#define RF_PA_TABLE1_OFF 0x2d + +__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0; +#define RF_PA_TABLE0_OFF 0x2e + +__xdata __at (0xdf36) uint8_t RF_PARTNUM; +#define RF_PARTNUM_OFF 0x36 + +__xdata __at (0xdf37) uint8_t RF_VERSION; +#define RF_VERSION_OFF 0x37 + +__xdata __at (0xdf38) uint8_t RF_FREQEST; +#define RF_FREQEST_OFF 0x38 + +__xdata __at (0xdf39) uint8_t RF_LQI; +#define RF_LQI_OFF 0x39 + +#define RF_LQI_CRC_OK (1 << 7) +#define RF_LQI_LQI_EST_MASK (0x7f) + +__xdata __at (0xdf3a) uint8_t RF_RSSI; +#define RF_RSSI_OFF 0x3a + +__xdata __at (0xdf3b) uint8_t RF_MARCSTATE; +#define RF_MARCSTATE_OFF 0x3b + +#define RF_MARCSTATE_MASK 0x0f +#define RF_MARCSTATE_SLEEP 0x00 +#define RF_MARCSTATE_IDLE 0x01 +#define RF_MARCSTATE_VCOON_MC 0x03 +#define RF_MARCSTATE_REGON_MC 0x04 +#define RF_MARCSTATE_MANCAL 0x05 +#define RF_MARCSTATE_VCOON 0x06 +#define RF_MARCSTATE_REGON 0x07 +#define RF_MARCSTATE_STARTCAL 0x08 +#define RF_MARCSTATE_BWBOOST 0x09 +#define RF_MARCSTATE_FS_LOCK 0x0a +#define RF_MARCSTATE_IFADCON 0x0b +#define RF_MARCSTATE_ENDCAL 0x0c +#define RF_MARCSTATE_RX 0x0d +#define RF_MARCSTATE_RX_END 0x0e +#define RF_MARCSTATE_RX_RST 0x0f +#define RF_MARCSTATE_TXRX_SWITCH 0x10 +#define RF_MARCSTATE_RX_OVERFLOW 0x11 +#define RF_MARCSTATE_FSTXON 0x12 +#define RF_MARCSTATE_TX 0x13 +#define RF_MARCSTATE_TX_END 0x14 +#define RF_MARCSTATE_RXTX_SWITCH 0x15 +#define RF_MARCSTATE_TX_UNDERFLOW 0x16 + + +__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS; +#define RF_PKTSTATUS_OFF 0x3c + +#define RF_PKTSTATUS_CRC_OK (1 << 7) +#define RF_PKTSTATUS_CS (1 << 6) +#define RF_PKTSTATUS_PQT_REACHED (1 << 5) +#define RF_PKTSTATUS_CCA (1 << 4) +#define RF_PKTSTATUS_SFD (1 << 3) + +__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC; +#define RF_VCO_VC_DAC_OFF 0x3d + +#define PACKET_LEN 128 + +void +radio_init(void); + +void +delay (unsigned char n); diff --git a/target/radio/recv.c b/target/radio/recv.c new file mode 100644 index 00000000..17a3d178 --- /dev/null +++ b/target/radio/recv.c @@ -0,0 +1,66 @@ +/* + * 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 "radio.h" + +main () +{ + static uint8_t packet[PACKET_LEN + 2]; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + /* Set P2_0 to output */ + P1 = 0; + P1DIR = 0x02; + radio_init (); + delay(100); + + for (;;) { + uint8_t i; + RFST = RFST_SIDLE; + RFIF = 0; + delay(100); + RFST = RFST_SRX; +// while (!(RFIF & RFIF_IM_CS)); +// P1 = 2; + for (i = 0; i < PACKET_LEN + 2; i++) { + while (!RFTXRXIF) + ; + P1=2; + RFTXRXIF = 0; + packet[i] = RFD; + } + P1 = 0; + + /* check packet contents */ + for (i = 0; i < PACKET_LEN; i++) + if (packet[i] != i) + break; + + /* get excited if the packet came through correctly */ + if (i == PACKET_LEN) { + for (i = 0; i < 3; i++){ + P1 = 2; + delay(100); + P1 = 0; + delay(100); + } + } + delay(100); + } +} diff --git a/target/radio/xmit.c b/target/radio/xmit.c new file mode 100644 index 00000000..e80a0f8b --- /dev/null +++ b/target/radio/xmit.c @@ -0,0 +1,47 @@ +/* + * Copyright © 2009 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; version 2 of the License. + * + * 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 "radio.h" + +main () +{ + int16_t j; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + P1 = 0; + P1DIR = 3; + radio_init (); + delay(100); + + for (;;) { + uint8_t i; + + for (j = 0; j < 100; j++) + delay(100); + P1 = 2; + RFST = RFST_SIDLE; + delay(1); + RFST = RFST_STX; + for (i = 0; i < PACKET_LEN; i++) { + while (!RFTXRXIF); + RFTXRXIF = 0; + RFD = i; + } + P1 = 0; + } +} -- cgit v1.2.3 From 94e5343a72121a81ab19bf5025e6b6fc9847eb4f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:19:25 -0700 Subject: Add packet status byte defines --- target/radio/radio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/target/radio/radio.h b/target/radio/radio.h index d501ad12..f68001e4 100644 --- a/target/radio/radio.h +++ b/target/radio/radio.h @@ -109,6 +109,13 @@ __xdata __at (0xdf03) uint8_t RF_PKTCTRL1; #define PKTCTRL1_ADR_CHK_00_BROADCAST (2 << 0) #define PKTCTRL1_ADR_CHK_00_FF_BROADCAST (3 << 0) +/* If APPEND_STATUS is used, two bytes will be added to the packet data */ +#define PKT_APPEND_STATUS_0_RSSI_MASK (0xff) +#define PKT_APPEND_STATUS_0_RSSI_SHIFT 0 +#define PKT_APPEND_STATUS_1_CRC_OK (1 << 7) +#define PKT_APPEND_STATUS_1_LQI_MASK (0x7f) +#define PKT_APPEND_STATUS_1_LQI_SHIFT 0 + __xdata __at (0xdf04) uint8_t RF_PKTCTRL0; #define RF_PKTCTRL0_OFF 0x04 #define RF_PKTCTRL0_WHITE_DATA (1 << 6) -- cgit v1.2.3 From 20834caf01ddf481e8362b0d2627ef383a82e09d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:23:10 -0700 Subject: Add data whitening --- target/radio/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/radio/init.c b/target/radio/init.c index 61efb347..6843ef9a 100644 --- a/target/radio/init.c +++ b/target/radio/init.c @@ -157,7 +157,8 @@ static __code uint8_t radio_setup[] = { RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)| PKTCTRL1_APPEND_STATUS| PKTCTRL1_ADR_CHK_NONE), - RF_PKTCTRL0_OFF, (RF_PKTCTRL0_PKT_FORMAT_NORMAL| + RF_PKTCTRL0_OFF, (RF_PKTCTRL0_WHITE_DATA| + RF_PKTCTRL0_PKT_FORMAT_NORMAL| RF_PKTCTRL0_LENGTH_CONFIG_FIXED), RF_ADDR_OFF, 0x00, RF_MCSM2_OFF, (RF_MCSM2_RX_TIME_END_OF_PACKET), -- cgit v1.2.3 From 293a357911090a2f37bdd6f7ea96942079ffdf2e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:29:42 -0700 Subject: Add CRC to radio packets --- target/radio/init.c | 1 + target/radio/recv.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/target/radio/init.c b/target/radio/init.c index 6843ef9a..6349e16d 100644 --- a/target/radio/init.c +++ b/target/radio/init.c @@ -159,6 +159,7 @@ static __code uint8_t radio_setup[] = { PKTCTRL1_ADR_CHK_NONE), RF_PKTCTRL0_OFF, (RF_PKTCTRL0_WHITE_DATA| RF_PKTCTRL0_PKT_FORMAT_NORMAL| + RF_PKTCTRL0_CRC_EN| RF_PKTCTRL0_LENGTH_CONFIG_FIXED), RF_ADDR_OFF, 0x00, RF_MCSM2_OFF, (RF_MCSM2_RX_TIME_END_OF_PACKET), diff --git a/target/radio/recv.c b/target/radio/recv.c index 17a3d178..1f50d8a9 100644 --- a/target/radio/recv.c +++ b/target/radio/recv.c @@ -53,8 +53,10 @@ main () break; /* get excited if the packet came through correctly */ - if (i == PACKET_LEN) { - for (i = 0; i < 3; i++){ + if (i == PACKET_LEN && + packet[PACKET_LEN+1] & PKT_APPEND_STATUS_1_CRC_OK) + { + for (i = 0; i < 5; i++){ P1 = 2; delay(100); P1 = 0; -- cgit v1.2.3 From 31fce622b1bab7e3f421069d7f6d4d9bdcd825de Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Apr 2009 10:32:45 -0700 Subject: Enable FEC in radio packets --- target/radio/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/radio/init.c b/target/radio/init.c index 6349e16d..c9b3d186 100644 --- a/target/radio/init.c +++ b/target/radio/init.c @@ -117,7 +117,7 @@ static __code uint8_t radio_setup[] = { RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF | RF_MDMCFG2_MOD_FORMAT_GFSK | RF_MDMCFG2_SYNC_MODE_15_16_THRES), - RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_DIS | + RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN | RF_MDMCFG1_NUM_PREAMBLE_4 | (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)), RF_MDMCFG0_OFF, (17 << RF_MDMCFG0_CHANSPC_M_SHIFT), -- cgit v1.2.3 From 837c620f07b63efc171be3ac14c78bc99adf7592 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 Apr 2009 14:25:43 -0700 Subject: Shrink USB output buffers, work around USB packet errors --- lib/cc-usb.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/cc-usb.c b/lib/cc-usb.c index 9df2e312..2efe572e 100644 --- a/lib/cc-usb.c +++ b/lib/cc-usb.c @@ -31,7 +31,11 @@ #define CC_NUM_READ 16 -#define CC_BUF 1024 +/* + * AltOS has different buffer sizes for in/out packets + */ +#define CC_IN_BUF 256 +#define CC_OUT_BUF 64 #define DEFAULT_TTY "/dev/ttyACM0" struct cc_read { @@ -41,9 +45,9 @@ struct cc_read { struct cc_usb { int fd; - uint8_t in_buf[CC_BUF]; + uint8_t in_buf[CC_IN_BUF]; int in_count; - uint8_t out_buf[CC_BUF]; + uint8_t out_buf[CC_OUT_BUF]; int out_count; struct cc_read read_buf[CC_NUM_READ]; int read_count; @@ -167,7 +171,7 @@ cc_usb_sync(struct cc_usb *cc) else timeout = 0; fds.events = 0; - if (cc->in_count < CC_BUF) + if (cc->in_count < CC_IN_BUF) fds.events |= POLLIN; if (cc->out_count) fds.events |= POLLOUT; @@ -180,12 +184,13 @@ cc_usb_sync(struct cc_usb *cc) } if (fds.revents & POLLIN) { ret = read(cc->fd, cc->in_buf + cc->in_count, - CC_BUF - cc->in_count); + CC_IN_BUF - cc->in_count); if (ret > 0) { cc_usb_dbg(24, cc->in_buf + cc->in_count, ret); cc->in_count += ret; cc_handle_in(cc); - } + } else if (ret < 0) + perror("read"); } if (fds.revents & POLLOUT) { ret = write(cc->fd, cc->out_buf, @@ -196,7 +201,8 @@ cc_usb_sync(struct cc_usb *cc) cc->out_buf + ret, cc->out_count - ret); cc->out_count -= ret; - } + } else if (ret < 0) + perror("write"); } } } @@ -221,13 +227,13 @@ cc_usb_printf(struct cc_usb *cc, char *format, ...) b = buf; while (ret > 0) { this_time = ret; - if (this_time > CC_BUF - cc->out_count) - this_time = CC_BUF - cc->out_count; + if (this_time > CC_OUT_BUF - cc->out_count) + this_time = CC_OUT_BUF - cc->out_count; memcpy(cc->out_buf + cc->out_count, b, this_time); cc->out_count += this_time; ret -= this_time; b += this_time; - while (cc->out_count >= CC_BUF) + while (cc->out_count >= CC_OUT_BUF) cc_usb_sync(cc); } } -- cgit v1.2.3 From 8a9a3f02b951382573ff74dd6ce5a1c0f335fa86 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 27 May 2009 21:53:15 -0700 Subject: Add aoload to load serial-numbered altos binaries. aoload is a custom version of ccload which edits the data before sending it to the target machine, writing the target serial number into the data. Signed-off-by: Keith Packard --- Makefile.am | 2 +- aoload/Makefile.am | 10 +++ aoload/aoload.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 1 + 4 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 aoload/Makefile.am create mode 100644 aoload/aoload.c diff --git a/Makefile.am b/Makefile.am index ee3d2924..86f2fad5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ccload s51 ccmanual ccdump +SUBDIRS=lib ccload s51 ccmanual ccdump aoload diff --git a/aoload/Makefile.am b/aoload/Makefile.am new file mode 100644 index 00000000..2e32c0b9 --- /dev/null +++ b/aoload/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS=aoload + +AM_CFLAGS=-I$(top_srcdir)/lib $(LIBUSB_CFLAGS) +AOLOAD_LIBS=../lib/libcc.a + +aoload_DEPENDENCIES = $(AOLOAD_LIBS) + +aoload_LDADD=$(AOLOAD_LIBS) $(LIBUSB_LIBS) + +aoload_SOURCES = aoload.c diff --git a/aoload/aoload.c b/aoload/aoload.c new file mode 100644 index 00000000..a36ad375 --- /dev/null +++ b/aoload/aoload.c @@ -0,0 +1,231 @@ +/* + * 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 +#include +#include +#include "ccdbg.h" + +#define AO_USB_DESC_STRING 3 + +void +usage(char *program) +{ + fprintf(stderr, "usage: %s \n", program); + exit(1); +} + +struct sym { + unsigned addr; + char *name; +} serial_symbols[] = { + { 0, "_ao_serial_number" }, +#define AO_SERIAL_NUMBER (serial_symbols[0].addr) + { 0, "_ao_usb_descriptors" }, +#define AO_USB_DESCRIPTORS (serial_symbols[1].addr) +}; + +#define NUM_SERIAL_SYMBOLS (sizeof(serial_symbols)/sizeof(serial_symbols[0])) + +static int +find_symbols(FILE *map) +{ + char line[2048]; + char *addr, *addr_end; + char *name; + char *save; + char *colon; + unsigned long a; + int s; + int found = 0; + + while (fgets(line, sizeof(line), map) != NULL) { + line[sizeof(line)-1] = '\0'; + addr = strtok_r(line, " \t\n", &save); + if (!addr) + continue; + name = strtok_r(NULL, " \t\n", &save); + if (!name) + continue; + colon = strchr (addr, ':'); + if (!colon) + continue; + a = strtoul(colon+1, &addr_end, 16); + if (a == ULONG_MAX || addr_end == addr) + continue; + for (s = 0; s < NUM_SERIAL_SYMBOLS; s++) + if (!strcmp(serial_symbols[s].name, name)) { + serial_symbols[s].addr = (unsigned) a; + ++found; + break; + } + } + return found == NUM_SERIAL_SYMBOLS; +} + +static int +rewrite(struct hex_image *image, unsigned addr, char *data, int len) +{ + int i; + if (addr < image->address || image->address + image->length < addr + len) + return 0; + printf("rewrite %04x:", addr); + for (i = 0; i < len; i++) + printf (" %02x", image->data[addr - image->address + i]); + printf(" ->"); + for (i = 0; i < len; i++) + printf (" %02x", data[i]); + printf("\n"); + memcpy(image->data + addr - image->address, data, len); +} + +int +main (int argc, char **argv) +{ + struct ccdbg *dbg; + uint8_t status; + uint16_t pc; + struct hex_file *hex; + struct hex_image *image; + char *filename; + FILE *file; + FILE *map; + char *serial_string; + unsigned int serial; + char *mapname, *dot; + char *serial_ucs2; + int serial_ucs2_len; + char serial_int[2]; + unsigned int s; + int i; + unsigned usb_descriptors; + int string_num; + + filename = argv[1]; + if (filename == NULL) + usage(argv[0]); + mapname = strdup(filename); + dot = strrchr(mapname, '.'); + if (!dot || strcmp(dot, ".ihx") != 0) + usage(argv[0]); + strcpy(dot, ".map"); + + serial_string = argv[2]; + if (serial_string == NULL) + usage(argv[0]); + + file = fopen(filename, "r"); + if (!file) { + perror(filename); + exit(1); + } + map = fopen(mapname, "r"); + if (!map) { + perror(mapname); + exit(1); + } + if (!find_symbols(map)) { + fprintf(stderr, "Cannot find symbols in \"%s\"\n", mapname); + exit(1); + } + fclose(map); + + hex = ccdbg_hex_file_read(file, filename); + fclose(file); + if (!hex) { + perror(filename); + exit (1); + } + image = ccdbg_hex_image_create(hex); + if (!image) { + fprintf(stderr, "image create failed\n"); + exit (1); + } + ccdbg_hex_file_free(hex); + + serial = strtoul(serial_string, NULL, 0); + if (!serial) + usage(argv[0]); + + serial_int[0] = serial & 0xff; + serial_int[1] = (serial >> 8) & 0xff; + + if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { + fprintf(stderr, "Cannot rewrite serial integer at %04x\n", + AO_SERIAL_NUMBER); + exit(1); + } + + usb_descriptors = AO_USB_DESCRIPTORS - image->address; + string_num = 0; + while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) { + if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) { + ++string_num; + if (string_num == 4) + break; + } + usb_descriptors += image->data[usb_descriptors]; + } + if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) { + fprintf(stderr, "Cannot rewrite serial string at %04x\n", AO_USB_DESCRIPTORS); + exit(1); + } + + serial_ucs2_len = image->data[usb_descriptors] - 2; + serial_ucs2 = malloc(serial_ucs2_len); + if (!serial_ucs2) { + fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); + exit(1); + } + s = serial; + for (i = serial_ucs2_len / 2; i; i--) { + serial_ucs2[i * 2 - 1] = 0; + serial_ucs2[i * 2 - 2] = (s % 10) + '0'; + s /= 10; + } + if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len)) + usage(argv[0]); + + dbg = ccdbg_open(); + if (!dbg) + exit (1); + + ccdbg_add_debug(CC_DEBUG_FLASH); + + ccdbg_debug_mode(dbg); + ccdbg_halt(dbg); + if (image->address == 0xf000) { + printf("Loading %d bytes to execute from RAM\n", + image->length); + ccdbg_write_hex_image(dbg, image, 0); + } else if (image->address == 0x0000) { + printf("Loading %d bytes to execute from FLASH\n", + image->length); + ccdbg_flash_hex_image(dbg, image); + } else { + printf("Cannot load code to 0x%04x\n", + image->address); + ccdbg_hex_image_free(image); + ccdbg_close(dbg); + exit(1); + } + ccdbg_set_pc(dbg, image->address); + ccdbg_resume(dbg); + ccdbg_close(dbg); + exit (0); +} diff --git a/configure.ac b/configure.ac index 1d4720a6..6c8963c4 100644 --- a/configure.ac +++ b/configure.ac @@ -99,4 +99,5 @@ ccload/Makefile s51/Makefile ccmanual/Makefile ccdump/Makefile +aoload/Makefile ]) -- cgit v1.2.3