diff options
Diffstat (limited to 'spectro/icoms_ux.c')
-rwxr-xr-x[-rw-r--r--] | spectro/icoms_ux.c | 163 |
1 files changed, 91 insertions, 72 deletions
diff --git a/spectro/icoms_ux.c b/spectro/icoms_ux.c index 8fd1b3e..7fb7359 100644..100755 --- a/spectro/icoms_ux.c +++ b/spectro/icoms_ux.c @@ -98,7 +98,7 @@ int icompaths_refresh_paths(icompaths *p) { /* Find all the matching serial ports */ for (;;) { char pname[200]; - int fast = 0; + icom_ser_attr sattr = icom_normal; CFTypeRef dfp; /* Device file path */ @@ -122,19 +122,19 @@ int icompaths_refresh_paths(icompaths *p) { /* Would be nice to identify FTDI serial ports more specifically ? */ if (strstr(pname, "usbserial") != NULL) - fast = 1; + sattr |= icom_fast; #ifndef ENABLE_SERIAL - if (fast) { /* Only add fast ports if !ENABLE_SERIAL */ + if (sattr & icom_fast) { /* Only add fast ports if !ENABLE_SERIAL */ #endif /* Add the port to the list */ - p->add_serial(p, pname, pname, fast); - a1logd(p->log, 8, "icoms_get_paths: Added path '%s' fast %d\n",pname, fast); + p->add_serial(p, pname, pname, sattr); + a1logd(p->log, 8, "icoms_get_paths: Added path '%s' attr 0x%x\n",pname, sattr); #ifndef ENABLE_SERIAL } #endif /* If fast, try and identify it */ - if (fast) { + if (sattr & icom_fast) { icompath *path; icoms *icom; if ((path = p->get_last_path(p)) != NULL @@ -217,7 +217,7 @@ int icompaths_refresh_paths(icompaths *p) { for (;;) { int fd; char *dpath; - int fast = 0; + icom_ser_attr sattr = icom_normal; if ((de = readdir(dd)) == NULL) break; @@ -271,21 +271,21 @@ int icompaths_refresh_paths(icompaths *p) { a1logd(p->log, 8, "icoms_get_paths: open'd serial \"%s\" - assume real\n",dpath); if (strncmp(de->d_name, "ttyUSB", 5) == 0) - fast = 1; + sattr |= icom_fast; #ifndef ENABLE_SERIAL - if (fast) { /* Only add fast ports if !ENABLE_SERIAL */ + if (sattr & icom_fast) { /* Only add fast ports if !ENABLE_SERIAL */ #endif /* Add the path to the list */ p->add_serial(p, dpath, dpath, 0); - a1logd(p->log, 8, "icoms_get_paths: Added path '%s' fast %d\n",dpath,fast); + a1logd(p->log, 8, "icoms_get_paths: Added path '%s' attr 0x%x\n",dpath,sattr); #ifndef ENABLE_SERIAL } #endif free(dpath); /* If fast, try and identify it */ - if (fast) { + if (sattr & icom_fast) { icompath *path; icoms *icom; if ((path = p->get_last_path(p)) != NULL @@ -630,17 +630,21 @@ char *wbuf, /* null terminated unless nwch > 0 */ int nwch, /* if > 0, number of characters to write */ double tout ) { - int rv, retrv = ICOM_OK; int len, wbytes; - long toc, i, top; /* Timout count, counter, timeout period */ + long ttop, top; /* Total timeout period, timeout period */ + unsigned int stime, etime; /* Start and end times of USB operation */ struct pollfd pa[1]; /* Poll array to monitor serial write and stdin */ int nfd = 1; /* Number of fd's to poll */ struct termios origs, news; + int retrv = ICOM_OK; + + a1logd(p->log, 8, "\nicoms_ser_write: writing '%s'\n", + nwch > 0 ? icoms_tohex((unsigned char *)wbuf, nwch) : icoms_fix(wbuf)); if (!p->is_open) { a1loge(p->log, ICOM_SYS, "icoms_ser_write: device not initialised\n"); - p->lserr = rv = ICOM_SYS; - return rv; + p->lserr = ICOM_SYS; + return p->lserr; } /* Setup to wait for serial output not block */ @@ -648,52 +652,56 @@ double tout pa[0].events = POLLOUT; pa[0].revents = 0; - /* Until timed out, aborted, or transmitted */ if (nwch != 0) len = nwch; else len = strlen(wbuf); - tout *= 1000.0; /* Timout in msec */ - a1logd(p->log, 8, "icoms_ser_write: About to write %d bytes",len); - top = 100; /* Timeout period in msecs */ - toc = (int)(tout/top + 0.5); /* Number of timout periods in timeout */ - if (toc < 1) - toc = 1; + ttop = (int)(tout * 1000.0 + 0.5); /* Total timeout period in msecs */ + + a1logd(p->log, 8, "\nicoms_ser_write: ep 0x%x, bytes %d, ttop %d, quant %d\n", p->rd_ep, len, ttop, p->rd_qa); + + etime = stime = msec_time(); + + /* Until data is all written or we time out */ + for (top = ttop; top > 0 && len > 0;) { + + if (poll_x(pa, nfd, top) > 0) { /* Wait for something */ - /* Until data is all written, we time out, or the user aborts */ - for(i = toc; i > 0 && len > 0;) { - if (poll_x(pa, nfd, top) > 0) { if (pa[0].revents != 0) { if (pa[0].revents != POLLOUT) { a1loge(p->log, ICOM_SYS, "icoms_ser_write: poll returned " "unexpected value 0x%x",pa[0].revents); - p->lserr = rv = ICOM_SYS; - return rv; + p->lserr = ICOM_SYS; + return p->lserr; } /* We can write it without blocking */ - if ((wbytes = write(p->fd, wbuf, len)) < 0) { + wbytes = write(p->fd, wbuf, len); + if (wbytes < 0) { + a1logd(p->log, 8, "icoms_ser_write: write failed with %d\n",wbytes); retrv |= ICOM_SERW; break; + } else if (wbytes > 0) { - i = toc; + a1logd(p->log, 8, "icoms_ser_write: wrote %d bytes\n",wbytes); len -= wbytes; wbuf += wbytes; } } - } else { - i--; /* timeout (or error!) */ } - } - if (i <= 0) { /* Timed out */ - retrv |= ICOM_TO; + etime = msec_time(); + top = ttop - (etime - stime); /* Remaining time */ } - a1logd(p->log, 8, "icoms_ser_write: returning ICOM err 0x%x\n",retrv); + if (top <= 0) { /* Must have timed out */ + a1logd(p->log, 8, "icoms_ser_write: timeout, took %d msec out of %d\n",etime - stime,ttop); + retrv |= ICOM_TO; + } + a1logd(p->log, 8, "icoms_ser_write: took %d msec, returning ICOM err 0x%x\n",etime - stime,retrv); p->lserr = retrv; - return retrv; + return p->lserr; } /* Read characters into the buffer */ @@ -709,69 +717,71 @@ char *tc, /* Terminating characers, NULL for none or char count mode */ int ntc, /* Number of terminating characters or char count needed, if 0 use bsize */ double tout /* Time out in seconds */ ) { - int rv, retrv = ICOM_OK; - int rbytes; - long j, toc, i, top; /* Timout count, counter, timeout period */ + int j, rbytes; + long ttop, top; /* Total timeout period, timeout period */ + unsigned int stime, etime; /* Start and end times of USB operation */ struct pollfd pa[1]; /* Poll array to monitor serial read and stdin */ int nfd = 1; /* Number of fd's to poll */ struct termios origs, news; char *rrbuf = rbuf; /* Start of return buffer */ int bread = 0; + int retrv = ICOM_OK; + int nreads; /* Number of reads performed */ if (!p->is_open) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: device not initialised\n"); - p->lserr = rv = ICOM_SYS; - return rv; + p->lserr = ICOM_SYS; + return p->lserr; } if (bsize < 3) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: given too small a buffer\n"); - p->lserr = rv = ICOM_SYS; - return rv; + p->lserr = ICOM_SYS; + return p->lserr; } - a1logd(p->log, 8, "icoms_ser_read: About to read buf %d, tc %p ntc %d tout %f",bsize,tc,ntc,tout); + for (j = 0; j < bsize; j++) + rbuf[j] = 0; + + ttop = (int)(tout * 1000.0 + 0.5); /* Total timeout period in msecs */ + + a1logd(p->log, 8, "\nicoms_ser_read: bytes %d, ttop %d, ntc %d\n", bsize, ttop, ntc); /* Wait for serial input to have data */ pa[0].fd = p->fd; pa[0].events = POLLIN | POLLPRI; pa[0].revents = 0; - bsize--; /* Allow space for forced null */ - tout *= 1000.0; /* Timout in msec */ - - top = 100; /* Timeout period in msecs */ - toc = (int)(tout/top + 0.5); /* Number of timout periods in timeout */ - if (toc < 1) - toc = 1; + bsize -=1; /* Allow space for forced null */ - if (tc == NULL) { /* no tc or char count mode */ - j = -1; - if (ntc > 0 && ntc < bsize) - bsize = ntc; /* Don't read more than ntc */ - } else { - j = 0; - } /* Until data is all read, we time out, or the user aborts */ - for (i = toc; i > 0 && bsize > 0 && j < ntc ;) { + etime = stime = msec_time(); + j = (tc == NULL && ntc <= 0) ? -1 : 0; + + /* Until data is all read or we time out */ + for (top = ttop, nreads = 0; top > 0 && bsize > 0 && j < ntc ;) { + if (poll_x(pa, nfd, top) > 0) { if (pa[0].revents != 0) { int btr; if (pa[0].revents != POLLIN && pa[0].revents != POLLPRI) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: poll on serin returned " "unexpected value 0x%x",pa[0].revents); - p->lserr = rv = ICOM_SYS; - return rv; + p->lserr = ICOM_SYS; + return p->lserr; } /* We have data to read from input */ - if ((rbytes = read(p->fd, rbuf, bsize)) < 0) { + rbytes = read(p->fd, rbuf, bsize); + if (rbytes < 0) { + a1logd(p->log, 8, "icoms_ser_read: read failed with %d, rbuf = '%s'\n",rbytes,icoms_fix(rrbuf)); retrv |= ICOM_SERR; break; + } else if (rbytes > 0) { - i = toc; /* Reset time */ + a1logd(p->log, 8, "icoms_ser_read: read %d bytes, rbuf = '%s'\n",rbytes,icoms_fix(rrbuf)); + bsize -= rbytes; - bread += rbytes; if (tc != NULL) { while(rbytes--) { /* Count termination characters */ char ch = *rbuf++, *tcp = tc; @@ -782,6 +792,7 @@ double tout /* Time out in seconds */ tcp++; } } + a1logd(p->log, 8, "icoms_ser_read: tc count %d\n",j); } else { if (ntc > 0) j += rbytes; @@ -789,22 +800,30 @@ double tout /* Time out in seconds */ } } } - } else { - i--; /* We timed out (or error!) */ } + etime = msec_time(); + top = ttop - (etime - stime); /* Remaining time */ } - if (i <= 0) /* timed out */ - retrv |= ICOM_TO; - *rbuf = '\000'; + a1logd(p->log, 8, "icoms_ser_read: read %d total bytes with %d reads\n",rbuf - rrbuf, nreads); if (pbread != NULL) - *pbread = bread; + *pbread = (rbuf - rrbuf); + + /* If ran out of time and not completed */ + a1logd(p->log, 8, "icoms_ser_read: took %d msec\n",etime - stime); + if (top <= 0 && bsize > 0 && j < ntc) { + a1logd(p->log, 8, "icoms_ser_read: timeout, took %d msec out of %d\n",etime - stime,ttop); + retrv |= ICOM_TO; + } - a1logd(p->log, 8, "icoms_ser_read: returning '%s' ICOM err 0x%x\n",icoms_fix(rrbuf),retrv); + a1logd(p->log, 8, "icoms_ser_read: took %d msec, returning '%s' ICOM err 0x%x\n", + etime - stime, tc == NULL && ntc > 0 + ? icoms_tohex((unsigned char *)rrbuf, rbuf - rrbuf) + : icoms_fix(rrbuf), retrv); p->lserr = retrv; - return retrv; + return p->lserr; } #endif /* ENABLE_SERIAL */ |