
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^GIGEXD.C^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/               
#include <stdio.h>            /* Standard ANSI C Include Files      */
#include <stdlib.h>
#include <math.h>       
#include <time.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <curses.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/stat.h>


/* From Dave C. */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>    /* for FIONBIO                                                            */
#include <netinet/in.h>   /* struct in_addr (internet address), struct sockaddr_in,  struct ip_mreq */
#include <arpa/inet.h>    /* for inet_* calls                                                       */
#include <netdb.h>        /* for gethostbyaddr call                                                 */



#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE  1
#endif

#ifndef SUCCESSFUL
#define SUCCESSFUL 1
#endif

#ifndef NOT_SUCCESSFUL
#define NOT_SUCCESSFUL 0
#endif

typedef unsigned char  int_u1;                     /* Typedefs For Size Operations-8 Bits   */
typedef unsigned short int_u2;                     /* Type  int_u2 = Unsigned 16 Bits       */
typedef unsigned int   int_u4;                     /* Type  int_u4 = Unsigned 32 Bits       */
typedef long int       int_4;                      /* Type  int_4  = Signed   32 Bits       */
typedef u_int64_t      int_u8;                     /* Type  int_u8 = Unsigned 64 Bits       */  
typedef int64_t        int_8;                      /* Type  int_8  = Signed   64 Bits       */

#define INVALID_SOCKET -1
typedef int SOCKET;


#define GIGMEMBUFSIZE          10485760            /* Size Of GIGE Memory Buffer            */  

 
#define SECTOR_ERASE                  1            /* Enable Individual Sector Erase        */         

#define MAXFNAME                80                 /* Maximum Path & Filename Size          */  
#define ONEMEG                  1048576            /* One Megabyte                          */

/* Globals */
struct sockaddr_in Client;
int Client_len;

/* Software Version   */
#define GE_SOFTWAREVERS          0x0220            /* Version 2.04 Of Software                               */
#define GE_LASTCOMPATVERS        0x0220            /* Version 2.04 Last Compatible Version With This Version */

#define IOMT_NONE  0
#define IOMT_DR2D -1
#define IOMT_A2D  -3

/* GIGEXD Rev1 & Rev2 */    
#define GE_MAXGEREVS                  2            /* Number Of GIGEXD Hardware Revisions                   */
#define GE_GER1IDVAL                  0            /* GIGEXD Rev 1 Value                                    */
#define GE_GER2IDVAL                  1            /* GIGEXD Rev 2 Value                                    */ 
#define GE_MAXFWDNLDS                 8            /* Max Number Of Firmware Downloads Per Rev              */
#define GE_IDADDRESS             0x0040            /* Address Where ID Value For GIGEXD Resides             */     
#define GER1_IDDETECT            0x1818            /* GIGEXD Rev 1 Detect Value                             */
#define GER2_IDDETECT            0x1C1C            /* GIGEXD Rev 2 Detect Value                             */
  
/* Communication/Filename Defaults     */ 
#define SENDPORT                 1300              /* This Machine UDP Port For Send                        */    
#define DESTPORT                 2300              /* GigE Module Rx UPD Port                               */
#define SDDSTXPORT               29495             /* SDDS UDP Port Number Of Data Transmission             */
#define DEFAULT_PROGFILE         "gigexd.rpd"      /* Default Programming File-In Local Directory           */
#define DEFAULT_USRCFGFILE       "gigexdusr.cfg"   /* Default User Area Config File-In Local Directory      */
#define DEFAULT_DEFCFGFILE       "gigexddef.cfg"   /* Default Default Area Config File-Local Directory      */                  
#define MAX_GIGE_TRANSFER        100000000.0       /* Maximum GIGEXD Data Transfer Rate                     */
#define GE_RDFLASH_SIZE               16           /* Size Of Read From Flash-In Bytes                      */

/* I/O Module Definitions              */
#define GE_IOMCFG_SIZE              1024           /* Size Configuration Space For I/O Modules              */      
#define A2D_REFCLK_FREQ       10000000.0           /* A2DR7, A2DR8, A2DR9 Reference Clock Frequency         */
#define A2D_DEFAULT_R              100.0           /* Default Synthetic Clock R Value                       */
#define A2D_DEFAULT_N             7440.0           /* Default Synthetic Clock N Value                       */

#define GE_TIMEC_SCALAR    (8.0 * 1048576.0)       /* Scalar For Clock Period For Timecode Calcs            */     

#define CFGPKTDATASIZE            22               /* Configuration Packet Data Size                        */
#define SDDSPKTHDRSIZE            56               /* Size Of SDDS Header                                   */
#define SDDSPKTDATASIZE           1024             /* Size Of SDDS Data                                     */
#define SDDSPKTSIZE               1080             /* Size Of SDDS Packet (Header + Data Size)              */
#define GE_PKTTCOFFSET             4               /* Timecode Offset Within SDDS Header (In Bytes)         */  
#define GE_PKTTCSIZE              16               /* Timecode Length (In Bytes)                            */
   
/* Define EPROM Programming Operations */
#define GE_EPROMSECTORSIZE        0x00010000       /* EPROM Sector Size = 64K                               */
#define GER1_IDWORDADDRESS        0x00098000       /* GIGEXDR1 FPGA Program ID Value Address                */
#define GER2_IDWORDADDRESS        0x00198000       /* GIGEXDR2 FPGA Program ID Value Address                */

#define GE_CFGNRPLYHDRVAL         0xA5A5           /* Config Hdr-Reply With Identical Packet Data           */
#define GE_CFGREPLYHDRVAL         0xB4B4           /* Config Hdr-Reply With EPROM Read Data                 */                       
#define GE_EPROMENDCFGVAL         0xFFFF           /* Value To End Configuration Data In Packet             */
#define GE_EPROMCFGSIZE           0x00020000       /* Size Of Cfg User Space & Default Cfg Space            */
#define GE_CFGAREASIZE            0x00010000       /* Size Of Cfg Space For Each Download                   */  
#define GE_EPROMQUERYADR          0x0000C000       /* Offset In Cfg Space To Query Info                     */
#define GE_EPROMCFGSPACE          0x000A0000       /* Start of Cfg Space (After Programming Words)          */
#define GE_EPROMDWNCFGADDR  (0x000A0000 + GE_EPROMQUERYADR - 2) /* Download Config Number Address           */    
#define GE_MAGICNUMBER            0xABCD           /* 'Magic" Num To ID File As Correct Program File        */
#define GER1_MAGICNUMADR          0x00099000       /* 'Magic' Num Addr To ID File As Correct Program File   */
#define GER2_MAGICNUMADR          0x00199000       /* 'Magic' Num Addr To ID File As Correct Program File   */
#define GER1_EPROMENDPROG         0x000A0000       /* GIGEXDR1 End Program Area                             */
#define GER2_EPROMENDPROG         0x00130000       /* GIGEXDR2 End Program Area                             */
#define GER2_DETECTSECT           0x00190000       /* Sector Address Of GIGEXDR2 Detect Area                */ 
#define GER1_EPROMDEFSPACE        0x000B0000       /* Start of GIGEXDR1 Default Cfg Space (After Cfp Space) */
#define GER2_EPROMDEFSPACE        0x001B0000       /* Start of GIGEXDR2 Default Cfg Space (After Cfp Space) */


/* Register Addresses                  */
#define GE_RXCFGADDR              0x0000           /* Rx CPU DP Address                                     */
#define GE_SYNCLKADDR             0x1000           /* Synthetic Clock N/R Register                          */
#define GE_INPUTCFGADDR           0x2000           /* Input Configuration Register Address                  */
#define GE_TXCFGADDR              0x4000           /* Tx CPU DP or Data DP Address                          */ 
#define GE_TXRSTADDR              0x5000           /* Write Reg W/ 0 To Turn Off Data, W/ 1 To Turn On Data */
#define GE_VLANTXCFGADDR          0x7000           /* Tx VLAN CPU DP or Data DP Address                     */
#define GE_TUNCFGADDR             0x8000           /* Tuner Cfg Registers                                   */
#define GE_PULSENCFGADDR          0xA000           /* Pulse The nConfig Line                                */
#define GE_EPROMCFGPAGEADDR       0xB000           /* Eprom Wr Page Address Reg Flash Register Address      */ 
#define GE_EPROMCFGWRDATA         0xC000           /* Eprom Wr Flash Register Address                       */ 
#define GE_EPROMCFGCLRSECTOR      0xD000           /* Eprom Clear Flash Register Address                    */ 
#define GE_EPROMCFGRDDATA         0xE000           /* Eprom Rd Flash Register Address                       */ 


/* Tx Logic Low Level Addresses       */ 
#define GE_TX_CPUWRADDR           0x0100           /* Offset Of Tx CPU  DP Region                           */                        
#define GE_TX_DATWRADDR           0x0200           /* Offset Of Tx Data DP Region                           */
#define GE_TX_DATRDADDR           0x0400           /* Offset Of Tx Data DP Rd Register                      */
#define GE_TX_TCREGADDR           0x0800           /* Offset Of Tx Timecode Register/Vlan Cfg Reg           */ 

/* Rx Logic Low Level Addresses       */ 
#define GE_RX_CFGREGADDR          0x0100           /* Offset Of Rx Config Register                          */ 
#define GE_RX_CPUWRADDR           0x0200           /* Offset Of Tx CPU  DP Region                           */                        
#define GE_RX_NREGADDR            0x0400           /* Offset Of M/N Register, M Always 32                   */
#define GE_RX_STRICTADDR          0x0800           /* Offset Of Rx Strict MC Address Register               */

/* Tuner Logic Low Level Addresses/Defines */
#define GE_TUNE_MAX_COEF            1023           /* Maximum Number Of Coefficients                        */            
#define GE_TUNE_NCO_CFGADDR       0x0800           /* NCO Phase Increment Config Register Address           */
#define GE_TUNE_GAIN_CFGADDR      0x0400           /* Gain Config Register Addres                           */
#define GE_TUNE_COEF_CFGADDR      0x0200           /* Coefficent Config Fifo Address                        */
#define GE_TUNE_FILT_CFGADDR      0x0100           /* Filter Config Register Address                        */
#define GE_TUNE_DECI_CFGADDR      0x0080           /* Decimation Config Register Address                    */  
#define GE_TUNE_NCO_NUM_BITS          20.0         /* Phase Increment Number Of Bits                        */
#define GE_TUNE_COEF_SCALAR       32768.0 /*262144.0 */         /* Default Scalar Value                                  */
#define GE_TUNE_COEF_BIT_WIDTH        16           /* Bit Width Of Scaled Coefficients                      */
#define GE_TUNE_NUM_CYCLES             1           /* Number of Cycles to Compute                           */  
#define GE_COEF_OFF                    0           /* Where To Get Coeffs-Off No Tuner Use                  */
#define GE_COEF_DEFAULT                1           /* Where To Get Coeffs-Use Default Coeffs                */
#define GE_COEF_COMPUTE                2           /* Where To Get Coeffs-Compute From User Input           */
#define GE_COEF_FILE                   3           /* Where To Get Coeffs-Get From User File                */  
#define GE_COEFQUERYFILE    "gigexdquerycoef.txt"  /* Default Coefficients File For 79  Tap Download        */
#define GER1_DOWNLOAD0      "gigexdr1_79d2.rpd"    /* GIGEXD Rev 1 Download 0   79 Tap Decimation =  2      */ 
#define GER1_DOWNLOAD1      "gigexdr1_127d4.rpd"   /* GIGEXD Rev 1 Download 1  127 Tap Decimation =  4      */ 
#define GER1_DOWNLOAD2      "gigexdr1_255d8.rpd"   /* GIGEXD Rev 1 Download 2  255 Tap Decimation =  8      */ 
#define GER1_DOWNLOAD3      "gigexdr1_1023d32.rpd" /* GIGEXD Rev 1 Download 3 1023 Tap Decimation = 32      */ 
#define GER2_DOWNLOAD0      "gigexdr2_79d2.rpd"    /* GIGEXD Rev 2 Download 0   79 Tap Decimation =  2      */ 
#define GER2_DOWNLOAD1      "gigexdr2_127d4.rpd"   /* GIGEXD Rev 2 Download 1  127 Tap Decimation =  4      */
#define GER2_DOWNLOAD2      "gigexdr2_255d8.rpd"   /* GIGEXD Rev 2 Download 2  255 Tap Decimation =  8      */    
#define GER2_DOWNLOAD3      "gigexdr2_1023d32.rpd" /* GIGEXD Rev 2 Download 2 1023 Tap Decimation = 32      */
#define GER2_DOWNLOAD4      "tbd.rpd"              /* To Be Determined                                      */ 


typedef struct IOModule_cfg
  {
    int_u2 inputcfgreg;
    int_u2 numcfgwr;
    int_u2 cfgwrbuf[GE_IOMCFG_SIZE];
  } Type_IOModule_cfg;

typedef struct GIGEXD_cfg
  {
   int_4  gigexdrev; 
   char   pathnfile[256];
   char   gigeipaddr[MAXFNAME];
   int_u4 gigeipaddrval;
   char   destmcaddr[MAXFNAME];
   int_u4 destmcaddrval;
   int_u4 vlanval;
   char   modname[MAXFNAME];
   int    module_type;
   int    module_rev;
   int_u4 freq;
   int_u4 input_decim;
   int    numbits; 
   int    bitshift;
   char   direction[MAXFNAME];
   char   tcstr[MAXFNAME];
   int_u4 tcval;
   char   tunstr[MAXFNAME];
   int_u4 tunval;
   char   coef_fname[MAXFNAME];
   int_u4 coefval;
   int_u4 coef_gainshift;
   int_u4 decmultval;
   int_u4 reqcntrfreqval;
   int_u4 actualcntrfreq;
   int_u4 tunegainval;
   char   flagstr[300];
   int_u4 firmwareval;  
   int    coef[GE_TUNE_MAX_COEF];
   int    querycoef[GE_TUNE_MAX_COEF];     /* For Retrieval During Query Command */
   Type_IOModule_cfg iom;
  } Type_GIGEXD_cfg; 

typedef struct GIGEXD_query
  {
    int_u4 gigeipaddrval;
    int_u4 destmcaddrval;
    int_u2 vlanval;
    int_u4 freq;
    int_u4 input_decim; 
    int    numbits;
    int    bitshift;
    int_u4 tcval;
    int_u4 tunval;
    int_u4 coefval;
    int_u4 decmultval;
    int_u4 reqcntrfreqval;
    int_u4 actualcntrfreq;
    int_u4 coef_gainshift;
    int_u4 tunegainval;
    short int  coef[(GE_TUNE_MAX_COEF/2)+1];
    char   flagstr[300];
  } Type_GIGEXD_query; 


int  Filter_taps[GE_MAXGEREVS][GE_MAXFWDNLDS]               = {{79,127,255,1023,1,1,1,1},
                                                               {79,127,255,1023,1,1,1,1}};
int  Filter_deci[GE_MAXGEREVS][GE_MAXFWDNLDS]               = {{2,4,8,32,1,1,1,1},
                                                               {2,4,8,32,1,1,1,1}};
int  Filter_tcdel[GE_MAXGEREVS][GE_MAXFWDNLDS]              = {{137,187,319,1111,1,1,1,1},
                                                               {137,187,319,1111,1,1,1,1}};
char GIGEXD_dload[GE_MAXGEREVS][GE_MAXFWDNLDS][MAXFNAME]    =
 {{GER1_DOWNLOAD0,GER1_DOWNLOAD1,GER1_DOWNLOAD2,GER1_DOWNLOAD3,GER2_DOWNLOAD4,GER2_DOWNLOAD4,GER2_DOWNLOAD4,GER2_DOWNLOAD4},
  {GER2_DOWNLOAD0,GER2_DOWNLOAD1,GER2_DOWNLOAD2,GER2_DOWNLOAD3,GER2_DOWNLOAD4,GER2_DOWNLOAD4,GER2_DOWNLOAD4,GER2_DOWNLOAD4}};

