Example #1
0
bool FTDIDMXDevice::open()
{
	// Change QString to char* (not const char* note)

	char *serial;
	QByteArray a = m_path.toLatin1();

	serial = (char*)malloc(sizeof(char) * (a.count() + 1));
	memcpy(serial, a.constData(), a.count());
	serial[a.count()] = 0;

#ifndef WIN32
	// Windows users cannot dynamiccaly set VID/PID of harward
	if (FT_SetVIDPID(m_vid, m_pid) == FT_OK && 
	    FT_OpenEx(serial, FT_OPEN_BY_SERIAL_NUMBER, &m_handle) == FT_OK)
	{
#else
	if (FT_OpenEx(serial, FT_OPEN_BY_SERIAL_NUMBER, &m_handle) == FT_OK)
	{
#endif
		free(serial);
		if (!FT_SUCCESS(FT_ResetDevice(m_handle)))
		{
			qWarning() << "Unable to reset FTDI device" << m_path;
			return false;
		}

		// Set the baud rate 12 will give us 250Kbits
		if (!FT_SUCCESS(FT_SetDivisor(m_handle, 12)))
		{
			qWarning() << "Unable to set divisor on FTDI device"
				   << m_path;
			return false;
		}

		// Set the data characteristics
		if (!FT_SUCCESS(FT_SetDataCharacteristics(m_handle,
							  FT_BITS_8,
							  FT_STOP_BITS_2,
							  FT_PARITY_NONE)))
		{
			qWarning() << "Unable to set data characteristics on"
				   << "FTDI device" << m_path;
			return false;
		}

		// Set flow control
	 	if (!FT_SUCCESS(FT_SetFlowControl(m_handle, FT_FLOW_NONE, 0, 0)))
	 	{
			qWarning() << "Unable to set flow control on"
				   << "FTDI device" << m_path;
			return false;
		}

		// set RS485 for sendin
		FT_ClrRts(m_handle);

		// Clear TX RX buffers
		FT_Purge(m_handle,FT_PURGE_TX | FT_PURGE_RX);

		m_threadRunning = true;
		start(QThread::TimeCriticalPriority);

		return true;
	}
	else
	{
		qWarning() << "Unable to open FTDIDMX"
			   << m_output << ":" << serial;
		free(serial);
		return false;
	}
}

bool FTDIDMXDevice::close()
{
	// Kill thread
	m_threadRunning = false;
	wait(500);

	FT_Close(m_handle);
	return true;
}
Example #2
0
/* This internal function handles the actual FTDI init and memory alloc
   for the library, with graceful cleanup in all error cases.  Keeps
   subsequent TCopen() function simpler with regards to error handling. */
static TCstatusCode openAlloc(
  unsigned char s, /* Number of strands                  */
  int           p) /* Number of pixels in longest strand */
{
	/* Parameter validation was already done in TCopen(). */

	/* Function works from a presumed error condition progressing
	   toward success.  This makes the cleanup cases easier. */
	TCstatusCode status = TC_ERR_MALLOC;

	/* Size of pixelOutBuffer depends whether the serial clock is
	   provided by one of the CBUS pins or must be bit-banged via
	   software.  If using 8 strands, MUST use CBUS clock. */
	if(s >= TC_CBUS_CLOCK)
	{
		bytesPerPixel = 32;
		if(s > TC_CBUS_CLOCK) s -= TC_CBUS_CLOCK;
	} else
	{
		bytesPerPixel = 64;
	}

	/* All library memory use is handled in one big malloc.
	   The data types are sorted to avoid alignment issues.
	   pixelOutBuffer includes latch data at end. */
	if((pixelCurrent = (double *)malloc(
	    (s * p * sizeof(double)) +      /* pixelCurrent array + */
	    ((p+((p+63)/64)) * bytesPerPixel))))  /* pixelOutBuffer */
	{
		pixelOutBuffer = (unsigned char *)&pixelCurrent[s * p];

		/* Alloc successful.  Next phase... */
		status = TC_ERR_OPEN;

		/* Currently rigged for a single FTDI device,
		   and always index 0.  Might address this in
		   a future update if it's an issue. */
		if(FT_OK == FT_Open(0,&ftdiHandle))
		{
			status = TC_ERR_MODE;
			/* Currently hogs all pins as outputs,
			   whether they're used by strands or not. */
			if(FT_OK == FT_SetBitMode(ftdiHandle,255,1))
			{
				status = TC_OK; /* Tentative success */

				/* Try to set baud rate & divisor to non-
				   default values.  3090000 seems to be the
				   absolute max baud rate; even +1 more, and
				   it fails.  Failure of either of these
				   steps returns a warning but does not
				   abort; program can continue with default
				   baud rate setting.  FTDI docs suggest max
				   of 3000000; this may be pushing it. */
				if(FT_OK != FT_SetDivisor(ftdiHandle,1))
					status = TC_ERR_DIVISOR;
				if(FT_OK != FT_SetBaudRate(ftdiHandle,3090000))
					status = TC_ERR_BAUDRATE;

				/* Clear any lingering data in queue. */
				(void)FT_Purge(ftdiHandle,
				  FT_PURGE_RX | FT_PURGE_TX);

				return status; /* Success */
			}
			/* Else fatal error of some sort.
			   Clean up any interim results. */
			FT_Close(ftdiHandle);
		}
		ftdiHandle = NULL;
		free(pixelCurrent);
		pixelCurrent   = NULL;
		pixelOutBuffer = NULL;
	}
	return status; /* Fail */
}
Example #3
0
int dev_open_uart (int n_dev_indx, FT_HANDLE *ph_device)
{

    FT_STATUS ft_status;
    DWORD   dw_num_devs;
    LONG    devLocation;


    ft_status = FT_ListDevices(&dw_num_devs, NULL, FT_LIST_NUMBER_ONLY);
    if (ft_status != FT_OK) return FALSE;

    if (dw_num_devs == 0){
        // No devices were found
        return FALSE;
    }

    ft_status = FT_ListDevices((void*)n_dev_indx, &devLocation, FT_LIST_BY_INDEX | FT_OPEN_BY_LOCATION);
    if (ft_status != FT_OK) {
        return FALSE;
    }

    ft_status |= FT_ListDevices((void*)n_dev_indx, &devDescriptor, FT_LIST_BY_INDEX | FT_OPEN_BY_DESCRIPTION);
    ft_status |= FT_ListDevices((void*)n_dev_indx, &devSerial, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER);

    if (ft_status != FT_OK){
        return FALSE;
    }
#define FT_Classic  0

#if FT_Classic
    ft_status |= FT_OpenEx((void*)devLocation, FT_OPEN_BY_LOCATION, ph_device);

    ft_status |= FT_SetTimeouts(*ph_device, 500, 500);
    ft_status |= FT_SetLatencyTimer(*ph_device, 2);

    // Divisor selection
    // BAUD = 3000000 / Divisor
    // Divisor = (N + 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875)
    // Divisor = 24 ==> Baud 125000 
    ft_status |= FT_SetDivisor(*ph_device, 3000000 / 125000);

    // Set UART format 8N1
    ft_status |= FT_SetDataCharacteristics(*ph_device, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);

    if (ft_status != FT_OK){
        return FALSE;
    }


    // Just in case
    FT_Purge(*ph_device, FT_PURGE_TX | FT_PURGE_RX);
#else


    // Open a device for overlapped I/O using its serial number
    *ph_device = FT_W32_CreateFile(
        (LPCTSTR)devLocation,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FT_OPEN_BY_LOCATION,
        0);

    if (*ph_device == INVALID_HANDLE_VALUE)
    {
        // FT_W32_CreateDevice failed
        return FALSE;
    }

    // ----------------------------------------
    // --- Set comm parameters
    // ----------------------------------------

    FTDCB ftDCB;
    FTTIMEOUTS    ftTimeouts;
    FTCOMSTAT    ftPortStatus;
    DWORD   dw_port_error;

    if (!FT_W32_GetCommState(*ph_device, &ftDCB))
    {
        return FALSE;
    }

    // Divisor selection
    // BAUD = 3000000 / Divisor
    // Divisor = (N + 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875)
    // Divisor = 24 ==> Baud 125000 

    ftDCB.BaudRate = 38400;
    ftDCB.fBinary = TRUE;                       /* Binary Mode (skip EOF check)    */
    ftDCB.fParity = FALSE;                      /* Enable parity checking          */
    ftDCB.fOutxCtsFlow = FALSE;                 /* CTS handshaking on output       */
    ftDCB.fOutxDsrFlow = FALSE;                 /* DSR handshaking on output       */
    ftDCB.fDtrControl = DTR_CONTROL_DISABLE;    /* DTR Flow control                */
    ftDCB.fTXContinueOnXoff = FALSE;

    ftDCB.fErrorChar = FALSE;            // enable error replacement 
    ftDCB.fNull = FALSE;                // enable null stripping 
    ftDCB.fRtsControl = RTS_CONTROL_DISABLE;       // RTS flow control 
    ftDCB.fAbortOnError = TRUE;            // abort reads/writes on error 

    ftDCB.fOutX = FALSE;                        /* Enable output X-ON/X-OFF        */
    ftDCB.fInX = FALSE;                         /* Enable input X-ON/X-OFF         */
    ftDCB.fNull = FALSE;                        /* Enable Null stripping           */
    ftDCB.fRtsControl = RTS_CONTROL_DISABLE;    /* Rts Flow control                */
    ftDCB.fAbortOnError = TRUE;                 /* Abort all reads and writes on Error */

    // 8N1
    ftDCB.ByteSize = 8;                 /* Number of bits/byte, 4-8        */
    ftDCB.Parity = NOPARITY;            /* 0-4=None,Odd,Even,Mark,Space    */
    ftDCB.StopBits = ONESTOPBIT;        /* 0,1,2 = 1, 1.5, 2               */

    if (!FT_W32_SetCommState(*ph_device, &ftDCB))
    {
        return FALSE;
    }

    FT_W32_GetCommState(*ph_device, &ftDCB);

    // Set serial port Timeout values
    FT_W32_GetCommTimeouts(*ph_device, &ftTimeouts);

    ftTimeouts.ReadIntervalTimeout = 0;
    ftTimeouts.ReadTotalTimeoutMultiplier = 0;
    ftTimeouts.ReadTotalTimeoutConstant = 200;
    ftTimeouts.WriteTotalTimeoutConstant = 0;
    ftTimeouts.WriteTotalTimeoutMultiplier = 0;

    FT_W32_SetCommTimeouts(*ph_device, &ftTimeouts);

    FT_W32_ClearCommError(*ph_device, &dw_port_error, &ftPortStatus);
    FT_W32_PurgeComm(*ph_device, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

#endif  // End of W32 device init

    return TRUE;
}