/Modules/CPLD_FPGA/XILINX_XVC/XVC_SOFTWARE/XVC_1x/mlab_xvcd.cpp
14,6 → 14,7
// 1.03 2012_12 Release version ready to publish
// 1.04 2013_04 Socket Bind Error with explanation (multiple instance of XVC Server)
// 1.05 2013-04 Test FTDI cable during wait for Accept (to stop the server immediately when cable is disconnected)
// 1.06 2013-04 Added support for Linux (thanks to Martin Poviser)
//
//
// Purpose:
59,18 → 60,21
// Ask Google about Xilinx Virtual Cable.
//
//
// Compilation:
// Compilation for Windows:
//
// MS Visual C++ 2010 Express (free, registration required)
// Create new empty project for Win32 Console Application and name project mlab_xvcd (to build mlab_xvcd.exe)
// Header Files / Add / Existing Items - all .h files
// Resource Files / Add / Existing Items - all .lib files
// Source Files / Add / Existing Items - all .cpp files
// Library Files / Add / Existing Items - all .lib .h files from lib_win32 directory
// Select Release version (no debug info)
// Set static linkage Project Properties / Configuration Release / Configuration Properties
// / Code Generation / Runtime Library = Multithreaded (/MT)
//
// Compilation for Linux:
//
// On Ubuntu 12.04LTS just run the .sh file
//
// Problems:
//
// Programming of SPI FLASH configuration memory connected to FPGA does not work. No idea why.
91,20 → 95,62
#define WIN32_LEAN_AND_MEAN
 
#include "mlab_xvcd.h" // Program Configuration
#include <windows.h> // Windows Console Application
#include <winsock2.h> // Windows WinSock2
#include <ws2tcpip.h> // Windows WinSock2
#include <stdlib.h> // Standard Library (exit, atoi, ...)
#include <stdio.h> // Standard IO (printf, ...)
#include <signal.h> // CTRL+C handling
 
#ifdef WIN32
 
#include <windows.h> // Windows Console Application
#include <winsock2.h> // Windows WinSock2
#include <ws2tcpip.h> // Windows WinSock2
 
// Link with library
#pragma comment (lib, "Ws2_32.lib")
//#pragma comment (lib, "../lib_win32/ftd2xx.lib") // Add this file to Resources
 
#else // not WIN32
 
#include "lib_linux_i386/WinTypes.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
 
#endif
 
#define XVC_RX_BUFLEN (XVC_JTAG_LEN/8*2+20) // Length of receive buffer in bytes (command+length+TMSbuffer+TDIbuffer)
#define XVC_TX_BUFLEN (XVC_JTAG_LEN/8) // Length of transmit buffer in bytes (TDObuffer)
 
#ifdef WIN32
 
typedef int socklen_t;
 
#else //not WIN32
 
typedef int SOCKET;
 
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
 
void closesocket(int socket)
{
close(socket);
}
 
void WSACleanup()
{
}
 
int WSAGetLastError()
{
return errno;
}
 
#endif
 
// JTAG state machine
// ------------------
 
168,7 → 214,7
 
// Read Command
char command[16];
int commandLen = 0;
unsigned int commandLen = 0;
 
// Read String terminated by ':'
do
220,7 → 266,7
char buffer[2048];
 
// Read Data (data string for TMS and TDI)
int nr_bytes = (len + 7) / 8;
unsigned int nr_bytes = (len + 7) / 8;
if (nr_bytes * 2 > sizeof(buffer))
{
fprintf(stderr, "Buffer Size Exceeded\n");
227,7 → 273,7
return -2;
}
 