static SOCKET HIDI_Socket = INVALID_SOCKET;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 getcfgstring(FILE *fp,char *targetstr)
 {
   int status;
   char filestr[MAXFNAME];

    status = fscanf (fp,"%s",filestr);
    if (status == 1)
      {
        strcpy(targetstr,filestr);
          
        /* Read To End Of Line */ 
        strcpy(filestr,"");
        while((filestr[0] != '\n') && (status == 1))
          status = fread((void *)filestr, 1, 1, fp);
        return(SUCCESSFUL);
      }  
    else if (status == EOF)
      return(NOT_SUCCESSFUL);    
   
    printf("Read Of Config File String Failed\n");
    return(NOT_SUCCESSFUL);
 } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 getcfgvalue(FILE *fp,int_u4 *value)
 {
   int status;
   char filestr[MAXFNAME];

  /*  status = fscanf (fp,"%d",value); */
    status = fscanf(fp,"%s",filestr);
    *value = (int_u4) atof(filestr);
    if (status == 1)
      {          
        /* Read To End Of Line */ 
        strcpy(filestr,"");
        while((filestr[0] != '\n') && (status == 1))
          status = fread((void *)filestr, 1, 1, fp);
        return(SUCCESSFUL);
      }      
   
    printf("Read Of Config File String Failed\n");
    return(NOT_SUCCESSFUL);
 } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_4 findflag (char *fstr,char *astr) 
{
  if (strstr(astr,fstr)==NULL)
    return(-1);
  else
    return(strstr(astr,fstr)-astr);   
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_4 findintflag (char *fstr,char *astr) 
{
  int locstr = 0;
  int mult   = 1;
  int ii;
  int value  = 0; 

  locstr = findflag(fstr,astr);

  if (locstr==-1)
    return(0);
  
  locstr = locstr + strlen(fstr);   

  
  if (astr[locstr]!='=') return 0;    
  if (astr[locstr+1]=='-')
     { 
       mult = -1; 
       ++locstr; 
     }
  for (ii=locstr+1; astr[ii] >= '0' && astr[ii] <= '9'; ii++)
    value = value*10 + (astr[ii]-48);  

  return(mult*value);   
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
void convert2upper(char *str)
  {
   int ii;
   for (ii=0;ii<strlen(str);ii++)
     {
       if (str[ii]>'Z') 
         str[ii] -= 32;
     } 
  }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 answer_yes()
  {
   int keych = 'n';
   int_u4 cont_cfg = 0;

    while (keych != '\n')
     { 
       keych = getchar();
       if ((keych == 'Y') || (keych == 'y'))
         cont_cfg = 1;
       else if ((keych == 'N') || (keych == 'n'))
         cont_cfg = 0;
     }

    if (cont_cfg == 1)
      return(TRUE);

    return(FALSE);     
  }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*Copy Word Into Buffer, Increment Address To Next Available    */
/*--------------------------------------------------------------*/
void store_sequence_word(int_u1* cfgbuf,int_u4 *address,int_u2 dbytes)  
{  
  memcpy(cfgbuf+(*address),&dbytes,sizeof(int_u2)); 
  *address = *address + sizeof(int_u2);   
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Creates A Socket On The Specified Port.                      */
/* Returns SUCCESSFUL Or NOT_SUCCESSFUL If Port In Use          */
/*--------------------------------------------------------------*/
int_u1 soc_start_server(char *hostip, char *gigeip)
{
    SOCKET hSocket;
    struct sockaddr_in server;

    hSocket =  socket(PF_INET, SOCK_DGRAM, 0);
    if(hSocket == INVALID_SOCKET )
      {
        printf("Socket Failed\n");
        return(NOT_SUCCESSFUL);
      }

   /* Fill In Server Structure   */
    memset( (char *)&server,0, sizeof(server));
    server.sin_family      = PF_INET;
    server.sin_addr.s_addr = inet_addr(hostip);   
    server.sin_port        = htons(SENDPORT);

   /* Bind Address To Socket     */
    if(bind( hSocket, (struct sockaddr *)&server, sizeof(server)) < 0 )
      {
        printf("Bind Failed\n");
        return(NOT_SUCCESSFUL);
      }

   /*Assign To Global Socket     */
    HIDI_Socket = hSocket;

   
   /* Fill In Target Global Structure   */ 
    memset( (char *)&Client,0, sizeof(Client)); 
    Client.sin_family      = AF_INET; 
    Client.sin_addr.s_addr = inet_addr(gigeip);    
    Client.sin_port        = htons(DESTPORT);
    Client_len             = sizeof(Client);

    return(SUCCESSFUL);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u2 sdds_compute_checksum (int_u2 sizeregion,int_u2 *data)
{
  int_u4 chksum = 0;
  int_u2 ii;
 
  for(ii=0;ii<sizeregion;ii++)
    chksum = chksum + *(data+ii);
   
  chksum = chksum + (chksum >> 16);

  return((int_u2)(~chksum));  /* Ones Complement Of Ones Complement Sum */  
} 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 handshake_op(int_u1 *txdata,int_u1 *rxdata, int reply)
 {  
   int ii,st;
   int_u2 *wrxdata;
   int_u2 *wtxdata;
   
   wrxdata = (int_u2 *)rxdata;
   wtxdata = (int_u2 *)txdata;
  
      
   st = sendto(HIDI_Socket,txdata,CFGPKTDATASIZE,0,(struct sockaddr *)&Client,Client_len);
 /* 
   printf("\n%s%d\n","Tx Sent = ",st); 
   for(ii=0;ii<CFGPKTDATASIZE/2;ii++)
     printf("Index = %d, Tx Data = %x\n",ii,wtxdata[ii]); 
 */
    
   st = recvfrom(HIDI_Socket,rxdata,CFGPKTDATASIZE,0,(struct sockaddr *)&Client,&Client_len);
/*
    printf("%s%d\n","Rx Received = ",st); 
   for(ii=0;ii<CFGPKTDATASIZE/2;ii++)
     printf("Index = %d, Rx Data = %x\n",ii,wrxdata[ii]); 
*/    
   
   if (reply == 0)
     {
       if(memcmp(txdata,rxdata,CFGPKTDATASIZE) == 0)
         return(SUCCESSFUL);
       else
         return(NOT_SUCCESSFUL);
     }
   return(SUCCESSFUL); 
 } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 single_command(int_u1 *txdata,int_u1 *rxdata,int_u2 address,int_u2 data)
 { 
   int_u2 *word;  
   word          = (int_u2 *)txdata;

  *(word + 0)   = GE_CFGNRPLYHDRVAL;
  *(word + 1)   = address;
  *(word + 2)   = data;
  *(word + 3)   = GE_EPROMENDCFGVAL;

   return(handshake_op(txdata,rxdata,0));
 }


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_wr_pageaddr_reg(int_u1 *txdata,int_u1 *rxdata,int_u2 addr)
{ 
 
  if (single_command(txdata,rxdata,GE_EPROMCFGPAGEADDR,addr) == NOT_SUCCESSFUL)
    {
      printf("%s%x\n","Write Page Address Register Failed, Wr Value = ",addr);
      return(NOT_SUCCESSFUL);
    }

/*  printf("%s%x\n","Write Page Address Register Successful, Wr Value = ",addr); */
  return(SUCCESSFUL); 

}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_clear_sector(int_u1 *data,int_u1 *rxdata,int_u4 sector) /* sector Is a 20-bit Address */
{ 
  if (single_command(data,
                     rxdata,
                     GE_EPROMCFGCLRSECTOR | ((int_u2)(0x00000FFF & sector)),
                     ((int_u2)((sector >> 4) & 0x0000FF00))) == NOT_SUCCESSFUL)   
    {
      printf("%s%x\n","Clear Sector Failed, Sector Address = ",sector);
      return(NOT_SUCCESSFUL);
    }

  return(SUCCESSFUL); 

}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_clear_bulk(int_u1 *data,int_u1 *rxdata,int_u4 sector) /* sector Is a 20-bit Address */
{ 
  if (single_command(data,
                     rxdata,
                     GE_EPROMCFGCLRSECTOR | ((int_u2)(0x00000FFF & sector)),
                     ((int_u2)((sector >> 4) & 0x0000FF00)) | 0x00FF) == NOT_SUCCESSFUL)   /* 0x00FF For Data Clears All EPROM */
    {
      printf("%s%x\n","Clear Sector Failed, Sector Address = ",sector);
      return(NOT_SUCCESSFUL);
    }

  return(SUCCESSFUL); 

}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_read_data(int_u1 *txdata,int_u1 *rxdata,int_u4 address)                              /* Address Is a 20-bit Address */
{ 
  int_u2 *word;
  
  word          = (int_u2 *)txdata;

  *(word + 0)   = GE_CFGREPLYHDRVAL;
  *(word + 1)   = GE_EPROMCFGRDDATA | ((int_u2)(0x00000FFF & address));                           /* LS 12 Bits Of Read Address  */
  *(word + 2)   = ((int_u2) ((address >> 4) & 0x0000FF00)) | 0x0008;                              /* MS  8 Bits Of Read Address  */
  *(word + 3)   = GE_EPROMENDCFGVAL;
 
   if (handshake_op(txdata,rxdata,1) == NOT_SUCCESSFUL)
    {
      printf("%s%x\n","Read Bytes Failed, Address = ",address);
      return(NOT_SUCCESSFUL);
    }

  return(SUCCESSFUL); 

}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_write_byte(int_u1 *data,int_u1 *rxdata,int_u4 address,int_u2 dbytes)  /* Address Is a 20-bit Address */
{ 
  
  if (single_command(data,
                     rxdata,
                     GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & address)),
                     ((int_u2) ((address >> 4) & 0x0000FF00)) | (dbytes & 0x00FF)) == NOT_SUCCESSFUL)
    
    {
      printf("%s%x%s%x\n","Write EPROM Single Byte Failed, Address = ",address," Data = ",dbytes);
      return(NOT_SUCCESSFUL);
    }

  return(SUCCESSFUL); 

}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_write_word(int_u1 *data,int_u1 *rxdata,int_u4 address,int_u2 dbytes)              /* Address Is a 20-bit Address */
{ 
  int_u2 *word;
  
  word          = (int_u2 *)data;

  *(word + 0)   = GE_CFGNRPLYHDRVAL;
  *(word + 1)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & address));                        /* LS 12 Bits Of Write Address */
  *(word + 2)   = ((int_u2) ((address >> 4) & 0x0000FF00)) | (dbytes & 0x00FF);                /* MS  8 Bits Of Write Address */
  *(word + 3)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & (address+1)));                    /* LS 12 Bits Of Write Address */
  *(word + 4)   = ((int_u2) (((address+1) >> 4) & 0x0000FF00)) | ((dbytes >> 8) & 0x00FF);     /* MS  8 Bits Of Write Address */ 
  *(word + 5)   = GE_EPROMENDCFGVAL;
 
  if (handshake_op(data,rxdata,0) == NOT_SUCCESSFUL)
    {
      printf("%s%x%s%x\n","Write Word Failed, Address = ",address," Data = ",dbytes);
      return(NOT_SUCCESSFUL);
    }


  return(SUCCESSFUL); 

}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 EPROM_write_Dword(int_u1 *txdata,int_u1 *rxdata,int_u4 address,int_u4 dbytes)           /* Address Is a 20-bit Address */
{ 
  int_u2 *word;
  
  word          = (int_u2 *)txdata;

  *(word + 0)   = GE_CFGNRPLYHDRVAL;
  *(word + 1)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & address));                        /* LS 12 Bits Of Write Address */
  *(word + 2)   = ((int_u2) ((address >> 4) & 0x0000FF00)) | (dbytes & 0x00FF);                /* MS  8 Bits Of Write Address */
  *(word + 3)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & (address+1)));                    /* LS 12 Bits Of Write Address */
  *(word + 4)   = ((int_u2) (((address+1) >> 4) & 0x0000FF00)) | ((dbytes >> 8) & 0x00FF);     /* MS  8 Bits Of Write Address */ 

  *(word + 5)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & (address+2)));                    /* LS 12 Bits Of Write Address */ 
  *(word + 6)   = ((int_u2) (((address+2) >> 4) & 0x0000FF00)) | ((dbytes >> 16) & 0x00FF);    /* MS  8 Bits Of Write Address */
  *(word + 7)   = GE_EPROMCFGWRDATA | ((int_u2)(0x00000FFF & (address+3)));                    /* LS 12 Bits Of Write Address */
  *(word + 8)   = ((int_u2) (((address+3) >> 4) & 0x0000FF00)) | ((dbytes >> 24) & 0x00FF);    /* MS  8 Bits Of Write Address */ 

  *(word + 9)   = GE_EPROMENDCFGVAL;
 
  if (handshake_op(txdata,rxdata,0) == NOT_SUCCESSFUL)
    {
      printf("%s%x%s%x\n","Write Dword Failed, Address = ",address," Data = ",dbytes);
      return(NOT_SUCCESSFUL);
    }


  return(SUCCESSFUL); 

}
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*Write Word, Increment Address To Next Available               */
/*--------------------------------------------------------------*/
int_u1 EPROM_wrsequence_word(int_u1 *txdata,int_u1 *rxdata,int_u4 *address,int_u2 dbytes)  
{
  int_u1 success;

  success = EPROM_write_word(txdata,rxdata,*address,dbytes);
  *address = *address + sizeof(int_u2);
  return(success);  
} 

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 GIGE_turnOFF_data(int_u1 *txdata,int_u1 *rxdata,int_u1 delay,int_u1 msg)
  {
    if (msg == TRUE) 
      printf("\nTurning Off Incoming Data Stream ...");   
    if (single_command(txdata,rxdata,GE_TXRSTADDR,0x0000) == NOT_SUCCESSFUL)
      {
        if (msg == TRUE)
          printf("ERROR:Turning Off Incoming Data Failed\n");
        return(NOT_SUCCESSFUL);
      }
    if (delay == TRUE) 
      sleep(1);
    if (msg == TRUE)
      printf("Done\n");
    
    return(SUCCESSFUL);
  }

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 GIGE_turnON_data(int_u1 *txdata,int_u1 *rxdata,int_u1 delay,int_u1 msg)
  {
    if (msg == TRUE) 
      printf("\nTurning ON Incoming Data Stream ...");   
    if (single_command(txdata,rxdata,GE_TXRSTADDR,0x0001) == NOT_SUCCESSFUL)
      {
        if (msg == TRUE)
          printf("Turning ON Incoming Data Failed\n");       
        return(NOT_SUCCESSFUL);
      }
    if (delay == TRUE)
      sleep(1);
    if (msg == TRUE)
      printf("Done\n");

    return(SUCCESSFUL);
  }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_4 GIGE_retrieve_rev(int_u1 *txdata,int_u1 *rxdata)
 {
   int_u2 *rxwdat;  /* Word Pointer To Rx Buffer */
                        
   rxwdat = (int_u2 *) rxdata;  
 
   if (EPROM_read_data(txdata,rxdata,GE_IDADDRESS) == NOT_SUCCESSFUL)
     {
       printf("ERROR: Retrieval Of Download Program ID Failed!\n");
       return(NOT_SUCCESSFUL); 
     }  
  
   if (*rxwdat == GER1_IDDETECT)
     return(GE_GER1IDVAL);
   else if (*rxwdat == GER2_IDDETECT)    
     return(GE_GER2IDVAL);
       
    
   printf("ERR: GIGEXD Revision Value Not Recognized = %x\n",*rxwdat);
   
   return(-1);
 } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 GIGE_retrieve_revnvers(int_u1 *txdata,int_u1 *rxdata,int_4 *rev)
 {
   int_4 gigexd_rev = -1;

  /* Set Page Address To 0x0000 */  
   if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0000) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   
   gigexd_rev = GIGE_retrieve_rev(txdata,rxdata);
   if (gigexd_rev == -1)      
     return(NOT_SUCCESSFUL);
   else if (gigexd_rev == GE_GER1IDVAL) 
     {
       printf("Err: GIGEXD Rev 1 Detected!!!\n");
       printf("Software Support For GIGEXD Rev 1 Ended With Version 1.9\n");
       printf("User Will Need To 'Back Rev' To Version 1.9 For GIGEXD Rev 1 Support!\n\n");
       return(NOT_SUCCESSFUL);  
     }   
        
   if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL); 

  /* Get Programming ID Value */       
   if (EPROM_read_data(txdata,rxdata,GER1_IDWORDADDRESS) == NOT_SUCCESSFUL)    
     {
       printf("ERROR: Retrieval Of Download Program ID Failed!\n");
       return(NOT_SUCCESSFUL); 
     }  

   if (rev != NULL)
     *rev = gigexd_rev;

   return(SUCCESSFUL);
 } 


