Example #1
0
File: vcc.c Project: koheik/vcctool
int main(int argc, char *argv[])
{
	int ret;
	int i;
	struct ftdi_context *ftdi;
	unsigned int chipid;
	unsigned char buf[256];
	track *tracks;
	int ntracks;


	ftdi = ftdi_new();
	ret = ftdi_usb_open(ftdi, 0x0403, 0xB70A);
	if (ret < -1) {
		fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
				ret, ftdi_get_error_string(ftdi));
		return ret;
	}

	printf("type=%d\n", ftdi->type);
	ftdi_read_chipid(ftdi, &chipid);
	printf("chipid=%x\n", chipid);


	setup(ftdi);

	ftdi_setrts(ftdi, 1);
	while((ret = ftdi_read_data(ftdi, buf, 256)) > 0) {
		for(i = 0; i < ret; ++i)
			printf("%02X ", buf[i]);
	}
	ftdi_setrts(ftdi, 0);

	read_version(ftdi);
	read_product(ftdi);

	read_list(ftdi, &tracks, &ntracks);

	if (argc > 1) {
		i = atoi(argv[1]);
		printf("tracks[%d].no=%d\n", i, tracks[i].no);
		read_track_points(ftdi, &tracks[i], i);
	}
	free(tracks);

	ftdi_usb_close(ftdi);
	ftdi_free(ftdi);

	return 0;
}
	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;
	}
Example #3
0
File: vcc.c Project: koheik/vcctool
void begin(struct ftdi_context *ftdi)
{
	ftdi_usb_reset(ftdi);
	ftdi_usb_purge_rx_buffer(ftdi);
	ftdi_usb_purge_tx_buffer(ftdi);

	ftdi_setrts(ftdi, 1);
}
Example #4
0
bool EnttecDMXUSBOpen::open()
{
	if (isOpen() == false)
	{
		if (ftdi_usb_open_desc(&m_context, EnttecDMXUSBWidget::VID,
						   EnttecDMXUSBWidget::PID,
						   name().toAscii(),
						   serial().toAscii()) < 0)
		{
			qWarning() << "Unable to open" << uniqueName()
				   << ":" << ftdi_get_error_string(&m_context);
			return false;
		}

		if (ftdi_usb_reset(&m_context) < 0)
		{
			qWarning() << "Unable to reset" << uniqueName()
				   << ":" << ftdi_get_error_string(&m_context);
			return close();
		}

		if (ftdi_set_line_property(&m_context, BITS_8, STOP_BIT_2, NONE) < 0)
		{
			qWarning() << "Unable to set 8N2 serial properties to"
				   << uniqueName()
				   << ":" << ftdi_get_error_string(&m_context);
			return close();
		}

		if (ftdi_set_baudrate(&m_context, 250000) < 0)
		{
			qWarning() << "Unable to set 250kbps baudrate for"
				   << uniqueName()
				   << ":" << ftdi_get_error_string(&m_context);
			return close();
		}

		if (ftdi_setrts(&m_context, 0) < 0)
		{
			qWarning() << "Unable to set RTS line to 0 for"
				   << uniqueName()
				   << ":" << ftdi_get_error_string(&m_context);
			return close();
		}

		if (isRunning() == false)
			start();

		return true;
	}
	else
	{
		/* Already open */
		return true;
	}
}
Example #5
0
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;
    }
}
Example #6
0
static dc_status_t serial_ftdi_set_rts (void *io, unsigned int level)
{
	ftdi_serial_t *device = io;

	if (device == NULL)
		return DC_STATUS_INVALIDARGS;

	INFO (device->context, "RTS: value=%u", level);

	if (ftdi_setrts(device->ftdi_ctx, level)) {
		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
		return DC_STATUS_IO;
	}

	return DC_STATUS_SUCCESS;
}
Example #7
0
static dc_status_t serial_ftdi_set_rts (dc_custom_io_t *io, int level)
{
	ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;

	if (device == NULL)
		return DC_STATUS_INVALIDARGS;

	INFO (device->context, "RTS: value=%i", level);

	if (ftdi_setrts(device->ftdi_ctx, level)) {
		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
		return DC_STATUS_IO;
	}

	return DC_STATUS_SUCCESS;
}
Example #8
0
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;
}
Example #9
0
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;
    }
}
Example #10
0
File: vcc.c Project: koheik/vcctool
void end(struct ftdi_context *ftdi)
{
	ftdi_setrts(ftdi, 0);
}
Example #11
0
int Context::set_rts(bool state)
{
    return ftdi_setrts(d->ftdi, state);
}
Example #12
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;
    }
}