int main() { char cBufWrite[BUF_SIZE]; char * pcBufRead = NULL; char * pcBufLD[MAX_DEVICES + 1]; char cBufLD[MAX_DEVICES][64]; DWORD dwRxSize = 0; DWORD dwBytesWritten, dwBytesRead, dwErrors; FT_STATUS ftStatus; FT_HANDLE ftHandle[MAX_DEVICES]; int iNumDevs = 0; int i, j; int iDevicesOpen; FTDCB ftDCB, ftnewDCB; FTCOMSTAT ftComStat; FTTIMEOUTS ftTimouts, ftnewTimouts; struct timeval tv; struct timezone tz; for(i = 0; i < MAX_DEVICES; i++) { pcBufLD[i] = cBufLD[i]; } pcBufLD[MAX_DEVICES] = NULL; ftStatus = FT_ListDevices(pcBufLD, &iNumDevs, FT_LIST_ALL | FT_OPEN_BY_SERIAL_NUMBER); if(ftStatus != FT_OK) { printf("Error: FT_ListDevices(%d)\n", ftStatus); return 1; } for(j = 0; j < BUF_SIZE; j++) { cBufWrite[j] = j; } for(i = 0; ( (i <MAX_DEVICES) && (i < iNumDevs) ); i++) { printf("Device %d Serial Number - %s\n", i, cBufLD[i]); } for(i = 0; ( (i <MAX_DEVICES) && (i < iNumDevs) ) ; i++) { memset(&ftDCB, 0, sizeof(FTDCB)); ftHandle[i] = FT_W32_CreateFile( cBufLD[i], 0, // GENERIC_READ|GENERIC_WRITE ignored 0, // ignored 0, // ignored 0, // OPEN_EXISTING ignored FT_OPEN_BY_SERIAL_NUMBER, // ignored FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FT_OPEN_BY_SERIAL_NUMBER, 0 // ignored ); /* Setup */ if(ftHandle[i] == (FT_HANDLE)INVALID_HANDLE_VALUE){ /* This can fail if the ftdi_sio driver is loaded use lsmod to check this and rmmod ftdi_sio to remove also rmmod usbserial */ printf("Error FT_W32_CreateFile(%d), device\n", i); return 1; } printf("Opened device %s\n", cBufLD[i]); ftDCB.BaudRate = 9600; if(FT_W32_SetCommState(ftHandle[i], &ftDCB) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); printf("Error FT_W32_SetCommState = %d)\n", ftStatus); return 1; } if(FT_W32_GetCommState(ftHandle[i], &ftnewDCB) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); printf("Error FT_W32_GetCommState = %d)\n", ftStatus); return 1; } if(ftnewDCB.BaudRate != ftDCB.BaudRate) { printf("New baud rate does not match baud rate set\n"); } ftTimouts.ReadIntervalTimeout = 0; // ignored by library ftTimouts.ReadTotalTimeoutMultiplier = 0; // ignored by library ftTimouts.ReadTotalTimeoutConstant = 1000; // 1 second ftTimouts.WriteTotalTimeoutMultiplier = 0; // ignored by library ftTimouts.WriteTotalTimeoutConstant = 1000; // 1 second // 1 second for both read and write if(FT_W32_SetCommTimeouts(ftHandle[i], &ftTimouts) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); printf("Error FT_W32_GetCommState = %d)\n", ftStatus); return 1; } if(FT_W32_GetCommTimeouts(ftHandle[i], &ftnewTimouts) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); printf("Error FT_W32_GetCommState = %d)\n", ftStatus); return 1; } else { printf("ftTimouts.ReadIntervalTimeout = %d\n", ftTimouts.ReadIntervalTimeout); printf("ftTimouts.ReadTotalTimeoutMultiplier = %d\n", ftTimouts.ReadTotalTimeoutMultiplier); printf("ftTimouts.ReadTotalTimeoutConstant = %d\n", ftTimouts.ReadTotalTimeoutConstant); printf("ftTimouts.WriteTotalTimeoutMultiplier = %d\n", ftTimouts.WriteTotalTimeoutMultiplier); printf("ftTimouts.WriteTotalTimeoutConstant = %d\n", ftTimouts.WriteTotalTimeoutConstant); } for(j = 0 ; j < 10; j++) { if(FT_W32_ReadFile(ftHandle[i], cBufWrite, BUF_SIZE, &dwBytesRead, NULL) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); gettimeofday(&tv, &tz); printf("%d secs, %d usecs\n", tv.tv_sec, tv.tv_usec); // printf("Error FT_W32_ReadFile = %d)\n", ftStatus); // return 1; } else if(dwBytesRead != BUF_SIZE) { gettimeofday(&tv, &tz); printf("%d secs, %d usecs\n", tv.tv_sec, tv.tv_usec); } } printf("dwBytesRead = %d\n", dwBytesRead); } iDevicesOpen = i; /* Cleanup */ for(i = 0; i < iDevicesOpen; i++) { if(FT_W32_CloseHandle(ftHandle[i]) == FALSE) { ftStatus = FT_W32_GetLastError(ftHandle[i]); printf("Error FT_W32_CloseHandle = %d, device = %d)\n", ftStatus, i); } printf("Closed device %s\n", cBufLD[i]); } if(pcBufRead) free(pcBufRead); return 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; }