X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=cctools%2Flib%2Fcc-usb.c;fp=cctools%2Flib%2Fcc-usb.c;h=0000000000000000000000000000000000000000;hp=81309983fd46b7487aaba7cabc005051373322be;hb=9789ca5e8caa9a013e804f307b9da380e147bd75;hpb=a5782398d968e7cb11f7203afada7c216f233b3b diff --git a/cctools/lib/cc-usb.c b/cctools/lib/cc-usb.c deleted file mode 100644 index 81309983..00000000 --- a/cctools/lib/cc-usb.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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 -/* - * 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++); - cc_usb_sync(cc); - 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\nm 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); -}