#define DEBUG  0   /* Set DEBUG = 1 For File Output Of Coeff Calculations */ 


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Reorder for decimation fir (allow symmetric)                 */
/*--------------------------------------------------------------*/
void deci_reseq(int coef_length,int poly_fact,int *coef)
{ 
  int half_len; 
  int tmp_coef[GE_TUNE_MAX_COEF];
  int loc_coef[GE_TUNE_MAX_COEF];
  int num_mac;

  float mcv_coef_length;
  int   zeros_insert; 

  int calc_cycles;
  int mem_num;
  int coef_one_mem ;
  int mcv_reload_zero_insert;
  int i,j,k;
   
  half_len        = (int) ceil(((double) coef_length)/2.0);
  calc_cycles     = GE_TUNE_NUM_CYCLES * poly_fact;
  num_mac         = (int) ceil(((double) half_len)/((double) calc_cycles));
  mcv_coef_length = num_mac * calc_cycles;
  zeros_insert    = mcv_coef_length - half_len;  /* Number of Zeroes To Insert for Sym */

  for (i=0; i<GE_TUNE_MAX_COEF; ++i)
    tmp_coef[i] = 0;
 
  for (i=0; i<half_len; ++i)
    tmp_coef[i + zeros_insert] = coef[i];
 
  for (i=0; i<mcv_coef_length; ++ i)
    loc_coef[i] = tmp_coef[i];
 
  for (i=0; i<mcv_coef_length; ++i)
    coef[i] = tmp_coef[i];
 
 /* insert zeros when use memory to store coefficient and coefficient in one memory is more than one  */

  coef_one_mem           = (int) floor(36.0/((double) GE_TUNE_COEF_BIT_WIDTH));            /* For M4K Memory Storage Of Coefficients */
  mem_num                = (int) ceil(((double) num_mac)/ ((double)coef_one_mem));
  mcv_reload_zero_insert = mem_num * coef_one_mem - num_mac;
  if(mem_num == 1)
    mcv_reload_zero_insert = 0;
  
  if (mcv_reload_zero_insert > 0)
    {
      for (j=0; j<mem_num * coef_one_mem; ++j)
        {
           for (i=0; i<calc_cycles; ++i)
             {
               if (j < (mem_num -1) * coef_one_mem)
                 coef[j* calc_cycles + i] = tmp_coef[j* calc_cycles + i];
               else if (j <(mem_num -1) * coef_one_mem + mcv_reload_zero_insert)
                 coef[j* calc_cycles + i] = 0;
               else
                 coef[j* calc_cycles + i] = tmp_coef[(j - mcv_reload_zero_insert)* calc_cycles + i];  
             }
         }
     }
 
 /* Reorder For Symmetry */
  for (k=0;k<calc_cycles;++k)
    { 
      for (i=0;i<num_mac+mcv_reload_zero_insert;++i)
        tmp_coef[(k*(num_mac+mcv_reload_zero_insert))+i] = coef[(i*calc_cycles)+k];                       
    }
  
  for(i=0;i<half_len;i++)
    coef[i] = tmp_coef[i]; 
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Determine Power Of 2 Scalar For Coefficents                  */
/*--------------------------------------------------------------*/
void scale_coefficients(double *float_coef,int num_coef, int *int_coef, int *gain_shift)
  {
    int ii;
    double max_coef = 0.0;
    int_u4 coef_scalar = 1;
    double sum_coeff = 0.0;

    for(ii=0;ii<num_coef;++ii)
     {
       if (float_coef[ii] > max_coef)
         max_coef = float_coef[ii];
     } 

   /* Max Scalar 1048576 (1M)               */
   /* 32767 Largest 16 Bit Positive Integer */
    for (ii=1;ii<21;ii++)
      {
        if ((max_coef * pow(2,ii)) >  32767.5) 
          break;   
      }
    
    coef_scalar = pow(2,ii-1);
 
   /* **************************************/  
   /* For Math Operation Of Tuner Mult/Sum */
   /* Add Gain So Sig Does Not Attenuate   */
   /* gain_shift In dB                     */
   /****************************************/
    *gain_shift = (21-ii) * 6;
     
/*      
    printf("Coef Scalar = %d\n",coef_scalar);
    printf("Gain Shift = %d\n",*gain_shift);

    for (ii=0;ii<num_coef;ii++)
      {
        printf("Index = %d Float Coefficient = %E\n",ii,float_coef[ii]);   
        sum_coeff = sum_coeff + float_coef[ii];
      }
      
    printf("Coefficients Scalar Value = %d\n",coef_scalar); 
    printf("Coefficients Sum Value = %e\n",sum_coeff);
    printf("Sum * Scalar Value = %e\n",((double) coef_scalar)*sum_coeff);
*/ 

    for (ii=0;ii<num_coef;ii++)
      {                  
        float_coef[ii] = (coef_scalar * float_coef[ii]);    /* Scale By Max Value, Add/Subtract  .5 For Rounding */
        if (float_coef[ii] < 0.0)
          float_coef[ii] = float_coef[ii] - 0.5;      
        else
          float_coef[ii] = float_coef[ii] + 0.5;
     
        int_coef[ii]    = (int) float_coef[ii];
      }

/* 
    for (ii=0;ii<num_coef;ii++) 
      printf("Index = %d Integer Coefficent = %d\n",ii,int_coef[ii]); 
*/ 

  }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Must Reorder Coefficients For Downloading To GIGEXD          */
/*--------------------------------------------------------------*/
int_u1 coeff_reorder(Type_GIGEXD_cfg *g)
{

  FILE *fpi;
  FILE *ftempo;
  FILE *fpo;
  int half_len, num_coef;
  char coef_str[80];
  double float_coef[GE_TUNE_MAX_COEF];
  int ii;
  int_u4 coef_scalar = 1; 
  float max_value    = (float)pow(2.0,36); /* initial as m4k */

/*&&&&&&&&&&&&&&&&&&&&&*/  
/*Begin Debug */
#if DEBUG    
  ftempo = fopen("debugscalecoef.txt","w+");
  if (ftempo ==NULL)
  {
    printf("Open Of Debug File 'debugscalecoef.txt'  FAILED!!\n");
    printf("Aborting Configuration Update.\n");
    return(NOT_SUCCESSFUL);
  } 

  fpo = fopen("debugfinalcoef.txt","w+");
  if (fpo ==NULL)
    {
      printf("Open Of Debug File 'debugfinalcoef.txt' FAILED!!\n");
      printf("Aborting Configuration Update.\n");
      return(NOT_SUCCESSFUL);
    }   
  printf("Debug ON: File 'debugscalecoef.txt' Will Hold Scaled Coeffs Before Reordering\n");
  printf("Debug ON: File 'debugfinalcoef.txt' Will Hold Scaled Coeffs After  Reordering\n"); 
  printf("Debug ON: File Coefficients As Read From File: \n");
#endif
/*End Debug */
/*&&&&&&&&&&&&&&&&&&&&&*/  

  
  fpi = fopen(g->coef_fname,"r");
  if (fpi ==NULL)
    {
      printf("\n%s%s%s\n","Open Of Coefficients Config File ",g->coef_fname," FAILED!!");
      printf("Aborting Configuration Update.\n");
      return(NOT_SUCCESSFUL);
    }   

#if !DEBUG  
  printf("\n\nReading Coefficients File %s ...",g->coef_fname);
#endif 

 /* Assign Number Of Coefs For Current Programming */
  num_coef       = Filter_taps[g->gigexdrev][g->firmwareval]; 

  for (ii = 0; ii<num_coef; ++ii)
    {
      g->coef[ii] = 0;
      if (getcfgstring(fpi,coef_str) == NOT_SUCCESSFUL)
        {
          printf("Read Of Coefficients Failed\n"); 
          return(NOT_SUCCESSFUL);
        }
      float_coef[ii] = atof(coef_str);

/*&&&&&&&&&&&&&&&&&&&&&*/
#if DEBUG 
      printf("%s%d%s%s\n","Index = ",ii," Coef String From File = ",coef_str);
#endif
/*&&&&&&&&&&&&&&&&&&&&&*/
    }

#if !DEBUG
  printf("Done\n");
#endif

 /* Get Maximum Coefficient Scalar, Tuner Float Coeffs To Int Coeffs */
  scale_coefficients(float_coef,num_coef,g->coef,&(g->coef_gainshift));

/*&&&&&&&&&&&&&&&&&&&&&*/
#if DEBUG 
   for (ii=0;ii<num_coef;ii++)
     fprintf(ftempo,"%d\n",g->coef[ii]);
#endif
/*&&&&&&&&&&&&&&&&&&&&&*/
   
  fclose(fpi);
 /* Error Check For Symmetry */
  half_len = (int)ceil(((double)num_coef)/2.0);
  for (ii = 0; ii < half_len; ++ii)
    {
      if (g->coef[ii] != g->coef[num_coef-1-ii])
        {
          printf("Error Coefficients MUST Be Symmetrical!!!\n");
          return(NOT_SUCCESSFUL);
        }
    }

 /* Store Non-Reordered Coefficients For Query Command */
  for (ii=0;ii<num_coef;ii++)
    g->querycoef[ii] = g->coef[ii];  

 /* Resequence Coefficients For Download To FPGA                    */ 
  deci_reseq(Filter_taps[g->gigexdrev][g->firmwareval],Filter_deci[g->gigexdrev][g->firmwareval],g->coef);

/*&&&&&&&&&&&&&&&&&&&&&*/ 
/* Begin Debug */ 
#if DEBUG    
  printf("Reordered Coefficients\n");
  fprintf(fpo,"%s\n","Reordered Coefficients");
  for (ii=0; ii<half_len; ++ii)
    {
      fprintf(fpo,"%d\n",g->coef[ii]);
    /*  printf("Coeff Index = %d, Coeff = %d\n",ii,g->coef[ii]);  */
    } 
  fclose(ftempo);                      
  fclose(fpo);
#endif
/* End Debug */
/*&&&&&&&&&&&&&&&&&&&&&*/
 
  return(SUCCESSFUL);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 fir_design(Type_GIGEXD_cfg *g) 
{
#define Pi  3.1415926535
   double sHigh,Sum, TmpFloat,CutHigh, float_coef[GE_TUNE_MAX_COEF], srate;
   int HalfLen, ii,coefnum;
   FILE *ftempo;

/*&&&&&&&&&&&&&&&&&&&&&*/  
/*Begin Debug */
#if DEBUG    
  ftempo = fopen("debugcomputecoef.txt","w+");
  if (ftempo ==NULL)
   {
     printf("Open Of Debug File 'debugcomputecoef.txt'  FAILED!!\n");
     printf("Aborting Configuration Update.\n");
     return(NOT_SUCCESSFUL);
   } 
  printf("Debug ON: File 'debugcomputecoef.txt' Will Hold Computed Coefficients\n"); 
#endif
/*&&&&&&&&&&&&&&&&&&&&&*/

  /* Assign Number Of Coefs For Current Programming */
   coefnum     = Filter_taps[g->gigexdrev][g->firmwareval];
  
  /* Compute Effective Sample Rate Out Of Tuner      */
   srate = (double)(((double)g->freq)/ ((double) (g->input_decim * Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval))) ;
  /* printf("Sample Rate = %e\n",srate);             */

  /* If DEFAULT, Choose First Nyquist Zone           */ 
  /* If COMPUTE, String g->coef_fname Holds Value    */
   if (g->coefval == GE_COEF_DEFAULT)
     sHigh     = srate/2.0;
   else
     sHigh     = atof(g->coef_fname);
 
   if ((sHigh * 2.0) >  srate)
    {
      printf("ERROR: Sample Rate (freq/(input decim * tune decim * decim scalar) = %e Hz\n",srate);
      printf("ERROR: Filter High Cutoff Greater Than Nyquist Region!!\n");
      printf("ERROR: Reset Filter Width\n");
      return(NOT_SUCCESSFUL);
    }  

  /*----------------------------------*/
  /* Normalize High Cutoff To Nyquist */
  /*----------------------------------*/   
  /* CutHigh = sHigh / srate * 2.0;   */   
   CutHigh = sHigh / ((double) ((double) g->freq)/((double) g->input_decim)) * 2.0;  

   
  /* printf("CutHigh = %e\n",CutHigh); */  

   HalfLen = (coefnum - 1) / 2; 
  
  /*------------------*/
  /*  Lowpass filter  */
  /*------------------*/   
   float_coef[HalfLen] = CutHigh;
   for (ii=1; ii<=HalfLen; ii++) 
     {
        TmpFloat = Pi * ((double)ii);
        float_coef[HalfLen + ii] = sin(CutHigh * TmpFloat) / TmpFloat;
        float_coef[HalfLen - ii] = float_coef[HalfLen + ii];
     }
   
  /* for (ii=0; ii<=HalfLen; ii++)                              */
  /*  printf("Index = %d Coefficent = %E\n",ii,float_coef[ii]); */  
 
  /*-------------------------------------*/
  /* Multiplying With Blackman Window    */
  /*-------------------------------------*/
   TmpFloat = 2.0 * Pi / (((double)coefnum) - 1.0);
   Sum = 0.0;
   for (ii=0; ii<coefnum; ii++) 
     {
       /* Blackman Window */
        float_coef[ii] *= (0.42 - (0.5 * cos(TmpFloat * ((double)ii))) + (0.08 * cos(2.0*TmpFloat*((double)ii))));  

       /* Hamming Window */
       /* float_coef[ii] *= (0.54 - 0.46 * cos(TmpFloat * ii)); */          
        Sum += float_coef[ii];
     }

  /*------------------------------*/
  /* Normalize GAIN to 1          */
  /*------------------------------*/
   for (ii=0; ii<coefnum; ii++) 
     float_coef[ii] /= fabs (Sum);
    
 
/*&&&&&&&&&&&&&&&&&&&&&*/
#if DEBUG 
   for (ii=0;ii<coefnum;ii++)
     fprintf(ftempo,"%e\n",float_coef[ii]);
#endif
/*&&&&&&&&&&&&&&&&&&&&&*/ 
  
   
  /* Get Maximum Coefficient Scalar, Turn Float Coeffs To Int Coeffs */
   scale_coefficients(float_coef,coefnum,g->coef,&(g->coef_gainshift));  

  /* Store Non-Reordered Coefficients For Query Command              */
   for (ii=0;ii<coefnum;ii++)
     g->querycoef[ii] = g->coef[ii];

  /* Resequence Coefficients For Download To FPGA                    */ 
   deci_reseq(Filter_taps[g->gigexdrev][g->firmwareval],Filter_deci[g->gigexdrev][g->firmwareval],g->coef);
   return (SUCCESSFUL);    
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 check_iom_type(Type_GIGEXD_cfg *g)
 { 
   g->module_type = IOMT_NONE;

   if (strncmp(g->modname,"A2D",3) == 0) 
      g->module_type = IOMT_A2D;  
   else if (strncmp(g->modname,"DR2D",4) == 0)   
      g->module_type = IOMT_DR2D;
   else if (strncmp(g->modname,"E2D",3) == 0) 
      {
        
        printf("\n\n**** Note: Depricated Module Type E2D ****\n");
        printf("Use Of The Module Type E2D Changed To DR2D (Differential Receiver) \n");
        printf("Change Configuration Module Type To DR2D In Configuration File\n\n");   
        g->module_type = IOMT_DR2D;
      }  

   g->module_rev = 0; 
   if ((g->modname[4]>='0') && (g->modname[4]<='9')) g->module_rev = g->modname[4]-'0';
   if ((g->modname[5]>='0') && (g->modname[5]<='9'))
     {
       g->module_rev = g->module_rev * 10;
       g->module_rev = g->module_rev + (g->modname[5]-'0');  
     }

   if (g->module_type == IOMT_A2D)
     {  
       if ((g->module_rev >= 7) && (g->module_rev <= 10))
         return(SUCCESSFUL);   
     }  
   if (g->module_type == IOMT_DR2D)
      return(SUCCESSFUL);
    
   printf("\nERR: GIGEXD Valid Module Types Are A2DR7, A2DR8, A2DR9, A2DR10, and DR2D\n");
   printf("Module Type %s Is Not Supported!!!\n",g->modname);
   printf("Change Module Type In Config File %s\n",g->pathnfile);
   return(NOT_SUCCESSFUL);     
 } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 read_cfg_file(int_u1 *txdata, int_u1 *rxdata, Type_GIGEXD_cfg *g)
 {
   FILE *fp;
   float data_rate;
   float decim_clk_freq;
   int_u4 phase_inc;

   fp = fopen(g->pathnfile,"r");
   if (fp ==NULL)
     {
       printf("%s%s%s\n","Open Of Config File ",g->pathnfile," FAILED!!");
       printf("Aborting Configuration Update.\n");
       return(NOT_SUCCESSFUL);
     } 
 
   printf("%s%s%s\n","Config File ",g->pathnfile," Info :"); 
  /* Get Module IP Address String      */             
   if (getcfgstring(fp,g->gigeipaddr) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%s\n","GigE IP Addr = ",g->gigeipaddr);
   g->gigeipaddrval = inet_addr(g->gigeipaddr);    
   
  /* Get Multicast Destination String  */
   if (getcfgstring(fp,g->destmcaddr) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%s\n","GigE MC Addr = ",g->destmcaddr);
   g->destmcaddrval = inet_addr(g->destmcaddr);    

  /* VLAN Number                       */ 
   if (getcfgvalue(fp,&(g->vlanval)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","VLAN = ",g->vlanval);
   
  /* Get Module Name                   */ 
   if (getcfgstring(fp,g->modname) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL); 
   convert2upper(g->modname);
   printf("\t%s%s\n","GigE Module Type = ",g->modname);
   
  /* Get Data Frequency                */ 
   if (getcfgvalue(fp,&(g->freq)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Data Rate = ",g->freq);

   /* Get Input Decimation             */ 
   if (getcfgvalue(fp,&(g->input_decim)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Input Decimation = ",g->input_decim);

  /* Get Number Of Data Bits           */
    if (getcfgvalue(fp,&(g->numbits)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Number Of Bits = ",g->numbits);    
  
  /* Get Number Bits For Bit Shift     */
    if (getcfgvalue(fp,&(g->bitshift)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Number Of Bits For Shift= ",g->bitshift);    

  /* Get GIGE Transfer Direction       */
   if (getcfgstring(fp,g->direction) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   convert2upper(g->direction);
   if (strstr(g->direction,"TX") == NULL)
     {
       printf("\n\nERR: Currently Only TX GIGE Operations Supported!\n");
       printf("ERR: Rx Operations Are Not Supported-Yet\n");
       return(NOT_SUCCESSFUL); 
     }
    printf("\t%s\n","GIGE Transfer Direction = TX");
 
  /* Get Timecode Enable/Disable       */
   if (getcfgstring(fp,g->tcstr) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   convert2upper(g->tcstr);
   if (strstr(g->tcstr,"ON") == NULL)
    { 
      g->tcval = FALSE;
      printf("\t%s\n","Timecode Generation = OFF");
    }
   else
    { 
      g->tcval = TRUE;
      printf("\t%s\n","Timecode Generation = ON");
    }
       
  /* Get Tuner Enable/Disable       */
   if (getcfgstring(fp,g->tunstr) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
   convert2upper(g->tunstr);

  /* Get Coefficients Filename      */
   if (getcfgstring(fp,g->coef_fname) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Determine Where To Get Coeffs  */
   if (strstr(g->tunstr,"DEFAULT") != NULL)
    { 
       g->tunval  = TRUE;
       g->coefval = GE_COEF_DEFAULT;       
       printf("\t%s\n","Tuner = ON, Default Coefficients Filter Set To First Nyquist Zone");
     }
   else if (strstr(g->tunstr,"COMPUTE") != NULL)
     { 
       g->tunval  = TRUE;
       g->coefval = GE_COEF_COMPUTE;
       printf("\t%s%s%s\n","Tuner = ON, Will Compute Filter Width To ",g->coef_fname,"Hz");
     }   
   else if (strstr(g->tunstr,"FILE") != NULL)
     { 
       g->tunval  = TRUE;
       g->coefval = GE_COEF_FILE;
       printf("\t%s%s\n","Tuner = ON, Will Download Coefficients From File ",g->coef_fname);
     }
   else
     {
        g->tunval  = FALSE;
        g->coefval = GE_COEF_OFF;
        printf("\t%s\n","Tuner = OFF");
     }  

  /* Init Coefficient Gain Shift   */ 
   g->coef_gainshift = 0;

  /* Get Decimation Mult Val       */
   if (getcfgvalue(fp,&(g->decmultval)) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Decimation Scalar = ",g->decmultval);   
 
  /* Get Center Freqency Val       */
   if (getcfgvalue(fp,&(g->reqcntrfreqval)) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Center Frequency = ",g->reqcntrfreqval);

  /* Get Tuner Gain Val            */
   if (getcfgvalue(fp,&(g->tunegainval)) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
   printf("\t%s%d\n","Tuner Gain = ",g->tunegainval);

  /* Get Flag String               */
   if (getcfgstring(fp,g->flagstr) == NOT_SUCCESSFUL)
     { 
       printf("\nERR: 'FLAG='Line Missing From Config File-Aborting Config\n");
       printf("ERR: Add 'FLAG=NONE' To End Of Config Parameters\n"); 
       return(NOT_SUCCESSFUL);
     }
   convert2upper(g->flagstr);
   printf("\t%s%s\n","Flags = ",g->flagstr+6);
   fclose(fp);

  /* Turn Off Incoming Data Stream */     
   if (GIGE_turnOFF_data(txdata,rxdata,FALSE,FALSE) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
      
  /* Retrieve Firmware Version     */
   if (GIGE_retrieve_revnvers(txdata,rxdata,&(g->gigexdrev)) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Query Current Programming In GIGEXD */ 
   if (GE_LASTCOMPATVERS > (*((int_u2 *)rxdata) & 0xFFF8))
     { 
       printf("%s%d\n","GIGEXD Hardware Type = GIGEXDR",g->gigexdrev+1);
       printf("%s%d%s%02d\n","Firmware  Version = ",*(rxdata+1),".",(*rxdata & 0xF8) >> 3);
       printf("%s%d%s%02d\n","Software Version = ",GE_SOFTWAREVERS >> 8,".",(GE_SOFTWAREVERS & 0x00FF) >> 3);
       printf("ERR: Versions DO NOT Match!!...Aborting Configuration\n");
       printf("Update (Re-Program) The GIGEXD To Match Software With Firmware Versions.\n");
       return(NOT_SUCCESSFUL);  
     }  
   else
     { 
       g->firmwareval   = *rxdata & 0x0007;                                           /* Firmware Value In Bits[2..0]  */       
       printf("%s%d%s%02d\n","\tFirmware  Version = ",*(rxdata+1),".",(*rxdata & 0xF8)>>3);           
     }
   
  /* File Read, Scale, & Halve Amount Of Coefficients */    
   if (g->coefval == GE_COEF_DEFAULT)
     {      
       if (fir_design(g) == NOT_SUCCESSFUL)
        return(NOT_SUCCESSFUL);    
     }
   else  if (g->coefval == GE_COEF_COMPUTE)
    {
      if (fir_design(g) == NOT_SUCCESSFUL)
        return(NOT_SUCCESSFUL);
    }  
   else if (g->coefval == GE_COEF_FILE)
    { 
      if (coeff_reorder(g) == NOT_SUCCESSFUL)
        return(NOT_SUCCESSFUL);
    }    
 
    g->tunegainval = g->tunegainval + g->coef_gainshift ;
   

   /********************************************/
   /* Check Configuration Parameters From User */
   /********************************************/   

   /* Check Module Type  */
    if (check_iom_type(g) == NOT_SUCCESSFUL)
      return(NOT_SUCCESSFUL);
  
   /* Check For Use Of VLAN */ 
    if (g->vlanval != 0)
      {
        if (g->vlanval > 16384)
          {
            printf("\nERROR: VLAN Value %d Is Out Of Valid Range!!!\n",g->vlanval);
            printf("Change VLAN Value In Configuration File\n");            
            return(NOT_SUCCESSFUL);
          } 
      }  

   /* Check For Valid Multicast Address                          */
    if (((g->destmcaddrval & 0x000000FF) <  224) || ((g->destmcaddrval & 0x000000FF) > 239)) 
      {
        printf("\nERROR: Multicast Address %s Is Out Of Valid Range!!!\n",g->destmcaddr); 
        printf("ERROR: Valid Mulitcast Address Range 224.1.0.0 to 239.255.255.255\n");
        return(NOT_SUCCESSFUL);  
      }
    if (((g->destmcaddrval & 0x000000FF) == 224) && ((g->destmcaddrval & 0x0000FF00) == 0)) 
      {
        printf("\nERROR: Multicast Address %s Is Out Of Valid Range!!!\n",g->destmcaddr); 
        printf("ERROR: Valid Mulitcast Address Range 224.1.0.0 to 239.255.255.255\n");
        return(NOT_SUCCESSFUL);  
      }

   /* Error Check When Tuner Enabled                             */ 
    if (g->tunval == TRUE)
      {
       /* Check Center Freqency Accuracy                             */ 
        decim_clk_freq = (float) (((float) (g->freq))/ ((float) (g->input_decim)));  
        phase_inc      = (int_u4) ((((float) ((float)(g->reqcntrfreqval)/ decim_clk_freq )) * 1048576.0) + 0.5);  

        if (((float)g->reqcntrfreqval) != ((float)(((float)phase_inc)/1048576.0 * decim_clk_freq)))
          {
            g->actualcntrfreq = (int_u4) ((double)(((double)phase_inc)/1048576.0 * ((double)decim_clk_freq)));             
            printf("\nWARN: Center Frequency Deviation\n");   
            printf("WARN: Actual Center Frequency Set To %f Hz\n",((double)(((double)phase_inc)/1048576.0 * ((double)decim_clk_freq))));
          } 
        else
          g->actualcntrfreq = g->reqcntrfreqval;

      }  

   /* Data Size Must Be (Positive) Non-Complex For Wide Band Use */
    if ((g->numbits < 0 ) && (g->tunval == FALSE))            
      {
        printf("\nERROR: Complex Data Type Only Supported With Tuner Use!!!\n");
        printf("Sample Size In Config File Must Be Set To Either 8 or 16.\n");
        printf("Aborting Configuration.\n");
        return(NOT_SUCCESSFUL);
      } 

   /* Check Input Decimation Within Valid Range                  */
    if ((g->input_decim < 1) || (g->input_decim > 8))
      {
        printf("\nERROR: Valid Input Decimation Values Are 1 to 8\n");
        printf("%s%d%s\n","User Value ",g->input_decim," Is Out Of Range-Change Value!!");
        printf("Aborting Configuration.\n");
        return(NOT_SUCCESSFUL);    
      }    

   /* Data Rate Check */      
    data_rate = ((((float) (abs(g->numbits)))/8.0)  *  ((float) g->freq)) / ((float)g->input_decim);  /* Calc Num Bits * Rate/Decim     */   
    if (g->numbits < 0)                                                                               /* Multiply By 2 For Complex Data */                 
      data_rate = data_rate * 2.0;      
    if (g->tunval == TRUE)                                                                            /* Divide By Decimation Factor    */ 
      data_rate = data_rate / ((float)(Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval));   
    if (data_rate > MAX_GIGE_TRANSFER)
      {
        printf("%s%d%s\n","\nERROR: Data Rate Too High: ",(int)data_rate/1000000," MBytes/Sec");
        printf("%s%d%s\n","Maximum GIGEXD Transfer Rate: ",((int_u4)MAX_GIGE_TRANSFER)/1000000," MBytes/Sec"); 
        printf("Change Data Rate, Number Of Bits (Sample Size), Or Decimation To Lower Rate.\n");
        printf("Aborting Configuration.\n");
        return(NOT_SUCCESSFUL);
      }   

    /* Bit Shift Check */
     if ((g->bitshift< 0) || (g->bitshift > 7))
      {
        printf("\nERROR: Valid Bit Shift Values Are 0 to 7\n");
        printf("%s%d%s\n","User Value ",g->bitshift," Is Out Of Range-Change Value!!");
        printf("Aborting Configuration.\n");
        return(NOT_SUCCESSFUL);    
      }  

   /* Tuner Check */
    if ((g->decmultval < 1) || (g->decmultval > 255))  
      {
        printf("\nERROR: Valid Decimation Multiplier Values Are 1 To 255 \n");
        printf("%s%d%s\n","User Value ",g->decmultval," Is Out Of Range-Change Value!!");
        printf("Aborting Configuration.\n");
        return(NOT_SUCCESSFUL); 
      }


    if (g->tunegainval > 42)
      {
        if (g->coef_gainshift > 0) 
          {
            printf("\nWARN: Coefficient Scaling Math Operations Will Limit Gain To %d dB\n",42-g->coef_gainshift); 
            g->tunegainval = 42 - g->coef_gainshift;         
          } 
      }       

   /* Check Tuner Gain Value */  
    if (((g->tunegainval % 6) != 0) || (g->tunegainval < 0) || (g->tunegainval > 42)) 
      {
        printf("Error: Tuner Gain Value Must Be In 6dB Increments And 0<= <Tuner Gain> <=30dB\n");
        return(NOT_SUCCESSFUL);
      }        
                     
   return(SUCCESSFUL);

  } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u4 reverse_bit_order(int_u4 value,int_u4 amount)
  {
    int ii;
    int_u4 hold_dat = 0; 
    
    for (ii=0;ii<amount;ii++)
      hold_dat = ((value  >> ii) & 0x00000001) | ((hold_dat << 1) & 0xFFFFFFFE); 
    
    return(hold_dat);    
  } 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
void iom_store_cfg(int_u2 *dbuf,int_u2 *offset,int_u2 data, int_u2 sizecfg)
 {     
   dbuf[(*offset)]     = GE_SYNCLKADDR;
   dbuf[(*offset) + 1] = data;
   dbuf[(*offset) + 2] = GE_SYNCLKADDR; 
   dbuf[(*offset) + 3] = sizecfg;
  
   *offset = *offset + 4;           
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
void store_a2dr10_cfg(int_u2 *dbuf,int_u2 *offset,int_4 value)
 {

/* A2DR10 Configuration Regs */
#define A2DR10D_MAX_FREQ       200000000.0             /* AD9230 Maximum Sample Rate                            */
#define A2DR10D_MIN_FREQ        40000000.0             /* AD9230 Minimum Sample Rate                            */              
#define A2DR10D_MAXPLL_FREQ    200000000.0             /* Synthetic Clock Maximum PLL Output Rate               */
#define A2DR10D_MINPLL_FREQ     40000000.0             /* Synthetic Clock Minimum PLL Output Rate               */

#define A2DR10_GAINREG        0x0000                   /* Gain Control Reg                                      */   
#define A2DR10_SYNLOREG       0x2000                   /* Synthetic Clock Low  Address Reg                      */      
#define A2DR10_SYNHIREG       0x3000                   /* Synthetic Clock High Address Reg                      */
#define A2DR10_A2DLOREG       0x4000                   /* A2D Config Low  Address Reg                           */  
#define A2DR10_A2DHIREG       0x5000                   /* A2D Config High Address Reg                           */
#define A2DR10_A2DRSTREG      0x6000                   /* A2D Reset Line Address Reg, Active Low                */ 
#define A2DR10_SETADR         0x0000                   /* Set Address To Be Written                             */
#define A2DR10_WRDAT          0x0040                   /* Write Data                                            */  

#define EXTFPGACFG_BIT        0x2000                   /* Configuration To Be Sent To Module FPGA               */ 

  /* Parameter value, Low Byte Data, Next Byte Address, Higher 2 Bytes Unused */  
   iom_store_cfg(dbuf,offset,A2DR10_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
   iom_store_cfg(dbuf,offset,(int_u2) (value & 0x0000FF00),0x1000|EXTFPGACFG_BIT);                
   iom_store_cfg(dbuf,offset,A2DR10_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
   iom_store_cfg(dbuf,offset,A2DR10_SETADR,0x1000|EXTFPGACFG_BIT);          

   iom_store_cfg(dbuf,offset,A2DR10_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
   iom_store_cfg(dbuf,offset,(int_u2) ((value << 8) & 0x0000FF00),0x1000|EXTFPGACFG_BIT);                
   iom_store_cfg(dbuf,offset,A2DR10_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
   iom_store_cfg(dbuf,offset,A2DR10_WRDAT,0x1000|EXTFPGACFG_BIT);          
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 iomodule_setconfig(Type_GIGEXD_cfg *g)
 {
#define A2DR78D_MAX_FREQ      100000000.0              /* Synthetic Clock Maximum PLL Output Rate               */
#define A2DR78D_MIN_FREQ       90000000.0              /* Synthetic Clock Minimum PLL Output Rate               */
#define A2DR9D_MAXPLL_FREQ    200000000.0              /* Synthetic Clock Maximum PLL Output Rate               */
#define A2DR9D_MINPLL_FREQ    180000000.0              /* Synthetic Clock Minimum PLL Output Rate               */
#define A2DR9D_MAX_FREQ       200000000.0              /* AD9230 Maximum Sample Rate                            */
#define A2DR9D_MIN_FREQ        40000000.0              /* AD9230 Minimum Sample Rate                            */              


/* A2DR9 Configuration Regs  */
#define A2DR9_GAINREG         0x0000                   /* Gain Control Reg                                      */   
#define A2DR9_SYNLOREG        0x2000                   /* Synthetic Clock Low  Address Reg                      */      
#define A2DR9_SYNHIREG        0x3000                   /* Synthetic Clock High Address Reg                      */
#define A2DR9_A2DLOREG        0x4000                   /* A2D Config Low  Address Reg                           */  
#define A2DR9_A2DHIREG        0x5000                   /* A2D Config High Address Reg                           */

  
   int_u4 rate_div      = 0x0001C040;                  /* Divide IF Freq By 8                                   */  
   int_u4 n_synclk      = A2D_DEFAULT_N;
   int_u4 r_synclk      = A2D_DEFAULT_R;
   int_u4 actual_synclk = 0;
   int_u4 rate;     
   int_4  dload_val     = 0;
  

   int_u4 n32s,n2hs,n2ls,n1hs,nc2ls,holdn32s,holdn2hs,holdn2ls,holdn1hs,holdnc2ls,f3nbint;
   float n2hsflt,n2lsflt,n32sflt,f3nbflt,n1flt,freqdif;
   float lowdif        = 1000000.0;
   int_u4 ref_freq      = 10000000;                    /* Reference Frequency                                   */ 
   int    negdiff       = FALSE;  
   int    holdnegdiff   = FALSE;
  
   g->iom.numcfgwr = 0;                                /* Init Num Cfg Wr = 0 */                
   rate            = g->freq;                          /* Store Clock Freq    */

  /* Set Input Frequency For A2DR7, A2DR8, A2DR9 Synthetic Clock */   
   if (g->module_type == IOMT_A2D)
     {              
       g->iom.inputcfgreg = 0x0004;                    /* Bit 2 Hi, Pos Clk, Bits[1..0]=00 Select PLL w/Ext 10M Ref      */
       
       if (findflag("MUXCLK=C",g->flagstr) >= 0)
         g->iom.inputcfgreg = 0x0007;                  /* Bit 2 Hi, Pos Clk, Bits[1..0]=11 Select User Oscillator        */          
       else if (findflag("MUXCLK=P",g->flagstr) >= 0)
         g->iom.inputcfgreg = 0x0005;                  /* Bit 2 Hi, Pos Clk, Bits[1..0]=01 Select PLL w/Ext On-Board Ref */
       else if (findflag("MUXCLK=N",g->flagstr) >= 0)
         g->iom.inputcfgreg = 0x0006;                  /* Bit 2 Hi, Pos Clk, Bits[1..0]=10 Select Ext Clock              */          
       
       if ((g->module_rev == 7) || (g->module_rev == 8))
         { 
          /* Must Reverse Bit Order Of Data */
          /* Syn Clk Expects Data MSB First */
          /* GIGEXD Supplies Data LSB First */  
           dload_val          = 0x00000002;                                          /* Power Down Synthesizer */                        
           dload_val          = reverse_bit_order(dload_val,22);    
           g->iom.cfgwrbuf[0] = GE_SYNCLKADDR;
           g->iom.cfgwrbuf[1] = (int_u2) dload_val;                                  /* Set Register 2 Low     */
           g->iom.cfgwrbuf[2] = GE_SYNCLKADDR;
           g->iom.cfgwrbuf[3] = (((int_u2) (dload_val >> 16)) & 0x003F) | 0x1600;    /* Set Register 2 High    */ 
           g->iom.numcfgwr    = 4;
         }
       else if (g->module_rev == 9)
         {
            if ((rate < A2DR9D_MIN_FREQ) || (rate > A2DR9D_MAX_FREQ))                    
              {
                printf("\n\nERR: A2DR9 Sample Rate Out Of Range !!!\n");
                printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR9D_MIN_FREQ/1e6),(int_u4)(A2DR9D_MAX_FREQ/1e6));                         
                return(NOT_SUCCESSFUL);             
              }  
            
           dload_val = 0x00000002;                                                   /* Power Down Synthesizer */
          /* Set Low Addr, Dload Num Bits, FPGA Cfg Mode, Low Word Div Value*/       /* Power Down Bits        */
           iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
           iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);  
          /* Set Hi  Addr, Dload Num Bits, FPGA Cfg Mode, Hi  Word Div Value*/
           iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
           iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)(dload_val>>16),0x1000|EXTFPGACFG_BIT);    
         }  
       else if (g->module_rev == 10)
         {
            if ((rate < A2DR10D_MIN_FREQ) || (rate > A2DR10D_MAX_FREQ))                    
              {
                printf("\n\nERR: A2DR10 Sample Rate Out Of Range !!!\n");
                printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR10D_MIN_FREQ/1e6),(int_u4)(A2DR10D_MAX_FREQ/1e6));                         
                return(NOT_SUCCESSFUL);             
              }   
           store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00008880);          /* Put Device In Reset    */
           store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00008800);          /* Remove Reset           */   
           store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000A04);          /* Disable Clk1 Output    */ 
           store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000157C);          /* ClkSel[1..0] Reg Active*/                 
         }


       if (((g->iom.inputcfgreg == 0x0004) || (g->iom.inputcfgreg == 0x0005))  && (g->module_rev != 10)) /* PLL W/Ext or On-Board Ref */
         {
           if ((g->module_rev == 7) || (g->module_rev == 8))
             { 
               if ((rate < A2DR78D_MIN_FREQ) || (rate > A2DR78D_MAX_FREQ))   
                 {
                   printf("\n\nERR: A2DR%d PLL Freq Out of Range\n",g->module_rev);
                   printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR78D_MIN_FREQ/1e6),(int_u4)(A2DR78D_MAX_FREQ/1e6));
                   return(NOT_SUCCESSFUL);             
                 }
             }
           if (g->module_rev == 9)
             { 
               if (((rate < (A2DR9D_MINPLL_FREQ/2)) || (rate > A2DR9D_MAXPLL_FREQ)) || 
                   ((rate > (A2DR9D_MAXPLL_FREQ/2)) && (rate < A2DR9D_MINPLL_FREQ))) 
                 {
                   printf("\n\nERR: A2DR9  PLL Freq Out of Range!!!\n");
                   printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR9D_MINPLL_FREQ/1e6),(int_u4)(A2DR9D_MAXPLL_FREQ/1e6));
                   printf("        OR \n");
                   printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR9D_MINPLL_FREQ/2e6),(int_u4)(A2DR9D_MAXPLL_FREQ/2e6));           
                   return(NOT_SUCCESSFUL);             
                 } 
         
              /* Change Syn Clk Divisor From 8 To 4 */
               if ((rate >= A2DR9D_MINPLL_FREQ) && (rate <= A2DR9D_MAXPLL_FREQ))
                 {
                   rate_div = 0x00018040;
                   rate     = rate/2;
                 }                                                                  
             } 
             
          /* For Synthetic Clock Desired Freq = (Ref Freq * N)/(R*8) */            
           n_synclk      = (int_u4) (((float)(rate)) * 0.00008);             /* N Value = (freq*R*8)/Ref Freq */         
           actual_synclk = (int_u4) (((float) (A2D_REFCLK_FREQ / 800.0)) * ((float)n_synclk));
           if (rate != actual_synclk)
             printf("\nNOTE: Desired Clock Freq = %d, Actual = %d\n",g->freq,actual_synclk * (g->freq/rate));          
          
          /* 2 Writes Of 16 Bit Words = 32 Bit DWord, LS Word First  */
          /* Bits[21..0] Data, Bits[23..22] Unused, Bits[28..24] Count, Bit[29] Prog Mode, Bits[31..30] */
           if ((g->module_rev == 7) || (g->module_rev == 8))                             /* PLL Ext,On-Board Ref  */ 
             {                          
               dload_val = ((r_synclk << 4) & 0x0001FFF0) | 0x0008;                      /* R Value 13 Bits       */
               dload_val = reverse_bit_order(dload_val,22);
               g->iom.cfgwrbuf[4]  = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[5]  = (int_u2) dload_val;                                 /* Set R Reg-Low 12 Bits */
               g->iom.cfgwrbuf[6]  = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[7]  = (((int_u2) (dload_val >> 16)) & 0x003F) | 0x1600;   /* Set R Reg-High 1 Bit  */ 
                                                                                         /* Size=22 Bits, No FPGA */ 
               dload_val = ((n_synclk << 4) & 0x000FFFF0) | 0x0005;                      /* N Value 16 Bits       */   
               dload_val = reverse_bit_order(dload_val,22);
               g->iom.cfgwrbuf[8]  = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[9]  = (int_u2) dload_val;                                 /* Set N Reg-Low 12 Bits */
               g->iom.cfgwrbuf[10]  = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[11]  = (((int_u2) (dload_val >> 16)) & 0x003F) | 0x1600;  /* Set N Reg-High 4 Bits */ 
                 
               dload_val = rate_div;
               dload_val = reverse_bit_order(dload_val,22);
               g->iom.cfgwrbuf[12]  = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[13]  = (int_u2) dload_val;                                 /* Set Register 0 Low    */
               g->iom.cfgwrbuf[14] = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[15] = (((int_u2) (dload_val >> 16)) & 0x003F) | 0x1600;    /* Set Register 0 High   */ 
      
               dload_val = 0x00000022;
               dload_val = reverse_bit_order(dload_val,22);    
               g->iom.cfgwrbuf[16] = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[17] = (int_u2) dload_val;                                 /* Set Register 2 Low    */
               g->iom.cfgwrbuf[18] = GE_SYNCLKADDR;
               g->iom.cfgwrbuf[19] = (((int_u2) (dload_val >> 16)) & 0x003F) | 0x1600;   /* Set Register 2 High   */ 
             
               g->iom.numcfgwr  = 20;
             }
           else if (g->module_rev == 9)
             {              
               dload_val = ((r_synclk << 4) & 0x0001FFF0) | 0x0008;                       /* R Value 13 Bits       */      
              /* Set Low Addr, Dload Num Bits, FPGA Cfg Mode, Low Word R Value */   
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNLOREG,0x1000|EXTFPGACFG_BIT) ;                        
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);  
              /* Set Hi  Addr, Dload Num Bits, FPGA Cfg Mode, Hi  Word R Value */
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)(dload_val>>16),0x1000|EXTFPGACFG_BIT);  

               dload_val = ((n_synclk << 4) & 0x000FFFF0) | 0x0005;                       /* N Value 16 Bits       */
              /* Set Low Addr, Dload Num Bits, FPGA Cfg Mode, Low Word N Value */   
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);  
              /* Set Hi  Addr, Dload Num Bits, FPGA Cfg Mode, Hi  Word N Value */
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)(dload_val>>16),0x1000|EXTFPGACFG_BIT);  
 
               dload_val = rate_div;                                                      /* Clk Div Bits          */  
              /* Set Low Addr, Dload Num Bits, FPGA Cfg Mode, Low Word Div Value*/   
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);  
              /* Set Hi  Addr, Dload Num Bits, FPGA Cfg Mode, Hi  Word Div Value*/
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)(dload_val>>16),0x1000|EXTFPGACFG_BIT);  
               
               dload_val = 0x00000022;   
              /* Set Low Addr, Dload Num Bits, FPGA Cfg Mode, Low Word Div Value*/        /* Power Down Bits       */
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNLOREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);  
              /* Set Hi  Addr, Dload Num Bits, FPGA Cfg Mode, Hi  Word Div Value*/
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_SYNHIREG,0x1000|EXTFPGACFG_BIT);    
               iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)(dload_val>>16),0x1000|EXTFPGACFG_BIT);                                      
             }
                    
         }
       else if (g->module_rev == 10)
         {                   
           if (g->iom.inputcfgreg == 0x0007)                                             /* User Oscillator       */
             {                      
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000305);          /* Set Clk1 Input Select */                                             
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000016);          /* Set Bypass Bit        */               
             } 
           else if (g->iom.inputcfgreg == 0x0006)                                        /* External Clock        */
             {
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000345);          /* Set Clk2 Input Select */   
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000016);          /* Set Bypass Bit        */               
             }
           else
             {
               if ((rate < A2DR10D_MINPLL_FREQ) || (rate > A2DR10D_MAXPLL_FREQ))                     
                 {
                   printf("\n\nERR: A2DR10 PLL Freq Out of Range!!!\n");
                   printf(" Valid Range = %d Mhz To %d MHz\n",(int_u4)(A2DR10D_MINPLL_FREQ/1e6),(int_u4)(A2DR10D_MAXPLL_FREQ/1e6));                              
                   return(NOT_SUCCESSFUL);             
                 }
                 
               if (g->iom.inputcfgreg == 0x0005)                                         /* On-Board Ref PLL      */ 
                 store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000315);        /* Set Clk1 Input Select */ 
               else                                                                      /* Ext Ref PLL,Or Ext Clk*/
                 store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00000355);        /* Set Clk2 Input Select */   
           
           /*  for(n32s=5;n32s<50001;n32s++) */ /* n32s range, 1-512K, Assuming 10MHz Reg, Cut Down Range */
               for(n32s=10;n32s<11;n32s++) 
                 {
                   if ((ref_freq/n32s) < 2000)
                     break; 
                   if ((ref_freq/n32s) <= 2000000)    /* Ref Freq Range 2KHz-2MHz */
                     {                     
                       for(n2hs=4;n2hs<12;n2hs++)
                         {                                
                           for(n2ls=220;n2ls<708752;n2ls=n2ls+2)    /* for(n2ls=2;n2ls<1048578;n2ls=n2ls+2) */
                             {
                              /* printf("n2ls = %d\n",n2ls); */
                              /* Check Fvco */
                               n2hsflt = (float)n2hs;
                               n2lsflt = (float)n2ls;
                               n32sflt = (float)n32s;
                               f3nbflt = (((float)ref_freq)/n32sflt) * n2hsflt * n2lsflt;
                               
                               if (f3nbflt > 5.67e9)
                                 break; 
                                                                                                                                                                                     
                               if (f3nbflt >= 4.85e9)  
                                 {                                                                                                                                                   
                                   for(n1hs=4;n1hs<12;n1hs++)
                                     {                                                                            
                                       for(nc2ls=2;nc2ls<38;nc2ls=nc2ls+2)  /* FULL RANGE for(nc2ls=1;nc2ls<1048578;nc2ls=nc2ls+2) */
                                         { 
                                           n1flt   = (float)(n1hs*nc2ls);                                                                               
                                           f3nbflt = ((((float)ref_freq)/n32sflt) / n1flt) * n2hsflt * n2lsflt;      

                                           freqdif = f3nbflt - ((float)rate);
                                                                                       
                                           if (freqdif < 0.0)
                                             {
                                               freqdif = freqdif * -1.0;   
                                               negdiff = TRUE;
                                             }
                                           else
                                             negdiff = FALSE;
                                                                        
                                           if (freqdif < lowdif)
                                             {                                                
                                                holdn32s    = n32s  - 1;      /* Sbutract 1 Before Register Write */
                                                holdn2hs    = n2hs  - 4;      /* Subtract 4 Before Register Write */           
                                                holdn2ls    = n2ls  - 1;      /* Sbutract 1 Before Register Write */
                                                holdn1hs    = n1hs  - 4;      /* Subtract 4 Before Register Write */           
                                                holdnc2ls   = nc2ls - 1;      /* Sbutract 1 Before Register Write */
                                   
                                                holdnegdiff = negdiff; 
                                                lowdif      = freqdif;                                                                                          
                                             }
                                        
                                           if (lowdif == 0.0)
                                             break;  
                                                                                                                   
                                          /* if (nc2ls == 1) */
                                          /*   nc2ls = 0;    */
                                          
                                         }        /* For NC2LS */
                                       if (lowdif == 0.0)
                                         break; 
                                     }            /* For N1HS  */
                                   if (lowdif == 0.0)
                                     break;
                                 }                /* IF F3NBINT*/
                             }                    /* For N2LS  */  
                           if (lowdif == 0.0)
                             break;  
                         }                        /* For N2HS  */ 
                       if (lowdif == 0.0)
                        break;                         
                     }                            /* IF        */ 
                   if (lowdif == 0.0)
                     break; 
                 }                                /* For N32S  */

              /* Debug Output */
          /*   printf("N32S  = %d\n",holdn32s  + 1);  */     
          /*   printf("N2HS  = %d\n",holdn2hs  + 4);  */          
          /*   printf("N2LS  = %d\n",holdn2ls  + 1);  */ 
          /*   printf("N1HS  = %d\n",holdn1hs  + 4);  */           
          /*   printf("NC2LS = %d\n",holdnc2ls + 1);  */ 
                                                                                                                                                 
              /* N32S Reg  */  
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002E00 | ((holdn32s >> 16) & 0x00000007));
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002F00 | ((holdn32s >>  8) & 0x000000FF)); 
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00003000 | (holdn32s & 0x000000FF));

              /* N2HS Reg, N2LS High Bits  */
       store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002800 | ((holdn2hs << 5) & 0x000000E0) | ((holdn2ls >> 16) & 0x0000000F));

              /* N2LS Reg  */ 
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002900 | ((holdn2ls >> 8) & 0x000000FF));
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002A00 | (holdn2ls  & 0x000000FF));


              /* N1HS Reg  */ 
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00001900 | ((holdn1hs << 5) & 0x000000E0) );

              /* NC2LS Reg */    
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002200 | ((holdnc2ls >> 16) & 0x0000000F) );               
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002300 | ((holdnc2ls >>  8) & 0x000000FF) );
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00002400 | (holdnc2ls  & 0x000000FF) );
       
               store_a2dr10_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x00008840);          /* Start ICAL            */         
               if (lowdif != 0.0)
                 { 
                   if (holdnegdiff == TRUE)
                     printf("\nNOTE: Desired Clock Freq = %d, Actual = %e\n",g->freq,((float)rate) + lowdif);
                   else
                     printf("\nNOTE: Desired Clock Freq = %d, Actual = %e\n",g->freq,((float)rate) - lowdif);
                 }                   
             }
         }
       

       if ((g->module_rev == 9) || (g->module_rev == 10))
         {
            if (findflag("A2D9GAIN",g->flagstr) >= 0)
              { 
                printf("WARN: The A2D9GAIN flag is being depricated!!!\n");
                printf("WARN: Future Software Versions Will Not Support The Use Of This Flag.\n");                
                printf("WARN: Use the Flag A2DGAIN=<value> to avoid receiving this message and for future compatibility.\n");
                dload_val = findintflag("A2D9GAIN",g->flagstr);
              }  
            else
             dload_val = findintflag("A2DGAIN",g->flagstr);           

           /* Set Front End Gain */              
            if ((dload_val > 20) || (dload_val < -4))
              {
                printf("\nERR: A2DR9 Gain Range -4 to 20 dB!!\n");
                printf("User Value %d Out Of Range-Change Value In Config File %s\n",dload_val,g->pathnfile);
                return(NOT_SUCCESSFUL); 
              } 

           /* Set A/D Gain   */
            dload_val = dload_val + 11;           /* Gain Value Offset From Data Sheet */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_GAINREG,0x1000|EXTFPGACFG_BIT); 
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT);             /* Gain Logic In Reset */ 
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_GAINREG,0x1000|EXTFPGACFG_BIT); 
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),dload_val | 0x0100,0x1000|EXTFPGACFG_BIT); /* Reove Reset, Value  */ 

           /* Set A/D Config */    
            dload_val = 0x0018;   /* Address Reg 0x00, Value 0x18-MSB First        */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT);
        
           /* Negative Edge Clock */    
            dload_val = 0x1683;   /* Address Reg 0x16, Data Valid Neg Edge         */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT); 

            dload_val = 0x1401;   /* Address Reg 0x14, Value 0x01-SDR On, 2's Comp */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT);

            dload_val = 0x1811;   /* Address Reg 0x18, Value 0x11-1Vp-p            */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT);
      
           /* ***FOR DEBUG Address Reg 0x0D, Value 04,Output Checker Board Pattern */
            dload_val = 0x0D00;   /* Set Value 0x0D00 For Normal Operation         */  
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT); 
            
           /* LVDS Power */
            dload_val = 0x00150F; /* Address Reg 0x15, 2mA LVDS Output             */
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT); 

            dload_val = 0x00FF01; /* Address Reg 0xFF, Value 01, Trans To Slave Reg*/
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DLOREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),(int_u2)dload_val,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),A2DR9_A2DHIREG,0x1000|EXTFPGACFG_BIT);
            iom_store_cfg(g->iom.cfgwrbuf,&(g->iom.numcfgwr),0x0000,0x1000|EXTFPGACFG_BIT); 

         }  
     }
         
   else if (g->module_type == IOMT_DR2D)
     {
       if (findflag("CLKI",g->flagstr) >= 0)            /* Negative Edge Clock  */                                       
         g->iom.inputcfgreg = 0x0000;                      
       else
         g->iom.inputcfgreg = 0x0004;                   /* Positive Edge Clock  */              
     }
   
