struct cc_hex_read hex_buf[CC_NUM_HEX_READ];
int hex_count;
+ int show_input;
int remote;
};
static void
cc_usb_dbg(int indent, uint8_t *bytes, int len)
{
- int eol = 1;
+ static int eol = 1;
int i;
uint8_t c;
+ ccdbg_debug(CC_DEBUG_BITBANG, "<<<%d bytes>>>", len);
while (len--) {
c = *bytes++;
if (eol) {
}
switch (c) {
case '\r':
- ccdbg_debug(CC_DEBUG_BITBANG, "^M");
+ ccdbg_debug(CC_DEBUG_BITBANG, "\\r");
break;
case '\n':
eol = 1;
+ ccdbg_debug(CC_DEBUG_BITBANG, "\\n\n");
+ break;
default:
- ccdbg_debug(CC_DEBUG_BITBANG, "%c", c);
+ if (c < ' ' || c > '~')
+ ccdbg_debug(CC_DEBUG_BITBANG, "\\%02x", c);
+ else
+ ccdbg_debug(CC_DEBUG_BITBANG, "%c", c);
}
}
}
*/
static int
-_cc_usb_sync(struct cc_usb *cc, int wait_for_input)
+_cc_usb_sync(struct cc_usb *cc, int wait_for_input, int write_timeout)
{
int ret;
struct pollfd fds;
fds.fd = cc->fd;
for (;;) {
if (cc->hex_count || cc->out_count)
- timeout = 5000;
+ timeout = write_timeout;
else if (wait_for_input && cc->in_pos == cc->in_count)
timeout = wait_for_input;
else
cc->in_count += ret;
if (cc->hex_count)
cc_handle_hex_read(cc);
+ if (cc->show_input && cc->in_count) {
+ write(2, cc->in_buf, cc->in_count);
+ cc->in_count = 0;
+ }
} else if (ret < 0)
perror("read");
}
void
cc_usb_sync(struct cc_usb *cc)
{
- if (_cc_usb_sync(cc, 0) < 0) {
+ if (_cc_usb_sync(cc, 0, 5000) < 0) {
fprintf(stderr, "USB link timeout\n");
exit(1);
}
}
int
-cc_usb_getchar(struct cc_usb *cc)
+cc_usb_getchar_timeout(struct cc_usb *cc, int timeout)
{
while (cc->in_pos == cc->in_count) {
- if (_cc_usb_sync(cc, 5000) < 0) {
+ if (_cc_usb_sync(cc, timeout, 5000) < 0) {
fprintf(stderr, "USB link timeout\n");
exit(1);
}
return cc->in_buf[cc->in_pos++];
}
+int
+cc_usb_getchar(struct cc_usb *cc)
+{
+ return cc_usb_getchar_timeout(cc, 5000);
+}
+
void
cc_usb_getline(struct cc_usb *cc, char *line, int max)
{
cc_usb_printf(cc, "\nc F %d\nc c %s\np\nE 0\n", freq, call);
do {
cc->in_count = cc->in_pos = 0;
- _cc_usb_sync(cc, 100);
+ _cc_usb_sync(cc, 100, 5000);
} while (cc->in_count > 0);
cc->remote = 1;
}
static struct termios save_termios;
+#include <errno.h>
+
struct cc_usb *
cc_usb_open(char *tty)
{
struct cc_usb *cc;
struct termios termios;
+ int i;
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) {
+ i = 0;
+ for (;;) {
+ cc->fd = open(tty, O_RDWR | O_NONBLOCK);
+ if (cc->fd >= 0)
+ break;
+ i++;
+ if (errno == EBUSY || errno == EPERM || errno == EACCES) {
+ fprintf(stderr, "open failed, pausing");
+ perror(tty);
+ if (i < 20) {
+ sleep(3);
+ continue;
+ }
+ }
+
perror(tty);
free (cc);
return NULL;
tcgetattr(cc->fd, &termios);
save_termios = termios;
cfmakeraw(&termios);
+ cfsetospeed(&termios, B9600);
+ cfsetispeed(&termios, B9600);
tcsetattr(cc->fd, TCSAFLUSH, &termios);
cc_usb_printf(cc, "\nE 0\nm 0\n");
do {
cc->in_count = cc->in_pos = 0;
- _cc_usb_sync(cc, 100);
+ _cc_usb_sync(cc, 100, 5000);
} while (cc->in_count > 0);
return cc;
}
close (cc->fd);
free (cc);
}
+
+int
+cc_usb_write(struct cc_usb *cc, void *buf, int c)
+{
+ uint8_t *b;
+ int this_time;
+
+ b = buf;
+ cc->show_input = 1;
+ while (c > 0) {
+ this_time = c;
+ 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;
+ c -= this_time;
+ b += this_time;
+ while (cc->out_count >= CC_OUT_BUF) {
+ _cc_usb_sync(cc, 0, -1);
+ }
+ }
+ return 1;
+}