#include "redpitaya_gui.h"
#include <ansi_c.h>
#include <tcpsupp.h>
#include <utility.h>
#include <cvirte.h>
#include <userint.h>
#include "redpitaya_gui.h"
#include "H1D.h"
#define NBEFORE 150
#define MAXSAMPLES 16384
#define MINTRGDELAY -8192
static int panelHandle;
static int outputHandle;
static int settingsHandle;
static int ch0Handle;
static int ch1Handle;
static unsigned int chandle = 0;
//static int tfID;
int pfreq;
static int plothandle[2]= {0,0};
static int tdcplothandle[2]= {0,0};
static int adcplothandle[2]= {0,0};
static int excludefirst[2]= {0,0};
int debug ;
int initialized = 0;
#define MAX_THREADS 10
int nsamples=0;
int adctype;
float athreshold, twin0,twin1;
float timebins[0XFFFF];
float daqtime;
double starttime;
FILE *foutput;
int outwaveforms=0;
static CmtThreadPoolHandle poolHandle = 0;
int ctrl_c=0;
int CVICALLBACK SocketCB (unsigned handle, int xType, int errCode, void *callbackData);
static int export_data (int hid) {
char filename[0xFF],rootcmd[0xFF];
char fname[0xFF];
char path[0xFF];
char datestr[0xFF];
int type=0;
GetCtrlVal(settingsHandle,SETTINGS_EXPORTNAME,fname);
GetCtrlVal(settingsHandle,SETTINGS_FILETYPE,&type);
MakeDir (path);
FILE *fp;
int hour, min, month, day,year;
double sec;
double mtime;
GetCurrentDateTime (&mtime);
GetDateTimeElements (mtime, &hour, &min, &sec, &month, &day, &year);
sprintf(datestr
,"%02d_%02d_%02d", hour
, min
, (int) sec
);
switch (type) {
case 0:
case 1:
sprintf(filename
,"%s\\%s_%d_%s.dat",path
, fname
, hid
, datestr
);
fp
=fopen(filename
,"wb");
if (fp) {
H1D_Write2File(hid,fp);
if (type) {
sprintf(rootcmd
,"thisroot.bat && root.exe C:/home/cvi/apps/RedPitaya/soccli/H1Dload.cxx(\\\"%s_%d_%s.dat\\\")", fname
, hid
, datestr
);
LaunchExecutable(rootcmd);
}
printf("Histogram %d exported to %s \n%s\n", hid
, filename
, rootcmd
);
}
break;
case 2:
sprintf(filename
,"%s\\%s_%d_%s.txt",path
, fname
, hid
, datestr
);
if (fp) {
for (int i
=0; i
<H1D_GetNbinsX
(hid
); i
++) fprintf(fp
,"%g\t%g\n", H1D_GetXBinCenter
(hid
,i
), H1D_GetBinContent
(hid
,i
) );
printf("Histogram %d exported to %s\n", hid
, filename
);
}
break;
}
return (0);
}
int main (int argc, char *argv[]) {
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "redpitaya_gui.uir", PANEL)) < 0)
return -1;
GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 0, &settingsHandle);
GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 1, &outputHandle);
GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 2, &ch0Handle);
GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 3, &ch1Handle);
SetStdioPort (CVI_STDIO_WINDOW);
SetSleepPolicy(VAL_SLEEP_MORE);
CmtNewThreadPool (MAX_THREADS, &poolHandle);
//printf("size of double = %d\n",sizeof(double));
DisplayPanel (panelHandle);
RunUserInterface ();
DiscardPanel (panelHandle);
CmtDiscardThreadPool (poolHandle);
if (chandle!=0) DisconnectFromTCPServer (chandle);
return 0;
}
char strbuf[0xFF];
int gLog=0;
int printf(const char *format
, ...
) {
va_list aptr;
int ret;
FILE *flog;
SetCtrlVal(outputHandle,OUTPUT_STDIO,strbuf);
if (gLog) {
flog
= fopen ("stdio.log", "a");
}
return(ret);
}
int CVICALLBACK SetGraphLogYCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
int cid=0;
int logy=0;
switch (event) {
case EVENT_COMMIT:
GetCtrlVal(panel,control, &logy);
if (panel== ch0Handle){
switch (control) {
case CH0_LOGY_1:
cid = CH0_TDC1;
break;
case CH0_LOGY_2:
cid = CH0_ADC1;
break;
}
}
if (panel == ch1Handle){
switch (control) {
case CH1_LOGY_3:
cid = CH1_TDC2;
break;
case CH1_LOGY_4:
cid = CH1_ADC2;
break;
}
}
if (logy) SetCtrlAttribute (panel, cid, ATTR_YMAP_MODE, VAL_LOG);
else SetCtrlAttribute (panel, cid, ATTR_YMAP_MODE, VAL_LINEAR);
break;
}
return 0;
}
int CVICALLBACK SetGraphPropertiesCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
float min, max;
int autoscale;
switch (event) {
case EVENT_COMMIT:
GetCtrlVal(panelHandle,PANEL_MINX_5, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_5, &max);
GetCtrlVal(panelHandle,PANEL_AUTOY, &autoscale);
if (autoscale)
SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
GetCtrlVal(panelHandle,PANEL_MINX_6, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_6, &max);
GetCtrlVal(panelHandle,PANEL_AUTOX, &autoscale);
if (autoscale)
SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_BOTTOM_XAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_BOTTOM_XAXIS, VAL_MANUAL, min, max);
GetCtrlVal(ch0Handle,CH0_MINX_7, &min);
GetCtrlVal(ch0Handle,CH0_MAXX_7, &max);
GetCtrlVal(ch0Handle,CH0_AUTOY_2, &autoscale);
if (autoscale)
SetAxisScalingMode (ch0Handle, CH0_TDC1, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (ch0Handle, CH0_TDC1, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
GetCtrlVal(ch0Handle,CH0_MINX_8, &min);
GetCtrlVal(ch0Handle,CH0_MAXX_8, &max);
GetCtrlVal(ch0Handle,CH0_AUTOY_3, &autoscale);
if (autoscale)
SetAxisScalingMode (ch0Handle, CH0_ADC1, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (ch0Handle, CH0_ADC1, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
GetCtrlVal(ch1Handle,CH1_MINX_9, &min);
GetCtrlVal(ch1Handle,CH1_MAXX_9, &max);
GetCtrlVal(ch1Handle,CH1_AUTOY_4, &autoscale);
if (autoscale)
SetAxisScalingMode (ch1Handle, CH1_TDC2, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (ch1Handle, CH1_TDC2, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
GetCtrlVal(ch1Handle,CH1_MINX_10, &min);
GetCtrlVal(ch1Handle,CH1_MAXX_10, &max);
GetCtrlVal(ch1Handle,CH1_AUTOY_5, &autoscale);
if (autoscale)
SetAxisScalingMode (ch1Handle, CH1_ADC2, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
else
SetAxisScalingMode (ch1Handle, CH1_ADC2, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
break;
}
return 0;
}
int histoinit() {
int nch;
float min,max;
GetCtrlVal(ch0Handle,CH0_NCH_1, &nch);
GetCtrlVal(ch0Handle,CH0_MINX_1, &min);
GetCtrlVal(ch0Handle,CH0_MAXX_1, &max);
H1D_Init(1, "ADC ch 1","Pulse height", nch, min, max );
H1D_SetTitleX(1,"ADC (V)");
H1D_SetTitleY(1,"N");
GetCtrlVal(ch1Handle,CH1_NCH_2, &nch);
GetCtrlVal(ch1Handle,CH1_MINX_2, &min);
GetCtrlVal(ch1Handle,CH1_MAXX_2, &max);
H1D_Init(2, "ADC ch 2","Pulse height", nch, min, max );
H1D_SetTitleX(2,"ADC (V)");
H1D_SetTitleY(2,"N");
GetCtrlVal(ch0Handle,CH0_NCH_3, &nch);
GetCtrlVal(ch0Handle,CH0_MINX_3, &min);
GetCtrlVal(ch0Handle,CH0_MAXX_3, &max);
H1D_Init(3, "TDC ch 1","TDC", nch, min, max );
H1D_SetTitleX(3,"TDC (us)");
H1D_SetTitleY(3,"N");
GetCtrlVal(ch1Handle,CH1_NCH_4, &nch);
GetCtrlVal(ch1Handle,CH1_MINX_4, &min);
GetCtrlVal(ch1Handle,CH1_MAXX_4, &max);
H1D_Init(4, "TDC ch 2","TDC", nch, min, max );
H1D_SetTitleX(4,"TDC (us)");
H1D_SetTitleY(4,"N");
SetCtrlAttribute (ch0Handle, CH0_ADC1, ATTR_XNAME, H1D_GetTitleX(1) );
SetCtrlAttribute (ch0Handle, CH0_ADC1, ATTR_YNAME, H1D_GetTitleY(1) );
SetCtrlAttribute (ch1Handle, CH1_ADC2, ATTR_XNAME, H1D_GetTitleX(2) );
SetCtrlAttribute (ch1Handle, CH1_ADC2, ATTR_YNAME, H1D_GetTitleY(2) );
SetCtrlAttribute (ch0Handle, CH0_TDC1, ATTR_XNAME, H1D_GetTitleX(3) );
SetCtrlAttribute (ch0Handle, CH0_TDC1, ATTR_YNAME, H1D_GetTitleY(3) );
SetCtrlAttribute (ch1Handle, CH1_TDC2, ATTR_XNAME, H1D_GetTitleX(4) );
SetCtrlAttribute (ch1Handle, CH1_TDC2, ATTR_YNAME, H1D_GetTitleY(4) );
SetGraphLogYCB( ch0Handle, CH0_LOGY_1, EVENT_COMMIT,NULL,0,0);
SetGraphLogYCB( ch0Handle, CH0_LOGY_2, EVENT_COMMIT,NULL,0,0);
SetGraphLogYCB( ch1Handle, CH1_LOGY_3, EVENT_COMMIT,NULL,0,0);
SetGraphLogYCB( ch1Handle, CH1_LOGY_4, EVENT_COMMIT,NULL,0,0);
SetGraphPropertiesCB( panelHandle, PANEL, EVENT_COMMIT,NULL,0,0);
SetCtrlAttribute (panelHandle, PANEL_GRAPH, ATTR_LABEL_TEXT , "sampling adc data");
SetCtrlAttribute (panelHandle, PANEL_GRAPH, ATTR_XNAME, "t(us)" );
SetCtrlAttribute (panelHandle, PANEL_GRAPH, ATTR_YNAME, "U(V)" );
GetCtrlVal(settingsHandle,SETTINGS_TWIN0, &twin0);
GetCtrlVal(settingsHandle,SETTINGS_TWIN1, &twin1);
GetCtrlVal(panelHandle,PANEL_ADCTYPE, &adctype);
GetCtrlVal(settingsHandle,SETTINGS_ITRGLEVEL , &athreshold);
return 0;
}
int analyse(int nb, unsigned char *cdata, int *info, int *ninfo) {
int *ibuf = (int *)cdata;
float *fbuf = (float *)cdata;
float *finfo = (float *)info;
int neve=0;
int *data = (ibuf+3);
int nr=0;
static float adc = 10000;
static float qdc = 0;
*ninfo = 0;
printf("Run HDR LEN=%d NEVE=%d dt=%f adc=%f qdc=%f\n", ibuf
[0],ibuf
[1],fbuf
[2],adc
,qdc
);
daqtime += fbuf[2];
SetCtrlVal(panelHandle, PANEL_CDAQTIME,daqtime);
float ctime = Timer
() -starttime
;
SetCtrlVal
(panelHandle
, PANEL_CTIME
, ctime);
if (ctime
>0)SetCtrlVal
(panelHandle
, PANEL_DAQEFF
, daqtime
/ctime);
//daqtime =0;
while (nr<nb) {
int recid = *data++;
int chmask = *data++;
nr +=8;
if (recid!=0x2) continue;
for (int id=0; id<2; id++) {
if ( !(chmask & (1 << id)) ) {
if (neve % pfreq == 0)
if (plothandle[id]) {
DeleteGraphPlot (panelHandle, PANEL_GRAPH, plothandle[id], VAL_IMMEDIATE_DRAW);
plothandle[id] = 0;
}
continue;
}
if ( id
!= *(data
++) ) printf("Error\n");
int nsamples = *(data++);
if (nsamples<=0 || nsamples>16*1024) {
printf("Error nsamples %d\n", nsamples
);
return -1;
}
float *fdata = (float *) data;
if ( nsamples>0 && neve % pfreq == 0) {
const int col[4]= {VAL_RED,VAL_GREEN,VAL_BLUE,VAL_WHITE};
if (plothandle[id]) DeleteGraphPlot (panelHandle, PANEL_GRAPH, plothandle[id], VAL_IMMEDIATE_DRAW);
plothandle[id] = PlotXY (panelHandle, PANEL_GRAPH, timebins, fdata, nsamples, VAL_FLOAT, VAL_FLOAT, VAL_FAT_LINE, VAL_NO_POINT, VAL_SOLID, 1, col[id]);
H1D_Draw(1, ch0Handle,CH0_ADC1,&adcplothandle[0]);
H1D_Draw(2, ch1Handle,CH1_ADC2,&adcplothandle[1]);
H1D_Draw(3, ch0Handle,CH0_TDC1,&tdcplothandle[0]);
H1D_Draw(4, ch1Handle,CH1_TDC2,&tdcplothandle[1]);
if (debug
) for (int k
=0; k
<10; k
++) printf("%d %d (%f , %d)\n", id
,k
, timebins
[k
],data
[k
]);
}
nr+=8;
adc=10000;
qdc=0;
int nqdc=0;
int ntdc=0;
for (int k=1; k<nsamples; k++) {
float t =timebins[k];
float tp=timebins[k-1];
if (fdata[k] < adc) adc = fdata[k];
if (t>twin0 && t<twin1 ) {
nqdc++;
qdc+=fdata[k];
}
if (fdata[k]< athreshold && fdata[k-1]> athreshold) {
double t0= tp+(athreshold-fdata[k-1])/(fdata[k]-fdata[k-1])* (t-tp);
if (ntdc>0) H1D_Fill(3+id, t0,1);
if (ntdc==0 && !excludefirst[id]) H1D_Fill(3+id, t0,1);
finfo[*ninfo+4+ntdc]=t0;
ntdc++;
}
}
if (nqdc) qdc/=nqdc;
//printf("adc %f qdc %f\n", adc,qdc);
info[*ninfo]=(ntdc+4)*sizeof(int); // len
info[*ninfo+1]=id | 0xF0000000; // recid
finfo[*ninfo+2]=adc;
finfo[*ninfo+3]=qdc;
*ninfo+= ntdc+4;
if (adctype)
H1D_Fill(1+id, -adc,1);
else
H1D_Fill(1+id, -qdc,1);
nr+=4*nsamples;
data+=nsamples;
}
recid = *data++;
int event = *data++;
nr+=8;
neve++;
if (debug
) printf("recid %d event %d\n",recid
, event
);
}
return neve;
}
const int maxlen = 100000000;
unsigned char data[maxlen];
int *idata = (int *) &data[0];
int evinfo[maxlen];
int CVICALLBACK SocketCB (unsigned handle, int xType, int errCode, void *callbackData) {
int nb = 0 ;
static int event = 0;
static int ncalls = 0;
static time_t t0, t1;
switch (xType) {
case TCP_DISCONNECT:
printf("TCP_DISCONNECT ErrorString %s\n",GetTCPErrorString
(errCode
));
printf("TCP_DISCONNECT SystemErrorString %s\n",GetTCPSystemErrorString
());
chandle = 0;
break;
case TCP_DATAREADY: {
int hdr[2]= {0,0};
nb = ClientTCPRead(handle,&hdr[0],8,1000);
int size = hdr[1] - 8;
if (size>maxlen) size=maxlen;
nb = 0;
while (nb < size) {
int retval = ClientTCPRead(handle,&data[nb],size-nb,1000);
if (retval<1) break;
nb += retval;
}
if (debug
) printf("Received RECID %d HDRLEN %d == read %d\n", hdr
[0], size
, nb
);
int ninfo=0;
switch (hdr[0]) {
case 0:
data[nb]=0;
break;
case 1:// read
GetCtrlVal(panelHandle,PANEL_CEVE , &event);
GetCtrlVal(settingsHandle,SETTINGS_NTOTAL , &ncalls);
event += analyse(nb,data, evinfo, &ninfo);
if (foutput) {
if (outwaveforms
) fwrite(data
, 1, nb
, foutput
);
fwrite(evinfo
, 1, ninfo
*sizeof(int), foutput
);
if ((t1-t0)>10000) {
for (int i=0; i<4; i++) H1D_Write2File(1+i,foutput);
}
}
SetCtrlVal(panelHandle,PANEL_CEVE , event);
if (event>=ncalls) StartCB (panelHandle, PANEL_START, EVENT_COMMIT, NULL,1,0);
break;
default:
printf("Unknown command = %d\n", hdr
[0]);
break;
}
break;
}
}
return 0;
}
int rpdecimation(int i) {
switch (i) {
case 1:
return 0;
case 8:
return 1;
case 64:
return 2;
case 1024:
return 3;
case 8192:
return 4;
case 65536:
return 5;
}
return 0;
}
int CVICALLBACK StartCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
char ip[0xFF];
char path[0xFF];
int hdr[0xFF];
char filename[0xFF];
char filepath[0xFF];
unsigned short *sbuff = (unsigned short *)&hdr[5] ;
unsigned char *cbuff = (unsigned char *)&sbuff[3] ;
int imask[2];
unsigned char mask;
unsigned char trigger;
unsigned short nsamples;
int delay;
int nbefore;
unsigned int decimation;
unsigned short neve;
int output;
switch (event) {
case EVENT_COMMIT: {
GetCtrlVal(settingsHandle,SETTINGS_IP, ip);
GetCtrlVal(settingsHandle,SETTINGS_TRIGGER, &trigger);
GetCtrlVal(settingsHandle,SETTINGS_SAMPLES, &nsamples);
GetCtrlVal(settingsHandle,SETTINGS_DECIMATION,&decimation);
GetCtrlVal(settingsHandle,SETTINGS_NEVE , &neve);
GetCtrlVal(settingsHandle,SETTINGS_CH0 , &imask[0] );
GetCtrlVal(settingsHandle,SETTINGS_CH1 , &imask[1] );
GetCtrlVal(settingsHandle,SETTINGS_PFREQ , &pfreq);
GetCtrlVal(settingsHandle,SETTINGS_DEBUG , &debug);
GetCtrlVal(settingsHandle,SETTINGS_NBEFORE , &nbefore);
GetCtrlVal(settingsHandle,SETTINGS_ENABLEDOUTPUT, &output);
GetCtrlVal(panel,PANEL_OUTWAVE, &outwaveforms);
GetCtrlVal(settingsHandle,SETTINGS_FILENAME, filename);
MakeDir (path);
sprintf(filepath
,"%s\\%s", path
, filename
);
delay= MINTRGDELAY + nsamples - nbefore + 1;
mask = 0;
for (int i=0; i<2; i++) {
if (imask[i]) mask |= (1<<i);
}
double level =0;
GetCtrlVal(settingsHandle,SETTINGS_TRGLEVEL , &level);
switch (control) {
case PANEL_CONNECT: {
int state;
GetCtrlVal(panel,PANEL_CONNECT, &state);
if (state) {
ConnectToTCPServerEx (&chandle, 9930, ip, SocketCB, NULL, 0, TCP_ANY_LOCAL_PORT);
} else {
if (chandle!=0) DisconnectFromTCPServer (chandle);
chandle = 0;
}
}
break;
case PANEL_START: {
int state;
GetCtrlVal(panel,PANEL_START, &state);
GetCtrlVal(ch0Handle,CH0_EXCLUDE_1, &excludefirst[0]);
GetCtrlVal(ch1Handle,CH1_EXCLUDE_2, &excludefirst[1]);
if (state && eventData1==0) {
histoinit();
starttime=Timer();
daqtime =0;
/* decimation n (=1,8,64...) : frequency = 125/n MHz*/
for (int i=0; i<nsamples; i++) timebins[i]=(i-nbefore)* (float)decimation /125.;
if (output
) foutput
= fopen(filepath
, "wb");
printf("decimation %d\n", decimation
);
SetCtrlVal(panel,PANEL_CEVE , 0);
ctrl_c=0;
hdr[0] = 0;
hdr[1] = 7*sizeof(int);
hdr[2] = delay;
hdr[3] = rpdecimation(decimation);
hdr[4] = level * 1000;
sbuff[0] = neve;
sbuff[1] = nsamples;
sbuff[2] = 1000; //tout
cbuff[0] = trigger;
cbuff[1] = mask;
ClientTCPWrite(chandle,&hdr[0],hdr[1],5000); // acquire
} else {
hdr[0] = 1;
hdr[1] = 2*sizeof(int);
ClientTCPWrite(chandle,&hdr[0],hdr[1],5000); // stop the transfer
printf("INFO Stopping the acquisition\n");
SetCtrlVal(panel,PANEL_START, 0);
foutput=NULL;
}
break;
}
default:
break;
}
ProcessSystemEvents ();
break;
}
}
return 0;
}
int CVICALLBACK ExitCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
switch (event) {
case EVENT_COMMIT:
QuitUserInterface(0);
break;
}
return 0;
}
int CVICALLBACK ExportCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
int hid=0;
switch (event) {
case EVENT_COMMIT:
if (panel== ch0Handle){
switch (control) {
case CH0_EXPORT_1:
hid=1;
break;
case CH0_EXPORT_3:
hid=3;
break;
}
}
if (panel== ch1Handle){
switch (control) {
case CH1_EXPORT_2:
hid=2;
break;
case CH1_EXPORT_4:
hid=4;
break;
}
}
export_data(hid);
break;
}
return 0;
}
int CVICALLBACK ResetCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
switch (event) {
case EVENT_COMMIT:
for (int i=1; i<=4; i++) H1D_Clear(i);
break;
}
return 0;
}