diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 21 | ||||
-rw-r--r-- | lib/cc-bitbang.c | 269 | ||||
-rw-r--r-- | lib/cc-bitbang.h | 94 | ||||
-rw-r--r-- | lib/cc-usb.c | 359 | ||||
-rw-r--r-- | lib/cc-usb.h | 59 | ||||
-rw-r--r-- | lib/cccp.c | 112 | ||||
-rw-r--r-- | lib/cccp.h | 41 | ||||
-rw-r--r-- | lib/ccdbg-command.c | 176 | ||||
-rw-r--r-- | lib/ccdbg-debug.c | 63 | ||||
-rw-r--r-- | lib/ccdbg-debug.h | 44 | ||||
-rw-r--r-- | lib/ccdbg-flash.c | 356 | ||||
-rw-r--r-- | lib/ccdbg-hex.c | 330 | ||||
-rw-r--r-- | lib/ccdbg-io.c | 137 | ||||
-rw-r--r-- | lib/ccdbg-manual.c | 77 | ||||
-rw-r--r-- | lib/ccdbg-memory.c | 179 | ||||
-rw-r--r-- | lib/ccdbg-rom.c | 63 | ||||
-rw-r--r-- | lib/ccdbg-state.c | 128 | ||||
-rw-r--r-- | lib/ccdbg.h | 341 | ||||
-rw-r--r-- | lib/cp-usb-async.c | 188 | ||||
-rw-r--r-- | lib/cp-usb-async.h | 38 | ||||
-rw-r--r-- | lib/cp-usb.c | 157 | ||||
-rw-r--r-- | lib/cp-usb.h | 36 |
22 files changed, 0 insertions, 3268 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index 4d9ded3a..00000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -noinst_LIBRARIES = libcc.a - -AM_CFLAGS=$(WARN_CFLAGS) $(LIBUSB_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 \ - 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 deleted file mode 100644 index 1d3ba476..00000000 --- a/lib/cc-bitbang.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright © 2009 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include <time.h> -#include <stdio.h> -#include <stdlib.h> -#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 deleted file mode 100644 index 54b20e2c..00000000 --- a/lib/cc-bitbang.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2009 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _CC_BITBANG_H_ -#define _CC_BITBANG_H_ - -#include <stdint.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) - -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 deleted file mode 100644 index dc764c24..00000000 --- a/lib/cc-usb.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright © 2009 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdarg.h> -#include <poll.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <termios.h> -#include "ccdbg-debug.h" -#include "cc-usb.h" - - -#define CC_NUM_READ 16 -/* - * 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 { - uint8_t *buf; - int len; -}; - -struct cc_usb { - int fd; - uint8_t in_buf[CC_IN_BUF]; - int in_count; - uint8_t out_buf[CC_OUT_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_IN_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_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, - 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; - } else if (ret < 0) - perror("write"); - } - } -} - -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_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_OUT_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; -} - -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(char *tty) -{ - struct cc_usb *cc; - struct termios termios; - - 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 deleted file mode 100644 index d7acfbd2..00000000 --- a/lib/cc-usb.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright © 2009 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _CC_USB_H_ -#define _CC_USB_H_ - -#include <stdint.h> - -struct cc_usb; - -struct cc_usb * -cc_usb_open(char *tty); - -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); - -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_ */ diff --git a/lib/cccp.c b/lib/cccp.c deleted file mode 100644 index 34e866e8..00000000 --- a/lib/cccp.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -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; -} - -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/cccp.h b/lib/cccp.h deleted file mode 100644 index eecdbb49..00000000 --- a/lib/cccp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -/* - * 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 deleted file mode 100644 index a1002879..00000000 --- a/lib/ccdbg-command.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -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) -{ - 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 -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); -} - -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) -{ - 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]); - 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; -} - -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); - ccdbg_debug(CC_DEBUG_EXECUTE, "pc starts at 0x%04x\n", pc); - status = ccdbg_resume(dbg); - ccdbg_debug(CC_DEBUG_EXECUTE, "resume status: 0x%02x\n", status); - return 0; -} diff --git a/lib/ccdbg-debug.c b/lib/ccdbg-debug.c deleted file mode 100644 index 6eb4e0c5..00000000 --- a/lib/ccdbg-debug.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include <stdarg.h> - -int -ccdbg_level = 0; - -void -ccdbg_add_debug(int level) -{ - ccdbg_level |= level; -} - -void -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); - va_end(ap); - } -} - -void -ccdbg_flush(int level) -{ - if (ccdbg_level & level) - fflush(stdout); -} diff --git a/lib/ccdbg-debug.h b/lib/ccdbg-debug.h deleted file mode 100644 index 0b5b44c1..00000000 --- a/lib/ccdbg-debug.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#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(int level); - -#endif /* _CCDBG_DEBUG_H_ */ diff --git a/lib/ccdbg-flash.c b/lib/ccdbg-flash.c deleted file mode 100644 index 3e672985..00000000 --- a/lib/ccdbg-flash.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -/* 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); - ccdbg_debug(CC_DEBUG_FLASH, "erase status 0x%02x\n", status); - do { - status = ccdbg_execute(dbg, flash_read_control); - 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++) - ccdbg_debug(CC_DEBUG_FLASH, "0x%02x -> 0x%02x\n", old[i], new[i]); - status = ccdbg_execute(dbg, flash_control_clear); - ccdbg_debug(CC_DEBUG_FLASH, "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]; - 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); - 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); - ccdbg_debug(CC_DEBUG_FLASH, "clear fctl 0x%02x\n", status); - ccdbg_read_memory(dbg, addr, check, 2); - for (i = 0; i < 2; i++) - ccdbg_debug(CC_DEBUG_FLASH, "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); - 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; -} -#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_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) { - 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; - 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)); - - remain = image->length; - start = 0; - while (remain) { - this_time = remain; - if (this_time > 0x400) - this_time = 0x400; - - offset = ram_addr - (image->address + start); - - 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; - 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_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, "Flashing %d bytes at 0x%04x\n", - this_time, flash_addr); - status = ccdbg_resume(dbg); - for (times = 0; times < 10; times++) { - status = ccdbg_read_status(dbg); - 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; - } - - 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; - } - return 0; -} diff --git a/lib/ccdbg-hex.c b/lib/ccdbg-hex.c deleted file mode 100644 index dfea9156..00000000 --- a/lib/ccdbg-hex.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include <stdarg.h> -#include <ctype.h> - -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 deleted file mode 100644 index 9c6693cd..00000000 --- a/lib/ccdbg-io.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include <time.h> -#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; - } - 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) { - free(dbg); - return NULL; - } - } - return dbg; -} - -void -ccdbg_close(struct ccdbg *dbg) -{ - if (dbg->usb) - cc_usb_close(dbg->usb); - if (dbg->bb) - cc_bitbang_close(dbg->bb); - free (dbg); -} - -void -ccdbg_debug_mode(struct ccdbg *dbg) -{ - if (dbg->usb) - cc_usb_debug_mode(dbg->usb); - else if (dbg->bb) - cc_bitbang_debug_mode(dbg->bb); -} - -void -ccdbg_reset(struct ccdbg *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) -{ - 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_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes) -{ - 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_sync(struct ccdbg *dbg) -{ - 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) -{ - ccdbg_send_bytes(dbg, &cmd, 1); - ccdbg_send_bytes(dbg, data, len); -} - -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); - ccdbg_sync(dbg); - 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); - 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 deleted file mode 100644 index 0e811b76..00000000 --- a/lib/ccdbg-manual.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include "cc-bitbang.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; - - 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); - 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; - 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"); - } - cc_bitbang_send(dbg->bb, mask, set); - cc_bitbang_sync(dbg->bb); - } -} diff --git a/lib/ccdbg-memory.c b/lib/ccdbg-memory.c deleted file mode 100644 index 554ac637..00000000 --- a/lib/ccdbg-memory.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -/* - * Read and write arbitrary memory through the debug port - */ - -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; - 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; - (void) ccdbg_execute(dbg, memory_init); - for (i = 0; i < nbytes; i++) { - write8[DATA_BYTE] = *bytes++; - ccdbg_execute(dbg, write8); - if ((i & 0xf) == 0xf) { - ccdbg_debug(CC_DEBUG_MEMORY, "."); - ccdbg_flush(CC_DEBUG_MEMORY); - nl = 1; - } - if ((i & 0xff) == 0xff) { - ccdbg_debug(CC_DEBUG_MEMORY, "\n"); - nl = 0; - } - } - ccdbg_state_restore(dbg, &state); - if (nl) - ccdbg_debug(CC_DEBUG_MEMORY, "\n"); - return 0; -} - -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; - } - 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; - (void) ccdbg_execute(dbg, memory_init); - for (i = 0; i < nbytes; i++) { - *bytes++ = ccdbg_execute(dbg, read8); - if ((i & 0xf) == 0xf) { - ccdbg_debug(CC_DEBUG_MEMORY, "."); - ccdbg_flush(CC_DEBUG_MEMORY); - nl = 1; - } - if ((i & 0xff) == 0xff) { - ccdbg_debug(CC_DEBUG_MEMORY, "\n"); - nl = 0; - } - } - ccdbg_state_replace_xmem(dbg, &state, addr, bytes, nbytes); - ccdbg_state_restore(dbg, &state); - if (nl) - ccdbg_debug(CC_DEBUG_MEMORY, "\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; -} - -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; - 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); - } - ccdbg_state_replace_sfr(dbg, &state, addr, bytes, nbytes); - ccdbg_state_restore(dbg, &state); - 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-rom.c b/lib/ccdbg-rom.c deleted file mode 100644 index 71bed220..00000000 --- a/lib/ccdbg-rom.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -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 deleted file mode 100644 index 9aca8d2e..00000000 --- a/lib/ccdbg-state.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" - -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 deleted file mode 100644 index 4a2e3b9f..00000000 --- a/lib/ccdbg.h +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _CCDBG_H_ -#define _CCDBG_H_ - -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <stdint.h> -#include <assert.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include "ccdbg-debug.h" -#include "cc-bitbang.h" -#include "cc-usb.h" - -/* 8051 instructions - */ -#define NOP 0x00 -#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_direct1_direct2 0x85 -#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 JB 0x20 - -/* 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 -#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)) - -/* Bit-addressable status word */ -#define PSW(bit) (0xD0 | (bit)) - -struct ccdbg { - struct cc_bitbang *bb; - struct cc_usb *usb; - struct hex_image *rom; -}; - -/* Intel hex file format data - */ -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 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 - -/* CC1111 debug port commands - */ -#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 - -/* 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); - -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); - -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-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 */ -struct ccdbg * -ccdbg_open(void); - -void -ccdbg_close(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); - -void -ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd, - uint8_t *data, int len, uint8_t *reply); - -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_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes); - -void -ccdbg_sync(struct ccdbg *dbg); - -/* 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); - -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); - -/* 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/lib/cp-usb-async.c b/lib/cp-usb-async.c deleted file mode 100644 index 6539394b..00000000 --- a/lib/cp-usb-async.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#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; - uint8_t value; - uint8_t set; -}; - -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); - cp->ack = -1; - if (!cp->handle) { - libusb_exit(cp->ctx); - free(cp); - return NULL; - } - cp->value = 0; - cp->set = 0; - 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; - 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; - 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 = -1; -} diff --git a/lib/cp-usb-async.h b/lib/cp-usb-async.h deleted file mode 100644 index 976a320e..00000000 --- a/lib/cp-usb-async.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _CP_USB_ASYNC_H_ -#define _CP_USB_ASYNC_H_ -#include <libusb.h> - -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/lib/cp-usb.c b/lib/cp-usb.c deleted file mode 100644 index 530848db..00000000 --- a/lib/cp-usb.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -/* - * 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 <stdio.h> -#include <errno.h> -#include <libusb.h> - -struct cp_usb { - usb_dev_handle *usb_dev; - uint8_t gpio; -}; - -#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 cp_usb *cp, uint8_t *gpio_get) -{ - return usb_control_msg(cp->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 cp_usb *cp, uint8_t mask, uint8_t value) -{ - uint16_t gpio_set = ((uint16_t) value << 8) | mask; - - return usb_control_msg(cp->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 cp_usb *cp, uint16_t enable) -{ - return usb_control_msg(cp->usb_dev, - CP2101_UART, - REQTYPE_HOST_TO_DEVICE, - enable, - 0, - NULL, - 0, - 300); -} - -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; - 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"); - 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); - 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_close(struct cp_usb *cp) -{ - cp_usb_uart_enable_disable(cp, UART_DISABLE); - usb_close(cp->usb_dev); - free(cp); -} - -void -cp_usb_write(struct cp_usb *cp, uint8_t mask, uint8_t value) -{ - uint8_t new_gpio; - int ret; - - 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"); - cp->gpio = new_gpio; - } -} - -uint8_t -cp_usb_read(struct cp_usb *cp) -{ - int ret; - uint8_t gpio; - - ret = cp_usb_gpio_get(cp, &gpio); - if (ret < 0) - perror("gpio_get"); - return gpio; -} diff --git a/lib/cp-usb.h b/lib/cp-usb.h deleted file mode 100644 index 3e5f25ff..00000000 --- a/lib/cp-usb.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _CP_USB_H_ -#define _CP_USB_H_ -#include <usb.h> - -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 |