Rev 2935 Rev 2940
Line 12... Line 12...
12 // 1.01 2012_09 Added parameter for device selection 12 // 1.01 2012_09 Added parameter for device selection
13 // 1.02 2012_12 Error handling and debugged 13 // 1.02 2012_12 Error handling and debugged
14 // 1.03 2012_12 Release version ready to publish 14 // 1.03 2012_12 Release version ready to publish
15 // 1.04 2013_04 Socket Bind Error with explanation (multiple instance of XVC Server) 15 // 1.04 2013_04 Socket Bind Error with explanation (multiple instance of XVC Server)
16 // 1.05 2013-04 Test FTDI cable during wait for Accept (to stop the server immediately when cable is disconnected) 16 // 1.05 2013-04 Test FTDI cable during wait for Accept (to stop the server immediately when cable is disconnected)
-   17 // 1.06 2013-04 Added support for Linux (thanks to Martin Poviser)
17 // 18 //
18 // 19 //
19 // Purpose: 20 // Purpose:
20 // 21 //
21 // XILINX development software (ISE, WebPack) supports several types of JTAG programming 22 // XILINX development software (ISE, WebPack) supports several types of JTAG programming
Line 57... Line 58...
57 // XVC protocol is documented (you have to ask XILINX support to gain access). 58 // XVC protocol is documented (you have to ask XILINX support to gain access).
58 // The program is inspired by the work http://debugmo.de/2012/02/xvcd-the-xilinx-virtual-cable-daemon/ 59 // The program is inspired by the work http://debugmo.de/2012/02/xvcd-the-xilinx-virtual-cable-daemon/
59 // Ask Google about Xilinx Virtual Cable. 60 // Ask Google about Xilinx Virtual Cable.
60 // 61 //
61 // 62 //
62 // Compilation: 63 // Compilation for Windows:
63 // 64 //
64 // MS Visual C++ 2010 Express (free, registration required) 65 // MS Visual C++ 2010 Express (free, registration required)
65 // Create new empty project for Win32 Console Application and name project mlab_xvcd (to build mlab_xvcd.exe) 66 // Create new empty project for Win32 Console Application and name project mlab_xvcd (to build mlab_xvcd.exe)
66 // Header Files / Add / Existing Items - all .h files 67 // Header Files / Add / Existing Items - all .h files
67 // Resource Files / Add / Existing Items - all .lib files -  
68 // Source Files / Add / Existing Items - all .cpp files 68 // Source Files / Add / Existing Items - all .cpp files
-   69 // Library Files / Add / Existing Items - all .lib .h files from lib_win32 directory
69 // Select Release version (no debug info) 70 // Select Release version (no debug info)
70 // Set static linkage Project Properties / Configuration Release / Configuration Properties 71 // Set static linkage Project Properties / Configuration Release / Configuration Properties
71 // / Code Generation / Runtime Library = Multithreaded (/MT) 72 // / Code Generation / Runtime Library = Multithreaded (/MT)
72 // 73 //
-   74 // Compilation for Linux:
-   75 //
-   76 // On Ubuntu 12.04LTS just run the .sh file
73 // 77 //
74 // Problems: 78 // Problems:
75 // 79 //
76 // Programming of SPI FLASH configuration memory connected to FPGA does not work. No idea why. 80 // Programming of SPI FLASH configuration memory connected to FPGA does not work. No idea why.
77 // It does not work for internal FLASH of Spartan XC3SxxAN either. 81 // It does not work for internal FLASH of Spartan XC3SxxAN either.
Line 89... Line 93...
89   93  
90 #undef UNICODE 94 #undef UNICODE
91 #define WIN32_LEAN_AND_MEAN 95 #define WIN32_LEAN_AND_MEAN
92   96  
93 #include "mlab_xvcd.h" // Program Configuration 97 #include "mlab_xvcd.h" // Program Configuration
94 #include <windows.h> // Windows Console Application -  
95 #include <winsock2.h> // Windows WinSock2 -  
96 #include <ws2tcpip.h> // Windows WinSock2 -  
97 #include <stdlib.h> // Standard Library (exit, atoi, ...) 98 #include <stdlib.h> // Standard Library (exit, atoi, ...)
98 #include <stdio.h> // Standard IO (printf, ...) 99 #include <stdio.h> // Standard IO (printf, ...)
99 #include <signal.h> // CTRL+C handling 100 #include <signal.h> // CTRL+C handling
100   101  
-   102 #ifdef WIN32
-   103  
-   104 #include <windows.h> // Windows Console Application
-   105 #include <winsock2.h> // Windows WinSock2
-   106 #include <ws2tcpip.h> // Windows WinSock2
-   107  
101 // Link with library 108 // Link with library
102 #pragma comment (lib, "Ws2_32.lib") 109 #pragma comment (lib, "Ws2_32.lib")
-   110 //#pragma comment (lib, "../lib_win32/ftd2xx.lib") // Add this file to Resources
-   111  
-   112 #else // not WIN32
-   113  
-   114 #include "lib_linux_i386/WinTypes.h"
-   115 #include <sys/types.h>
-   116 #include <sys/socket.h>
-   117 #include <fcntl.h>
-   118 #include <errno.h>
-   119 #include <unistd.h>
-   120 #include <netdb.h>
-   121  
-   122 #endif
103   123  
104 #define XVC_RX_BUFLEN (XVC_JTAG_LEN/8*2+20) // Length of receive buffer in bytes (command+length+TMSbuffer+TDIbuffer) 124 #define XVC_RX_BUFLEN (XVC_JTAG_LEN/8*2+20) // Length of receive buffer in bytes (command+length+TMSbuffer+TDIbuffer)
105 #define XVC_TX_BUFLEN (XVC_JTAG_LEN/8) // Length of transmit buffer in bytes (TDObuffer) 125 #define XVC_TX_BUFLEN (XVC_JTAG_LEN/8) // Length of transmit buffer in bytes (TDObuffer)
106   126  
-   127 #ifdef WIN32
-   128  
-   129 typedef int socklen_t;
-   130  
-   131 #else //not WIN32
-   132  
-   133 typedef int SOCKET;
-   134  
-   135 #define SOCKET_ERROR -1
-   136 #define INVALID_SOCKET -1
-   137  
-   138 void closesocket(int socket)
-   139 {
-   140 close(socket);
-   141 }
-   142  
-   143 void WSACleanup()
-   144 {
-   145 }
-   146  
-   147 int WSAGetLastError()
-   148 {
-   149 return errno;
-   150 }
-   151  
-   152 #endif
107   153  
108 // JTAG state machine 154 // JTAG state machine
109 // ------------------ 155 // ------------------
110   156  
111 // JTAG States 157 // JTAG States
Line 166... Line 212...
166 { 212 {
167 int iResult; 213 int iResult;
168   214  
169 // Read Command 215 // Read Command
170 char command[16]; 216 char command[16];
171 int commandLen = 0; 217 unsigned int commandLen = 0;
172   218  
173 // Read String terminated by ':' 219 // Read String terminated by ':'
174 do 220 do
175 { 221 {
176 iResult = recv(ClientSocket, command+commandLen, 1, 0); 222 iResult = recv(ClientSocket, command+commandLen, 1, 0);
Line 218... Line 264...
218 } 264 }
219   265  
220 char buffer[2048]; 266 char buffer[2048];
221   267  
222 // Read Data (data string for TMS and TDI) 268 // Read Data (data string for TMS and TDI)
223 int nr_bytes = (len + 7) / 8; 269 unsigned int nr_bytes = (len + 7) / 8;
224 if (nr_bytes * 2 > sizeof(buffer)) 270 if (nr_bytes * 2 > sizeof(buffer))
225 { 271 {
226 fprintf(stderr, "Buffer Size Exceeded\n"); 272 fprintf(stderr, "Buffer Size Exceeded\n");
227 return -2; 273 return -2;
228 } 274 }
229   275  
230 int iReceivedBytes=0; 276 unsigned int iReceivedBytes=0;
231 while (iReceivedBytes<nr_bytes * 2) 277 while (iReceivedBytes<nr_bytes * 2)
232 { 278 {
233 iResult = recv(ClientSocket, buffer+iReceivedBytes, nr_bytes * 2 - iReceivedBytes, 0); 279 iResult = recv(ClientSocket, buffer+iReceivedBytes, nr_bytes * 2 - iReceivedBytes, 0);
234 if (iResult==0) 280 if (iResult==0)
235 { 281 {
Line 300... Line 346...
300 return jtagError ? -2 : 0; 346 return jtagError ? -2 : 0;
301 } 347 }
302   348  
303   349  
304 // Stop Handler - switch JTAG port off and stop program 350 // Stop Handler - switch JTAG port off and stop program
305 void stopHandler(int sig) 351 void stopHandler(int)
306 { 352 {
307 jtagClosePort(); 353 jtagClosePort();
308 exit(1); 354 exit(1);
309 } 355 }
310   356  
Line 324... Line 370...
324 fprintf(stderr, " The first FTDI device is used if no argument\n"); 370 fprintf(stderr, " The first FTDI device is used if no argument\n");
325 exit(2); 371 exit(2);
326 } 372 }
327   373  
328   374  
329 int __cdecl main(int argc, char *argv[]) 375 int main(int argc, char *argv[])
330 { 376 {
331 // Variables 377 // Variables
332 bool verbose = true; 378 bool verbose = true;
333   379  
334 // Program Info 380 // Program Info
Line 386... Line 432...
386 } 432 }
387 else 433 else
388 { 434 {
389 // Empty String - find device by number and number is empty 435 // Empty String - find device by number and number is empty
390 findDeviceBy = 0; 436 findDeviceBy = 0;
391 findDeviceByStr = ""; 437 findDeviceByStr = (char *)"";
392 } 438 }
393   439  
394 // Find, Init and Open FTDI USB Chip 440 // Find, Init and Open FTDI USB Chip
395 if (jtagOpenPort(findDeviceBy, findDeviceByStr)<0) { 441 if (jtagOpenPort(findDeviceBy, findDeviceByStr)<0) {
396 // No Device Found 442 // No Device Found
Line 400... Line 446...
400   446  
401 // Signal Handler (for CRTL+C) 447 // Signal Handler (for CRTL+C)
402 signal(SIGINT, &stopHandler); 448 signal(SIGINT, &stopHandler);
403   449  
404 printf("Starting Network Server\n"); 450 printf("Starting Network Server\n");
405 WSADATA wsaData; -  
406 int iResult; 451 int iResult;
407   452  
408 SOCKET ListenSocket = INVALID_SOCKET; 453 SOCKET ListenSocket = INVALID_SOCKET;
409 SOCKET ClientSocket = INVALID_SOCKET; 454 SOCKET ClientSocket = INVALID_SOCKET;
410   455  
-   456 #ifdef WIN32
411 // Initialize Winsock 457 // Initialize Winsock
-   458 WSADATA wsaData;
412 iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 459 iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
413 if (iResult != 0) 460 if (iResult != 0)
414 { 461 {
415 fprintf(stderr, "WSAStartup failed with error: %d\n", iResult); 462 fprintf(stderr, "WSAStartup failed with error: %d\n", iResult);
416 jtagClosePort(); 463 jtagClosePort();
417 return -2; 464 return -2;
418 } 465 }
-   466 #endif
419   467  
420 // Display HostName and Address 468 // Display HostName and Address
421 char sMyName[255]; 469 char sMyName[255];
422 gethostname(sMyName, sizeof(sMyName)); 470 gethostname(sMyName, sizeof(sMyName));
423 printf(" Host Name %s\n", sMyName); 471 printf(" Host Name %s\n", sMyName);
Line 434... Line 482...
434 printf("%d\n", (unsigned char)pHostInfo->h_addr_list[0][pHostInfo->h_length-1]); 482 printf("%d\n", (unsigned char)pHostInfo->h_addr_list[0][pHostInfo->h_length-1]);
435 } 483 }
436   484  
437 // Create Protocol Structure 485 // Create Protocol Structure
438 struct addrinfo hints; 486 struct addrinfo hints;
439 ZeroMemory(&hints, sizeof(hints)); 487 memset(&hints, 0, sizeof(hints));
440 hints.ai_family = AF_INET; // IP6 488 hints.ai_family = AF_INET; // IP6
441 hints.ai_socktype = SOCK_STREAM; // Reliable two-way connection 489 hints.ai_socktype = SOCK_STREAM; // Reliable two-way connection
442 hints.ai_protocol = IPPROTO_TCP; // Protocol TCP 490 hints.ai_protocol = IPPROTO_TCP; // Protocol TCP
443 hints.ai_flags = AI_PASSIVE; 491 hints.ai_flags = AI_PASSIVE;
444   492  
Line 455... Line 503...
455   503  
456 // Create a SOCKET 504 // Create a SOCKET
457 ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); 505 ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
458 if (ListenSocket == INVALID_SOCKET) 506 if (ListenSocket == INVALID_SOCKET)
459 { 507 {
460 fprintf(stderr, "socket failed with error: %ld\n", WSAGetLastError()); 508 fprintf(stderr, "socket failed with error: %d\n", WSAGetLastError());
461 freeaddrinfo(result); 509 freeaddrinfo(result);
462 WSACleanup(); 510 WSACleanup();
463 jtagClosePort(); 511 jtagClosePort();
464 return -2; 512 return -2;
465 } 513 }
Line 468... Line 516...
468 iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); 516 iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
469 if (iResult == SOCKET_ERROR) 517 if (iResult == SOCKET_ERROR)
470 { 518 {
471 int LastError=WSAGetLastError(); 519 int LastError=WSAGetLastError();
472 fprintf(stderr, "Bind failed with error: %d\n", LastError); 520 fprintf(stderr, "Bind failed with error: %d\n", LastError);
-   521 #ifdef WIN32
-   522 if (LastError==WSAEADDRINUSE)
-   523 #else
-   524 if (LastError==EADDRINUSE)
-   525 #endif
473 if (LastError==WSAEADDRINUSE) fprintf(stderr, "Trying to start second instance of XVC Server?\n"); 526 fprintf(stderr, "Trying to start second instance of XVC Server?\n");
474 freeaddrinfo(result); 527 freeaddrinfo(result);
475 closesocket(ListenSocket); 528 closesocket(ListenSocket);
476 WSACleanup(); 529 WSACleanup();
477 jtagClosePort(); 530 jtagClosePort();
478 return -2; 531 return -2;
Line 506... Line 559...
506 printf(" Listen\n"); 559 printf(" Listen\n");
507 jtagSetLED(true); 560 jtagSetLED(true);
508   561  
509 // Set ListenSocket to non-blocking mode 562 // Set ListenSocket to non-blocking mode
510 // We need during waiting for Accept to detect FTDI disconnect 563 // We need during waiting for Accept to detect FTDI disconnect
-   564  
-   565 #ifdef WIN32
511 u_long iMode = 1; 566 u_long iMode = 1;
512 iResult = ioctlsocket(ListenSocket, FIONBIO, &iMode); 567 iResult = ioctlsocket(ListenSocket, FIONBIO, &iMode);
513 if (iResult != NO_ERROR) 568 if (iResult != NO_ERROR)
514 { 569 {
515 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult); 570 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult);
516 WSACleanup(); 571 WSACleanup();
517 jtagClosePort(); 572 jtagClosePort();
518 return -2; 573 return -2;
519 } 574 }
-   575 #else
-   576 iResult = fcntl(ListenSocket, F_GETFL, 0);
-   577 if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult | O_NONBLOCK) < 0)
-   578 {
-   579 fprintf(stderr, "fcntl failed with error: %d\n", errno);
-   580 jtagClosePort();
-   581 return -2;
-   582 }
-   583 #endif
520   584  
521 // Accept a client SOCKET (wait for Accept) 585 // Accept a client SOCKET (wait for Accept)
522 sockaddr ClientSocetAddr; 586 sockaddr ClientSocetAddr;
523 int ClientSocetAddrLen = sizeof(sockaddr); 587 socklen_t ClientSocetAddrLen = sizeof(sockaddr);
524 do 588 do
525 { 589 {
526 // Try Accept (non-blocking) 590 // Try Accept (non-blocking)
527 ClientSocket = accept(ListenSocket, &ClientSocetAddr, &ClientSocetAddrLen); 591 ClientSocket = accept(ListenSocket, &ClientSocetAddr, &ClientSocetAddrLen);
528 if (ClientSocket == INVALID_SOCKET) 592 if (ClientSocket == INVALID_SOCKET)
529 { 593 {
530 // Accept Error 594 // Accept Error
-   595 #ifdef WIN32
531 if (WSAGetLastError() != WSAEWOULDBLOCK) 596 if (WSAGetLastError() != WSAEWOULDBLOCK)
-   597 #else
-   598 if (WSAGetLastError() != EAGAIN && WSAGetLastError() != EWOULDBLOCK)
-   599 #endif
532 { 600 {
533 fprintf(stderr, "accept failed with error: %d\n", WSAGetLastError()); 601 fprintf(stderr, "accept failed with error: %d\n", WSAGetLastError());
534 closesocket(ListenSocket); 602 closesocket(ListenSocket);
535 WSACleanup(); 603 WSACleanup();
536 jtagClosePort(); 604 jtagClosePort();
Line 539... Line 607...
539 // Not yet Accepted 607 // Not yet Accepted
540 { 608 {
541 // Check FTDI 609 // Check FTDI
542 if (!CheckCable()) 610 if (!CheckCable())
543 { 611 {
544 fprintf(stderr, "XVC Cable unexpectadly disconnected\n"); 612 fprintf(stderr, "XVC Cable unexpectedly disconnected\n");
545 closesocket(ListenSocket); 613 closesocket(ListenSocket);
546 WSACleanup(); 614 WSACleanup();
547 jtagClosePort(); 615 jtagClosePort();
548 return -2; 616 return -2;
549 } 617 }
550 // Sleep some time (do not eat CPU time for nothong) 618 // Sleep some time (do not eat CPU time for nothong)
551 //nanosleep(); 619 #ifdef WIN32
552 Sleep(100); //ms 620 Sleep(100); //ms
-   621 #else
-   622 usleep(100000); //us
-   623 #endif
553 } 624 }
554 } 625 }
555 } 626 }
556 while (ClientSocket == INVALID_SOCKET); 627 while (ClientSocket == INVALID_SOCKET);
557   628  
558 // Set (Accepted) Socket to blocking mode 629 // Set (Accepted) Socket to blocking mode
-   630  
-   631 #ifdef WIN32
559 iMode = 0; 632 iMode = 0;
560 iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode); 633 iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode);
561 if (iResult != NO_ERROR) 634 if (iResult != NO_ERROR)
562 { 635 {
563 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult); 636 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult);
564 WSACleanup(); 637 WSACleanup();
565 jtagClosePort(); 638 jtagClosePort();
566 return -2; 639 return -2;
567 } 640 }
-   641 #else
-   642 iResult = fcntl(ListenSocket, F_GETFL, 0);
-   643 if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult & ~O_NONBLOCK) < 0)
-   644 {
-   645 fprintf(stderr, "fcntl failed with error: %d\n", errno);
-   646 jtagClosePort();
-   647 return -2;
-   648 }
-   649 #endif
568   650  
569 // Print Accepted + Address 651 // Print Accepted + Address
570 printf(" Accepted "); 652 printf(" Accepted ");
571 jtagSetLED(false); 653 jtagSetLED(false);
572 for (int i=2; i<2+4-1; i++) 654 for (int i=2; i<2+4-1; i++)
Line 582... Line 664...
582 { 664 {
583 iResult = handleData(ClientSocket); 665 iResult = handleData(ClientSocket);
584 if (iResult>=0) 666 if (iResult>=0)
585 { 667 {
586 printf("."); 668 printf(".");
-   669 fflush(stdout);
587 Cnt++; 670 Cnt++;
588 if (Cnt>40) 671 if (Cnt>40)
589 { 672 {
590 Cnt = 0; 673 Cnt = 0;
591 printf("\n "); 674 printf("\n ");
Line 603... Line 686...
603   686  
604 // Error - shutdown the connection 687 // Error - shutdown the connection
605 if (iResult==-2) 688 if (iResult==-2)
606 { 689 {
607 fprintf(stderr, " Disconnect\n"); 690 fprintf(stderr, " Disconnect\n");
-   691 #ifdef WIN32
608 iResult = shutdown(ClientSocket, SD_SEND); 692 iResult = shutdown(ClientSocket, SD_SEND);
-   693 #else
-   694 iResult = shutdown(ClientSocket, SHUT_WR);
-   695 #endif
609 if (iResult == SOCKET_ERROR) 696 if (iResult == SOCKET_ERROR)
610 { 697 {
611 fprintf(stderr, "shutdown failed with error: %d\n", WSAGetLastError()); 698 fprintf(stderr, "shutdown failed with error: %d\n", WSAGetLastError());
612 } 699 }
613 iResult=-2; // Error 700 iResult=-2; // Error