libaltos: Need to check for tty/ttyACMx before ttyACMx
[fw/altos] / libaltos / libaltos.c
index 6e884c80ea145eeb576955d7d703f6a43f2d94af..ca56746a643d8cd0de773ceb180e0c2ea95320b3 100644 (file)
@@ -116,7 +116,6 @@ altos_open(struct altos_device *device)
                return NULL;
        }
 
-       printf ("open\n");
 //     altos_set_last_error(12, "yeah yeah, failed again");
 //     free(file);
 //     return NULL;
@@ -479,26 +478,26 @@ usb_tty(char *sys)
                                return tty;
                        }
 
-                       /* Check for ttyACMx style names
+                       /* Check for tty/ttyACMx style names
                         */
-                       ntty = scandir(endpoint_full, &namelist,
+                       tty_dir = cc_fullname(endpoint_full, "tty");
+                       ntty = scandir(tty_dir, &namelist,
                                       dir_filter_tty,
                                       alphasort);
+                       free (tty_dir);
                        if (ntty > 0) {
-                               free(endpoint_full);
                                tty = cc_fullname("/dev", namelist[0]->d_name);
+                               free(endpoint_full);
                                free(namelist);
                                return tty;
                        }
 
-                       /* Check for tty/ttyACMx style names
+                       /* Check for ttyACMx style names
                         */
-                       tty_dir = cc_fullname(endpoint_full, "tty");
-                       free(endpoint_full);
-                       ntty = scandir(tty_dir, &namelist,
+                       ntty = scandir(endpoint_full, &namelist,
                                       dir_filter_tty,
                                       alphasort);
-                       free (tty_dir);
+                       free(endpoint_full);
                        if (ntty > 0) {
                                tty = cc_fullname("/dev", namelist[0]->d_name);
                                free(namelist);
@@ -607,12 +606,17 @@ 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)
 {
        struct altos_usbdev *dev;
        if (list->current >= list->ndev) {
-               printf ("end\n");
                return 0;
        }
        dev = list->dev[list->current];
@@ -787,6 +791,7 @@ no_file:
 
 struct altos_list {
        io_iterator_t iterator;
+       int ftdi;
 };
 
 static int
@@ -844,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;
 }
 
@@ -863,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))) {
@@ -937,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
@@ -987,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;
 }
 
@@ -1021,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);
@@ -1205,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;
@@ -1230,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;
 }