#include <ansi_c.h>
 
#include <cvirte.h>
 
#include "ftd2xx.h"
 
#include <utility.h>
 
 
 
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
                       LPSTR lpszCmdLine, int nCmdShow) {
 
 
 
  BYTE bufOut[1024],bufIn[1024];
 
  DWORD bToSend, bSent, bToReceive, bReceived;
 
  DWORD dwClockDivisor=29;//Value of clock divisor, SCL Frequency = 60/((1+29)*2) (MHz) = 1Mhz
 
  DWORD numDevs;
 
  DWORD Flags;
 
  DWORD ID;
 
  DWORD Type;
 
  DWORD LocId;
 
  char SerialNumber[16];
 
  char Description[64];
 
  FT_STATUS ftStatus;
 
  FT_HANDLE ftHandle,ftHandleTemp;
 
  FT_DEVICE_LIST_INFO_NODE *devInfo;
 
  
 
  if (InitCVIRTE (hInstance, 0, 0) == 0)
 
    return -1;    /* out of memory */
 
// create the device information list
 
  ftStatus = FT_CreateDeviceInfoList(&numDevs);
 
  if (ftStatus == FT_OK) {
 
    printf("Number of devices is %d\n",numDevs
);  
  }
 
  if (numDevs > 0) {
 
// allocate storage for list based on numDevs
 
    devInfo 
= (FT_DEVICE_LIST_INFO_NODE
*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE
)*numDevs
); 
// get the device information list
 
    ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs);
 
    if (ftStatus == FT_OK) {
 
      for (int i = 0; i < numDevs; i++) {
 
        printf(" Flags=0x%x\n",devInfo
[i
].
Flags);  
        printf(" Type=0x%x\n",devInfo
[i
].
Type);  
        printf(" ID=0x%x\n",devInfo
[i
].
ID);  
        printf(" LocId=0x%x\n",devInfo
[i
].
LocId);  
        printf(" SerialNumber=%s\n",devInfo
[i
].
SerialNumber);  
        printf(" Description=%s\n",devInfo
[i
].
Description);  
        printf(" ftHandle=0x%x\n",devInfo
[i
].
ftHandle);  
      }
 
    }
 
// get information for device 0
 
/*
 
    ftStatus = FT_GetDeviceInfoDetail(0, &Flags, &Type, &ID, &LocId, SerialNumber, Description, &ftHandleTemp);
 
    if (ftStatus == FT_OK) {
 
      printf("Dev 0:\n");
 
      printf(" Flags=0x%x\n",Flags);
 
      printf(" Type=0x%x\n",Type);
 
      printf(" ID=0x%x\n",ID);
 
      printf(" LocId=0x%x\n",LocId);
 
      printf(" SerialNumber=%s\n",SerialNumber);
 
      printf(" Description=%s\n",Description);
 
      printf(" ftHandle=0x%x\n",ftHandleTemp);
 
    }
 
*/
 
  }
 
  ftStatus = FT_Open(0,&ftHandle);
 
  if (ftStatus != FT_OK) {
 
    printf("Can't open FT232H device! \n");  
    return 1;
 
  } else // Port opened successfully
 
    printf("Successfully open FT2232H device! \n");  
 
 
// reset device
 
  ftStatus = FT_ResetDevice(ftHandle);
 
//Purge USB receive buffer first by reading out all old data from FT232H receive buffer
 
  ftStatus |= FT_GetQueueStatus(ftHandle, &bToReceive); // Get the number of bytes in the FT232H receive buffer
 
  if ((ftStatus == FT_OK) && (bToReceive > 0))
 
    ftStatus |= FT_Read(ftHandle, bufIn, bToReceive, &bReceived); //Read out the data from FT232H receive buffer
 
  ftStatus |= FT_SetUSBParameters(ftHandle, 65535, 65535); //Set USB request transfer size
 
  ftStatus |= FT_SetChars(ftHandle, FALSE, 0, FALSE, 0); //Disable event and error characters
 
  ftStatus |= FT_SetTimeouts(ftHandle, 3000, 3000); //Sets the read and write timeouts in 3 sec for the FT232H
 
  ftStatus |= FT_SetLatencyTimer(ftHandle, 1); //Set the latency timer
 
  ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x00); //Reset controller
 
  ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x02); //Enable MPSSE mode
 
  if (ftStatus != FT_OK) {
 
    printf("fail on initialize FT2232H device ! \n");  
    return FALSE;
 
  }
 
  Sleep(50); // Wait 50ms for all the USB stuff to complete and work
 
  
 
