#include <windows.h>
 
#include <userint.h>
 
#include <utility.h>
 
//#include <userint.h>
 
#include <stdlib.h>
 
//#include <formatio.h>
 
#include <ansi_c.h>
 
#include "usb.h"
 
#include "xxusbdll.h"
 
 #include "scaler.h"
 
#include <cvirte.h>    /* Needed if linking in external compiler; harmless otherwise */
 
 
 
extern int p4;
 
extern int daq_on;
 
 
 
 
 
#define NDIS 21
 
#define NSCA 22
 
#define NTGG 23
 
 
 
 
 
 
 
#define C_I CAMAC_I
 
#define C_Z CAMAC_Z
 
#define C_C CAMAC_C
 
//#define C_write        WUSBXX_CAMAC_write
 
//#define C_read             WUSBXX_CAMAC_read
 
#define C_write          CAMAC_write
 
#define C_read       CAMAC_read
 
 
 
//********************************************************************
 
usb_dev_handle *udev;
 
int Q;
 
int X;
 
static HINSTANCE DLLHandle;
 
 
 
int  WUSBXX_load (char *module_path) {
 
 
 
 
 
        if (module_path == NULL)
 
                DLLHandle = LoadLibrary("libxxusb.dll");
 
        else
 
                DLLHandle = LoadLibrary(module_path);
 
 
 
        if (!(xxusb_register_read_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_register_read"))) return __LINE__;
 
        if (!(xxusb_stack_read_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_stack_read"))) return __LINE__;
 
        if (!(xxusb_stack_write_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_stack_write"))) return __LINE__;
 
        if (!(xxusb_stack_execute_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_stack_execute"))) return __LINE__;
 
        if (!(xxusb_register_write_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_register_write"))) return __LINE__;
 
        if (!(xxusb_usbfifo_read_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_usbfifo_read"))) return __LINE__;
 
        if (!(xxusb_bulk_read_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_bulk_read"))) return __LINE__;
 
        if (!(xxusb_bulk_write_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_bulk_write"))) return __LINE__;
 
        if (!(xxusb_reset_toggle_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_reset_toggle"))) return __LINE__;
 
 
 
        if (!(xxusb_devices_find_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_devices_find"))) return __LINE__;
 
        if (!(xxusb_device_close_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_device_close"))) return __LINE__;
 
        if (!(xxusb_device_open_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_device_open"))) return __LINE__;
 
        if (!(xxusb_flash_program_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_flash_program"))) return __LINE__;
 
        if (!(xxusb_flashblock_program_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_flashblock_program"))) return __LINE__;
 
        if (!(xxusb_serial_open_Ptr = (void *) GetProcAddress(DLLHandle,"xxusb_serial_open"))) return __LINE__;
 
 
 
        if (!(VME_register_write_Ptr = (void *) GetProcAddress(DLLHandle,"VME_register_write"))) return __LINE__;
 
        if (!(VME_register_read_Ptr = (void *) GetProcAddress(DLLHandle,"VME_register_read"))) return __LINE__;
 
        if (!(VME_LED_settings_Ptr = (void *) GetProcAddress(DLLHandle,"VME_LED_settings"))) return __LINE__;
 
        if (!(VME_DGG_Ptr = (void *) GetProcAddress(DLLHandle,"VME_DGG"))) return __LINE__;
 
        if (!(VME_Output_settings_Ptr = (void *) GetProcAddress(DLLHandle,"VME_Output_settings"))) return __LINE__;
 
        if (!(VME_read_16_Ptr = (void *) GetProcAddress(DLLHandle,"VME_read_16"))) return __LINE__;
 
        if (!(VME_read_32_Ptr = (void *) GetProcAddress(DLLHandle,"VME_read_32"))) return __LINE__;
 
        if (!(VME_BLT_read_32_Ptr = (void *) GetProcAddress(DLLHandle,"VME_BLT_read_32"))) return __LINE__;
 
        if (!(VME_write_16_Ptr = (void *) GetProcAddress(DLLHandle,"VME_write_16"))) return __LINE__;
 
        if (!(VME_write_32_Ptr = (void *) GetProcAddress(DLLHandle,"VME_write_32"))) return __LINE__;
 
 
 
        if (!(CAMAC_DGG_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_DGG"))) return __LINE__;
 
        if (!(CAMAC_register_read_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_register_read"))) return __LINE__;
 
        if (!(CAMAC_register_write_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_register_write"))) return __LINE__;
 
        if (!(CAMAC_LED_settings_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_LED_settings"))) return __LINE__;
 
        if (!(CAMAC_Output_settings_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_Output_settings"))) return __LINE__;
 
        if (!(CAMAC_read_LAM_mask_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_read_LAM_mask"))) return __LINE__;
 
        if (!(CAMAC_write_LAM_mask_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_write_LAM_mask"))) return __LINE__;
 
        if (!(CAMAC_write_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_write"))) return __LINE__;
 
        if (!(CAMAC_read_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_read"))) return __LINE__;
 
        if (!(CAMAC_Z_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_Z"))) return __LINE__;
 
        if (!(CAMAC_C_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_C"))) return __LINE__;
 
        if (!(CAMAC_I_Ptr = (void *) GetProcAddress(DLLHandle,"CAMAC_I"))) return __LINE__;
 
        return 0;
 
}
 
 
 
 
 
void  WUSBXX_open (char *serial) {
 
        if (serial != NULL)
 
                udev = xxusb_serial_open(serial);
 
        if (!udev)
 
                MessagePopup ("Error", "Cannot connect to USB. ! Check the connection!");
 
}
 
 
 
void  WUSBXX_close (void) {
 
        if (udev) xxusb_device_close(udev);
 
}
 
 
 
int WUSBXX_CAMAC_write( usb_dev_handle *udev, int N, int A, int F, long Data, int *Q, int *X);
 
int WUSBXX_CAMAC_read( usb_dev_handle *udev,int N, int A, int F, long *Data, int *Q, int *X);
 
int WUSBXX_CAMAC_Z( usb_dev_handle *udev );
 
int WUSBXX_CAMAC_C( usb_dev_handle *udev );
 
int WUSBXX_CAMAC_I(usb_dev_handle *udev, int inhibit);
 
 
 
int WUSBXX_CAMAC_write( usb_dev_handle *udev,int N, int A, int F, long Data, int *Q, int *X) {
 
        long intbuf[4];
 
        int ret=0;
 
// CAMAC direct write function
 
        intbuf[0]=1;
 
        intbuf[1]=(long)(F+A*32+N*512 + 0x4000);
 
        if ((F > 15) && (F < 24))  // orig controla
 
                //if ((F > 15) && (F < 28))  // orig controla
 
        {
 
                intbuf[0]=3;
 
                intbuf[2]=(Data & 0xffff);
 
                intbuf[3]=((Data >>16) & 255);
 
                ret = xxusb_stack_execute(udev, intbuf);
 
                *Q = (intbuf[0] & 1);
 
                *X = ((intbuf[0] >> 1) & 1);
 
        } else {
 
                printf("Error N%d A%d F%d",N
,A
,F
);  
        }
 
        return ret;
 
}
 
 
 
int WUSBXX_CAMAC_read( usb_dev_handle *udev,int N, int A, int F, long *Data, int *Q, int *X) {
 
        long intbuf[4];
 
        int ret;
 
        // CAMAC direct read function
 
        intbuf[0]=1;
 
        intbuf[1]=(long)(F+A*32+N*512 + 0x4000);
 
//    intbuf[1]=(long)(F+A*32+N*512);
 
        ret = xxusb_stack_execute(udev, intbuf);
 
//    printf ("ret = %d\n",ret);
 
        if (F < 16) { // orig controla
 
//      *Data = intbuf[0];   //16-bit word
 
                *Data = intbuf[0] + (intbuf[1] & 0xFF) * 0x10000;   //24-bit word
 
                *Q = ((intbuf[1] >> 8) & 1);
 
                *X = ((intbuf[1] >> 9) & 1);
 
        }
 
//    else {
 
//      printf("Error N%d A%d F%d",N,A,F);
 
//    }
 
        return ret;
 
}
 
 
 
int WUSBXX_CAMAC_Z(usb_dev_handle *udev) {
 
        long intbuf[4];
 
        int  ret;
 
//  CAMAC Z = N(28) A(8) F(29)
 
        intbuf[0]=1;
 
        intbuf[1]=(long)(29+8*32+28*512 + 0x4000);
 
        ret = xxusb_stack_execute(udev, intbuf);
 
        return ret;
 
}
 
 
 
int WUSBXX_CAMAC_C(usb_dev_handle *udev) {
 
        long intbuf[4];
 
        int ret;
 
//  CAMAC C = N(28) A(9) F(29)
 
        intbuf[0]=1;
 
        intbuf[1]=(long)(29+9*32+28*512 + 0x4000);
 
        ret = xxusb_stack_execute( udev, intbuf);
 
        return ret;
 
}
 
 
 
int WUSBXX_CAMAC_I(usb_dev_handle *udev, int inhibit) {
 
        long intbuf[4];
 
        int  ret;
 
//      Set Inhibit             = N(29) A(9) F(24)
 
//      Clear Inhibit   = N(29) A(9) F(26)
 
        intbuf[0]=1;
 
        if (inhibit) intbuf[1]=(long)(24+9*32+29*512 + 0x4000);
 
        else intbuf[1]=(long)(26+9*32+29*512 + 0x4000);
 
        ret = xxusb_stack_execute(udev, intbuf);
 
        return ret;
 
}
 
 
 
int init_CAMAC () {
 
 
 
        long dum;
 
        C_Z(udev);
 
        C_C(udev);
 
        C_I(udev,1);
 
 
 
        C_read ( udev,NTGG, 0 , 9, &dum,  &Q,&X); /* init TGG */
 
        C_write ( udev,NTGG, 0, 16, 1000,  &Q,&X); /* Set preset counting value */
 
        C_write ( udev,NTGG, 0 ,17, 0x2,  &Q,&X); /* Set Load&Clock Modes */
 
        C_write ( udev,NDIS, 0, 16, 0xffff,  &Q,&X); /* enable all ch. */
 
        C_read ( udev,NDIS, 0, 26, &dum, &Q, &X);
 
 
 
        C_I(udev, 0);
 
 
 
        return 0 ;
 
}
 
 
 
 
 
 
 
int scaler(int min, int max, int dx, int time_set, char *filename){
 
        FILE *fp ; 
 
        if (filename!=NULL) {
 
                        fp 
= fopen ( filename
, "w" ); 
        } else {
 
                        fp =stdout;
 
  }
 
        
 
        long val, dum;
 
        int thr_set;
 
        char str[0xFF];
 
  int n=(max-min)/dx;
 
        double *x
= (double *) malloc(n
*sizeof(double));  
        double *y
= (double *) malloc(n
*sizeof(double));  
        
 
        
 
        
 
        dum=WUSBXX_load (NULL);
 
        if (dum
) printf("Error", "Cannot load dll!");  
        WUSBXX_open ("CC0130");
 
        
 
        init_CAMAC ( );
 
        
 
        time_t mtime;
 
        for (int i=0; i<n; i++) {
 
                int thr=min+i*dx;
 
                C_write ( udev, NDIS, 0, 17,  thr, &Q, &X);   /* set the threshold */
 
                C_write ( udev, NDIS, 1, 17, 0,  &Q,&X);         /*                                     */
 
                
 
          C_read ( udev, NSCA,0,9,&dum,  &Q,&X);
 
    C_write( udev, NTGG, 0, 16, time_set,  &Q,&X);
 
    C_read ( udev, NTGG, 0, 15, &dum,  &Q,&X);
 
    
 
        
 
                                        
 
                Delay(time_set*1e-3+0.01);
 
                int mych=2;
 
                val=0;
 
                for (int ch=1;ch<mych+1;ch++){
 
                C_read (  udev, NSCA, ch, 0, &val,  &Q,&X);
 
                  //printf("%d\t", val);
 
                  C_read (  udev, NSCA, ch, 0, &val,  &Q,&X);
 
                }
 
                val--;
 
          x[i]=thr;
 
                y[i]=val;
 
                static int plothandle=0;
 
                if (plothandle) DeleteGraphPlot (p4, SCALER_GRAPH, plothandle, VAL_IMMEDIATE_DRAW);
 
                plothandle = PlotXY (p4,SCALER_GRAPH, x, y, i+1, VAL_DOUBLE, VAL_DOUBLE, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, VAL_BLUE);
 
                                                        
 
                sprintf ( str
, "%d %d", thr
, val
) ;  
                
 
                C_I(udev, 0);
 
                if (!daq_on) break; 
 
                
 
        
 
        }
 
        if (fp
!=stdout
) fclose ( fp 
) ;   
        printf("Threshold scan in the file %s\n", filename
);  
        
 
        WUSBXX_close ();
 
  return 0;
 
}
 
 
 
#ifdef MAIN
 
int main( int argc, char **argv){
 
 
 
        
 
                                                
 
        char filename[256]="tmp.txt" ;
 
 
 
        
 
 
 
        //ii=80000000/i-40;
 
        //if (ii<72) ii=72;
 
        //CAMAC_DGG(udev,0,7,0,ii,40,0,0);
 
        //CAMAC_DGG(udev,1,1,1,12,8,0,0);
 
 
 
 
 
 
 
 
 
        int min=0;
 
        int max=1000;
 
        int dx=10;
 
        int time_set=200;
 
 
 
        if (argc
>1) min 
= atoi(argv
[1]);  
        if (argc
>2) max 
= atoi(argv
[2]);  
        if (argc
>3) dx  
= atoi(argv
[3]);  
        if (argc
>4) time_set 
= (int)(1000*atof(argv
[4]));  
        if (argc
>5) sprintf(filename
, "%s", argv
[5]);  
        scaler(min, max, dx, time_set, filename);
 
        return 0;
 
}       
 
 
 
#endif