summaryrefslogtreecommitdiff
path: root/spectro/icoms_ux.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/icoms_ux.c')
-rw-r--r--spectro/icoms_ux.c146
1 files changed, 98 insertions, 48 deletions
diff --git a/spectro/icoms_ux.c b/spectro/icoms_ux.c
index 722492e..3e49f3e 100644
--- a/spectro/icoms_ux.c
+++ b/spectro/icoms_ux.c
@@ -46,6 +46,10 @@
#include <mach/task_policy.h>
#endif /* __APPLE__ */
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+instType fast_ser_inst_type(icoms *p, int tryhard, void *, void *);
+#endif /* ENABLE_SERIAL */
+
/* Create and return a list of available serial ports or USB instruments for this system */
/* return icom error */
int icompaths_refresh_paths(icompaths *p) {
@@ -65,7 +69,7 @@ int icompaths_refresh_paths(icompaths *p) {
#endif /* ENABLE_USB */
usbend = p->npaths;
-#ifdef ENABLE_SERIAL
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
#ifdef __APPLE__
/* Search the OSX registry for serial ports */
{
@@ -93,7 +97,8 @@ int icompaths_refresh_paths(icompaths *p) {
/* Find all the matching serial ports */
for (;;) {
- char pname[100];
+ char pname[200];
+ int fast = 0;
CFTypeRef dfp; /* Device file path */
@@ -115,10 +120,26 @@ int icompaths_refresh_paths(icompaths *p) {
|| strstr(pname, "Bluetooth") != NULL)
goto continue2;
- /* Add the port to the list */
- p->add_serial(p, pname, pname);
- a1logd(p->log, 8, "icoms_get_paths: Added path '%s'\n",pname);
+ /* Would be nice to identify FTDI serial ports more specifically ? */
+ if (strstr(pname, "usbserial") != NULL)
+ fast = 1;
+ /* 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);
+
+ /* If fast, try and identify it */
+ if (fast) {
+ icompath *path;
+ icoms *icom;
+ if ((path = p->get_last_path(p)) != NULL
+ && (icom = new_icoms(path, p->log)) != NULL) {
+ instType itype = fast_ser_inst_type(icom, 0, NULL, NULL);
+ if (itype != instUnknown)
+ icompaths_set_serial_itype(path, itype);
+ icom->del(icom);
+ }
+ }
continue2:
CFRelease(dfp);
continue1:
@@ -177,6 +198,7 @@ int icompaths_refresh_paths(icompaths *p) {
*/
/* Search for devices that match the pattern /dev/ttyS[0-9]* and /dev/ttyUSB* */
+ /* We will assume that ttyUSB* ports includes FTDI ports */
{
DIR *dd;
struct dirent *de;
@@ -190,6 +212,7 @@ int icompaths_refresh_paths(icompaths *p) {
for (;;) {
int fd;
char *dpath;
+ int fast = 0;
if ((de = readdir(dd)) == NULL)
break;
@@ -242,9 +265,26 @@ 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;
+
/* Add the path to the list */
- p->add_serial(p, dpath, dpath);
- a1logd(p->log, 8, "icoms_get_paths: Added path '%s'\n",dpath);
+ p->add_serial(p, dpath, dpath, 0);
+ a1logd(p->log, 8, "icoms_get_paths: Added path '%s' fast %d\n",dpath,fast);
+ free(dpath);
+
+ /* If fast, try and identify it */
+ if (fast) {
+ icompath *path;
+ icoms *icom;
+ if ((path = p->get_last_path(p)) != NULL
+ && (icom = new_icoms(path, p->log)) != NULL) {
+ instType itype = fast_ser_inst_type(icom, 0, NULL, NULL);
+ if (itype != instUnknown)
+ icompaths_set_serial_itype(path, itype);
+ icom->del(icom);
+ }
+ }
}
closedir(dd);
}
@@ -252,12 +292,13 @@ int icompaths_refresh_paths(icompaths *p) {
#endif /* ENABLE_SERIAL */
/* Sort the serial /dev keys so people don't get confused... */
- /* Sort USB serial ports ahead of normal serial ports. */
+ /* Sort identified instruments ahead of unknown serial ports */
for (i = usbend; i < (p->npaths-1); i++) {
for (j = i+1; j < p->npaths; j++) {
- if ((strncmp(p->paths[i]->name, "/dev/ttyUSB", 11) ||
- strncmp(p->paths[j]->name, "/dev/ttyS", 9)) &&
- strcmp(p->paths[i]->name, p->paths[j]->name) > 0) {
+ if ((p->paths[i]->itype == instUnknown && p->paths[j]->itype != instUnknown)
+ || (((p->paths[i]->itype == instUnknown && p->paths[j]->itype == instUnknown)
+ || (p->paths[i]->itype != instUnknown && p->paths[j]->itype != instUnknown))
+ && strcmp(p->paths[i]->name, p->paths[j]->name) > 0)) {
icompath *tt = p->paths[i];
p->paths[i] = p->paths[j];
p->paths[j] = tt;
@@ -279,7 +320,7 @@ static void icoms_close_port(icoms *p) {
hid_close_port(p);
}
#endif
-#ifdef ENABLE_SERIAL
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
if (p->fd != -1) {
close(p->fd);
p->fd = -1;
@@ -289,10 +330,20 @@ static void icoms_close_port(icoms *p) {
}
}
-#ifdef ENABLE_SERIAL
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
static int icoms_ser_write(icoms *p, char *wbuf, double tout);
-static int icoms_ser_read(icoms *p, char *rbuf, int bsize, char tc, int ntc, double tout);
+static int icoms_ser_read(icoms *p, char *rbuf, int bsize, char *tc, int ntc, double tout);
+
+
+#ifdef __APPLE__
+# ifndef IOSSIOSPEED
+# define IOSSIOSPEED _IOW('T', 2, speed_t)
+# endif
+# ifndef B921600
+# define B921600 921600
+# endif
+#endif
/* Set the serial port number and characteristics */
/* This always re-opens the port */
@@ -344,7 +395,7 @@ word_length word
a1logd(p->log, 8, "icoms_set_ser_port: about to open serial port '%s'\n",p->spath);
if ((p->fd = open(p->spath, O_RDWR | O_NOCTTY )) < 0) {
- a1loge(p->log, ICOM_SYS, "icoms_set_ser_port: open port '%s' failed with %d (%s)\n",p->spath,p->fd,strerror(errno));
+ a1logd(p->log, 1, "icoms_set_ser_port: open port '%s' failed with %d (%s)\n",p->spath,p->fd,strerror(errno));
return ICOM_SYS;
}
/* O_NONBLOCK O_SYNC */
@@ -490,6 +541,9 @@ word_length word
case baud_115200:
speed = B115200;
break;
+ case baud_921600:
+ speed = B921600;
+ break;
default:
close(p->fd);
a1loge(p->log, ICOM_SYS, "icoms_set_ser_port: illegal baud rate! (0x%x)\n",p->br);
@@ -498,6 +552,15 @@ word_length word
tcflush(p->fd, TCIOFLUSH); /* Discard any current in/out data */
+#ifdef NEVER
+ // for osx >= 10.4 ? or >= 10.3 ??
+ // Doesn't actually seem to be needed... ??
+ if (speed > B115200) {
+ if (ioctl(p->fd, IOSSIOSPEED, &speed ) == -1)
+ printf( "Error %d calling ioctl( ..., IOSSIOSPEED, ... )\n", errno );
+
+ }
+#endif
if ((rv = cfsetispeed(&tio, speed)) < 0) {
close(p->fd);
a1loge(p->log, ICOM_SYS, "icoms_set_ser_port: cfsetispeed failed with '%s'\n", strerror(errno));
@@ -611,7 +674,7 @@ icoms_ser_read(
icoms *p,
char *rbuf, /* Buffer to store characters read */
int bsize, /* Buffer size */
-char tc, /* Terminating characer */
+char *tc, /* Terminating characers, NULL for none */
int ntc, /* Number of terminating characters */
double tout /* Time out in seconds */
) {
@@ -635,34 +698,6 @@ double tout /* Time out in seconds */
return rv;
}
-#ifdef NEVER
- /* The Prolific 2303 USB<->serial seems to choke on this, */
- /* so we just put up with the 100msec delay at the end of each reply. */
- if (tc != p->tc) { /* Set the termination char */
- struct termios tio;
-
- if (tcgetattr(p->fd, &tio) < 0) {
- a1loge(p->log, ICOM_SYS, "icoms_ser_read: tcgetattr failed with '%s' on '%s'\n",
- strerror(errno),p->spath);
- p->lserr = rv = ICOM_SYS;
- return rv;
- }
-
- tio.c_cc[VEOL] = tc;
-
- /* Make change immediately */
- tcflush(p->fd, TCIFLUSH);
- if (tcsetattr(p->fd, TCSANOW, &tio) < 0) {
- a1loge(p->log, ICOM_SYS, "icoms_ser_read: tcsetattr failed with '%s' on '%s'\n",
- strerror(errno),p->spath);
- p->lserr = rv = ICOM_SYS;
- return rv;
- }
-
- p->tc = tc;
- }
-#endif
-
/* Wait for serial input to have data */
pa[0].fd = p->fd;
pa[0].events = POLLIN | POLLPRI;
@@ -695,10 +730,18 @@ double tout /* Time out in seconds */
} else if (rbytes > 0) {
i = toc; /* Reset time */
bsize -= rbytes;
- while(rbytes--) { /* Count termination characters */
- if (*rbuf++ == tc)
- j++;
- }
+ if (tc != NULL) {
+ while(rbytes--) { /* Count termination characters */
+ char ch = *rbuf++, *tcp = tc;
+
+ while(*tcp != '\000') {
+ if (ch == *tcp)
+ j++;
+ tcp++;
+ }
+ }
+ } else
+ rbuf += rbytes;
}
}
} else {
@@ -733,6 +776,13 @@ icoms_del(icoms *p) {
usb_del_usb(p);
hid_del_hid(p);
#endif
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+ if (p->spath != NULL)
+ free(p->spath);
+#endif
+ p->log = del_a1log(p->log);
+ if (p->name != NULL)
+ free(p->name);
p->log = del_a1log(p->log);
free (p);
}