// test communication by sending bad command 0xAA
 
  bToSend=0;
 
  bufOut[bToSend++]=0xAA;
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent);
 
  do{
 
    ftStatus = FT_GetQueueStatus(ftHandle, &bToReceive); // Get the number of bytes in the device input buffer
 
  }while ((bToReceive == 0) && (ftStatus == FT_OK)); //or Timeout
 
  ftStatus = FT_Read(ftHandle, bufIn, bToReceive, &bReceived); //Read out the data from input buffer
 
  printf("Received byts: %d",bReceived
);  
  if (bReceived 
> 1) printf(": 0x%02X, 0x%02X",bufIn
[bReceived
-2],bufIn
[bReceived
-1]);  
 
 
  bToSend=0;
 
  bufOut[bToSend++]=0xAB;
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent);
 
  do{
 
    ftStatus = FT_GetQueueStatus(ftHandle, &bToReceive); // Get the number of bytes in the device input buffer
 
  }while ((bToReceive == 0) && (ftStatus == FT_OK)); //or Timeout
 
  ftStatus = FT_Read(ftHandle, bufIn, bToReceive, &bReceived); //Read out the data from input buffer
 
  printf("Received bytes: %d",bReceived
);  
  if (bReceived 
> 1) printf(": 0x%02X, 0x%02X",bufIn
[bReceived
-2],bufIn
[bReceived
-1]);  
 
 
  bToSend=0;
 
  bufOut[bToSend++]=0x8A;//Ensure disable clock divide by 5 for 60Mhz master clock
 
  bufOut[bToSend++]=0x97;//Ensure turn off adaptive clocking
 
  bufOut[bToSend++]=0x8D;//disable 3 phase data clock
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent);
 
  
 
  bToSend = 0;
 
  bufOut[bToSend++]=0x80; //Command to set directions of lower 8 pins and force value on bits set as output
 
  bufOut[bToSend++]=0x00; //Set SDA, SCL high, WP disabled by SK, DO at bit &*, GPIOL0 at bit &*
 
  bufOut[bToSend++]=0x0B; //Set SK,DO,GPIOL0 pins as output with bit **, other pins as input with bit &*
 
// The SK clock frequency can be worked out by below algorithm with divide by 5 set as off
 
// SK frequency = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2)
 
  bufOut[bToSend++]=0x86; //Command to set clock divisor
 
  bufOut[bToSend++]=dwClockDivisor & 0xFF; //Set 0xValueL of clock divisor
 
  bufOut[bToSend++]=dwClockDivisor >> 8; //Set 0xValueH of clock divisor
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent); // Send out the commands
 
  Sleep(20); //Delay for a while
 
//Turn off loop back in case
 
  bToSend = 0;
 
  bufOut[bToSend++]=0x85; //Command to turn off loop back of TDI/TDO connection
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent); // Send out the commands
 
  Sleep(30); //Delay for a while
 
  printf("SPI initialized successfuly\n");  
  
 
  bToSend=0;
 
  bufOut[bToSend++]=0x82;// set ACBUS 0-7 
 
  bufOut[bToSend++]=0x00;// value
 
  bufOut[bToSend++]=0x00;// direction 0-input  
 
  bufOut[bToSend++]=0x80;// set ADBUS 0-7  
 
  bufOut[bToSend++]=0xF0;  
 
  bufOut[bToSend++]=0xFF;  
 
  bufOut[bToSend++]=0x81;// read ADBUS
 
  bufOut[bToSend++]=0x83;// read ACBUS  
 
  bufOut[bToSend++]=0x80;  
 
  bufOut[bToSend++]=0x00;  
 
  bufOut[bToSend++]=0xFF;  
 
  bufOut[bToSend++]=0x81;  
 
  bufOut[bToSend++]=0x83;  
 
  ftStatus = FT_Write(ftHandle, bufOut, bToSend, &bSent);
 
  do{
 
    ftStatus = FT_GetQueueStatus(ftHandle, &bToReceive); // Get the number of bytes in the device input buffer
 
  }while ((bToReceive == 0) && (ftStatus == FT_OK)); //or Timeout
 
  ftStatus = FT_Read(ftHandle, bufIn, bToReceive, &bReceived); //Read out the data from input buffer
 
  printf("Received bytes: 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",bufIn
[0],bufIn
[1],bufIn
[2],bufIn
[3]);  
  
 
//  Delay(10);
 
  FT_Close(ftHandle);
 
  return 0;
 
}