From 746ae98829a0fc15577ae0f7b506112178f481e3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Jan 2013 10:35:20 -0800 Subject: [PATCH 1/1] 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 --- libaltos/libaltos.c | 102 ++++++++++++++++++++++++++++++++++---------- libaltos/libaltos.h | 3 ++ 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); -- 2.30.2