#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 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};
int debug ;
int initialized = 0;
#define MAX_THREADS 10
int nsamples=0;
int adctype;
float athreshold, twin0,twin1;
float timebins[0XFFFF];
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];
int type=0;
GetCtrlVal(panelHandle,PANEL_EXPORTNAME,fname);
GetCtrlVal(panelHandle,PANEL_FILETYPE,&type);
FILE *fp;
switch (type) {
case 0:
case 1:
sprintf(filename
,"%s_%d.root",fname
, hid
);
fp
=fopen(filename
,"wb");
if (fp) {
H1D_Write2File(hid,fp);
if (type) {
sprintf(rootcmd
,"thisroot.bat && root.exe H1Dload.cxx(\\\"%s\\\")", filename
);
LaunchExecutable(rootcmd);
}
printf("Histogram %d exported to %s\n", hid
, filename
);
}
break;
case 2:
sprintf(filename
,"%s_%d.txt",fname
, hid
);
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;
SetStdioPort (CVI_STDIO_WINDOW);
SetSleepPolicy(VAL_SLEEP_MORE);
CmtNewThreadPool (MAX_THREADS, &poolHandle);
//for (int i=0;i<1000;i++) H1D_Fill(1,i,i);
//H1D_Draw(1,panelHandle,PANEL_ADC1,&adcplothandle[0]);
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(panelHandle,PANEL_STDIO,strbuf);
if (gLog) {
flog
= fopen ("stdio.log", "a");
}
return(ret);
}
int histoinit() {
int nch;
float min,max;
GetCtrlVal(panelHandle,PANEL_NCH_1, &nch);
GetCtrlVal(panelHandle,PANEL_MINX_1, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_1, &max);
H1D_Init(1, "ADC ch 1","Pulse height", nch, min, max );
H1D_SetTitleX(1,"ADC (V)");
H1D_SetTitleY(1,"N");
GetCtrlVal(panelHandle,PANEL_NCH_2, &nch);
GetCtrlVal(panelHandle,PANEL_MINX_2, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_2, &max);
H1D_Init(2, "ADC ch 2","Pulse height", nch, min, max );
H1D_SetTitleX(2,"ADC (V)");
H1D_SetTitleY(2,"N");
GetCtrlVal(panelHandle,PANEL_NCH_3, &nch);
GetCtrlVal(panelHandle,PANEL_MINX_3, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_3, &max);
H1D_Init(3, "TDC ch 1","TDC", nch, min, max );
H1D_SetTitleX(3,"TDC (us)");
H1D_SetTitleY(3,"N");
GetCtrlVal(panelHandle,PANEL_NCH_4, &nch);
GetCtrlVal(panelHandle,PANEL_MINX_4, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_4, &max);
H1D_Init(4, "TDC ch 2","TDC", nch, min, max );
H1D_SetTitleX(4,"TDC (us)");
H1D_SetTitleY(4,"N");
SetCtrlAttribute (panelHandle, PANEL_ADC1, ATTR_XNAME, H1D_GetTitleX(1) );
SetCtrlAttribute (panelHandle, PANEL_ADC1, ATTR_YNAME, H1D_GetTitleY(1) );
SetCtrlAttribute (panelHandle, PANEL_ADC2, ATTR_XNAME, H1D_GetTitleX(2) );
SetCtrlAttribute (panelHandle, PANEL_ADC2, ATTR_YNAME, H1D_GetTitleY(2) );
SetCtrlAttribute (panelHandle, PANEL_TDC1, ATTR_XNAME, H1D_GetTitleX(3) );
SetCtrlAttribute (panelHandle, PANEL_TDC1, ATTR_YNAME, H1D_GetTitleY(3) );
SetCtrlAttribute (panelHandle, PANEL_TDC2, ATTR_XNAME, H1D_GetTitleX(4) );
SetCtrlAttribute (panelHandle, PANEL_TDC2, ATTR_YNAME, H1D_GetTitleY(4) );
GetCtrlVal(panelHandle,PANEL_MINX_5, &min);
GetCtrlVal(panelHandle,PANEL_MAXX_5, &max);
SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);
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(panelHandle,PANEL_TWIN0, &twin0);
GetCtrlVal(panelHandle,PANEL_TWIN1, &twin1);
GetCtrlVal(panelHandle,PANEL_ADCTYPE, &adctype);
GetCtrlVal(panelHandle,PANEL_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
);
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_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, col[id]);
//plothandle[id] = PlotXY (panelHandle, PANEL_GRAPH, timebins, data, nsamples, VAL_FLOAT, VAL_INTEGER, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, col[id]);
H1D_Draw(1,panelHandle,PANEL_ADC1,&adcplothandle[0]);
H1D_Draw(2,panelHandle,PANEL_ADC2,&adcplothandle[1]);
H1D_Draw(3,panelHandle,PANEL_TDC1,&tdcplothandle[0]);
H1D_Draw(4,panelHandle,PANEL_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);
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(panelHandle,PANEL_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];
int hdr[0xFF];
char filename[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(panel,PANEL_IP, ip);
GetCtrlVal(panel,PANEL_TRIGGER, &trigger);
GetCtrlVal(panel,PANEL_SAMPLES, &nsamples);
GetCtrlVal(panel,PANEL_DECIMATION,&decimation);
GetCtrlVal(panel,PANEL_NEVE , &neve);
GetCtrlVal(panel,PANEL_CH0 , &imask[0] );
GetCtrlVal(panel,PANEL_CH1 , &imask[1] );
GetCtrlVal(panel,PANEL_PFREQ , &pfreq);
GetCtrlVal(panel,PANEL_DEBUG , &debug);
GetCtrlVal(panel,PANEL_NBEFORE , &nbefore);
GetCtrlVal(panel,PANEL_ENABLEDOUTPUT, &output);
GetCtrlVal(panel,PANEL_OUTWAVE, &outwaveforms);
GetCtrlVal(panel,PANEL_FILENAME, 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(panel,PANEL_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);
if (state && eventData1==0) {
histoinit();
/* 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(filename
, "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
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:
switch (control) {
case PANEL_EXPORT_1:
hid=1;
break;
case PANEL_EXPORT_2:
hid=2;
break;
case PANEL_EXPORT_3:
hid=3;
break;
case PANEL_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;
}