cell ft_open_serial (cell devidx, cell pid) { ft_handle fh = ftdi_new(); ft_errno = ftdi_usb_open_desc_index(fh, 0x0403, pid, NULL, NULL, devidx); if (ft_errno) { return (cell)NULL; } ftdi_set_baudrate(fh, 115200); ftdi_set_line_property(fh, BITS_8, STOP_BIT_1, NONE); ftdi_setflowctrl(fh, SIO_DISABLE_FLOW_CTRL); ftdi_set_latency_timer(fh, 1); com_ops_t *ops = malloc(sizeof(com_ops_t)); ops->handle = (cell)fh; ops->close = ft_close; ops->get_modem_control = ft_get_modem_control; ops->set_modem_control = ft_set_modem_control; ops->set_baud = ft_set_baud; ops->set_parity = ft_set_parity; ops->write = ft_write; ops->timed_read = ft_timed_read; return (cell)ops; }
int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index) { // translate empty strings to NULL // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM) const char* c_description=NULL; const char* c_serial=NULL; if (!description.empty()) c_description=description.c_str(); if (!serial.empty()) c_serial=serial.c_str(); int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index); if (ret < 0) return ret; return get_strings_and_reopen(); }
static int ft245r_open(PROGRAMMER * pgm, char * port) { int rv; int devnum = -1; rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true); if(rv) { pgm->display(pgm, progbuf); return rv; } strcpy(pgm->port, port); if (strcmp(port,DEFAULT_USB) != 0) { if (strncasecmp("ft", port, 2) == 0) { char *startptr = port + 2; char *endptr = NULL; devnum = strtol(startptr,&endptr,10); if ((startptr==endptr) || (*endptr != '\0')) { devnum = -1; } } if (devnum < 0) { avrdude_message(MSG_INFO, "%s: invalid portname '%s': use 'ft[0-9]+'\n", progname,port); return -1; } } else { devnum = 0; } handle = malloc (sizeof (struct ftdi_context)); ftdi_init(handle); LNODEID usbpid = lfirst(pgm->usbpid); int pid; if (usbpid) { pid = *(int *)(ldata(usbpid)); if (lnext(usbpid)) avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n", progname, pid); } else { pid = USB_DEVICE_FT245; } rv = ftdi_usb_open_desc_index(handle, pgm->usbvid?pgm->usbvid:USB_VENDOR_FTDI, pid, pgm->usbproduct[0]?pgm->usbproduct:NULL, pgm->usbsn[0]?pgm->usbsn:NULL, devnum); if (rv) { avrdude_message(MSG_INFO, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle)); goto cleanup_no_usb; } ft245r_ddr = pgm->pin[PIN_AVR_SCK].mask[0] | pgm->pin[PIN_AVR_MOSI].mask[0] | pgm->pin[PIN_AVR_RESET].mask[0] | pgm->pin[PPI_AVR_BUFF].mask[0] | pgm->pin[PPI_AVR_VCC].mask[0] | pgm->pin[PIN_LED_ERR].mask[0] | pgm->pin[PIN_LED_RDY].mask[0] | pgm->pin[PIN_LED_PGM].mask[0] | pgm->pin[PIN_LED_VFY].mask[0]; /* set initial values for outputs, no reset everything else is off */ ft245r_out = 0; ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0); ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0); rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang if (rv) { avrdude_message(MSG_INFO, "%s: Synchronous BitBangMode is not supported (%s)\n", progname, ftdi_get_error_string(handle)); goto cleanup; } rv = ft245r_set_bitclock(pgm); if (rv) { goto cleanup; } /* We start a new thread to read the output from the FTDI. This is * necessary because otherwise we'll deadlock. We cannot finish * writing because the ftdi cannot send the results because we * haven't provided a read buffer yet. */ sem_init (&buf_data, 0, 0); sem_init (&buf_space, 0, BUFSIZE); pthread_create (&readerthread, NULL, reader, handle); /* * drain any extraneous input */ ft245r_drain (pgm, 0); ft245r_send (pgm, &ft245r_out, 1); ft245r_recv (pgm, &ft245r_in, 1); return 0; cleanup: ftdi_usb_close(handle); cleanup_no_usb: ftdi_deinit (handle); free(handle); handle = NULL; return -1; }
int CKMotionIO::Connect() { char reason[256]; int ftStatus; if (NonRespondingCount==CONNECT_TRIES) return 1; m_SaveChars[0]=0; // start anew Mutex->Lock(); if (!RequestedDeviceAvail(reason)) { ErrorMessageBox(reason); Mutex->Unlock(); return 1; } #define TIME_TO_TRY_TO_OPEN 3000 // FT_ListDevices OK, number of devices connected is in numDevs // usually during boot the board comes and goes, since it appeared // to be there, try for a while to open it DWORD t0=timeGetTime(); for (;;) { ftStatus = ftdi_usb_open_desc_index(ftdi, VENDOR, PRODUCT, NULL, NULL, USB_Loc_ID); if (ftStatus < FT_OK) { log_info("ftdi_usb_open_desc_index failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi)); // FT_Open failed if (timeGetTime()-t0 > TIME_TO_TRY_TO_OPEN) { ErrorMessageBox("Unable to open KMotion device"); Mutex->Unlock(); return 1; } Sleep(100); // delay a bit then loop back and try again } else { // FT_Open OK, use ftHandle to access device if (SetLatency(2)) { //Close handle if(_ftdi_usb_close(ftdi) < FT_OK){ log_info("_ftdi_usb_close failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi)); } Mutex->Unlock(); return 1; } if (FlushInputBuffer()) { log_info("FAIL: FlushInputBuffer for device %d",USB_Loc_ID); //This is the key to why it works on second attempt //After usb_close has executed once the device works forever. //The ftdi device is not closed when killing the KMotionServer //Try to recover from this action when initialising this class. if(_ftdi_usb_close(ftdi) < FT_OK){ log_info("_ftdi_usb_close failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi)); } Mutex->Unlock(); return 1; } m_Connected=true; // All set Mutex->Unlock(); return 0; } } Mutex->Unlock(); return 0; }