int iReceivedBytes=0;
unsigned int iReceivedBytes=0;
while (iReceivedBytes<nr_bytes * 2)
{
iResult = recv(ClientSocket, buffer+iReceivedBytes, nr_bytes * 2 - iReceivedBytes, 0);
302,7 → 348,7
 
 
// Stop Handler - switch JTAG port off and stop program
void stopHandler(int sig)
void stopHandler(int)
{
jtagClosePort();
exit(1);
326,7 → 372,7
}
 
 
int __cdecl main(int argc, char *argv[])
int main(int argc, char *argv[])
{
// Variables
bool verbose = true;
388,7 → 434,7
{
// Empty String - find device by number and number is empty
findDeviceBy = 0;
findDeviceByStr = "";
findDeviceByStr = (char *)"";
}
 
// Find, Init and Open FTDI USB Chip
402,13 → 448,14
signal(SIGINT, &stopHandler);
 
printf("Starting Network Server\n");
WSADATA wsaData;
int iResult;
 
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
 
#ifdef WIN32
// Initialize Winsock
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
416,6 → 463,7
jtagClosePort();
return -2;
}
#endif
 
// Display HostName and Address
char sMyName[255];
436,7 → 484,7
 
// Create Protocol Structure
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // IP6
hints.ai_socktype = SOCK_STREAM; // Reliable two-way connection
hints.ai_protocol = IPPROTO_TCP; // Protocol TCP
457,7 → 505,7
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
fprintf(stderr, "socket failed with error: %ld\n", WSAGetLastError());
fprintf(stderr, "socket failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
jtagClosePort();
470,7 → 518,12
{
int LastError=WSAGetLastError();
fprintf(stderr, "Bind failed with error: %d\n", LastError);
if (LastError==WSAEADDRINUSE) fprintf(stderr, "Trying to start second instance of XVC Server?\n");
#ifdef WIN32
if (LastError==WSAEADDRINUSE)
#else
if (LastError==EADDRINUSE)
#endif
fprintf(stderr, "Trying to start second instance of XVC Server?\n");
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
508,6 → 561,8
 
// Set ListenSocket to non-blocking mode
// We need during waiting for Accept to detect FTDI disconnect
 
#ifdef WIN32
u_long iMode = 1;
iResult = ioctlsocket(ListenSocket, FIONBIO, &iMode);
if (iResult != NO_ERROR)
517,10 → 572,19
jtagClosePort();
return -2;
}
#else
iResult = fcntl(ListenSocket, F_GETFL, 0);
if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult | O_NONBLOCK) < 0)
{
fprintf(stderr, "fcntl failed with error: %d\n", errno);
jtagClosePort();
return -2;
}
#endif
 
// Accept a client SOCKET (wait for Accept)
sockaddr ClientSocetAddr;
int ClientSocetAddrLen = sizeof(sockaddr);
socklen_t ClientSocetAddrLen = sizeof(sockaddr);
do
{
// Try Accept (non-blocking)
528,7 → 592,11
if (ClientSocket == INVALID_SOCKET)
{
// Accept Error
#ifdef WIN32
if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (WSAGetLastError() != EAGAIN && WSAGetLastError() != EWOULDBLOCK)
#endif
{
fprintf(stderr, "accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
541,7 → 609,7
// Check FTDI
if (!CheckCable())
{
fprintf(stderr, "XVC Cable unexpectadly disconnected\n");
fprintf(stderr, "XVC Cable unexpectedly disconnected\n");
closesocket(ListenSocket);
WSACleanup();
jtagClosePort();
548,8 → 616,11
return -2;
}
// Sleep some time (do not eat CPU time for nothong)
//nanosleep();
#ifdef WIN32
Sleep(100); //ms
#else
usleep(100000); //us
#endif
}
}
}
556,6 → 627,8
while (ClientSocket == INVALID_SOCKET);
 
// Set (Accepted) Socket to blocking mode
 
#ifdef WIN32
iMode = 0;
iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode);
if (iResult != NO_ERROR)
565,6 → 638,15
jtagClosePort();
return -2;
}
#else
iResult = fcntl(ListenSocket, F_GETFL, 0);
if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult & ~O_NONBLOCK) < 0)
{
fprintf(stderr, "fcntl failed with error: %d\n", errno);
jtagClosePort();
return -2;
}
#endif
 
// Print Accepted + Address
printf(" Accepted ");
584,6 → 666,7
if (iResult>=0)
{
printf(".");
fflush(stdout);
Cnt++;
if (Cnt>40)
{
605,7 → 688,11
if (iResult==-2)
{
fprintf(stderr, " Disconnect\n");
#ifdef WIN32
iResult = shutdown(ClientSocket, SD_SEND);
#else
iResult = shutdown(ClientSocket, SHUT_WR);
#endif
if (iResult == SOCKET_ERROR)
{
fprintf(stderr, "shutdown failed with error: %d\n", WSAGetLastError());