summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-01-05 10:35:20 -0800
committerKeith Packard <keithp@keithp.com>2013-01-05 10:35:20 -0800
commit746ae98829a0fc15577ae0f7b506112178f481e3 (patch)
tree946297b0cfa2f968195918735f3db65e7c72408c
parentca284d8bef2f4bd360eaec58048ba9abdafc55bd (diff)
Add separate code path for listing FTDI devices
This lets the library do different things for FTDI devices, as is required on Windows (for instance) Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--libaltos/libaltos.c102
-rw-r--r--libaltos/libaltos.h3
2 files changed, 83 insertions, 22 deletions
diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c
index 24c20179..505b3147 100644
--- a/libaltos/libaltos.c
+++ b/libaltos/libaltos.c
@@ -606,6 +606,12 @@ altos_list_start(void)
return devs;
}
+PUBLIC struct altos_list *
+altos_ftdi_list_start(void)
+{
+ return altos_list_start();
+}
+
int
altos_list_next(struct altos_list *list, struct altos_device *device)
{
@@ -785,6 +791,7 @@ no_file:
struct altos_list {
io_iterator_t iterator;
+ int ftdi;
};
static int
@@ -842,8 +849,21 @@ altos_list_start(void)
int i;
ret = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary, &list->iterator);
- if (ret != kIOReturnSuccess)
+ if (ret != kIOReturnSuccess) {
+ free(list);
return NULL;
+ }
+ list->ftdi = 0;
+ return list;
+}
+
+PUBLIC struct altos_list *
+altos_ftdi_list_start(void)
+{
+ struct altos_list *list = altos_list_start();
+
+ if (list)
+ list->ftdi = 1;
return list;
}
@@ -861,10 +881,15 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
if (!get_number (object, CFSTR(kUSBVendorID), &device->vendor) ||
!get_number (object, CFSTR(kUSBProductID), &device->product))
continue;
- if (device->vendor != 0xfffe)
- continue;
- if (device->product < 0x000a || 0x0013 < device->product)
- continue;
+ if (list->ftdi) {
+ if (device->vendor != 0x0403)
+ continue;
+ } else {
+ if (device->vendor != 0xfffe)
+ continue;
+ if (device->product < 0x000a || 0x0013 < device->product)
+ continue;
+ }
if (get_string (object, CFSTR("IOCalloutDevice"), device->path, sizeof (device->path)) &&
get_string (object, CFSTR("USB Product Name"), device->name, sizeof (device->name)) &&
get_string (object, CFSTR("USB Serial Number"), serial_string, sizeof (serial_string))) {
@@ -935,6 +960,7 @@ altos_bt_open(struct altos_bt_device *device)
struct altos_list {
HDEVINFO dev_info;
int index;
+ int ftdi;
};
#define USB_BUF_SIZE 64
@@ -985,6 +1011,26 @@ altos_list_start(void)
return NULL;
}
list->index = 0;
+ list->ftdi = 0;
+ return list;
+}
+
+PUBLIC struct altos_list *
+altos_ftdi_list_start(void)
+{
+ struct altos_list *list = calloc(1, sizeof (struct altos_list));
+
+ if (!list)
+ return NULL;
+ list->dev_info = SetupDiGetClassDevs(NULL, "FTDIBUS", NULL,
+ DIGCF_ALLCLASSES|DIGCF_PRESENT);
+ if (list->dev_info == INVALID_HANDLE_VALUE) {
+ altos_set_last_windows_error();
+ free(list);
+ return NULL;
+ }
+ list->index = 0;
+ list->ftdi = 1;
return list;
}
@@ -1019,24 +1065,30 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
continue;
}
- /* Fetch symbolic name for this device and parse out
- * the vid/pid/serial info */
- symbolic_len = sizeof(symbolic);
- result = RegQueryValueEx(dev_key, "SymbolicName", NULL, NULL,
- symbolic, &symbolic_len);
- if (result != 0) {
- altos_set_last_windows_error();
- printf("cannot find SymbolicName value\n");
- RegCloseKey(dev_key);
- continue;
+ if (list->ftdi) {
+ vid = 0x0403;
+ pid = 0x6015;
+ serial = 0;
+ } else {
+ /* Fetch symbolic name for this device and parse out
+ * the vid/pid/serial info */
+ symbolic_len = sizeof(symbolic);
+ result = RegQueryValueEx(dev_key, "SymbolicName", NULL, NULL,
+ symbolic, &symbolic_len);
+ if (result != 0) {
+ altos_set_last_windows_error();
+ printf("cannot find SymbolicName value\n");
+ RegCloseKey(dev_key);
+ continue;
+ }
+ vid = pid = serial = 0;
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
+ "%04X", &vid);
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
+ "%04X", &pid);
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
+ "%d", &serial);
}
- vid = pid = serial = 0;
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
- "%04X", &vid);
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
- "%04X", &pid);
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
- "%d", &serial);
/* Fetch the com port name */
port_len = sizeof (port);
@@ -1203,6 +1255,7 @@ altos_open(struct altos_device *device)
struct altos_file *file = calloc (1, sizeof (struct altos_file));
char full_name[64];
COMMTIMEOUTS timeouts;
+ DCB dcb;
if (!file)
return NULL;
@@ -1228,6 +1281,11 @@ altos_open(struct altos_device *device)
timeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(file->handle, &timeouts);
+ if (GetCommState(file->handle, &dcb)) {
+ dcb.BaudRate = CBR_9600;
+ (void) SetCommState(file->handle, &dcb);
+ }
+
return file;
}
diff --git a/libaltos/libaltos.h b/libaltos/libaltos.h
index f90fbb87..6d43159b 100644
--- a/libaltos/libaltos.h
+++ b/libaltos/libaltos.h
@@ -73,6 +73,9 @@ altos_get_last_error(struct altos_error *error);
PUBLIC struct altos_list *
altos_list_start(void);
+PUBLIC struct altos_list *
+altos_ftdi_list_start(void);
+
/* Returns 1 for success, zero on end of list */
PUBLIC int
altos_list_next(struct altos_list *list, struct altos_device *device);