int init_rs485(struct rs485_data_t *rs485_data) { int ret; rs485_data->ftdi = ftdi_new(); if (!rs485_data->ftdi) { fprintf(stderr, "ftdi_new failed\n"); return -1; } /* check for FT232RL device */ if ((ret = ftdi_usb_open(rs485_data->ftdi, 0x0403, 0x6001)) < 0) { fprintf(stderr, "unable to open FTDI device: %d (%s)\n", ret, ftdi_get_error_string(rs485_data->ftdi)); ftdi_free(rs485_data->ftdi); return EXIT_FAILURE; } if ((ret = ftdi_set_baudrate(rs485_data->ftdi, rs485_data->speed)) < 0) { fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(rs485_data->ftdi)); ftdi_free(rs485_data->ftdi); return EXIT_FAILURE; } if ((ret = ftdi_setflowctrl(rs485_data->ftdi, SIO_DISABLE_FLOW_CTRL)) < 0) { fprintf(stderr, "unable to set flow control: %d (%s)\n", ret, ftdi_get_error_string(rs485_data->ftdi)); return EXIT_FAILURE; } return 0; }
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; }
static int dmx_init(struct ftdi_context* ftdic) { int ret; if (ftdi_init(ftdic) < 0) { fprintf(stderr, "ftdi_init failed\n"); return EXIT_FAILURE; } if ((ret = ftdi_usb_open(ftdic, 0x0403, 0x6001)) < 0) { fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_set_baudrate(ftdic, 250000)) < 0) { fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_set_line_property(ftdic, BITS_8, STOP_BIT_2, NONE)) < 0) { fprintf(stderr, "unable to set line property: %d (%s)\n", ret, ftdi_get_error_string(ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_setflowctrl(ftdic, SIO_DISABLE_FLOW_CTRL)) < 0) { fprintf(stderr, "unable to set flow control: %d (%s)\n", ret, ftdi_get_error_string(ftdic)); return EXIT_FAILURE; } return EXIT_SUCCESS; }
int spectrig_connect(struct ftdi_context *ftdi) { int ret; ftdi_init(ftdi); /* TODO: Be a bit more selective and support multiple devices properly */ ret = open_by_desc_prefix(ftdi, 0x0403, 0x6010, spectrig_descs); if (ret < 0) { perror("Failed to open the device"); return ret; } ftdi_usb_purge_buffers(ftdi); /* Initialize synchronous communication */ ret = ftdi_set_latency_timer(ftdi, 2); if (ret < 0) { perror("Failed to set the latency timer"); goto close; } ret = ftdi_read_data_set_chunksize(ftdi, 0x10000); if (ret < 0) { perror("Failed to set read data chunksize"); goto close; } ret = ftdi_write_data_set_chunksize(ftdi, 0x10000); if (ret < 0) { perror("Failed to write read data chunksize"); goto close; } ret = ftdi_setflowctrl(ftdi, SIO_RTS_CTS_HS); if (ret < 0) { perror("Failed to set flow control"); goto close; } msleep(20); ret = ftdi_set_bitmode(ftdi, 0xff, 0x00); if (ret < 0) { perror("Failed to set bitmode 0x00"); goto close; } msleep(20); ftdi_set_bitmode(ftdi, 0xff, 0x40); if (ret < 0) { perror("Failed to set bitmode 0x40"); goto close; } msleep(300); ftdi_usb_purge_buffers(ftdi); return 0; close: ftdi_usb_close(ftdi); ftdi_deinit(ftdi); return ret; }
bool FalconCommLibFTDI::setFirmwareMode() { unsigned int bytes_written, bytes_read; unsigned char check_msg_1_send[3] = {0x0a, 0x43, 0x0d}; unsigned char check_msg_1_recv[4] = {0x0a, 0x44, 0x2c, 0x0d}; unsigned char check_msg_2[1] = {0x41}; unsigned char send_buf[128], receive_buf[128]; int k; if(!m_isCommOpen) { m_errorCode = FALCON_COMM_DEVICE_NOT_VALID_ERROR; return false; } //Save ourselves having to reset this on every error m_errorCode = FALCON_COMM_DEVICE_ERROR; //Clear out current buffers to make sure we have a fresh start if((m_deviceErrorCode = ftdi_usb_purge_buffers((m_falconDevice))) < 0) return false; //Reset the device if((m_deviceErrorCode = ftdi_usb_reset((m_falconDevice))) < 0) return false; //Make sure our latency timer is at 16ms, otherwise firmware checks tend to always fail if((m_deviceErrorCode = ftdi_set_latency_timer((m_falconDevice), 16)) < 0) return false; //Set to: // 9600 baud // 8n1 // No Flow Control // RTS Low // DTR High if((m_deviceErrorCode = ftdi_set_baudrate((m_falconDevice), 9600)) < 0) return false; if((m_deviceErrorCode = ftdi_set_line_property((m_falconDevice), BITS_8, STOP_BIT_1, NONE)) < 0) return false; if((m_deviceErrorCode = ftdi_setflowctrl((m_falconDevice), SIO_DISABLE_FLOW_CTRL)) < 0) return false; if((m_deviceErrorCode = ftdi_setrts((m_falconDevice), 0)) < 0) return false; if((m_deviceErrorCode = ftdi_setdtr((m_falconDevice), 0)) < 0) return false; if((m_deviceErrorCode = ftdi_setdtr((m_falconDevice), 1)) < 0) return false; //Send 3 bytes: 0x0a 0x43 0x0d if(!write(check_msg_1_send, 3)) return false; if(!read(receive_buf, 4)) return false; //Set to: // DTR Low // 140000 baud (0x15 clock ticks per signal) if((m_deviceErrorCode = ftdi_setdtr((m_falconDevice),0)) < 0) return false; if((m_deviceErrorCode = ftdi_set_baudrate((m_falconDevice), 140000)) < 0) return false; //Send "A" character if(!write(check_msg_2, 1)) return false; //Expect back 2 bytes: // 0x13 0x41 if(!read(receive_buf, 2)) return false; m_errorCode = 0; return true; }
static int dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; int ret; if (!(devc = sdi->priv)) return SR_ERR_BUG; /* Allocate memory for the FTDI context and initialize it. */ if (!(devc->ftdic = ftdi_new())) { sr_err("Failed to initialize libftdi."); return SR_ERR; } sr_dbg("Opening %s device (%04x:%04x).", devc->prof->modelname, devc->usb_vid, devc->usb_pid); /* Open the device. */ if ((ret = ftdi_usb_open_desc(devc->ftdic, devc->usb_vid, devc->usb_pid, devc->prof->iproduct, NULL)) < 0) { sr_err("Failed to open FTDI device (%d): %s.", ret, ftdi_get_error_string(devc->ftdic)); goto err_ftdi_free; } sr_dbg("Device opened successfully."); /* Purge RX/TX buffers in the FTDI chip. */ if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) { sr_err("Failed to purge FTDI buffers (%d): %s.", ret, ftdi_get_error_string(devc->ftdic)); goto err_ftdi_free; } sr_dbg("FTDI buffers purged successfully."); /* Enable flow control in the FTDI chip. */ if ((ret = ftdi_setflowctrl(devc->ftdic, SIO_RTS_CTS_HS)) < 0) { sr_err("Failed to enable FTDI flow control (%d): %s.", ret, ftdi_get_error_string(devc->ftdic)); goto err_ftdi_free; } sr_dbg("FTDI flow control enabled successfully."); /* Wait 100ms. */ g_usleep(100 * 1000); sdi->status = SR_ST_ACTIVE; if (ret == SR_OK) return SR_OK; err_ftdi_free: ftdi_free(devc->ftdic); /* Close device (if open), free FTDI context. */ devc->ftdic = NULL; return ret; }
QString LibFTDIInterface::readLabel(uchar label, int *ESTA_code) { if (ftdi_usb_open_desc(&m_handle, DMXInterface::FTDIVID, DMXInterface::FTDIPID, name().toLatin1().data(), serial().toLatin1().data()) < 0) return QString(); if (ftdi_usb_reset(&m_handle) < 0) return QString(); if (ftdi_set_baudrate(&m_handle, 250000) < 0) return QString(); if (ftdi_set_line_property(&m_handle, BITS_8, STOP_BIT_2, NONE) < 0) return QString(); if (ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) < 0) return QString(); QByteArray request; request.append(ENTTEC_PRO_START_OF_MSG); request.append(label); request.append(ENTTEC_PRO_DMX_ZERO); // data length LSB request.append(ENTTEC_PRO_DMX_ZERO); // data length MSB request.append(ENTTEC_PRO_END_OF_MSG); if (ftdi_write_data(&m_handle, (uchar*) request.data(), request.size()) < 0) { qDebug() << Q_FUNC_INFO << "Cannot write data to device"; return QString(); } uchar *buffer = (uchar*) malloc(sizeof(uchar) * 40); Q_ASSERT(buffer != NULL); QByteArray array; usleep(300000); // give some time to the device to respond int read = ftdi_read_data(&m_handle, buffer, 40); //qDebug() << Q_FUNC_INFO << "Data read: " << read; array = QByteArray::fromRawData((char*) buffer, read); if (array[0] != ENTTEC_PRO_START_OF_MSG) qDebug() << Q_FUNC_INFO << "Reply message wrong start code: " << QString::number(array[0], 16); *ESTA_code = (array[5] << 8) | array[4]; array.remove(0, 6); // 4 bytes of Enttec protocol + 2 of ESTA ID array.replace(ENTTEC_PRO_END_OF_MSG, '\0'); // replace Enttec termination with string termination //for (int i = 0; i < array.size(); i++) // qDebug() << "-Data: " << array[i]; ftdi_usb_close(&m_handle); return QString(array); }
bool QLCFTDI::setFlowControl() { if (ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } }
static int dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; int ret; if (!(devc = sdi->priv)) { sr_err("%s: sdi->priv was NULL.", __func__); return SR_ERR_BUG; } sr_dbg("Opening LA8 device (%04x:%04x).", USB_VENDOR_ID, devc->usb_pid); /* Open the device. */ if ((ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, devc->usb_pid, USB_DESCRIPTION, NULL)) < 0) { sr_err("%s: ftdi_usb_open_desc: (%d) %s", __func__, ret, ftdi_get_error_string(devc->ftdic)); (void) la8_close_usb_reset_sequencer(devc); /* Ignore errors. */ return SR_ERR; } sr_dbg("Device opened successfully."); /* Purge RX/TX buffers in the FTDI chip. */ if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) { sr_err("%s: ftdi_usb_purge_buffers: (%d) %s", __func__, ret, ftdi_get_error_string(devc->ftdic)); (void) la8_close_usb_reset_sequencer(devc); /* Ignore errors. */ goto err_dev_open_close_ftdic; } sr_dbg("FTDI buffers purged successfully."); /* Enable flow control in the FTDI chip. */ if ((ret = ftdi_setflowctrl(devc->ftdic, SIO_RTS_CTS_HS)) < 0) { sr_err("%s: ftdi_setflowcontrol: (%d) %s", __func__, ret, ftdi_get_error_string(devc->ftdic)); (void) la8_close_usb_reset_sequencer(devc); /* Ignore errors. */ goto err_dev_open_close_ftdic; } sr_dbg("FTDI flow control enabled successfully."); /* Wait 100ms. */ g_usleep(100 * 1000); sdi->status = SR_ST_ACTIVE; return SR_OK; err_dev_open_close_ftdic: (void) la8_close(devc); /* Log, but ignore errors. */ return SR_ERR; }
void send_command(struct ftdi_context *ftdi, unsigned char *cmd, unsigned int cmd_len, unsigned char *buf, unsigned int buf_len, int *len, int cr) { int i; int idx = 0; int num; for (i = 0; i < cmd_len; i++) { printf("cmd[%d] %02X\n", i, cmd[i]); ftdi_setflowctrl(ftdi, 0); ftdi_write_data(ftdi, &cmd[i], 1); } while((num = ftdi_read_data(ftdi, buf, buf_len)) > 0) { for (i = 0; i < num; i++) { if (idx == 2 || ((idx - 2) % cr == 0)) { printf("\n"); } printf("%02X ", buf[i]); idx++; } } *len = idx; printf("\n"); }
Ft245sync::Ft245sync(unsigned int chunkSizeRead, unsigned int chunkSizeWrite, uint8_t gpio, struct ftdi_context * vftdic, struct ftdi_context * vftdic2) { if(vftdic == NULL) { this->ftdic = static_cast<struct ftdi_context*>(malloc(sizeof(struct ftdi_context))); } else { this->ftdic = vftdic; } if(vftdic2 == NULL) { this->ftdic2 = static_cast<struct ftdi_context*>(malloc(sizeof(struct ftdi_context))); } else { this->ftdic2 = vftdic2; } int f; // Init 1. channel if (ftdi_init(ftdic) < 0) { throw Exception("ftdi_init failure\n"); } ftdi_set_interface(ftdic, INTERFACE_A); f = ftdi_usb_open(ftdic, 0x0403, PID); if (f < 0 && f != -5) { throw Exception("Unable to open FTDI device, channel A\n"); } // Init 2. channel if (ftdi_init(ftdic2) < 0) { throw Exception("ftdi_init failure\n"); } ftdi_usb_reset(ftdic); ftdi_usb_reset(ftdic2); ftdi_set_interface(ftdic2, INTERFACE_B); f = ftdi_usb_open(ftdic2, 0x0403, PID); if (f < 0 && f != -5) { throw Exception("Unable to open FTDI device, channel B\n"); } ftdi_write_data_set_chunksize(ftdic2, 512); ftdi_set_interface(ftdic2, INTERFACE_B); ftdi_usb_reset(ftdic2); ftdi_set_latency_timer(ftdic2, 2); ftdi_setflowctrl(ftdic2, SIO_RTS_CTS_HS); ftdi_set_bitmode(ftdic2, 0, BBMODE_SPI); uint8_t buf[3]; buf[0] = SET_BITS_LOW; buf[1] = 8; buf[2] = BIT_DIR; //holding programming of FPGA*/ ftdi_write_data(ftdic2, buf, 3); buf[0] = SET_BITS_HIGH; buf[1] = 0xFF; //lighting leds buf[2] = BIT_DIR; ftdi_write_data(ftdic2, buf, 3); buf[0] = SET_BITS_HIGH; buf[1] = 0x00; //lighting leds buf[2] = BIT_DIR; ftdi_write_data(ftdic2, buf, 3); buf[0] = SET_BITS_LOW; buf[1] = gpio; buf[2] = BIT_DIR; //releasing programming of FPGA ftdi_write_data(ftdic2, buf, 3); sleep(1); buf[0] = SET_BITS_LOW; buf[1] = 0xFF; //reseting design in FPGA buf[2] = BIT_DIR; ftdi_write_data(ftdic2, buf, 3); sleep(1); buf[0] = SET_BITS_LOW; buf[1] = 0xDD; //releasing reset buf[2] = BIT_DIR; ftdi_write_data(ftdic2, buf, 3); sleep(1); buf[0] = SET_BITS_HIGH; buf[1] = 0xFF; //lighting leds buf[2] = BIT_DIR; ftdi_write_data(ftdic2, buf, 3); if (ftdi_usb_purge_buffers(ftdic2)) { throw Exception("Purging buffers failed\n"); } ftdi_usb_close(ftdic2); // close channel 2 ftdi_deinit(ftdic2); // close channel 2 ftdic->usb_read_timeout = READ_TIMEOUT; ftdic->usb_write_timeout = WRITE_TIMEOUT; ftdi_read_data_set_chunksize(ftdic, chunkSizeRead); ftdi_write_data_set_chunksize(ftdic, chunkSizeWrite); if (ftdi_usb_reset(ftdic)) { throw Exception("Reset failed\n"); } usleep(1000); if(ftdi_usb_purge_buffers(ftdic) < 0) { throw Exception("Setting FT2232 synchronous bitmode failed\n"); } if(ftdi_set_bitmode(ftdic, 0xFF, 0x00) < 0) { throw Exception("Setting FT2232 synchronous bitmode failed\n"); } if(ftdi_set_bitmode(ftdic, 0xFF, 0x40) < 0) { throw Exception("Setting FT2232 synchronous bitmode failed\n"); } if (ftdi_set_latency_timer(ftdic, 2)) /* AN_130 */ { throw Exception("Set latency failed failed\n"); } //SetUSBParameters(ftHandle,0x10000, 0x10000); if (ftdi_setflowctrl(ftdic, SIO_RTS_CTS_HS)) // AN_130 { throw Exception("Set RTS_CTS failed\n"); } /*if(ftdi_usb_purge_buffers(ftdic) < 0) { throw Exception("Setting FT2232 synchronous bitmode failed\n"); }*/ //fixes unalignment of first read (should be fixed in cleaner manner) usleep(400); unsigned char cleanup[10] = { 0xBB, 0xBB, 0xBB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; ftdi_write_data(ftdic, cleanup, 10); unsigned char recvbuf[4000]; read(recvbuf); }
int FtdiDevice::setFlowControl( FTDI_FLOWCTL_TYPE flowCtl ) const { if ( context_ == 0 ) return RV_DEVICE_NOT_OPEN; int r = ftdi_setflowctrl( context_, flowCtl ); return ( r < 0 ) ? false : true; }
QList<DMXInterface *> LibFTDIInterface::interfaces(QList<DMXInterface *> discoveredList) { QList <DMXInterface*> interfacesList; int id = 0; struct ftdi_context ftdi; ftdi_init(&ftdi); #ifdef LIBFTDI1 libusb_device *dev; libusb_device **devs; struct libusb_device_descriptor dev_descriptor; int i = 0; if (libusb_get_device_list(ftdi.usb_ctx, &devs) < 0) { qDebug() << "usb_find_devices() failed"; return interfacesList; } while ((dev = devs[i++]) != NULL) { libusb_get_device_descriptor(dev, &dev_descriptor); #else struct usb_bus *bus; struct usb_device *dev; struct usb_device_descriptor dev_descriptor; usb_init(); if (usb_find_busses() < 0) { qDebug() << "usb_find_busses() failed"; return interfacesList; } if (usb_find_devices() < 0) { qDebug() << "usb_find_devices() failed"; return interfacesList; } for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { dev_descriptor = dev->descriptor; #endif Q_ASSERT(dev != NULL); // Skip non wanted devices if (validInterface(dev_descriptor.idVendor, dev_descriptor.idProduct) == false) continue; char ser[256]; memset(ser, 0, 256); char nme[256]; char vend[256]; ftdi_usb_get_strings(&ftdi, dev, vend, 256, nme, 256, ser, 256); QString serial(ser); QString name(nme); QString vendor(vend); qDebug() << Q_FUNC_INFO << "DMX USB VID:" << QString::number(dev_descriptor.idVendor, 16) << "PID:" << QString::number(dev_descriptor.idProduct, 16); qDebug() << Q_FUNC_INFO << "DMX USB serial: " << serial << "name:" << name << "vendor:" << vendor; bool found = false; for (int c = 0; c < discoveredList.count(); c++) { if (discoveredList.at(c)->checkInfo(serial, name, vendor) == true) { found = true; break; } } if (found == false) { LibFTDIInterface *iface = new LibFTDIInterface(serial, name, vendor, dev_descriptor.idVendor, dev_descriptor.idProduct, id++); #ifdef LIBFTDI1 iface->setBusLocation(libusb_get_port_number(dev)); #else iface->setBusLocation(dev->bus->location); #endif interfacesList << iface; } #ifndef LIBFTDI1 } #endif } #ifdef LIBFTDI1 libusb_free_device_list(devs, 1); #endif ftdi_deinit(&ftdi); return interfacesList; } bool LibFTDIInterface::open() { if (isOpen() == true) return true; QByteArray sba = serial().toLatin1(); const char *ser = NULL; if (serial().isEmpty() == false) ser = (const char *)sba.data(); if (ftdi_usb_open_desc(&m_handle, vendorID(), productID(), name().toLatin1(), ser) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::openByPID(const int PID) { if (isOpen() == true) return true; if (ftdi_usb_open(&m_handle, DMXInterface::FTDIVID, PID) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::close() { if (ftdi_usb_close(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::isOpen() const { return (m_handle.usb_dev != NULL) ? true : false; } bool LibFTDIInterface::reset() { if (ftdi_usb_reset(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setLineProperties() { if (ftdi_set_line_property(&m_handle, BITS_8, STOP_BIT_2, NONE) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setBaudRate() { if (ftdi_set_baudrate(&m_handle, 250000) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setFlowControl() { if (ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::clearRts() { if (ftdi_setrts(&m_handle, 0) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::purgeBuffers() { if (ftdi_usb_purge_buffers(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setBreak(bool on) { ftdi_break_type type; if (on == true) type = BREAK_ON; else type = BREAK_OFF; if (ftdi_set_line_property2(&m_handle, BITS_8, STOP_BIT_2, NONE, type) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } }
int Context::set_flow_control(int flowctrl) { return ftdi_setflowctrl(d->ftdi, flowctrl); }
// init serial communication device bool CPlatform::initSerial(char*cPort, unsigned int baudrate) { // Windows #ifdef WIN32 if(hSerialPort != INVALID_HANDLE_VALUE) { CloseHandle(hSerialPort); } if(cPort == NULL) { cPort = STDSERIALWINDOWS; } hSerialPort = ::CreateFile(cPort, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(hSerialPort == INVALID_HANDLE_VALUE) { CUtil::cout("initSerial: CreateFile() failed.\n", TEXT_ERROR); return false; } else { CUtil::cout("initSerial: Connected!\n", TEXT_ERROR); } COMMTIMEOUTS timeouts; GetCommTimeouts(hSerialPort, &timeouts); int a = 40; //40 timeouts.ReadIntervalTimeout = a; timeouts.ReadTotalTimeoutMultiplier = 20; timeouts.ReadTotalTimeoutConstant = a; timeouts.WriteTotalTimeoutMultiplier = 20; timeouts.WriteTotalTimeoutConstant = a; SetCommTimeouts(hSerialPort, &timeouts); DCB dcb = {0}; dcb.DCBlength = sizeof(DCB); if(!::GetCommState(hSerialPort, &dcb) ) { CUtil::cout("initSerial: GetCommState() failed.\n", TEXT_ERROR); } else { // 8bit, no parity, one stopbit dcb.BaudRate = baudrate; dcb.ByteSize = 8; dcb.Parity = 0; dcb.StopBits = 0; if(!::SetCommState(hSerialPort, &dcb) ) { CUtil::cout("initSerial: SetCommState() failed.\n", TEXT_ERROR); } } return true; // LINUX #else if(cPort == NULL) { cPort = (char *)STDSERIALLINUX; } #ifdef USE_FTDI /* Still testing */ unsigned char buf [1000]; int a; int rsize; if (ftdi_init(&ftdi) < 0 ) return false; int ret; if((ret = ftdi_usb_open(&ftdi, 0x0403, 0x6001)) < 0) { printf( "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdi)); return EXIT_FAILURE; } // Read out FTDIChip-ID of R type chips if (ftdi.type == TYPE_R) { unsigned int chipid; printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(&ftdi, &chipid)); printf("FTDI chipid: %X\n", chipid); } ftdi_read_data_set_chunksize(&ftdi, 4096); ftdi_write_data_set_chunksize(&ftdi, 4096); ftdi_set_line_property2(&ftdi, BITS_8, STOP_BIT_1, NONE, BREAK_OFF); ftdi_usb_reset (&ftdi); printf("baudrate: %d\n", ftdi_set_baudrate (&ftdi, baudrate)); ftdi_setflowctrl(&ftdi, SIO_DISABLE_FLOW_CTRL); ftdi_set_latency_timer(&ftdi, 1); ftdi_usb_purge_buffers (&ftdi); printf (" Err : %s \n", ftdi.error_str); unsigned char nix[150]; int j = 0; int cr; for (j = 0; j < 10; j++) { cr = ftdi_read_data (&ftdi, &nix[0], 100); printf (" %i \n", cr); } printf ("Typ: %d\n", ftdi.type); printf ("usb_read_timeout: %d\n", ftdi.usb_read_timeout); printf ("usb_write_timeout: %d\n", ftdi.usb_write_timeout); printf ("baudrate: %d\n", ftdi.baudrate); printf ("bitbang_enabled: %x\n", ftdi.bitbang_enabled); printf ("bitbang_mode: %x\n", ftdi.bitbang_mode); return true; /* close handles */ ftdi_usb_close(&ftdi); ftdi_deinit(&ftdi); return false; #endif //system("stty -F /dev/ttyS0 speed 115200 raw cs8"); fdSerialPort = open(cPort, O_RDWR | O_NOCTTY | O_NDELAY);// | O_NONBLOCK | O_NDELAY); if(fdSerialPort == -1) { CUtil::cout("initSerial: open() failed.\n", TEXT_ERROR); return false; } else { CUtil::cout("initSerial: Connected.\n", TEXT_ERROR); } clearLine(); #ifndef SERIALDONTINIT //fcntl(fdSerialPort, F_SETFL, FNDELAY); struct termios options; if(tcgetattr(fdSerialPort, &options) == -1) { CUtil::cout("initSerial: tvgetattr() failed.\n", TEXT_ERROR); } else { options.c_iflag = 0; options.c_oflag = 0; options.c_cflag = 0; options.c_lflag = 0; cfsetispeed(&options, getSpeedConstant(baudrate) ); cfsetospeed(&options, getSpeedConstant(baudrate) ); cfmakeraw(&options); options.c_cflag |= (CLOCAL | CREAD); // 8 bit, no parity, 1 stopbit options.c_cflag |= CS8; options.c_cflag &= ~CRTSCTS; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // wait for 1 characters options.c_cc[VMIN] = 1; // timeout 1 seconds options.c_cc[VTIME] = 1; /* cfsetispeed(&options, getSpeedConstant(baudrate)); cfsetospeed(&options, getSpeedConstant(baudrate)); //options.c_cflag = 0; options.c_cflag |= (getSpeedConstant(baudrate) | CLOCAL | CREAD); // 8 bit, no parity, 1 stopbit options.c_cflag |= CS8; options.c_cflag &= ~CRTSCTS; //options.c_lflag = 0; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);*/ // testing --> // <-- testing /* // baudrate >> 1152000 struct serial_struct nuts; int arby; if(ioctl(fdSerialPort, TIOCGSERIAL, &nuts) == -1) CUtil::cout( "Serial: ioctl(*,TIOCGSERIAL,*) failed.\n"); nuts.custom_divisor = nuts.baud_base / 500000; if (!(nuts.custom_divisor)) nuts.custom_divisor = 1; arby = nuts.baud_base / nuts.custom_divisor; nuts.flags &= ~ASYNC_SPD_MASK; nuts.flags |= ASYNC_SPD_CUST; if (ioctl(fdSerialPort, TIOCSSERIAL, &nuts) == -1) CUtil::cout("Serial: ioctl(*, TIOCSSERIAL, *) failed.\n"); options.c_cflag |= B38400; // wait for 1 characters options.c_cc[VMIN] = 1; // timeout 1 seconds options.c_cc[VTIME] = 1; */ if(tcsetattr(fdSerialPort, TCSANOW, &options) != 0) { CUtil::cout("initSerial: tcsetattr() failed.\n", TEXT_ERROR); } } #endif return true; #endif }
int nifalcon_load_firmware(falcon_device* dev, const char* firmware_filename) { unsigned int bytes_written, bytes_read; unsigned char check_msg_1_send[3] = {0x0a, 0x43, 0x0d}; unsigned char check_msg_1_recv[4] = {0x0a, 0x44, 0x2c, 0x0d}; unsigned char check_msg_2[1] = {0x41}; unsigned char send_buf[128], receive_buf[128]; FILE* firmware_file; int k; if(!dev->is_initialized) nifalcon_error_return(NIFALCON_DEVICE_NOT_VALID_ERROR, "tried to load firmware on an uninitialized device"); if(!dev->is_open) nifalcon_error_return(NIFALCON_DEVICE_NOT_FOUND_ERROR, "tried to load firmware on an unopened device"); //Clear out current buffers to make sure we have a fresh start if((dev->falcon_status_code = ftdi_usb_purge_buffers(&(dev->falcon))) < 0) return dev->falcon_status_code; //Reset the device if((dev->falcon_status_code = ftdi_usb_reset(&(dev->falcon))) < 0) return dev->falcon_status_code; //Make sure our latency timer is at 16ms, otherwise firmware checks tend to always fail if((dev->falcon_status_code = ftdi_set_latency_timer(&(dev->falcon), 16)) < 0) return dev->falcon_status_code; //Set to: // 9600 baud // 8n1 // No Flow Control // RTS Low // DTR High if((dev->falcon_status_code = ftdi_set_baudrate(&(dev->falcon), 9600)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_set_line_property(&(dev->falcon), BITS_8, STOP_BIT_1, NONE)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_setflowctrl(&(dev->falcon), SIO_DISABLE_FLOW_CTRL)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_setrts(&(dev->falcon), 0)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_setdtr(&(dev->falcon), 0)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_setdtr(&(dev->falcon), 1)) < 0) return dev->falcon_status_code; //Send 3 bytes: 0x0a 0x43 0x0d if((dev->falcon_status_code = nifalcon_write(dev, check_msg_1_send, 3)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = nifalcon_read(dev, receive_buf, 4, 1000)) < 0) return dev->falcon_status_code; //Set to: // DTR Low // 140000 baud (0x15 clock ticks per signal) if((dev->falcon_status_code = ftdi_setdtr(&(dev->falcon),0)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = ftdi_set_baudrate(&(dev->falcon), 140000)) < 0) return dev->falcon_status_code; //Send "A" character if((dev->falcon_status_code = nifalcon_write(dev, check_msg_2, 1)) < 0) return dev->falcon_status_code; //Expect back 2 bytes: // 0x13 0x41 if((dev->falcon_status_code = nifalcon_read(dev, receive_buf, 2, 1000)) < 0) return dev->falcon_status_code; firmware_file = fopen(firmware_filename, "rb"); if(!firmware_file) { nifalcon_error_return(NIFALCON_FIRMWARE_NOT_FOUND_ERROR, "cannot find falcon firmware file"); } while(!feof(firmware_file)) { int firmware_bytes_read; int i; firmware_bytes_read = fread(send_buf, 1, 128, firmware_file); if((dev->falcon_status_code = nifalcon_write(dev, send_buf, firmware_bytes_read)) < 0) return dev->falcon_status_code; if((dev->falcon_status_code = nifalcon_read(dev, receive_buf, firmware_bytes_read, 1000)) < firmware_bytes_read) { nifalcon_error_return(NIFALCON_FIRMWARE_CHECKSUM_ERROR, "error sending firmware (firmware send step, 128 byte reply not received)"); } for(i = 0; i < firmware_bytes_read; ++i) { if(send_buf[i] != receive_buf[i]) { nifalcon_error_return(NIFALCON_FIRMWARE_CHECKSUM_ERROR, "error sending firmware (firmware send step, checksum does not match)"); } } if(firmware_bytes_read < 128) break; } fclose(firmware_file); //VERY IMPORTANT //If we do not reset latency to 1ms, then we either have to fill the FTDI butter (64bytes) or wait 16ms //to get any data back. This is what was causing massive slowness in pre-1.0 releases if((dev->falcon_status_code = ftdi_set_latency_timer(&(dev->falcon), 1)) < 0) return dev->falcon_status_code; //Shift to full speed if((dev->falcon_status_code = ftdi_set_baudrate(&(dev->falcon), 1456312)) < 0) return dev->falcon_status_code; return 0; }
QList <DMXUSBWidget*> QLCFTDI::widgets() { QList <DMXUSBWidget*> widgetList; quint32 input_id = 0; struct ftdi_context ftdi; ftdi_init(&ftdi); #ifdef LIBFTDI1 libusb_device *dev; libusb_device **devs; int i = 0; if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0) { qDebug() << "usb_find_devices() failed"; ftdi_error_return(-5, "libusb_get_device_list() failed"); } while ((dev = devs[i++]) != NULL) { #else struct usb_bus *bus; struct usb_device *dev; usb_init(); if (usb_find_busses() < 0) { qDebug() << "usb_find_busses() failed"; return widgetList; } if (usb_find_devices() < 0) { qDebug() << "usb_find_devices() failed"; return widgetList; } for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { #endif Q_ASSERT(dev != NULL); // Skip non wanted devices if (dev->descriptor.idVendor != QLCFTDI::FTDIVID && dev->descriptor.idVendor != QLCFTDI::ATMELVID) continue; if (dev->descriptor.idProduct != QLCFTDI::FTDIPID && dev->descriptor.idProduct != QLCFTDI::DMX4ALLPID && dev->descriptor.idProduct != QLCFTDI::NANODMXPID) continue; char ser[256]; char nme[256]; char vend[256]; ftdi_usb_get_strings(&ftdi, dev, vend, 256, nme, 256, ser, 256); QString serial(ser); QString name(nme); QString vendor(vend); QMap <QString,QVariant> types(typeMap()); qDebug() << Q_FUNC_INFO << "DMX USB VID:" << QString::number(dev->descriptor.idVendor, 16) << "PID:" << QString::number(dev->descriptor.idProduct, 16); qDebug() << Q_FUNC_INFO << "DMX USB serial: " << serial << "name:" << name << "vendor:" << vendor; if (types.contains(serial) == true) { // Force a widget with a specific serial to either type DMXUSBWidget::Type type = (DMXUSBWidget::Type) types[serial].toInt(); switch (type) { case DMXUSBWidget::OpenTX: widgetList << new EnttecDMXUSBOpen(serial, name, vendor); break; case DMXUSBWidget::ProRX: { EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++); widgetList << prorx; break; } case DMXUSBWidget::ProMk2: { EnttecDMXUSBProTX* protx = new EnttecDMXUSBProTX(serial, name, vendor, 1); widgetList << protx; widgetList << new EnttecDMXUSBProTX(serial, name, vendor, 2, protx->ftdi()); EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++, protx->ftdi()); widgetList << prorx; break; } case DMXUSBWidget::UltraProTx: { UltraDMXUSBProTx* protx = new UltraDMXUSBProTx(serial, name, vendor, 1); widgetList << protx; widgetList << new UltraDMXUSBProTx(serial, name, vendor, 2, protx->ftdi()); EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++, protx->ftdi()); widgetList << prorx; break; } case DMXUSBWidget::VinceTX: widgetList << new VinceUSBDMX512TX(serial, name, vendor); break; default: case DMXUSBWidget::ProTX: widgetList << new EnttecDMXUSBProTX(serial, name, vendor); break; } } else if (name.toUpper().contains("PRO MK2") == true) { EnttecDMXUSBProTX* protx = new EnttecDMXUSBProTX(serial, name, vendor, 1); widgetList << protx; widgetList << new EnttecDMXUSBProTX(serial, name, vendor, 2, protx->ftdi()); EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++, protx->ftdi()); widgetList << prorx; } else if (name.toUpper().contains("DMX USB PRO")) { /** Check if the device responds to label 77 and 78, so it might be a DMXking adapter */ int ESTAID = 0; int DEVID = 0; QString manName = readLabel(&ftdi, name.toLatin1().data(), serial.toLatin1().data(), USB_DEVICE_MANUFACTURER, &ESTAID); qDebug() << "--------> Device Manufacturer: " << manName; QString devName = readLabel(&ftdi, name.toLatin1().data(), serial.toLatin1().data(), USB_DEVICE_NAME, &DEVID); qDebug() << "--------> Device Name: " << devName; qDebug() << "--------> ESTA Code: " << QString::number(ESTAID, 16) << ", Device ID: " << QString::number(DEVID, 16); if (ESTAID == DMXKING_ESTA_ID) { if (DEVID == ULTRADMX_PRO_DEV_ID) { UltraDMXUSBProTx* protxP1 = new UltraDMXUSBProTx(serial, name, vendor, 1); protxP1->setRealName(devName); widgetList << protxP1; UltraDMXUSBProTx* protxP2 = new UltraDMXUSBProTx(serial, name, vendor, 2, protxP1->ftdi()); protxP2->setRealName(devName); widgetList << protxP2; EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++, protxP1->ftdi()); prorx->setRealName(devName); widgetList << prorx; } else { EnttecDMXUSBProTX* protx = new EnttecDMXUSBProTX(serial, name, vendor); protx->setRealName(devName); widgetList << protx; } } else { /* This is probably a Enttec DMX USB Pro widget */ EnttecDMXUSBProTX* protx = new EnttecDMXUSBProTX(serial, name, vendor); widgetList << protx; EnttecDMXUSBProRX* prorx = new EnttecDMXUSBProRX(serial, name, vendor, input_id++, protx->ftdi()); widgetList << prorx; } } else if (name.toUpper().contains("USB-DMX512 CONVERTER") == true) { widgetList << new VinceUSBDMX512TX(serial, name, vendor); } else if (dev->descriptor.idVendor == QLCFTDI::FTDIVID && dev->descriptor.idProduct == QLCFTDI::DMX4ALLPID) { widgetList << new Stageprofi(serial, name, vendor); } #if defined(Q_WS_X11) || defined(Q_OS_LINUX) else if (dev->descriptor.idVendor == QLCFTDI::ATMELVID && dev->descriptor.idProduct == QLCFTDI::NANODMXPID) { widgetList << new NanoDMX(serial, name, vendor); } #endif else { /* This is probably an Open DMX USB widget */ widgetList << new EnttecDMXUSBOpen(serial, name, vendor, 0); } #ifndef LIBFTDI1 } #endif } #ifdef LIBFTDI1 libusb_free_device_list(devs, 1); #endif ftdi_deinit(&ftdi); return widgetList; } bool QLCFTDI::open() { if (m_openCount < m_refCount) m_openCount++; if (isOpen() == true) return true; if (ftdi_usb_open_desc(&m_handle, QLCFTDI::FTDIVID, QLCFTDI::FTDIPID, name().toLatin1(), serial().toLatin1()) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::openByPID(const int PID) { if (m_openCount < m_refCount) m_openCount++; if (isOpen() == true) return true; if (ftdi_usb_open(&m_handle, QLCFTDI::FTDIVID, PID) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::close() { if (m_openCount > 1) { m_openCount--; return true; } if (ftdi_usb_close(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::isOpen() const { return (m_handle.usb_dev != NULL) ? true : false; } bool QLCFTDI::reset() { if (ftdi_usb_reset(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::setLineProperties() { if (ftdi_set_line_property(&m_handle, BITS_8, STOP_BIT_2, NONE) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::setBaudRate() { if (ftdi_set_baudrate(&m_handle, 250000) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::setFlowControl() { if (ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::clearRts() { if (ftdi_setrts(&m_handle, 0) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::purgeBuffers() { if (ftdi_usb_purge_buffers(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool QLCFTDI::setBreak(bool on) { ftdi_break_type type; if (on == true) type = BREAK_ON; else type = BREAK_OFF; if (ftdi_set_line_property2(&m_handle, BITS_8, STOP_BIT_2, NONE, type) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } }
// // Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol). // static dc_status_t serial_ftdi_configure (void *io, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) { ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; INFO (device->context, "Configure: baudrate=%i, databits=%i, parity=%i, stopbits=%i, flowcontrol=%i", baudrate, databits, parity, stopbits, flowcontrol); enum ftdi_bits_type ft_bits; enum ftdi_stopbits_type ft_stopbits; enum ftdi_parity_type ft_parity; if (ftdi_set_baudrate(device->ftdi_ctx, baudrate) < 0) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } // Set the character size. switch (databits) { case 7: ft_bits = BITS_7; break; case 8: ft_bits = BITS_8; break; default: return DC_STATUS_INVALIDARGS; } // Set the parity type. switch (parity) { case DC_PARITY_NONE: /**< No parity */ ft_parity = NONE; break; case DC_PARITY_EVEN: /**< Even parity */ ft_parity = EVEN; break; case DC_PARITY_ODD: /**< Odd parity */ ft_parity = ODD; break; case DC_PARITY_MARK: /**< Mark parity (always 1) */ case DC_PARITY_SPACE: /**< Space parity (alwasy 0) */ default: return DC_STATUS_INVALIDARGS; } // Set the number of stop bits. switch (stopbits) { case DC_STOPBITS_ONE: /**< 1 stop bit */ ft_stopbits = STOP_BIT_1; break; case DC_STOPBITS_TWO: /**< 2 stop bits */ ft_stopbits = STOP_BIT_2; break; case DC_STOPBITS_ONEPOINTFIVE: /**< 1.5 stop bits*/ default: return DC_STATUS_INVALIDARGS; } // Set the attributes if (ftdi_set_line_property(device->ftdi_ctx, ft_bits, ft_stopbits, ft_parity)) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } // Set the flow control. switch (flowcontrol) { case DC_FLOWCONTROL_NONE: /**< No flow control */ if (ftdi_setflowctrl(device->ftdi_ctx, SIO_DISABLE_FLOW_CTRL) < 0) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } break; case DC_FLOWCONTROL_HARDWARE: /**< Hardware (RTS/CTS) flow control */ if (ftdi_setflowctrl(device->ftdi_ctx, SIO_RTS_CTS_HS) < 0) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } break; case DC_FLOWCONTROL_SOFTWARE: /**< Software (XON/XOFF) flow control */ if (ftdi_setflowctrl(device->ftdi_ctx, SIO_XON_XOFF_HS) < 0) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } break; default: return DC_STATUS_INVALIDARGS; } device->baudrate = baudrate; device->nbits = 1 + databits + stopbits + (parity ? 1 : 0); device->databits = databits; device->stopbits = stopbits; device->parity = parity; return DC_STATUS_SUCCESS; }
int ftdi_device_setup(ftdi_device_t* dev, int baud_rate, int data_bits, int stop_bits, ftdi_parity_t parity, ftdi_flow_ctrl_t flow_ctrl, ftdi_break_t break_type, double timeout, double latency) { struct ftdi_context* libftdi_context = dev->libftdi_context; enum ftdi_bits_type libftdi_data_bits; enum ftdi_stopbits_type libftdi_stop_bits; enum ftdi_parity_type libftdi_parity; int libftdi_flow_ctrl; enum ftdi_break_type libftdi_break; int error; error_clear(&dev->error); switch (data_bits) { case 7: libftdi_data_bits = BITS_7; break; case 8: libftdi_data_bits = BITS_8; break; default: error_setf(&dev->error, FTDI_ERROR_INVALID_DATA_BITS, "%d", data_bits); return error_get(&dev->error); } dev->data_bits = data_bits; switch (stop_bits) { case 1: libftdi_stop_bits = STOP_BIT_1; break; case 2 : libftdi_stop_bits = STOP_BIT_2; break; case 15: libftdi_stop_bits = STOP_BIT_15; break; default: error_setf(&dev->error, FTDI_ERROR_INVALID_STOP_BITS, "%d", stop_bits); return error_get(&dev->error); } dev->stop_bits = stop_bits; switch (parity) { case ftdi_parity_none: libftdi_parity = NONE; break; case ftdi_parity_odd: libftdi_parity = ODD; break; case ftdi_parity_even: libftdi_parity = EVEN; break; case ftdi_parity_mark: libftdi_parity = MARK; break; case ftdi_parity_space: libftdi_parity = SPACE; break; default: error_set(&dev->error, FTDI_ERROR_INVALID_PARITY); return error_get(&dev->error); } dev->parity = parity; switch (flow_ctrl) { case ftdi_flow_ctrl_off: libftdi_flow_ctrl = SIO_DISABLE_FLOW_CTRL; break; case ftdi_flow_ctrl_xon_xoff: libftdi_flow_ctrl = SIO_XON_XOFF_HS; break; case ftdi_flow_ctrl_rts_cts: libftdi_flow_ctrl = SIO_RTS_CTS_HS; break; case ftdi_flow_ctrl_dtr_dsr: libftdi_flow_ctrl = SIO_DTR_DSR_HS; break; default: error_set(&dev->error, FTDI_ERROR_INVALID_FLOW_CTRL); return error_get(&dev->error); } dev->flow_ctrl = flow_ctrl; switch (break_type) { case ftdi_break_off: libftdi_break = BREAK_OFF; break; case ftdi_break_on: libftdi_break = BREAK_ON; break; default: error_set(&dev->error, FTDI_ERROR_INVALID_BREAK); return error_get(&dev->error); } dev->break_type = break_type; if (ftdi_set_line_property2(libftdi_context, libftdi_data_bits, libftdi_stop_bits, libftdi_parity, libftdi_break)) { error_setf(&dev->error, FTDI_ERROR_SETUP, "%03:%03", dev->bus, dev->address); return error_get(&dev->error); } if (ftdi_setflowctrl(libftdi_context, libftdi_flow_ctrl)) { error_setf(&dev->error, FTDI_ERROR_SETUP, "%03:%03", dev->bus, dev->address); return error_get(&dev->error); } error = ftdi_set_baudrate(libftdi_context, baud_rate); if (error == -1) { error_setf(&dev->error, FTDI_ERROR_INVALID_BAUD_RATE, "%d", baud_rate); return error_get(&dev->error); } dev->baud_rate = baud_rate; if (error) { error_setf(&dev->error, FTDI_ERROR_SETUP, "%03:%03", dev->bus, dev->address); return error_get(&dev->error); } libftdi_context->usb_read_timeout = timeout*1e6; libftdi_context->usb_write_timeout = timeout*1e6; dev->timeout = timeout; error = ftdi_set_latency_timer(libftdi_context, latency*1e3); if (error == -1) { error_setf(&dev->error, FTDI_ERROR_INVALID_LATENCY, "%f", latency); return error_get(&dev->error); } dev->latency = latency; if (error) { error_setf(&dev->error, FTDI_ERROR_SETUP, "%03:%03", dev->bus, dev->address); return error_get(&dev->error); } return error_get(&dev->error); }