/* printf("Number Of Moudle Config Writes = %d\n",g->iom.numcfgwr); */
 
   return(SUCCESSFUL);
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 realtime_setconfig(int_u1 *txdata,int_u1 *rxdata,Type_GIGEXD_cfg *g,int usage)
 {
   int ii;
   int_8  jj;
   int_u2 inputcfgreg = 0;      
   int_u4 clks_per_pkt;
   int_u4 phase_inc;                     /* NCO Phase Increment Register Value                 */
   double data_rate;
   float  decim_clk_freq;
   double inclktime   = 0.0;             /* Input Clock Freq In 250pSec Increments * 8M Scalar */
   double tunetcdelay = 0.0;             /* Tuner Timecode Delay-Delay Of Data Through Tuner   */

if (usage == 0)
  {
 printf("\nSyntax: gigexd rtcfg <Host IP Addr> <GIGEXD IP Addr>  <Path & Filename> \n\n");
 printf("                  rtcfg                  = writes user cfg info to RAM memory for immediate GIGEXD config \n");
 printf("                  <Host IP Addr>         = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
 printf("                  <GIGEXD IP Addr>       = Dot Notation Of GIGEXD  IP Addr, Ex. 192.168.200.1 \n");
 printf("                  <path & filename>      = Path & Filename Of Config File That Holds Config Parameters\n");
   
 printf("\nThe 'rtcfg' operation is used to write user config info to RAM of the GIGEXD. \n");
 printf("This config info is used to change parameters during testing of the GIGEXD \n");
 printf("IP Address, Multicast Address, VLAN, and Module Type CANNOT be changed with 'rtcfg'. \n");
 printf("All other parameters, Sample Rate, Sample Size, Digital Tuner Parameters, etc can \n");
 printf("be changed 'on the fly'.  This allows for quick testing of the GIGEXD capabilities in\n");
 printf("an 'engineering' environment.  Once the settings have been tested they can be committed \n");
 printf("to flash memory on the GIGEXD (using the flashcfg operation) for permanent retention \n");
 printf("through power cycles.  In short, 'rtcfg' provides for quick prototyping and analysis \n");
 printf("by engineers. Removal of power erases the parameters set by rtcfg in memory and \n");
 printf("power up causes parameters set by 'flashcfg' to be loaded and active. \n");   
 exit(-1);
  }

  /* Read User Config File */ 
  /* Turn Off Data Stream  */
   if (read_cfg_file(txdata,rxdata,g) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Retrieve I/O Module Config Parameters  */            
   if (iomodule_setconfig(g) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);  

   printf("\nYou Are About To Change Realtime Configuration Parameters.\n");
   printf("GIGEXD Configuration Changes For IP, Multicast, VLAN, and Module Type Can ONLY \n");
   printf("Be Changed With A Flash Configuration Operation.  All Other Parameters Will Be \n");
   printf("Changed To Those Listed Above.\n"); 
   printf("\nThese Realtime Changes Will NOT Overwrite Previous FLASH Configuration Settings!!\n");
   printf("Continue? ('y' or 'n') ");

  /* Get User Response */ 
   if (answer_yes() == FALSE)
     {
       printf("Aborting Configuration \n");
       return(SUCCESSFUL);
     }
    
  /* Turn Off Incoming Data Stream */ 
   if (GIGE_turnOFF_data(txdata,rxdata,FALSE,TRUE) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
  
   printf("Programming Realtime Config Areas  ...");
  
   /* Set Format Identifier Field In SDDS Header */
   ii = (abs(g->numbits) << 8);
   if (abs(g->numbits)  ==  8) ii = ii | 0x0001;
   if (abs(g->numbits)  == 16) ii = ii | 0x0002;  
   if ((abs(g->numbits) == 16) && (findflag("LEND",g->flagstr) >=0)) ii = ii | 0x8000; /* Non-Standard SDDS Little Endian */
   ii = ii | 0x0080;                                                                   /* Set Standard SDDS Bit           */
   single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0015,ii);    
   single_command(txdata,rxdata,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0017,ii);             

  /* Set Data Rate Field In SDDS Header     */   
   data_rate =  (double) (((double) g->freq) / ((double)g->input_decim));                           /* Calc Num Bits * Rate/Decim   */                                  
   if (g->tunval == TRUE)                                                       
     data_rate = data_rate / ((double)(Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval)); /* Divide By Decimation Factor  */      
   data_rate  = (data_rate  * (pow(2,63)/125000000.0)) + 0.5;                                       /* Put In SDDS Format           */       
   jj         = (int_u4) (((int_8)data_rate) >> 32);  
   single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0021,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));                
   single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0022,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));             
   single_command(txdata,rxdata,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0023,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));             
   single_command(txdata,rxdata,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0024,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));               
   jj         = (int_u4) (((int_8)data_rate));  
   single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0023,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));             
   single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0024,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));             
   single_command(txdata,rxdata,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0025,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));             
   single_command(txdata,rxdata,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0026,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));             
                  
  /* Set Input Config Reg Values For Module */
   inputcfgreg = g->iom.inputcfgreg << 8;        /* High Byte of 16 Bit Cfg Word */       
             
  /* Set Input Config Reg, Data Size For Output 16 Bit Packing    */ 
  /* Set Input Config Reg, Timecode Enable Bit                    */
  /* Set Input Config Reg, Input Rate Decimation                  */
  /* Set Input Config Reg, Tuner Enable Bit                       */
   if ((abs(g->numbits) == 16)  && 
       (g->tunval == TRUE) && 
       (findflag("LEND",g->flagstr) >=0))                   inputcfgreg = inputcfgreg | 7; /* Real|Complex Tuner-16 Bits Little Endian */ 
   else if ((abs(g->numbits) == 16) && (g->tunval == TRUE)) inputcfgreg = inputcfgreg | 6; /* Real|Complex Tuner-16 Bits Big Endian    */
   else if ((abs(g->numbits) ==  8) && (g->tunval == TRUE)) inputcfgreg = inputcfgreg | 5; /* Real|Complex Tuner- 8 Bits               */
   else if ((g->numbits == 16) && (findflag("LEND",g->flagstr) >= 0)) inputcfgreg = inputcfgreg | 4; /* Raw Data-16 Bits Little Endian */
   else if (g->numbits == 16)                                         inputcfgreg = inputcfgreg | 3; /* Raw Data-16 Bits Big    Endian */ 
   else                                                    inputcfgreg = inputcfgreg | g->numbits/4; /* 8,4, or 1 Bit Raw Data         */ 

   if (g->tcval  == TRUE)      inputcfgreg = inputcfgreg | 0x08;            /* If Timecode Required-Set Timecode Enable Bit */     
   inputcfgreg = inputcfgreg | ((0x08 - g->input_decim) << 4);              /* Set Input Decimation Value                   */ 
   if (g->tunval == TRUE)      inputcfgreg = inputcfgreg | 0x80;            /* If Tuner Required -Set Tuner Enable Bit      */

  /* Set Input Bit Shift Value                                    */
  /* 1st Of 2 Config Register Write                               */
   inputcfgreg = inputcfgreg | (g->bitshift << 11);                                    
   single_command(txdata,rxdata,GE_INPUTCFGADDR,inputcfgreg);   
      
  /* printf("InputCfgReg = %x\n",inputcfgreg);                    */  

  /************/
  /* TimeCode Config */
  /* Calc Number Of Clocks For Single SDDS Packet */
  /* If Tuner Enabled  clks_per_pkt = Input Decim * 1024/NUMBYTES *  Tune Decim * Tune Scalar) */
  /* If !Tuner Enabled clks_per_pkt = Input Decim * 1024/NUMBYTES                              */
   if (g->tunval == TRUE)
     { 
       clks_per_pkt = g->input_decim * (1024/(abs(g->numbits)/8)) * Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval;

      /* For Complex Data */
       if (g->numbits < 0)
         clks_per_pkt = clks_per_pkt/2;  
     } 
   else
     clks_per_pkt = g->input_decim * (1024/(abs(g->numbits)/8));

  /* 2nd Of 2 Config Register Write                               */
   single_command(txdata,rxdata,GE_INPUTCFGADDR,(int_u2)(clks_per_pkt>>8));     

  /* Set I/O Module Config Parameters                             */
  /* **Must Happen After Input Cfg Write**                        */   
   for(ii=0;ii<g->iom.numcfgwr;ii=ii+2)
     single_command(txdata,rxdata,g->iom.cfgwrbuf[ii],g->iom.cfgwrbuf[ii+1]); 

   /* printf("Clocks Per Packet = %d\n",clks_per_pkt);                    */                   
   /* printf("Clocks Per Packet Written To Reg = %d\n",clks_per_pkt>>8);  */                   

  /* Set Up Timecode Calcs If Timecode Enabled                                                */
  /* Num Clk (Time) Per Pkt = ( (1/freq) / 250e-12) * 8M Scalar                               */
  /* If Tuner, Subtract ((StartDelay * InputDec) - ((InputDec - 1) * 5)) * ((1/Freq)/25opSec) */
   if (g->tcval == TRUE)
     {
      /*For Timecode Calc Number Of Clk Delays Through Tuner    */  
       if (g->tunval == TRUE)
         {
          /* Calc Base Delay Value-In Clocks */
           tunetcdelay = (double) (Filter_tcdel[g->gigexdrev][g->firmwareval] - ((Filter_taps[g->gigexdrev][g->firmwareval]+1)/2));
           
          /* Add In Actual Delay For Tuner   */
           tunetcdelay = (double) ((tunetcdelay * g->input_decim) - ((g->input_decim -1) * 5) - (g->input_decim -1));  

           tunetcdelay = (tunetcdelay / ((double)g->freq)) * -4000000000.0;     /* Make Delay Negative (Subtract Out Delay)*/
           /* printf("Time Delay For TC = %d\n",(int_u4)tunetcdelay);                     */   
         }

      /* Add In User Specified Delay */ 
       if (findflag("XTCDEL",g->flagstr) >= 0)
         tunetcdelay = tunetcdelay + ((double)(findintflag("XTCDEL",g->flagstr)));
       if (tunetcdelay < 0.0)
         {
           single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,0xFFFF);
           single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,0xFFFF);   
         }
       else
         { 
           single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,0x0000);
           single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,0x0000); 
         }  
       single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,(int_u2)(((int_u4)tunetcdelay)>>16));
       single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,(int_u2)((int_u4)tunetcdelay));
          

      /* Calc Number Of 250pS In Clock Freq * Scalar GE_TIMEC_SCALAR */ 
       inclktime = (GE_TIMEC_SCALAR/((double)g->freq))*4000000000.0 ; 
       /* printf("Input Clock Rate = %d\n",(int_u4)inclktime);                            */   
              
       single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,(int_u2)(((int_u4)inclktime)>>16));
       single_command(txdata,rxdata,GE_TXCFGADDR|GE_TX_TCREGADDR,(int_u2)((int_u4)inclktime));
     }                  
 /************/
  /* Tuner Config */   
   if (g->tunval == TRUE)
     {
      /* Set Real Tuner Output Mode */
       if (g->numbits > 0 )
         single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_FILT_CFGADDR,0x0001);  /* Turn On Real    Tuner Mode */
       else
         single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_FILT_CFGADDR,0x0000);  /* Turn On Complex Tuner Mode */  
         
      /* Set Decimation Scalar */                               
       single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_DECI_CFGADDR,(int_u2) (0x00010000 - g->decmultval));                   

      /* Set NCO Frequency     */
       decim_clk_freq = (float) (((float) (g->freq))/ ((float) (g->input_decim))); 
       phase_inc      = (int_u4) (((float) (((float) ((float)(g->reqcntrfreqval)/ decim_clk_freq)) * 1048576.0)) + 0.5);     
       single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_NCO_CFGADDR,(int_u2) (phase_inc >> 16));        
       single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_NCO_CFGADDR,(int_u2) (phase_inc));       
                 
      /* Set Tuner Gain        */ 
       single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_GAIN_CFGADDR,(int_u2) (g->tunegainval/6));                              
      
      /* Set Coefficients From User File     */ 
        if (g->coefval != GE_COEF_OFF)
          {
           /* Write Symmetric Coefficients  */  
            for(ii =0;ii<((Filter_taps[g->gigexdrev][g->firmwareval]/2)+1);ii++)              
              single_command(txdata,rxdata,GE_TUNCFGADDR|GE_TUNE_COEF_CFGADDR,g->coef[ii]);              
          }  
     } 

   printf("Done\n");

  /* Turn On Incoming Data Stream */ 
   printf("Restarting Data With New Cfg Parameters ... ");            
   if (GIGE_turnON_data(txdata,rxdata,FALSE,FALSE) == NOT_SUCCESSFUL)
     {
       printf("Failure\n");
       return(NOT_SUCCESSFUL);
     }   
   printf("Done\n");
   
   printf("\nRealtime Config Complete-New Config Parmeters Take Effect Immediately!!\n"); 

   return(SUCCESSFUL);
 }
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 setconfig_EPROM(int_u1 *txdata,int_u1 *rxdata,Type_GIGEXD_cfg *g, int usage)
 {
   int ii,numbytesrd = 0;
   int_u4 jj;
   int_u1 *cfgsectdat;
   int_u4 address = GE_EPROMCFGSPACE;       /* Assign Start Address To User CFG Space              */   
   int_u2 ip_hdr[10]   = {0x0045, 0x5404, 0x0000, 0x0040, 0x1140, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
   int_u2 *word;
   int_u4 wrseqadr  = 0;                    /* Assign First Write Address To Start Of EPROM Region */
   int_u4 query_adr = GE_EPROMQUERYADR;     /* Assign Query Data To Eprom Region                   */ 
   int_u4 phase_inc;                        /* NCO Phase Increment Register Value                  */
   int_u2 inputcfgreg = 0;
   double data_rate;
   int_u4 clks_per_pkt;
   float decim_clk_freq;
   double  inclktime  = 0.0;                 /* Input Clock Freq In 250pSec Increments             */
   double tunetcdelay = 0.0;                 /* Tuner Timecode Delay-Delay Of Data Through Tuner   */
   Type_GIGEXD_query geQ;

   /* FILE *ftempo; */
   

 if (usage == 0)
  {
 printf("\nSyntax: gigexd flashcfg <Host IP Addr> <GIGEXD IP Addr>  <Path & Filename> \n\n");
 printf("                  flashcfg               = writes user cfg info to flash memory for retention between power cycles \n");
 printf("                  <Host IP Addr>         = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
 printf("                  <GIGEXD IP Addr>       = Dot Notation Of GIGEXD IP Addr, Ex. 192.168.200.1 \n");
 printf("                  <path & filename>      = Path & Filename Of Config File That Holds Config Parameters\n");
   
 printf("\nThe 'flashcfg' operation is used to write user config info to flash memory of the GIGEXD. \n");
 printf("This config info is used at 'power up' to configure GIGEXD parameters such as IP address, \n");
 printf("Multicast Address, Data Rate, Sample Size, Sample Rate, and Digital Tuning parameters. \n");
 printf("Writing config info to flash allows the user to remove power from the GIGEXD and upon \n");
 printf("next power cycle retain configuration previous to the power cycle.\n");
 printf("If the flash config area happens to be empty, (normally not the case, all GIGEXD units \n");
 printf("are programmed with default config before shipment) the GIGEXD will default to IP address \n");
 printf("192.9.200.105\n");  
 exit(-1);
  }
 
 /* Check GigExD Rev 2 Only */
  if (GIGE_retrieve_revnvers(txdata,rxdata,NULL) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL); 
           
  /* Read Config File Info-Check For User Errors */ 
   if (read_cfg_file(txdata,rxdata,g) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Retrieve I/O Module Config Parameters  */
   if (iomodule_setconfig(g) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

   printf("Operating On User Config Space\n");
   printf("\nYou Are About To Re-Configure The GigExD Internal Settings To The Above Configuration!!\n");
   printf("These Settings Will Overwrite Previous Configuration Settings!!\n");
   printf("Continue? ('y' or 'n') ");
  
  /* Get User Response */ 
   if (answer_yes() == FALSE)
    {
      printf("Aborting Configuration \n");
      return(SUCCESSFUL);
    }

  /* Set Page Address To Next Page At 0x00100000 */ 
   if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
 
  /* Allocate Space/Setup Pointers */
   word       = (int_u2 *)txdata;
   cfgsectdat = (int_u1 *)malloc(GE_EPROMSECTORSIZE*sizeof(int_u1));
   if (cfgsectdat == NULL)
     {
       printf("ERROR: Malloc Of Memory For Cfg Space Write Failed\n");
       return(NOT_SUCCESSFUL); 
     }
     
  /* Clear Config Memory Buf       */
   memset(cfgsectdat,0xFF,GE_EPROMSECTORSIZE*sizeof(int_u1));
 
  /* Turn Off Incoming Data Stream */ 
   if (GIGE_turnOFF_data(txdata,rxdata,FALSE,TRUE) == NOT_SUCCESSFUL)
     {
       free(cfgsectdat);
       return(NOT_SUCCESSFUL);
     }
       
   printf("Clearing EPROM Cfg Sector...");
   EPROM_clear_sector(txdata,rxdata,address);
   printf("Done\n");
  
  /****************************************/   
  /* Fill Buf With New Config             */
  /****************************************/    
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXRSTADDR);     /* Turn Off Incoming Data            */
   store_sequence_word(cfgsectdat,&wrseqadr,0x0000);

  /* Set GigE Header Values */
    /* Destination HW Address */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0001);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) ((g->destmcaddrval & 0x7f00)|0x005E));  
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0002);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->destmcaddrval >> 16)); 

    /* Source HW Address      */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0004);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0005);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
    
  /* Set IP Header Values   */
   /* Tx Output Packet        */  
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x000D);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x000E);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));   

  /*  ARP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0073);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0074);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0075);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
  /* ARP Packet HW Address  */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x007B);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x007C);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x007D);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
 
  /* ARP Packet IP Address  */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x007E);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x007F);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* IGMP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0093);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0094);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x0095);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
 
  /* IGMP Packet IP Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x009D);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x009E);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* ICMP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x00C3);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x00C4);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x00C5);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* ICMP Packet IP Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x00CD);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_TXCFGADDR|GE_TX_DATWRADDR)+0x00CE);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));
       
  /* Set Rx IP Addresses   */
  /* ARP Rx IP Address     */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0004);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0007);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));
  /* ICMP Rx IP Address    */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0024);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0027);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));


  /********VLAN**************/
  /* Destination HW Address */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0001);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) ((g->destmcaddrval & 0x7f00)|0x005E));  
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0002);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->destmcaddrval >> 16)); 

  /* Source HW Address      */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0004);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0005);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
    
  /* Set IP Header Values   */
   /* Tx Output Packet        */  
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x000F);     
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0010);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));   

  /*  ARP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0073);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0074);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0075);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
  /* ARP Packet HW Address  */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x007D);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x007E);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x007F);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
 
  /* ARP Packet IP Address  */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0080);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0081);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* IGMP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0093);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0094);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x0095);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16)); 
 
  /* IGMP Packet IP Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x009F);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00A0);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* ICMP Packet HW Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00C3);     
   store_sequence_word(cfgsectdat,&wrseqadr,0x6000);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00C4);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00C5);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* ICMP Packet IP Address */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00CF);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_VLANTXCFGADDR|GE_TX_DATWRADDR)+0x00D0);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));
       
  /* Set Rx IP Addresses   */
  /* ARP Rx IP Address     */ 
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0074);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x0077);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));
  /* ICMP Rx IP Address    */
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x009C);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) g->gigeipaddrval);   
   store_sequence_word(cfgsectdat,&wrseqadr,(GE_RXCFGADDR|GE_RX_CPUWRADDR)+0x009F);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->gigeipaddrval >> 16));

  /* Setup IP Header Data                   */   
   ip_hdr[6]     = (int_u2) g->gigeipaddrval;             /* Source Address      */
   ip_hdr[7]     = (int_u2) (g->gigeipaddrval >> 16);
   ip_hdr[8]     = (int_u2) g->destmcaddrval;             /* Destination Address */
   ip_hdr[9]     = (int_u2) (g->destmcaddrval >> 16);
   ip_hdr[5]     = sdds_compute_checksum(10,ip_hdr);

  /* Setup Tx IP Header Data For SDDS Pkt   */
   for (ii=0;ii<10;ii++)
    {   
      store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0007+ii);             
      store_sequence_word(cfgsectdat,&wrseqadr,ip_hdr[ii]);

      store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0009+ii);             
      store_sequence_word(cfgsectdat,&wrseqadr,ip_hdr[ii]);
    }
    
 /* &BILL-For Saving Default Sector Values */  
 /* ftempo = fopen("defaultcfg.txt","w+");
  if (ftempo ==NULL)
   {
     printf("Open Of Debug File 'debugcomputecoef.txt'  FAILED!!\n");
     printf("Aborting Configuration Update.\n");
     return(NOT_SUCCESSFUL);
   } 
  printf("Size Default Config = %d \n",wrseqadr);
  for (ii=0;ii<wrseqadr;ii=ii+8)
   { 
      for(jj=0;jj<8;jj++)
        fprintf(ftempo,"0x%02x,", cfgsectdat[ii+jj]);
      fprintf(ftempo,"\n");
   } 
  fclose(ftempo);
 */

 /* For Init Of Rack Mount GIGEXD Units */ 
   if (usage == 2)
     {
      /* Retrieve Download Revision In rxdata */
      /* Store Download Revision In Download Config Num Location */ 
       if (GIGE_retrieve_revnvers(txdata,rxdata,NULL) == NOT_SUCCESSFUL)
         return(NOT_SUCCESSFUL);
       memcpy(cfgsectdat+(GE_EPROMDWNCFGADDR-GE_EPROMCFGSPACE),rxdata,sizeof(int_u2));

      /* Write Cfg Membuf To EPROM */
       printf("Writing Configuration Section (15 Secs)\n");
       for (ii=0;ii<GE_EPROMSECTORSIZE*sizeof(int_u1);ii=ii+sizeof(int_u4))
        EPROM_write_Dword(txdata,rxdata,GE_EPROMCFGSPACE+ii,*((int_u4 *)(cfgsectdat+ii))); 

       /* Send EPROM Rd Cfg Command         */
       printf("Restarting Data With New Cfg Parameters ... ");           
       if (single_command(txdata,                                                              
                      rxdata,
                      GE_EPROMCFGRDDATA | (0x0FFF & address),
                      (int_u2)((address >> 4) & 0xF000)) == NOT_SUCCESSFUL)
         {
           printf("FAILED!\n");
           free(cfgsectdat);
           return(NOT_SUCCESSFUL);
         }
       sleep(1);
       printf("Done\n");


       return(SUCCESSFUL);
     }   


  /* Set VLAN Tx Output Enable Bit          */
   if (g->vlanval != 0)
     { 
      /* Set VLAN Value In Eth Hdr          */ 
       ii = ((g->vlanval << 8) & 0xFF00) | ((g->vlanval >> 8) & 0x00FF);                /* Convert Little E To Big E      */     
       store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0007);             
       store_sequence_word(cfgsectdat,&wrseqadr,ii);

      /* Turn Tx MC Output Enable Bit On    */
       store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_TCREGADDR);             
       store_sequence_word(cfgsectdat,&wrseqadr,1);
     }
   else
     { 
      /* Turn Tx MC Output Enable Bit Off   */
       store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_TCREGADDR);             
       store_sequence_word(cfgsectdat,&wrseqadr,0);
     }

   
  /* Set Format Identifier In SDDS Header   */
   ii = (abs(g->numbits) << 8);
   if (abs(g->numbits) ==  8) ii = ii | 0x0001;
   if (abs(g->numbits) == 16) ii = ii | 0x0002;  
   if ((abs(g->numbits) == 16) &&  (findflag("LEND",g->flagstr) >=0)) ii = ii | 0x8000; /* Non-Standard SDDS Little Endian */ 
   ii = ii | 0x0080;                                                                    /* Set Standard SDDS Bit           */
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0015);             
   store_sequence_word(cfgsectdat,&wrseqadr,ii);
   store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0017);             
   store_sequence_word(cfgsectdat,&wrseqadr,ii);

  /* Set Data Rate Field In SDDS Header     */   
   data_rate =  (double) (((double) g->freq) / ((double)g->input_decim));                           /* Calc Num Bits * Rate/Decim   */                                  
   if (g->tunval == TRUE)                                                       
     data_rate = data_rate / ((double)(Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval)); /* Divide By Decimation Factor  */   
   data_rate  = (data_rate  * (pow(2,63)/125000000.0)) + 0.5;                                       /* Put In SDDS Format           */     
   jj         = (int_u4) (((int_8)data_rate) >> 32);  
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0021);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0022);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));  
   store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0023);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));
   store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0024);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));
   jj         = (int_u4) (((int_8)data_rate));  
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0023);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_DATWRADDR+0x0024);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));  
   store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0025);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj>>24) &0x000000FF) | ((jj>>8) & 0x0000FF00)));
   store_sequence_word(cfgsectdat,&wrseqadr,GE_VLANTXCFGADDR|GE_TX_DATWRADDR+0x0026);             
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((jj<<8) &0x0000FF00) | ((jj>>8) & 0x000000FF)));
     

   
     
  /* Set Input Config Reg Values For Module */
   inputcfgreg = g->iom.inputcfgreg << 8;        /* High Byte of 16 Bit Cfg Word */       
 
  /* Set Input Config Reg, Data Size For Output 16 Bit Packing    */ 
  /* Set Input Config Reg, Timecode Enable Bit                    */
  /* Set Input Config Reg, Input Rate Decimation                  */
  /* Set Input Config Reg, Tuner Enable Bit                       */ 
   if ((abs(g->numbits) == 16)  && 
       (g->tunval == TRUE) && 
       (findflag("LEND",g->flagstr) >=0))                   inputcfgreg = inputcfgreg | 7; /* Real|Complex Tuner-16 Bits Little Endian */ 
   else if ((abs(g->numbits) == 16) && (g->tunval == TRUE)) inputcfgreg = inputcfgreg | 6; /* Real|Complex Tuner-16 Bits Big Endian    */
   else if ((abs(g->numbits) ==  8) && (g->tunval == TRUE)) inputcfgreg = inputcfgreg | 5; /* Real|Complex Tuner- 8 Bits               */
   else if ((g->numbits == 16) && (findflag("LEND",g->flagstr) >= 0)) inputcfgreg = inputcfgreg | 4; /* Raw Data-16 Bits Little Endian */
   else if (g->numbits == 16)                                         inputcfgreg = inputcfgreg | 3; /* Raw Data-16 Bits Big    Endian */ 
   else                                                inputcfgreg = inputcfgreg | g->numbits/4;     /* 8,4, or 1 Bit Raw Data         */ 

   if (g->tcval  == TRUE)         inputcfgreg = inputcfgreg | 0x08;              /* If TC Required-Set TC Enable Bit        */     
   inputcfgreg = inputcfgreg | ((0x08 - g->input_decim) << 4);                   /* Set Input Decimation Value              */ 
   if (g->tunval == TRUE)      inputcfgreg = inputcfgreg | 0x80;                 /* If Tuner Required -Set Tuner Enable Bit */
       
  /* Set Input Bit Shift Value                                    */
  /* 1st Of 2 Config Register Write                               */
   inputcfgreg = inputcfgreg | (g->bitshift << 11); 
   store_sequence_word(cfgsectdat,&wrseqadr,GE_INPUTCFGADDR);   
   store_sequence_word(cfgsectdat,&wrseqadr,inputcfgreg);                             
    
 /************/
  /* TimeCode Config */
  /* Calc Number Of Clocks For Single SDDS Packet */
  /* If Tuner Enabled  clks_per_pkt = Input Decim * 1024/NUMBYTES *  Tune Decim * Tune Scalar) */
  /* If !Tuner Enabled clks_per_pkt = Input Decim * 1024/NUMBYTES                              */
   if (g->tunval == TRUE)
     { 
       clks_per_pkt = g->input_decim * (1024/(abs(g->numbits)/8)) * Filter_deci[g->gigexdrev][g->firmwareval] * g->decmultval;

      /* For Complex Data */
       if (g->numbits < 0)
         clks_per_pkt = clks_per_pkt/2;  
     } 
   else
     clks_per_pkt = g->input_decim * (1024/(abs(g->numbits)/8));

  /* 2nd Of 2 Config Register Write                               */
   store_sequence_word(cfgsectdat,&wrseqadr,GE_INPUTCFGADDR);   
   store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(clks_per_pkt>>8));
       
   /* printf("Clocks Per Packet = %d\n",clks_per_pkt);                     */     
   /* printf("Clocks Per Packet Written To Reg = %d\n",clks_per_pkt>>8);   */     

  /* Set I/O Module Config Parameters       */ 
  /* **Must Happen After Input Cfg Write**  */ 
   for(ii=0;ii<g->iom.numcfgwr;ii=ii+2)
     {
       store_sequence_word(cfgsectdat,&wrseqadr,g->iom.cfgwrbuf[ii]);      /* Write Address */
       store_sequence_word(cfgsectdat,&wrseqadr,g->iom.cfgwrbuf[ii+1]);    /* Write Data    */
     }  

  /* Set Up Timecode Calcs If Timecode Enabled                                                */
  /* Num Clk (Time) Per Pkt = ( (1/freq) / 250e-12) * 8M Scalar                               */
  /* If Tuner, Subtract ((StartDelay * InputDec) - ((InputDec - 1) * 5)) * ((1/Freq)/25opSec) */
   if (g->tcval == TRUE)
     {
      /*For Timecode Calc Number Of Clk Delays Through Tuner    */  
       if (g->tunval == TRUE)
         {
          /* Calc Base Delay Value-In Clocks */
           tunetcdelay = (double) (Filter_tcdel[g->gigexdrev][g->firmwareval] - ((Filter_taps[g->gigexdrev][g->firmwareval]+1)/2));
                                                  
          /* Add In Actual Delay For Tuner   */
           tunetcdelay = (double) ((tunetcdelay * g->input_decim) - ((g->input_decim -1) * 5) - (g->input_decim -1));  

           tunetcdelay = (tunetcdelay / ((double)g->freq)) * -4000000000.0 ;
           /* printf("Time Delay For TC = %d\n",(int_u4)tunetcdelay);                    */   
         }

      /* Add In User Specified Delay */ 
       if (findflag("XTCDEL",g->flagstr) >= 0) 
         tunetcdelay = tunetcdelay + ((double)(findintflag("XTCDEL",g->flagstr)));
       if (tunetcdelay < 0.0)
         {
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
           store_sequence_word(cfgsectdat,&wrseqadr,0xFFFF);
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
           store_sequence_word(cfgsectdat,&wrseqadr,0xFFFF);
         }
       else
         { 
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
           store_sequence_word(cfgsectdat,&wrseqadr,0x0000);
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
           store_sequence_word(cfgsectdat,&wrseqadr,0x0000);
         }  

       store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((int_u4)tunetcdelay)>>16));

       store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)((int_u4)tunetcdelay));

      /* Calc Number Of 250pS In Clock Freq * Scalar GE_TIMEC_SCALAR */
       inclktime = (GE_TIMEC_SCALAR/((double)g->freq))*4000000000.0 ; 
       /* printf("Input Clock Rate = %d\n",(int_u4)inclktime);                           */   
              
       store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);   
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)(((int_u4)inclktime)>>16));

       store_sequence_word(cfgsectdat,&wrseqadr,GE_TXCFGADDR|GE_TX_TCREGADDR);
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2)((int_u4)inclktime));
     }   
 /************/
 /* Tuner Config */   
   if (g->tunval == TRUE)
     {
      /* Set Real Tuner Output Mode */
       if (g->numbits > 0 )
         {            
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_FILT_CFGADDR);  /* Turn On Real    Tuner Mode */
           store_sequence_word(cfgsectdat,&wrseqadr,0x0001);  
         }
       else
        {
           store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_FILT_CFGADDR);  /* Turn On Complex Tuner Mode */
           store_sequence_word(cfgsectdat,&wrseqadr,0x0000);  
         }   
          

      /* Set Decimation Scalar */                               
       store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_DECI_CFGADDR); 
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (0x00010000 - g->decmultval));                             

      /* Set NCO Frequency     */
       decim_clk_freq = (float) (((float) (g->freq))/ ((float) (g->input_decim)));     /* Calc Input Decimated Clock Rate */ 
       phase_inc    = (int_u4) (((float) (((float) ((float)(g->reqcntrfreqval)/ decim_clk_freq)) * 1048576.0)) + 0.5);  
       store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_NCO_CFGADDR); 
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (phase_inc >> 16) );   
       store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_NCO_CFGADDR); 
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (phase_inc));                             
      /* Set Tuner Gain        */ 
       store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_GAIN_CFGADDR); 
       store_sequence_word(cfgsectdat,&wrseqadr,(int_u2) (g->tunegainval/6));                             
      
      /* Set Coefficients From User File   */ 
        if (g->coefval != GE_COEF_OFF)
          {          
           /* Write To Flash Coefficients  */  
            for(ii =0;ii<((Filter_taps[g->gigexdrev][g->firmwareval]/2)+1);ii++)
              {
                store_sequence_word(cfgsectdat,&wrseqadr,GE_TUNCFGADDR|GE_TUNE_COEF_CFGADDR);
                store_sequence_word(cfgsectdat,&wrseqadr,g->coef[ii]);
              }
          }  
      } 

 /* Turn On Incoming Data Instruction */ 
   store_sequence_word(cfgsectdat,&wrseqadr,GE_TXRSTADDR);                  
   store_sequence_word(cfgsectdat,&wrseqadr,0x0001);
  
 
 /* printf("Finish Write Sequence Size & Address = %d \n",wrseqadr);  */   
 
 /********************************/ 
 /* Finised Configuration Update */
 /********************************/

  /********************/
  /* Store Query Info */
  /********************/
   geQ.gigeipaddrval  = g->gigeipaddrval;
   geQ.destmcaddrval  = g->destmcaddrval;
   geQ.vlanval        = g->vlanval;  
   geQ.freq           = g->freq;
   geQ.input_decim    = g->input_decim;
   geQ.numbits        = g->numbits;
   geQ.bitshift       = g->bitshift;
   geQ.tcval          = g->tcval;
   geQ.tunval         = g->tunval; 
   geQ.coefval        = g->coefval;
   geQ.decmultval     = g->decmultval;
   geQ.reqcntrfreqval = g->reqcntrfreqval;
   geQ.actualcntrfreq = g->actualcntrfreq;
   geQ.coef_gainshift = g->coef_gainshift;
   geQ.tunegainval    = g->tunegainval;
   for (ii = 0; ii < (GE_TUNE_MAX_COEF/2)+1; ii++)
     geQ.coef[ii] = (short int) g->querycoef[ii];
   strcpy(geQ.flagstr,g->flagstr);

  /* Store Query Info In FLASH EPROM */  
   for (ii=0;ii<(sizeof(Type_GIGEXD_query)/sizeof(int_u2));ii++)
     store_sequence_word(cfgsectdat,&query_adr,*(int_u2 *) ((int_u2 *)(&geQ)  + ii));
      
 /*  printf("Size Of Query Write = %d\n",ii*2);  */

 /* Retrieve Download Revision In rxdata */
 /* Store Download Revision In Download Config Num Location */ 
  if (GIGE_retrieve_revnvers(txdata,rxdata,NULL) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);
  memcpy(cfgsectdat+(GE_EPROMDWNCFGADDR-GE_EPROMCFGSPACE),rxdata,sizeof(int_u2));

  /* Write Cfg Membuf To EPROM */
   printf("Writing Configuration Section (15 Secs)\n");
   for (ii=0;ii<GE_EPROMSECTORSIZE*sizeof(int_u1);ii=ii+sizeof(int_u4))
     EPROM_write_Dword(txdata,rxdata,GE_EPROMCFGSPACE+ii,*((int_u4 *)(cfgsectdat+ii)));
     
  /* Send EPROM Rd Cfg Command         */
   printf("Restarting Data With New Cfg Parameters ... ");           
   if (single_command(txdata,                                                              
                      rxdata,
                      GE_EPROMCFGRDDATA | (0x0FFF & address),
                      (int_u2)((address >> 4) & 0xF000)) == NOT_SUCCESSFUL)
    {
      printf("FAILED!\n");
      free(cfgsectdat);
      return(NOT_SUCCESSFUL);
    }
   sleep(1);
   printf("Done\n");
   
   sleep(1);
   printf("\nConfig Complete-New Config Parameters Take Effect Immediately!!\n"); 

   free(cfgsectdat);
   return(SUCCESSFUL);
 } 

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 program_EPROM(int_u1 *txdata,int_u1 *rxdata, char *pathnfile, int usage)
 {
   int fp;
   int bytestransfer;
   int_u2 dbytes = 0;
   int_u4 dword  = 0;
   int_u4 numbytesrd = 0;
   int ii,jj;
   int numclrsectors;
   int numbytesprg = 0;
   int epromdefadr = 0;
   int_u1 verifybuf[GE_RDFLASH_SIZE]; 
   int_u1 cfgsectdat[GE_EPROMSECTORSIZE];
   int_4 gigexdrev = 0; 
   
   
if (usage == 0)
  {
 printf("\nSyntax: gigexd program <Host IP Addr> <GIGEXD IP Addr>  <Path & Filename> \n\n");
 printf("                  program OR prgclrcfg   = firmware update utility (re-programs GIGEXD with new firmware) \n");
 printf("                  <Host IP Addr>         = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
 printf("                  <GIGEXD IP Addr>       = Dot Notation Of GIGEXD IP Addr, Ex. 192.168.200.1 \n");
 printf("                  <path & filename>      = Path & Filename Of Programming File That Holds Firmware\n");
   
 printf("\n\n\tThe 'program' operation is used to update the firmware of the GIGEXD. \n");
 printf("For the GIGEXDR1, once programming is finished, the unit must be power cycled for the \n");
 printf("new firmware to be loaded into the FPGA. The GIGEXDR2 does NOT need a power cycle after \n"); 
 printf("programming.  If programming is successfully verified, the GIGEXDR2 will automatically reboot\n");
 printf("with the new programming.\n"); 
 printf("\tProgramming only overwrites the 'firmware' portion of flash memory. \n");
 printf("All configuration that is stored in Flash (done with flashcfg operation) remains \n");
 printf("intact. Since the configuration is intact, all user settings still remain and are \n");
 printf("loaded at the power up sequence or reboot-along with the new firmware. Firmware \n"); 
 printf("files for the GIGEXD can be identified in the zip sofware packages as having \n");
 printf("the filename extension of .rpd \n");

 printf("\n\nThe 'prgclrcfg' operation performs the same function as the 'program' operation but \n");
 printf("in addition erases all of the Flash configuration data that was stored using the 'flashcfg' \n");
 printf("operation.  The 'prgclrcfg' operation is necessary as firmware/software evolve in complexity \n");
 printf("and old 'flashcfg' values become obsolete.  \n");
 printf("\nIMPORTANT--Upon completion of the 'prgclrcfg' operaton, and a power cycle for the GIGEXDR1 \n");
 printf("or reboot for the GIGEXDR2, the GIGEXDR1 or GIGEXDR2 will default to IP address 192.9.200.105\n");
 exit(-1);
  }

   if (strstr(pathnfile,".rpd") == NULL)
     {
       printf("\nERR: Programming Files Should Have The Filename Extension '.rpd' \n");
       printf("ERR: Are you sure this is a programming file?\n");
       printf("ERR: Aborting Programming\n");
       return(NOT_SUCCESSFUL);
     } 

   fp = open(pathnfile,O_RDONLY);
   if (fp == -1)
     {
       printf("\nERR: Cannot open file %s \n",pathnfile);
       return(NOT_SUCCESSFUL);     
     }

  /* Turn Off Incoming Data Stream */ 
   if (GIGE_turnOFF_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Get Programming ID Value */
   if (GIGE_retrieve_revnvers(txdata,rxdata,&gigexdrev) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);
      
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/  
  /*        Check For Magic Number In Program File          */
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 
   lseek(fp,GER2_MAGICNUMADR,SEEK_SET);

   bytestransfer = read(fp,&dbytes,sizeof(int_u2));
   if (bytestransfer != sizeof(int_u2))
     {
       printf("ERR: Read Of Magic Number Failed\n");
       return(NOT_SUCCESSFUL);
     }    

   if (dbytes != GE_MAGICNUMBER)
     {
       printf("\nERR: %s Does Not Appear To Be A Programming File For GIGEXDR%d\n",pathnfile,gigexdrev+1);
       printf("ERR: Are you sure this is a programming file for a GIGEXDR%d?\n",gigexdrev+1);
       printf("Aborting Programming\n");
       return(NOT_SUCCESSFUL);
     } 
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/            
  /* Check For Previous Firmware Versions */ 
    if (((*((int_u2 *)rxdata) & 0xFFF8) < GE_LASTCOMPATVERS) && (usage == 1))
     {
    printf("\n%s%d\n","GIGEXD Hardware Type = GIGEXDR",gigexdrev+1);
    printf("%s%d%s%02d\n","Current GIGEXD Firmware Version = ",*(rxdata+1),".",(*rxdata & 0xF8) >> 3);
    printf("%s%d%s%02d\n","This Software Version = ",GE_SOFTWAREVERS >> 8,".",(GE_SOFTWAREVERS & 0x00FF) >> 3);
    printf("Config Values For Version %d.%d Have CHANGED From Previous Versions \n",GE_SOFTWAREVERS >> 8,(GE_SOFTWAREVERS & 0x00FF) >> 3);
    printf("To Re-Program The GIGEXD You Must Execute The 'prgclrcfg' Command Instead Of The 'program' Command \n");
    return(NOT_SUCCESSFUL);  
     }  
  
  /* Check Download Type vs. Config Type  */     
    lseek(fp,GER2_IDWORDADDRESS,SEEK_SET);               /* Return File Ptr To ID Value Location */
    bytestransfer = read(fp,&dbytes,sizeof(int_u2));     /* Read Programming Donwload Number     */ 
    if (bytestransfer != sizeof(int_u2))
     {
       printf("ERR: Read Of ID Word Failed\n");
       return(NOT_SUCCESSFUL);
     } 

    EPROM_read_data(txdata,rxdata,GE_EPROMDWNCFGADDR);   /* Read Download Num Last Config        */    
    if (((*((int_u2 *)rxdata) & 0x0007) != (dbytes & 0x0007))  && (usage == 1))
     {
printf("\n%s%d\n","GIGEXD Hardware Type = GIGEXDR",gigexdrev+1);
printf("%s%d%s%s\n","Current GIGEXD Firmware Number To Download = ",(dbytes & 0x0007)," Filename: ",pathnfile);
printf("%s%d%s%s\n","Current GIGEXD Residing Configuration For Download = ",*rxdata & 0x07," Filename: ",GIGEXD_dload[1][*rxdata & 0x07]);
printf("New Desired Download Will NOT Match Current Configuration!!\n");
printf("To Re-Program The GIGEXD You Must Execute The 'prgclrcfg' Command Instead Of The 'program' Command \n");
return(NOT_SUCCESSFUL);  
     }         
    lseek(fp,0,SEEK_SET); /* Return Ptr To Beginning Of Programming File */

    

   if (usage == 1)
     {
       printf("%s%s\n","\nProgramming File: ",pathnfile);
       printf("You Are About To Re-Program The GigExD Firmware!!\n");
       printf("Do NOT Interrupt This Process!!\n");
       printf("Continue? ('y' or 'n') ");
     }
   else
     {
       printf("%s%s\n","\nProgramming File: ",pathnfile);
       printf("You Are About To Re-Program The GigExD Firmware And Erase ALL Configuration Data!!\n");
       printf("After Configuration Erase, The GIGEXD IP Address Will Default To 192.9.200.105\n");
       printf("After Programmng and Power Cycle, Re-Configure The GIGEXD Using IP Addr 192.9.200.105\n");
       printf("Do NOT Interrupt The Erasure & Programming Process!!\n");
       printf("Continue? ('y' or 'n') ");

     }

  /* Get User Response */ 
   if (answer_yes() == FALSE)
     {
       printf("Aborting Programming \n");
       /* Turn Off Incoming Data Stream */ 
       if (GIGE_turnON_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
         return(NOT_SUCCESSFUL);

       return(SUCCESSFUL);
     }     
       
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/  
  /* Check For Full Erase Of Config Area & Programming Area */
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 
   if (gigexdrev == GE_GER2IDVAL)
     {      
        numbytesprg = GER2_EPROMENDPROG;                       
        epromdefadr = GER2_EPROMDEFSPACE;         
  
       /* Set Page Address To Next Page At 0x00100000 */ 
        if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
          return(NOT_SUCCESSFUL);

        if (usage == 1)
          {            
            printf("\nReading Configuration Section (15 Secs)\n"); 
            numbytesrd = 0;
            while (numbytesrd < GE_EPROMSECTORSIZE)
              {  
                EPROM_read_data(txdata,rxdata,GE_EPROMCFGSPACE+numbytesrd);
                memcpy(cfgsectdat+numbytesrd,rxdata,GE_RDFLASH_SIZE*sizeof(int_u1)); 
                numbytesrd = numbytesrd + (GE_RDFLASH_SIZE*sizeof(int_u1));         
              }
          }

       /* Execute Bulk Erase */         
        printf("\nPerforming EPROM Bulk Erase For Programming (20 Secs)\n");   
        if (EPROM_clear_bulk(txdata,rxdata,0x00000000) == NOT_SUCCESSFUL) 
          return(NOT_SUCCESSFUL);    
        sleep(20);

 
        printf("\nProgramming Takes About 30 Seconds Per 64K Bytes \n");
        printf("Status Will Be Reported For Every 64K Bytes Programmed\n");
        printf("Programming EPROM (1300K Bytes-Approx 7.5 Min.)...\n");             
        if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0000) == NOT_SUCCESSFUL)          /* Set Page Address To 0x0000 */
          return(NOT_SUCCESSFUL);
        numbytesrd    = 0;
        bytestransfer = read(fp,&dword,sizeof(int_u4));
        while ((bytestransfer == sizeof(int_u4)) && (numbytesrd < numbytesprg))
          {
           /* Check Next Page */ 
            if (numbytesrd == 0x100000)
              {
               /* Set Page Address To Next Page At 0x00100000 */ 
                if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
                  return(NOT_SUCCESSFUL);
              }

            EPROM_write_Dword(txdata,rxdata,numbytesrd,dword);
       
            bytestransfer = read(fp,&dword,sizeof(int_u4)); 
           numbytesrd    = numbytesrd + sizeof(int_u4);
           if ((numbytesrd % 0x10000) == 0)
             printf("\tBytes Programmed = %d Kbytes\n",numbytesrd/1024);                            
          }
   
   
       /* Program Extra Sector For Detect Info         */         
        printf("Programming Detection Area (30 Secs)\n");
        lseek(fp,GER2_DETECTSECT,SEEK_SET); /* Reposition To Detect Section */
        numbytesrd    = 0;
        bytestransfer = read(fp,&dword,sizeof(int_u4));
        while ((bytestransfer == sizeof(int_u4)) && (numbytesrd < GE_EPROMSECTORSIZE))
          {       
            EPROM_write_Dword(txdata,rxdata,numbytesrd+GER2_DETECTSECT,dword);
       
            bytestransfer = read(fp,&dword,sizeof(int_u4)); 
            numbytesrd    = numbytesrd + sizeof(int_u4);       
          } 
        
       /* Restore Configuration For 'program' Command */
        if (usage == 1)
          {
           /* Program Extra Sector For Detect Info         */         
            printf("Restoring Configuration Area (30 Secs)\n");       
            numbytesrd    = 0;            
            while (numbytesrd < GE_EPROMSECTORSIZE)
              {       
                EPROM_write_Dword(txdata,rxdata,numbytesrd+GE_EPROMCFGSPACE,*((int_u4 *)(cfgsectdat+numbytesrd)));       
                numbytesrd    = numbytesrd + sizeof(int_u4);       
              }
          }        
     } 
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
 
   if (usage == 2)
     {
       printf("Programming User Configuration Area (30 Secs)\n");      
       lseek(fp,epromdefadr,SEEK_SET);
       numbytesrd    = 0;
       bytestransfer = read(fp,&dbytes,sizeof(int_u2));
       while ((bytestransfer == sizeof(int_u2)) && (numbytesrd < GE_EPROMSECTORSIZE))
         {       
           EPROM_write_word(txdata,rxdata,numbytesrd+GE_EPROMCFGSPACE,dbytes);
       
           bytestransfer = read(fp,&dbytes,sizeof(int_u2)); 
           numbytesrd    = numbytesrd + sizeof(int_u2);       
         }
     } 

   printf("Programming Default Configuration Area (30 Secs)\n");
   lseek(fp,epromdefadr,SEEK_SET);
   numbytesrd    = 0;
   bytestransfer = read(fp,&dbytes,sizeof(int_u2));
   while ((bytestransfer == sizeof(int_u2)) && (numbytesrd < GE_EPROMSECTORSIZE))
     {       
       EPROM_write_word(txdata,rxdata,numbytesrd+epromdefadr,dbytes);
       
       bytestransfer = read(fp,&dbytes,sizeof(int_u2)); 
       numbytesrd    = numbytesrd + sizeof(int_u2);       
     } 
  
   
  /* Verify Programming To Flash */ 
   printf("\nEPROM Programming Verification Takes About 30 Seconds Per 256K Bytes \n");
   printf("Status Will Be Reported For Every 64K Bytes Verified\n");
   printf("Verifying EPROM Programming (1300K Bytes-Approx 3.0 Min.)...\n");

  /* Set Page Address 0x0000 */
   if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0000) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);     
   numbytesrd = 0;
   lseek(fp,0,SEEK_SET); /* Reposition To Start Of File */  
   bytestransfer = read(fp,verifybuf,GE_RDFLASH_SIZE * sizeof(int_u1));
   while ((bytestransfer == (GE_RDFLASH_SIZE*sizeof(int_u1))) && (numbytesrd < numbytesprg))
     {  
       if (numbytesrd == 0x00100000)
         {
           if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
             return(NOT_SUCCESSFUL);
         }  

       EPROM_read_data(txdata,rxdata,numbytesrd);   
        if (memcmp(verifybuf,rxdata,GE_RDFLASH_SIZE*sizeof(int_u1)) != 0)
          {
            for (ii=0;ii<GE_RDFLASH_SIZE;ii++)
              {
                if (*(rxdata+ii) != *(verifybuf+ii))
                  {
                    printf("Error Location = %d\n",numbytesrd+ii);
                    printf("Index = %d Data   = %x\n",ii,*(rxdata+ii));
                    printf("Index = %d Verify = %x\n",ii,*(verifybuf+ii));  
                    break;
                  }  
              }
            break;
          }
                  
       bytestransfer = read(fp,verifybuf,GE_RDFLASH_SIZE*sizeof(int_u1)); 
       numbytesrd    = numbytesrd + (GE_RDFLASH_SIZE*sizeof(int_u1));
       if ((numbytesrd % 0x10000) == 0)
         printf("\tBytes Verified = %d Kbytes\n",numbytesrd/1024); 
     }
   printf("Done\n");

  /* Close Programming File */  
   close(fp); 

   if (numbytesrd != numbytesprg)
     {
     
       printf("\nVerification NOT Successful\n");
       printf("You MUST Immediately Attempt To Program The GIGEXD AGAIN!!\n");
       printf("Do NOT Power Cycle Before Attempting To Re-program\n");       
       return(NOT_SUCCESSFUL);  
     }              

   printf("\nVerification SUCCESSFUL!!!\n");   
   printf("Restarting GIGEXDR2 With New Programming (Power Cycle NOT Necessary)..."); 
   if (single_command(txdata,rxdata,GE_PULSENCFGADDR,0x0001) == NOT_SUCCESSFUL)
     {
       printf("Failed\n");
       return(NOT_SUCCESSFUL);
     }
   sleep(1);
   printf("Done\n");        
   if (usage == 2)
     printf("Command 'prgclrcfg' Complete: GIGEXD IP Address Is Now 192.9.200.105\n");        
     
         
  /* Turn ON Incoming Data Stream */ 
   if (GIGE_turnON_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);     
      
  
   return(SUCCESSFUL);
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 init_EPROM(int_u1 *txdata,int_u1 *rxdata, char *pathnfile)
 {

   int fp;
   int bytestransfer;
   int_u2 dbytes = 0;
   int_u4 dword  = 0;
   int_u4 numbytesrd = 0;
   int ii,jj;
   int_4 gigexdrev = 0; 
   int_u2 *rxword;
   int_u1 cfgsectdat[GE_EPROMSECTORSIZE];
     
   rxword = (int_u2 *) rxdata;

   if (strstr(pathnfile,".rpd") == NULL)
     {
       printf("\nERR: Programming Files Should Have The Filename Extension '.rpd' \n");
       printf("ERR: Are you sure this is a programming file?\n");
       printf("ERR: Aborting Programming\n");
       return(NOT_SUCCESSFUL);
     } 

   fp = open(pathnfile,O_RDONLY);
   if (fp == -1)
     {
       printf("\nERR: Cannot open file %s \n",pathnfile);
       return(NOT_SUCCESSFUL);     
     }

  /* Turn Off Incoming Data Stream */ 
   if (GIGE_turnOFF_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Get Programming ID Value */
   if (GIGE_retrieve_revnvers(txdata,rxdata,&gigexdrev) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);

  /* Check If GIGEXDR2 Already Initialized */
   if (*rxword != 0xFFFF)
     {
       printf("\nGIGEXDR2 Already Initialized\n");
       printf("Continue??");
      /* Get User Response */ 
       if (answer_yes() == FALSE)
         {
           printf("Aborting Initialization \n");
           return(SUCCESSFUL);
         } 
     } 
      
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/  
  /*        Check For Magic Number In Program File          */
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 
   if (gigexdrev == GE_GER1IDVAL)
     {
       printf("Initialization Only Available For GIGEXDR2-GIGEXDR1 Detected\n");
       printf("Aborting Initialization\n");
       return(NOT_SUCCESSFUL);
     }
   else
     lseek(fp,GER2_MAGICNUMADR,SEEK_SET);

   bytestransfer = read(fp,&dbytes,sizeof(int_u2));
   if (bytestransfer != sizeof(int_u2))
     {
       printf("ERR:Read Of Magic Number Failed\n");
       return(NOT_SUCCESSFUL);
     }    

   if (dbytes != GE_MAGICNUMBER)
     {
       printf("\nERR: %s Does Not Appear To Be A Programming File For GIGEXDR%d\n",pathnfile,gigexdrev+1);
       printf("ERR: Are you sure this is a programming file for a GIGEXDR%d?\n",gigexdrev+1);
       printf("Aborting Programming\n");
       return(NOT_SUCCESSFUL);
     } 

 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/  
  /* Erase Of Detect Amd Config Areas                       */
  /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/   
  /* Set Page Address To Next Page At 0x00100000 */
   if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
     return(NOT_SUCCESSFUL);   
   
   printf("\nClearing Single Detect Info Sector\n"); 
   printf("\tSector Address 0x%0x Cleared\n",GER2_DETECTSECT); 
   EPROM_clear_sector(txdata,rxdata,GER2_DETECTSECT);

   printf("Clearing Single User Config Sector\n"); 
   printf("\tSector Address 0x%0x Cleared\n",0x00100000+GE_EPROMCFGSPACE); 
   EPROM_clear_sector(txdata,rxdata,GE_EPROMCFGSPACE);               
        
   printf("Clearing Single Default Config Sector\n");
   printf("\tSector Address 0x%0x Cleared\n",GER2_EPROMDEFSPACE);
   EPROM_clear_sector(txdata,rxdata,GER2_EPROMDEFSPACE);   
 /****************************************/
 /*  Write Detect Word                   */
 /****************************************/     
   lseek(fp,GER2_IDWORDADDRESS ,SEEK_SET); /* Return File Ptr To ID Value Location */
   bytestransfer = read(fp,&dbytes,sizeof(int_u2));
   if (bytestransfer != sizeof(int_u2))
     {
       printf("ERR:Read Of File ID Value Failed\n");
       return(NOT_SUCCESSFUL);
     }
  /* Write ID Value To Flash */
   EPROM_write_word(txdata,rxdata,GER2_IDWORDADDRESS,dbytes);

 /****************************************/
 /*  Write User Cfg Area                 */
 /****************************************/ 
   printf("Programming User Configuration Area (15 Secs)\n");  
   lseek(fp,GER2_EPROMDEFSPACE,SEEK_SET);
   bytestransfer = read(fp,cfgsectdat,GE_EPROMSECTORSIZE * sizeof(int_u1));
   memcpy(cfgsectdat+(GE_EPROMDWNCFGADDR-GE_EPROMCFGSPACE),&dbytes,sizeof(int_u2));  /* dbytes From Above, Set Configuration Version */

   numbytesrd = 0;     
   while (numbytesrd < GE_EPROMSECTORSIZE)
     {       
       dword = *((int_u4 *) (cfgsectdat+numbytesrd));
       EPROM_write_Dword(txdata,rxdata,numbytesrd+GE_EPROMCFGSPACE,dword);               
       numbytesrd    = numbytesrd + sizeof(int_u4);       
     }
 /****************************************/
 /*  Write Default Cfg Area              */
 /****************************************/    
   printf("Programming Default Configuration Area (15 Secs)\n");
   numbytesrd = 0;   
   while (numbytesrd < GE_EPROMSECTORSIZE)
     {       
       dword = *((int_u4 *) (cfgsectdat+numbytesrd));
       EPROM_write_Dword(txdata,rxdata,numbytesrd+GER2_EPROMDEFSPACE,dword);        
       numbytesrd    = numbytesrd + sizeof(int_u4);       
     } 
  
   close(fp);

   printf("Restarting Data With New Cfg Parameters ... ");           
   if (single_command(txdata,                                                              
                      rxdata,
                      GE_EPROMCFGRDDATA | (0x0FFF & GE_EPROMCFGSPACE),
                      (int_u2)((GE_EPROMCFGSPACE >> 4) & 0xF000)) == NOT_SUCCESSFUL)
    {
      printf("FAILED!\n");
      return(NOT_SUCCESSFUL);
    }
   printf("Done\n");
 
   printf("\nInitialization Completed \n");

   return(SUCCESSFUL);
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int getpath (char *path, char *area) {
  char *str;

  str = getenv("ICEROOT");
  if (str == NULL)
    {
      printf("Environment variable ICEROOT not defined\n");
      return(-1);
    }

  sprintf(path,"%s/%s/",str,area);

  return strlen(path);
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
/* setsockopt and getsockopt return 0 on success and -1 on err  */
/* mcaddress is the multicast to join and                       */ 
/* ifaddress is the IP address of the local interface to look   */
/*           for the multicast data.                            */
/* Both are char string of form (for example) 192.168.1.200     */
/*--------------------------------------------------------------*/
/* Special Note - Thank you to Dave C. For Help With This Code  */
/*--------------------------------------------------------------*/
int openacquiresocket (char *mcaddress, char *ifaddress, int sbufsize, int debug) {
  int sock;
  int status;
  int unblock=0;                     /* Set to 1 to make requests unblocking, 0 for blocking */
                                     /* Set to 0 for blocking so CPU conserved               */
  socklen_t len;
  unsigned int retbufsize;
  unsigned int bufsize=sbufsize;     /* Try to get this much -> kernel will tell us how much we can actually get! */
  
  unsigned char multicast_loop = 0;  /* Disable multicast looping */
  struct ip_mreq mreq;               /* Multicast request structure */
  struct sockaddr_in bindsockaddress;

  in_addr_t if_addr;
  socklen_t if_siz = sizeof(if_addr);

 
 /* Convert network addresses to binary form and place in mreq structure */
  inet_aton(mcaddress,&mreq.imr_multiaddr);
  inet_aton(ifaddress,&mreq.imr_interface);

 /* Below command opens datagram socket, AF_INET means IPv4 Internet protocols (see  */
 /* man ip). The other valid value for 3rd argument is 0 (shouldn't matter tho)      */
  if (debug > 0) printf("About to open UDP socket\n");   
  sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (sock<0) { printf("Err opening socket\n"); return -1; }
  if (debug > 0) printf("Opened socket %d\n",sock);

 
  bindsockaddress.sin_family      = AF_INET;
  bindsockaddress.sin_port        = htons(SDDSTXPORT);
  bindsockaddress.sin_addr.s_addr = mreq.imr_multiaddr.s_addr;

 /* Disable multicast looping -> by default it is enabled  When enabled          */
 /* it will loop back and send data to host (so more than one user can           */ 
 /* listen).  Right now we only want one user listening (us!) so we will disable */
  status = setsockopt(sock,IPPROTO_IP,IP_MULTICAST_LOOP,&multicast_loop,sizeof(multicast_loop));
  if (status<0) 
    { 
      printf("Err Disabling multicast looping\n"); 
      return -1; 
    }
  
 /* Now become a member of multicast group! */
  status = setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
  if (status<0) 
    { 
      printf("Err joining multicast group\n"); 
      return -1; 
    }

 /* Bind socket */
  status = bind (sock, (struct sockaddr *)&bindsockaddress,sizeof(bindsockaddress));
  if (status<0) 
    { 
      printf("Err binding socket\n");
      return -1; 
    }

 /* Unblock socket */
  status = ioctl (sock, FIONBIO, &unblock);
  if (status<0) 
    { 
      printf("Err unblocking socket\n"); 
      return(-1); 
    }

 /* set socket size to the larger of 10M and the system default    */
 /* Check If Buffer Size Already Set Larger Than What We Requested */        
  len=4; 
  status = getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &retbufsize, &len);
  if (status==0 && retbufsize>bufsize) 
    bufsize=retbufsize;

  len = sizeof(unsigned int);
  status = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &bufsize, len);
  if (status<0) 
    { 
      printf("Err sizing receive socket buffer\n"); 
      return(-1); 
    }

  len=4; 
  status = getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &retbufsize, &len);
  if (retbufsize<sbufsize) 
    {
      printf("\nWARN: Requested %d KBytes For GigE Buffer\n",sbufsize/1024);
      printf("WARN: But, Receive Buffer Only Set To %d KBytes\n",retbufsize/1024);
      printf("WARN: As root Use, /sbin/sysctl -w  net.core.rmem_max=10485760 To Change Size\n\n");
    }

  return sock;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 acquire_data(char *hostip, int_u1 *txdata, int_u1 *rxdata,char *join_adr, char *pathnfile, int_u4 filesize, int usage)
{
#define PKTTRANSIZE   1024                               /* Number of Pkts To Acquire & Write To Disk */
  SOCKET hSocket;
  int    rv = 0;
  int_u4 jj = 0; 
  struct ip_mreq mreq; 
  struct sockaddr_in mca;
  int    mca_len,byteswritten;
  int_u2 rxpktlocnt,rxpkthicnt;
  int_u2 chkpktlocnt, chkpkthicnt; 
  int_u2 *dataw; 
  int    fp;
  int    numbits = 8;
  int_u1 holdbyte;
  int    ii,kk;
  int_u4 numpkttran,pktlost=0;
  int_u1 *mcdatbuf;
  int_u4 litend = 0;  /* Automatic Endian Converstion For 16 Bit Data For acquire & acqwtc Commands*/
 

if (usage == 0)
  { 
    printf("\nSyntax: gigexd acquire <Host IP Addr> <GIGEXD IP Addr>  <Path & Filename> <MC Address> <file size>\n\n");
    printf("               acquire OR acqwtc OR acqall  = acquire data from the GIGEXD and store to file \n");
    printf("               <Host IP Addr>               = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
    printf("               <GIGEXD IP Addr>             = Dot Notation Of GIGEXD  IP Addr, Ex. 192.168.200.1 \n");
    printf("               <path & filename>            = Path & Filename Data File Where Data is to be Stored\n");
    printf("               <MC Address>                 = Multicast Address Of GiGExD To Acquire Data \n");
    printf("               <file size>                  = Size Of File To Acquire Data (In KBytes)\n");

printf("\nThe 'acquire' operation opens a multicast receive connection (sends out a Join Request) \n");
printf("Data acquisition is to file and for a duration as specified by the user. Only the SDDS Data \n");
printf("portion is acquired. The SDDS header, including timecode information, is discarded.\n");

printf("\nThe 'acqall' operation opens a multicast receive connection (sends out a Join Request) \n");
printf("Data acquisition is to file and for a duration as specified by the user. All of the SDDS/UDP  \n");
printf("packet is acquired (56 Bytes Header + 1024 Bytes Data = 1080 Bytes Per Packet)\n");
printf("Unlike the 'acquire' or 'acqwtc' operations the 'acqall' operation does NOT Endian convert\n");
printf("the SDDS header (timecode) or SDDS data. Endian conversion must be performed by a user\n");
printf("application on the data written to file\n"); 

printf("\nThe 'acqwtc' operation adds 16 bytes of Timecode info before each 1KByte of data. \n");
printf("to the acquired file.  Data block sizes are in 1040 bytes with the first 8 bytes \n");
printf("being the actual timecode. Bytes 9-15 are not used (TBD) and can be ignored. Byte 16 \n");
printf("of the Timecode info specifies whether the Timecode in bytes 1-8 is valid.  If byte 16 \n");
printf("is 0xC0 then the timecode is valid and applies to the 1st sample of data in the 1K block\n");
printf("after the current 16 byte Timecode info field.  If the 16th byte is 0x00 then the Timecode\n");
printf("is not valid for the current block of 1KBytes and can be ignored.\n");  
printf("*****************************************************************\n");
printf("*Bytes 1-8 TC**Bytes 9-15 TBD**Byte 16 Valid TC Marker**Bytes 17-1040 Data**REPEAT PATTERN*\n");
printf("*****************************************************************\n"); 
    exit(-1);
  }


 /* Setup Multicast Address Structure */      
  memset(&mca,0,sizeof(mca));
  mca.sin_family      = AF_INET; 
  mca.sin_addr.s_addr = inet_addr(join_adr);
  mca.sin_port        = htons(SDDSTXPORT);
  mca_len             = sizeof(mca);
  
  inet_aton(join_adr,&mreq.imr_multiaddr);
  inet_aton(hostip,&mreq.imr_interface);

  mcdatbuf = (int_u1 *)malloc(PKTTRANSIZE*SDDSPKTSIZE*sizeof(int_u1)*2);   /* Double Memory Needed-Use Endian Convert */
  if (mcdatbuf == NULL)
    { 
      printf("\nERROR: Malloc Of MC Rx Data Buffer Failed!!\n");
      printf("ERROR: Acquisition Aborted\n");
      return(NOT_SUCCESSFUL);
    }      

 /* Set Word Pointer To Rx Buffer */ 
  dataw = (int_u2 *)rxdata; 
  
 /* Setup Pkt Transfer Size       */
  numpkttran = PKTTRANSIZE;
  if (numpkttran > filesize)
    numpkttran = filesize;  
  
 
 /* Open File For Acquisition     */ 
  fp = open(pathnfile,O_RDWR|O_CREAT|O_TRUNC,S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH|S_IRUSR|S_IWUSR); 
  if (fp == -1)
   {
     free(mcdatbuf);
     printf("%s%s\n","\nERROR: File Creation Failed For: ",pathnfile);
     printf("ERROR: Acquisition Aborted!!!\n"); 
     return(NOT_SUCCESSFUL);
   } 
  
 /* Check GIGEXD Rev 2 Only       */
   if (GIGE_retrieve_revnvers(txdata,rxdata,NULL) == NOT_SUCCESSFUL)
     {
       free(mcdatbuf);
       return(NOT_SUCCESSFUL); 
     } 

 /* Turn Off Incoming Data Stream */ 
  if (GIGE_turnOFF_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
   { 
      free(mcdatbuf);
      close(fp);
      close(hSocket);
      return(NOT_SUCCESSFUL);
   }
  
 /* Open Socket To Acquire Data */
  hSocket = openacquiresocket (join_adr, hostip, GIGMEMBUFSIZE,0);
  if (hSocket < 0)
    {
      free(mcdatbuf);
      return(NOT_SUCCESSFUL);
    }  

 /* Turn ON Incoming Data Stream */ 
  if (GIGE_turnON_data(txdata,rxdata,FALSE,TRUE) == NOT_SUCCESSFUL)
    {
      setsockopt(hSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(struct ip_mreq));
      free(mcdatbuf);
      close(fp);
      close(hSocket); 
      return(NOT_SUCCESSFUL);
    }
  
 /* Start Data Acquisition */     
  for(ii=0;ii<numpkttran;ii++)
    rv  = recvfrom(hSocket,mcdatbuf+(SDDSPKTSIZE*ii),SDDSPKTSIZE,0,(struct sockaddr *)&mca,&mca_len); 
            
 /* Packet Count In Bytes #2 & 3   */
 /* Count Is Modulo 31             */
  rxpktlocnt = *(mcdatbuf+3) & 0x1F;
  rxpkthicnt = *(mcdatbuf+2);
  rxpkthicnt = (rxpkthicnt << 3) | ((*(mcdatbuf+3)) >> 5);

 /* Find Number Of Bits In Sample  */
  if ((*(mcdatbuf+1) & 0x1F)== 0x10)
    numbits = 16;
  
 /* Turn Off Endian Conversion-Already Little Endian  */
   if ((*(mcdatbuf+1) & 0x80) != 0x00)
    litend = 1;    
    

  do  
    {         
      if (usage == 3)    /* ACQALL COMMAND */
        {       
         /* Write Entire SDDS Packet-1080 Bytes */ 
          byteswritten = write(fp,mcdatbuf,SDDSPKTSIZE*numpkttran);
          if (byteswritten != (SDDSPKTSIZE*numpkttran))
            {
              printf("ERROR: File Write Operation Failed\n");
              free(mcdatbuf); 
              close(fp);
              setsockopt(hSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(struct ip_mreq));  
              close(hSocket);
              return(NOT_SUCCESSFUL); 
            }                                     
        }
      else if (usage == 2)              /* ACQWTC COMMAND */ 
        {  
               
          for(ii=0;ii<numpkttran;ii++)
            {  
             /* Endian Convert Timecode                       */
             /* Store In 2nd Half Of Memory Allocation Buffer */
              for (kk=0;kk<(GE_PKTTCSIZE/2);kk++)
                {
                  *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+1040*ii+GE_PKTTCSIZE-kk-1) = *(mcdatbuf+ii*SDDSPKTSIZE+kk+GE_PKTTCOFFSET);
                  *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+1040*ii+kk) = *(mcdatbuf+ii*SDDSPKTSIZE+GE_PKTTCOFFSET+GE_PKTTCSIZE-kk-1);                                
                }
             }        
          if ((numbits == 8) || (litend == 1))       /* 1,4,8,-8, Or Little Endian Data Format */                    
            {
              for(ii=0;ii<numpkttran;ii++)
                memcpy(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+1040*ii+GE_PKTTCSIZE,mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE,SDDSPKTDATASIZE);                     
            }
          else if (litend == 0)    /* Only Endian Convert If Not Already Little Endian */
            {
              /* Endian Convert 16 Bit Data */ 
               for(ii=0;ii<numpkttran;ii++)
                 { 
                   for(kk=0;kk<SDDSPKTDATASIZE;kk=kk+2)
                      {
                        *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+1040*ii+GE_PKTTCSIZE+kk+1) = *(mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE+kk);
                        *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+1040*ii+GE_PKTTCSIZE+kk) = *(mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE+kk+1);
                      }                    
                  }      /* for ii       */
             }           /* else numbits */

           byteswritten = write(fp,mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE,1040*numpkttran); /* Strip Off SDDS Header */
           if (byteswritten != (1040*numpkttran))
             {
               printf("ERROR: File Write Operation Failed\n");
               free(mcdatbuf); 
               close(fp);
               setsockopt(hSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(struct ip_mreq));  
               close(hSocket);
               return(NOT_SUCCESSFUL); 
             }   

        }   /* else if usage */                
      else if (usage == 1)             /* ACQUIRE Command */
        { 
          if ((numbits == 8) || (litend == 1))        /* 1,4,8,-8, Or Little Endian Data Format */                    
            {          
              for(ii=0;ii<numpkttran;ii++)
                 memcpy(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+SDDSPKTDATASIZE*ii,mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE,SDDSPKTDATASIZE);
            }                      
          else if (litend == 0)    /* Only Endian Convert If Not Already Little Endian */
            {
              /* Endian Convert 16 Bit Data */ 
               for(ii=0;ii<numpkttran;ii++)
                 { 
                    for(kk=0;kk<SDDSPKTDATASIZE;kk=kk+2)
                      {
                        *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+SDDSPKTDATASIZE*ii+kk+1) = *(mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE+kk);
                        *(mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE+SDDSPKTDATASIZE*ii+kk)   = *(mcdatbuf+SDDSPKTSIZE*ii+SDDSPKTHDRSIZE+kk+1);
                      }                    
                  }      /* for ii       */
             }           /* else numbits */
   
          byteswritten = write(fp,mcdatbuf+PKTTRANSIZE*SDDSPKTSIZE,SDDSPKTDATASIZE*numpkttran); 
          if (byteswritten != (SDDSPKTDATASIZE*numpkttran))
            {
              printf("ERROR: File Write Operation Failed\n");
              free(mcdatbuf); 
              close(fp);
              setsockopt(hSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(struct ip_mreq));  
              close(hSocket);
              return(NOT_SUCCESSFUL); 
            } 
        } 
         
      jj = jj + numpkttran;
      if (jj<filesize)
        { 
          if ((jj + numpkttran) > filesize)
            numpkttran = filesize - jj;

          for(ii=0;ii<numpkttran;ii++)
            rv  = recvfrom(hSocket,mcdatbuf+(SDDSPKTSIZE*ii),SDDSPKTSIZE,0,(struct sockaddr *)&mca,&mca_len); 

         /* Check Current Pkt Count In Data With Calculated Packet Count */  
          chkpktlocnt = *(mcdatbuf+3) & 0x1F;                                           /* Current Count In Data     */
          chkpkthicnt = *(mcdatbuf+2);
          chkpkthicnt = (chkpkthicnt << 3) | ((*(mcdatbuf+3)) >> 5); 

          rxpktlocnt  = rxpktlocnt + (numpkttran % 31);                                 /* Running, Calculated Count */
          rxpkthicnt  = (rxpkthicnt + (numpkttran / 31) + (rxpktlocnt / 31)) % 2048 ;
          rxpktlocnt  = rxpktlocnt % 31;                 

          if ((rxpktlocnt != chkpktlocnt) || (rxpkthicnt != chkpkthicnt))
            {
              pktlost    = pktlost + abs((chkpkthicnt*31 + chkpktlocnt) - (rxpkthicnt*31 + rxpktlocnt));  
             /* Reset Running Count To Current Count */ 
              rxpktlocnt = chkpktlocnt;            
              rxpkthicnt = chkpkthicnt;
            }
         }
    }  while (jj<filesize);
   
    
  printf("%s%s\n","Dropping Membership ",join_adr);
  if (setsockopt(hSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(struct ip_mreq)) < 0)
   {
      printf("WARN: Drop Membership Failed\n");
      printf("\nPackets Lost During Acquisition = %d\n",pktlost);
      free(mcdatbuf); 
      close(fp);
      close(hSocket);
      return(NOT_SUCCESSFUL); 
   }

  printf("\nPackets Lost During Acquisition = %d\n",pktlost);

  free(mcdatbuf); 
  close(fp);
  close(hSocket);  /* Close Connection */

  return(SUCCESSFUL);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int_u1 gigexd_query(int_u1 *txdata,int_u1 *rxdata, int usage)
 {
   int ii;
   Type_GIGEXD_query geQ; 
   int firmwareval;
   struct in_addr  addr;
   FILE *ftempo;
   int_4  gigexdrev = 0;


if (usage == 0)
  {
 printf("\nSyntax: gigexd query <Host IP Addr> <GIGEXD IP Addr>  \n\n");
 printf("               query OR qrywcfg    = Flash Configuration Query Utility  \n");
 printf("               <Host IP Addr>      = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
 printf("               <GIGEXD IP Addr>    = Dot Notation Of GIGEXD IP Addr, Ex. 192.168.200.1 \n");
    
 printf("\n\nThe 'query' operation is used to retrieve the Firmware version number and the \n");
 printf("FLASH configuration settings for review by a user. The information displayed gives\n");
 printf("the last configuration that was written to the flash memory using the 'flashcfg' \n");
 printf("operation for the CURRENT download of firmware.\n");

 printf("\n\nThe 'qrywcfg' operation gives the same query info as listed above for the 'query' \n");
 printf("command.  In addition, once the query information has been reported to the user the \n");
 printf("'qrywcfg' command will reload the configuration settings that were reported. \n");
 exit(-1);
  }

  /* Turn Off Incoming Data Stream */ 
   if (GIGE_turnOFF_data(txdata,rxdata,TRUE,TRUE) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);

  /* Get Programming ID Value */
   if (GIGE_retrieve_revnvers(txdata,rxdata,&gigexdrev) == NOT_SUCCESSFUL)
    return(NOT_SUCCESSFUL);     
      
   firmwareval  = *rxdata & 0x07;

   printf("\n*********************\n");
   printf("* GIGEXD Query Info *\n");
   printf("*********************\n");
   if (GE_LASTCOMPATVERS > (*((int_u2 *)rxdata) & 0xFFF8))
     {
       printf("\n%s%d\n","GIGEXD Hardware Type = GIGEXDR",gigexdrev+1);
       printf("%s%d%s%02d\n","Firmware  Version = ",*(rxdata+1),".",(*rxdata & 0xF8) >> 3);
       printf("%s%d%s%02d\n","Software Version = ",GE_SOFTWAREVERS >> 8,".",(GE_SOFTWAREVERS & 0x00FF) >> 3);
       printf("Versions DO NOT Match!!...Aborting Query Operation\n");
       printf("Update (Re-Program) The GIGEXD To Match Software With Firmware Version.\n");
       GIGE_turnON_data(txdata,rxdata,FALSE,FALSE);
       return(NOT_SUCCESSFUL);  
     }  
   else
     {  
       printf("GIGEXD Hardware Type\n");
       printf("\tGIGEXDR%d \n",gigexdrev+1); 
       printf("Firmware Download Info:\n");
       printf("\tCurrent Firmware Download - %s\n",GIGEXD_dload[gigexdrev][firmwareval]); 
       printf("\tCurrent Firmware Download Number = %d\n",firmwareval);
       printf("%s%d%s%02d\n","\tFirmware  Version = ",*(rxdata+1),".",(*rxdata & 0xF8) >> 3); 
       
       printf("Tuner Capabilities:\n");
       printf("\tBase Decimation Value = %d \n",Filter_deci[gigexdrev][firmwareval]);
       printf("\tNumber Of Filter Taps = %d \n",Filter_taps[gigexdrev][firmwareval]);
       
       printf("User Flash Config Values: \n");

       /* Set Page Address To Next Page At 0x00100000 */ 
       if (EPROM_wr_pageaddr_reg(txdata,rxdata,0x0001) == NOT_SUCCESSFUL)
         return(NOT_SUCCESSFUL); 
                                                       
       for (ii=0;ii<sizeof(Type_GIGEXD_query)/2;ii++)
          {
            if (EPROM_read_data(txdata,rxdata,GE_EPROMCFGSPACE + GE_EPROMQUERYADR + (ii*2)) == NOT_SUCCESSFUL)
              return(NOT_SUCCESSFUL);
            *((int_u1 *)(((int_u1 *)(&geQ)) + (ii*2)))   = *rxdata;
            *((int_u1 *)(((int_u1 *)(&geQ)) + (ii*2+1))) = *(rxdata+1);
          } 

        if (geQ.gigeipaddrval == 0xFFFFFFFF)
          {
            printf("\tGIGEXD Flash Configuration Memory Empty!!\n");
            printf("\tNo Settings Available For Query-Run 'flashcfg' Operation\n"); 
            printf("*********************\n");
            GIGE_turnON_data(txdata,rxdata,FALSE,TRUE);
            return(SUCCESSFUL);
          } 
        addr.s_addr = geQ.gigeipaddrval;
        printf("%s%s\n","\tGIGE IP Address = ",inet_ntoa(addr));
        addr.s_addr = geQ.destmcaddrval;
        printf("%s%s\n","\tGIGE MC Address = ",inet_ntoa(addr));
        printf("%s%d\n","\tVLAN = ",geQ.vlanval);
        printf("%s%d\n","\tSample Rate = ",geQ.freq);
        printf("%s%d\n","\tInput Decimation = ",geQ.input_decim);
        printf("%s%d\n","\tNumber Of Bits = ",geQ.numbits);
        printf("%s%d\n","\tNumber Bits To Shift = ",geQ.bitshift); 
        printf("%s%s\n","\tFlags = ",geQ.flagstr+6);                /* User Specified Flags     */
        if (geQ.tcval == FALSE)
          printf("%s\n","\tTimeCode Insertion = OFF");
        else
          printf("%s\n","\tTimeCode Insertion = ON");
        if (geQ.tunval == FALSE)
          printf("%s\n","\tTuner Enable = OFF");
        else
           {
              printf("%s\n","\tTuner Enable = ON");

              if (geQ.coefval == GE_COEF_DEFAULT)
                printf("%s\n","\tTuner Coefficients = DEFAULT");
              else if (geQ.coefval == GE_COEF_COMPUTE)
                printf("%s\n","\tTuner Coefficients = Computed From User Value");
              else if (geQ.coefval == GE_COEF_FILE)
                printf("%s\n","\tTuner Coefficients = Downloaded From User File");

            /* Write Coefficients To File */ 
             ftempo = fopen(GE_COEFQUERYFILE,"w+");
             if (ftempo == NULL)
                {
                  printf("\tWARNING: Open Of Coefficients File %s FAILED!!\n",GE_COEFQUERYFILE);
                  printf("\tWARNING: Aborting Write To File Of Coefficients.\n");
     
                } 
              else
                {
                  printf("%s%s\n","\tTuner Coefficients Written To File ",GE_COEFQUERYFILE);
                  for(ii=0;ii<(Filter_taps[gigexdrev][firmwareval])/2+1;ii++)
                    fprintf(ftempo,"%e\n",((double)((double)geQ.coef[ii])/pow(2,20-(geQ.coef_gainshift/6))));
                  for(ii=(Filter_taps[gigexdrev][firmwareval]/2)-1;ii>=0;ii=ii-1)
                    fprintf(ftempo,"%e\n",((double)((double)geQ.coef[ii])/pow(2,20-(geQ.coef_gainshift/6))));
                  fclose(ftempo);                 
                }

               printf("%s%d\n","\tDecimation Multiplier = ",geQ.decmultval); 
               printf("%s%d\n","\tRequested Center Frequency  = ",geQ.reqcntrfreqval);
               printf("%s%d\n","\tActual    Center Frequency  = ",geQ.actualcntrfreq);
               printf("%s%d\n","\tTuner Gain (dB)  = ",geQ.tunegainval-geQ.coef_gainshift);  /* Subtract Coef Gain Shift */               
           }                             
     }  
   printf("*********************\n");
   
   
   if (usage == 2)
     {
      /* Send EPROM Rd Cfg Command         */
       printf("\nRestarting Data With With Above Parameters ... ");           
       if (single_command(txdata,rxdata,
                          GE_EPROMCFGRDDATA | (0x0FFF & GE_EPROMCFGSPACE),
                          (int_u2)((GE_EPROMCFGSPACE >> 4) & 0xF000)) == NOT_SUCCESSFUL)
         {
           printf("FAILED!\n");
           return(NOT_SUCCESSFUL);
         }
        printf("Done\n");
      } 
    else
      GIGE_turnON_data(txdata,rxdata,FALSE,TRUE);
  
   return(SUCCESSFUL);
 }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
void soc_terminate_server()
{
  /* Close Socket */
   if (HIDI_Socket != INVALID_SOCKET )
     close(HIDI_Socket);   
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 
/*--------------------------------------------------------------*/ 
void exit_prog()
  {
    printf("Syntax: gigexd <Operation Type> <Host IP Addr> <GIGEXD IP Addr>  <Path & Filename> <MC Address <file size>\n\n");
    printf("        <Operation Type>       = program, prgclrcfg, flashcfg, rtcfg, query, qrywcfg, flags, acquire, acqwtc, or acqall \n");
    printf("        <Host IP Addr>         = Dot Notation Of Host Machine IP Addr, Ex. 192.9.200.110 \n");
    printf("        <GIGEXD IP Addr>       = Dot Notation Of GIGEXD IP Addr, Ex. 192.168.200.1 \n");
    printf("        <path & filename>      = Path & Filename Of Program or Config File(OPTIONAL) or Data File(MANDATORY)\n");
    printf("        <MC Address>           = Multicast Address Of GiGExD To Acquire Data From-OPTIONAL For Prog or Config\n");
    printf("        <file size>            = Size Of File To Acquire Data (In KBytes)-OPTIONAL For Prog or Config\n");

    printf("\nTyping: gigexd <Operation Type> help \n");
    printf("Will display help for specific commands \n");  
    exit(-1); 
  }
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
void flags_help()
  {
    printf("\n\n");
    printf("\t*****************************************************\n");
    printf("\t               Config File Flags\n");
    printf("\tBelow is a Description Of Available Config File Flags\n");
    printf("\t*****************************************************\n");
    printf("\tLEND\t For Use With GIGEXDR1 or GIGEXDR2\n");
    printf("Per the SDDS spec, 16 bit data is transmitted in Big Endian Format\n");
    printf("This is problematic for a host that in realtime has to Swap Bytes\n");
    printf("to Little Endian Format and then store the data to disk.\n");
    printf("Using this flag will cause all 16 bit data (tuner or raw) to be sent\n");
    printf("in Little Format-saving the host work in byte swapping the data.\n");
    printf("The acquire or acqwtc commands of this executable recognize Big or Little \n");
    printf("format and automatically do the Big Endian conversion on Big Endian\n");
    printf("data before storing to file. \n");

    printf("\t*****************************************************\n");    

    printf("\tXTCDEL\t For Use With GIGEXDR1 or GIGEXDR2\n"); 
    printf("Syntax: XTCDEL=<t> where <t> represents the number 250 pSec increments of time\n");
    printf("delay external to the GIGEXD. <t> may be positive or negative and has the\n");
    printf("range of -4096<=t<=4096.  XTCDEL (External Timecode Delay) is useful when\n");
    printf("IRIG Timecode or the signal of interest (data) have external delays that\n");
    printf("differ from each other-Ex. cable lengths, external routing, etc.\n");
    printf("XTCDEL is a linear offset that is added to each timecode reported\n");
    printf("(If XTCDEL is negative then time is subtracted.) This allows for \n");
    printf("'calibration' of a system. Ex: XTCDEL=400 represents 100nSec more delay\n");
    printf("in the timecode source (IRIG) from the delay of the data.\n"); 
     
    printf("\t*****************************************************\n");
    
    printf("\tMUXCLK=P or MUXCLK=N, or MUXCLK=C\t  For Use With GIGEXDR2 ONLY!!\n"); 
    printf("The GIGEXDR1 allowed A/D clock selection via on-board jumper manipulation.\n");
    printf("The GIGEXDR2 allows A/D clock selection via software. The default standard\n");
    printf("is to drive the GIGEXDR2 with a 10MHz external clock and have the GIGEXDR2 set\n");
    printf("the A/D clock rate between 90-100MHz.\n"); 
    printf("\tUsing the flag MUXCLK=P causes the GIGEXDR2 A/D\n");
    printf("to use its on-board 10MHz reference instead of an external ref.\n");
    printf("supplied by the user-this eliminates the need for an external clock input\n");
    printf("\tMUXCLK=N causes the GIGEXDR2 A/D to be driven directly\n");
    printf("from a user clock input.  The clock freq. being any number between 1 to 100MHz.\n");
    printf("\tMUXCLK=C causes the GIGEXDR2 A/D to use the socketed oscillator location\n");
    printf("on the A/D board.  Note this oscillator is user supplied and has the freq.\n");
    printf("of 1-100MHz. \n");
    printf("\tMUXCLK=P or MUXCLK=N, or MUXCLK=C flags are ignored when \n");
    printf("used with the GIGEXDR2 containing modules types other than the A2DR7,A2DR8, or A2DR9.\n");   

    printf("\t*****************************************************\n");

    
    printf("\tA2DGAIN\t  For Use With GIGEXDR2 & A2DR9 or A2DR10 Module ONLY!!\n"); 
    printf("Syntax: A2DGAIN=<value> where <value> represents the A2DR9/A2DR10 GAIN in dB\n");
    printf("The acceptable range for <value> is:  -4 <= <value> <= 20\n");
    printf("The A2DR9/A2DR10 I/O Module has an on-board variable gain front end.\n");
    printf("Setting the amount of gain (or attenuation) is done via the use of \n"); 
    printf("this flag. Without use of this flag, the front end gain is set to 0 dB.\n");  
    printf("\t*****************************************************\n");

  } 


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*--------------------------------------------------------------*/
int main(int argc, char *argv[])
  {
    Type_GIGEXD_cfg g;
    int_u4 dat_size = 0;
    char optypestr[80];
    int_u4 optype = 0;
    char multic_ip[80];
    char source_ip[80];
    char dest_ip[80];
    char pathnfile[256];
    char path[100];
    int_u1 *txdata;
    int_u1 *rxdata;
    int_u4 filesize;
    int_u4 usage = 1;

   /* printf("%s%d\n","argc = ",argc); */
    if (argc < 3)
      exit_prog();
    
   /* Determine Operation Type      */ 
    strcpy(optypestr,argv[1]);
    convert2upper(optypestr);   
    if (strcmp(optypestr,"PROGRAM") == 0)
      optype = 1;
    else if (strcmp(optypestr,"PRGCLRCFG") == 0)
      {
        optype = 1;
        usage  = 2;
      }
    else if (strcmp(optypestr,"FLASHCFG") == 0)
      optype = 2;            
    else if (strcmp(optypestr,"FLASHINITCFG") == 0)
      {               
        optype = 2;
        usage  = 2;
      }
    else if (strcmp(optypestr,"RTCFG") == 0)
     optype = 3;
    else if (strcmp(optypestr,"ACQUIRE") == 0)
     optype = 4;
    else if (strcmp(optypestr,"ACQWTC") == 0)
      {
        optype = 4;
        usage  = 2; 
      } 
     else if (strcmp(optypestr,"ACQALL") == 0)
      {
        optype = 4;
        usage  = 3; 
      }
    else if (strcmp(optypestr,"INITCFG") == 0)
     optype = 5;  
    else if (strcmp(optypestr,"QUERY") == 0)
     optype = 6;
    else if (strcmp(optypestr,"QRYWCFG") == 0)
     {
       optype = 6;
       usage  = 2;  
     }  
    else if (strcmp(optypestr,"FLAGS") == 0)
      optype = 7;
    else
     exit_prog();

   /* Get Host Address */ 
    strcpy(source_ip,argv[2]);
    if (argc == 3)
      {
        convert2upper(source_ip);
        if (strcmp(source_ip,"HELP") == 0)
          usage = 0; 
        else
          exit_prog(); 
      }  
    
   /* Check If Operation Or Help */
    if (usage != 0)
      {

       /* Get GIGEXD IP Address From User */
        strcpy(dest_ip,argv[3]);

       /* Check For Correct Args For Acquire Operation */ 
        if (optype == 4)    
          {
            if (argc <= 6)
              {
                printf("For Acquire Operation, User Must Specify <Path & Filename> <MC Address> <file size>\n\n\n");  
                exit_prog();
              }
            else
              {
               /* Get Multicast Address For Acquire */
                strcpy(multic_ip,argv[5]);    
               /* Get File Size For Acquire         */ 
                filesize = atol(argv[6]);
              }
          } 
    
       /* Get Filename For All Operations Except Query */  
        if (optype < 6)
          { 
            if (argc > 4)
              strcpy(g.pathnfile,argv[4]);
            else
              {
                if (getpath(path,"dat") == -1);
                  {
                    printf("User Must Define Program/Config File Path\n");
                    exit(-1);
                  }

                if (optype == 1) 
                  sprintf(g.pathnfile,"%s%s",path,DEFAULT_PROGFILE);
                else if ((optype == 2) && (usage == 1))
                  sprintf(g.pathnfile,"%s%s",path,DEFAULT_USRCFGFILE); 
                else if ((optype == 2) && (usage == 2))
                  sprintf(g.pathnfile,"%s%s",path,DEFAULT_DEFCFGFILE);     
              } 
          }

       /* Start GIGE Communications Via Host Ethernet Port */ 
        printf("\nStart Communications With GigE...");  
        if (soc_start_server(source_ip,dest_ip) == SUCCESSFUL)
          {
            printf("Done\n");
           /* Allocate UDP Buffers    */  
            txdata = (int_u1 *) malloc(SDDSPKTSIZE * sizeof(int_u1));
            rxdata = (int_u1 *) malloc(SDDSPKTSIZE * sizeof(int_u1));
            if ((txdata==NULL) || (rxdata == NULL))
              {
                printf("Mmemory Allocation FAILED!!\n");
                soc_terminate_server();
                if (txdata != NULL)
                  free(txdata);
                if (rxdata != NULL)
                  free(rxdata);

                exit(-1); 
              }
          }
        else
          exit(-1); 

        printf("%s%s\n","\nStarting Operation: ",optypestr);
      }          
     
    if (optype == 1) 
      program_EPROM(txdata,rxdata,g.pathnfile,usage);
    else if (optype == 2)
      setconfig_EPROM(txdata,rxdata,&g,usage);              
    else if (optype == 3) 
      realtime_setconfig(txdata,rxdata,&g,usage);
    else if (optype == 4)
      acquire_data(source_ip,txdata,rxdata,multic_ip,g.pathnfile,filesize,usage); 
    else if (optype == 5)
      init_EPROM(txdata,rxdata,g.pathnfile);
    else if (optype == 6)
      gigexd_query(txdata,rxdata,usage);
    else if (optype == 7)
      flags_help();
    
    if (usage != 0)
      {   
        free(txdata);
        free(rxdata); 
        soc_terminate_server();
      }
          
  }    
