/lab/sipmscan/trunk/GuiLinkDef.h |
---|
0,0 → 1,17 |
#ifdef __CINT__ |
#pragma link off all globals; |
#pragma link off all classes; |
#pragma link off all functions; |
//#pragma link C++ class TGMdiSubwindow+; |
//#pragma link C++ class TGAppMainFrame+; |
//#pragma link C++ function MyEventHandler; |
//#pragma link C++ function GetDebug; |
//#pragma link C++ function MyRedraw; |
//#pragma link C++ function MyTimer; |
//#pragma link C++ class daq; |
#endif |
/lab/sipmscan/trunk/MIKRO/MIKRO.c |
---|
0,0 → 1,296 |
#include "rs232.h" |
#include "MIKRO.h" |
//#define DEBUG |
#define COMWAIT 0.5 |
#define COMDELAY 0.1 |
static char MIKRO_Send[100], MIKRO_Receive[100]; |
static char MIKRO_Device, MIKRO_Axes, MIKRO_Response; |
static int MIKRO_Port; |
static int nin, nout, rstat; |
static int MIKRO_type[100]; |
int MIKRO_Cmd (int node, char *cmd) |
{ |
printf("Command: %1d %s\n",node,cmd); |
Delay(COMDELAY); |
FlushInQ (MIKRO_Port); |
nout = sprintf (MIKRO_Send, "%1d %s\r", node, cmd); |
ComWrt (MIKRO_Port, MIKRO_Send, nout); |
if ((nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa))==0) { |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
if (nin==2) return (0); |
} |
return (-1); |
} |
int MIKRO_Set (int node, char cmd[], int val) |
{ |
printf("Command: %1d %s %d\n",node,cmd, val); |
Delay(COMDELAY); |
FlushInQ (MIKRO_Port); |
nout = sprintf (MIKRO_Send, "%1d %s %d\r", node, cmd, val); |
ComWrt (MIKRO_Port, MIKRO_Send, nout); |
if ((nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa))==0) { |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
if (nin==2) return (0); |
} |
return (-1); |
} |
int MIKRO_Get (int node, char cmd[], int *val) |
{ |
short int stmp; |
Delay(COMDELAY); |
FlushInQ (MIKRO_Port); |
nout = sprintf (MIKRO_Send, "%1d %s\r", node, cmd); |
ComWrt (MIKRO_Port, MIKRO_Send, nout); |
if ((nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa))==0) { |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
if (nin>0){ |
// MIKRO_Receive[--nin]=0; |
switch (nin) { |
case 9: |
sscanf (MIKRO_Receive, "%*x %hx",&stmp); |
*val=stmp; |
return (0); |
case 13: |
sscanf (MIKRO_Receive, "%*x %x",val); |
return (0); |
default: |
printf("Node %d Com error => bytes rcved=0x%02x buf=%s\n",node,nin,MIKRO_Receive); |
break; |
} |
} |
} |
return (-1); |
} |
int MIKRO_GetStat (int node) |
{ |
int tmp; |
Delay(COMDELAY); |
FlushInQ (MIKRO_Port); |
nout = sprintf (MIKRO_Send, "%1d st\r", node); |
ComWrt (MIKRO_Port, MIKRO_Send, nout); |
if ((nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa))==0) { |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
// if (nin>0) nin--; |
MIKRO_Receive[nin]=0; |
if (nin==9) { |
tmp=0; |
sscanf (MIKRO_Receive, "%*x %hx",(short int *)&tmp); |
return (tmp); |
} |
} |
return (-1); |
} |
int _VI_FUNC MIKRO_Open (char * dev) |
{ |
MIKRO_Port=OpenComConfig (dev, "", 38400, 0, 8, 1, 512, 512); |
// SetXMode (MIKRO_Port, 0); |
// SetCTSMode (MIKRO_Port, LWRS_HWHANDSHAKE_OFF); |
// SetComTime (MIKRO_Port, COMWAIT); |
return 0; |
} |
int _VI_FUNC MIKRO_Init (int node, int type) |
{ |
MIKRO_type[node]=type; |
Delay(0.1); |
MIKRO_Cmd(node,"ok 1"); |
MIKRO_Cmd(node,"ab"); |
switch (type){ |
case 1: // 3M Linear |
MIKRO_Cmd(node,"k 1"); |
MIKRO_Cmd(node,"ad 200"); |
MIKRO_Cmd(node,"aa 2"); |
MIKRO_Cmd(node,"fa 1"); |
MIKRO_Cmd(node,"fd 3000"); // Set Max Dynamic Following Error (1000) |
MIKRO_Cmd(node,"sr 1000"); |
MIKRO_Cmd(node,"sp 750"); |
MIKRO_Cmd(node,"ac 100"); |
MIKRO_Cmd(node,"dc 200"); |
MIKRO_Cmd(node,"por 28000"); |
MIKRO_Cmd(node,"i 600"); |
MIKRO_Cmd(node,"ano 2350"); |
MIKRO_Cmd(node,"ls 1"); |
MIKRO_Cmd(node,"hp 1"); |
MIKRO_Cmd(node,"hf 1"); |
break; |
case 2: // 3M Rotary |
MIKRO_Cmd(node,"k 1"); |
MIKRO_Cmd(node,"ad 200"); |
MIKRO_Cmd(node,"aa 1"); |
MIKRO_Cmd(node,"fa 1"); |
MIKRO_Cmd(node,"fd 3000"); // Set Max Dynamic Following Error (1000) |
MIKRO_Cmd(node,"sr 1000"); |
MIKRO_Cmd(node,"sp 550"); |
MIKRO_Cmd(node,"ac 100"); |
MIKRO_Cmd(node,"dc 200"); |
MIKRO_Cmd(node,"por 28000"); |
MIKRO_Cmd(node,"i 600"); |
MIKRO_Cmd(node,"ano 2350"); |
MIKRO_Cmd(node,"ls 99"); |
MIKRO_Cmd(node,"hp 1"); |
MIKRO_Cmd(node,"hf 1"); |
break; |
case 3: // 4M Linear |
MIKRO_Cmd(node,"k 1"); |
MIKRO_Cmd(node,"ad 1000"); |
MIKRO_Cmd(node,"aa 2"); |
MIKRO_Cmd(node,"fa 1"); |
MIKRO_Cmd(node,"fd 3000"); // Set Max Dynamic Following Error (1000) |
MIKRO_Cmd(node,"sr 1000"); |
MIKRO_Cmd(node,"sp 1000"); |
MIKRO_Cmd(node,"ac 100"); |
MIKRO_Cmd(node,"dc 200"); |
MIKRO_Cmd(node,"por 28000"); |
MIKRO_Cmd(node,"i 600"); |
MIKRO_Cmd(node,"ano 2600"); |
MIKRO_Cmd(node,"ls 1"); |
MIKRO_Cmd(node,"hp 1"); |
MIKRO_Cmd(node,"hf 1"); |
break; |
case 4: // 4M Rotary |
MIKRO_Cmd(node,"k 1"); |
MIKRO_Cmd(node,"ad 100"); |
MIKRO_Cmd(node,"aa 1"); |
MIKRO_Cmd(node,"fa 1"); |
MIKRO_Cmd(node,"fd 3000"); // Set Max Dynamic Following Error (1000) |
MIKRO_Cmd(node,"sp 800"); |
MIKRO_Cmd(node,"sr 1000"); |
MIKRO_Cmd(node,"ac 100"); |
MIKRO_Cmd(node,"dc 200"); |
MIKRO_Cmd(node,"por 28000"); |
MIKRO_Cmd(node,"i 600"); |
MIKRO_Cmd(node,"ano 2600"); |
MIKRO_Cmd(node,"ls 99"); |
break; |
default: |
break; |
} |
MIKRO_Cmd(node,"rd 0"); |
MIKRO_Cmd(node,"n 2"); |
MIKRO_Cmd(node,"en"); |
if (type != 0){ |
MIKRO_Cmd(node,"eeboot 1"); |
MIKRO_Cmd(node,"eepsav 1"); |
Delay(0.1); |
} |
return 0; |
} |
int _VI_FUNC MIKRO_Reset (int node) |
{ |
MIKRO_Cmd(node,"di"); // disables the node |
Delay(COMDELAY); |
nout = sprintf (MIKRO_Send, "%1d rn\r", node); // resets the node |
ComWrt (MIKRO_Port, MIKRO_Send, nout); |
SetComTime (MIKRO_Port, 20); |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
SetComTime (MIKRO_Port, COMWAIT); |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
// if (nin!=0) nin--; |
// MIKRO_Receive[nin]=0; |
printf("%s\n",MIKRO_Receive); |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa); |
// if (nin!=0) nin--; |
// MIKRO_Receive[nin]=0; |
printf("%s\n",MIKRO_Receive); |
MIKRO_Init(node,0); |
return 0; |
} |
int _VI_FUNC MIKRO_ReferenceMove (int node) |
{ |
int fac=10; |
int n2,as; |
MIKRO_Cmd(node,"ab"); |
MIKRO_Cmd(node,"en"); |
MIKRO_Set(node,"ll",-1000000); |
MIKRO_Set(node,"ll",1000000); |
if (!(MIKRO_GetStat(node)&0x8000)){ |
MIKRO_Set(node,"v", -100*fac); |
do { |
MIKRO_GetPosition(node,&n2); |
MIKRO_Get(node,"as",&as); |
printf("Approaching N-limit node=%d pos=%d speed=%d\n",node,n2,as); |
} while (MIKRO_GetStat(node)&0x1 ); |
if (!(MIKRO_GetStat(node)&0x8000)){ |
printf("N-limit not reached! Trying with half speed.\n"); |
MIKRO_Set(node,"v", -50*fac); |
do { |
MIKRO_GetPosition(node,&n2); |
MIKRO_Get(node,"as",&as); |
printf("Approaching N-limit node=%d pos=%d speed=%d\n",node,n2,as); |
} while (MIKRO_GetStat(node)&0x1 ); |
if (!(MIKRO_GetStat(node)&0x8000)){ |
printf("N-limit not reached! Aborting ...\n"); |
MIKRO_Cmd(node,"ab"); |
return -1; |
} |
} |
} |
MIKRO_MoveFor(node,1000); |
MIKRO_Set(node,"v", -10*fac); |
do { |
MIKRO_GetPosition(node,&n2); |
MIKRO_Get(node,"as",&as); |
printf("Fine tuning 0: node=%d pos=%d speed=%d\n",node,n2, as); |
} while (MIKRO_GetStat(node)&0x1); |
if (!(MIKRO_GetStat(node)&0x8000)){ |
printf("N-limit not reached! Aborting ...\n"); |
MIKRO_Cmd(node,"ab"); |
return -1; |
} |
MIKRO_MoveFor(node,1000); |
MIKRO_Set(node,"ho",0); |
MIKRO_Set(node,"ll",-100); |
MIKRO_Set(node,"ll",500100); |
return 0; |
} |
int _VI_FUNC MIKRO_MoveFor (int node, int dist) |
{ |
MIKRO_Set(node,"lr", dist); |
MIKRO_Cmd(node,"mv"); |
while (MIKRO_GetStat(node)&1) Delay(0.1); |
return 0; |
} |
int _VI_FUNC MIKRO_MoveTo (int node, int dest) |
{ |
// printf("-> MIKRO_MoveTo \n"); |
MIKRO_Set(node,"la", dest); |
MIKRO_Cmd(node,"mv"); |
while (MIKRO_GetStat(node)&1) Delay(0.1); |
return 0; |
} |
int _VI_FUNC MIKRO_GetPosition (int node, int pos[]) |
{ |
MIKRO_Get(node,"pos",pos); |
return 0; |
} |
void _VI_FUNC MIKRO_Close (void) |
{ |
CloseCom (MIKRO_Port); |
} |
/lab/sipmscan/trunk/MIKRO/MIKRO.h |
---|
0,0 → 1,21 |
#define _VI_FUNC |
int _VI_FUNC MIKRO_Open (char *dev); |
int _VI_FUNC MIKRO_Reset (int node); |
int _VI_FUNC MIKRO_Init (int node, int type); |
int _VI_FUNC MIKRO_ReferenceMove (int node); |
int _VI_FUNC MIKRO_MoveFor (int node, int dist); |
int _VI_FUNC MIKRO_MoveTo (int node, int dest); |
int _VI_FUNC MIKRO_GetPosition (int node, int pos[]); |
int _VI_FUNC MIKRO_SetZero (char axes); |
int _VI_FUNC MIKRO_SetPlain (char axes); |
void _VI_FUNC MIKRO_Close (void); |
/lab/sipmscan/trunk/MIKRO/Makefile |
---|
0,0 → 1,4 |
mikro_ctrl: mikro_ctrl.c rs232.c rs232.h MIKRO.c |
gcc mikro_ctrl.c rs232.c MIKRO.c -o mikro_ctrl -lm |
mikro_ctrl_d: mikro_ctrl.c rs232.c rs232.h MIKRO.c |
gcc mikro_ctrl.c rs232.c MIKRO.c -o mikro_ctrl_d -lm -DDEBUG |
/lab/sipmscan/trunk/MIKRO/mikro_ctrl |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: sipmscan/trunk/MIKRO/mikro_ctrl.c |
=================================================================== |
--- sipmscan/trunk/MIKRO/mikro_ctrl.c (nonexistent) |
+++ sipmscan/trunk/MIKRO/mikro_ctrl.c (revision 118) |
@@ -0,0 +1,148 @@ |
+#include <stdlib.h> |
+#include <stdio.h> |
+#include "MIKRO.h" |
+ |
+ |
+#include <getopt.h> |
+ |
+#define MIKRO_COM "/dev/ttyUSB0" |
+ |
+int help(){ |
+ fprintf(stderr,"Usage: mikro [-i node][-n node] [-u up] [-d down] [-r node] [-h node] [-a] [-g] [-m pos]\n"); |
+ fprintf(stderr," Options:\n"); |
+ fprintf(stderr,"[-n node] -i type .. initialize node + save to EEPROM\n"); |
+ fprintf(stderr," (1=3MLin,2=3MRot,3=4MLin,4=4MRot,0=skip\n"); |
+ fprintf(stderr," -n node -h .. homing procedure for node\n"); |
+ fprintf(stderr," -n node -r .. reset node\n"); |
+ fprintf(stderr," -n node -u .. move node for +1000\n"); |
+ fprintf(stderr," -n node -d .. move node for -1000\n"); |
+ fprintf(stderr,"[-n node] -a .. current status of the nodes\n"); |
+ fprintf(stderr," -n node -v value -s cmd .. set value of the cmd on the node\n"); |
+ fprintf(stderr," -n node -g cmd .. get value of the cmd on the node\n"); |
+ fprintf(stderr," -n node -m position .. move node to position\n"); |
+ fprintf(stderr," -l delaysec .. loop test with the delay delaysec\n"); |
+ return 0; |
+} |
+ |
+int main (int argc, char ** argv){ |
+ int i,j,k; |
+ int node=0,opt,value=0,itype=0; |
+ int nr_nodes=3; |
+ int ierr; |
+ int pos,xpos,ypos,zpos; |
+ char custcmd[20]; |
+ char statbits[16][10]={"Moving","In-Pos","Mode","AMN Mode","%Done","DNet","DNErr","FD-Error", |
+ "Disable","R-Lim","Local","Estop","Event1","P-Lim","Event2","N-Lim"}; |
+ |
+ MIKRO_Open (MIKRO_COM); |
+ |
+ // ":" just indicates that this option needs an argument |
+ while ((opt = getopt(argc, argv, "i:av:s:l:udn:c:pm:g:hre")) != -1) { |
+ switch (opt) { |
+ case 'i': |
+ itype = atoi(optarg); |
+ if(node != 0) |
+ MIKRO_Init (node,itype); |
+ else |
+ for(i=1; i<nr_nodes+1; i++) MIKRO_Init (i,itype); |
+ break; |
+ case 'a': |
+ if(node != 0) { |
+ pos=0; |
+ ierr=MIKRO_GetStat(node); |
+ MIKRO_GetPosition (node, &pos); |
+ printf("node %d position %d status =%04x\n",node,pos,ierr); |
+ for(i=0; i<16; i++){ |
+ printf("%d: %s\n", (ierr&1),statbits[i]); |
+ ierr>>=1; |
+ } |
+ }else{ |
+ pos=0; |
+ for (j=1;j<nr_nodes+1;j++){ |
+ ierr=MIKRO_GetStat(j); |
+ MIKRO_GetPosition (j, &pos); |
+ printf("node %d position %d status =%04x\n",j,pos,ierr); |
+ for(i=0; i<16; i++){ |
+ printf("%d: %s\n", (ierr&1),statbits[i]); |
+ ierr>>=1; |
+ } |
+ } |
+ } |
+ break; |
+ case 'l': |
+ printf("MIKRO_MoveTo Loop\n"); |
+ for (i=0;i<5;i++){ |
+ xpos=i*1000+10000; |
+ MIKRO_MoveTo (1, xpos); |
+ for (j=0;j<5;j++){ |
+ ypos=j*1000+10000; |
+ MIKRO_MoveTo (2, ypos); |
+ for (k=0;k<50;k++){ |
+ zpos=k*1000+10000; |
+ MIKRO_MoveTo (3, zpos); |
+ printf("x=%d y=%d z=%d\n",xpos,ypos,zpos); |
+ Delay(atof(optarg)); |
+ } |
+ } |
+ } |
+ break; |
+ case 'n': |
+ node = atoi(optarg); |
+ break; |
+ case 'm': |
+ MIKRO_MoveTo (node, atoi(optarg)); |
+ printf("MIKRO_MoveTo node=%d pos=%d \n",node,atoi(optarg)); |
+ MIKRO_GetPosition (node, &i); |
+ printf("node %d position %d \n",node,i); |
+ break; |
+ case 'v': |
+ value=atoi(optarg); |
+ break; |
+ case 's': |
+ MIKRO_Set (node,optarg,value); |
+ printf("MIKRO_Set node %d cmd=%s val=%d\n",node,optarg, value); |
+ break; |
+ case 'g': |
+ MIKRO_Get (node,optarg,&i); |
+ printf("MIKRO_Get node %d cmd=%s val=%d\n",node,optarg, i); |
+ break; |
+ case 'h': |
+ printf("MIKRO_ReferenceMove node=%d\n",node); |
+ MIKRO_ReferenceMove (node); |
+ break; |
+ case 'r': |
+ printf("MIKRO_Reset node=%d\n",node); |
+ MIKRO_Reset (node); |
+ break; |
+ case 'u': |
+ MIKRO_Set(node,"lr", 1000); |
+ MIKRO_Cmd(node,"mv"); |
+ break; |
+ case 'd': |
+ MIKRO_Set(node,"lr", -1000); |
+ MIKRO_Cmd(node,"mv"); |
+ break; |
+ case 'e': |
+ MIKRO_Cmd(node,"ab"); |
+ MIKRO_Cmd(node,"n 2"); |
+ MIKRO_Cmd(node,"en"); |
+ break; |
+ case 'c': // cust. com. |
+ sprintf(custcmd,"%s",optarg); |
+ MIKRO_Cmd(node,custcmd); |
+ break; |
+ case 'p': // get pos. |
+ if(node != 0){ |
+ MIKRO_GetPosition (node, &pos); |
+ printf("%d\n",pos); |
+ } |
+ break; |
+ default: // '?' |
+ help(); |
+ break; |
+ } |
+ } |
+ if (argc==1) help(); |
+ MIKRO_Close (); |
+ return 0; |
+} |
Index: sipmscan/trunk/MIKRO/mikro_ctrl_d |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/sipmscan/trunk/MIKRO/mikro_ctrl_d |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: sipmscan/trunk/MIKRO/quick_scan.sh |
=================================================================== |
--- sipmscan/trunk/MIKRO/quick_scan.sh (nonexistent) |
+++ sipmscan/trunk/MIKRO/quick_scan.sh (revision 118) |
@@ -0,0 +1,15 @@ |
+#! /bin/bash |
+ |
+#fname=$1 |
+#num_events=$2 |
+ |
+#./addheader $fname 1 $num_events 0 0 0 0 0 0 |
+#./addheader $fname 3 0 0 0 0 0 0 |
+#./daq $fname $num_events |
+#./addheader $fname 2 |
+ |
+position=`./mikro_ctrl -a | grep -o '[[:digit:]]*' | awk -F : '{if(NR==2 || NR==5){print $1}}'` |
+#pos_x=${position}[0] |
+#pos_y=${position}[1] |
+#echo "position x = " $pos_x " position y = " $pos_y |
+echo $position >> test.txt |
Index: sipmscan/trunk/MIKRO/rs232.c |
=================================================================== |
--- sipmscan/trunk/MIKRO/rs232.c (nonexistent) |
+++ sipmscan/trunk/MIKRO/rs232.c (revision 118) |
@@ -0,0 +1,125 @@ |
+#include <sys/stat.h> |
+#include <fcntl.h> |
+#include <string.h> |
+#include <termios.h> |
+ |
+#include "rs232.h" |
+//#define DEBUG |
+ |
+const int debug=0; |
+ |
+struct termios tattr; |
+ |
+int Delay(double sec){ |
+ return usleep((int) (sec*1e6) ); |
+} |
+ |
+int SetComTime(int fd, double timeout_seconds){ |
+ |
+ int ntenth; |
+ |
+ ntenth = (int)(timeout_seconds*10); |
+ tattr.c_cc[VTIME] = ntenth; |
+ tcsetattr(fd, TCSANOW, &tattr); |
+#ifdef DEBUG |
+ printf("SetComTime: %d\n", ntenth); |
+#endif |
+ return 0; |
+} |
+ |
+int FlushInQ(int fd){ |
+ return 0; |
+} |
+ |
+int FlushOutQ(int fd){ |
+ return 0; |
+} |
+ |
+int ComWrt (int fd, char* cmd, int Count ){ |
+ |
+ int nwr; |
+ |
+ nwr=write(fd, cmd, Count); |
+#ifdef DEBUG |
+ printf ( "ComWrt: %d, %d, %s\n", Count, nwr, cmd); |
+#endif |
+ return nwr; |
+} |
+ |
+int ComRdTerm (int fd, char *response, int nb, int termchar) |
+{ |
+ |
+ int nread, nloop; |
+ |
+ nread=0; |
+ nloop=0; |
+ |
+#ifdef DEBUG |
+ printf ( "ComRdTerm start\n") ; |
+#endif |
+// rewind(fpr); |
+ while (1) { |
+ if (nloop++ == nb) return -1; |
+// nread += read ( fd, response+nread, nb-nread ); |
+ nread += read ( fd, response+nread, 1 ); |
+#ifdef DEBUG |
+ response[nread]=0; |
+ printf ("ComRdTerm nread: %d %d %s\n", nloop, nread, response) ; |
+#endif |
+ if (nread>1) if(response[nread-1] == termchar) break; |
+ } |
+ |
+ nread = nread - 2; |
+ response[nread]=0; |
+#ifdef DEBUG |
+ printf("CmdRdTerm: %s\n",response); |
+#endif |
+ return nread; |
+} |
+ |
+int OpenComConfig( char *dev, char * device_name, long Baud_Rate, int Parity, int Data_Bits, |
+ int Stop_Bits, int Input_Queue_Size, int Output_Queue_Size ){ |
+ |
+ int fd; |
+ |
+ memset (&tattr, 0, sizeof tattr); |
+ |
+ fd=open(dev, O_RDWR | O_NOCTTY | O_SYNC); |
+// see 'man tcsetattr' |
+ tcgetattr (fd, &tattr); |
+ cfmakeraw(&tattr); |
+ cfsetspeed(&tattr, B38400); |
+// cfsetispeed(&tattr, B38400); |
+// cfsetospeed(&tattr, B38400); |
+// input modes |
+ tattr.c_iflag&=~IGNBRK; |
+ tattr.c_iflag&=~(IGNCR | ICRNL | INLCR); |
+ tattr.c_iflag&=~(IXON | IXOFF | IXANY); |
+// output modess |
+ tattr.c_oflag=0; |
+// local modes |
+ tattr.c_lflag=0; |
+ tattr.c_lflag &= ~(ICANON|ECHO) ; // canonical mode and echo input char |
+// control modes |
+ tattr.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, |
+ // enable reading |
+ tattr.c_cflag &= ~(PARENB | PARODD); // shut off parity |
+ tattr.c_cflag &= ~CSTOPB; // set two stop bits |
+ tattr.c_cflag &= ~CRTSCTS; // enable RTS/CTS flow control |
+ |
+ tattr.c_cc[VMIN] = 0; |
+ tattr.c_cc[VTIME] = 2; |
+ tcsetattr(fd, TCSAFLUSH, &tattr); |
+ |
+#ifdef DEBUG |
+ printf("OpenComConfig\n"); |
+#endif |
+ return fd; ; |
+} |
+ |
+ |
+int CloseCom (int fd){ |
+ |
+ close(fd); |
+ return; |
+} |
Index: sipmscan/trunk/MIKRO/rs232.h |
=================================================================== |
--- sipmscan/trunk/MIKRO/rs232.h (nonexistent) |
+++ sipmscan/trunk/MIKRO/rs232.h (revision 118) |
@@ -0,0 +1,20 @@ |
+#ifndef _RS232_H_ |
+#define _RS232_H_ |
+#include <stdlib.h> |
+#include <stdio.h> |
+ |
+#define LWRS_HWHANDSHAKE_OFF 0 |
+#define LWRS_HWHANDSHAKE_CTS_RTS_DTR 1 |
+#define LWRS_HWHANDSHAKE_CTS_RTS 2 |
+ |
+int Delay(double seconds); |
+int FlushInQ(int fd); |
+int FlushOutQ(int fd); |
+int ComWrt (int fd, char* cmd, int Count ) ; |
+int ComRdTerm (int fd, char* result, int count, int termchar ); |
+int OpenComConfig(char *dev, char * device_name, long Baud_Rate, int Parity, int Data_Bits, |
+ int Stop_Bits, int Input_Queue_Size, int Output_Queue_Size ); |
+int CloseCom (int fd); |
+int SetComTime(int fd, double timeout_seconds); |
+#endif |
+ |
Index: sipmscan/trunk/MIKRO/test.txt |
=================================================================== |
--- sipmscan/trunk/MIKRO/test.txt (nonexistent) |
+++ sipmscan/trunk/MIKRO/test.txt (revision 118) |
@@ -0,0 +1,4 @@ |
+125877 50001 |
+0 3 |
+0 3 |
+0 3 |
Index: sipmscan/trunk/configure |
=================================================================== |
--- sipmscan/trunk/configure (nonexistent) |
+++ sipmscan/trunk/configure (revision 118) |
@@ -0,0 +1,199 @@ |
+#!/bin/bash |
+ |
+function helptext() |
+{ |
+ echo "#------------------------------" |
+ echo "# Configure instructions: -----" |
+ echo "#------------------------------" |
+ echo "" |
+ echo "./configure [option] [type]" |
+ echo "" |
+ echo "[option] = Option for configure:" |
+ echo " - help = Display configure instructions." |
+ echo " - nomake = Only prepare workstation.h file (base directory and online/offline mode)." |
+ echo " - all = Prepare workstation.h file and set used libraries." |
+ echo " - clean = Clean the installation directory." |
+ echo " - compress = Compress the source code in a tar-ball." |
+ echo "" |
+ echo "[type] = Configure for use in online or offline mode (only needed in nomake and all):" |
+ echo " - I = Online mode." |
+ echo " - O = Offline mode (no connection to CAMAC, motor, voltage supply and scope)." |
+ echo "" |
+ echo "#------------------------------" |
+} |
+ |
+# Check for arguments |
+if [ "$1" == "" ]; then |
+ echo "Error! No arguments supplied." |
+ echo "" |
+ helptext |
+ exit 1 |
+else |
+ # When using help, only display help and then exit |
+ if [ "$1" == "help" ]; then |
+ helptext |
+ exit 0 |
+ fi |
+ |
+ # Print help and exit if we give a wrong first argument |
+ if [ "$1" != "nomake" ] && [ "$1" != "all" ] && [ "$1" != "clean" ] && [ "$1" != "compress" ]; then |
+ echo "Error! Wrong configuration option selected (first argument)." |
+ echo "" |
+ helptext |
+ exit 1 |
+ fi |
+ |
+ startdir=$PWD |
+ |
+ ostype=`uname -p` |
+ |
+ # Compiles the table microcontroller program |
+ if [ "$1" == "all" ]; then |
+ if [ -d $startdir/MIKRO ]; then |
+ cd $startdir/MIKRO |
+ rm -f $startdir/MIKRO/mikro_ctrl |
+ make |
+ cd $startdir |
+ fi |
+ fi |
+ |
+ # When using compress, only create a tar-ball and then exit |
+ if [ "$1" == "compress" ]; then |
+ cd $startdir |
+ if [ ! -d $startdir/camac_gui_windowed ]; then |
+ mkdir $startdir/camac_gui_windowed |
+ mkdir $startdir/camac_gui_windowed/results |
+ echo "Copying source files to temporary directory $startdir/camac_gui_windowed..." |
+ cp -r configure daq.h daqscope.h GuiLinkDef.h libxxusb.cpp libxxusb.h libxxusb.o root_include.h start.cxx usb.h windowed_test.C windowed_test.h wusbcc.h wusbxx_dll.c wusbxx_dll.h wusbxx_dll.o mpod/ MIKRO/ vxi11_x86_64/ vxi11_i686/ input/ ./camac_gui_windowed/ |
+ cd $startdir/camac_gui_windowed |
+ echo "Cleaning the base directory in $startdir/camac_gui_windowed..." |
+ rm -f *.bak |
+ cd $startdir/camac_gui_windowed/input |
+ echo "Cleaning the input directory in $startdir/camac_gui_windowed/input..." |
+ rm -f *.bak |
+ cd $startdir/camac_gui_windowed/vxi11_x86_64 |
+ echo "Cleaning the 64 bit VXI11 directory in $startdir/camac_gui_windowed/vxi11_x86_64..." |
+ rm -f *.bak |
+ make clean |
+ cd $startdir/camac_gui_windowed/vxi11_i686 |
+ echo "Cleaning the 32 bit VXI11 directory in $startdir/camac_gui_windowed/vxi11_i686..." |
+ rm -f *.bak |
+ make clean |
+ cd $startdir |
+ echo "Creating a tar-ball camac_gui_windowed.tar.gz..." |
+ tar czf $startdir/camac_gui_windowed.tar.gz ./camac_gui_windowed |
+ echo "Removing the temporary directory $startdir/camac_gui_windowed..." |
+ rm -r $startdir/camac_gui_windowed |
+ exit 0 |
+ else |
+ echo "Error! Directory ./camac_gui_windowed already exists." |
+ exit 1 |
+ fi |
+ fi |
+ |
+ # Configure the workstation information and directory of program (0 if we find something and 1 otherwise) |
+ basedir=$(echo $startdir | sed 's/\//\\\//g') |
+ |
+ if [ "$1" == "nomake" ] || [ "$1" == "all" ]; then |
+ if [ "$2" == "O" ] || [ "$2" == "I" ]; then |
+ grep -q "#define WORKSTAT 'N'" $startdir/input/workstation.h.in |
+ if [ $? == 0 ]; then |
+ sed "s/define WORKSTAT 'N'/define WORKSTAT '$2'/" $startdir/input/workstation.h.in > $startdir/workstation.h.mid |
+ fi |
+ grep -q "#define rootdir \"path-to-installation\"" $startdir/input/workstation.h.in |
+ if [ $? == 0 ]; then |
+ sed "s/path-to-installation/$basedir/g" $startdir/workstation.h.mid > $startdir/workstation.h |
+ rm $startdir/workstation.h.mid |
+ fi |
+ grep -q "#include \"vxi11_user.h\"" $startdir/input/daqscope.C.in |
+ if [ $? == 0 ]; then |
+ sed "s/vxi11_user.h/.\/vxi11_$ostype\/vxi11_user.h/g" $startdir/input/daqscope.C.in > $startdir/daqscope.C |
+ fi |
+ grep -q "SHLIB = \$(LIBFILE) libvxi11.a" $startdir/input/Makefile.in |
+ if [ $? == 0 ]; then |
+ if [ "$2" == "I" ]; then |
+ sed "s/SHLIB = \$(LIBFILE) libvxi11.a/SHLIB = \$(LIBFILE) libvxi11.a -lusb/g" $startdir/input/Makefile.in > $startdir/Makefile.mid |
+ fi |
+ fi |
+ grep -q "CAMLIB = \$(LIBFILE)" $startdir/input/Makefile.in |
+ if [ $? == 0 ]; then |
+ if [ "$2" == "I" ]; then |
+ sed "s/CAMLIB = \$(LIBFILE)/CAMLIB = \$(LIBFILE) -lusb/g" $startdir/Makefile.mid > $startdir/Makefile |
+ rm $startdir/Makefile.mid |
+ elif [ "$2" == "O" ]; then |
+ cp $startdir/input/Makefile.in $startdir/Makefile |
+ fi |
+ fi |
+ |
+ if [ "$2" == "O" ]; then |
+ cp $startdir/input/daqusb.C.offline $startdir/daqusb.C |
+ cp $startdir/input/start.sh.offline $startdir/start.sh |
+ elif [ "$2" == "I" ]; then |
+ cp $startdir/input/daqusb.C.online $startdir/daqusb.C |
+ cp $startdir/input/start.sh.online $startdir/start.sh |
+ fi |
+ fi |
+ fi |
+ |
+ # In case we just want to set the workstation information, exit here |
+ if [ "$1" == "nomake" ]; then |
+ exit 0 |
+ fi |
+ |
+ # 64 bit configuration rules |
+ if [ $ostype == "x86_64" ]; then |
+ vxidir=$startdir/vxi11_$ostype |
+ if [ -d $vxidir ]; then |
+ cd $vxidir |
+ if [ "$1" == "clean" ]; then |
+ make clean |
+ cd $startdir |
+ make clean |
+ rm -f Makefile |
+ else |
+ if [ "$2" == "O" ] || [ "$2" == "I" ]; then |
+ make |
+ else |
+ echo "Error! No configuration type selected (second argument)." |
+ echo "" |
+ helptext |
+ exit 1 |
+ fi |
+ fi |
+ cd $startdir |
+ else |
+ echo "No 64 bit VXI11 source folder." |
+ exit 1 |
+ fi |
+ # 32 bit configuration rules |
+ elif [ $ostype == "i686" ]; then |
+ vxidir=$startdir/vxi11_$ostype |
+ if [ -d $vxidir ]; then |
+ cd $vxidir |
+ if [ "$1" == "clean" ]; then |
+ make clean |
+ cd $startdir |
+ make clean |
+ rm -f Makefile |
+ else |
+ if [ "$2" == "O" ] || [ "$2" == "I" ]; then |
+ make |
+ else |
+ echo "Error! No installation type selected (second argument)." |
+ echo "" |
+ helptext |
+ exit 1 |
+ fi |
+ fi |
+ cd $startdir |
+ else |
+ echo "No 32 bit VXI11 source folder." |
+ exit 1 |
+ fi |
+ else |
+ echo "No OS type information found." |
+ exit 1 |
+ fi |
+fi |
+ |
+exit 0 |
/sipmscan/trunk/configure |
---|
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Index: sipmscan/trunk/daq.h |
=================================================================== |
--- sipmscan/trunk/daq.h (nonexistent) |
+++ sipmscan/trunk/daq.h (revision 118) |
@@ -0,0 +1,28 @@ |
+#ifndef _daq_h_ |
+#define _daq_h_ |
+ |
+#define BUFF_L 2048 |
+ |
+// Number of channels we are using (used only if we run daqusb.C, not the GUI version) |
+#define NTDC 1 /* TDC */ |
+#define NTDCCH 1 |
+#define NADC 2 /* ADC */ |
+#define NADCCH 1 |
+ |
+// Class for measurement process (DAQ for CAMAC) |
+class daq |
+{ |
+public: |
+ unsigned long stackwrite[BUFF_L],stackdata[10000],stackdump[27000]; |
+ int fStop; |
+ int connect(); |
+ int init(); |
+ int start(); |
+ int event(unsigned int *, int); |
+ int stop(); |
+ int disconnect(); |
+ daq(); |
+ ~daq(); |
+}; |
+ |
+#endif |
Index: sipmscan/trunk/daqscope.h |
=================================================================== |
--- sipmscan/trunk/daqscope.h (nonexistent) |
+++ sipmscan/trunk/daqscope.h (revision 118) |
@@ -0,0 +1,62 @@ |
+#ifndef _daqscope_h_ |
+#define _daqscope_h_ |
+ |
+#define WAVE_LEN 100000 |
+ |
+//class VmUsbStack; |
+class daqscope { |
+public: |
+// VmUsbStack * fStack; |
+// VmUsbStack * fInit; |
+ |
+ int OSrepetition; |
+ int OSmeasu; |
+ int OSmeasuchan; |
+ int OSgating; |
+ int OSsaving; |
+ int OSinf; |
+ int nmeaslc; |
+ char OSchannels[1024]; |
+ char IP[1024]; |
+ char lecroycmd[1024]; |
+ char lecroycmd2[1024]; |
+ char lecroywfm[1024]; |
+ int lecroystate; |
+ char pch[1024]; |
+ char lecroyadd[1024]; |
+ char multibuf[WAVE_LEN]; |
+ char eventbuf[WAVE_LEN]; |
+ double tektime,tekvolt,lctime,lcvolt; |
+ int fastacqstate; /* GKM - variable that saves the fastacq state */ |
+ double choffset; /* GKM - position offset for signal */ |
+ |
+ int fPoints; |
+ int fStop; |
+ int fMode; |
+ int clear(); |
+ int end(); |
+ int event(); |
+ int lecroyevent(); |
+ void measurement(float&); |
+ void measulecroy(float&); |
+ void measumult(); |
+ int init(); |
+ int initlecroy(); |
+ int connect(char* IPaddr); |
+ int disconnect(char* IPaddr); |
+ void fileopen(const char*); |
+ void fileclose(); |
+ void countcontrol(); |
+ void fastacq(int setting); /* GKM - gets tek out of fastacq*/ |
+ void header(); |
+ void measuheader(); |
+ void lecroyheader(); |
+ void lecroywave(); |
+ double tekunit(char*); |
+ double lcunit(char*); |
+ daqscope(); |
+// daqscope(const char *); |
+ ~daqscope(); |
+}; |
+ |
+#endif |
Index: sipmscan/trunk/input/Makefile.in |
=================================================================== |
--- sipmscan/trunk/input/Makefile.in (nonexistent) |
+++ sipmscan/trunk/input/Makefile.in (revision 118) |
@@ -0,0 +1,99 @@ |
+# Make variables ---------------------------------------------------- |
+ |
+# ROOT include and libraries |
+ROOTINC=$(shell root-config --incdir ) |
+ROOTLIB=$(shell root-config --libs ) |
+LIBS1=$(shell root-config --cflags --glibs ) |
+ |
+# Includes, 32 vs. 64 bit type, libraries |
+INC=-I. -I$(ROOTINC) |
+OSTYPE = $(shell uname -p) |
+LIBS=$(ROOTLIB) -L./ -lm |
+ |
+# Source and debug prefixes |
+SRC = . |
+DBG = |
+ |
+# CAMAC DAQ library variables |
+OBJ_FILES = wusbxx_dll.o libxxusb.o |
+LIBFILE = libdaqusb.a |
+ |
+# Specific variables for the main program |
+TARGET = windowed_test |
+DAQFILE = $(SRC)/daqusb.C |
+FILES = $(SRC)/daqusb.C $(SRC)/windowed_test.C $(SRC)/daqscope.C |
+HEADER = daq.h workstation.h root_include.h windowed_test.h |
+CAMLIB = $(LIBFILE) |
+SHLIB = $(LIBFILE) libvxi11.a |
+ |
+# VXI scope connection variables, Scope DAQ library variables |
+VXIDIR = ./vxi11_$(OSTYPE) |
+#VXI_FILES = $(VXIDIR)/vxi11_user.o $(VXIDIR)/vxi11.h $(VXIDIR)/vxi11_clnt.c $(VXIDIR)/vxi11_xdr.c |
+VXI_OBJECT = $(VXIDIR)/vxi11_user.o $(VXIDIR)/vxi11_clnt.o $(VXIDIR)/vxi11_xdr.o |
+# ----------------------------------------------------------------------------- |
+ |
+# Base rules ------------------------------------------------------------------ |
+ |
+# Make the main program and libraries |
+all: $(TARGET) libdaqusb.so libvxi11.so |
+ |
+# Rules for making the main program |
+$(TARGET): $(FILES) workstation.h daq.h library $(SHLIB) |
+ @echo "Generating dictionary Dict.C..." |
+ rootcint -f GuiDict.C -c $(INC) $(CPPFLAGS) windowed_test.h GuiLinkDef.h |
+ $(CXX) $(INC) -DG__DICTIONARY -fPIC -g -Wall $(FILES) GuiDict.C $(CPPFLAGS) $(VXI_OBJECT) -o $(TARGET) $(SHLIB) $(LIBS1) -lstdc++ -lSpectrum |
+# ----------------------------------------------------------------------------- |
+ |
+# CAMAC DAQ library rules ----------------------------------------------------- |
+ |
+# Rules for making CAMAC DAQ library source files (wusbxx_dll and libxxusb) |
+library: $(OBJ_FILES) |
+ |
+wusbxx_dll.o:wusbxx_dll.c wusbxx_dll.h |
+libxxusb.o: libxxusb.cpp libxxusb.h |
+ |
+.cc.o: |
+ $(CXX) -c $< |
+ ar r $(LIBFILE) $@ |
+ |
+.cpp.o: |
+ $(CXX) -c $< |
+ ar r $(LIBFILE) $@ |
+ |
+.c.o: |
+ $(CXX) -c $< |
+ ar r $(LIBFILE) $@ |
+ |
+# Rules for recreating the CAMAC DAQ libraries even if they exist (libdaqusb.so/.a) |
+relib: |
+ rm -f libdaqusb.so libdaqusb.a libvxi11.so libvxi11.a |
+ make libdaqusb.so libvxi11.so |
+ |
+# Rule for making the CAMAC DAQ library (libdaqusb.so) |
+libdaqusb.so: $(DAQFILE) $(LIBFILE) |
+ @echo "Generating dictionary Dict.C..." |
+ rootcint -f Dict.C -c $(INC) $(CPPFLAGS) $(HEADER) GuiLinkDef.h |
+ $(CXX) -DG__DICTIONARY $(CPPFLAGS) $(INC) -fPIC -g -Wall $(DAQFILE) Dict.C $(CAMLIB) -shared -o $@ |
+ |
+# Rule for making the CAMAC DAQ library (libdaqusb.a) |
+$(LIBFILE): $(OBJ_FILES) |
+ ar r $@ $^ |
+# ----------------------------------------------------------------------------- |
+ |
+# Scope DAQ library rules ----------------------------------------------------- |
+ |
+libvxi11.so: libvxi11.a |
+ @echo "Generating dictionary VxiDict.C..." |
+ rootcint -f VxiDict.C -c $(INC) $(CPPFLAGS) daqscope.h GuiLinkDef.h |
+ $(CXX) -DG__DICTIONARY $(CPPFLAGS) $(INC) -fPIC -g -Wall daqscope.C VxiDict.C -L. libvxi11.a -shared -o $@ |
+ |
+libvxi11.a: $(VXI_OBJECT) |
+ ar r $@ $^ |
+# ----------------------------------------------------------------------------- |
+ |
+# Clean rule ------------------------------------------------------------------ |
+ |
+# Rule for cleaning the installation |
+clean: |
+ rm -f Dict.C Dict.h GuiDict.C GuiDict.h windowed_test windowed_test_C.d windowed_test_C.so curpos.txt curvolt.txt workstation.h VxiDict.C VxiDict.h daqscope.C daqusb.C start.sh |
+# ----------------------------------------------------------------------------- |
Index: sipmscan/trunk/input/daqscope.C.in |
=================================================================== |
--- sipmscan/trunk/input/daqscope.C.in (nonexistent) |
+++ sipmscan/trunk/input/daqscope.C.in (revision 118) |
@@ -0,0 +1,44 @@ |
+#include <stdio.h> |
+#include <stdlib.h> |
+ |
+#include "vxi11_user.h" |
+#include "daqscope.h" |
+ |
+CLINK *clink; |
+char *savedIP; |
+ |
+int daqscope::connect(char *IPaddr) |
+{ |
+ int iTemp; |
+ char buf[WAVE_LEN]; |
+ clink = new CLINK; |
+ iTemp = vxi11_open_device(IPaddr, clink); |
+ if(iTemp == 0) |
+ { |
+ vxi11_send(clink, "*IDN?"); |
+ vxi11_receive(clink, buf, WAVE_LEN); |
+ printf("Connected to device (%s): %s\n", IPaddr, buf); |
+ savedIP = IPaddr; |
+ return iTemp; |
+ } |
+ else |
+ return iTemp; |
+} |
+ |
+int daqscope::disconnect(char *IPaddr) |
+{ |
+ int iTemp; |
+ iTemp = vxi11_close_device(IPaddr, clink); |
+ if(iTemp == 0) |
+ printf("Disconnected from device (%s).\n", IPaddr); |
+ delete clink; |
+ return iTemp; |
+} |
+ |
+daqscope::daqscope() { |
+ fStop=0; |
+} |
+ |
+daqscope::~daqscope() { |
+ disconnect(savedIP); |
+} |
Index: sipmscan/trunk/input/daqusb.C.offline |
=================================================================== |
--- sipmscan/trunk/input/daqusb.C.offline (nonexistent) |
+++ sipmscan/trunk/input/daqusb.C.offline (revision 118) |
@@ -0,0 +1,243 @@ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <unistd.h> |
+#include <sys/mman.h> |
+#include <errno.h> |
+#include <signal.h> |
+#include <ctype.h> |
+#include <time.h> |
+//#include "wusbxx_dll.h" /* the header of the shared library */ |
+#include "daq.h" |
+ |
+//#define DEBUG /* vkljuci dodatni izpis */ |
+#ifdef DEBUG |
+ #define DBG(X) X |
+ #define DBGFUNI(X) printf(">>> %s -> %d\n",#X,(X)) |
+#else |
+ #define DBG(X) |
+ #define DBGFUNI(X) X |
+#endif |
+ |
+/* definiram lokacije enot*/ |
+//#define NTDC 1 /* TDC */ |
+//#define NTDCCH 8 |
+//#define NADC 2 /* ADC */ |
+//#define NADCCH 8 |
+int ctrlc=0; |
+char *ccserial="CC0126"; |
+int devDetect; // variable to tell if we detect any devices |
+ |
+int daq::connect(){ |
+// odpri daq |
+/* xxusb_device_type devices[100]; |
+ //struct usb_device *dev; |
+ devDetect = xxusb_devices_find(devices); |
+// printf("Detected devices: %d\n", devDetect); |
+ //dev = devices[0].usbdev; |
+ //udev = xxusb_device_open(dev); |
+ |
+ if(devDetect > 0) |
+ { |
+ WUSBXX_load(NULL); |
+ WUSBXX_open(ccserial); |
+ printf("daq::connect()\n"); |
+ } |
+ else |
+*/ printf("daq::connect() - No devices were detected!\n"); |
+ return 0; |
+} |
+ |
+int daq::init(){ |
+ |
+ int i; |
+ long k; |
+ |
+/* DBGFUNI(xxusb_register_write(udev,1,0x0)); // Stop DAQ mode |
+ while (xxusb_usbfifo_read(udev, (int*) stackdump,BUFF_L,100)>0); |
+ |
+ CCCZ; |
+ CCCC; |
+ CREM_I; |
+ |
+// create command stack for the TDC and ADC |
+ k=1; |
+ for(i=0;(i<NTDCCH)&&(i<NADCCH);i++) { stackwrite[k++]=NAF(NTDC,i,0); stackwrite[k++]=NAF(NADC,i,0); } |
+// for(i=0;i<NADCCH;i++) stackwrite[k++]=NAF(NADC,i,0); |
+ stackwrite[k++]=NAF(NTDC,0,9); |
+ stackwrite[k++]=NAF(NADC,0,9); |
+ stackwrite[k++]=NAFS(0,0,16); // insert next word to data |
+ stackwrite[k++]=0xfafb; // event termination word |
+ stackwrite[0]=k-1; |
+// upload stack #2 |
+ xxusb_stack_write(udev,0x2,(long int *)stackwrite); |
+ xxusb_stack_read(udev,0x2,(long int *) stackdata); |
+ DBG(for(i=0;i<k;i++) printf("0x%04x\n",stackdata[i]);) |
+ |
+ int ret[10]; |
+ |
+ CAMAC_LED_settings(udev, 1,1,0,0); |
+ ret[0] = CAMAC_register_read(udev,0,&k); |
+ printf("Firmware ID (return %d) -> 0x%08lX\n",ret[0],k); // GKM: Firmware ID (i.e. 0x72000001 = 0111 0010 0000 0000 0000 0000 0000 0001) |
+ ret[1] = CAMAC_register_read(udev,1,&k); |
+ printf("Global Mode (return %d) -> 0x%08lX\n",ret[1],k); |
+ k=(k&0xF000)|0x0005; // set buffer length: n=0..6 -> 0x10000 >> n, n=7 -> single event |
+ ret[0] = CAMAC_register_write(udev,1,k); // GKM: sets the buffer length (i.e. k=5 -> buf length=128 words) |
+ ret[1] = CAMAC_register_write(udev,2,0x80); // wait 0x80 us after trigger // GKM: delay settings in microseconds |
+ ret[2] = CAMAC_register_write(udev,3,0x0); // Scaler Readout Control Register // GKM: scaler readout settings - sets the frequency of readout (if 0, it is disabled) |
+ ret[3] = CAMAC_register_write(udev,9,0x0); // Lam Mask Register // GKM: When 0, readout is triggered by the signal on NIM input |
+ ret[4] = CAMAC_register_write(udev,14,0x0); // USB Bulk Transfer Setup Register |
+ |
+ // CAMAC_DGG(udev,1,2,3,0,200,0,0); |
+ // CAMAC_DGG(udev,0,0,0,0,100,0,0); |
+ ret[5] = CAMAC_register_write(udev,5,(0x06<<16)+(0x04<<8)+0x00); // output // GKM: NIM outputs (i.e. 0x060400 = 00 0110 0000 0100 0000 0000 -> NIM O2=DGG_B, NIM O3=DGG_A) |
+ ret[6] = CAMAC_register_write(udev,6,(0x01<<24)+(0x01<<16)+(0x0<<8)+0x0); // SCLR & DGG // GKM: device source selector (i.e. 0x01010000 = 00 0000 0001 0000 0001 0000 0000 0000 0000 -> DGG_A=NIM I1, DGG_B=NIM I1, SCLR=disabled) |
+ ret[7] = CAMAC_register_write(udev,7,(100<<16)+0); // output // GKM: Delay and Gate Generator A registers (i.e. 0x00640000 = 0000 0000 0110 0100 0000 0000 0000 0000 -> DDG_A [gate=100, delay=0]) |
+ ret[8] = CAMAC_register_write(udev,8,(10000<<16)+0); // output // GKM: Delay and Gate Generator B registers (i.e. 0x27100000 = 0010 0111 0001 0000 0000 0000 0000 0000 -> DDG_B [gate=10000, delay=0]) |
+ ret[9] = CAMAC_register_write(udev,13,0); // output // GKM: Extended (course) delay (i.e. 0x00000000 = 0 -> DDG_A ext=0, DDG_B ext=0) |
+ |
+// for(i = 0; i < 10; i++) printf("Setting %d? -> return = %d\n",i,ret[i]); |
+ |
+// ret[0] = CAMAC_register_read(udev,1,&k); |
+// printf("k (return %d) -> 0x%08lX\n",ret[0],k); |
+ |
+*/ printf("daq::init()\n"); |
+ return 0; |
+} |
+ |
+int daq::start(){ |
+// xxusb_register_write(udev,1,0x1); // Start DAQ mode |
+ printf("daq::start()\n"); |
+ return 0; |
+} |
+ |
+int daq::stop(){ |
+// xxusb_register_write(udev,1,0x0); // Stop DAQ mode |
+// while (xxusb_usbfifo_read(udev,(int *)stackdump,BUFF_L,30)>0); |
+ printf("daq::stop()\n"); |
+ return 0; |
+} |
+ |
+int daq::event(unsigned int *data, int maxn){ |
+ int i,ib,count; |
+/* int events,evsize; |
+ short ret; |
+ |
+ ib=0; |
+ ret=xxusb_usbfifo_read(udev,(int *) stackdata,BUFF_L,500); |
+ events=stackdata[ib++]; |
+ DBG(printf("ret=%d,events=0x%08x\n",ret,events);) |
+ if ((ret<0)||(ret!=(((NTDCCH+NADCCH)*4+4)*events+4))) return 0; |
+ |
+ count=0; |
+ while (ib<(ret/2-1)){ |
+ evsize = stackdata[ib++]&0xffff; |
+ DBG(printf("Event:%d EvSize:%d\n", events, evsize);) |
+ for (int i=0;i<(NTDCCH+NADCCH);i++,ib++) data[count++] =stackdata[ib++]&0xffff; |
+ if (stackdata[ib++]!=0xfafb){ |
+ printf("Error!\n"); |
+ return 0; |
+ } |
+ events--; |
+ if (fStop) return 0; |
+ } |
+ if (stackdata[ib++]!=0xffff){ |
+ printf("Error!\n"); |
+ return 0; |
+ } |
+*/ |
+ count = 1; |
+ return count; |
+} |
+ |
+int daq::disconnect(){ |
+// zapri daq |
+// WUSBXX_close(); |
+ printf("daq::disconnect()\n"); |
+ return 0; |
+} |
+ |
+daq::daq(){ |
+ fStop=0; |
+ connect(); |
+ if(devDetect > 0) |
+ init(); |
+} |
+ |
+daq::~daq(){ |
+disconnect(); |
+} |
+ |
+#ifdef MAIN |
+void CatchSig (int signumber) |
+{ |
+ ctrlc = 1; |
+} |
+ |
+ |
+int main (int argc, char **argv){ |
+ |
+ int neve=1000000; |
+ char *fname="test.dat"; |
+ if (argc==1) { |
+ printf("Uporaba: %s stevilo_dogodkov ime_datoteke\n",argv[0]); |
+ printf("Meritev prekini s Ctrl-C, ce je nabranih dogodkov ze dovolj\n"); |
+ exit(0); |
+ } |
+ if (argc>1) neve = atoi(argv[1]); |
+ if (argc>2) fname = argv[2]; |
+ |
+ |
+// intercept routine |
+ if (signal (SIGINT, CatchSig) == SIG_ERR) perror ("sigignore"); |
+ |
+#define BSIZE 10000 |
+ int i,ieve,nc,nb; |
+// int hdr[4]={1,(NTDCCH+4)*sizeof(int)}; // hdr[0]=1, hdr[1]=(NTDCCH+4)*4 |
+ int hdr[4]={1,(NTDCCH+NADCCH+4)*sizeof(int)}; |
+ unsigned short adc; |
+ unsigned int data[BSIZE]; |
+ daq *d= new daq(); |
+ time_t time_check; |
+ |
+// odpremo datoteko za pisanje |
+ FILE *fp=fopen(fname,"w"); |
+ |
+ d->start(); |
+ ieve=0; |
+ |
+ while((ieve<neve)&&(!ctrlc)){ |
+ nc=d->event(data,BSIZE); |
+ nb=0; |
+ while((nc>0)&&(ieve++<neve)&&(!ctrlc)){ |
+ // zapis v datoteko |
+ hdr[2]=time(NULL); |
+ hdr[3]=ieve; |
+ fwrite(hdr,sizeof(int),4 ,fp); |
+ fwrite(&data[nb],sizeof(int),(NTDCCH+NADCCH),fp); |
+// DBG( |
+ for(i=0;i<(NTDCCH+NADCCH);i++){ |
+ adc=data[nb+i]&0xFFFF; |
+ if(i % 2 == 0) |
+printf(/*"nev=%4d %d. TDC data=%d\n"*/"%d\t"/*,ieve,i*//*/2*/,adc); |
+// printf("nev=%4d %d. TDC data=%d\n",ieve,i/2,adc); |
+ else if(i % 2 == 1) |
+printf(/*"nev=%4d %d. TDC data=%d\n"*/"%d\t"/*,ieve,i*//*/2*/,adc); |
+// printf("nev=%4d %d. ADC data=%d\n",ieve,i/2,adc); |
+ } |
+printf("\n"); |
+// ) |
+ nb+=(NTDCCH+NADCCH); |
+ nc-=(NTDCCH+NADCCH); |
+ if (!(ieve%1000)) printf("event no. -> %d\n",ieve); |
+ }; |
+ }; |
+ |
+ d->stop(); |
+ fclose(fp); |
+ printf("Podatki so v datoteki %s\n", fname); |
+ delete d; |
+ |
+ return 0; |
+} |
+#endif |
Index: sipmscan/trunk/input/daqusb.C.online |
=================================================================== |
--- sipmscan/trunk/input/daqusb.C.online (nonexistent) |
+++ sipmscan/trunk/input/daqusb.C.online (revision 118) |
@@ -0,0 +1,243 @@ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <unistd.h> |
+#include <sys/mman.h> |
+#include <errno.h> |
+#include <signal.h> |
+#include <ctype.h> |
+#include <time.h> |
+#include "wusbxx_dll.h" /* the header of the shared library */ |
+#include "daq.h" |
+ |
+//#define DEBUG /* vkljuci dodatni izpis */ |
+#ifdef DEBUG |
+ #define DBG(X) X |
+ #define DBGFUNI(X) printf(">>> %s -> %d\n",#X,(X)) |
+#else |
+ #define DBG(X) |
+ #define DBGFUNI(X) X |
+#endif |
+ |
+/* definiram lokacije enot*/ |
+//#define NTDC 1 /* TDC */ |
+//#define NTDCCH 8 |
+//#define NADC 2 /* ADC */ |
+//#define NADCCH 8 |
+int ctrlc=0; |
+char *ccserial="CC0126"; |
+int devDetect; // variable to tell if we detect any devices |
+ |
+int daq::connect(){ |
+// odpri daq |
+ xxusb_device_type devices[100]; |
+ //struct usb_device *dev; |
+ devDetect = xxusb_devices_find(devices); |
+// printf("Detected devices: %d\n", devDetect); |
+ //dev = devices[0].usbdev; |
+ //udev = xxusb_device_open(dev); |
+ |
+ if(devDetect > 0) |
+ { |
+ WUSBXX_load(NULL); |
+ WUSBXX_open(ccserial); |
+ printf("daq::connect()\n"); |
+ } |
+ else |
+ printf("daq::connect() - No devices were detected!\n"); |
+ return 0; |
+} |
+ |
+int daq::init(){ |
+ |
+ int i; |
+ long k; |
+ |
+ DBGFUNI(xxusb_register_write(udev,1,0x0)); // Stop DAQ mode |
+ while (xxusb_usbfifo_read(udev, (int*) stackdump,BUFF_L,100)>0); |
+ |
+ CCCZ; |
+ CCCC; |
+ CREM_I; |
+ |
+// create command stack for the TDC and ADC |
+ k=1; |
+ for(i=0;(i<NTDCCH)&&(i<NADCCH);i++) { stackwrite[k++]=NAF(NTDC,i,0); stackwrite[k++]=NAF(NADC,i,0); } |
+// for(i=0;i<NADCCH;i++) stackwrite[k++]=NAF(NADC,i,0); |
+ stackwrite[k++]=NAF(NTDC,0,9); |
+ stackwrite[k++]=NAF(NADC,0,9); |
+ stackwrite[k++]=NAFS(0,0,16); // insert next word to data |
+ stackwrite[k++]=0xfafb; // event termination word |
+ stackwrite[0]=k-1; |
+// upload stack #2 |
+ xxusb_stack_write(udev,0x2,(long int *)stackwrite); |
+ xxusb_stack_read(udev,0x2,(long int *) stackdata); |
+ DBG(for(i=0;i<k;i++) printf("0x%04x\n",stackdata[i]);) |
+ |
+ int ret[10]; |
+ |
+ CAMAC_LED_settings(udev, 1,1,0,0); |
+ ret[0] = CAMAC_register_read(udev,0,&k); |
+ printf("Firmware ID (return %d) -> 0x%08lX\n",ret[0],k); // GKM: Firmware ID (i.e. 0x72000001 = 0111 0010 0000 0000 0000 0000 0000 0001) |
+ ret[1] = CAMAC_register_read(udev,1,&k); |
+ printf("Global Mode (return %d) -> 0x%08lX\n",ret[1],k); |
+ k=(k&0xF000)|0x0005; // set buffer length: n=0..6 -> 0x10000 >> n, n=7 -> single event |
+ ret[0] = CAMAC_register_write(udev,1,k); // GKM: sets the buffer length (i.e. k=5 -> buf length=128 words) |
+ ret[1] = CAMAC_register_write(udev,2,0x80); // wait 0x80 us after trigger // GKM: delay settings in microseconds |
+ ret[2] = CAMAC_register_write(udev,3,0x0); // Scaler Readout Control Register // GKM: scaler readout settings - sets the frequency of readout (if 0, it is disabled) |
+ ret[3] = CAMAC_register_write(udev,9,0x0); // Lam Mask Register // GKM: When 0, readout is triggered by the signal on NIM input |
+ ret[4] = CAMAC_register_write(udev,14,0x0); // USB Bulk Transfer Setup Register |
+ |
+ // CAMAC_DGG(udev,1,2,3,0,200,0,0); |
+ // CAMAC_DGG(udev,0,0,0,0,100,0,0); |
+ ret[5] = CAMAC_register_write(udev,5,(0x06<<16)+(0x04<<8)+0x00); // output // GKM: NIM outputs (i.e. 0x060400 = 00 0110 0000 0100 0000 0000 -> NIM O2=DGG_B, NIM O3=DGG_A) |
+ ret[6] = CAMAC_register_write(udev,6,(0x01<<24)+(0x01<<16)+(0x0<<8)+0x0); // SCLR & DGG // GKM: device source selector (i.e. 0x01010000 = 00 0000 0001 0000 0001 0000 0000 0000 0000 -> DGG_A=NIM I1, DGG_B=NIM I1, SCLR=disabled) |
+ ret[7] = CAMAC_register_write(udev,7,(100<<16)+0); // output // GKM: Delay and Gate Generator A registers (i.e. 0x00640000 = 0000 0000 0110 0100 0000 0000 0000 0000 -> DDG_A [gate=100, delay=0]) |
+ ret[8] = CAMAC_register_write(udev,8,(10000<<16)+0); // output // GKM: Delay and Gate Generator B registers (i.e. 0x27100000 = 0010 0111 0001 0000 0000 0000 0000 0000 -> DDG_B [gate=10000, delay=0]) |
+ ret[9] = CAMAC_register_write(udev,13,0); // output // GKM: Extended (course) delay (i.e. 0x00000000 = 0 -> DDG_A ext=0, DDG_B ext=0) |
+ |
+// for(i = 0; i < 10; i++) printf("Setting %d? -> return = %d\n",i,ret[i]); |
+ |
+// ret[0] = CAMAC_register_read(udev,1,&k); |
+// printf("k (return %d) -> 0x%08lX\n",ret[0],k); |
+ |
+ printf("daq::init()\n"); |
+ return 0; |
+} |
+ |
+int daq::start(){ |
+ xxusb_register_write(udev,1,0x1); // Start DAQ mode |
+ printf("daq::start()\n"); |
+ return 0; |
+} |
+ |
+int daq::stop(){ |
+ xxusb_register_write(udev,1,0x0); // Stop DAQ mode |
+ while (xxusb_usbfifo_read(udev,(int *)stackdump,BUFF_L,30)>0); |
+ printf("daq::stop()\n"); |
+ return 0; |
+} |
+ |
+int daq::event(unsigned int *data, int maxn){ |
+ int i,ib,count; |
+ int events,evsize; |
+ short ret; |
+ |
+ ib=0; |
+ ret=xxusb_usbfifo_read(udev,(int *) stackdata,BUFF_L,500); |
+ events=stackdata[ib++]; |
+ DBG(printf("ret=%d,events=0x%08x\n",ret,events);) |
+ if ((ret<0)||(ret!=(((NTDCCH+NADCCH)*4+4)*events+4))) return 0; |
+ |
+ count=0; |
+ while (ib<(ret/2-1)){ |
+ evsize = stackdata[ib++]&0xffff; |
+ DBG(printf("Event:%d EvSize:%d\n", events, evsize);) |
+ for (int i=0;i<(NTDCCH+NADCCH);i++,ib++) data[count++] =stackdata[ib++]&0xffff; |
+ if (stackdata[ib++]!=0xfafb){ |
+ printf("Error!\n"); |
+ return 0; |
+ } |
+ events--; |
+ if (fStop) return 0; |
+ } |
+ if (stackdata[ib++]!=0xffff){ |
+ printf("Error!\n"); |
+ return 0; |
+ } |
+ |
+// count = 1; |
+ return count; |
+} |
+ |
+int daq::disconnect(){ |
+// zapri daq |
+ WUSBXX_close(); |
+ printf("daq::disconnect()\n"); |
+ return 0; |
+} |
+ |
+daq::daq(){ |
+ fStop=0; |
+ connect(); |
+ if(devDetect > 0) |
+ init(); |
+} |
+ |
+daq::~daq(){ |
+disconnect(); |
+} |
+ |
+#ifdef MAIN |
+void CatchSig (int signumber) |
+{ |
+ ctrlc = 1; |
+} |
+ |
+ |
+int main (int argc, char **argv){ |
+ |
+ int neve=1000000; |
+ char *fname="test.dat"; |
+ if (argc==1) { |
+ printf("Uporaba: %s stevilo_dogodkov ime_datoteke\n",argv[0]); |
+ printf("Meritev prekini s Ctrl-C, ce je nabranih dogodkov ze dovolj\n"); |
+ exit(0); |
+ } |
+ if (argc>1) neve = atoi(argv[1]); |
+ if (argc>2) fname = argv[2]; |
+ |
+ |
+// intercept routine |
+ if (signal (SIGINT, CatchSig) == SIG_ERR) perror ("sigignore"); |
+ |
+#define BSIZE 10000 |
+ int i,ieve,nc,nb; |
+// int hdr[4]={1,(NTDCCH+4)*sizeof(int)}; // hdr[0]=1, hdr[1]=(NTDCCH+4)*4 |
+ int hdr[4]={1,(NTDCCH+NADCCH+4)*sizeof(int)}; |
+ unsigned short adc; |
+ unsigned int data[BSIZE]; |
+ daq *d= new daq(); |
+ time_t time_check; |
+ |
+// odpremo datoteko za pisanje |
+ FILE *fp=fopen(fname,"w"); |
+ |
+ d->start(); |
+ ieve=0; |
+ |
+ while((ieve<neve)&&(!ctrlc)){ |
+ nc=d->event(data,BSIZE); |
+ nb=0; |
+ while((nc>0)&&(ieve++<neve)&&(!ctrlc)){ |
+ // zapis v datoteko |
+ hdr[2]=time(NULL); |
+ hdr[3]=ieve; |
+ fwrite(hdr,sizeof(int),4 ,fp); |
+ fwrite(&data[nb],sizeof(int),(NTDCCH+NADCCH),fp); |
+// DBG( |
+ for(i=0;i<(NTDCCH+NADCCH);i++){ |
+ adc=data[nb+i]&0xFFFF; |
+ if(i % 2 == 0) |
+printf(/*"nev=%4d %d. TDC data=%d\n"*/"%d\t"/*,ieve,i*//*/2*/,adc); |
+// printf("nev=%4d %d. TDC data=%d\n",ieve,i/2,adc); |
+ else if(i % 2 == 1) |
+printf(/*"nev=%4d %d. TDC data=%d\n"*/"%d\t"/*,ieve,i*//*/2*/,adc); |
+// printf("nev=%4d %d. ADC data=%d\n",ieve,i/2,adc); |
+ } |
+printf("\n"); |
+// ) |
+ nb+=(NTDCCH+NADCCH); |
+ nc-=(NTDCCH+NADCCH); |
+ if (!(ieve%1000)) printf("event no. -> %d\n",ieve); |
+ }; |
+ }; |
+ |
+ d->stop(); |
+ fclose(fp); |
+ printf("Podatki so v datoteki %s\n", fname); |
+ delete d; |
+ |
+ return 0; |
+} |
+#endif |
Index: sipmscan/trunk/input/start.sh.offline |
=================================================================== |
--- sipmscan/trunk/input/start.sh.offline (nonexistent) |
+++ sipmscan/trunk/input/start.sh.offline (revision 118) |
@@ -0,0 +1,12 @@ |
+#!/bin/bash |
+dir=`dirname $0` |
+ |
+#source /opt/root/bin/thisroot.sh # only for operation with IJS |
+ |
+if [ ! -d results ]; then |
+ mkdir results |
+fi |
+ |
+root -l "$dir/start.cxx(\"$dir\")" |
+ |
+ |
/sipmscan/trunk/input/start.sh.offline |
---|
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Index: sipmscan/trunk/input/start.sh.online |
=================================================================== |
--- sipmscan/trunk/input/start.sh.online (nonexistent) |
+++ sipmscan/trunk/input/start.sh.online (revision 118) |
@@ -0,0 +1,12 @@ |
+#!/bin/bash |
+dir=`dirname $0` |
+ |
+source /opt/root/bin/thisroot.sh # only for operation with IJS |
+ |
+if [ ! -d results ]; then |
+ mkdir results |
+fi |
+ |
+root -l "$dir/start.cxx(\"$dir\")" |
+ |
+ |
/sipmscan/trunk/input/start.sh.online |
---|
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Index: sipmscan/trunk/input/workstation.h.in |
=================================================================== |
--- sipmscan/trunk/input/workstation.h.in (nonexistent) |
+++ sipmscan/trunk/input/workstation.h.in (revision 118) |
@@ -0,0 +1,11 @@ |
+#ifndef _workstation_h_ |
+#define _workstation_h_ |
+ |
+// Define the working computer (O=offline, I=IJS/online) and the base directory |
+#define WORKSTAT 'N' |
+ |
+#ifdef WORKSTAT |
+ #define rootdir "path-to-installation" |
+#endif |
+ |
+#endif |
Index: sipmscan/trunk/libxxusb.cpp |
=================================================================== |
--- sipmscan/trunk/libxxusb.cpp (nonexistent) |
+++ sipmscan/trunk/libxxusb.cpp (revision 118) |
@@ -0,0 +1,1651 @@ |
+ |
+// libxxusb.cpp : Defines the entry point for the DLL application. |
+// |
+ |
+ |
+ |
+#include <string.h> |
+#include <malloc.h> |
+#include "usb.h" |
+#include "libxxusb.h" |
+#include <time.h> |
+ |
+ |
+ |
+ |
+// 03/09/06 Release 3.00 changes |
+// 07/28/06 correction CAMAC write for F to be in range 16...23 |
+// 10/09/06 correction CAMAC read for F to be in range <16 OR >23 |
+// 10/16/06 CAMAC DGG corrected |
+// 12/28/07 Open corrected for bug when calling register after opening |
+/* |
+******** xxusb_longstack_execute ************************ |
+ |
+ Executes stack array passed to the function and returns the data read from the VME bus |
+ |
+ Paramters: |
+ hdev: USB device handle returned from an open function |
+ DataBuffer: pointer to the dual use buffer |
+ when calling , DataBuffer contains (unsigned short) stack data, with first word serving |
+ as a placeholder |
+ upon successful return, DataBuffer contains (unsigned short) VME data |
+ lDataLen: The number of bytes to be fetched from VME bus - not less than the actual number |
+ expected, or the function will return -5 code. For stack consisting only of write operations, |
+ lDataLen may be set to 1. |
+ timeout: The time in ms that should be spent tryimg to write data. |
+ |
+ Returns: |
+ When Successful, the number of bytes read from xxusb. |
+ Upon failure, a negative number |
+ |
+ Note: |
+ The function must pass a pointer to an array of unsigned integer stack data, in which the first word |
+ is left empty to serve as a placeholder. |
+ The function is intended for executing long stacks, up to 4 MBytes long, both "write" and "read" |
+ oriented, such as using multi-block transfer operations. |
+ Structure upon call: |
+ DataBuffer(0) = 0(don't care place holder) |
+ DataBuffer(1) = (unsigned short)StackLength bits 0-15 |
+ DataBuffer(2) = (unsigned short)StackLength bits 16-20 |
+ DataBuffer(3 - StackLength +2) (unsigned short) stack data |
+ StackLength represents the number of words following DataBuffer(1) word, thus the total number |
+ of words is StackLength+2 |
+ Structure upon return: |
+ DataBuffer(0 - (ReturnValue/2-1)) - (unsigned short)array of returned data when ReturnValue>0 |
+*/ |
+ |
+int xxusb_longstack_execute(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout) |
+{ |
+ int ret; |
+ char *cbuf; |
+ unsigned short *usbuf; |
+ int bufsize; |
+ |
+ cbuf = (char *)DataBuffer; |
+ usbuf = (unsigned short *)DataBuffer; |
+ cbuf[0]=12; |
+ cbuf[1]=0; |
+ bufsize = 2*(usbuf[1]+0x10000*usbuf[2])+4; |
+ ret=usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, cbuf, bufsize, timeout); |
+ if (ret>0) |
+ ret=usb_bulk_read(hDev, XXUSB_ENDPOINT_IN, cbuf, lDataLen, timeout); |
+ |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_bulk_read ************************ |
+ |
+ Reads the content of the usbfifo whenever "FIFO full" flag is set, |
+ otherwise times out. |
+ |
+ Paramters: |
+ hdev: USB device handle returned from an open function |
+ DataBuffer: pointer to an array to store data that is read from the VME bus; |
+ the array may be declared as byte, unsigned short, or unsigned long |
+ lDatalen: The number of bytes to read from xxusb |
+ timeout: The time in ms that should be spent waiting for data. |
+ |
+ Returns: |
+ When Successful, the number of bytes read from xxusb. |
+ Upon failure, a negative number |
+ |
+ Note: |
+ Depending upon the actual need, the function may be used to return the data in a form |
+ of an array of bytes, unsigned short integers (16 bits), or unsigned long integers (32 bits). |
+ The latter option of passing a pointer to an array of unsigned long integers is meaningful when |
+ xxusb data buffering option is used (bit 7=128 of the global register) that requires data |
+ 32-bit data alignment. |
+ |
+*/ |
+int xxusb_bulk_read(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout) |
+{ |
+int ret; |
+char *cbuf; |
+cbuf = (char *)DataBuffer; |
+ ret = usb_bulk_read(hDev, XXUSB_ENDPOINT_IN, cbuf, lDataLen, timeout); |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_bulk_write ************************ |
+ |
+ Writes the content of an array of bytes, unsigned short integers, or unsigned long integers |
+ to the USB port fifo; times out when the USB fifo is full (e.g., when xxusb is busy). |
+ |
+ Paramters: |
+ hdev: USB device handle returned from an open function |
+ DataBuffer: pointer to an array storing the data to be sent; |
+ the array may be declared as byte, unsigned short, or unsigned long |
+ lDatalen: The number of bytes to to send to xxusb |
+ timeout: The time in ms that should be spent waiting for data. |
+ |
+ Returns: |
+ When Successful, the number of bytes passed to xxusb. |
+ Upon failure, a negative number |
+ |
+ Note: |
+ Depending upon the actual need, the function may be used to pass to xxusb the data in a form |
+ of an array of bytes, unsigned short integers (16 bits), or unsigned long integers (32 bits). |
+*/ |
+int xxusb_bulk_write(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout) |
+{ |
+int ret; |
+char *cbuf; |
+cbuf = (char *)DataBuffer; |
+ ret = usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, cbuf, lDataLen, timeout); |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_usbfifo_read ************************ |
+ |
+ Reads data stored in the xxusb fifo and packs them in an array of long integers. |
+ |
+ Paramters: |
+ hdev: USB device handle returned from an open function |
+ DataBuffer: pointer to an array of long to store data that is read |
+ the data occupy only the least significant 16 bits of the 32-bit data words |
+ lDatalen: The number of bytes to read from the xxusb |
+ timeout: The time in ms that should be spent waiting for data. |
+ |
+ Returns: |
+ When Successful, the number of bytes read from xxusb. |
+ Upon failure, a negative number |
+ |
+ Note: |
+ The function is not economical as it wastes half of the space required for storing |
+ the data received. Also, it is relatively slow, as it performs extensive data repacking. |
+ It is recommended to use xxusb_bulk_read with a pointer to an array of unsigned short |
+ integers. |
+*/ |
+int xxusb_usbfifo_read(usb_dev_handle *hDev, int *DataBuffer, int lDataLen, int timeout) |
+{ |
+int ret; |
+char *cbuf; |
+unsigned short *usbuf; |
+int i; |
+ |
+cbuf = (char *)DataBuffer; |
+usbuf = (unsigned short *)DataBuffer; |
+ |
+ ret = usb_bulk_read(hDev, XXUSB_ENDPOINT_IN, cbuf, lDataLen, timeout); |
+ if (ret > 0) |
+ for (i=ret/2-1; i >= 0; i=i-1) |
+ { |
+ usbuf[i*2]=usbuf[i]; |
+ usbuf[i*2+1]=0; |
+ } |
+ return ret; |
+} |
+ |
+ |
+//******************************************************// |
+//******************* GENERAL XX_USB *******************// |
+//******************************************************// |
+// The following are functions used for both VM_USB & CC_USB |
+ |
+ |
+/* |
+******** xxusb_register_write ************************ |
+ |
+ Writes Data to the xxusb register selected by RedAddr. For |
+ acceptable values for RegData and RegAddr see the manual |
+ the module you are using. |
+ |
+ Parameters: |
+ hdev: usb device handle returned from open device |
+ RegAddr: The internal address if the xxusb |
+ RegData: The Data to be written to the register |
+ |
+ Returns: |
+ Number of bytes sent to xxusb if successful |
+ 0 if the register is write only |
+ Negative numbers if the call fails |
+*/ |
+short xxusb_register_write(usb_dev_handle *hDev, short RegAddr, long RegData) |
+{ |
+ long RegD; |
+ char buf[8]={5,0,0,0,0,0,0,0}; |
+ int ret; |
+ int lDataLen; |
+ int timeout; |
+ if ((RegAddr==0) || (RegAddr==12) || (RegAddr==15)) |
+ return 0; |
+ buf[2]=(char)(RegAddr & 15); |
+ buf[4]=(char)(RegData & 255); |
+ |
+ RegD = RegData >> 8; |
+ buf[5]=(char)(RegD & 255); |
+ RegD = RegD >>8; |
+ if (RegAddr==8) |
+ { |
+ buf[6]=(char)(RegD & 255); |
+ lDataLen=8; |
+ } |
+ else |
+ lDataLen=6; |
+ timeout=10; |
+ ret=xxusb_bulk_write(hDev, buf, lDataLen, timeout); |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_stack_write ************************ |
+ |
+ Writes a stack of VME/CAMAC calls to the VM_USB/CC_USB |
+ to be executed upon trigger. |
+ |
+ Parameters: |
+ hdev: usb device handle returned from an open function |
+ StackAddr: internal register to which the stack should be written |
+ lpStackData: Pointer to an array holding the stack |
+ |
+ Returns: |
+ The number of Bytes written to the xxusb when successful |
+ A negative number upon failure |
+*/ |
+short xxusb_stack_write(usb_dev_handle *hDev, short StackAddr, long *intbuf) |
+{ |
+ int timeout; |
+ short ret; |
+ short lDataLen; |
+ char buf[2000]; |
+ short i; |
+ int bufsize; |
+ |
+ buf[0]=(char)((StackAddr & 51) + 4); |
+ buf[1]=0; |
+ lDataLen=(short)(intbuf[0] & 0xFFF); |
+ buf[2]=(char)(lDataLen & 255); |
+ lDataLen = lDataLen >> 8; |
+ buf[3] = (char)(lDataLen & 255); |
+ bufsize=intbuf[0]*2+4; |
+ if (intbuf[0]==0) |
+ return 0; |
+ for (i=1; i <= intbuf[0]; i++) |
+ { |
+ buf[2+2*i] = (char)(intbuf[i] & 255); |
+ buf[3+2*i] = (char)((intbuf[i] >>8) & 255); |
+ } |
+ timeout=50; |
+ ret=usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf, bufsize, timeout); |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_stack_execute ********************** |
+ |
+ Writes, executes and returns the value of a DAQ stack. |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ intbuf: Pointer to an array holding the values stack. Upon return |
+ Pointer value is the Data returned from the stack. |
+ |
+ Returns: |
+ When successful, the number of Bytes read from xxusb |
+ Upon Failure, a negative number. |
+*/ |
+short xxusb_stack_execute(usb_dev_handle *hDev, long *intbuf) |
+{ |
+ int timeout; |
+ short ret; |
+ short lDataLen; |
+ char buf[26700]; |
+ short i; |
+ int bufsize; |
+ int ii = 0; |
+ |
+ buf[0]=12; |
+ buf[1]=0; |
+ lDataLen=(short)(intbuf[0] & 0xFFF); |
+ buf[2]=(char)(lDataLen & 255); |
+ lDataLen = lDataLen >> 8; |
+ buf[3] = (char)(lDataLen & 15); |
+ bufsize=intbuf[0]*2+4; |
+ if (intbuf[0]==0) |
+ return 0; |
+ for (i=1; i <= intbuf[0]; i++) |
+ { |
+ buf[2+2*i] = (char)(intbuf[i] & 255); |
+ buf[3+2*i] = (char)((intbuf[i] >>8) & 255); |
+ } |
+ timeout=2000; |
+ ret=usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf, bufsize, timeout); |
+ if (ret>0) |
+ { |
+ lDataLen=26700; |
+ timeout=6000; |
+ ret=usb_bulk_read(hDev, XXUSB_ENDPOINT_IN, buf, lDataLen, timeout); |
+ if (ret>0) |
+ for (i=0; i < ret; i=i+2) |
+ intbuf[ii++]=(UCHAR)(buf[i]) +(UCHAR)( buf[i+1])*256; |
+ } |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_stack_read ************************ |
+ |
+ Reads the current DAQ stack stored by xxusb |
+ |
+ Parameters: |
+ hdev: USB device handle returned by an open function |
+ StackAddr: Indicates which stack to read, primary or secondary |
+ intbuf: Pointer to a array where the stack can be stored |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short xxusb_stack_read(usb_dev_handle *hDev, short StackAddr, long *intbuf) |
+{ |
+ int timeout; |
+ short ret; |
+ short lDataLen; |
+ short bufsize; |
+ char buf[1600]; |
+ int i; |
+ |
+ buf[0]=(char)(StackAddr & 51); |
+ buf[1]=0; |
+ lDataLen = 2; |
+ timeout=100; |
+ ret=usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf, lDataLen, timeout); |
+ if (ret < 0) |
+ return ret; |
+ else |
+ bufsize=1600; |
+ int ii=0; |
+ { |
+ ret=usb_bulk_read(hDev, XXUSB_ENDPOINT_IN, buf, bufsize, timeout); |
+ if (ret>0) |
+ for (i=0; i < ret; i=i+2) |
+ intbuf[ii++]=(UCHAR)(buf[i]) + (UCHAR)(buf[i+1])*256; |
+ return ret; |
+ |
+ } |
+} |
+ |
+/* |
+******** xxusb_register_read ************************ |
+ |
+ Reads the current contents of an internal xxusb register |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ RegAddr: The internal address of the register from which to read |
+ RegData: Pointer to a long to hold the data. |
+ |
+ Returns: |
+ When Successful, the number of bytes read from xxusb. |
+ Upon failure, a negative number |
+*/ |
+short xxusb_register_read(usb_dev_handle *hDev, short RegAddr, long *RegData) |
+{ |
+//long RegD; |
+int timeout; |
+ char buf[4]={1,0,0,0}; |
+ int ret; |
+ int lDataLen; |
+ |
+ buf[2]=(char)(RegAddr & 15); |
+ timeout=10; |
+ lDataLen=4; |
+ ret=xxusb_bulk_write(hDev, buf, lDataLen, timeout); |
+ if (ret < 0) |
+ return (short)ret; |
+ else |
+ { |
+ lDataLen=8; |
+ timeout=100; |
+ ret=xxusb_bulk_read(hDev, buf, lDataLen, timeout); |
+ if (ret<0) |
+ return (short)ret; |
+ else |
+ { |
+ *RegData=(UCHAR)(buf[0])+256*(UCHAR)(buf[1]); |
+ if (ret==4) |
+ *RegData=*RegData+0x10000*(UCHAR)(buf[2]); |
+ return (short)ret; |
+ } |
+ } |
+} |
+ |
+/* |
+******** xxusb_reset_toggle ************************ |
+ |
+ Toggles the reset state of the FPGA while the xxusb in programming mode |
+ |
+ Parameters |
+ hdev: US B device handle returned from an open function |
+ |
+ Returns: |
+ Upon failure, a negative number |
+*/ |
+short xxusb_reset_toggle(usb_dev_handle *hDev) |
+{ |
+ short ret; |
+ char buf[2] = {(char)255,(char)255}; |
+ int lDataLen=2; |
+ int timeout=1000; |
+ ret = usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf,lDataLen, timeout); |
+ return (short)ret; |
+} |
+ |
+/* |
+******** xxusb_devices_find ************************ |
+ |
+ Determines the number and parameters of all xxusb devices attched to |
+ the computer. |
+ |
+ Parameters: |
+ xxdev: pointer to an array on which the device parameters are stored |
+ |
+ Returns: |
+ Upon success, returns the number of devices found |
+ Upon Failure returns a negative number |
+*/ |
+short xxusb_devices_find(xxusb_device_type *xxdev) |
+{ |
+ short DevFound = 0; |
+ usb_dev_handle *udev; |
+ struct usb_bus *bus; |
+ struct usb_device *dev; |
+struct usb_bus *usb_busses; |
+ char string[256]; |
+ short ret; |
+ usb_init(); |
+ usb_find_busses(); |
+ usb_busses=usb_get_busses(); |
+ usb_find_devices(); |
+ for (bus=usb_busses; bus; bus = bus->next) |
+ { |
+ for (dev = bus->devices; dev; dev= dev->next) |
+ { |
+ if (dev->descriptor.idVendor==XXUSB_WIENER_VENDOR_ID) |
+ { |
+ udev = usb_open(dev); |
+ if (udev) |
+ { |
+ ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string)); |
+ if (ret >0 ) |
+ { |
+ xxdev[DevFound].usbdev=dev; |
+ strcpy(xxdev[DevFound].SerialString, string); |
+ DevFound++; |
+ } |
+ usb_close(udev); |
+ } |
+ else return -1; |
+ } |
+ } |
+ } |
+ return DevFound; |
+} |
+ |
+/* |
+******** xxusb_device_close ************************ |
+ |
+ Closes an xxusb device |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ |
+ Returns: 1 |
+*/ |
+short xxusb_device_close(usb_dev_handle *hDev) |
+{ |
+ short ret; |
+ ret=usb_release_interface(hDev,0); |
+ usb_close(hDev); |
+ return 1; |
+} |
+ |
+/* |
+******** xxusb_device_open ************************ |
+ |
+ Opens an xxusb device found by xxusb_device_find |
+ |
+ Parameters: |
+ dev: a usb device |
+ |
+ Returns: |
+ A USB device handle |
+*/ |
+usb_dev_handle* xxusb_device_open(struct usb_device *dev) |
+{ |
+ short ret; |
+ long val; |
+ int count =0; |
+ usb_dev_handle *udev; |
+ udev = usb_open(dev); |
+ ret = usb_set_configuration(udev,1); |
+ ret = usb_claim_interface(udev,0); |
+// RESET USB (added 10/16/06 Andreas Ruben) |
+ ret=xxusb_register_write(udev, 10, 0x04); |
+// Loop to find known state (added 12/28/07 TH / AR) |
+ ret =-1; |
+ while ((ret <0) && (count <10)) |
+ { |
+ xxusb_register_read(udev, 0, &val); |
+ count++; |
+ } |
+ |
+ return udev; |
+} |
+ |
+/* |
+******** xxusb_flash_program ************************ |
+ |
+ --Untested and therefore uncommented-- |
+*/ |
+short xxusb_flash_program(usb_dev_handle *hDev, char *config, short nsect) |
+{ |
+ int i=0; |
+ int k=0; |
+ short ret=0; |
+ time_t t1,t2; |
+ |
+ char *pconfig; |
+ char *pbuf; |
+ pconfig=config; |
+ char buf[518] ={(char)0xAA,(char)0xAA,(char)0x55,(char)0x55,(char)0xA0,(char)0xA0}; |
+ while (*pconfig++ != -1); |
+ for (i=0; i<nsect; i++) |
+ { |
+ pbuf=buf+6; |
+ for (k=0; k<256; k++) |
+ { |
+ *(pbuf++)=*(pconfig); |
+ *(pbuf++)=*(pconfig++); |
+ } |
+ ret = usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf, 518, 2000); |
+ if (ret<0) |
+ return ret; |
+ t1=clock()+(time_t)(0.03*CLOCKS_PER_SEC); |
+ while (t1>clock()); |
+ t2=clock(); |
+ } |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_flashblock_program ************************ |
+ |
+ --Untested and therefore uncommented-- |
+*/ |
+short xxusb_flashblock_program(usb_dev_handle *hDev, UCHAR *config) |
+{ |
+ int k=0; |
+ short ret=0; |
+ |
+ UCHAR *pconfig; |
+ char *pbuf; |
+ pconfig=config; |
+ char buf[518] ={(char)0xAA,(char)0xAA,(char)0x55,(char)0x55,(char)0xA0,(char)0xA0}; |
+ pbuf=buf+6; |
+ for (k=0; k<256; k++) |
+ { |
+ *(pbuf++)=(UCHAR)(*(pconfig)); |
+ *(pbuf++)=(UCHAR)(*(pconfig++)); |
+ } |
+ ret = usb_bulk_write(hDev, XXUSB_ENDPOINT_OUT, buf, 518, 2000); |
+ return ret; |
+} |
+ |
+/* |
+******** xxusb_serial_open ************************ |
+ |
+ Opens a xxusb device whose serial number is given |
+ |
+ Parameters: |
+ SerialString: a char string that gives the serial number of |
+ the device you wish to open. It takes the form: |
+ VM0009 - for a vm_usb with serial number 9 or |
+ CC0009 - for a cc_usb with serial number 9 |
+ |
+ Returns: |
+ A USB device handle |
+*/ |
+usb_dev_handle* xxusb_serial_open(char *SerialString) |
+{ |
+ short DevFound = 0; |
+ usb_dev_handle *udev = NULL; |
+ struct usb_bus *bus; |
+ struct usb_device *dev; |
+struct usb_bus *usb_busses; |
+char string[7]; |
+ short ret; |
+// usb_set_debug(4); |
+ usb_init(); |
+ usb_find_busses(); |
+ usb_busses=usb_get_busses(); |
+ usb_find_devices(); |
+ for (bus=usb_busses; bus; bus = bus->next) |
+ { |
+ for (dev = bus->devices; dev; dev= dev->next) |
+ { |
+ if (dev->descriptor.idVendor==XXUSB_WIENER_VENDOR_ID) |
+ { |
+ udev = xxusb_device_open(dev); |
+ if (udev) |
+ { |
+ ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string)); |
+ if (ret >0 ) |
+ { |
+ if (strcmp(string,SerialString)==0) |
+ return udev; |
+ } |
+ usb_close(udev); |
+ } |
+ } |
+ } |
+ } |
+ udev = NULL; |
+ return udev; |
+} |
+ |
+ |
+//******************************************************// |
+//****************** EZ_VME Functions ******************// |
+//******************************************************// |
+// The following are functions used to perform simple |
+// VME Functions with the VM_USB |
+ |
+/* |
+******** VME_write_32 ************************ |
+ |
+ Writes a 32 bit data word to the VME bus |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Address_Modifier: VME address modifier for the VME call |
+ VME_Address: Address to write the data to |
+ Data: 32 bit data word to be written to VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_write_32(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ intbuf[0]=7; |
+ intbuf[1]=0; |
+ intbuf[2]=Address_Modifier; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff); |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ intbuf[6]=(Data & 0xffff); |
+ intbuf[7]=((Data >> 16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_read_32 ************************ |
+ |
+ |
+ Reads a 32 bit data word from a VME address |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Address_Modifier: VME address modifier for the VME call |
+ VME_Address: Address to read the data from |
+ Data: 32 bit data word read from VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_read_32(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long *Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ intbuf[0]=5; |
+ intbuf[1]=0; |
+ intbuf[2]=Address_Modifier +0x100; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff); |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Data=intbuf[0] + (intbuf[1] * 0x10000); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_write_16 ************************ |
+ |
+ Writes a 16 bit data word to the VME bus |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Address_Modifier: VME address modifier for the VME call |
+ VME_Address: Address to write the data to |
+ Data: word to be written to VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_write_16(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ intbuf[0]=7; |
+ intbuf[1]=0; |
+ intbuf[2]=Address_Modifier; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff)+ 0x01; |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ intbuf[6]=(Data & 0xffff); |
+ intbuf[7]=0; |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_read_16 ************************ |
+ |
+ Reads a 16 bit data word from a VME address |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Address_Modifier: VME address modifier for the VME call |
+ VME_Address: Address to read the data from |
+ Data: word read from VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_read_16(usb_dev_handle *hdev,short Address_Modifier, long VME_Address, long *Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ intbuf[0]=5; |
+ intbuf[1]=0; |
+ intbuf[2]=Address_Modifier +0x100; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff)+ 0x01; |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Data=intbuf[0]; |
+ return ret; |
+} |
+ |
+/* |
+******** VME_BLT_read_32 ************************ |
+ |
+ Performs block transfer of 32 bit words from a VME address |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Address_Modifier: VME address modifier for the VME call |
+ count: number of data words to read |
+ VME_Address: Address to read the data from |
+ Data: pointer to an array to hold the data words |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_BLT_read_32(usb_dev_handle *hdev, short Adress_Modifier, int count, long VME_Address, long Data[]) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ int i=0; |
+ if (count > 255) return -1; |
+ intbuf[0]=5; |
+ intbuf[1]=0; |
+ intbuf[2]=Adress_Modifier +0x100; |
+ intbuf[3]=(count << 8); |
+ intbuf[4]=(VME_Address & 0xffff); |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ int j=0; |
+ for (i=0;i<(2*count);i=i+2) |
+ { |
+ Data[j]=intbuf[i] + (intbuf[i+1] * 0x10000); |
+ j++; |
+ } |
+ return ret; |
+} |
+ |
+//******************************************************// |
+//****************** VM_USB Registers ******************// |
+//******************************************************// |
+// The following are functions used to set the registers |
+// in the VM_USB |
+ |
+/* |
+******** VME_register_write ************************ |
+ |
+ Writes to the vmusb registers that are accessible through |
+ VME style calls |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ VME_Address: The VME Address of the internal register |
+ Data: Data to be written to VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_register_write(usb_dev_handle *hdev, long VME_Address, long Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ |
+ intbuf[0]=7; |
+ intbuf[1]=0; |
+ intbuf[2]=0x1000; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff); |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ intbuf[6]=(Data & 0xffff); |
+ intbuf[7]=((Data >> 16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_register_read ************************ |
+ |
+ Reads from the vmusb registers that are accessible trough VME style calls |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ VME_Address: The VME Address of the internal register |
+ Data: Data read from VME_Address |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_register_read(usb_dev_handle *hdev, long VME_Address, long *Data) |
+{ |
+ long intbuf[1000]; |
+ short ret; |
+ |
+ intbuf[0]=5; |
+ intbuf[1]=0; |
+ intbuf[2]=0x1100; |
+ intbuf[3]=0; |
+ intbuf[4]=(VME_Address & 0xffff); |
+ intbuf[5]=((VME_Address >>16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Data=intbuf[0] + (intbuf[1] * 0x10000); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_LED_settings ************************ |
+ |
+ Sets the vmusb LED's |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ LED: The number which corresponds to an LED values are: |
+ 0 - for Top YELLOW LED |
+ 1 - for RED LED |
+ 2 - for GREEN LED |
+ 3 - for Bottom YELLOW LED |
+ code: The LED aource selector code, valid values for each LED |
+ are listed in the manual |
+ invert: to invert the LED lighting |
+ latch: sets LED latch bit |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_LED_settings(usb_dev_handle *hdev, int LED, int code, int invert, int latch) |
+{ |
+ short ret; |
+// long internal; |
+ long Data; |
+ |
+ if( (LED <0) ||(LED > 3) || (code < 0) || (code > 7)) return -1; |
+ |
+ VME_register_read(hdev,0xc,&Data); |
+ if(LED == 0) |
+ { |
+ Data = Data & 0xFFFFFF00; |
+ Data = Data | code; |
+ if (invert == 1 && latch == 1) Data = Data | 0x18; |
+ if (invert == 1 && latch == 0) Data = Data | 0x08; |
+ if (invert == 0 && latch == 1) Data = Data | 0x10; |
+ } |
+ if(LED == 1) |
+ { |
+ Data = Data & 0xFFFF00FF; |
+ Data = Data | (code * 0x0100); |
+ if (invert == 1 && latch == 1) Data = Data | 0x1800; |
+ if (invert == 1 && latch == 0) Data = Data | 0x0800; |
+ if (invert == 0 && latch == 1) Data = Data | 0x1000; |
+ } |
+ if(LED == 2) |
+ { |
+ Data = Data & 0xFF00FFFF; |
+ Data = Data | (code * 0x10000); |
+ if (invert == 1 && latch == 1) Data = Data | 0x180000; |
+ if (invert == 1 && latch == 0) Data = Data | 0x080000; |
+ if (invert == 0 && latch == 1) Data = Data | 0x100000; |
+ } |
+ if(LED == 3) |
+ { |
+ Data = Data & 0x00FFFFFF; |
+ Data = Data | (code * 0x10000); |
+ if (invert == 1 && latch == 1) Data = Data | 0x18000000; |
+ if (invert == 1 && latch == 0) Data = Data | 0x08000000; |
+ if (invert == 0 && latch == 1) Data = Data | 0x10000000; |
+ } |
+ ret = VME_register_write(hdev, 0xc, Data); |
+ return ret; |
+} |
+ |
+/* |
+******** VME_DGG ************************ |
+ |
+ Sets the parameters for Gate & Delay channel A of vmusb |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ channel: Which DGG channel to use Valid Values are: |
+ 0 - For DGG A |
+ 1 - For DGG B |
+ trigger: Determines what triggers the start of the DGG Valid values are: |
+ 0 - Channel disabled |
+ 1 - NIM input 1 |
+ 2 - NIM input 2 |
+ 3 - Event Trigger |
+ 4 - End of Event |
+ 5 - USB Trigger |
+ 6 - Pulser |
+ output: Determines which NIM output to use for the channel, Vaild values are: |
+ 0 - for NIM O1 |
+ 1 - for NIM O2 |
+ delay: 32 bit word consisting of |
+ lower 16 bits: Delay_fine in steps of 12.5ns between trigger and start of gate |
+ upper 16 bits: Delay_coarse in steps of 81.7us between trigger and start of gate |
+ gate: the time the gate should stay open in steps of 12.5ns |
+ invert: is 1 if you wish to invert the DGG channel output |
+ latch: is 1 if you wish to run the DGG channel latched |
+ |
+ Returns: |
+ Returns 1 when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_DGG(usb_dev_handle *hdev, unsigned short channel, unsigned short trigger, unsigned short output, |
+ long delay, unsigned short gate, unsigned short invert, unsigned short latch) |
+{ |
+ long Data, DGData, Delay_ext; |
+ long internal; |
+ short ret; |
+ |
+ |
+ ret = VME_register_read(hdev, 0x10, &Data); |
+ // check and correct values |
+ if(ret<=0) return -1; |
+ |
+ if(channel >1) channel =1; |
+ if(invert >1) invert =1; |
+ if(latch >1) latch =1; |
+ if(output >1) output =1; |
+ if(trigger >6) trigger =0; |
+ |
+ // define Delay and Gate data |
+ DGData = gate * 0x10000; |
+ DGData += (unsigned short) delay; |
+ |
+ // Set channel, output, invert, latch |
+ if (output == 0) |
+ { |
+ Data = Data & 0xFFFFFF00; |
+ Data += 0x04 + channel +0x08*invert + 0x10*latch; |
+ } |
+ if (output == 1) |
+ { |
+ Data = Data & 0xFFFF00FF; |
+ Data += (0x04 + channel +0x08*invert + 0x10*latch)*0x100; |
+ } |
+ |
+ // Set trigger, delay, gate |
+ |
+ if(channel ==0) // CHANNEL DGG_A |
+ { |
+ internal = (trigger * 0x1000000) ; |
+ Data= Data & 0xF0FFFFFF; |
+ Data += internal; |
+ ret = VME_register_write(hdev,0x10,Data); |
+ if(ret<=0) return -1; |
+ ret=VME_register_write(hdev,0x14,DGData); |
+ if(ret<=0) return -1; |
+ // Set coarse delay in DGG_Extended register |
+ ret = VME_register_read(hdev,0x38,&Data); |
+ Delay_ext= (Data & 0xffff0000); |
+ Delay_ext+= ((delay/0x10000) & 0xffff); |
+ ret = VME_register_write(hdev,0x38,Delay_ext); |
+ } |
+ if( channel ==1) // CHANNEL DGG_B |
+ { |
+ internal = (trigger * 0x10000000) ; |
+ Data= Data & 0x0FFFFFFF; |
+ Data += internal; |
+ ret = VME_register_write(hdev,0x10,Data); |
+ if(ret<=0) return -1; |
+ ret=VME_register_write(hdev,0x18,DGData); |
+ if(ret<=0) return -1; |
+ // Set coarse delay in DGG_Extended register |
+ ret = VME_register_read(hdev,0x38,&Data); |
+ Delay_ext= (Data & 0x0000ffff); |
+ Delay_ext+= (delay & 0xffff0000); |
+ ret = VME_register_write(hdev,0x38,Delay_ext); |
+ } |
+ return 1; |
+ |
+} |
+ |
+/* |
+******** VME_Output_settings ************************ |
+ |
+ Sets the vmusb NIM output register |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Channel: The number which corresponds to an output: |
+ 1 - for Output 1 |
+ 2 - for Output 2 |
+ code: The Output selector code, valid values |
+ are listed in the manual |
+ invert: to invert the output |
+ latch: sets latch bit |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short VME_Output_settings(usb_dev_handle *hdev, int Channel, int code, int invert, int latch) |
+{ |
+ |
+ short ret; |
+// long internal; |
+ long Data; |
+ |
+ if( (Channel <1) ||(Channel > 2) || (code < 0) || (code > 7)) return -1; |
+ VME_register_read(hdev,0x10,&Data); |
+ if(Channel == 1) |
+ { |
+ Data = Data & 0xFFFF00; |
+ Data = Data | code; |
+ if (invert == 1 && latch == 1) Data = Data | 0x18; |
+ if (invert == 1 && latch == 0) Data = Data | 0x08; |
+ if (invert == 0 && latch == 1) Data = Data | 0x10; |
+ } |
+ if(Channel == 2) |
+ { |
+ Data = Data & 0xFF00FF; |
+ Data = Data | (code * 0x0100); |
+ if (invert == 1 && latch == 1) Data = Data | 0x1800; |
+ if (invert == 1 && latch == 0) Data = Data | 0x0800; |
+ if (invert == 0 && latch == 1) Data = Data | 0x1000; |
+ } |
+ ret = VME_register_write(hdev, 0x10, Data); |
+ return ret; |
+} |
+ |
+ |
+//******************************************************// |
+//****************** CC_USB Registers ******************// |
+//******************************************************// |
+// The following are functions used to set the registers |
+// in the CAMAC_USB |
+ |
+/* |
+******** CAMAC_register_write ***************** |
+ |
+ Performs a CAMAC write to CC_USB register |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ A: CAMAC Subaddress |
+ F: CAMAC Function |
+ Data: data to be written |
+ |
+ Returns: |
+ Number of bytes written to xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_register_write(usb_dev_handle *hdev, int A, long Data) |
+{ |
+ int F = 16; |
+ int N = 25; |
+ long intbuf[4]; |
+ int ret; |
+ |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(F+A*32+N*512 + 0x4000); |
+ intbuf[0]=3; |
+ intbuf[2]=(Data & 0xffff); |
+ intbuf[3]=((Data >>16) & 0xffff); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_register_read ************************ |
+ |
+ Performs a CAMAC read from CC_USB register |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ N: CAMAC Station Number |
+ A: CAMAC Subaddress |
+ F: CAMAC Function |
+ Q: The Q response from the CAMAC dataway |
+ X: The comment accepted response from CAMAC dataway |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_register_read(usb_dev_handle *hdev, int A, long *Data) |
+{ |
+ int F = 0; |
+ int N = 25; |
+ long intbuf[4]; |
+ int ret; |
+ |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(F+A*32+N*512 + 0x4000); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Data=intbuf[0] + (intbuf[1] * 0x10000); |
+ |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_DGG ************************ |
+ |
+ Sets the parameters for Gate & Delay channel A of CC_USB |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ channel: Which DGG channel to use Valid Values are: |
+ 0 - For DGG A |
+ 1 - For DGG B |
+ trigger: Determines what triggers the start of the DGG Valid values are: |
+ 0 - Channel disabled |
+ 1 - NIM input 1 |
+ 2 - NIM input 2 |
+ 3 - NIM input 2 |
+ 4 - Event Trigger |
+ 5 - End of Event |
+ 6 - USB Trigger |
+ 7 - Pulser |
+ output: Determines which NIM output to use for the channel, Vaild values are: |
+ 1 - for NIM O1 |
+ 2 - for NIM O2 |
+ 3 - for NIM O3 |
+ delay: Delay in steps of 12.5ns between trigger and start of gate |
+ gate: the time the gate should stay open in steps of 12.5ns |
+ invert: is 1 if you wish to invert the DGG channel output |
+ latch: is 1 if you wish to run the DGG channel latched |
+ |
+ Returns: |
+ Returns 1 when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_DGG(usb_dev_handle *hdev, short channel, short trigger, short output, |
+ int delay, int gate, short invert, short latch) |
+ |
+ |
+ |
+{ |
+// short channel_ID; |
+ long Data; |
+ long internal; |
+ short ret; |
+ long Delay_ext; |
+ |
+ ret = CAMAC_register_read(hdev,5,&Data); |
+ //Set trigger |
+ if((output < 1 ) || (output >3) || (channel < 0 ) || (channel > 1)) |
+ return -1; |
+ if(output ==1) |
+ { |
+ if(channel ==0) |
+ { |
+ internal = 0x03; |
+ } else { |
+ internal = 0x04; |
+ } |
+ } |
+ if(output ==2) |
+ { |
+ if(channel ==0) |
+ { |
+ internal = 0x04; |
+ } else { |
+ internal = 0x05; |
+ } |
+ } |
+ if(output ==3) |
+ { |
+ if(channel ==0) |
+ { |
+ internal = 0x05; |
+ } else { |
+ internal = 0x06; |
+ } |
+ } |
+ |
+ |
+// Set invert bit |
+ if(invert ==1) |
+ internal = internal | 0x10; |
+ else |
+ internal = internal & 0x0F; |
+ // Set Latch Bit |
+ if(latch==1) |
+ internal = internal | 0x20; |
+ else |
+ internal = internal & 0x1F; |
+// Add new data to old |
+ if(output == 1) |
+ { |
+ Data = Data & 0xFFFF00; |
+ Data = Data | internal; |
+ } |
+ if(output == 2) |
+ { |
+ Data = Data & 0xFF00FF; |
+ Data = Data |(internal * 0x100); |
+ } |
+ if(output == 3) |
+ { |
+ Data = Data & 0x00FFFF; |
+ Data = Data | (internal * 0x10000) ; |
+ } |
+ CAMAC_register_write(hdev, 5, Data); |
+ ret = CAMAC_register_read(hdev,6,&Data); |
+//Set Trigger |
+ if(trigger <0 || trigger > 7) |
+ return -1; |
+ if(channel ==0) |
+ { |
+ Data = Data & 0xFF00FFFF; |
+ internal = trigger * 0x10000; |
+ Data = Data | internal; |
+ } else { |
+ Data = Data & 0x00FFFFFF; |
+ internal = trigger * 0x1000000; |
+ Data = Data | internal; |
+ } |
+ ret = CAMAC_register_write(hdev, 6, Data); |
+ if(channel == 0) |
+ { |
+// Write Delay and Gate info |
+ ret = CAMAC_register_read(hdev,13,&Data); |
+ Delay_ext= (Data & 0xffff0000); |
+ Delay_ext+= ((delay/0x10000) & 0xffff); |
+ internal = gate * 0x10000; |
+ Data = internal + (delay & 0xffff); |
+ ret=CAMAC_register_write(hdev,7,Data); |
+// Set coarse delay in DGG_Extended register |
+ ret=CAMAC_register_write(hdev,13,Delay_ext); |
+ } |
+ else |
+ { |
+ ret=CAMAC_register_write(hdev,8,Data); |
+ ret = CAMAC_register_read(hdev,13,&Data); |
+ Delay_ext= (Data & 0x0000ffff); |
+ Delay_ext+= (delay & 0xffff0000); |
+ internal = gate * 0x10000; |
+ Data = internal + (delay & 0xffff); |
+// Set coarse delay in DGG_Extended register |
+ ret=CAMAC_register_write(hdev,13,Delay_ext); |
+ } |
+ return 1; |
+} |
+ |
+/* |
+******** CAMAC_LED_settings ************************ |
+ |
+ Writes a data word to the vmusb LED register |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ LED: The number which corresponds to an LED values are: |
+ 1 - for RED LED |
+ 2 - for GREEN LED |
+ 3 - for Yellow LED |
+ code: The LED aource selector code, valid values for each LED |
+ are listed in the manual |
+ invert: to invert the LED lighting |
+ latch: sets LED latch bit |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_LED_settings(usb_dev_handle *hdev, int LED, int code, int invert, int latch) |
+{ |
+ |
+ short ret; |
+// long internal; |
+ long Data; |
+ |
+ if( (LED <1) ||(LED > 3) || (code < 0) || (code > 7)) |
+ return -1; |
+ |
+ CAMAC_register_read(hdev,4,&Data); |
+ |
+ if(LED == 1) |
+ { |
+ Data = Data & 0xFFFF00; |
+ Data = Data | code; |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x30; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x10; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x20; |
+ } |
+ if(LED == 2) |
+ { |
+ Data = Data & 0xFF00FF; |
+ Data = Data | (code * 0x0100); |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x3000; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x1000; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x2000; |
+ } |
+ if(LED == 3) |
+ { |
+ Data = Data & 0x00FFFF; |
+ Data = Data | (code * 0x10000); |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x300000; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x100000; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x200000; |
+ } |
+ ret = CAMAC_register_write(hdev, 4, Data); |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_Output_settings ************************ |
+ |
+ Writes a data word to the vmusb LED register |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Channel: The number which corresponds to an output: |
+ 1 - for Output 1 |
+ 2 - for Output 2 |
+ 3 - for Output 3 |
+ code: The Output selector code, valid values |
+ are listed in the manual |
+ invert: to invert the output |
+ latch: sets latch bit |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_Output_settings(usb_dev_handle *hdev, int Channel, int code, int invert, int latch) |
+{ |
+ short ret; |
+// long internal; |
+ long Data; |
+ |
+ if( (Channel <1) ||(Channel > 3) || (code < 0) || (code > 7)) |
+ return -1; |
+ |
+ CAMAC_register_read(hdev,5,&Data); |
+ |
+ if(Channel == 1) |
+ { |
+ Data = Data & 0xFFFF00; |
+ Data = Data | code; |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x30; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x10; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x20; |
+ } |
+ if(Channel == 2) |
+ { |
+ Data = Data & 0xFF00FF; |
+ Data = Data | (code * 0x0100); |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x3000; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x1000; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x2000; |
+ } |
+ if(Channel == 3) |
+ { |
+ Data = Data & 0x00FFFF; |
+ Data = Data | (code * 0x10000); |
+ if (invert == 1 && latch == 1) |
+ Data = Data | 0x300000; |
+ if (invert == 1 && latch == 0) |
+ Data = Data | 0x100000; |
+ if (invert == 0 && latch == 1) |
+ Data = Data | 0x200000; |
+ } |
+ ret = CAMAC_register_write(hdev, 5, Data); |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_write_LAM_mask ************************ |
+ |
+ Writes the data word to the LAM mask register |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Data: LAM mask to write |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_write_LAM_mask(usb_dev_handle *hdev, long Data) |
+{ |
+ short ret; |
+ ret = CAMAC_register_write(hdev, 9, Data); |
+ |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_read_LAM_mask ************************ |
+ |
+ Writes the data word to the LAM mask register |
+ |
+ Parameters: |
+ hdev: USB devcie handle returned from an open function |
+ Data: LAM mask to write |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_read_LAM_mask(usb_dev_handle *hdev, long *Data) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+ int N = 25; |
+ int F = 0; |
+ int A = 9; |
+ |
+ // CAMAC direct read function |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(F+A*32+N*512 + 0x4000); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Data=intbuf[0] + (intbuf[1] & 255) * 0x10000; |
+ return ret; |
+} |
+ |
+ |
+//******************************************************// |
+//**************** EZ_CAMAC Functions ******************// |
+//******************************************************// |
+// The following are functions used to perform simple |
+// CAMAC Functions with the CC_USB |
+ |
+ |
+/* |
+******** CAMAC_write ************************ |
+ |
+ Performs a CAMAC write using NAF comments |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ N: CAMAC Station Number |
+ A: CAMAC Subaddress |
+ F: CAMAC Function (16...23) |
+ Q: The Q response from the CAMAC dataway |
+ X: The comment accepted response from CAMAC dataway |
+ |
+ Returns: |
+ Number of bytes written to xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_write(usb_dev_handle *hdev, int N, int A, int F, long Data, int *Q, int *X) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+// CAMAC direct write function |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(F+A*32+N*512 + 0x4000); |
+ if ((F > 15) && (F < 24)) |
+ { |
+ intbuf[0]=3; |
+ intbuf[2]=(Data & 0xffff); |
+ intbuf[3]=((Data >>16) & 255); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ *Q = (intbuf[0] & 1); |
+ *X = ((intbuf[0] >> 1) & 1); |
+ } |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_read ************************ |
+ |
+ Performs a CAMAC read using NAF comments |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ N: CAMAC Station Number |
+ A: CAMAC Subaddress |
+ F: CAMAC Function (F<16 or F>23) |
+ Q: The Q response from the CAMAC dataway |
+ X: The comment accepted response from CAMAC dataway |
+ |
+ Returns: |
+ Number of bytes read from xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_read(usb_dev_handle *hdev, 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); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ if ((F < 16) || (F >23)) |
+ { |
+ *Data=intbuf[0] + (intbuf[1] & 255) * 0x10000; //24-bit word |
+ *Q = ((intbuf[1] >> 8) & 1); |
+ *X = ((intbuf[1] >> 9) & 1); |
+ } |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_Z ************************ |
+ |
+ Performs a CAMAC init |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ |
+ Returns: |
+ Number of bytes written to xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_Z(usb_dev_handle *hdev) |
+{ |
+ 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(hdev, intbuf); |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_C ************************ |
+ |
+ Performs a CAMAC clear |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ |
+ Returns: |
+ Number of bytes written to xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_C(usb_dev_handle *hdev) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(29+9*32+28*512 + 0x4000); |
+ ret = xxusb_stack_execute(hdev, intbuf); |
+ return ret; |
+} |
+ |
+/* |
+******** CAMAC_I ************************ |
+ |
+ Set CAMAC inhibit |
+ |
+ Parameters: |
+ hdev: USB device handle returned from an open function |
+ |
+ Returns: |
+ Number of bytes written to xxusb when successful |
+ Upon failure, a negative number |
+*/ |
+short CAMAC_I(usb_dev_handle *hdev, int inhibit) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+ 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(hdev, intbuf); |
+ return ret; |
+} |
+ |
+ |
Index: sipmscan/trunk/libxxusb.h |
=================================================================== |
--- sipmscan/trunk/libxxusb.h (nonexistent) |
+++ sipmscan/trunk/libxxusb.h (revision 118) |
@@ -0,0 +1,111 @@ |
+#include <usb.h> |
+ |
+ |
+#define XXUSB_WIENER_VENDOR_ID 0x16DC /* Wiener, Plein & Baus */ |
+#define XXUSB_VMUSB_PRODUCT_ID 0x000B /* VM-USB */ |
+#define XXUSB_CCUSB_PRODUCT_ID 0x0001 /* CC-USB */ |
+#define XXUSB_ENDPOINT_OUT 2 /* Endpoint 2 Out*/ |
+#define XXUSB_ENDPOINT_IN 0x86 /* Endpoint 6 In */ |
+#define XXUSB_FIRMWARE_REGISTER 0 |
+#define XXUSB_GLOBAL_REGISTER 1 |
+#define XXUSB_ACTION_REGISTER 10 |
+#define XXUSB_DELAYS_REGISTER 2 |
+#define XXUSB_WATCHDOG_REGISTER 3 |
+#define XXUSB_SELLEDA_REGISTER 6 |
+#define XXUSB_SELNIM_REGISTER 7 |
+#define XXUSB_SELLEDB_REGISTER 4 |
+#define XXUSB_SERIAL_REGISTER 15 |
+#define XXUSB_LAMMASK_REGISTER 8 |
+#define XXUSB_LAM_REGISTER 12 |
+#define XXUSB_READOUT_STACK 2 |
+#define XXUSB_SCALER_STACK 3 |
+#define XXUSB_NAF_DIRECT 12 |
+ |
+struct XXUSB_STACK |
+{ |
+long Data; |
+short Hit; |
+short APatt; |
+short Num; |
+short HitMask; |
+}; |
+ |
+struct XXUSB_CC_COMMAND_TYPE |
+{ |
+short Crate; |
+short F; |
+short A; |
+short N; |
+long Data; |
+short NoS2; |
+short LongD; |
+short HitPatt; |
+short QStop; |
+short LAMMode; |
+short UseHit; |
+short Repeat; |
+short AddrScan; |
+short FastCam; |
+short NumMod; |
+short AddrPatt; |
+long HitMask[4]; |
+long Num; |
+}; |
+ |
+struct xxusb_device_typ |
+{ |
+ struct usb_device *usbdev; |
+ char SerialString[7]; |
+}; |
+ |
+typedef struct xxusb_device_typ xxusb_device_type; |
+typedef unsigned char UCHAR; |
+typedef struct usb_bus usb_busx; |
+ |
+ |
+int xxusb_longstack_execute(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout); |
+int xxusb_bulk_read(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout); |
+int xxusb_bulk_write(usb_dev_handle *hDev, void *DataBuffer, int lDataLen, int timeout); |
+int xxusb_usbfifo_read(usb_dev_handle *hDev, int *DataBuffer, int lDataLen, int timeout); |
+ |
+short xxusb_register_read(usb_dev_handle *hDev, short RegAddr, long *RegData); |
+short xxusb_stack_read(usb_dev_handle *hDev, short StackAddr, long *StackData); |
+short xxusb_stack_write(usb_dev_handle *hDev, short StackAddr, long *StackData); |
+short xxusb_stack_execute(usb_dev_handle *hDev, long *StackData); |
+short xxusb_register_write(usb_dev_handle *hDev, short RegAddr, long RegData); |
+short xxusb_reset_toggle(usb_dev_handle *hDev); |
+ |
+short xxusb_devices_find(xxusb_device_type *xxusbDev); |
+short xxusb_device_close(usb_dev_handle *hDev); |
+usb_dev_handle* xxusb_device_open(struct usb_device *dev); |
+short xxusb_flash_program(usb_dev_handle *hDev, char *config, short nsect); |
+short xxusb_flashblock_program(usb_dev_handle *hDev, UCHAR *config); |
+usb_dev_handle* xxusb_serial_open(char *SerialString); |
+ |
+short VME_register_write(usb_dev_handle *hdev, long VME_Address, long Data); |
+short VME_register_read(usb_dev_handle *hdev, long VME_Address, long *Data); |
+short VME_LED_settings(usb_dev_handle *hdev, int LED, int code, int invert, int latch); |
+short VME_DGG(usb_dev_handle *hdev, unsigned short channel, unsigned short trigger,unsigned short output, long delay, unsigned short gate, unsigned short invert, unsigned short latch); |
+ |
+short VME_Output_settings(usb_dev_handle *hdev, int Channel, int code, int invert, int latch); |
+ |
+short VME_read_16(usb_dev_handle *hdev,short Address_Modifier, long VME_Address, long *Data); |
+short VME_read_32(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long *Data); |
+short VME_BLT_read_32(usb_dev_handle *hdev, short Address_Modifier, int count, long VME_Address, long Data[]); |
+short VME_write_16(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long Data); |
+short VME_write_32(usb_dev_handle *hdev, short Address_Modifier, long VME_Address, long Data); |
+ |
+short CAMAC_DGG(usb_dev_handle *hdev, short channel, short trigger, short output, int delay, int gate, short invert, short latch); |
+short CAMAC_register_read(usb_dev_handle *hdev, int A, long *Data); |
+short CAMAC_register_write(usb_dev_handle *hdev, int A, long Data); |
+short CAMAC_LED_settings(usb_dev_handle *hdev, int LED, int code, int invert, int latch); |
+short CAMAC_Output_settings(usb_dev_handle *hdev, int Channel, int code, int invert, int latch); |
+short CAMAC_read_LAM_mask(usb_dev_handle *hdev, long *Data); |
+short CAMAC_write_LAM_mask(usb_dev_handle *hdev, long Data); |
+ |
+short CAMAC_write(usb_dev_handle *hdev, int N, int A, int F, long Data, int *Q, int *X); |
+short CAMAC_read(usb_dev_handle *hdev, int N, int A, int F, long *Data, int *Q, int *X); |
+short CAMAC_Z(usb_dev_handle *hdev); |
+short CAMAC_C(usb_dev_handle *hdev); |
+short CAMAC_I(usb_dev_handle *hdev, int inhibit); |
+ |
Index: sipmscan/trunk/mpod/WIENER-CRATE-MIB.txt |
=================================================================== |
--- sipmscan/trunk/mpod/WIENER-CRATE-MIB.txt (nonexistent) |
+++ sipmscan/trunk/mpod/WIENER-CRATE-MIB.txt (revision 118) |
@@ -0,0 +1,1578 @@ |
+---------------------------------------------------------------------------------------------------- |
+-- $HeadURL: http://svn.wiener-d.com/src/enet/trunk/mibs/WIENER-CRATE-MIB.txt $ |
+-- $LastChangedDate: 2008-11-27 12:00:00 +0100 (Fr, 21. Nov 2008) $ |
+-- $LastChangedRevision: 617 / 510 $ |
+-- $LastChangedBy: koester (roemer)$ |
+-- Copyright © 2005-2007 W-IE-NE-R Plein & Baus GmbH, Burscheid, Germany |
+---------------------------------------------------------------------------------------------------- |
+WIENER-CRATE-MIB DEFINITIONS ::= BEGIN |
+ |
+IMPORTS |
+ OBJECT-TYPE, MODULE-IDENTITY, OBJECT-IDENTITY, |
+ Integer32, Opaque, enterprises |
+ FROM SNMPv2-SMI |
+ |
+ TEXTUAL-CONVENTION, DisplayString |
+ FROM SNMPv2-TC |
+ |
+-- Float |
+-- FROM NET-SNMP-TC |
+-- Float |
+-- FROM UCD-SNMP-MIB |
+ ; |
+ |
+ |
+ |
+ |
+wiener MODULE-IDENTITY |
+ LAST-UPDATED "200810090000Z" -- October 9, 2008 |
+ ORGANIZATION "WIENER Plein & Baus GmbH" |
+ CONTACT-INFO " |
+ postal: WIENER Plein & Baus GmbH |
+ Mullersbaum 20 |
+ D-51399 Burscheid |
+ Germany |
+ |
+ email: info@wiener-d.com |
+ |
+ " |
+ |
+ DESCRIPTION |
+ "Introduction of the communication.can branch. |
+ " |
+ |
+ |
+ REVISION "200805060000Z" -- May 6, 2008 |
+ DESCRIPTION |
+ "Introduction of the signal branch. |
+ " |
+ |
+ REVISION "200804150000Z" -- April 15, 2008 |
+ DESCRIPTION |
+ "Enlargement of u0..u11 -> u0..u1999 |
+ " |
+ |
+ REVISION "200804100000Z" -- April 10, 2008 |
+ DESCRIPTION |
+ "This revision uses again Integer32 instead of Counter32. |
+ " |
+ |
+ REVISION "200804020000Z" -- April 02, 2008 |
+ DESCRIPTION |
+ "This revision modifies the syntax of this file to be complient with smilint. |
+ " |
+ |
+ REVISION "200709100000Z" |
+ DESCRIPTION |
+ "This revision introduces new OIDs for debug functionality: |
+ sysDebugMemory8, sysDebugMemory16 and sysDebugMemory32. |
+ " |
+ |
+ REVISION "200703160000Z" |
+ DESCRIPTION |
+ "This revision introduces new OIDs for slew control: |
+ outputVoltageRiseRate and outputVoltageFallRate. |
+ " |
+ |
+ REVISION "200502010000Z" |
+ DESCRIPTION |
+ "This revision introduces new OIDs for group managment: |
+ groupTable |
+ " |
+ |
+ REVISION "200406280000Z" |
+ DESCRIPTION |
+ "WIENER Crate MIB, actual Firmware: UEL6E 4.02. |
+ Initial Version. |
+ " |
+ |
+ ::= { enterprises 19947 } |
+ |
+ |
+------------------------------------------------------------------------------- |
+-- Define the Float Textual Convention |
+-- This definition was written by David Perkins. |
+-- |
+Float ::= TEXTUAL-CONVENTION |
+ STATUS current |
+ DESCRIPTION |
+ "A single precision floating-point number. The semantics |
+ and encoding are identical for type 'single' defined in |
+ IEEE Standard for Binary Floating-Point, |
+ ANSI/IEEE Std 754-1985. |
+ The value is restricted to the BER serialization of |
+ the following ASN.1 type: |
+ FLOATTYPE ::= [120] IMPLICIT FloatType |
+ (note: the value 120 is the sum of '30'h and '48'h) |
+ The BER serialization of the length for values of |
+ this type must use the definite length, short |
+ encoding form. |
+ |
+ For example, the BER serialization of value 123 |
+ of type FLOATTYPE is '9f780442f60000'h. (The tag |
+ is '9f78'h; the length is '04'h; and the value is |
+ '42f60000'h.) The BER serialization of value |
+ '9f780442f60000'h of data type Opaque is |
+ '44079f780442f60000'h. (The tag is '44'h; the length |
+ is '07'h; and the value is '9f780442f60000'h." |
+ SYNTAX Opaque (SIZE (7)) |
+ |
+------------------------------------------------------------------------------- |
+-- crate |
+------------------------------------------------------------------------------- |
+ |
+crate OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "SNMP control for electronic crates. A crate is a complete electronic system and |
+ consists of the mechanical rack, a power supply, a fan tray and a backplane. |
+ All this things are necessary to provide an adequate housing for electronic |
+ modules (e.g. VME CPU's)" |
+ ::= { wiener 1 } |
+ |
+--Crate ::= SEQUENCE { |
+-- system System, |
+-- input Input, |
+-- output Output, |
+-- sensor Sensor, |
+-- communication Communication, |
+-- powersupply Powersupply, |
+-- fantray Fantray, |
+-- rack Rack |
+--} |
+ |
+system OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "A collection of objects which affect the complete crate" |
+ ::= { crate 1 } |
+ |
+ |
+input OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are associated with the power input of the crate" |
+ ::= { crate 2 } |
+ |
+output OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are associated with the power output of the crate" |
+ ::= { crate 3 } |
+ |
+sensor OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are associated with temperature sensors in the crate" |
+ ::= { crate 4 } |
+ |
+communication OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which affect the remote control of the crate" |
+ ::= { crate 5 } |
+ |
+powersupply OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are specific for the power supply of the crate" |
+ ::= { crate 6 } |
+ |
+fantray OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are specific for the fan tray of the crate" |
+ ::= { crate 7 } |
+ |
+rack OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are specific for the crate (BIN) of the crate" |
+ ::= { crate 8 } |
+ |
+signal OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "All objects which are associated with analog/digtal input/output in the crate" |
+ ::= { crate 9 } |
+ |
+ |
+------------------------------------------------------------------------------- |
+-- system |
+------------------------------------------------------------------------------- |
+System ::= SEQUENCE { |
+ sysMainSwitch INTEGER, |
+ sysStatus BITS, |
+ sysVmeSysReset INTEGER, |
+ sysDebugMemory8 Integer32, |
+ sysDebugMemory16 Integer32, |
+ sysDebugMemory32 Integer32 |
+} |
+ |
+sysMainSwitch OBJECT-TYPE |
+ SYNTAX INTEGER { off (0), on (1) } |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Read: An enumerated value which shows the current state of |
+ the crates main switch. |
+ Write: Try to switch the complete crate ON or OFF. |
+ Only the values ON or OFF are allowed." |
+ ::= { system 1 } |
+ |
+sysStatus OBJECT-TYPE |
+ SYNTAX BITS { |
+ mainOn (0) , |
+ mainInhibit (1) , |
+ localControlOnly (2) , |
+ inputFailure (3) , |
+ outputFailure (4) , |
+ fantrayFailure (5) , |
+ sensorFailure (6), |
+ vmeSysfail (7), |
+ plugAndPlayIncompatible (8) |
+ } |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "A bit string which shows the status (health) of the complete crate. |
+ If a bit is set (1), the explanation is satisfied |
+ mainOn (0), system is switched on, individual outputs may be controlled by their specific ON/INHIBIT |
+ mainInhibit(1), external (hardware-)inhibit of the complete system |
+ localControlOnly (2), local control only (CANBUS write access denied) |
+ inputFailure (3), any input failure (e.g. power fail) |
+ outputFailure (4), any output failure, details in outputTable |
+ fantrayFailure (5), fantray failure |
+ sensorFailure (6), temperature of the external sensors too high |
+ VmeSysfail(7), VME SYSFAIL signal is active |
+ plugAndPlayIncompatible (8) wrong power supply and rack connected |
+ " |
+ ::= { system 2 } |
+ |
+ |
+-- ERROR_BIN_CHECKSUM(?), |
+ |
+ |
+ |
+ |
+ |
+sysVmeSysReset OBJECT-TYPE |
+ SYNTAX INTEGER { trigger (1) } |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Read: Always 0. |
+ Write: Trigger the generation of the VME SYSRESET signal. |
+ This signal will be active for a time of 200 ms" |
+ ::= { system 3 } |
+ |
+sysDebugMemory8 OBJECT-TYPE |
+ SYNTAX Integer32 (0..255) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Debug 16-bit memory access." |
+ ::= { system 1024 } |
+ |
+sysDebugMemory16 OBJECT-TYPE |
+ SYNTAX Integer32 (0..65535) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Debug 16-bit memory access." |
+ ::= { system 1025 } |
+ |
+sysDebugMemory32 OBJECT-TYPE |
+ SYNTAX Integer32 (-2147483648..2147483647) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Debug 32-bit memory access." |
+ ::= { system 1026 } |
+ |
+------------------------------------------------------------------------------- |
+-- input |
+------------------------------------------------------------------------------- |
+-- reserved, possible entries: |
+-- inputSetPfcVoltage |
+-- inputMesPowerFail |
+-- inputMesVoltage |
+-- inputMesCurrent |
+-- inputMesPower |
+-- inputMesTemperature |
+------------------------------------------------------------------------------- |
+-- output |
+------------------------------------------------------------------------------- |
+--Output ::= SEQUENCE { |
+-- outputNumber Integer32, |
+-- outputTable OutputTable, |
+-- groupsNumber Integer32, |
+-- groupsTable GroupsTable |
+-- ??TotalPower |
+--} |
+ |
+outputNumber OBJECT-TYPE |
+ SYNTAX Integer32 (0..1999) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The number of output channels of the crate." |
+ ::= { output 1 } |
+ |
+outputTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF OutputEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A list of output entries." |
+ ::= { output 2 } |
+ |
+groupsNumber OBJECT-TYPE |
+ SYNTAX Integer32 (1..1999) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The number of output groups of the crate." |
+ ::= { output 3 } |
+ |
+groupsTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF GroupsEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A list of output groups entries." |
+ ::= { output 4 } |
+ |
+outputEntry OBJECT-TYPE |
+ SYNTAX OutputEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A table row" |
+ INDEX { outputIndex } |
+ ::= { outputTable 1 } |
+ |
+OutputEntry ::= SEQUENCE { |
+ outputIndex INTEGER, |
+ outputName DisplayString, |
+ outputGroup INTEGER, |
+ outputStatus BITS, |
+ outputMeasurementSenseVoltage Float, |
+ outputMeasurementTerminalVoltage Float, |
+ outputMeasurementCurrent Float, |
+ outputMeasurementTemperature INTEGER, |
+ |
+ outputSwitch INTEGER, |
+ outputVoltage Float, |
+ outputAdjustVoltage Integer32, |
+ outputCurrent Float, |
+ |
+ outputVoltageRiseRate Float, |
+ outputVoltageFallRate Float, |
+ |
+ outputSupervisionBehavior Integer32, |
+ outputSupervisionMinSenseVoltage Float, |
+ outputSupervisionMaxSenseVoltage Float, |
+ outputSupervisionMaxTerminalVoltage Float, |
+ outputSupervisionMaxCurrent Float, |
+-- outputSupervisionMaxTemperature Integer32, |
+ |
+ outputConfigMaxSenseVoltage Float, |
+ outputConfigMaxTerminalVoltage Float, |
+ outputConfigMaxCurrent Float, |
+ outputSupervisionMaxPower Float, |
+ |
+ outputCurrentRiseRate Float, |
+ outputCurrentFallRate Float, |
+ outputTripTimeMaxCurrent INTEGER |
+ } |
+ |
+ |
+outputIndex OBJECT-TYPE |
+ SYNTAX INTEGER { |
+ u0(1),u1(2),u2(3),u3(4),u4(5),u5(6),u6(7),u7(8),u8(9),u9(10), |
+ u10(11),u11(12),u12(13),u13(14),u14(15),u15(16),u16(17),u17(18),u18(19),u19(20), |
+ u20(21),u21(22),u22(23),u23(24),u24(25),u25(26),u26(27),u27(28),u28(29),u29(30), |
+ u30(31),u31(32),u32(33),u33(34),u34(35),u35(36),u36(37),u37(38),u38(39),u39(40), |
+ u40(41),u41(42),u42(43),u43(44),u44(45),u45(46),u46(47),u47(48),u48(49),u49(50), |
+ u50(51),u51(52),u52(53),u53(54),u54(55),u55(56),u56(57),u57(58),u58(59),u59(60), |
+ u60(61),u61(62),u62(63),u63(64),u64(65),u65(66),u66(67),u67(68),u68(69),u69(70), |
+ u70(71),u71(72),u72(73),u73(74),u74(75),u75(76),u76(77),u77(78),u78(79),u79(80), |
+ u80(81),u81(82),u82(83),u83(84),u84(85),u85(86),u86(87),u87(88),u88(89),u89(90), |
+ u90(91),u91(92),u92(93),u93(94),u94(95),u95(96),u96(97),u97(98),u98(99),u99(100), |
+ u100(101),u101(102),u102(103),u103(104),u104(105),u105(106),u106(107),u107(108),u108(109),u109(110), |
+ u110(111),u111(112),u112(113),u113(114),u114(115),u115(116),u116(117),u117(118),u118(119),u119(120), |
+ u120(121),u121(122),u122(123),u123(124),u124(125),u125(126),u126(127),u127(128),u128(129),u129(130), |
+ u130(131),u131(132),u132(133),u133(134),u134(135),u135(136),u136(137),u137(138),u138(139),u139(140), |
+ u140(141),u141(142),u142(143),u143(144),u144(145),u145(146),u146(147),u147(148),u148(149),u149(150), |
+ u150(151),u151(152),u152(153),u153(154),u154(155),u155(156),u156(157),u157(158),u158(159),u159(160), |
+ u160(161),u161(162),u162(163),u163(164),u164(165),u165(166),u166(167),u167(168),u168(169),u169(170), |
+ u170(171),u171(172),u172(173),u173(174),u174(175),u175(176),u176(177),u177(178),u178(179),u179(180), |
+ u180(181),u181(182),u182(183),u183(184),u184(185),u185(186),u186(187),u187(188),u188(189),u189(190), |
+ u190(191),u191(192),u192(193),u193(194),u194(195),u195(196),u196(197),u197(198),u198(199),u199(200), |
+ u200(201),u201(202),u202(203),u203(204),u204(205),u205(206),u206(207),u207(208),u208(209),u209(210), |
+ u210(211),u211(212),u212(213),u213(214),u214(215),u215(216),u216(217),u217(218),u218(219),u219(220), |
+ u220(221),u221(222),u222(223),u223(224),u224(225),u225(226),u226(227),u227(228),u228(229),u229(230), |
+ u230(231),u231(232),u232(233),u233(234),u234(235),u235(236),u236(237),u237(238),u238(239),u239(240), |
+ u240(241),u241(242),u242(243),u243(244),u244(245),u245(246),u246(247),u247(248),u248(249),u249(250), |
+ u250(251),u251(252),u252(253),u253(254),u254(255),u255(256),u256(257),u257(258),u258(259),u259(260), |
+ u260(261),u261(262),u262(263),u263(264),u264(265),u265(266),u266(267),u267(268),u268(269),u269(270), |
+ u270(271),u271(272),u272(273),u273(274),u274(275),u275(276),u276(277),u277(278),u278(279),u279(280), |
+ u280(281),u281(282),u282(283),u283(284),u284(285),u285(286),u286(287),u287(288),u288(289),u289(290), |
+ u290(291),u291(292),u292(293),u293(294),u294(295),u295(296),u296(297),u297(298),u298(299),u299(300), |
+ u300(301),u301(302),u302(303),u303(304),u304(305),u305(306),u306(307),u307(308),u308(309),u309(310), |
+ u310(311),u311(312),u312(313),u313(314),u314(315),u315(316),u316(317),u317(318),u318(319),u319(320), |
+ u320(321),u321(322),u322(323),u323(324),u324(325),u325(326),u326(327),u327(328),u328(329),u329(330), |
+ u330(331),u331(332),u332(333),u333(334),u334(335),u335(336),u336(337),u337(338),u338(339),u339(340), |
+ u340(341),u341(342),u342(343),u343(344),u344(345),u345(346),u346(347),u347(348),u348(349),u349(350), |
+ u350(351),u351(352),u352(353),u353(354),u354(355),u355(356),u356(357),u357(358),u358(359),u359(360), |
+ u360(361),u361(362),u362(363),u363(364),u364(365),u365(366),u366(367),u367(368),u368(369),u369(370), |
+ u370(371),u371(372),u372(373),u373(374),u374(375),u375(376),u376(377),u377(378),u378(379),u379(380), |
+ u380(381),u381(382),u382(383),u383(384),u384(385),u385(386),u386(387),u387(388),u388(389),u389(390), |
+ u390(391),u391(392),u392(393),u393(394),u394(395),u395(396),u396(397),u397(398),u398(399),u399(400), |
+ u400(401),u401(402),u402(403),u403(404),u404(405),u405(406),u406(407),u407(408),u408(409),u409(410), |
+ u410(411),u411(412),u412(413),u413(414),u414(415),u415(416),u416(417),u417(418),u418(419),u419(420), |
+ u420(421),u421(422),u422(423),u423(424),u424(425),u425(426),u426(427),u427(428),u428(429),u429(430), |
+ u430(431),u431(432),u432(433),u433(434),u434(435),u435(436),u436(437),u437(438),u438(439),u439(440), |
+ u440(441),u441(442),u442(443),u443(444),u444(445),u445(446),u446(447),u447(448),u448(449),u449(450), |
+ u450(451),u451(452),u452(453),u453(454),u454(455),u455(456),u456(457),u457(458),u458(459),u459(460), |
+ u460(461),u461(462),u462(463),u463(464),u464(465),u465(466),u466(467),u467(468),u468(469),u469(470), |
+ u470(471),u471(472),u472(473),u473(474),u474(475),u475(476),u476(477),u477(478),u478(479),u479(480), |
+ u480(481),u481(482),u482(483),u483(484),u484(485),u485(486),u486(487),u487(488),u488(489),u489(490), |
+ u490(491),u491(492),u492(493),u493(494),u494(495),u495(496),u496(497),u497(498),u498(499),u499(500), |
+ u500(501),u501(502),u502(503),u503(504),u504(505),u505(506),u506(507),u507(508),u508(509),u509(510), |
+ u510(511),u511(512),u512(513),u513(514),u514(515),u515(516),u516(517),u517(518),u518(519),u519(520), |
+ u520(521),u521(522),u522(523),u523(524),u524(525),u525(526),u526(527),u527(528),u528(529),u529(530), |
+ u530(531),u531(532),u532(533),u533(534),u534(535),u535(536),u536(537),u537(538),u538(539),u539(540), |
+ u540(541),u541(542),u542(543),u543(544),u544(545),u545(546),u546(547),u547(548),u548(549),u549(550), |
+ u550(551),u551(552),u552(553),u553(554),u554(555),u555(556),u556(557),u557(558),u558(559),u559(560), |
+ u560(561),u561(562),u562(563),u563(564),u564(565),u565(566),u566(567),u567(568),u568(569),u569(570), |
+ u570(571),u571(572),u572(573),u573(574),u574(575),u575(576),u576(577),u577(578),u578(579),u579(580), |
+ u580(581),u581(582),u582(583),u583(584),u584(585),u585(586),u586(587),u587(588),u588(589),u589(590), |
+ u590(591),u591(592),u592(593),u593(594),u594(595),u595(596),u596(597),u597(598),u598(599),u599(600), |
+ u600(601),u601(602),u602(603),u603(604),u604(605),u605(606),u606(607),u607(608),u608(609),u609(610), |
+ u610(611),u611(612),u612(613),u613(614),u614(615),u615(616),u616(617),u617(618),u618(619),u619(620), |
+ u620(621),u621(622),u622(623),u623(624),u624(625),u625(626),u626(627),u627(628),u628(629),u629(630), |
+ u630(631),u631(632),u632(633),u633(634),u634(635),u635(636),u636(637),u637(638),u638(639),u639(640), |
+ u640(641),u641(642),u642(643),u643(644),u644(645),u645(646),u646(647),u647(648),u648(649),u649(650), |
+ u650(651),u651(652),u652(653),u653(654),u654(655),u655(656),u656(657),u657(658),u658(659),u659(660), |
+ u660(661),u661(662),u662(663),u663(664),u664(665),u665(666),u666(667),u667(668),u668(669),u669(670), |
+ u670(671),u671(672),u672(673),u673(674),u674(675),u675(676),u676(677),u677(678),u678(679),u679(680), |
+ u680(681),u681(682),u682(683),u683(684),u684(685),u685(686),u686(687),u687(688),u688(689),u689(690), |
+ u690(691),u691(692),u692(693),u693(694),u694(695),u695(696),u696(697),u697(698),u698(699),u699(700), |
+ u700(701),u701(702),u702(703),u703(704),u704(705),u705(706),u706(707),u707(708),u708(709),u709(710), |
+ u710(711),u711(712),u712(713),u713(714),u714(715),u715(716),u716(717),u717(718),u718(719),u719(720), |
+ u720(721),u721(722),u722(723),u723(724),u724(725),u725(726),u726(727),u727(728),u728(729),u729(730), |
+ u730(731),u731(732),u732(733),u733(734),u734(735),u735(736),u736(737),u737(738),u738(739),u739(740), |
+ u740(741),u741(742),u742(743),u743(744),u744(745),u745(746),u746(747),u747(748),u748(749),u749(750), |
+ u750(751),u751(752),u752(753),u753(754),u754(755),u755(756),u756(757),u757(758),u758(759),u759(760), |
+ u760(761),u761(762),u762(763),u763(764),u764(765),u765(766),u766(767),u767(768),u768(769),u769(770), |
+ u770(771),u771(772),u772(773),u773(774),u774(775),u775(776),u776(777),u777(778),u778(779),u779(780), |
+ u780(781),u781(782),u782(783),u783(784),u784(785),u785(786),u786(787),u787(788),u788(789),u789(790), |
+ u790(791),u791(792),u792(793),u793(794),u794(795),u795(796),u796(797),u797(798),u798(799),u799(800), |
+ u800(801),u801(802),u802(803),u803(804),u804(805),u805(806),u806(807),u807(808),u808(809),u809(810), |
+ u810(811),u811(812),u812(813),u813(814),u814(815),u815(816),u816(817),u817(818),u818(819),u819(820), |
+ u820(821),u821(822),u822(823),u823(824),u824(825),u825(826),u826(827),u827(828),u828(829),u829(830), |
+ u830(831),u831(832),u832(833),u833(834),u834(835),u835(836),u836(837),u837(838),u838(839),u839(840), |
+ u840(841),u841(842),u842(843),u843(844),u844(845),u845(846),u846(847),u847(848),u848(849),u849(850), |
+ u850(851),u851(852),u852(853),u853(854),u854(855),u855(856),u856(857),u857(858),u858(859),u859(860), |
+ u860(861),u861(862),u862(863),u863(864),u864(865),u865(866),u866(867),u867(868),u868(869),u869(870), |
+ u870(871),u871(872),u872(873),u873(874),u874(875),u875(876),u876(877),u877(878),u878(879),u879(880), |
+ u880(881),u881(882),u882(883),u883(884),u884(885),u885(886),u886(887),u887(888),u888(889),u889(890), |
+ u890(891),u891(892),u892(893),u893(894),u894(895),u895(896),u896(897),u897(898),u898(899),u899(900), |
+ u900(901),u901(902),u902(903),u903(904),u904(905),u905(906),u906(907),u907(908),u908(909),u909(910), |
+ u910(911),u911(912),u912(913),u913(914),u914(915),u915(916),u916(917),u917(918),u918(919),u919(920), |
+ u920(921),u921(922),u922(923),u923(924),u924(925),u925(926),u926(927),u927(928),u928(929),u929(930), |
+ u930(931),u931(932),u932(933),u933(934),u934(935),u935(936),u936(937),u937(938),u938(939),u939(940), |
+ u940(941),u941(942),u942(943),u943(944),u944(945),u945(946),u946(947),u947(948),u948(949),u949(950), |
+ u950(951),u951(952),u952(953),u953(954),u954(955),u955(956),u956(957),u957(958),u958(959),u959(960), |
+ u960(961),u961(962),u962(963),u963(964),u964(965),u965(966),u966(967),u967(968),u968(969),u969(970), |
+ u970(971),u971(972),u972(973),u973(974),u974(975),u975(976),u976(977),u977(978),u978(979),u979(980), |
+ u980(981),u981(982),u982(983),u983(984),u984(985),u985(986),u986(987),u987(988),u988(989),u989(990), |
+ u990(991),u991(992),u992(993),u993(994),u994(995),u995(996),u996(997),u997(998),u998(999),u999(1000), |
+ u1000(1001),u1001(1002),u1002(1003),u1003(1004),u1004(1005),u1005(1006),u1006(1007),u1007(1008),u1008(1009),u1009(1010), |
+ u1010(1011),u1011(1012),u1012(1013),u1013(1014),u1014(1015),u1015(1016),u1016(1017),u1017(1018),u1018(1019),u1019(1020), |
+ u1020(1021),u1021(1022),u1022(1023),u1023(1024),u1024(1025),u1025(1026),u1026(1027),u1027(1028),u1028(1029),u1029(1030), |
+ u1030(1031),u1031(1032),u1032(1033),u1033(1034),u1034(1035),u1035(1036),u1036(1037),u1037(1038),u1038(1039),u1039(1040), |
+ u1040(1041),u1041(1042),u1042(1043),u1043(1044),u1044(1045),u1045(1046),u1046(1047),u1047(1048),u1048(1049),u1049(1050), |
+ u1050(1051),u1051(1052),u1052(1053),u1053(1054),u1054(1055),u1055(1056),u1056(1057),u1057(1058),u1058(1059),u1059(1060), |
+ u1060(1061),u1061(1062),u1062(1063),u1063(1064),u1064(1065),u1065(1066),u1066(1067),u1067(1068),u1068(1069),u1069(1070), |
+ u1070(1071),u1071(1072),u1072(1073),u1073(1074),u1074(1075),u1075(1076),u1076(1077),u1077(1078),u1078(1079),u1079(1080), |
+ u1080(1081),u1081(1082),u1082(1083),u1083(1084),u1084(1085),u1085(1086),u1086(1087),u1087(1088),u1088(1089),u1089(1090), |
+ u1090(1091),u1091(1092),u1092(1093),u1093(1094),u1094(1095),u1095(1096),u1096(1097),u1097(1098),u1098(1099),u1099(1100), |
+ u1100(1101),u1101(1102),u1102(1103),u1103(1104),u1104(1105),u1105(1106),u1106(1107),u1107(1108),u1108(1109),u1109(1110), |
+ u1110(1111),u1111(1112),u1112(1113),u1113(1114),u1114(1115),u1115(1116),u1116(1117),u1117(1118),u1118(1119),u1119(1120), |
+ u1120(1121),u1121(1122),u1122(1123),u1123(1124),u1124(1125),u1125(1126),u1126(1127),u1127(1128),u1128(1129),u1129(1130), |
+ u1130(1131),u1131(1132),u1132(1133),u1133(1134),u1134(1135),u1135(1136),u1136(1137),u1137(1138),u1138(1139),u1139(1140), |
+ u1140(1141),u1141(1142),u1142(1143),u1143(1144),u1144(1145),u1145(1146),u1146(1147),u1147(1148),u1148(1149),u1149(1150), |
+ u1150(1151),u1151(1152),u1152(1153),u1153(1154),u1154(1155),u1155(1156),u1156(1157),u1157(1158),u1158(1159),u1159(1160), |
+ u1160(1161),u1161(1162),u1162(1163),u1163(1164),u1164(1165),u1165(1166),u1166(1167),u1167(1168),u1168(1169),u1169(1170), |
+ u1170(1171),u1171(1172),u1172(1173),u1173(1174),u1174(1175),u1175(1176),u1176(1177),u1177(1178),u1178(1179),u1179(1180), |
+ u1180(1181),u1181(1182),u1182(1183),u1183(1184),u1184(1185),u1185(1186),u1186(1187),u1187(1188),u1188(1189),u1189(1190), |
+ u1190(1191),u1191(1192),u1192(1193),u1193(1194),u1194(1195),u1195(1196),u1196(1197),u1197(1198),u1198(1199),u1199(1200), |
+ u1200(1201),u1201(1202),u1202(1203),u1203(1204),u1204(1205),u1205(1206),u1206(1207),u1207(1208),u1208(1209),u1209(1210), |
+ u1210(1211),u1211(1212),u1212(1213),u1213(1214),u1214(1215),u1215(1216),u1216(1217),u1217(1218),u1218(1219),u1219(1220), |
+ u1220(1221),u1221(1222),u1222(1223),u1223(1224),u1224(1225),u1225(1226),u1226(1227),u1227(1228),u1228(1229),u1229(1230), |
+ u1230(1231),u1231(1232),u1232(1233),u1233(1234),u1234(1235),u1235(1236),u1236(1237),u1237(1238),u1238(1239),u1239(1240), |
+ u1240(1241),u1241(1242),u1242(1243),u1243(1244),u1244(1245),u1245(1246),u1246(1247),u1247(1248),u1248(1249),u1249(1250), |
+ u1250(1251),u1251(1252),u1252(1253),u1253(1254),u1254(1255),u1255(1256),u1256(1257),u1257(1258),u1258(1259),u1259(1260), |
+ u1260(1261),u1261(1262),u1262(1263),u1263(1264),u1264(1265),u1265(1266),u1266(1267),u1267(1268),u1268(1269),u1269(1270), |
+ u1270(1271),u1271(1272),u1272(1273),u1273(1274),u1274(1275),u1275(1276),u1276(1277),u1277(1278),u1278(1279),u1279(1280), |
+ u1280(1281),u1281(1282),u1282(1283),u1283(1284),u1284(1285),u1285(1286),u1286(1287),u1287(1288),u1288(1289),u1289(1290), |
+ u1290(1291),u1291(1292),u1292(1293),u1293(1294),u1294(1295),u1295(1296),u1296(1297),u1297(1298),u1298(1299),u1299(1300), |
+ u1300(1301),u1301(1302),u1302(1303),u1303(1304),u1304(1305),u1305(1306),u1306(1307),u1307(1308),u1308(1309),u1309(1310), |
+ u1310(1311),u1311(1312),u1312(1313),u1313(1314),u1314(1315),u1315(1316),u1316(1317),u1317(1318),u1318(1319),u1319(1320), |
+ u1320(1321),u1321(1322),u1322(1323),u1323(1324),u1324(1325),u1325(1326),u1326(1327),u1327(1328),u1328(1329),u1329(1330), |
+ u1330(1331),u1331(1332),u1332(1333),u1333(1334),u1334(1335),u1335(1336),u1336(1337),u1337(1338),u1338(1339),u1339(1340), |
+ u1340(1341),u1341(1342),u1342(1343),u1343(1344),u1344(1345),u1345(1346),u1346(1347),u1347(1348),u1348(1349),u1349(1350), |
+ u1350(1351),u1351(1352),u1352(1353),u1353(1354),u1354(1355),u1355(1356),u1356(1357),u1357(1358),u1358(1359),u1359(1360), |
+ u1360(1361),u1361(1362),u1362(1363),u1363(1364),u1364(1365),u1365(1366),u1366(1367),u1367(1368),u1368(1369),u1369(1370), |
+ u1370(1371),u1371(1372),u1372(1373),u1373(1374),u1374(1375),u1375(1376),u1376(1377),u1377(1378),u1378(1379),u1379(1380), |
+ u1380(1381),u1381(1382),u1382(1383),u1383(1384),u1384(1385),u1385(1386),u1386(1387),u1387(1388),u1388(1389),u1389(1390), |
+ u1390(1391),u1391(1392),u1392(1393),u1393(1394),u1394(1395),u1395(1396),u1396(1397),u1397(1398),u1398(1399),u1399(1400), |
+ u1400(1401),u1401(1402),u1402(1403),u1403(1404),u1404(1405),u1405(1406),u1406(1407),u1407(1408),u1408(1409),u1409(1410), |
+ u1410(1411),u1411(1412),u1412(1413),u1413(1414),u1414(1415),u1415(1416),u1416(1417),u1417(1418),u1418(1419),u1419(1420), |
+ u1420(1421),u1421(1422),u1422(1423),u1423(1424),u1424(1425),u1425(1426),u1426(1427),u1427(1428),u1428(1429),u1429(1430), |
+ u1430(1431),u1431(1432),u1432(1433),u1433(1434),u1434(1435),u1435(1436),u1436(1437),u1437(1438),u1438(1439),u1439(1440), |
+ u1440(1441),u1441(1442),u1442(1443),u1443(1444),u1444(1445),u1445(1446),u1446(1447),u1447(1448),u1448(1449),u1449(1450), |
+ u1450(1451),u1451(1452),u1452(1453),u1453(1454),u1454(1455),u1455(1456),u1456(1457),u1457(1458),u1458(1459),u1459(1460), |
+ u1460(1461),u1461(1462),u1462(1463),u1463(1464),u1464(1465),u1465(1466),u1466(1467),u1467(1468),u1468(1469),u1469(1470), |
+ u1470(1471),u1471(1472),u1472(1473),u1473(1474),u1474(1475),u1475(1476),u1476(1477),u1477(1478),u1478(1479),u1479(1480), |
+ u1480(1481),u1481(1482),u1482(1483),u1483(1484),u1484(1485),u1485(1486),u1486(1487),u1487(1488),u1488(1489),u1489(1490), |
+ u1490(1491),u1491(1492),u1492(1493),u1493(1494),u1494(1495),u1495(1496),u1496(1497),u1497(1498),u1498(1499),u1499(1500), |
+ u1500(1501),u1501(1502),u1502(1503),u1503(1504),u1504(1505),u1505(1506),u1506(1507),u1507(1508),u1508(1509),u1509(1510), |
+ u1510(1511),u1511(1512),u1512(1513),u1513(1514),u1514(1515),u1515(1516),u1516(1517),u1517(1518),u1518(1519),u1519(1520), |
+ u1520(1521),u1521(1522),u1522(1523),u1523(1524),u1524(1525),u1525(1526),u1526(1527),u1527(1528),u1528(1529),u1529(1530), |
+ u1530(1531),u1531(1532),u1532(1533),u1533(1534),u1534(1535),u1535(1536),u1536(1537),u1537(1538),u1538(1539),u1539(1540), |
+ u1540(1541),u1541(1542),u1542(1543),u1543(1544),u1544(1545),u1545(1546),u1546(1547),u1547(1548),u1548(1549),u1549(1550), |
+ u1550(1551),u1551(1552),u1552(1553),u1553(1554),u1554(1555),u1555(1556),u1556(1557),u1557(1558),u1558(1559),u1559(1560), |
+ u1560(1561),u1561(1562),u1562(1563),u1563(1564),u1564(1565),u1565(1566),u1566(1567),u1567(1568),u1568(1569),u1569(1570), |
+ u1570(1571),u1571(1572),u1572(1573),u1573(1574),u1574(1575),u1575(1576),u1576(1577),u1577(1578),u1578(1579),u1579(1580), |
+ u1580(1581),u1581(1582),u1582(1583),u1583(1584),u1584(1585),u1585(1586),u1586(1587),u1587(1588),u1588(1589),u1589(1590), |
+ u1590(1591),u1591(1592),u1592(1593),u1593(1594),u1594(1595),u1595(1596),u1596(1597),u1597(1598),u1598(1599),u1599(1600), |
+ u1600(1601),u1601(1602),u1602(1603),u1603(1604),u1604(1605),u1605(1606),u1606(1607),u1607(1608),u1608(1609),u1609(1610), |
+ u1610(1611),u1611(1612),u1612(1613),u1613(1614),u1614(1615),u1615(1616),u1616(1617),u1617(1618),u1618(1619),u1619(1620), |
+ u1620(1621),u1621(1622),u1622(1623),u1623(1624),u1624(1625),u1625(1626),u1626(1627),u1627(1628),u1628(1629),u1629(1630), |
+ u1630(1631),u1631(1632),u1632(1633),u1633(1634),u1634(1635),u1635(1636),u1636(1637),u1637(1638),u1638(1639),u1639(1640), |
+ u1640(1641),u1641(1642),u1642(1643),u1643(1644),u1644(1645),u1645(1646),u1646(1647),u1647(1648),u1648(1649),u1649(1650), |
+ u1650(1651),u1651(1652),u1652(1653),u1653(1654),u1654(1655),u1655(1656),u1656(1657),u1657(1658),u1658(1659),u1659(1660), |
+ u1660(1661),u1661(1662),u1662(1663),u1663(1664),u1664(1665),u1665(1666),u1666(1667),u1667(1668),u1668(1669),u1669(1670), |
+ u1670(1671),u1671(1672),u1672(1673),u1673(1674),u1674(1675),u1675(1676),u1676(1677),u1677(1678),u1678(1679),u1679(1680), |
+ u1680(1681),u1681(1682),u1682(1683),u1683(1684),u1684(1685),u1685(1686),u1686(1687),u1687(1688),u1688(1689),u1689(1690), |
+ u1690(1691),u1691(1692),u1692(1693),u1693(1694),u1694(1695),u1695(1696),u1696(1697),u1697(1698),u1698(1699),u1699(1700), |
+ u1700(1701),u1701(1702),u1702(1703),u1703(1704),u1704(1705),u1705(1706),u1706(1707),u1707(1708),u1708(1709),u1709(1710), |
+ u1710(1711),u1711(1712),u1712(1713),u1713(1714),u1714(1715),u1715(1716),u1716(1717),u1717(1718),u1718(1719),u1719(1720), |
+ u1720(1721),u1721(1722),u1722(1723),u1723(1724),u1724(1725),u1725(1726),u1726(1727),u1727(1728),u1728(1729),u1729(1730), |
+ u1730(1731),u1731(1732),u1732(1733),u1733(1734),u1734(1735),u1735(1736),u1736(1737),u1737(1738),u1738(1739),u1739(1740), |
+ u1740(1741),u1741(1742),u1742(1743),u1743(1744),u1744(1745),u1745(1746),u1746(1747),u1747(1748),u1748(1749),u1749(1750), |
+ u1750(1751),u1751(1752),u1752(1753),u1753(1754),u1754(1755),u1755(1756),u1756(1757),u1757(1758),u1758(1759),u1759(1760), |
+ u1760(1761),u1761(1762),u1762(1763),u1763(1764),u1764(1765),u1765(1766),u1766(1767),u1767(1768),u1768(1769),u1769(1770), |
+ u1770(1771),u1771(1772),u1772(1773),u1773(1774),u1774(1775),u1775(1776),u1776(1777),u1777(1778),u1778(1779),u1779(1780), |
+ u1780(1781),u1781(1782),u1782(1783),u1783(1784),u1784(1785),u1785(1786),u1786(1787),u1787(1788),u1788(1789),u1789(1790), |
+ u1790(1791),u1791(1792),u1792(1793),u1793(1794),u1794(1795),u1795(1796),u1796(1797),u1797(1798),u1798(1799),u1799(1800), |
+ u1800(1801),u1801(1802),u1802(1803),u1803(1804),u1804(1805),u1805(1806),u1806(1807),u1807(1808),u1808(1809),u1809(1810), |
+ u1810(1811),u1811(1812),u1812(1813),u1813(1814),u1814(1815),u1815(1816),u1816(1817),u1817(1818),u1818(1819),u1819(1820), |
+ u1820(1821),u1821(1822),u1822(1823),u1823(1824),u1824(1825),u1825(1826),u1826(1827),u1827(1828),u1828(1829),u1829(1830), |
+ u1830(1831),u1831(1832),u1832(1833),u1833(1834),u1834(1835),u1835(1836),u1836(1837),u1837(1838),u1838(1839),u1839(1840), |
+ u1840(1841),u1841(1842),u1842(1843),u1843(1844),u1844(1845),u1845(1846),u1846(1847),u1847(1848),u1848(1849),u1849(1850), |
+ u1850(1851),u1851(1852),u1852(1853),u1853(1854),u1854(1855),u1855(1856),u1856(1857),u1857(1858),u1858(1859),u1859(1860), |
+ u1860(1861),u1861(1862),u1862(1863),u1863(1864),u1864(1865),u1865(1866),u1866(1867),u1867(1868),u1868(1869),u1869(1870), |
+ u1870(1871),u1871(1872),u1872(1873),u1873(1874),u1874(1875),u1875(1876),u1876(1877),u1877(1878),u1878(1879),u1879(1880), |
+ u1880(1881),u1881(1882),u1882(1883),u1883(1884),u1884(1885),u1885(1886),u1886(1887),u1887(1888),u1888(1889),u1889(1890), |
+ u1890(1891),u1891(1892),u1892(1893),u1893(1894),u1894(1895),u1895(1896),u1896(1897),u1897(1898),u1898(1899),u1899(1900), |
+ u1900(1901),u1901(1902),u1902(1903),u1903(1904),u1904(1905),u1905(1906),u1906(1907),u1907(1908),u1908(1909),u1909(1910), |
+ u1910(1911),u1911(1912),u1912(1913),u1913(1914),u1914(1915),u1915(1916),u1916(1917),u1917(1918),u1918(1919),u1919(1920), |
+ u1920(1921),u1921(1922),u1922(1923),u1923(1924),u1924(1925),u1925(1926),u1926(1927),u1927(1928),u1928(1929),u1929(1930), |
+ u1930(1931),u1931(1932),u1932(1933),u1933(1934),u1934(1935),u1935(1936),u1936(1937),u1937(1938),u1938(1939),u1939(1940), |
+ u1940(1941),u1941(1942),u1942(1943),u1943(1944),u1944(1945),u1945(1946),u1946(1947),u1947(1948),u1948(1949),u1949(1950), |
+ u1950(1951),u1951(1952),u1952(1953),u1953(1954),u1954(1955),u1955(1956),u1956(1957),u1957(1958),u1958(1959),u1959(1960), |
+ u1960(1961),u1961(1962),u1962(1963),u1963(1964),u1964(1965),u1965(1966),u1966(1967),u1967(1968),u1968(1969),u1969(1970), |
+ u1970(1971),u1971(1972),u1972(1973),u1973(1974),u1974(1975),u1975(1976),u1976(1977),u1977(1978),u1978(1979),u1979(1980), |
+ u1980(1981),u1981(1982),u1982(1983),u1983(1984),u1984(1985),u1985(1986),u1986(1987),u1987(1988),u1988(1989),u1989(1990), |
+ u1990(1991),u1991(1992),u1992(1993),u1993(1994),u1994(1995),u1995(1996),u1996(1997),u1997(1998),u1998(1999),u1999(2000)} |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each power output channel. Its value |
+ ranges between 1 and total number of output channels. |
+ This value is equivalent to the output channel number at |
+ the type label of the crate or power supply, but because the SMI |
+ index starts at 1, index 1 corresponds to U0." |
+ ::= { outputEntry 1 } |
+ |
+outputName OBJECT-TYPE |
+ SYNTAX DisplayString (SIZE (1..4)) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "A textual string containing a short name of the |
+ output. If the crate is equipped with an alphanumeric |
+ display, this string is shown to identify a output channel." |
+ ::= { outputEntry 2 } |
+ |
+outputGroup OBJECT-TYPE |
+ SYNTAX Integer32 (0..1999) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The group number associated with this channel" |
+ ::= { outputEntry 3 } |
+ |
+ |
+outputStatus OBJECT-TYPE |
+ SYNTAX BITS { |
+ outputOn (0) , |
+ outputInhibit (1) , |
+ outputFailureMinSenseVoltage (2), |
+ outputFailureMaxSenseVoltage (3), |
+ outputFailureMaxTerminalVoltage (4), |
+ outputFailureMaxCurrent (5), |
+ outputFailureMaxTemperature (6), |
+ outputFailureMaxPower (7), |
+ -- reserved |
+ outputFailureTimeout (9), |
+ outputCurrentLimited (10), |
+ outputRampUp (11), |
+ outputRampDown (12), |
+ outputEnableKill(13), |
+ outputEmergencyOff (14) |
+ } |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "A bit string which shows the status (health and operating conditions) of one output channel. |
+ If a bit is set (1), the explanation is satisfied: |
+ outputOn (0), output channel is on |
+ outputInhibit(1), external (hardware-)inhibit of the output channel |
+ outputFailureMinSenseVoltage (2) Supervision limit hurt: Sense voltage is too low |
+ outputFailureMaxSenseVoltage (3), Supervision limit hurt: Sense voltage is too high |
+ outputFailureMaxTerminalVoltage (4), Supervision limit hurt: Terminal voltage is too high |
+ outputFailureMaxCurrent (5), Supervision limit hurt: Current is too high |
+ outputFailureMaxTemperature (6), Supervision limit hurt: Heat sink temperature is too high |
+ outputFailureMaxPower (7), Supervision limit hurt: Output power is too high |
+ outputFailureTimeout (9), Communication timeout between output channel and main control |
+ outputCurrentLimited (10), Current limiting is active (constant current mode) |
+ outputRampUp (11), Output voltage is increasing (e.g. after switch on) |
+ outputRampDown (12), Output voltage is decreasing (e.g. after switch off) |
+ outputEnableKill (13), EnableKill is aktive |
+ outputEmergencyOff (14), EmergencyOff event is aktive |
+ |
+ " |
+ |
+ ::= { outputEntry 4 } |
+ |
+ |
+ |
+ |
+outputMeasurementSenseVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured voltage at the sense input lines." |
+ ::= { outputEntry 5 } |
+ |
+outputMeasurementTerminalVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured voltage at the output terminals." |
+ ::= { outputEntry 6 } |
+ |
+outputMeasurementCurrent OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured output current." |
+ ::= { outputEntry 7 } |
+ |
+outputMeasurementTemperature OBJECT-TYPE |
+ SYNTAX INTEGER { ok (-128), failure(127) } |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured temperature of the power module." |
+ ::= { outputEntry 8 } |
+ |
+ |
+outputSwitch OBJECT-TYPE |
+ SYNTAX INTEGER { Off (0), On (1), resetEmergencyOff (2), setEmergencyOff (3), clearEvents (10) } |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Read: An enumerated value which shows the current state of |
+ the output channel. |
+ |
+ Write: Change the state of the channel. |
+ If the channel is On, and the write value is Off, then the channel |
+ will switch Off. |
+ If the channel is Off, and the write value is On, and if no other |
+ signals (mainInhibit, outputInhibit, outputEmergencyOff or outputFailureMaxCurrent) |
+ are active, then the channel will switch on. |
+ |
+ If the write value is resetEmergencyOff, then the channel will |
+ leave the state EmergencyOff. A write of clearEvents is necessary |
+ before the voltage can ramp up again. |
+ If the write value is setEmergencyOff, then the channel will have |
+ the state EmergencyOff, which means that the High Voltage will |
+ switch off without a ramp and reset of the outputVoltage to null volt. |
+ |
+ If the write value is clearEvents, then all failure messages |
+ of the outputStatus will be reset (all channel events, all module events |
+ and the state emergencyOff)." |
+ ::= { outputEntry 9 } |
+ |
+outputVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The nominal output voltage of the channel." |
+ ::= { outputEntry 10 } |
+ |
+outputAdjustVoltage OBJECT-TYPE |
+ SYNTAX Integer32 (-128..127) |
+ MAX-ACCESS read-write |
+ STATUS obsolete |
+ DESCRIPTION |
+ "A posibillity to make small changes of the output voltage." |
+ ::= { outputEntry 11 } |
+ |
+outputCurrent OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The current limit of the channel." |
+ ::= { outputEntry 12 } |
+ |
+outputVoltageRiseRate OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V/s" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Voltage Fall Slew Rate [V/s]. |
+ The slew rate of the output voltage if it increases (after switch on or if the Voltage has been |
+ changed). |
+ " |
+ ::= { outputEntry 13 } |
+ |
+outputVoltageFallRate OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V/s" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Voltage Rise Slew Rate [V/s]. |
+ The slew rate of the output voltage if it decreases (after switch off or if the Voltage has been |
+ changed). |
+ " |
+ ::= { outputEntry 14 } |
+ |
+outputSupervisionBehavior OBJECT-TYPE |
+ SYNTAX Integer32 (0..65535) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "A bit field packed into an integer which define the behavior of the output channel / power supply |
+ after failures. |
+ For each supervision value, a two-bit field exists. |
+ The enumeration of this value (..L+..H*2) is: |
+ WIENER LV devices |
+ 0 ignore the failure |
+ 1 switch off this channel |
+ 2 switch off all channels with the same group number |
+ 3 switch off the complete crate. |
+ iseg HV devices |
+ 0 ignore the failure |
+ 1 switch off this channel by ramp down the voltage |
+ 2 switch off this channel by a emergencyOff |
+ 3 switch off the whole board of the HV module by emergencyOff. |
+ The position of the bit fields in the integer value are: |
+ Bit 0, 1: outputFailureMinSenseVoltage |
+ Bit 2, 3: outputFailureMaxSenseVoltage |
+ Bit 4, 5: outputFailureMaxTerminalVoltage |
+ Bit 6, 7: outputFailureMaxCurrent |
+ Bit 8, 9: outputFailureMaxTemperature |
+ Bit 10, 11: outputFailureMaxPower |
+ Bit 12, 13: outputFailureInhibit |
+ Bit 14, 15: outputFailureTimeout |
+ " |
+ |
+ ::= { outputEntry 15 } |
+ |
+outputSupervisionMinSenseVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured sense voltage is below this value, the power supply |
+ performs the function defined by SupervisionAction." |
+ ::= { outputEntry 16 } |
+ |
+outputSupervisionMaxSenseVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured sense voltage is above this value, the power supply |
+ performs the function defined by SupervisionAction." |
+ ::= { outputEntry 17 } |
+ |
+outputSupervisionMaxTerminalVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured voltage at the power supply output |
+ terminals is above this value, the power supply |
+ performs the function defined by SupervisionAction." |
+ ::= { outputEntry 18 } |
+ |
+outputSupervisionMaxCurrent OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured current is above this value, the power supply |
+ performs the function defined by SupervisionAction." |
+ ::= { outputEntry 19 } |
+ |
+--outputSupervisionMaxTemperature OBJECT-TYPE wohl besser config !! |
+-- SYNTAX INTEGER |
+-- MAX-ACCESS read-write |
+-- STATUS current |
+-- DESCRIPTION |
+-- "If the measured module temperature is above this value, the power supply |
+-- performs the function defined by SupervisionAction." |
+-- ::= { outputEntry 20 } |
+ |
+ |
+ |
+outputConfigMaxSenseVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The maximum possible value of the sense voltage" |
+ ::= { outputEntry 21 } |
+ |
+outputConfigMaxTerminalVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The maximum possible value of the terminal voltage" |
+ ::= { outputEntry 22 } |
+ |
+outputConfigMaxCurrent OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The maximum possible value of the output current" |
+ ::= { outputEntry 23 } |
+ |
+outputSupervisionMaxPower OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "W" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured power (measured current * measured terminal voltage) |
+ is above this value, the power supply performs the function defined |
+ by SupervisionAction." |
+ ::= { outputEntry 24 } |
+ |
+outputCurrentRiseRate OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A/s" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Current Fall Slew Rate [A/s]. |
+ The slew rate of the output current if it increases (after |
+ switch on or if the Current has been changed). |
+ " |
+ ::= { outputEntry 25 } |
+ |
+outputCurrentFallRate OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "A/s" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Current Rise Slew Rate [A/s]. |
+ The slew rate of the output current if it decreases (after |
+ switch off or if the Current has been changed). |
+ " |
+ ::= { outputEntry 26 } |
+ |
+outputTripTimeMaxCurrent OBJECT-TYPE |
+ SYNTAX INTEGER (0..4000) |
+ UNITS "ms" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Current trip time out [ms]. |
+ The outputTripTimeMaxCurrent defines a span for the time out function. |
+ The activity is depending from the bit field outputFailureMaxCurrent |
+ of the outputSupervisionBehavior." |
+ ::= { outputEntry 27 } |
+ |
+------------------------------------------------------------------------------- |
+-- output->groups |
+------------------------------------------------------------------------------- |
+ |
+groupsEntry OBJECT-TYPE |
+ SYNTAX GroupsEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A table row" |
+ INDEX { groupsIndex } |
+ ::= { groupsTable 1 } |
+ |
+GroupsEntry ::= |
+ SEQUENCE { |
+ groupsIndex |
+ INTEGER, |
+-- outputGroupsName |
+-- DisplayString, |
+-- outputGroupsGroup |
+-- INTEGER, |
+ |
+-- outputGroupsStatus |
+-- BITS, |
+-- outputGroupsMeasurementSenseVoltage |
+-- Float, |
+-- outputMeasurementTerminalVoltage |
+-- Float, |
+-- outputMeasurementCurrent |
+-- Float, |
+-- outputMeasurementTemperature |
+-- INTEGER, |
+ |
+ |
+ groupsSwitch |
+ INTEGER |
+-- outputVoltage |
+-- Float, |
+-- outputAdjustVoltage |
+-- INTEGER, |
+-- outputCurrent |
+-- Float, |
+ |
+-- outputRampUp |
+-- Float, |
+-- outputRampDown |
+-- Float, |
+ |
+-- outputSupervisionBehavior |
+-- INTEGER, |
+-- outputSupervisionMinSenseVoltage |
+-- Float, |
+-- outputSupervisionMaxSenseVoltage |
+-- Float, |
+-- outputSupervisionMaxTerminalVoltage |
+-- Float, |
+-- outputSupervisionMaxCurrent |
+-- Float, |
+-- outputSupervisionMaxTemperature |
+-- INTEGER, |
+ |
+-- outputConfigMaxSenseVoltage |
+-- Float, |
+-- outputConfigMaxTerminalVoltage |
+-- Float, |
+-- outputConfigMaxCurrent |
+-- Float, |
+-- outputSupervisionMaxPower |
+-- Float, |
+ } |
+ |
+groupsIndex OBJECT-TYPE |
+ SYNTAX Integer32 (0..1999) |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each power output group. Its value |
+ ranges between 1 and 1999. |
+ The special group 0 is predefined and gives access to all channels. |
+ " |
+ ::= { groupsEntry 1 } |
+ |
+groupsSwitch OBJECT-TYPE |
+ SYNTAX INTEGER { undefined (-1), Off (0), On (1), resetEmergencyOff (2), setEmergencyOff(3), disableKill (4), enableKill (5), clearEvents(10) } |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Read: This function is not defined with groups of output channels. |
+ |
+ Write: Switch the state of all channels of a group. |
+ If any channel is On, and the write value is Off, then all channels |
+ will switch off. |
+ If any channel is Off, and the write value is On, and if no other |
+ signals (mainInhibit, outputInhibit, outputEmergencyOff or outputFailureMaxCurrent) |
+ are active, then all channels will switch on. |
+ |
+ If the write value is resetEmergencyOff, then all channels will |
+ leave the state EmergencyOff. A write of clearEvents is necessary |
+ before the voltage can ramp up again. |
+ If the write value is setEmergencyOff, then all channels will have |
+ the state EmergencyOff, which means that the High Voltage will |
+ switch off without a ramp and reset of the outputVoltage to null volt. |
+ |
+ If the write value is disableKILL, then all channels will switch |
+ to disableKill (outputStatus outputDisableKill). |
+ If the write value is enableKILL, then all channels will switch |
+ to enableKill (outputStatus outputEnableKill). |
+ |
+ If the write value is clearEvents, then all failure messages |
+ of the outputStatus will be cleared (all channel events, |
+ all module events and the state outputEmergencyOff will be reset)." |
+ ::= { groupsEntry 9 } |
+ |
+--groupsName OBJECT-TYPE |
+-- SYNTAX DisplayString (SIZE (1..4)) |
+-- MAX-ACCESS read-only |
+-- STATUS current |
+-- DESCRIPTION |
+-- "A textual string containing a short name of the |
+-- output. If the crate is equipped with an alphanumeric |
+-- display, this string is shown to identify a output channel." |
+-- ::= { groupsEntry 2 } |
+ |
+ |
+ |
+ |
+------------------------------------------------------------------------------- |
+-- sensor |
+------------------------------------------------------------------------------- |
+--Sensor ::= SEQUENCE { |
+-- sensorNumber Integer32, |
+-- sensorTable SensorTable |
+--} |
+ |
+sensorNumber OBJECT-TYPE |
+ SYNTAX Integer32 (0..8) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The number of temperature sensors of the crate." |
+ ::= { sensor 1 } |
+ |
+sensorTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF SensorEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A (conceptual table) of temperature sensor data." |
+ ::= { sensor 2 } |
+ |
+sensorEntry OBJECT-TYPE |
+ SYNTAX SensorEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "An entry (conceptual row) of the sensorTable." |
+ INDEX { sensorIndex } |
+ ::= { sensorTable 1 } |
+ |
+SensorEntry ::= SEQUENCE { |
+ sensorIndex INTEGER, |
+ sensorTemperature INTEGER, |
+ sensorWarningThreshold INTEGER, |
+ sensorFailureThreshold INTEGER |
+ } |
+ |
+sensorIndex OBJECT-TYPE |
+ SYNTAX INTEGER { temp1 (1), temp2(2), temp3(3), temp4(4), temp5(5), |
+ temp6(6), temp7(7), temp8(8) } |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each temperature sensor in the crate" |
+ ::= { sensorEntry 1 } |
+ |
+sensorTemperature OBJECT-TYPE |
+-- CHECK SYNTAX INTEGER { UNUSED(-128), (-127..127) } |
+ SYNTAX Integer32 (-128..127) |
+ UNITS "deg C" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured temperature of the sensor. |
+ Unused temperature probes have the special value -128" |
+ ::= { sensorEntry 2 } |
+ |
+sensorWarningThreshold OBJECT-TYPE |
+-- CHECK SYNTAX INTEGER { (0..126), DISABLED(127) } |
+ SYNTAX Integer32 (0..127) |
+ UNITS "deg C" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured temperature of the sensor is higher than this |
+ value, the fan speed of the connected fan tray is increased. |
+ The value 127 has the special meaning: channel disabled." |
+ ::= { sensorEntry 3} |
+ |
+sensorFailureThreshold OBJECT-TYPE |
+-- CHECK SYNTAX INTEGER { (0..126), DISABLED(127) } |
+ SYNTAX Integer32 (0..127) |
+ UNITS "deg C" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "If the measured temperature of the sensor is higher than this |
+ value, the power supply switches off. |
+ The value 127 has the special meaning: channel disabled." |
+ ::= { sensorEntry 4} |
+ |
+--################ |
+ |
+------------------------------------------------------------------------------- |
+-- signal |
+------------------------------------------------------------------------------- |
+--Signal ::= SEQUENCE { |
+-- numberOfAnalogInputs Integer32, |
+-- analogInputTable AnalogInputTable |
+-- numberOfAnalogOutputs Integer32, |
+-- analogOutputTable AnalogOutputTable |
+-- digitalInput BITS, |
+-- digitalOutput BITS |
+--} |
+ |
+numberOfAnalogInputs OBJECT-TYPE |
+ SYNTAX Integer32 (0..8) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The number of additional analog inputs of the crate." |
+ ::= { signal 1 } |
+ |
+analogInputTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF AnalogInputEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A (conceptual table) of analog input data." |
+ ::= { signal 2 } |
+ |
+analogInputEntry OBJECT-TYPE |
+ SYNTAX AnalogInputEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "An entry (conceptual row) of the analogInputTable." |
+ INDEX { analogInputIndex } |
+ ::= { analogInputTable 1 } |
+ |
+AnalogInputEntry ::= SEQUENCE { |
+ analogInputIndex INTEGER, |
+ analogMeasurementVoltage Float |
+ } |
+ |
+analogInputIndex OBJECT-TYPE |
+ SYNTAX Integer32 (1..8) |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each analog input of the crate" |
+ ::= { analogInputEntry 1 } |
+ |
+analogMeasurementVoltage OBJECT-TYPE |
+ SYNTAX Float |
+ UNITS "V" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured voltage of the analog input." |
+ ::= { analogInputEntry 2 } |
+ |
+ |
+digitalInput OBJECT-TYPE |
+ SYNTAX BITS { |
+ d0 (0) , |
+ d1 (1) , |
+ d2 (2) , |
+ d3 (3) |
+ } |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The value of the digital inputs." |
+ ::= { signal 5 } |
+ |
+ |
+ |
+ |
+-- ################### |
+------------------------------------------------------------------------------- |
+-- communication |
+------------------------------------------------------------------------------- |
+--Communication ::= SEQUENCE { |
+-- snmp Snmp, |
+-- tcpip Tcpip, |
+-- http Http, |
+-- telnet Telnet, |
+-- canbus Canbus, |
+-- rs232 RS232 |
+--} |
+ |
+------------------------------------------------------------------------------- |
+-- communication.snmp |
+------------------------------------------------------------------------------- |
+snmp OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "SNMP configuration." |
+ ::= { communication 1 } |
+ |
+--Snmp ::= SEQUENCE { |
+-- snmpCommunityTable SnmpCommunityTable, |
+-- snmpPort INTEGER |
+--} |
+ |
+snmpCommunityTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF SnmpCommunityEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "The SNMP community string table for different views." |
+ ::= { snmp 1 } |
+ |
+snmpCommunityEntry OBJECT-TYPE |
+ SYNTAX SnmpCommunityEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "One table row." |
+ INDEX { snmpAccessRight } |
+ ::= { snmpCommunityTable 1 } |
+ |
+ |
+SnmpCommunityEntry ::= SEQUENCE { |
+ snmpAccessRight INTEGER, |
+ snmpCommunityName OCTET STRING |
+} |
+ |
+snmpAccessRight OBJECT-TYPE |
+ SYNTAX INTEGER { public (1), private (2), admin (3), guru (4) } |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each access right" |
+ ::= { snmpCommunityEntry 1 } |
+ |
+snmpCommunityName OBJECT-TYPE |
+ SYNTAX OCTET STRING (SIZE (0..14)) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The SNMP community names for different views. The rights of the different communities are: |
+ public no write access |
+ private can switch power on/off, generate system reset |
+ admin can change supervision levels |
+ guru can change output voltage & current (this may destroy hardware if done wrong!) |
+ Setting a community name to a zero-length string completly |
+ disables the access to this view. If there is no higher- |
+ privileged community, the community name can only changed |
+ by direct access to the crate (not via network)! |
+ " |
+ ::= { snmpCommunityEntry 2} |
+ |
+snmpPort OBJECT-TYPE |
+ SYNTAX Integer32 |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The UDP port number of the SNMP protocol" |
+ ::= { snmp 2} |
+ |
+------------------------------------------------------------------------------- |
+-- communication.canTunnel |
+------------------------------------------------------------------------------- |
+can OBJECT-IDENTITY |
+ STATUS current |
+ DESCRIPTION |
+ "CAN-Bus tunnel via SNMP." |
+ ::= { communication 2 } |
+ |
+canBitRate OBJECT-TYPE |
+ SYNTAX Integer32 |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Control of the CAN-Bus. |
+ The value defines the bit rate of the CAN-bus interface. |
+ A write disconnects the CAN interface from the ISEG modules and connects |
+ it to the SNMP communication. Both the receive and transmit fifos are |
+ cleared and the CAN interface is initialized with the selected bit rate. |
+ The special bit rate 0 disables the tunnel and switches back to normal operation. |
+ " |
+ ::= { can 1 } |
+ |
+canReceive OBJECT-TYPE |
+ SYNTAX OCTET STRING (SIZE (14)) |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "Control of the CAN-Bus Receive FIFO. |
+ A read access returns the total number of CAN messages stored in the receive |
+ fifo and the oldest message. |
+ This message is removed from the fifo. |
+ The OCTET STRING data is formatted according to the CANviaSNMP structure. |
+ " |
+ ::= { can 2 } |
+ |
+canTransmit OBJECT-TYPE |
+ SYNTAX OCTET STRING (SIZE (14)) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Control of the CAN-Bus Transmit FIFO. |
+ A read access returns the total number of CAN messages stored in the transmit |
+ fifo and a NULL message. |
+ A write inserts the CAN message into the transmit fifo. This message will be |
+ transmitted via the CAN interface later. The total number of CAN messages |
+ stored in the transmit fifo and the recent message are returned. |
+ The OCTET STRING data is formatted according to the CANviaSNMP structure. |
+ " |
+ ::= { can 3 } |
+ |
+------------------------------------------------------------------------------- |
+-- communication.... |
+------------------------------------------------------------------------------- |
+ |
+-- other future entries: |
+-- +-tcpip |
+-- | | |
+-- | +- tcpipIpAddress |
+-- | +- tcpipGateway |
+-- | +- tcpipSubnetMask |
+-- | +- tcpipNegotiation |
+-- | +- tcpipMAC |
+-- | |
+-- +-http |
+-- | | |
+-- | +- httpPort |
+-- | +- httpWriteEnable |
+-- | |
+-- +-telnet |
+-- | | |
+-- | +- telnetPort |
+-- | |
+-- +-canbus |
+-- | | |
+-- | +- address |
+-- | +- address2 |
+-- | +- speed |
+-- | |
+-- +-rs232 |
+-- | | |
+-- | +- ? |
+ |
+ |
+ |
+------------------------------------------------------------------------------- |
+-- powersupply |
+------------------------------------------------------------------------------- |
+Powersupply ::= SEQUENCE { |
+ --psFirmwareVersion DisplayString, |
+ psSerialNumber DisplayString, |
+ psOperatingTime Integer32, |
+ psDirectAccess OCTET STRING |
+} |
+ |
+--integrated in system.sysDesc |
+--psFirmwareVersion OBJECT-TYPE |
+-- SYNTAX DisplayString |
+-- MAX-ACCESS read-only |
+-- STATUS current |
+-- DESCRIPTION |
+-- "The firmware version of the power supply main CPU." |
+-- ::= { powersupply 1 } |
+ |
+psSerialNumber OBJECT-TYPE |
+ SYNTAX DisplayString |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The serial number of the power supply." |
+ ::= { powersupply 2 } |
+ |
+psOperatingTime OBJECT-TYPE |
+ SYNTAX Integer32 |
+ UNITS "s" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The time in seconds for how long the power supply was switched on." |
+ ::= { powersupply 3 } |
+ |
+psDirectAccess OBJECT-TYPE |
+ SYNTAX OCTET STRING (SIZE (1..14)) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "Direct data transfer to the UEP6000 power supply. |
+ A read access returns nothing, a write access returns the |
+ response of the power supply. |
+ " |
+ ::= { powersupply 1024 } |
+ |
+------------------------------------------------------------------------------- |
+-- fantray |
+------------------------------------------------------------------------------- |
+--Fantray ::= SEQUENCE { |
+-- fanFirmwareVersion DisplayString, |
+-- fanSerialNumber OCTET STRING, |
+-- fanOperatingTime Integer32, |
+-- fanAirTemperature INTEGER, |
+-- fanSwitchOffDelay INTEGER, |
+-- fanNominalSpeed INTEGER, |
+-- fanNumberOfFans INTEGER, |
+-- fanSpeedTable FanSpeedTable |
+--} |
+ |
+--integrated in system.sysDesc |
+--fanFirmwareVersion OBJECT-TYPE |
+-- SYNTAX DisplayString |
+-- MAX-ACCESS read-only |
+-- STATUS current |
+-- DESCRIPTION |
+-- "The firmware version of the fan tray CPU." |
+-- ::= { fantray 1 } |
+ |
+fanSerialNumber OBJECT-TYPE |
+ SYNTAX DisplayString (SIZE (0..14)) |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The serial number of the fan tray." |
+ ::= { fantray 2 } |
+ |
+fanOperatingTime OBJECT-TYPE |
+ SYNTAX Integer32 |
+ UNITS "s" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The time in seconds for how long the fan tray was switched on." |
+ ::= { fantray 3 } |
+ |
+fanAirTemperature OBJECT-TYPE |
+ SYNTAX Integer32 |
+ UNITS "deg C" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The temperature of the fan tray inlet air." |
+ ::= { fantray 4 } |
+ |
+fanSwitchOffDelay OBJECT-TYPE |
+ SYNTAX Integer32 (0 .. 900) |
+ UNITS "s" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The maximum time in seconds for which the fans will continue running |
+ after the power supply has been switched off. This feature is used |
+ to cool down the electronics after switching off. |
+ " |
+ ::= { fantray 5 } |
+ |
+fanNominalSpeed OBJECT-TYPE |
+-- CHECK SYNTAX INTEGER { (0) , (1200..3600) } |
+ SYNTAX Integer32 (0..3600) |
+ UNITS "RPM" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The nominal fan rotation speed (RPM, Revolutions Per Minute) |
+ Value 0 does switch off the fans (only allowed if at least |
+ one rack temperature sensor is present). |
+ Values 1..1199 are not allowed" |
+ ::= { fantray 6 } |
+ |
+fanNumberOfFans OBJECT-TYPE |
+ SYNTAX Integer32 ( 0..12 ) |
+ UNITS "Fans" |
+ MAX-ACCESS read-write |
+ STATUS current |
+ DESCRIPTION |
+ "The number of installed fans" |
+ ::= { fantray 7 } |
+ |
+ |
+fanSpeedTable OBJECT-TYPE |
+ SYNTAX SEQUENCE OF FanSpeedEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A list of fanSpeedEntries." |
+ ::= { fantray 8 } |
+ |
+fanSpeedEntry OBJECT-TYPE |
+ SYNTAX FanSpeedEntry |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A table row" |
+ INDEX { fanNumber } |
+ ::= { fanSpeedTable 1 } |
+ |
+FanSpeedEntry ::= SEQUENCE { |
+ fanNumber |
+ INTEGER, |
+ fanSpeed |
+ INTEGER |
+} |
+ |
+fanNumber OBJECT-TYPE |
+ SYNTAX Integer32 ( 1..12 ) |
+ MAX-ACCESS not-accessible |
+ STATUS current |
+ DESCRIPTION |
+ "A unique number for each fan." |
+ ::= { fanSpeedEntry 1 } |
+ |
+fanSpeed OBJECT-TYPE |
+ SYNTAX Integer32 |
+ UNITS "RPM" |
+ MAX-ACCESS read-only |
+ STATUS current |
+ DESCRIPTION |
+ "The measured fan rotation speed (RPM, Revolutions Per Minute)" |
+ ::= { fanSpeedEntry 2 } |
+ |
+ |
+ |
+ |
+ |
+------------------------------------------------------------------------------- |
+-- rack |
+------------------------------------------------------------------------------- |
+-- this is reserved for futer items (BIN serial number, plug&play, ...) |
+ |
+ |
+ |
+------------------------------------------------------------------------------- |
+END |
Index: sipmscan/trunk/mpod/instructions_mpod.txt |
=================================================================== |
--- sipmscan/trunk/mpod/instructions_mpod.txt (nonexistent) |
+++ sipmscan/trunk/mpod/instructions_mpod.txt (revision 118) |
@@ -0,0 +1,6 @@ |
+mpod_voltage.sh has the following options: |
+ --resetall Resets all outputs |
+ -r [integer] Resets output selected with [integer] |
+ -o [integer] Selects output [integer] |
+ -v [float] Sets the voltage to [float]. Must be used in combination with -o |
+ -s [0/1] Turns output on (1) or off (0). Must be used in combination with -o |
Index: sipmscan/trunk/mpod/mpod_voltage.sh |
=================================================================== |
--- sipmscan/trunk/mpod/mpod_voltage.sh (nonexistent) |
+++ sipmscan/trunk/mpod/mpod_voltage.sh (revision 118) |
@@ -0,0 +1,114 @@ |
+#!/bin/bash |
+ |
+# Commands: |
+# snmpset - sets the selected attribute of a single channel |
+# snmpget - prints the selected atribute of a single channel |
+# snmpwalk - prints the selected attribute of all channels |
+# |
+# Attributes: |
+# outputVoltage - float(F), R/W |
+# outputCurrent - float(F), R/W |
+# outputMeasurementSenseVoltage - float(F), R |
+# outputMeasurementCurrent - float(F), R |
+# outputSwitch - integer(i), R/W |
+# outputVoltageRiseRate - float(F), R/W |
+# outputStatus - bits, R |
+ |
+#ip=194.249.156.124 |
+#ip=f9mpod.ijs.si |
+ |
+#if [$1 -lt 99]; then |
+# if [$2 -lt 74]; then |
+# echo "Setting bias to " $2 |
+# snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputVoltage.$1 F $2 |
+# else |
+# echo "Bias voltage needs to be smaller than 74V." |
+# fi |
+#else if [$1 -gt 99]; then |
+# if [$2 -lt 35]; then |
+# echo "Setting bias to " $2 |
+# snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputVoltage.$1 F $2 |
+# else |
+# echo "Bias voltage needs to be smaller than 35V." |
+# fi |
+#fi |
+ |
+function reset_all |
+{ |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.1 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.2 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.3 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.4 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.5 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.6 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.7 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.8 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.101 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.102 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.103 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.104 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.105 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.106 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.107 i 10 |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.108 i 10 |
+ |
+ exit 0 |
+} |
+ |
+ip=f9mpod.ijs.si |
+ |
+# save all arguments to array args |
+args=("$@") |
+ |
+argcnt=0 |
+outSel=-1 |
+outVolt=-1 |
+outSw=-1 |
+resetOut=-1 |
+getOut=-1 |
+ |
+# search the arguments for valid options |
+for ARG in "${args[@]}"; do |
+ if [ "$ARG" == "--resetall" ]; then |
+ reset_all |
+ elif [ "$ARG" == "-g" ]; then |
+ getOut=1 |
+ elif [ "$ARG" == "-r" ]; then |
+ resetOut=${args[$argcnt+1]} |
+ elif [ "$ARG" == "-o" ]; then |
+ outSel=${args[$argcnt+1]} |
+ elif [ "$ARG" == "-v" ]; then |
+ outVolt=${args[$argcnt+1]} |
+ elif [ "$ARG" == "-s" ]; then |
+ outSw=${args[$argcnt+1]} |
+ fi |
+ (( argcnt++ )) |
+done |
+ |
+if [ $resetOut != -1 ]; then |
+ if [ $resetOut -ge 1 -a $resetOut -le 8 ] || [ $resetOut -ge 101 -a $resetOut -le 108 ]; then |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.$resetOut i 10 |
+ else |
+ echo "Please select output between 1 and 8 (channel 1) or 101 and 108 (output 2)." |
+ fi |
+else |
+ if [ $outSel != -1 ]; then |
+ # limit the channels to the correct value |
+ if [ $outSel -ge 1 -a $outSel -le 8 ] || [ $outSel -ge 101 -a $outSel -le 108 ]; then |
+ if [ $outVolt != -1 ]; then |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputVoltage.$outSel F $outVolt |
+ fi |
+ if [ $outSw != -1 ]; then |
+ snmpset -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.$outSel i $outSw |
+ fi |
+ if [ $getOut != -1 ]; then |
+ snmpget -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputVoltage.$outSel |
+ snmpget -v 2c -M +. -m +WIENER-CRATE-MIB -c guru $ip outputSwitch.$outSel |
+ fi |
+ else |
+ echo "Please select output between 1 and 8 (channel 1) or 101 and 108 (output 2)." |
+ fi |
+ fi |
+fi |
+ |
+exit 0 |
/sipmscan/trunk/mpod/mpod_voltage.sh |
---|
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Index: sipmscan/trunk/mpod/test.sh |
=================================================================== |
--- sipmscan/trunk/mpod/test.sh (nonexistent) |
+++ sipmscan/trunk/mpod/test.sh (revision 118) |
@@ -0,0 +1,7 @@ |
+#!/bin/bash |
+ |
+echo "Bash start." |
+sleep $1 |
+echo "Bash end." |
+ |
+exit 0 |
Index: sipmscan/trunk/mpod/test.sh.bak |
=================================================================== |
--- sipmscan/trunk/mpod/test.sh.bak (nonexistent) |
+++ sipmscan/trunk/mpod/test.sh.bak (revision 118) |
@@ -0,0 +1,7 @@ |
+#!/bin/bash |
+ |
+echo "Bash start." |
+sleep 5 |
+echo "Bash end." |
+ |
+exit 0 |
Index: sipmscan/trunk/root_include.h |
=================================================================== |
--- sipmscan/trunk/root_include.h (nonexistent) |
+++ sipmscan/trunk/root_include.h (revision 118) |
@@ -0,0 +1,214 @@ |
+#ifndef _root_include_h_ |
+#define _root_include_h_ |
+ |
+// ROOT base includes |
+#ifndef ROOT_TRootBrowser |
+#include "TRootBrowser.h" |
+#endif |
+#ifndef ROOT_IOstream |
+#include "Riostream.h" |
+#endif |
+#ifndef ROOT_TSystem |
+#include "TSystem.h" |
+#endif |
+#ifndef ROOT_TApplication |
+#include "TApplication.h" |
+#endif |
+#ifndef ROOT_TROOT |
+#include "TROOT.h" |
+#endif |
+#ifndef ROOT_RQ_Object |
+#include "RQ_OBJECT.h" |
+#endif |
+#ifndef ROOT_TGClient |
+#include "TGClient.h" |
+#endif |
+#ifndef ROOT_TGResourcePool |
+#include "TGResourcePool.h" |
+#endif |
+ |
+// ROOT GUI frame includes |
+#ifndef ROOT_TGFrame |
+#include "TGFrame.h" |
+#endif |
+#ifndef ROOT_TGDockableFrame |
+#include "TGDockableFrame.h" |
+#endif |
+#ifndef ROOT_TGMenu |
+#include "TGMenu.h" |
+#endif |
+#ifndef ROOT_TGMdiDecorFrame |
+#include "TGMdiDecorFrame.h" |
+#endif |
+#ifndef ROOT_TGMdiFrame |
+#include "TGMdiFrame.h" |
+#endif |
+#ifndef ROOT_TGMdiMainFrame |
+#include "TGMdiMainFrame.h" |
+#endif |
+#ifndef ROOT_TGMdiMenu |
+#include "TGMdiMenu.h" |
+#endif |
+#ifndef ROOT_TGMdi |
+#include "TGMdi.h" |
+#endif |
+#ifndef ROOT_TG3DLine |
+#include "TG3DLine.h" |
+#endif |
+#ifndef ROOT_TGStatusBar |
+#include "TGStatusBar.h" |
+#endif |
+ |
+// ROOT GUI builder incudes (not needed) |
+#ifndef ROOT_TRootGuiBuilder |
+#include "TRootGuiBuilder.h" |
+#endif |
+#ifndef ROOT_TGuiBldHintsButton |
+#include "TGuiBldHintsButton.h" |
+#endif |
+#ifndef ROOT_TGuiBldHintsEditor |
+#include "TGuiBldHintsEditor.h" |
+#endif |
+#ifndef ROOT_TGuiBldEditor |
+#include "TGuiBldEditor.h" |
+#endif |
+#ifndef ROOT_TGuiBldDragManager |
+#include "TGuiBldDragManager.h" |
+#endif |
+ |
+// ROOT GUI object includes |
+#ifndef ROOT_TGListBox |
+#include "TGListBox.h" |
+#endif |
+#ifndef ROOT_TGNumberEntry |
+#include "TGNumberEntry.h" |
+#endif |
+#ifndef ROOT_TGScrollBar |
+#include "TGScrollBar.h" |
+#endif |
+#ifndef ROOT_TGFileDialog |
+#include "TGFileDialog.h" |
+#endif |
+#ifndef ROOT_TGShutter |
+#include "TGShutter.h" |
+#endif |
+#ifndef ROOT_TGButtonGroup |
+#include "TGButtonGroup.h" |
+#endif |
+#ifndef ROOT_TGCanvas |
+#include "TGCanvas.h" |
+#endif |
+#ifndef ROOT_TGButton |
+#include "TGButton.h" |
+#endif |
+#ifndef ROOT_TGTextEdit |
+#include "TGTextEdit.h" |
+#endif |
+#ifndef ROOT_TGLabel |
+#include "TGLabel.h" |
+#endif |
+#ifndef ROOT_TGView |
+#include "TGView.h" |
+#endif |
+#ifndef ROOT_TGTab |
+#include "TGTab.h" |
+#endif |
+#ifndef ROOT_TGListView |
+#include "TGListView.h" |
+#endif |
+#ifndef ROOT_TGSplitter |
+#include "TGSplitter.h" |
+#endif |
+#ifndef ROOT_TGListTree |
+#include "TGListTree.h" |
+#endif |
+#ifndef ROOT_TGToolTip |
+#include "TGToolTip.h" |
+#endif |
+#ifndef ROOT_TGToolBar |
+#include "TGToolBar.h" |
+#endif |
+#ifndef ROOT_TRootEmbeddedCanvas |
+#include "TRootEmbeddedCanvas.h" |
+#endif |
+#ifndef ROOT_TCanvas |
+#include "TCanvas.h" |
+#endif |
+#ifndef ROOT_TGComboBox |
+#include "TGComboBox.h" |
+#endif |
+#ifndef ROOT_TGProgressBar |
+#include "TGProgressBar.h" |
+#endif |
+#ifndef ROOT_TGTextEntry |
+#include "TGTextEntry.h" |
+#endif |
+#ifndef ROOT_TGMsgBox |
+#include "TGMsgBox.h" |
+#endif |
+#ifndef ROOT_TGSlider |
+#include "TGSlider.h" |
+#endif |
+#ifndef ROOT_TGFSContainer |
+#include "TGFSContainer.h" |
+#endif |
+#ifndef ROOT_TGFSComboBox |
+#include "TGFSComboBox.h" |
+#endif |
+ |
+// ROOT File browser includes |
+#ifndef ROOT_TSystemDir |
+#include "TSystemDirectory.h" |
+#endif |
+#ifndef ROOT_TTree |
+#include "TTree.h" |
+#endif |
+#ifndef ROOT_TFile |
+#include "TFile.h" |
+#endif |
+ |
+// ROOT plotting includes |
+#ifndef ROOT_TPaveStats |
+#include "TPaveStats.h" |
+#endif |
+#ifndef ROOT_TGraph2D |
+#include "TGraph2D.h" |
+#endif |
+#ifndef ROOT_TLatex |
+#include "TLatex.h" |
+#endif |
+#ifndef ROOT_TGraphErrors |
+#include "TGraphErrors.h" |
+#endif |
+#ifndef ROOT_TStyle |
+#include "TStyle.h" |
+#endif |
+#ifndef ROOT_TPaletteAxis |
+#include "TPaletteAxis.h" |
+#endif |
+#ifndef ROOT_TGraph |
+#include "TGraph.h" |
+#endif |
+#ifndef ROOT_TH1F |
+#include "TH1F.h" |
+#endif |
+#ifndef ROOT_TH2F |
+#include "TH2F.h" |
+#endif |
+#ifndef ROOT_TF1 |
+#include "TF1.h" |
+#endif |
+#ifndef ROOT_TSpectrum |
+#include "TSpectrum.h" |
+#endif |
+#ifndef ROOT_TVirtualFitter |
+#include "TVirtualFitter.h" |
+#endif |
+#ifndef ROOT_TMath |
+#include "TMath.h" |
+#endif |
+#ifndef ROOT_TRandom |
+#include "TRandom.h" |
+#endif |
+ |
+#endif |
Index: sipmscan/trunk/start.cxx |
=================================================================== |
--- sipmscan/trunk/start.cxx (nonexistent) |
+++ sipmscan/trunk/start.cxx (revision 118) |
@@ -0,0 +1,8 @@ |
+ |
+int start(char *path="."){ |
+ gROOT->SetMacroPath(path); |
+ gROOT->ProcessLine(".L libdaqusb.so"); |
+ gROOT->ProcessLine(".L libvxi11.so"); |
+ gROOT->ProcessLine(".L windowed_test.C+"); |
+ windowed_test(); |
+} |
/sipmscan/trunk/start.cxx |
---|
Property changes: |
Added: svn:executable |
## -0,0 +1 ## |
+* |
\ No newline at end of property |
Index: sipmscan/trunk/usb.h |
=================================================================== |
--- sipmscan/trunk/usb.h (nonexistent) |
+++ sipmscan/trunk/usb.h (revision 118) |
@@ -0,0 +1,344 @@ |
+/* |
+ * Prototypes, structure definitions and macros. |
+ * |
+ * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com> |
+ * |
+ * This library is covered by the LGPL, read LICENSE for details. |
+ * |
+ * This file (and only this file) may alternatively be licensed under the |
+ * BSD license as well, read LICENSE for details. |
+ */ |
+#ifndef __USB_H__ |
+#define __USB_H__ |
+ |
+#include <unistd.h> |
+#include <stdlib.h> |
+#include <stdint.h> |
+#include <limits.h> |
+ |
+#include <sys/param.h> |
+#include <dirent.h> |
+ |
+/* |
+ * USB spec information |
+ * |
+ * This is all stuff grabbed from various USB specs and is pretty much |
+ * not subject to change |
+ */ |
+ |
+/* |
+ * Device and/or Interface Class codes |
+ */ |
+#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ |
+#define USB_CLASS_AUDIO 1 |
+#define USB_CLASS_COMM 2 |
+#define USB_CLASS_HID 3 |
+#define USB_CLASS_PRINTER 7 |
+#define USB_CLASS_PTP 6 |
+#define USB_CLASS_MASS_STORAGE 8 |
+#define USB_CLASS_HUB 9 |
+#define USB_CLASS_DATA 10 |
+#define USB_CLASS_VENDOR_SPEC 0xff |
+ |
+/* |
+ * Descriptor types |
+ */ |
+#define USB_DT_DEVICE 0x01 |
+#define USB_DT_CONFIG 0x02 |
+#define USB_DT_STRING 0x03 |
+#define USB_DT_INTERFACE 0x04 |
+#define USB_DT_ENDPOINT 0x05 |
+ |
+#define USB_DT_HID 0x21 |
+#define USB_DT_REPORT 0x22 |
+#define USB_DT_PHYSICAL 0x23 |
+#define USB_DT_HUB 0x29 |
+ |
+/* |
+ * Descriptor sizes per descriptor type |
+ */ |
+#define USB_DT_DEVICE_SIZE 18 |
+#define USB_DT_CONFIG_SIZE 9 |
+#define USB_DT_INTERFACE_SIZE 9 |
+#define USB_DT_ENDPOINT_SIZE 7 |
+#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ |
+#define USB_DT_HUB_NONVAR_SIZE 7 |
+ |
+/* All standard descriptors have these 2 fields in common */ |
+struct usb_descriptor_header { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+} __attribute__ ((packed)); |
+ |
+/* String descriptor */ |
+struct usb_string_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint16_t wData[1]; |
+} __attribute__ ((packed)); |
+ |
+/* HID descriptor */ |
+struct usb_hid_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint16_t bcdHID; |
+ uint8_t bCountryCode; |
+ uint8_t bNumDescriptors; |
+ /* uint8_t bReportDescriptorType; */ |
+ /* uint16_t wDescriptorLength; */ |
+ /* ... */ |
+} __attribute__ ((packed)); |
+ |
+/* Endpoint descriptor */ |
+#define USB_MAXENDPOINTS 32 |
+struct usb_endpoint_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint8_t bEndpointAddress; |
+ uint8_t bmAttributes; |
+ uint16_t wMaxPacketSize; |
+ uint8_t bInterval; |
+ uint8_t bRefresh; |
+ uint8_t bSynchAddress; |
+ |
+ unsigned char *extra; /* Extra descriptors */ |
+ int extralen; |
+}; |
+ |
+#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ |
+#define USB_ENDPOINT_DIR_MASK 0x80 |
+ |
+#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ |
+#define USB_ENDPOINT_TYPE_CONTROL 0 |
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 |
+#define USB_ENDPOINT_TYPE_BULK 2 |
+#define USB_ENDPOINT_TYPE_INTERRUPT 3 |
+ |
+/* Interface descriptor */ |
+#define USB_MAXINTERFACES 32 |
+struct usb_interface_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint8_t bInterfaceNumber; |
+ uint8_t bAlternateSetting; |
+ uint8_t bNumEndpoints; |
+ uint8_t bInterfaceClass; |
+ uint8_t bInterfaceSubClass; |
+ uint8_t bInterfaceProtocol; |
+ uint8_t iInterface; |
+ |
+ struct usb_endpoint_descriptor *endpoint; |
+ |
+ unsigned char *extra; /* Extra descriptors */ |
+ int extralen; |
+}; |
+ |
+#define USB_MAXALTSETTING 128 /* Hard limit */ |
+struct usb_interface { |
+ struct usb_interface_descriptor *altsetting; |
+ |
+ int num_altsetting; |
+}; |
+ |
+/* Configuration descriptor information.. */ |
+#define USB_MAXCONFIG 8 |
+struct usb_config_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint16_t wTotalLength; |
+ uint8_t bNumInterfaces; |
+ uint8_t bConfigurationValue; |
+ uint8_t iConfiguration; |
+ uint8_t bmAttributes; |
+ uint8_t MaxPower; |
+ |
+ struct usb_interface *interface; |
+ |
+ unsigned char *extra; /* Extra descriptors */ |
+ int extralen; |
+}; |
+ |
+/* Device descriptor */ |
+struct usb_device_descriptor { |
+ uint8_t bLength; |
+ uint8_t bDescriptorType; |
+ uint16_t bcdUSB; |
+ uint8_t bDeviceClass; |
+ uint8_t bDeviceSubClass; |
+ uint8_t bDeviceProtocol; |
+ uint8_t bMaxPacketSize0; |
+ uint16_t idVendor; |
+ uint16_t idProduct; |
+ uint16_t bcdDevice; |
+ uint8_t iManufacturer; |
+ uint8_t iProduct; |
+ uint8_t iSerialNumber; |
+ uint8_t bNumConfigurations; |
+} __attribute__ ((packed)); |
+ |
+struct usb_ctrl_setup { |
+ uint8_t bRequestType; |
+ uint8_t bRequest; |
+ uint16_t wValue; |
+ uint16_t wIndex; |
+ uint16_t wLength; |
+} __attribute__ ((packed)); |
+ |
+/* |
+ * Standard requests |
+ */ |
+#define USB_REQ_GET_STATUS 0x00 |
+#define USB_REQ_CLEAR_FEATURE 0x01 |
+/* 0x02 is reserved */ |
+#define USB_REQ_SET_FEATURE 0x03 |
+/* 0x04 is reserved */ |
+#define USB_REQ_SET_ADDRESS 0x05 |
+#define USB_REQ_GET_DESCRIPTOR 0x06 |
+#define USB_REQ_SET_DESCRIPTOR 0x07 |
+#define USB_REQ_GET_CONFIGURATION 0x08 |
+#define USB_REQ_SET_CONFIGURATION 0x09 |
+#define USB_REQ_GET_INTERFACE 0x0A |
+#define USB_REQ_SET_INTERFACE 0x0B |
+#define USB_REQ_SYNCH_FRAME 0x0C |
+ |
+#define USB_TYPE_STANDARD (0x00 << 5) |
+#define USB_TYPE_CLASS (0x01 << 5) |
+#define USB_TYPE_VENDOR (0x02 << 5) |
+#define USB_TYPE_RESERVED (0x03 << 5) |
+ |
+#define USB_RECIP_DEVICE 0x00 |
+#define USB_RECIP_INTERFACE 0x01 |
+#define USB_RECIP_ENDPOINT 0x02 |
+#define USB_RECIP_OTHER 0x03 |
+ |
+/* |
+ * Various libusb API related stuff |
+ */ |
+ |
+#define USB_ENDPOINT_IN 0x80 |
+#define USB_ENDPOINT_OUT 0x00 |
+ |
+/* Error codes */ |
+#define USB_ERROR_BEGIN 500000 |
+ |
+/* |
+ * This is supposed to look weird. This file is generated from autoconf |
+ * and I didn't want to make this too complicated. |
+ */ |
+#if 0 |
+#define USB_LE16_TO_CPU(x) do { x = ((x & 0xff) << 8) | ((x & 0xff00) >> 8); } while(0) |
+#else |
+#define USB_LE16_TO_CPU(x) |
+#endif |
+ |
+/* Data types */ |
+struct usb_device; |
+struct usb_bus; |
+ |
+/* |
+ * To maintain compatibility with applications already built with libusb, |
+ * we must only add entries to the end of this structure. NEVER delete or |
+ * move members and only change types if you really know what you're doing. |
+ */ |
+#ifdef PATH_MAX |
+#define LIBUSB_PATH_MAX PATH_MAX |
+#else |
+#define LIBUSB_PATH_MAX 4096 |
+#endif |
+struct usb_device { |
+ struct usb_device *next, *prev; |
+ |
+ char filename[LIBUSB_PATH_MAX + 1]; |
+ |
+ struct usb_bus *bus; |
+ |
+ struct usb_device_descriptor descriptor; |
+ struct usb_config_descriptor *config; |
+ |
+ void *dev; /* Darwin support */ |
+ |
+ uint8_t devnum; |
+ |
+ unsigned char num_children; |
+ struct usb_device **children; |
+}; |
+ |
+struct usb_bus { |
+ struct usb_bus *next, *prev; |
+ |
+ char dirname[LIBUSB_PATH_MAX + 1]; |
+ |
+ struct usb_device *devices; |
+ uint32_t location; |
+ |
+ struct usb_device *root_dev; |
+}; |
+ |
+struct usb_dev_handle; |
+typedef struct usb_dev_handle usb_dev_handle; |
+ |
+/* Variables */ |
+extern struct usb_bus *usb_busses; |
+ |
+#ifdef __cplusplus |
+extern "C" { |
+#endif |
+ |
+/* Function prototypes */ |
+ |
+/* usb.c */ |
+usb_dev_handle *usb_open(struct usb_device *dev); |
+int usb_close(usb_dev_handle *dev); |
+int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, |
+ size_t buflen); |
+int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, |
+ size_t buflen); |
+ |
+/* descriptors.c */ |
+int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, |
+ unsigned char type, unsigned char index, void *buf, int size); |
+int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, |
+ unsigned char index, void *buf, int size); |
+ |
+/* <arch>.c */ |
+int usb_bulk_write(usb_dev_handle *dev, int ep, const char *bytes, int size, |
+ int timeout); |
+int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, |
+ int timeout); |
+int usb_interrupt_write(usb_dev_handle *dev, int ep, const char *bytes, int size, |
+ int timeout); |
+int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, |
+ int timeout); |
+int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, |
+ int value, int index, char *bytes, int size, int timeout); |
+int usb_set_configuration(usb_dev_handle *dev, int configuration); |
+int usb_claim_interface(usb_dev_handle *dev, int interface); |
+int usb_release_interface(usb_dev_handle *dev, int interface); |
+int usb_set_altinterface(usb_dev_handle *dev, int alternate); |
+int usb_resetep(usb_dev_handle *dev, unsigned int ep); |
+int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); |
+int usb_reset(usb_dev_handle *dev); |
+ |
+#if 1 |
+#define LIBUSB_HAS_GET_DRIVER_NP 1 |
+int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, |
+ unsigned int namelen); |
+#define LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP 1 |
+int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface); |
+#endif |
+ |
+char *usb_strerror(void); |
+ |
+void usb_init(void); |
+void usb_set_debug(int level); |
+int usb_find_busses(void); |
+int usb_find_devices(void); |
+struct usb_device *usb_device(usb_dev_handle *dev); |
+struct usb_bus *usb_get_busses(void); |
+ |
+#ifdef __cplusplus |
+} |
+#endif |
+ |
+#endif /* __USB_H__ */ |
+ |
Index: sipmscan/trunk/vxi11_i686/CHANGELOG.txt |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/CHANGELOG.txt (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/CHANGELOG.txt (revision 118) |
@@ -0,0 +1,199 @@ |
+------------------------------------------------------------------------------ |
+vxi11_1.08 - 3/09/2009 |
+ |
+Added a sanity check for link->maxRecvSize to make sure it's >0. This gets |
+around a bug in some versions of the Agilent Infiniium scope software. |
+ |
+Changed the erroneous strncpy() to memcpy() in vxi11_send, as we could be |
+sending binary data (not just strings). |
+ |
+Changed a lot of char *'s to const char *'s in an attempt to get rid of |
+pedantic gcc compiler warnings. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.07 - 9/10/2007 |
+ |
+Minor change to vxi11_receive_data_block(), this fn now copes with instruments |
+that return just "#0" (for whatever reason). Suggestion by Jarek Sadowski, |
+gratefully received. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.06 - 31/08/2007 |
+ |
+Bug fix in vxi11_receive(), to ensure that no more than "len" bytes are ever |
+received (and so avoiding a segmentation fault). This was a bug introduced in |
+release 1.04 whilst making some other changes to the vxi11_receive() fn. |
+ |
+Many thanks to Rob Penny for spotting the bug and providing a patch. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.05 - 11/07/2007 |
+ |
+Added the ability to specify a "device name" when calling vxi11_open_device(). |
+For regular VXI11-based instruments, such as scopes and AFGs, the device name |
+is usually "hard wired" to be "inst0", and up to now this has been hard wired |
+into the vxi11_user code. However, devices such as LAN to GPIB gateways need |
+some way of distinguishing between different devices... they are a single |
+client (one IP address), with multiple devices. |
+ |
+The vxi11_user fn, vxi11_open_device(), now takes a third argument |
+(char *device). |
+This gets passed to the core vxi11_open_device() fn (the one that deals with |
+separate clients and links), and the core vxi11_open_link() fn; these two |
+core functions have also had an extra parameter added accordingly. In order |
+to not break the API, a wrapper function is provided in the form of the |
+original vxi11_open_device() fn, that just takes 2 arguments |
+(char *ip, CLINK *clink), this then passes "inst0" as the device argument. |
+Backwards-compatible wrappers for the core functions have NOT been provided. |
+These are generally not used from userland anyway. Hopefully this won't |
+upset anyone! |
+ |
+vxi11_cmd, the simple test utility, has also been updated. You can now, |
+optionally, pass the device_name as a second argument (after the ip |
+address). The source has been renamed to vxi11_cmd.cc (from vxi11_cmd.c), as |
+it is C++ code not C. |
+ |
+Some minor tidying up in vxi11_user.h |
+ |
+With thanks to Oliver Schulz for bringing LAN to GPIB gateways to my |
+attention, for suggesting changes to the vxi11_user library to allow them to |
+be accommodated, and for tidying some things up. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.04 - 10/07/2007 |
+ |
+Patch applied, which was kindly provided by Robert Larice. This sorts out |
+the confusion (on my part) about the structures returned by the rpcgen |
+generated *_1() functions... these are statically allocated temporary structs, |
+apparently. In the words of Robert Larice: |
+ |
+****** |
+Hello Dr. Sharples, |
+ |
+ I'm sending some patches for your nice gem "vxi11_1.03" |
+ |
+ In the source code there were some strange comments, concerning |
+ a commented free() around ... Manfred S. ... |
+ and some notes, suggesting you had trouble to get more than one link |
+ working. |
+ |
+ I think thats caused by some misuse of the rpcgen generated subroutines. |
+ 1) those rpcgen generated *_1 functions returned pointers to |
+ statically allocated temporary structs. |
+ those where meant to be instantly copied to the user's space, |
+ which wasn't done |
+ thus instead of |
+ Device_ReadResp *read_resp; |
+ read_resp = device_read_1(...) |
+ one should have written someting like: |
+ Device_ReadResp *read_resp; |
+ read_resp = malloc(...) |
+ memcpy(read_resp, device_read_1(...), ...) |
+ 2) but a better fix is to use the rpcgen -M Flag |
+ which allows to pass the memory space as a third argument |
+ so one can write |
+ Device_ReadResp *read_resp; |
+ read_resp = malloc(...) |
+ device_read_1(..., read_resp, ...) |
+ furthermore this is now automatically thread save |
+ 3) the rpcgen function device_read_1 |
+ expects a target buffer to be passed via read_resp |
+ which was not done. |
+ 4) the return value of vxi11_receive() was computed incorrectly |
+ 5) minor, Makefile typo's |
+ CFLAGS versus |
+ CLFAGS |
+ |
+****** |
+ |
+Robert didn't have more than one device to try the patch with, but I've just |
+tried it and everything seems fine. So I've removed all references to the |
+VXI11_ENABLE_MULTIPLE_CLIENTS global variable, and removed the call to |
+vxi11_open_link() from the vxi11_send() fn. There has been an associated |
+tidying of functions, and removal of some comments. |
+ |
+Thanks once again to Robert Larice for the patch and the explanation! |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.03 - 29/01/2007 |
+ |
+Some bug-fixes (thanks to Manfred S.), and extra awareness of the |
+possibility that instruments could time out after receiving a query WITHOUT |
+causing an error condition. In some cases (prior to these changes) this |
+could have resulted in a segmentation fault. |
+ |
+Specifically: |
+ |
+(1) removed call to ANSI free() fn in vxi11_receive, which according to |
+ Manfred S. "is not necessary and wrong (crashes)". |
+ |
+(2) added extra check in vxi11_receive() to see if read_resp==NULL. |
+ read_resp can apparently be NULL if (eg) you send an instrument a |
+ query, but the instrument is so busy with something else for so long |
+ that it forgets the original query. So this extra check is for that |
+ situation, and vxi11_receive returns -VXI11_NULL_READ_RESP to the |
+ calling function. |
+ |
+(3) vxi11_send_and_receive() is now aware of the possibility of being |
+ returned -VXI11_NULL_READ_RESP. If so, it re-sends the query, until |
+ either getting a "regular" read error (read_resp->error!=0) or a |
+ successful read. |
+ |
+(4) Similar to (2)... added extra check in vxi11_send() to see if |
+ write_resp==NULL. If so, return -VXI11_NULL_WRITE_RESP. As with (3), |
+ send_and_receive() is now aware of this possibility. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.02 - 25/08/2006 |
+ |
+Important changes to the core vxi11_send() function, which should be |
+invisible to the user. |
+ |
+For those interested, the function now takes note of the value of |
+link->maxRecvSize, which is the maximum number of bytes that the vxi11 |
+intrument you're talking to can receive in one go. For many instruments |
+this may be a few kB, which isn't a problem for sending short commands; |
+however, sending large chunks of data (for example sending waveforms |
+to instruments) may exceed this maxRecvSize. The core vxi11_send() function |
+has been re-written to ensure that only a maximum of [maxRecvSize] bytes are |
+written in one go... the function sits in a loop until all the message/ |
+data is written. |
+ |
+Also tidied up some of the return values (specifically with regard to |
+vxi11_send() and vxi11_send_data_block() ). |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.01 - 06/07/2006 |
+ |
+Fair few changes since v1.00, all in vxi11_user.c and vxi11_user.h |
+ |
+Found I was having problems talking to multiple links on the same |
+client, if I created a different client for each one. So introduced |
+a few global variables to keep track of all the ip addresses of |
+clients that the library is asked to create, and only creating new |
+clients if the ip address is different. This puts a limit of how |
+many unique ip addresses (clients) a single process can connect to. |
+Set this value at 256 (should hopefully be enough!). |
+ |
+Next I found that talking to different clients on different ip |
+addresses didn't work. It turns out that create_link_1() creates |
+a static structure. This this link is associated with a given |
+client (and hence a given IP address), then the only way I could |
+think of making things work was to add a call to an |
+vxi11_open_link() function before each send command (no idea what |
+this adds to overheads and it's very messy!) - at least I was |
+able to get this to only happen when we are using more than one |
+client/ip address. |
+ |
+Also, while I was at it, I re-ordered the functions a little - |
+starts with core user functions, extra user functions, then core |
+library functions at the end. Added a few more comments. Tidied |
+up. Left some debugging info in, but commented out. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.00 - 23/06/2006 |
+ |
+Initial release. |
+ |
+------------------------------------------------------------------------------ |
+ |
Index: sipmscan/trunk/vxi11_i686/GNU_General_Public_License.txt |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/GNU_General_Public_License.txt (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/GNU_General_Public_License.txt (revision 118) |
@@ -0,0 +1,340 @@ |
+ GNU GENERAL PUBLIC LICENSE |
+ Version 2, June 1991 |
+ |
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
+ Everyone is permitted to copy and distribute verbatim copies |
+ of this license document, but changing it is not allowed. |
+ |
+ Preamble |
+ |
+ The licenses for most software are designed to take away your |
+freedom to share and change it. By contrast, the GNU General Public |
+License is intended to guarantee your freedom to share and change free |
+software--to make sure the software is free for all its users. This |
+General Public License applies to most of the Free Software |
+Foundation's software and to any other program whose authors commit to |
+using it. (Some other Free Software Foundation software is covered by |
+the GNU Library General Public License instead.) You can apply it to |
+your programs, too. |
+ |
+ When we speak of free software, we are referring to freedom, not |
+price. Our General Public Licenses are designed to make sure that you |
+have the freedom to distribute copies of free software (and charge for |
+this service if you wish), that you receive source code or can get it |
+if you want it, that you can change the software or use pieces of it |
+in new free programs; and that you know you can do these things. |
+ |
+ To protect your rights, we need to make restrictions that forbid |
+anyone to deny you these rights or to ask you to surrender the rights. |
+These restrictions translate to certain responsibilities for you if you |
+distribute copies of the software, or if you modify it. |
+ |
+ For example, if you distribute copies of such a program, whether |
+gratis or for a fee, you must give the recipients all the rights that |
+you have. You must make sure that they, too, receive or can get the |
+source code. And you must show them these terms so they know their |
+rights. |
+ |
+ We protect your rights with two steps: (1) copyright the software, and |
+(2) offer you this license which gives you legal permission to copy, |
+distribute and/or modify the software. |
+ |
+ Also, for each author's protection and ours, we want to make certain |
+that everyone understands that there is no warranty for this free |
+software. If the software is modified by someone else and passed on, we |
+want its recipients to know that what they have is not the original, so |
+that any problems introduced by others will not reflect on the original |
+authors' reputations. |
+ |
+ Finally, any free program is threatened constantly by software |
+patents. We wish to avoid the danger that redistributors of a free |
+program will individually obtain patent licenses, in effect making the |
+program proprietary. To prevent this, we have made it clear that any |
+patent must be licensed for everyone's free use or not licensed at all. |
+ |
+ The precise terms and conditions for copying, distribution and |
+modification follow. |
+ |
+ GNU GENERAL PUBLIC LICENSE |
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
+ |
+ 0. This License applies to any program or other work which contains |
+a notice placed by the copyright holder saying it may be distributed |
+under the terms of this General Public License. The "Program", below, |
+refers to any such program or work, and a "work based on the Program" |
+means either the Program or any derivative work under copyright law: |
+that is to say, a work containing the Program or a portion of it, |
+either verbatim or with modifications and/or translated into another |
+language. (Hereinafter, translation is included without limitation in |
+the term "modification".) Each licensee is addressed as "you". |
+ |
+Activities other than copying, distribution and modification are not |
+covered by this License; they are outside its scope. The act of |
+running the Program is not restricted, and the output from the Program |
+is covered only if its contents constitute a work based on the |
+Program (independent of having been made by running the Program). |
+Whether that is true depends on what the Program does. |
+ |
+ 1. You may copy and distribute verbatim copies of the Program's |
+source code as you receive it, in any medium, provided that you |
+conspicuously and appropriately publish on each copy an appropriate |
+copyright notice and disclaimer of warranty; keep intact all the |
+notices that refer to this License and to the absence of any warranty; |
+and give any other recipients of the Program a copy of this License |
+along with the Program. |
+ |
+You may charge a fee for the physical act of transferring a copy, and |
+you may at your option offer warranty protection in exchange for a fee. |
+ |
+ 2. You may modify your copy or copies of the Program or any portion |
+of it, thus forming a work based on the Program, and copy and |
+distribute such modifications or work under the terms of Section 1 |
+above, provided that you also meet all of these conditions: |
+ |
+ a) You must cause the modified files to carry prominent notices |
+ stating that you changed the files and the date of any change. |
+ |
+ b) You must cause any work that you distribute or publish, that in |
+ whole or in part contains or is derived from the Program or any |
+ part thereof, to be licensed as a whole at no charge to all third |
+ parties under the terms of this License. |
+ |
+ c) If the modified program normally reads commands interactively |
+ when run, you must cause it, when started running for such |
+ interactive use in the most ordinary way, to print or display an |
+ announcement including an appropriate copyright notice and a |
+ notice that there is no warranty (or else, saying that you provide |
+ a warranty) and that users may redistribute the program under |
+ these conditions, and telling the user how to view a copy of this |
+ License. (Exception: if the Program itself is interactive but |
+ does not normally print such an announcement, your work based on |
+ the Program is not required to print an announcement.) |
+ |
+These requirements apply to the modified work as a whole. If |
+identifiable sections of that work are not derived from the Program, |
+and can be reasonably considered independent and separate works in |
+themselves, then this License, and its terms, do not apply to those |
+sections when you distribute them as separate works. But when you |
+distribute the same sections as part of a whole which is a work based |
+on the Program, the distribution of the whole must be on the terms of |
+this License, whose permissions for other licensees extend to the |
+entire whole, and thus to each and every part regardless of who wrote it. |
+ |
+Thus, it is not the intent of this section to claim rights or contest |
+your rights to work written entirely by you; rather, the intent is to |
+exercise the right to control the distribution of derivative or |
+collective works based on the Program. |
+ |
+In addition, mere aggregation of another work not based on the Program |
+with the Program (or with a work based on the Program) on a volume of |
+a storage or distribution medium does not bring the other work under |
+the scope of this License. |
+ |
+ 3. You may copy and distribute the Program (or a work based on it, |
+under Section 2) in object code or executable form under the terms of |
+Sections 1 and 2 above provided that you also do one of the following: |
+ |
+ a) Accompany it with the complete corresponding machine-readable |
+ source code, which must be distributed under the terms of Sections |
+ 1 and 2 above on a medium customarily used for software interchange; or, |
+ |
+ b) Accompany it with a written offer, valid for at least three |
+ years, to give any third party, for a charge no more than your |
+ cost of physically performing source distribution, a complete |
+ machine-readable copy of the corresponding source code, to be |
+ distributed under the terms of Sections 1 and 2 above on a medium |
+ customarily used for software interchange; or, |
+ |
+ c) Accompany it with the information you received as to the offer |
+ to distribute corresponding source code. (This alternative is |
+ allowed only for noncommercial distribution and only if you |
+ received the program in object code or executable form with such |
+ an offer, in accord with Subsection b above.) |
+ |
+The source code for a work means the preferred form of the work for |
+making modifications to it. For an executable work, complete source |
+code means all the source code for all modules it contains, plus any |
+associated interface definition files, plus the scripts used to |
+control compilation and installation of the executable. However, as a |
+special exception, the source code distributed need not include |
+anything that is normally distributed (in either source or binary |
+form) with the major components (compiler, kernel, and so on) of the |
+operating system on which the executable runs, unless that component |
+itself accompanies the executable. |
+ |
+If distribution of executable or object code is made by offering |
+access to copy from a designated place, then offering equivalent |
+access to copy the source code from the same place counts as |
+distribution of the source code, even though third parties are not |
+compelled to copy the source along with the object code. |
+ |
+ 4. You may not copy, modify, sublicense, or distribute the Program |
+except as expressly provided under this License. Any attempt |
+otherwise to copy, modify, sublicense or distribute the Program is |
+void, and will automatically terminate your rights under this License. |
+However, parties who have received copies, or rights, from you under |
+this License will not have their licenses terminated so long as such |
+parties remain in full compliance. |
+ |
+ 5. You are not required to accept this License, since you have not |
+signed it. However, nothing else grants you permission to modify or |
+distribute the Program or its derivative works. These actions are |
+prohibited by law if you do not accept this License. Therefore, by |
+modifying or distributing the Program (or any work based on the |
+Program), you indicate your acceptance of this License to do so, and |
+all its terms and conditions for copying, distributing or modifying |
+the Program or works based on it. |
+ |
+ 6. Each time you redistribute the Program (or any work based on the |
+Program), the recipient automatically receives a license from the |
+original licensor to copy, distribute or modify the Program subject to |
+these terms and conditions. You may not impose any further |
+restrictions on the recipients' exercise of the rights granted herein. |
+You are not responsible for enforcing compliance by third parties to |
+this License. |
+ |
+ 7. If, as a consequence of a court judgment or allegation of patent |
+infringement or for any other reason (not limited to patent issues), |
+conditions are imposed on you (whether by court order, agreement or |
+otherwise) that contradict the conditions of this License, they do not |
+excuse you from the conditions of this License. If you cannot |
+distribute so as to satisfy simultaneously your obligations under this |
+License and any other pertinent obligations, then as a consequence you |
+may not distribute the Program at all. For example, if a patent |
+license would not permit royalty-free redistribution of the Program by |
+all those who receive copies directly or indirectly through you, then |
+the only way you could satisfy both it and this License would be to |
+refrain entirely from distribution of the Program. |
+ |
+If any portion of this section is held invalid or unenforceable under |
+any particular circumstance, the balance of the section is intended to |
+apply and the section as a whole is intended to apply in other |
+circumstances. |
+ |
+It is not the purpose of this section to induce you to infringe any |
+patents or other property right claims or to contest validity of any |
+such claims; this section has the sole purpose of protecting the |
+integrity of the free software distribution system, which is |
+implemented by public license practices. Many people have made |
+generous contributions to the wide range of software distributed |
+through that system in reliance on consistent application of that |
+system; it is up to the author/donor to decide if he or she is willing |
+to distribute software through any other system and a licensee cannot |
+impose that choice. |
+ |
+This section is intended to make thoroughly clear what is believed to |
+be a consequence of the rest of this License. |
+ |
+ 8. If the distribution and/or use of the Program is restricted in |
+certain countries either by patents or by copyrighted interfaces, the |
+original copyright holder who places the Program under this License |
+may add an explicit geographical distribution limitation excluding |
+those countries, so that distribution is permitted only in or among |
+countries not thus excluded. In such case, this License incorporates |
+the limitation as if written in the body of this License. |
+ |
+ 9. The Free Software Foundation may publish revised and/or new versions |
+of the General Public License from time to time. Such new versions will |
+be similar in spirit to the present version, but may differ in detail to |
+address new problems or concerns. |
+ |
+Each version is given a distinguishing version number. If the Program |
+specifies a version number of this License which applies to it and "any |
+later version", you have the option of following the terms and conditions |
+either of that version or of any later version published by the Free |
+Software Foundation. If the Program does not specify a version number of |
+this License, you may choose any version ever published by the Free Software |
+Foundation. |
+ |
+ 10. If you wish to incorporate parts of the Program into other free |
+programs whose distribution conditions are different, write to the author |
+to ask for permission. For software which is copyrighted by the Free |
+Software Foundation, write to the Free Software Foundation; we sometimes |
+make exceptions for this. Our decision will be guided by the two goals |
+of preserving the free status of all derivatives of our free software and |
+of promoting the sharing and reuse of software generally. |
+ |
+ NO WARRANTY |
+ |
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
+REPAIR OR CORRECTION. |
+ |
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
+POSSIBILITY OF SUCH DAMAGES. |
+ |
+ END OF TERMS AND CONDITIONS |
+ |
+ How to Apply These Terms to Your New Programs |
+ |
+ If you develop a new program, and you want it to be of the greatest |
+possible use to the public, the best way to achieve this is to make it |
+free software which everyone can redistribute and change under these terms. |
+ |
+ To do so, attach the following notices to the program. It is safest |
+to attach them to the start of each source file to most effectively |
+convey the exclusion of warranty; and each file should have at least |
+the "copyright" line and a pointer to where the full notice is found. |
+ |
+ <one line to give the program's name and a brief idea of what it does.> |
+ Copyright (C) <year> <name of author> |
+ |
+ This program is free software; you can redistribute it and/or modify |
+ it under the terms of the GNU General Public License as published by |
+ the Free Software Foundation; either version 2 of the License, or |
+ (at your option) any later version. |
+ |
+ This program is distributed in the hope that it will be useful, |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ GNU General Public License for more details. |
+ |
+ You should have received a copy of the GNU General Public License |
+ along with this program; if not, write to the Free Software |
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
+ |
+ |
+Also add information on how to contact you by electronic and paper mail. |
+ |
+If the program is interactive, make it output a short notice like this |
+when it starts in an interactive mode: |
+ |
+ Gnomovision version 69, Copyright (C) year name of author |
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
+ This is free software, and you are welcome to redistribute it |
+ under certain conditions; type `show c' for details. |
+ |
+The hypothetical commands `show w' and `show c' should show the appropriate |
+parts of the General Public License. Of course, the commands you use may |
+be called something other than `show w' and `show c'; they could even be |
+mouse-clicks or menu items--whatever suits your program. |
+ |
+You should also get your employer (if you work as a programmer) or your |
+school, if any, to sign a "copyright disclaimer" for the program, if |
+necessary. Here is a sample; alter the names: |
+ |
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
+ `Gnomovision' (which makes passes at compilers) written by James Hacker. |
+ |
+ <signature of Ty Coon>, 1 April 1989 |
+ Ty Coon, President of Vice |
+ |
+This General Public License does not permit incorporating your program into |
+proprietary programs. If your program is a subroutine library, you may |
+consider it more useful to permit linking proprietary applications with the |
+library. If this is what you want to do, use the GNU Library General |
+Public License instead of this License. |
Index: sipmscan/trunk/vxi11_i686/Makefile |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/Makefile (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/Makefile (revision 118) |
@@ -0,0 +1,18 @@ |
+VERSION=1.08 |
+ |
+#CFLAGS = -Wall -g |
+CFLAGS = -g |
+CXX = g++ |
+ |
+.PHONY: clean objs |
+ |
+objs: vxi11.h |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_user.cc |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_clnt.c |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_xdr.c |
+ |
+vxi11.h: vxi11.x |
+ rpcgen -M vxi11.x |
+ |
+clean: |
+ rm -f *.o vxi11_cmd vxi11.h vxi11_svc.c vxi11_xdr.c vxi11_clnt.c #TAGS |
Index: sipmscan/trunk/vxi11_i686/Makefile.old |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/Makefile.old (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/Makefile.old (revision 118) |
@@ -0,0 +1,23 @@ |
+#CFLAGS = -Wall -g |
+CFLAGS = -g |
+ |
+vxi11_cmd: vxi11_cmd.o vxi11_user.o vxi11_clnt.o vxi11_xdr.o |
+ g++ $(CFLAGS) -o vxi11_cmd vxi11_cmd.o vxi11_user.o vxi11_clnt.o vxi11_xdr.o |
+ |
+vxi11_cmd.o: vxi11_cmd.cc vxi11_user.cc vxi11.h |
+ g++ $(CFLAGS) -c vxi11_cmd.cc -o vxi11_cmd.o |
+ |
+vxi11_user.o: vxi11_user.cc vxi11.h |
+ g++ $(CFLAGS) -c vxi11_user.cc -o vxi11_user.o |
+ |
+vxi11.h vxi11_clnt.c vxi11_xdr.c : vxi11.x |
+ rpcgen -M vxi11.x |
+ |
+TAGS: $(wildcard *.c) $(wildcard *.h) $(wildcard *.cc) |
+ etags $^ |
+ |
+clean: |
+ rm -f *.o vxi11_cmd vxi11.h vxi11_svc.c vxi11_xdr.c vxi11_clnt.c TAGS |
+ |
+install: |
+ cp -f vxi11_cmd /usr/local/bin/ |
Index: sipmscan/trunk/vxi11_i686/vxi11.x |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/vxi11.x (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/vxi11.x (revision 118) |
@@ -0,0 +1,317 @@ |
+/* This file, vxi11.x, is the amalgamation of vxi11core.rpcl and vxi11intr.rpcl |
+ * which are part of the asynDriver (R4-5) EPICS module, which, at time of |
+ * writing, is available from: |
+ * http://www.aps.anl.gov/epics/modules/soft/asyn/index.html |
+ * More general information about EPICS is available from: |
+ * http://www.aps.anl.gov/epics/ |
+ * This code is open source, and is covered under the copyright notice and |
+ * software license agreement shown below, and also at: |
+ * http://www.aps.anl.gov/epics/license/open.php |
+ * |
+ * In order to comply with section 4.3 of the software license agreement, here |
+ * is a PROMINENT NOTICE OF CHNAGES TO THE SOFTWARE |
+ * =========================================== |
+ * (1) This file, vxi11.x, is the concatenation of the files vxi11core.rpcl and |
+ * vxi11intr.rpcl |
+ * (2) Tab spacing has been tidied up |
+ * |
+ * It is intended as a lightweight base for the vxi11 rpc protocol. If you |
+ * run rpcgen on this file, it will generate C files and headers, from which |
+ * it is relatively simple to write C programs to communicate with a range |
+ * of ethernet-enabled instruments, such as oscilloscopes and function |
+ * generated by manufacturers such as Agilent and Tektronix (amongst many |
+ * others). |
+ * |
+ * For what it's worth, this concatenation was done by Steve Sharples at |
+ * the University of Nottingham, UK, on 1 June 2006. |
+ * |
+ * Copyright notice and software license agreement follow, then the |
+ * original comments from vxi11core.rpcl etc. |
+ * |
+ ****************************************************************************** |
+ * Copyright © 2006 <University of Chicago and other copyright holders>. All |
+ * rights reserved. |
+ ****************************************************************************** |
+ * |
+ ****************************************************************************** |
+ * vxi11.x is distributed subject to the following license conditions: |
+ * SOFTWARE LICENSE AGREEMENT |
+ * Software: vxi11.x |
+ * |
+ * 1. The "Software", below, refers to vxi11.x (in either source code, or |
+ * binary form and accompanying documentation). Each licensee is addressed |
+ * as "you" or "Licensee." |
+ * |
+ * 2. The copyright holders shown above and their third-party licensors hereby |
+ * grant Licensee a royalty-free nonexclusive license, subject to the |
+ * limitations stated herein and U.S. Government license rights. |
+ * |
+ * 3. You may modify and make a copy or copies of the Software for use within |
+ * your organization, if you meet the following conditions: |
+ * 1. Copies in source code must include the copyright notice and this |
+ * Software License Agreement. |
+ * 2. Copies in binary form must include the copyright notice and this |
+ * Software License Agreement in the documentation and/or other |
+ * materials provided with the copy. |
+ * |
+ * 4. You may modify a copy or copies of the Software or any portion of it, |
+ * thus forming a work based on the Software, and distribute copies of such |
+ * work outside your organization, if you meet all of the following |
+ * conditions: |
+ * 1. Copies in source code must include the copyright notice and this |
+ * Software License Agreement; |
+ * 2. Copies in binary form must include the copyright notice and this |
+ * Software License Agreement in the documentation and/or other |
+ * materials provided with the copy; |
+ * 3. Modified copies and works based on the Software must carry |
+ * prominent notices stating that you changed specified portions of |
+ * the Software. |
+ * |
+ * 5. Portions of the Software resulted from work developed under a U.S. |
+ * Government contract and are subject to the following license: the |
+ * Government is granted for itself and others acting on its behalf a |
+ * paid-up, nonexclusive, irrevocable worldwide license in this computer |
+ * software to reproduce, prepare derivative works, and perform publicly |
+ * and display publicly. |
+ * |
+ * 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF |
+ * ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE UNITED |
+ * STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR EMPLOYEES: (1) |
+ * DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO |
+ * ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
+ * PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY |
+ * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF THE |
+ * SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE |
+ * PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION |
+ * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. |
+ * |
+ * 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR |
+ * THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF |
+ * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, |
+ * CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, |
+ * INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY |
+ * REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF |
+ * CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, |
+ * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE POSSIBILITY OF SUCH |
+ * LOSS OR DAMAGES. |
+ ****************************************************************************** |
+ */ |
+ |
+/****************************************************************************** |
+ * |
+ * vxi11core.rpcl |
+ * |
+ * This file is best viewed with a tabwidth of 4 |
+ * |
+ ****************************************************************************** |
+ * |
+ * TODO: |
+ * |
+ ****************************************************************************** |
+ * |
+ * Original Author: someone from VXIbus Consortium |
+ * Current Author: Benjamin Franksen |
+ * Date: 03-06-97 |
+ * |
+ * RPCL description of the core- and abort-channel of the TCP/IP Instrument |
+ * Protocol Specification. |
+ * |
+ * |
+ * Modification Log: |
+ * ----------------- |
+ * .00 03-06-97 bfr created this file |
+ * |
+ ****************************************************************************** |
+ * |
+ * Notes: |
+ * |
+ * This stuff is literally from |
+ * |
+ * VXI-11, Ref 1.0 : TCP/IP Instrument Protocol Specification |
+ * |
+ */ |
+ |
+typedef long Device_Link; |
+ |
+enum Device_AddrFamily |
+{ |
+ DEVICE_TCP, |
+ DEVICE_UDP |
+}; |
+ |
+typedef long Device_Flags; |
+ |
+typedef long Device_ErrorCode; |
+ |
+struct Device_Error |
+{ |
+ Device_ErrorCode error; |
+}; |
+ |
+struct Create_LinkParms |
+{ |
+ long clientId; /* implementation specific value */ |
+ bool lockDevice; /* attempt to lock the device */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ string device<>; /* name of device */ |
+}; |
+struct Create_LinkResp |
+{ |
+ Device_ErrorCode error; |
+ Device_Link lid; |
+ unsigned short abortPort; /* for the abort RPC */ |
+ unsigned long maxRecvSize; /* max # of bytes accepted on write */ |
+}; |
+struct Device_WriteParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ Device_Flags flags; /* flags with options */ |
+ opaque data<>; /* the data length and the data itself */ |
+}; |
+struct Device_WriteResp |
+{ |
+ Device_ErrorCode error; |
+ unsigned long size; /* # of bytes written */ |
+}; |
+struct Device_ReadParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ unsigned long requestSize; /* # of bytes requested */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ Device_Flags flags; /* flags with options */ |
+ char termChar; /* valid if flags & termchrset */ |
+}; |
+struct Device_ReadResp |
+{ |
+ Device_ErrorCode error; |
+ long reason; /* why read completed */ |
+ opaque data<>; /* the data length and the data itself */ |
+}; |
+struct Device_ReadStbResp |
+{ |
+ Device_ErrorCode error; |
+ unsigned char stb; /* the returned status byte */ |
+}; |
+struct Device_GenericParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* flags with options */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+}; |
+struct Device_RemoteFunc |
+{ |
+ unsigned long hostAddr; /* host servicing interrupt */ |
+ unsigned long hostPort; /* valid port # on client */ |
+ unsigned long progNum; /* DEVICE_INTR */ |
+ unsigned long progVers; /* DEVICE_INTR_VERSION */ |
+ Device_AddrFamily progFamily; /* DEVICE_UDP | DEVICE_TCP */ |
+}; |
+struct Device_EnableSrqParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ bool enable; /* enable or disable intr's */ |
+ opaque handle<40>; /* host specific data */ |
+}; |
+struct Device_LockParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* contains the waitlock flag */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+}; |
+struct Device_DocmdParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* flags with options */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ long cmd; /* which command to execute */ |
+ bool network_order; /* client's byte order */ |
+ long datasize; /* size of individual data elements */ |
+ opaque data_in<>; /* docmd data parameters */ |
+}; |
+struct Device_DocmdResp |
+{ |
+ Device_ErrorCode error; |
+ opaque data_out<>; /* returned data parameters */ |
+}; |
+ |
+program DEVICE_ASYNC |
+{ |
+ version DEVICE_ASYNC_VERSION |
+ { |
+ Device_Error device_abort (Device_Link) = 1; |
+ } = 1; |
+} = 0x0607B0; |
+ |
+program DEVICE_CORE |
+{ |
+ version DEVICE_CORE_VERSION |
+ { |
+ Create_LinkResp create_link (Create_LinkParms) = 10; |
+ Device_WriteResp device_write (Device_WriteParms) = 11; |
+ Device_ReadResp device_read (Device_ReadParms) = 12; |
+ Device_ReadStbResp device_readstb (Device_GenericParms) = 13; |
+ Device_Error device_trigger (Device_GenericParms) = 14; |
+ Device_Error device_clear (Device_GenericParms) = 15; |
+ Device_Error device_remote (Device_GenericParms) = 16; |
+ Device_Error device_local (Device_GenericParms) = 17; |
+ Device_Error device_lock (Device_LockParms) = 18; |
+ Device_Error device_unlock (Device_Link) = 19; |
+ Device_Error device_enable_srq (Device_EnableSrqParms) = 20; |
+ Device_DocmdResp device_docmd (Device_DocmdParms) = 22; |
+ Device_Error destroy_link (Device_Link) = 23; |
+ Device_Error create_intr_chan (Device_RemoteFunc) = 25; |
+ Device_Error destroy_intr_chan (void) = 26; |
+ } = 1; |
+} = 0x0607AF; |
+ |
+/****************************************************************************** |
+ * |
+ * vxi11intr.rpcl |
+ * |
+ * This file is best viewed with a tabwidth of 4 |
+ * |
+ ****************************************************************************** |
+ * |
+ * TODO: |
+ * |
+ ****************************************************************************** |
+ * |
+ * Original Author: someone from VXIbus Consortium |
+ * Current Author: Benjamin Franksen |
+ * Date: 03-06-97 |
+ * |
+ * RPCL description of the intr-channel of the TCP/IP Instrument Protocol |
+ * Specification. |
+ * |
+ * |
+ * Modification Log: |
+ * ----------------- |
+ * .00 03-06-97 bfr created this file |
+ * |
+ ****************************************************************************** |
+ * |
+ * Notes: |
+ * |
+ * This stuff is literally from |
+ * |
+ * "VXI-11, Ref 1.0 : TCP/IP Instrument Protocol Specification" |
+ * |
+ */ |
+ |
+struct Device_SrqParms |
+{ |
+ opaque handle<>; |
+}; |
+ |
+program DEVICE_INTR |
+{ |
+ version DEVICE_INTR_VERSION |
+ { |
+ void device_intr_srq (Device_SrqParms) = 30; |
+ } = 1; |
+} = 0x0607B1; |
Index: sipmscan/trunk/vxi11_i686/vxi11_cmd.cc |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/vxi11_cmd.cc (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/vxi11_cmd.cc (revision 118) |
@@ -0,0 +1,237 @@ |
+/*Predelava vmesnika vxi11 za lastne potrebe IJS F9*/ |
+ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <time.h> |
+#include "vxi11_user.h" |
+#define BUF_LEN 100000 |
+ |
+CLINK *clink; |
+FILE *test,*test1; |
+ |
+int query(char *mycmd){ |
+char buf[BUF_LEN]; |
+ |
+memset(buf, 0, BUF_LEN); |
+vxi11_send(clink, mycmd); |
+int bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+if (bytes_returned > 0) { |
+ printf("%s\n",buf); |
+} else if (bytes_returned == -15) printf("*** [ NOTHING RECEIVED ] ***\n"); |
+ |
+return 0; |
+} |
+ |
+int command(char *mycmd){ |
+char buf[BUF_LEN]; |
+ |
+memset(buf, 0, BUF_LEN); |
+vxi11_send(clink, mycmd); |
+ |
+return 0; |
+} |
+ |
+int queryrep(char *mycmd,char *mycmp,int i){ |
+char buf[BUF_LEN]; |
+ |
+memset(buf, 0, BUF_LEN); |
+vxi11_send(clink, mycmd); |
+int bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+ |
+if(strcmp(buf,mycmp)!=0){ |
+ if (bytes_returned > 0) fprintf(test1,"%d %s",i,buf); |
+ else if (bytes_returned == -15) printf("*** [ NOTHING RECEIVED ] ***\n"); |
+ |
+ } |
+ strcpy(mycmp,buf); |
+ |
+return 0; |
+} |
+ |
+/*float *fbuf; |
+fbuf= (float *) buf; |
+if (bytes_returned > 0){ |
+ for (int j=1;j<3;j++) printf("%f\n",fbuf[j]); |
+ } |
+*/ |
+ |
+int main(void) { |
+ |
+static char *device_ip; |
+static char *device_name; |
+char cmd[256],ukaz[256],end[256]; |
+char buf[BUF_LEN],pr1[BUF_LEN],pr2[BUF_LEN]; |
+int ret; |
+long bytes_returned; |
+ |
+int i,m,vnos; |
+ |
+clink = new CLINK; |
+time_t t1,t2; |
+ |
+/* |
+ fread(buf,1,size,fp); |
+ float *fbuf=(float *) buf; |
+ fbuf[0] |
+ |
+*/ |
+ memset(ukaz, 0, 256); |
+ printf("\nIJS F9 - September 2010 - Pripravil: Jaka Mur - Beta verzija\n\nProgram za povezavo in nadzor Tektronix ali LeCroy osciloskopa.\nAvtomatsko se program poveze z IP naslovom 194.249.156.91.\nVnesi 'a' za nadaljevanje, 'q' za izhod ali IP za drugo napravo: "); |
+ |
+ while(1){ |
+ scanf("%s",&ukaz); |
+ |
+ if (strncasecmp(ukaz, "q",1) == 0) return 0; |
+ |
+ else if (strncasecmp(ukaz, "a",1) != 0) ret=vxi11_open_device(ukaz,clink); |
+ else ret=vxi11_open_device("194.249.156.91",clink); //privzeti IP naprave |
+ |
+ printf("\nPovezan z "); |
+ |
+ memset(buf, 0, BUF_LEN); |
+ vxi11_send(clink, "*IDN?"); |
+ bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+ if (bytes_returned > 0) { |
+ printf("%s",buf); |
+ break;} |
+ else if (bytes_returned == -15) { |
+ printf("Error."); |
+ if (strncasecmp(ukaz, "a",1) == 0) ret=vxi11_close_device("194.249.156.91",clink); |
+ else ret=vxi11_close_device(ukaz,clink); |
+ return 0; |
+ } |
+ |
+ } |
+ |
+ printf("\nNekatere pomembnejse nastavitve:\n"); |
+ command("HEADER ON"); |
+ command("DATA:SOURCE CH1"); |
+ query("DAT?"); |
+ |
+ char odg[256]; |
+ printf("Zelite spreminjati nastavitve? y/n/q: "); |
+ scanf("%s",&odg); |
+ fgets(cmd,256,stdin); |
+ |
+ if (strncasecmp(odg, "q",1) == 0) { |
+ if (strncasecmp(ukaz, "a",1) == 0) ret=vxi11_close_device("194.249.156.91",clink); |
+ else ret=vxi11_close_device(ukaz,clink); |
+ return 0; |
+ } |
+ else if (strncasecmp(odg, "y",1) == 0){ |
+ printf("\nSpisek komand je v Programmer Manualu!\n"); |
+ while(1){ |
+ memset(cmd, 0, 256); |
+ memset(buf, 0, BUF_LEN); |
+ |
+ printf("Vnesi ukaz, vprasanje, 'q' za izhod ali 'x' za nadaljevanje: "); |
+ fgets(cmd,256,stdin); |
+ cmd[strlen(cmd)-1] = 0; |
+ if (strncasecmp(cmd, "q",1) == 0) { |
+ if (strncasecmp(ukaz, "a",1) == 0) ret=vxi11_close_device("194.249.156.91",clink); |
+ else ret=vxi11_close_device(ukaz,clink); |
+ return 0; |
+ } |
+ if (strncasecmp(cmd, "x",1) == 0) break; |
+ |
+ if (vxi11_send(clink, cmd) < 0) break; |
+ if (strstr(cmd, "?") != 0) { |
+ bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+ if (bytes_returned > 0) { |
+ printf("%s\n",buf); |
+ } |
+ else if (bytes_returned == -15) { |
+ printf("*** [ NOTHING RECEIVED ] ***\n"); |
+ } |
+ else break; |
+ } |
+ } |
+ } |
+ |
+ command("HEADER OFF"); |
+ |
+ printf("\nIzbor serije meritev\n1 = za zapis waveformov v binarnem formatu\n2 = MEASU:IMM test\n3 = Shenanigans\nVnesi #: "); |
+ scanf("%d",&vnos); |
+//prva opcija |
+ if (vnos==1){ |
+ |
+ printf("\nTrenutno je nastavljeno zapisovanje celotnih waveformov iz CH1 v datoteko 'test.txt'. Vnesite zeljeno stevilo ponovitev: "); |
+ scanf("%d",&m); |
+ |
+ test=fopen("/media/disk/vxi11_1.08/test.txt","w"); |
+ command("DATA:SOURCE CH1"); |
+ command("DATA:START 1"); |
+ command("DATA:STOP 1000"); |
+ command("DATA:ENCDG RPBINARY"); |
+ |
+(void) time(&t1); |
+ query("ACQUIRE:NUMFRAMESACQUIRED?"); |
+ |
+ for(i=1;i<m+1;i++) { //zajem binarnih podatkov |
+ |
+ memset(buf, 0, BUF_LEN); |
+ vxi11_send(clink, "CURVE?"); |
+ int bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+ |
+ if (bytes_returned > 0) fwrite(buf,1,bytes_returned,test); |
+ if(strcmp(buf,pr1)!=0){ |
+ if (bytes_returned > 0) fwrite(buf,1,1000,test); |
+ else if (bytes_returned == -15) printf("*** [ NOTHING RECEIVED ] ***\n"); |
+ } |
+ strcpy(pr1,buf); |
+ } |
+ |
+ query("ACQUIRE:NUMFRAMESACQUIRED?"); |
+(void) time(&t2); |
+ |
+ printf("Koncano!\n"); |
+ printf("Trajanje: %ld s\n",(int)t2-t1); |
+ fclose(test); |
+ |
+ } |
+//druga opcija |
+ else if (vnos==2){ |
+ |
+ test1=fopen("/media/disk/vxi11_1.08/test1.txt","w"); |
+ |
+ printf("Vnesi zeljeno stevilo meritev minimuma LeCroy: "); |
+ scanf("%d",&m); |
+ |
+ for (i=0;i<m;i++) queryrep("C1:PAVA? MIN",pr2,i); |
+ |
+ fclose(test1); |
+ } |
+//tretja opcija |
+ else if (vnos==3){ |
+ |
+ test1=fopen("/media/disk/vxi11_1.08/test1.txt","w"); |
+ |
+ printf("Vnesi zeljeno stevilo zajemov: "); |
+ scanf("%d",&m); |
+ |
+ command("DATA:SOURCE CH1, CH2"); |
+ command("DATA:START 1"); |
+ command("DATA:STOP 1000"); |
+ command("DATA:ENCDG ASCII"); |
+ |
+ query("ACQUIRE:NUMFRAMESACQUIRED?"); |
+ |
+ for (i=0;i<m;i++) queryrep("CURVE?",pr2,i); |
+ |
+ query("ACQUIRE:NUMFRAMESACQUIRED?"); |
+ |
+ fclose(test1); |
+ } |
+ |
+ if (strncasecmp(ukaz, "a",1) == 0) ret=vxi11_close_device("194.249.156.91",clink); |
+ else ret=vxi11_close_device(ukaz,clink); |
+ |
+ printf("Meritve opravljene!\nZa zakljucek pritisni 'q'! "); |
+ scanf("%s",&end); |
+ |
+ if (strcmp(end,"q")==0); |
+ |
+ return 0; |
+} |
+ |
Index: sipmscan/trunk/vxi11_i686/vxi11_user.cc |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/vxi11_user.cc (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/vxi11_user.cc (revision 118) |
@@ -0,0 +1,728 @@ |
+/* Revision history: */ |
+/* $Id: vxi11_user.cc,v 1.17 2008/10/20 07:59:54 sds Exp $ */ |
+/* |
+ * $Log: vxi11_user.cc,v $ |
+ * Revision 1.17 2008/10/20 07:59:54 sds |
+ * Removed Manfred's surname at his request from the comments/acknowledgments. |
+ * |
+ * Revision 1.16 2008/09/03 14:30:13 sds |
+ * added sanity check for link->maxRecvSize to make sure it's >0. |
+ * This got around a bug in some versions of the Agilent Infiniium |
+ * scope software. |
+ * |
+ * Revision 1.15 2007/10/30 12:55:15 sds |
+ * changed the erroneous strncpy() to memcpy() in vxi11_send, |
+ * as we could be sending binary data (not just strings). |
+ * |
+ * Revision 1.14 2007/10/30 12:46:48 sds |
+ * changed a lot of char *'s to const char *'s in an attempt to get |
+ * rid of pedantic gcc compiler warnings. |
+ * |
+ * Revision 1.13 2007/10/09 08:42:57 sds |
+ * Minor change to vxi11_receive_data_block(), this fn now |
+ * copes with instruments that return just "#0" (for whatever |
+ * reason). Suggestion by Jarek Sadowski. |
+ * |
+ * Revision 1.12 2007/08/31 10:32:39 sds |
+ * Bug fix in vxi11_receive(), to ensure that no more than "len" |
+ * bytes are ever received (and so avoiding a segmentation fault). |
+ * This was a bug introduced in release 1.04 (RCS 1.10) whilst |
+ * making some other changes to the vxi11_receive() fn. Many thanks |
+ * to Rob Penny for spotting the bug and providing a patch. |
+ * |
+ * Revision 1.11 2007/07/10 13:49:18 sds |
+ * Changed the vxi11_open_device() fn to accept a third argument, char *device. |
+ * This gets passed to the core vxi11_open_device() fn (the one that deals with |
+ * separate clients and links), and the core vxi11_open_link() fn; these two |
+ * core functions have also had an extra parameter added accordingly. In order |
+ * to not break the API, a wrapper function is provided in the form of the |
+ * original vxi11_open_device() fn, that just takes 2 arguments |
+ * (char *ip, CLINK *clink), this then passes "inst0" as the device argument. |
+ * Backwards-compatible wrappers for the core functions have NOT been provided. |
+ * These are generally not used from userland anyway. Hopefully this won't |
+ * upset anyone! |
+ * |
+ * Revision 1.10 2007/07/10 11:12:12 sds |
+ * Patches provided by Robert Larice. This basically solves the problem |
+ * of having to recreate a link each time you change client. In the words |
+ * of Robert: |
+ * |
+ * --------- |
+ * In the source code there were some strange comments, suggesting |
+ * you had trouble to get more than one link working. |
+ * |
+ * I think thats caused by some misuse of the rpcgen generated subroutines. |
+ * 1) those rpcgen generated *_1 functions returned pointers to |
+ * statically allocated temporary structs. |
+ * those where meant to be instantly copied to the user's space, |
+ * which wasn't done, thus instead of |
+ * Device_ReadResp *read_resp; |
+ * read_resp = device_read_1(...) |
+ * one should have written someting like: |
+ * Device_ReadResp *read_resp; |
+ * read_resp = malloc(...) |
+ * memcpy(read_resp, device_read_1(...), ...) |
+ * 2) but a better fix is to use the rpcgen -M Flag |
+ * which allows to pass the memory space as a third argument |
+ * so one can write |
+ * Device_ReadResp *read_resp; |
+ * read_resp = malloc(...) |
+ * device_read_1(..., read_resp, ...) |
+ * furthermore this is now automatically thread save |
+ * 3) the rpcgen function device_read_1 |
+ * expects a target buffer to be passed via read_resp |
+ * which was not done. |
+ * 4) the return value of vxi11_receive() was computed incorrectly |
+ * 5) minor, Makefile typo's |
+ * --------- |
+ * So big thanks to Robert Larice for the patch! I've tested it |
+ * (briefly) on more than one scope, and with multiple links per |
+ * client, and it seems to work fine. I've thus removed all references |
+ * to VXI11_ENABLE_MULTIPLE_CLIENTS, and deleted the vxi11_open_link() |
+ * function that WASN'T passed an ip address (that was only called |
+ * from the vxi11_send() fn, when there was more than one client). |
+ * |
+ * Revision 1.9 2006/12/08 12:06:58 ijc |
+ * Basically the same changes as revision 1.8, except replace all |
+ * references to "vxi11_receive" with "vxi11_send" and all references |
+ * to "-VXI11_NULL_READ_RESP" with "-VXI11_NULL_WRITE_RESP". |
+ * |
+ * Revision 1.8 2006/12/07 12:22:20 sds |
+ * Couple of changes, related. |
+ * (1) added extra check in vxi11_receive() to see if read_resp==NULL. |
+ * read_resp can apparently be NULL if (eg) you send an instrument a |
+ * query, but the instrument is so busy with something else for so long |
+ * that it forgets the original query. So this extra check is for that |
+ * situation, and vxi11_receive returns -VXI11_NULL_READ_RESP to the |
+ * calling function. |
+ * (2) vxi11_send_and_receive() is now aware of the possibility of |
+ * being returned -VXI11_NULL_READ_RESP. If so, it re-sends the query, |
+ * until either getting a "regular" read error (read_resp->error!=0) or |
+ * a successful read. |
+ * |
+ * Revision 1.7 2006/12/06 16:27:47 sds |
+ * removed call to ANSI free() fn in vxi11_receive, which according to |
+ * Manfred S. "is not necessary and wrong (crashes)". |
+ * |
+ * Revision 1.6 2006/08/25 13:45:12 sds |
+ * Major improvements to the vxi11_send function. Now takes |
+ * link->maxRecvSize into account, and writes a chunk at a time |
+ * until the entire message is sent. Important for sending large |
+ * data sets, because the data you want to send may be larger than |
+ * the instrument's "input buffer." |
+ * |
+ * Revision 1.5 2006/08/25 13:06:44 sds |
+ * tidied up some of the return values, and made sure that if a |
+ * sub-function returned an error value, this would also be |
+ * returned by the calling function. |
+ * |
+ * Revision 1.4 2006/07/06 13:04:59 sds |
+ * Lots of changes this revision. |
+ * Found I was having problems talking to multiple links on the same |
+ * client, if I created a different client for each one. So introduced |
+ * a few global variables to keep track of all the ip addresses of |
+ * clients that the library is asked to create, and only creating new |
+ * clients if the ip address is different. This puts a limit of how |
+ * many unique ip addresses (clients) a single process can connect to. |
+ * Set this value at 256 (should hopefully be enough!). |
+ * Next I found that talking to different clients on different ip |
+ * addresses didn't work. It turns out that create_link_1() creates |
+ * a static structure. This this link is associated with a given |
+ * client (and hence a given IP address), then the only way I could |
+ * think of making things work was to add a call to an |
+ * vxi11_open_link() function before each send command (no idea what |
+ * this adds to overheads and it's very messy!) - at least I was |
+ * able to get this to only happen when we are using more than one |
+ * client/ip address. |
+ * Also, while I was at it, I re-ordered the functions a little - |
+ * starts with core user functions, extra user functions, then core |
+ * library functions at the end. Added a few more comments. Tidied |
+ * up. Left some debugging info in, but commented out. |
+ * |
+ * Revision 1.3 2006/06/26 12:40:56 sds |
+ * Introduced a new CLINK structure, to reduce the number of arguments |
+ * passed to functions. Wrote wrappers for open(), close(), send() |
+ * and receieve() functions, then adjusted all the other functions built |
+ * on those to make use of the CLINK structure. |
+ * |
+ * Revision 1.2 2006/06/26 10:29:48 sds |
+ * Added GNU GPL and copyright notices. |
+ * |
+ */ |
+ |
+/* vxi11_user.cc |
+ * Copyright (C) 2006 Steve D. Sharples |
+ * |
+ * User library for opening, closing, sending to and receiving from |
+ * a device enabled with the VXI11 RPC ethernet protocol. Uses the files |
+ * generated by rpcgen vxi11.x. |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2 |
+ * of the License, or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * The author's email address is steve.sharples@nottingham.ac.uk |
+ */ |
+ |
+#include "vxi11_user.h" |
+ |
+/***************************************************************************** |
+ * GENERAL NOTES |
+ ***************************************************************************** |
+ * |
+ * There are four functions at the heart of this library: |
+ * |
+ * int vxi11_open_device(char *ip, CLIENT **client, VXI11_LINK **link) |
+ * int vxi11_close_device(char *ip, CLIENT *client, VXI11_LINK *link) |
+ * int vxi11_send(CLIENT *client, VXI11_LINK *link, char *cmd, unsigned long len) |
+ * long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) |
+ * |
+ * Note that all 4 of these use separate client and link structures. All the |
+ * other functions are built on these four core functions, and the first layer |
+ * of abstraction is to combine the CLIENT and VXI11_LINK structures into a |
+ * single entity, which I've called a CLINK. For the send and receive |
+ * functions, this is just a simple wrapper. For the open and close functions |
+ * it's a bit more complicated, because we somehow have to keep track of |
+ * whether we've already opened a device with the same IP address before (in |
+ * which case we need to recycle a previously created client), or whether |
+ * we've still got any other links to a given IP address left when we are |
+ * asked to close a clink (in which case we can sever the link, but have to |
+ * keep the client open). This is so the person using this library from |
+ * userland does not have to keep track of whether they are talking to a |
+ * different physical instrument or not each time they establish a connection. |
+ * |
+ * So the base functions that the user will probably want to use are: |
+ * |
+ * int vxi11_open_device(char *ip, CLINK *clink) |
+ * int vxi11_close_device(char *ip, CLINK *clink) |
+ * int vxi11_send(CLINK *clink, char *cmd, unsigned long len) |
+ * --- or --- (if sending just text) |
+ * int vxi11_send(CLINK *clink, char *cmd) |
+ * long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) |
+ * |
+ * There are then useful (to me, anyway) more specific functions built on top |
+ * of these: |
+ * |
+ * int vxi11_send_data_block(CLINK *clink, char *cmd, char *buffer, unsigned long len) |
+ * long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) |
+ * long vxi11_send_and_receive(CLINK *clink, char *cmd, char *buf, unsigned long buf_len, unsigned long timeout) |
+ * long vxi11_obtain_long_value(CLINK *clink, char *cmd, unsigned long timeout) |
+ * double vxi11_obtain_double_value(CLINK *clink, char *cmd, unsigned long timeout) |
+ * |
+ * (then there are some shorthand wrappers for the above without specifying |
+ * the timeout due to sheer laziness---explore yourself) |
+ */ |
+ |
+ |
+/* Global variables. Keep track of multiple links per client. We need this |
+ * because: |
+ * - we'd like the library to be able to cope with multiple links to a given |
+ * client AND multiple links to multiple clients |
+ * - we'd like to just refer to a client/link ("clink") as a single |
+ * entity from user land, we don't want to worry about different |
+ * initialisation procedures, depending on whether it's an instrument |
+ * with the same IP address or not |
+ */ |
+char VXI11_IP_ADDRESS[VXI11_MAX_CLIENTS][20]; |
+CLIENT *VXI11_CLIENT_ADDRESS[VXI11_MAX_CLIENTS]; |
+int VXI11_DEVICE_NO = 0; |
+int VXI11_LINK_COUNT[VXI11_MAX_CLIENTS]; |
+ |
+/***************************************************************************** |
+ * KEY USER FUNCTIONS - USE THESE FROM YOUR PROGRAMS OR INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* OPEN FUNCTIONS * |
+ * ============== */ |
+ |
+/* Use this function from user land to open a device and create a link. Can be |
+ * used multiple times for the same device (the library will keep track).*/ |
+int vxi11_open_device(const char *ip, CLINK *clink, char *device) { |
+int ret; |
+int l; |
+int device_no=-1; |
+ |
+// printf("before doing anything, clink->link = %ld\n", clink->link); |
+ /* Have a look to see if we've already initialised an instrument with |
+ * this IP address */ |
+ for (l=0; l<VXI11_MAX_CLIENTS; l++){ |
+ if (strcmp(ip,VXI11_IP_ADDRESS[l]) == 0 ) { |
+ device_no=l; |
+// printf("Open function, search, found ip address %s, device no %d\n",ip,device_no); |
+ } |
+ } |
+ |
+ /* Couldn't find a match, must be a new IP address */ |
+ if (device_no < 0) { |
+ /* Uh-oh, we're out of storage space. Increase the #define |
+ * for VXI11_MAX_CLIENTS in vxi11_user.h */ |
+ if (VXI11_DEVICE_NO >= VXI11_MAX_CLIENTS) { |
+ printf("Error: maximum of %d clients allowed\n",VXI11_MAX_CLIENTS); |
+ ret = -VXI11_MAX_CLIENTS; |
+ } |
+ /* Create a new client, keep a note of where the client pointer |
+ * is, for this IP address. Because it's a new client, this |
+ * must be link number 1. Keep track of how many devices we've |
+ * opened so we don't run out of storage space. */ |
+ else { |
+ ret = vxi11_open_device(ip, &(clink->client), &(clink->link), device); |
+ strncpy(VXI11_IP_ADDRESS[VXI11_DEVICE_NO],ip,20); |
+ VXI11_CLIENT_ADDRESS[VXI11_DEVICE_NO] = clink->client; |
+ VXI11_LINK_COUNT[VXI11_DEVICE_NO]=1; |
+// printf("Open function, could not find ip address %s.\n",ip); |
+// printf("So now, VXI11_IP_ADDRESS[%d]=%s,\n",VXI11_DEVICE_NO,VXI11_IP_ADDRESS[VXI11_DEVICE_NO]); |
+// printf("VXI11_CLIENT_ADDRESS[%d]=%ld,\n",VXI11_DEVICE_NO,VXI11_CLIENT_ADDRESS[VXI11_DEVICE_NO]); |
+// printf(" clink->client=%ld,\n",clink->client); |
+// printf("VXI11_LINK_COUNT[%d]=%d.\n",VXI11_DEVICE_NO,VXI11_LINK_COUNT[VXI11_DEVICE_NO]); |
+ VXI11_DEVICE_NO++; |
+ } |
+ } |
+ /* already got a client for this IP address */ |
+ else { |
+ /* Copy the client pointer address. Just establish a new link |
+ * (not a new client). Add one to the link count */ |
+ clink->client = VXI11_CLIENT_ADDRESS[device_no]; |
+ ret = vxi11_open_link(ip, &(clink->client), &(clink->link), device); |
+// printf("Found an ip address, copying client from VXI11_CLIENT_ADDRESS[%d]\n",device_no); |
+ VXI11_LINK_COUNT[device_no]++; |
+// printf("Have just incremented VXI11_LINK_COUNT[%d], it's now %d\n",device_no,VXI11_LINK_COUNT[device_no]); |
+ } |
+// printf("after creating link, clink->link = %ld\n", clink->link); |
+ return ret; |
+ } |
+ |
+/* This is a wrapper function, used for the situations where there is only one |
+ * "device" per client. This is the case for most (if not all) VXI11 |
+ * instruments; however, it is _not_ the case for devices such as LAN to GPIB |
+ * gateways. These are single clients that communicate to many instruments |
+ * (devices). In order to differentiate between them, we need to pass a device |
+ * name. This gets used in the vxi11_open_link() fn, as the link_parms.device |
+ * value. */ |
+int vxi11_open_device(const char *ip, CLINK *clink) { |
+ char device[6]; |
+ strncpy(device,"inst0",6); |
+ return vxi11_open_device(ip, clink, device); |
+ } |
+ |
+ |
+ |
+/* CLOSE FUNCTION * |
+ * ============== */ |
+ |
+/* Use this function from user land to close a device and/or sever a link. Can |
+ * be used multiple times for the same device (the library will keep track).*/ |
+int vxi11_close_device(const char *ip, CLINK *clink) { |
+int l,ret; |
+int device_no = -1; |
+ |
+ /* Which instrument are we referring to? */ |
+ for (l=0; l<VXI11_MAX_CLIENTS; l++){ |
+ if (strcmp(ip,VXI11_IP_ADDRESS[l]) == 0 ) { |
+ device_no=l; |
+ } |
+ } |
+ /* Something's up if we can't find the IP address! */ |
+ if (device_no == -1) { |
+ printf("vxi11_close_device: error: I have no record of you ever opening device\n"); |
+ printf(" with IP address %s\n",ip); |
+ ret = -4; |
+ } |
+ else { /* Found the IP, there's more than one link to that instrument, |
+ * so keep track and just close the link */ |
+ if (VXI11_LINK_COUNT[device_no] > 1 ) { |
+ ret = vxi11_close_link(ip,clink->client, clink->link); |
+ VXI11_LINK_COUNT[device_no]--; |
+ } |
+ /* Found the IP, it's the last link, so close the device (link |
+ * AND client) */ |
+ else { |
+ ret = vxi11_close_device(ip, clink->client, clink->link); |
+ } |
+ } |
+ return ret; |
+ } |
+ |
+ |
+/* SEND FUNCTIONS * |
+ * ============== */ |
+ |
+/* A _lot_ of the time we are sending text strings, and can safely rely on |
+ * strlen(cmd). */ |
+int vxi11_send(CLINK *clink, const char *cmd) { |
+ return vxi11_send(clink, cmd, strlen(cmd)); |
+ } |
+ |
+/* We still need the version of the function where the length is set explicitly |
+ * though, for when we are sending fixed length data blocks. */ |
+int vxi11_send(CLINK *clink, const char *cmd, unsigned long len) { |
+ return vxi11_send(clink->client, clink->link, cmd, len); |
+ } |
+ |
+ |
+/* RECEIVE FUNCTIONS * |
+ * ================= */ |
+ |
+/* Lazy wrapper for when I can't be bothered to specify a read timeout */ |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len) { |
+ return vxi11_receive(clink, buffer, len, VXI11_READ_TIMEOUT); |
+ } |
+ |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) { |
+ return vxi11_receive(clink->client, clink->link, buffer, len, timeout); |
+ } |
+ |
+ |
+ |
+/***************************************************************************** |
+ * USEFUL ADDITIONAL HIGHER LEVER USER FUNCTIONS - USE THESE FROM YOUR * |
+ * PROGRAMS OR INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* SEND FIXED LENGTH DATA BLOCK FUNCTION * |
+ * ===================================== */ |
+int vxi11_send_data_block(CLINK *clink, const char *cmd, char *buffer, unsigned long len) { |
+char *out_buffer; |
+int cmd_len=strlen(cmd); |
+int ret; |
+ |
+ out_buffer=new char[cmd_len+10+len]; |
+ sprintf(out_buffer,"%s#8%08lu",cmd,len); |
+ memcpy(out_buffer+cmd_len+10,buffer,(unsigned long) len); |
+ ret = vxi11_send(clink, out_buffer, (unsigned long) (cmd_len+10+len)); |
+ delete[] out_buffer; |
+ return ret; |
+ } |
+ |
+ |
+/* RECEIVE FIXED LENGTH DATA BLOCK FUNCTION * |
+ * ======================================== */ |
+ |
+/* This function reads a response in the form of a definite-length block, such |
+ * as when you ask for waveform data. The data is returned in the following |
+ * format: |
+ * #800001000<1000 bytes of data> |
+ * ||\______/ |
+ * || | |
+ * || \---- number of bytes of data |
+ * |\--------- number of digits that follow (in this case 8, with leading 0's) |
+ * \---------- always starts with # |
+ */ |
+long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) { |
+/* I'm not sure what the maximum length of this header is, I'll assume it's |
+ * 11 (#9 + 9 digits) */ |
+unsigned long necessary_buffer_size; |
+char *in_buffer; |
+int ret; |
+int ndigits; |
+unsigned long returned_bytes; |
+int l; |
+char scan_cmd[20]; |
+ necessary_buffer_size=len+12; |
+ in_buffer=new char[necessary_buffer_size]; |
+ ret=vxi11_receive(clink, in_buffer, necessary_buffer_size, timeout); |
+ if (ret < 0) return ret; |
+ if (in_buffer[0] != '#') { |
+ printf("vxi11_user: data block error: data block does not begin with '#'\n"); |
+ printf("First 20 characters received were: '"); |
+ for(l=0;l<20;l++) { |
+ printf("%c",in_buffer[l]); |
+ } |
+ printf("'\n"); |
+ return -3; |
+ } |
+ |
+ /* first find out how many digits */ |
+ sscanf(in_buffer,"#%1d",&ndigits); |
+ /* some instruments, if there is a problem acquiring the data, return only "#0" */ |
+ if (ndigits > 0) { |
+ /* now that we know, we can convert the next <ndigits> bytes into an unsigned long */ |
+ sprintf(scan_cmd,"#%%1d%%%dlu",ndigits); |
+ sscanf(in_buffer,scan_cmd,&ndigits,&returned_bytes); |
+ memcpy(buffer, in_buffer+(ndigits+2), returned_bytes); |
+ delete[] in_buffer; |
+ return (long) returned_bytes; |
+ } |
+ else return 0; |
+ } |
+ |
+ |
+/* SEND AND RECEIVE FUNCTION * |
+ * ========================= */ |
+ |
+/* This is mainly a useful function for the overloaded vxi11_obtain_value() |
+ * fn's, but is also handy and useful for user and library use */ |
+long vxi11_send_and_receive(CLINK *clink, const char *cmd, char *buf, unsigned long buf_len, unsigned long timeout) { |
+int ret; |
+long bytes_returned; |
+ do { |
+ ret = vxi11_send(clink, cmd); |
+ if (ret != 0) { |
+ if (ret != -VXI11_NULL_WRITE_RESP) { |
+ printf("Error: vxi11_send_and_receive: could not send cmd.\n"); |
+ printf(" The function vxi11_send returned %d. ",ret); |
+ return -1; |
+ } |
+ else printf("(Info: VXI11_NULL_WRITE_RESP in vxi11_send_and_receive, resending query)\n"); |
+ } |
+ |
+ bytes_returned = vxi11_receive(clink, buf, buf_len, timeout); |
+ if (bytes_returned <= 0) { |
+ if (bytes_returned >-VXI11_NULL_READ_RESP) { |
+ printf("Error: vxi11_send_and_receive: problem reading reply.\n"); |
+ printf(" The function vxi11_receive returned %ld. ",bytes_returned); |
+ return -2; |
+ } |
+ else printf("(Info: VXI11_NULL_READ_RESP in vxi11_send_and_receive, resending query)\n"); |
+ } |
+ } while (bytes_returned == -VXI11_NULL_READ_RESP || ret == -VXI11_NULL_WRITE_RESP); |
+ return 0; |
+ } |
+ |
+ |
+/* FUNCTIONS TO RETURN A LONG INTEGER VALUE SENT AS RESPONSE TO A QUERY * |
+ * ==================================================================== */ |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd, unsigned long timeout) { |
+char buf[50]; /* 50=arbitrary length... more than enough for one number in ascii */ |
+ memset(buf, 0, 50); |
+ if (vxi11_send_and_receive(clink, cmd, buf, 50, timeout) != 0) { |
+ printf("Returning 0\n"); |
+ return 0; |
+ } |
+ return strtol(buf, (char **)NULL, 10); |
+ } |
+ |
+/* Lazy wrapper function with default read timeout */ |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd) { |
+ return vxi11_obtain_long_value(clink, cmd, VXI11_READ_TIMEOUT); |
+ } |
+ |
+ |
+/* FUNCTIONS TO RETURN A DOUBLE FLOAT VALUE SENT AS RESPONSE TO A QUERY * |
+ * ==================================================================== */ |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd, unsigned long timeout) { |
+char buf[50]; /* 50=arbitrary length... more than enough for one number in ascii */ |
+double val; |
+ memset(buf, 0, 50); |
+ if (vxi11_send_and_receive(clink, cmd, buf, 50, timeout) != 0) { |
+ printf("Returning 0.0\n"); |
+ return 0.0; |
+ } |
+ val = strtod(buf, (char **)NULL); |
+ return val; |
+ } |
+ |
+/* Lazy wrapper function with default read timeout */ |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd) { |
+ return vxi11_obtain_double_value(clink, cmd, VXI11_READ_TIMEOUT); |
+ } |
+ |
+ |
+/***************************************************************************** |
+ * CORE FUNCTIONS - YOU SHOULDN'T NEED TO USE THESE FROM YOUR PROGRAMS OR * |
+ * INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* OPEN FUNCTIONS * |
+ * ============== */ |
+int vxi11_open_device(const char *ip, CLIENT **client, VXI11_LINK **link, char *device) { |
+ |
+ *client = clnt_create(ip, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp"); |
+ |
+ if (*client == NULL) { |
+ clnt_pcreateerror(ip); |
+ return -1; |
+ } |
+ |
+ return vxi11_open_link(ip, client, link, device); |
+ } |
+ |
+int vxi11_open_link(const char *ip, CLIENT **client, VXI11_LINK **link, char *device) { |
+ |
+Create_LinkParms link_parms; |
+ |
+ /* Set link parameters */ |
+ link_parms.clientId = (long) *client; |
+ link_parms.lockDevice = 0; |
+ link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; |
+ link_parms.device = device; |
+ |
+ *link = (Create_LinkResp *) calloc(1, sizeof(Create_LinkResp)); |
+ |
+ if (create_link_1(&link_parms, *link, *client) != RPC_SUCCESS) { |
+ clnt_perror(*client, ip); |
+ return -2; |
+ } |
+ return 0; |
+ } |
+ |
+ |
+/* CLOSE FUNCTIONS * |
+ * =============== */ |
+int vxi11_close_device(const char *ip, CLIENT *client, VXI11_LINK *link) { |
+int ret; |
+ |
+ ret = vxi11_close_link(ip, client, link); |
+ |
+ clnt_destroy(client); |
+ |
+ return ret; |
+ } |
+ |
+int vxi11_close_link(const char *ip, CLIENT *client, VXI11_LINK *link) { |
+Device_Error dev_error; |
+ memset(&dev_error, 0, sizeof(dev_error)); |
+ |
+ if (destroy_link_1(&link->lid, &dev_error, client) != RPC_SUCCESS) { |
+ clnt_perror(client,ip); |
+ return -1; |
+ } |
+ |
+ return 0; |
+ } |
+ |
+ |
+/* SEND FUNCTIONS * |
+ * ============== */ |
+ |
+/* A _lot_ of the time we are sending text strings, and can safely rely on |
+ * strlen(cmd). */ |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd) { |
+ return vxi11_send(client, link, cmd, strlen(cmd)); |
+ } |
+ |
+/* We still need the version of the function where the length is set explicitly |
+ * though, for when we are sending fixed length data blocks. */ |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len) { |
+Device_WriteParms write_parms; |
+int bytes_left = (int)len; |
+char *send_cmd; |
+ |
+ send_cmd = new char[len]; |
+ memcpy(send_cmd, cmd, len); |
+ |
+ write_parms.lid = link->lid; |
+ write_parms.io_timeout = VXI11_DEFAULT_TIMEOUT; |
+ write_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; |
+ |
+/* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop, |
+ * writing a chunk at a time, until we're done. */ |
+ |
+ do { |
+ Device_WriteResp write_resp; |
+ memset(&write_resp, 0, sizeof(write_resp)); |
+ |
+ if (bytes_left <= link->maxRecvSize) { |
+ write_parms.flags = 8; |
+ write_parms.data.data_len = bytes_left; |
+ } |
+ else { |
+ write_parms.flags = 0; |
+ /* We need to check that maxRecvSize is a sane value (ie >0). Believe it |
+ * or not, on some versions of Agilent Infiniium scope firmware the scope |
+ * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless |
+ * we need to catch this, otherwise the program just hangs. */ |
+ if (link->maxRecvSize > 0) { |
+ write_parms.data.data_len = link->maxRecvSize; |
+ } |
+ else { |
+ write_parms.data.data_len = 4096; /* pretty much anything should be able to cope with 4kB */ |
+ } |
+ } |
+ write_parms.data.data_val = send_cmd + (len - bytes_left); |
+ |
+ if(device_write_1(&write_parms, &write_resp, client) != RPC_SUCCESS) { |
+ delete[] send_cmd; |
+ return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely |
+ dropped it. There was no vxi11 comms error as such, the |
+ instrument is just being rude. Usually occurs when the instrument |
+ is busy. If we don't check this first, then the following |
+ line causes a seg fault */ |
+ } |
+ if (write_resp . error != 0) { |
+ printf("vxi11_user: write error: %d\n",write_resp . error); |
+ delete[] send_cmd; |
+ return -(write_resp . error); |
+ } |
+ bytes_left -= write_resp . size; |
+ } while (bytes_left > 0); |
+ |
+ delete[] send_cmd; |
+ return 0; |
+ } |
+ |
+ |
+/* RECEIVE FUNCTIONS * |
+ * ================= */ |
+ |
+// It appeared that this function wasn't correctly dealing with more data available than specified in len. |
+// This patch attempts to fix this issue. RDP 2007/8/13 |
+ |
+/* wrapper, for default timeout */ long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len) { return vxi11_receive(client, link, buffer, len, VXI11_READ_TIMEOUT); |
+ } |
+ |
+#define RCV_END_BIT 0x04 // An end indicator has been read |
+#define RCV_CHR_BIT 0x02 // A termchr is set in flags and a character which matches termChar is transferred |
+#define RCV_REQCNT_BIT 0x01 // requestSize bytes have been transferred. This includes a request size of zero. |
+ |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) { |
+Device_ReadParms read_parms; |
+Device_ReadResp read_resp; |
+long curr_pos = 0; |
+ |
+ read_parms.lid = link->lid; |
+ read_parms.requestSize = len; |
+ read_parms.io_timeout = timeout; /* in ms */ |
+ read_parms.lock_timeout = timeout; /* in ms */ |
+ read_parms.flags = 0; |
+ read_parms.termChar = 0; |
+ |
+ do { |
+ memset(&read_resp, 0, sizeof(read_resp)); |
+ |
+ read_resp.data.data_val = buffer + curr_pos; |
+ read_parms.requestSize = len - curr_pos; // Never request more total data than originally specified in len |
+ |
+ if(device_read_1(&read_parms, &read_resp, client) != RPC_SUCCESS) { |
+ return -VXI11_NULL_READ_RESP; /* there is nothing to read. Usually occurs after sending a query |
+ which times out on the instrument. If we don't check this first, |
+ then the following line causes a seg fault */ |
+ } |
+ if (read_resp . error != 0) { |
+ /* Read failed for reason specified in error code. |
+ * 0 no error |
+ * 4 invalid link identifier |
+ * 11 device locked by another link |
+ * 15 I/O timeout |
+ * 17 I/O error |
+ * 23 abort |
+ */ |
+ |
+ printf("vxi11_user: read error: %d\n",read_resp . error); |
+ return -(read_resp . error); |
+ } |
+ |
+ if((curr_pos + read_resp . data.data_len) <= len) { |
+ curr_pos += read_resp . data.data_len; |
+ } |
+ if( (read_resp.reason & RCV_END_BIT) || (read_resp.reason & RCV_CHR_BIT) ) { |
+ break; |
+ } |
+ else if( curr_pos == len ) { |
+ printf("xvi11_user: read error: buffer too small. Read %d bytes without hitting terminator.\n", curr_pos ); |
+ return -100; |
+ } |
+ } while(1); |
+ return (curr_pos); /*actual number of bytes received*/ |
+ |
+ } |
+ |
Index: sipmscan/trunk/vxi11_i686/vxi11_user.h |
=================================================================== |
--- sipmscan/trunk/vxi11_i686/vxi11_user.h (nonexistent) |
+++ sipmscan/trunk/vxi11_i686/vxi11_user.h (revision 118) |
@@ -0,0 +1,136 @@ |
+/* Revision history: */ |
+/* $Id: vxi11_user.h,v 1.10 2007/10/30 12:47:33 sds Exp $ */ |
+/* |
+ * $Log: vxi11_user.h,v $ |
+ * Revision 1.10 2007/10/30 12:47:33 sds |
+ * changed a lot of char *'s to const char *'s in an attempt to get |
+ * rid of pedantic gcc compiler warnings. |
+ * |
+ * Revision 1.9 2007/07/11 14:20:56 sds |
+ * removed #include <iostream> as not needed |
+ * removed using namespace std |
+ * |
+ * Revision 1.8 2007/07/10 13:54:11 sds |
+ * Added extra function: |
+ * int vxi11_open_device(char *ip, CLINK *clink, char *device); |
+ * This replaces the original vxi11_open_device fn, which did not pass |
+ * a char *device. Wrapper fn used for backwards compatibility. |
+ * |
+ * Revision 1.7 2007/07/10 11:20:43 sds |
+ * removed the following function: |
+ * int vxi11_open_link(CLIENT **client, VXI11_LINK **link); |
+ * ...since it was no longer needed, following the patch by |
+ * Robert Larice. |
+ * |
+ * Revision 1.6 2006/12/08 11:47:14 ijc |
+ * error on last ci, sorted. |
+ * |
+ * Revision 1.5 2006/12/08 11:45:29 ijc |
+ * added #define VXI11_NULL_READ_RESP |
+ * |
+ * Revision 1.4 2006/12/07 12:26:17 sds |
+ * added VXI11_NULL_READ_RESP #define |
+ * |
+ * Revision 1.3 2006/07/06 13:03:28 sds |
+ * Surrounded the whole header with #ifndef __VXI11_USER__. |
+ * Added a couple of vxi11_open_link() fns and a vxi11_close_link() fn, to |
+ * separate the link stuff from the client stuff. |
+ * |
+ * Revision 1.2 2006/06/26 12:42:54 sds |
+ * Introduced a new CLINK structure, to reduce the number of arguments |
+ * passed to functions. Wrote wrappers for open(), close(), send() |
+ * and receieve() functions, then adjusted all the other functions built |
+ * on those to make use of the CLINK structure. |
+ * |
+ * Revision 1.1 2006/06/26 10:36:02 sds |
+ * Initial revision |
+ * |
+ */ |
+ |
+/* vxi11_user.h |
+ * Copyright (C) 2006 Steve D. Sharples |
+ * |
+ * User library for opening, closing, sending to and receiving from |
+ * a device enabled with the VXI11 RPC ethernet protocol. Uses the files |
+ * generated by rpcgen vxi11.x. |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2 |
+ * of the License, or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * The author's email address is steve.sharples@nottingham.ac.uk |
+ */ |
+ |
+#ifndef __VXI11_USER__ |
+#define __VXI11_USER__ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+#include <rpc/rpc.h> |
+#include "vxi11.h" |
+ |
+#define VXI11_DEFAULT_TIMEOUT 10000 /* in ms */ |
+#define VXI11_READ_TIMEOUT 2000 /* in ms */ |
+#define VXI11_CLIENT CLIENT |
+#define VXI11_LINK Create_LinkResp |
+#define VXI11_MAX_CLIENTS 256 /* maximum no of unique IP addresses/clients */ |
+#define VXI11_NULL_READ_RESP 50 /* vxi11_receive() return value if a query |
+ * times out ON THE INSTRUMENT (and so we have |
+ * to resend the query again) */ |
+#define VXI11_NULL_WRITE_RESP 51 /* vxi11_send() return value if a sent command |
+ * times out ON THE INSTURMENT. */ |
+ |
+struct CLINK { |
+ VXI11_CLIENT *client; |
+ VXI11_LINK *link; |
+ } ; |
+typedef struct CLINK CLINK; |
+ |
+/* The four main functions: open, close, send, receieve (plus a couple of wrappers) */ |
+/* In fact all 6 of these are wrappers to the original functions listed at the |
+ * bottom, that use separate CLIENT and VXI11_LINK structures. It was easier to |
+ * write wrappers for these functions than to re-write the original functions |
+ * themselves. These are the 4 (or 6 if you like) key user functions that you |
+ * should probably be using. They all use the CLINK structure. */ |
+int vxi11_open_device(const char *ip, CLINK *clink); |
+int vxi11_open_device(const char *ip, CLINK *clink, char *device); |
+int vxi11_close_device(const char *ip, CLINK *clink); |
+int vxi11_send(CLINK *clink, const char *cmd); |
+int vxi11_send(CLINK *clink, const char *cmd, unsigned long len); |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len); |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout); |
+int vxi11_queryxx(CLINK *clink, char *mycmd); |
+/* Utility functions, that use send() and receive(). Use these too. */ |
+int vxi11_send_data_block(CLINK *clink, const char *cmd, char *buffer, unsigned long len); |
+long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout); |
+long vxi11_send_and_receive(CLINK *clink, const char *cmd, char *buf, unsigned long buf_len, unsigned long timeout); |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd, unsigned long timeout); |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd, unsigned long timeout); |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd); |
+double vxi11_obtain_double_value(CLINK *link, const char *cmd); |
+ |
+/* When I first wrote this library I used separate client and links. I've |
+ * retained the original functions and just written clink wrappers for them |
+ * (see above) as it's perhaps a little clearer this way. Probably not worth |
+ * delving this deep in use, but it's where the real nitty gritty is. */ |
+int vxi11_open_device(const char *ip, CLIENT **client, VXI11_LINK **link, char *device); |
+int vxi11_open_link(const char *ip, CLIENT **client, VXI11_LINK **link, char *device); |
+int vxi11_close_device(const char *ip, CLIENT *client, VXI11_LINK *link); |
+int vxi11_close_link(const char *ip, CLIENT *client, VXI11_LINK *link); |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd); |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len); |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len); |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout); |
+ |
+#endif |
Index: sipmscan/trunk/vxi11_x86_64/CHANGELOG.txt |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/CHANGELOG.txt (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/CHANGELOG.txt (revision 118) |
@@ -0,0 +1,218 @@ |
+------------------------------------------------------------------------------ |
+vxi11_1.10 - 9/09/2010 |
+ |
+Bug fix (thanks to Stephan Mahr): in vxi11_close(), remove the IP address |
+from the global array that keeps track of them so that if the same device |
+is opened again, then a new client is created, rather than it attempting |
+to use the old one (which was destroyed on the previous close). |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.09 - 7/06/2010 |
+ |
+Moved over to bazaar VCS (from RCS). |
+ |
+Makefile cleanups. Fixed signed/unsigned comparisons. Use consistent (and |
+sane) struct separator spacing in code. |
+ |
+Fix int casting on printf statements to fix new compiler warnings/errors |
+(thanks to Shouri Chatterjee for pointing this out). |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.08 - 3/09/2009 |
+ |
+Added a sanity check for link->maxRecvSize to make sure it's >0. This gets |
+around a bug in some versions of the Agilent Infiniium scope software. |
+ |
+Changed the erroneous strncpy() to memcpy() in vxi11_send, as we could be |
+sending binary data (not just strings). |
+ |
+Changed a lot of char *'s to const char *'s in an attempt to get rid of |
+pedantic gcc compiler warnings. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.07 - 9/10/2007 |
+ |
+Minor change to vxi11_receive_data_block(), this fn now copes with instruments |
+that return just "#0" (for whatever reason). Suggestion by Jarek Sadowski, |
+gratefully received. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.06 - 31/08/2007 |
+ |
+Bug fix in vxi11_receive(), to ensure that no more than "len" bytes are ever |
+received (and so avoiding a segmentation fault). This was a bug introduced in |
+release 1.04 whilst making some other changes to the vxi11_receive() fn. |
+ |
+Many thanks to Rob Penny for spotting the bug and providing a patch. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.05 - 11/07/2007 |
+ |
+Added the ability to specify a "device name" when calling vxi11_open_device(). |
+For regular VXI11-based instruments, such as scopes and AFGs, the device name |
+is usually "hard wired" to be "inst0", and up to now this has been hard wired |
+into the vxi11_user code. However, devices such as LAN to GPIB gateways need |
+some way of distinguishing between different devices... they are a single |
+client (one IP address), with multiple devices. |
+ |
+The vxi11_user fn, vxi11_open_device(), now takes a third argument |
+(char *device). |
+This gets passed to the core vxi11_open_device() fn (the one that deals with |
+separate clients and links), and the core vxi11_open_link() fn; these two |
+core functions have also had an extra parameter added accordingly. In order |
+to not break the API, a wrapper function is provided in the form of the |
+original vxi11_open_device() fn, that just takes 2 arguments |
+(char *ip, CLINK *clink), this then passes "inst0" as the device argument. |
+Backwards-compatible wrappers for the core functions have NOT been provided. |
+These are generally not used from userland anyway. Hopefully this won't |
+upset anyone! |
+ |
+vxi11_cmd, the simple test utility, has also been updated. You can now, |
+optionally, pass the device_name as a second argument (after the ip |
+address). The source has been renamed to vxi11_cmd.cc (from vxi11_cmd.c), as |
+it is C++ code not C. |
+ |
+Some minor tidying up in vxi11_user.h |
+ |
+With thanks to Oliver Schulz for bringing LAN to GPIB gateways to my |
+attention, for suggesting changes to the vxi11_user library to allow them to |
+be accommodated, and for tidying some things up. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.04 - 10/07/2007 |
+ |
+Patch applied, which was kindly provided by Robert Larice. This sorts out |
+the confusion (on my part) about the structures returned by the rpcgen |
+generated *_1() functions... these are statically allocated temporary structs, |
+apparently. In the words of Robert Larice: |
+ |
+****** |
+Hello Dr. Sharples, |
+ |
+ I'm sending some patches for your nice gem "vxi11_1.03" |
+ |
+ In the source code there were some strange comments, concerning |
+ a commented free() around ... Manfred S. ... |
+ and some notes, suggesting you had trouble to get more than one link |
+ working. |
+ |
+ I think thats caused by some misuse of the rpcgen generated subroutines. |
+ 1) those rpcgen generated *_1 functions returned pointers to |
+ statically allocated temporary structs. |
+ those where meant to be instantly copied to the user's space, |
+ which wasn't done |
+ thus instead of |
+ Device_ReadResp *read_resp; |
+ read_resp = device_read_1(...) |
+ one should have written someting like: |
+ Device_ReadResp *read_resp; |
+ read_resp = malloc(...) |
+ memcpy(read_resp, device_read_1(...), ...) |
+ 2) but a better fix is to use the rpcgen -M Flag |
+ which allows to pass the memory space as a third argument |
+ so one can write |
+ Device_ReadResp *read_resp; |
+ read_resp = malloc(...) |
+ device_read_1(..., read_resp, ...) |
+ furthermore this is now automatically thread save |
+ 3) the rpcgen function device_read_1 |
+ expects a target buffer to be passed via read_resp |
+ which was not done. |
+ 4) the return value of vxi11_receive() was computed incorrectly |
+ 5) minor, Makefile typo's |
+ CFLAGS versus |
+ CLFAGS |
+ |
+****** |
+ |
+Robert didn't have more than one device to try the patch with, but I've just |
+tried it and everything seems fine. So I've removed all references to the |
+VXI11_ENABLE_MULTIPLE_CLIENTS global variable, and removed the call to |
+vxi11_open_link() from the vxi11_send() fn. There has been an associated |
+tidying of functions, and removal of some comments. |
+ |
+Thanks once again to Robert Larice for the patch and the explanation! |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.03 - 29/01/2007 |
+ |
+Some bug-fixes (thanks to Manfred S.), and extra awareness of the |
+possibility that instruments could time out after receiving a query WITHOUT |
+causing an error condition. In some cases (prior to these changes) this |
+could have resulted in a segmentation fault. |
+ |
+Specifically: |
+ |
+(1) removed call to ANSI free() fn in vxi11_receive, which according to |
+ Manfred S. "is not necessary and wrong (crashes)". |
+ |
+(2) added extra check in vxi11_receive() to see if read_resp==NULL. |
+ read_resp can apparently be NULL if (eg) you send an instrument a |
+ query, but the instrument is so busy with something else for so long |
+ that it forgets the original query. So this extra check is for that |
+ situation, and vxi11_receive returns -VXI11_NULL_READ_RESP to the |
+ calling function. |
+ |
+(3) vxi11_send_and_receive() is now aware of the possibility of being |
+ returned -VXI11_NULL_READ_RESP. If so, it re-sends the query, until |
+ either getting a "regular" read error (read_resp->error!=0) or a |
+ successful read. |
+ |
+(4) Similar to (2)... added extra check in vxi11_send() to see if |
+ write_resp==NULL. If so, return -VXI11_NULL_WRITE_RESP. As with (3), |
+ send_and_receive() is now aware of this possibility. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.02 - 25/08/2006 |
+ |
+Important changes to the core vxi11_send() function, which should be |
+invisible to the user. |
+ |
+For those interested, the function now takes note of the value of |
+link->maxRecvSize, which is the maximum number of bytes that the vxi11 |
+intrument you're talking to can receive in one go. For many instruments |
+this may be a few kB, which isn't a problem for sending short commands; |
+however, sending large chunks of data (for example sending waveforms |
+to instruments) may exceed this maxRecvSize. The core vxi11_send() function |
+has been re-written to ensure that only a maximum of [maxRecvSize] bytes are |
+written in one go... the function sits in a loop until all the message/ |
+data is written. |
+ |
+Also tidied up some of the return values (specifically with regard to |
+vxi11_send() and vxi11_send_data_block() ). |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.01 - 06/07/2006 |
+ |
+Fair few changes since v1.00, all in vxi11_user.c and vxi11_user.h |
+ |
+Found I was having problems talking to multiple links on the same |
+client, if I created a different client for each one. So introduced |
+a few global variables to keep track of all the ip addresses of |
+clients that the library is asked to create, and only creating new |
+clients if the ip address is different. This puts a limit of how |
+many unique ip addresses (clients) a single process can connect to. |
+Set this value at 256 (should hopefully be enough!). |
+ |
+Next I found that talking to different clients on different ip |
+addresses didn't work. It turns out that create_link_1() creates |
+a static structure. This this link is associated with a given |
+client (and hence a given IP address), then the only way I could |
+think of making things work was to add a call to an |
+vxi11_open_link() function before each send command (no idea what |
+this adds to overheads and it's very messy!) - at least I was |
+able to get this to only happen when we are using more than one |
+client/ip address. |
+ |
+Also, while I was at it, I re-ordered the functions a little - |
+starts with core user functions, extra user functions, then core |
+library functions at the end. Added a few more comments. Tidied |
+up. Left some debugging info in, but commented out. |
+ |
+------------------------------------------------------------------------------ |
+vxi11_1.00 - 23/06/2006 |
+ |
+Initial release. |
+ |
+------------------------------------------------------------------------------ |
+ |
Index: sipmscan/trunk/vxi11_x86_64/GNU_General_Public_License.txt |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/GNU_General_Public_License.txt (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/GNU_General_Public_License.txt (revision 118) |
@@ -0,0 +1,340 @@ |
+ GNU GENERAL PUBLIC LICENSE |
+ Version 2, June 1991 |
+ |
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
+ Everyone is permitted to copy and distribute verbatim copies |
+ of this license document, but changing it is not allowed. |
+ |
+ Preamble |
+ |
+ The licenses for most software are designed to take away your |
+freedom to share and change it. By contrast, the GNU General Public |
+License is intended to guarantee your freedom to share and change free |
+software--to make sure the software is free for all its users. This |
+General Public License applies to most of the Free Software |
+Foundation's software and to any other program whose authors commit to |
+using it. (Some other Free Software Foundation software is covered by |
+the GNU Library General Public License instead.) You can apply it to |
+your programs, too. |
+ |
+ When we speak of free software, we are referring to freedom, not |
+price. Our General Public Licenses are designed to make sure that you |
+have the freedom to distribute copies of free software (and charge for |
+this service if you wish), that you receive source code or can get it |
+if you want it, that you can change the software or use pieces of it |
+in new free programs; and that you know you can do these things. |
+ |
+ To protect your rights, we need to make restrictions that forbid |
+anyone to deny you these rights or to ask you to surrender the rights. |
+These restrictions translate to certain responsibilities for you if you |
+distribute copies of the software, or if you modify it. |
+ |
+ For example, if you distribute copies of such a program, whether |
+gratis or for a fee, you must give the recipients all the rights that |
+you have. You must make sure that they, too, receive or can get the |
+source code. And you must show them these terms so they know their |
+rights. |
+ |
+ We protect your rights with two steps: (1) copyright the software, and |
+(2) offer you this license which gives you legal permission to copy, |
+distribute and/or modify the software. |
+ |
+ Also, for each author's protection and ours, we want to make certain |
+that everyone understands that there is no warranty for this free |
+software. If the software is modified by someone else and passed on, we |
+want its recipients to know that what they have is not the original, so |
+that any problems introduced by others will not reflect on the original |
+authors' reputations. |
+ |
+ Finally, any free program is threatened constantly by software |
+patents. We wish to avoid the danger that redistributors of a free |
+program will individually obtain patent licenses, in effect making the |
+program proprietary. To prevent this, we have made it clear that any |
+patent must be licensed for everyone's free use or not licensed at all. |
+ |
+ The precise terms and conditions for copying, distribution and |
+modification follow. |
+ |
+ GNU GENERAL PUBLIC LICENSE |
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
+ |
+ 0. This License applies to any program or other work which contains |
+a notice placed by the copyright holder saying it may be distributed |
+under the terms of this General Public License. The "Program", below, |
+refers to any such program or work, and a "work based on the Program" |
+means either the Program or any derivative work under copyright law: |
+that is to say, a work containing the Program or a portion of it, |
+either verbatim or with modifications and/or translated into another |
+language. (Hereinafter, translation is included without limitation in |
+the term "modification".) Each licensee is addressed as "you". |
+ |
+Activities other than copying, distribution and modification are not |
+covered by this License; they are outside its scope. The act of |
+running the Program is not restricted, and the output from the Program |
+is covered only if its contents constitute a work based on the |
+Program (independent of having been made by running the Program). |
+Whether that is true depends on what the Program does. |
+ |
+ 1. You may copy and distribute verbatim copies of the Program's |
+source code as you receive it, in any medium, provided that you |
+conspicuously and appropriately publish on each copy an appropriate |
+copyright notice and disclaimer of warranty; keep intact all the |
+notices that refer to this License and to the absence of any warranty; |
+and give any other recipients of the Program a copy of this License |
+along with the Program. |
+ |
+You may charge a fee for the physical act of transferring a copy, and |
+you may at your option offer warranty protection in exchange for a fee. |
+ |
+ 2. You may modify your copy or copies of the Program or any portion |
+of it, thus forming a work based on the Program, and copy and |
+distribute such modifications or work under the terms of Section 1 |
+above, provided that you also meet all of these conditions: |
+ |
+ a) You must cause the modified files to carry prominent notices |
+ stating that you changed the files and the date of any change. |
+ |
+ b) You must cause any work that you distribute or publish, that in |
+ whole or in part contains or is derived from the Program or any |
+ part thereof, to be licensed as a whole at no charge to all third |
+ parties under the terms of this License. |
+ |
+ c) If the modified program normally reads commands interactively |
+ when run, you must cause it, when started running for such |
+ interactive use in the most ordinary way, to print or display an |
+ announcement including an appropriate copyright notice and a |
+ notice that there is no warranty (or else, saying that you provide |
+ a warranty) and that users may redistribute the program under |
+ these conditions, and telling the user how to view a copy of this |
+ License. (Exception: if the Program itself is interactive but |
+ does not normally print such an announcement, your work based on |
+ the Program is not required to print an announcement.) |
+ |
+These requirements apply to the modified work as a whole. If |
+identifiable sections of that work are not derived from the Program, |
+and can be reasonably considered independent and separate works in |
+themselves, then this License, and its terms, do not apply to those |
+sections when you distribute them as separate works. But when you |
+distribute the same sections as part of a whole which is a work based |
+on the Program, the distribution of the whole must be on the terms of |
+this License, whose permissions for other licensees extend to the |
+entire whole, and thus to each and every part regardless of who wrote it. |
+ |
+Thus, it is not the intent of this section to claim rights or contest |
+your rights to work written entirely by you; rather, the intent is to |
+exercise the right to control the distribution of derivative or |
+collective works based on the Program. |
+ |
+In addition, mere aggregation of another work not based on the Program |
+with the Program (or with a work based on the Program) on a volume of |
+a storage or distribution medium does not bring the other work under |
+the scope of this License. |
+ |
+ 3. You may copy and distribute the Program (or a work based on it, |
+under Section 2) in object code or executable form under the terms of |
+Sections 1 and 2 above provided that you also do one of the following: |
+ |
+ a) Accompany it with the complete corresponding machine-readable |
+ source code, which must be distributed under the terms of Sections |
+ 1 and 2 above on a medium customarily used for software interchange; or, |
+ |
+ b) Accompany it with a written offer, valid for at least three |
+ years, to give any third party, for a charge no more than your |
+ cost of physically performing source distribution, a complete |
+ machine-readable copy of the corresponding source code, to be |
+ distributed under the terms of Sections 1 and 2 above on a medium |
+ customarily used for software interchange; or, |
+ |
+ c) Accompany it with the information you received as to the offer |
+ to distribute corresponding source code. (This alternative is |
+ allowed only for noncommercial distribution and only if you |
+ received the program in object code or executable form with such |
+ an offer, in accord with Subsection b above.) |
+ |
+The source code for a work means the preferred form of the work for |
+making modifications to it. For an executable work, complete source |
+code means all the source code for all modules it contains, plus any |
+associated interface definition files, plus the scripts used to |
+control compilation and installation of the executable. However, as a |
+special exception, the source code distributed need not include |
+anything that is normally distributed (in either source or binary |
+form) with the major components (compiler, kernel, and so on) of the |
+operating system on which the executable runs, unless that component |
+itself accompanies the executable. |
+ |
+If distribution of executable or object code is made by offering |
+access to copy from a designated place, then offering equivalent |
+access to copy the source code from the same place counts as |
+distribution of the source code, even though third parties are not |
+compelled to copy the source along with the object code. |
+ |
+ 4. You may not copy, modify, sublicense, or distribute the Program |
+except as expressly provided under this License. Any attempt |
+otherwise to copy, modify, sublicense or distribute the Program is |
+void, and will automatically terminate your rights under this License. |
+However, parties who have received copies, or rights, from you under |
+this License will not have their licenses terminated so long as such |
+parties remain in full compliance. |
+ |
+ 5. You are not required to accept this License, since you have not |
+signed it. However, nothing else grants you permission to modify or |
+distribute the Program or its derivative works. These actions are |
+prohibited by law if you do not accept this License. Therefore, by |
+modifying or distributing the Program (or any work based on the |
+Program), you indicate your acceptance of this License to do so, and |
+all its terms and conditions for copying, distributing or modifying |
+the Program or works based on it. |
+ |
+ 6. Each time you redistribute the Program (or any work based on the |
+Program), the recipient automatically receives a license from the |
+original licensor to copy, distribute or modify the Program subject to |
+these terms and conditions. You may not impose any further |
+restrictions on the recipients' exercise of the rights granted herein. |
+You are not responsible for enforcing compliance by third parties to |
+this License. |
+ |
+ 7. If, as a consequence of a court judgment or allegation of patent |
+infringement or for any other reason (not limited to patent issues), |
+conditions are imposed on you (whether by court order, agreement or |
+otherwise) that contradict the conditions of this License, they do not |
+excuse you from the conditions of this License. If you cannot |
+distribute so as to satisfy simultaneously your obligations under this |
+License and any other pertinent obligations, then as a consequence you |
+may not distribute the Program at all. For example, if a patent |
+license would not permit royalty-free redistribution of the Program by |
+all those who receive copies directly or indirectly through you, then |
+the only way you could satisfy both it and this License would be to |
+refrain entirely from distribution of the Program. |
+ |
+If any portion of this section is held invalid or unenforceable under |
+any particular circumstance, the balance of the section is intended to |
+apply and the section as a whole is intended to apply in other |
+circumstances. |
+ |
+It is not the purpose of this section to induce you to infringe any |
+patents or other property right claims or to contest validity of any |
+such claims; this section has the sole purpose of protecting the |
+integrity of the free software distribution system, which is |
+implemented by public license practices. Many people have made |
+generous contributions to the wide range of software distributed |
+through that system in reliance on consistent application of that |
+system; it is up to the author/donor to decide if he or she is willing |
+to distribute software through any other system and a licensee cannot |
+impose that choice. |
+ |
+This section is intended to make thoroughly clear what is believed to |
+be a consequence of the rest of this License. |
+ |
+ 8. If the distribution and/or use of the Program is restricted in |
+certain countries either by patents or by copyrighted interfaces, the |
+original copyright holder who places the Program under this License |
+may add an explicit geographical distribution limitation excluding |
+those countries, so that distribution is permitted only in or among |
+countries not thus excluded. In such case, this License incorporates |
+the limitation as if written in the body of this License. |
+ |
+ 9. The Free Software Foundation may publish revised and/or new versions |
+of the General Public License from time to time. Such new versions will |
+be similar in spirit to the present version, but may differ in detail to |
+address new problems or concerns. |
+ |
+Each version is given a distinguishing version number. If the Program |
+specifies a version number of this License which applies to it and "any |
+later version", you have the option of following the terms and conditions |
+either of that version or of any later version published by the Free |
+Software Foundation. If the Program does not specify a version number of |
+this License, you may choose any version ever published by the Free Software |
+Foundation. |
+ |
+ 10. If you wish to incorporate parts of the Program into other free |
+programs whose distribution conditions are different, write to the author |
+to ask for permission. For software which is copyrighted by the Free |
+Software Foundation, write to the Free Software Foundation; we sometimes |
+make exceptions for this. Our decision will be guided by the two goals |
+of preserving the free status of all derivatives of our free software and |
+of promoting the sharing and reuse of software generally. |
+ |
+ NO WARRANTY |
+ |
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
+REPAIR OR CORRECTION. |
+ |
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
+POSSIBILITY OF SUCH DAMAGES. |
+ |
+ END OF TERMS AND CONDITIONS |
+ |
+ How to Apply These Terms to Your New Programs |
+ |
+ If you develop a new program, and you want it to be of the greatest |
+possible use to the public, the best way to achieve this is to make it |
+free software which everyone can redistribute and change under these terms. |
+ |
+ To do so, attach the following notices to the program. It is safest |
+to attach them to the start of each source file to most effectively |
+convey the exclusion of warranty; and each file should have at least |
+the "copyright" line and a pointer to where the full notice is found. |
+ |
+ <one line to give the program's name and a brief idea of what it does.> |
+ Copyright (C) <year> <name of author> |
+ |
+ This program is free software; you can redistribute it and/or modify |
+ it under the terms of the GNU General Public License as published by |
+ the Free Software Foundation; either version 2 of the License, or |
+ (at your option) any later version. |
+ |
+ This program is distributed in the hope that it will be useful, |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ GNU General Public License for more details. |
+ |
+ You should have received a copy of the GNU General Public License |
+ along with this program; if not, write to the Free Software |
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
+ |
+ |
+Also add information on how to contact you by electronic and paper mail. |
+ |
+If the program is interactive, make it output a short notice like this |
+when it starts in an interactive mode: |
+ |
+ Gnomovision version 69, Copyright (C) year name of author |
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
+ This is free software, and you are welcome to redistribute it |
+ under certain conditions; type `show c' for details. |
+ |
+The hypothetical commands `show w' and `show c' should show the appropriate |
+parts of the General Public License. Of course, the commands you use may |
+be called something other than `show w' and `show c'; they could even be |
+mouse-clicks or menu items--whatever suits your program. |
+ |
+You should also get your employer (if you work as a programmer) or your |
+school, if any, to sign a "copyright disclaimer" for the program, if |
+necessary. Here is a sample; alter the names: |
+ |
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
+ `Gnomovision' (which makes passes at compilers) written by James Hacker. |
+ |
+ <signature of Ty Coon>, 1 April 1989 |
+ Ty Coon, President of Vice |
+ |
+This General Public License does not permit incorporating your program into |
+proprietary programs. If your program is a subroutine library, you may |
+consider it more useful to permit linking proprietary applications with the |
+library. If this is what you want to do, use the GNU Library General |
+Public License instead of this License. |
Index: sipmscan/trunk/vxi11_x86_64/Makefile |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/Makefile (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/Makefile (revision 118) |
@@ -0,0 +1,18 @@ |
+VERSION=1.08 |
+ |
+#CFLAGS = -Wall -g |
+CFLAGS = -g |
+CXX = g++ |
+ |
+.PHONY: clean objs |
+ |
+objs: vxi11.h |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_user.cc |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_clnt.c |
+ $(CXX) -c -fPIC $(CFLAGS) vxi11_xdr.c |
+ |
+vxi11.h: vxi11.x |
+ rpcgen -M vxi11.x |
+ |
+clean: |
+ rm -f *.o vxi11_cmd vxi11.h vxi11_svc.c vxi11_xdr.c vxi11_clnt.c #TAGS |
Index: sipmscan/trunk/vxi11_x86_64/Makefile.old |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/Makefile.old (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/Makefile.old (revision 118) |
@@ -0,0 +1,40 @@ |
+VERSION=1.08 |
+ |
+#CFLAGS = -Wall -g |
+CFLAGS = -g |
+INSTALL = install |
+prefix = /usr/local |
+CXX = g++ |
+ |
+.PHONY : install clean dist distclean |
+ |
+vxi11_cmd: vxi11_cmd.o vxi11_user.o vxi11_clnt.o vxi11_xdr.o |
+ $(CXX) -fPIC $(CFLAGS) -o $@ $^ |
+ |
+vxi11_cmd.o: vxi11_cmd.cc vxi11_user.cc vxi11.h |
+ $(CXX) -fPIC $(CFLAGS) -c $< -o $@ |
+ |
+vxi11_user.o: vxi11_user.cc vxi11.h |
+ $(CXX) -fPIC $(CFLAGS) -c $< -o $@ |
+ |
+vxi11.h vxi11_clnt.c vxi11_xdr.c : vxi11.x |
+ rpcgen -M vxi11.x |
+ |
+TAGS: $(wildcard *.c) $(wildcard *.h) $(wildcard *.cc) |
+ etags $^ |
+ |
+clean: |
+ rm -f *.o vxi11_cmd vxi11.h vxi11_svc.c vxi11_xdr.c vxi11_clnt.c TAGS |
+ |
+install: vxi11_cmd |
+ $(INSTALL) vxi11_cmd $(DESTDIR)$(prefix)/bin/ |
+ |
+dist : distclean |
+ mkdir vxi11-$(VERSION) |
+ cp -p vxi11_cmd.cc vxi11_user.cc vxi11_user.h vxi11.x vxi11-$(VERSION)/ |
+ cp -p Makefile CHANGELOG.txt README.txt GNU_General_Public_License.txt vxi11-$(VERSION)/ |
+ tar -zcf vxi11-$(VERSION).tar.gz vxi11-$(VERSION) |
+ |
+distclean : |
+ rm -rf vxi11-$(VERSION) |
+ rm -f vxi11-$(VERSION).tar.gz |
Index: sipmscan/trunk/vxi11_x86_64/README.txt |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/README.txt (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/README.txt (revision 118) |
@@ -0,0 +1,98 @@ |
+RPC PROTOCOL FOR COMMUNICATING WITH VXI11-ENABLED DEVICES OVER ETHERNET FROM LINUX |
+================================================================================== |
+(including instruments such as oscilloscopes, by manufacturers such as |
+Agilent and Tektronix, amongst others). |
+ |
+By Steve D. Sharples, June 2006. |
+ |
+This is a collection of source code that will allow you to talk to ethernet- |
+enabled instruments that use the VXI11 protocol, from Linux. This includes |
+a wide range of instruments (including oscilloscopes, logic analysers, |
+function generators etc) by a wide range of manufacturers (including |
+Tektronix and Agilent to name just a couple). An interactive "send and |
+receive" utility is included as an example. |
+ |
+You may want to build on to this libraries for your specific instruments - |
+I'm currently working on libraries for talking to Agilent Infiniium scopes, |
+and will probably do the same for Tektronix scopes too. Basically if you've |
+got a Programmer's Reference for your instrument, and this code, you should |
+be able to cobble something together. |
+ |
+This collection of code has been produced because I grew frustrated at how |
+difficult it seemed to be to do a relatively simple task. None of the |
+major manufacturers had any "out of the box" Linux solutions to talking to |
+their instruments (although often I would talk to technical folks who would |
+try their best to help). One of the solutions offered was to use something |
+called NI VISA; parts of this are closed source, it was enormous, and I had |
+worries about legacy issues with changing PC hardware. |
+ |
+Via Guy McBride at Agilent, I obtained a copy of a vxi11.x RPC file similar |
+to the one included here (although no-one at Agilent seemed to know or care |
+where it came from). After lots of searching on the information superhighway |
+I located what I believe is the original source (or something like it); see |
+the section on vxi11.x below. This source seems to have literally been written |
+from the published VXI11 protocol. I also received from Agilent a simple |
+example program that showed you how to use the protocol; working from this |
+and the (open) source that uses the vxi11.x that is included here, I wrote |
+vxi11_cmd and the user libraries. |
+ |
+This collection of source code consists of: |
+ |
+(1) vxi11.x |
+This file, vxi11.x, is the amalgamation of vxi11core.rpcl and vxi11intr.rpcl |
+which are part of the asynDriver (R4-5) EPICS module, which, at time of |
+writing, is available from: |
+http://www.aps.anl.gov/epics/modules/soft/asyn/index.html |
+More general information about EPICS is available from: |
+http://www.aps.anl.gov/epics/ |
+This code is open source, and is covered under the copyright notice and |
+software license agreement shown below, and also at: |
+http://www.aps.anl.gov/epics/license/open.php |
+ |
+It is intended as a lightweight base for the vxi11 rpc protocol. If you |
+run rpcgen on this file, it will generate C files and headers, from which |
+it is relatively simple to write C programs to communicate with a range |
+of ethernet-enabled instruments, such as oscilloscopes and function |
+generators by manufacturers such as Agilent and Tektronix (amongst many |
+others). |
+ |
+(2) vxi11_user.cc (and vxi11_user.h) |
+These are (fairly) friendly user libraries. At the core are 4 key functions: |
+vxi11_open(), vxi11_close(), vxi11_send() and vxi11_receive(). These allow |
+you to talk to your device. There are also some other functions that I |
+considered to be generally useful (send_and_receive, functions for sending |
+and receiving fixed length data blocks etc) that are all non-instrument- |
+specific. |
+ |
+(3) vxi11_cmd.c |
+This is a fairly simple interactive utility that allows you to send |
+commands and queries to your vxi11-enabled instrument, which you |
+locate by way of IP address. I recommend you start with *IDN? It shows you |
+how the vxi11_user library works |
+ |
+(4) Makefile |
+Type "make" to compile the source above. Type "make clean" to remove |
+old object files and ./vxi11_cmd. Type "make install" to copy |
+./vxi11_cmd to /usr/local/bin/ |
+ |
+(5) GNU_General_Public_License.txt |
+Fairly obvious. All programs, source, readme files etc NOT covered by any |
+other license (e.g. vxi11.x, which is covered by its own open source |
+license) are covered by this license. |
+ |
+These programs are free software; you can redistribute it and/or |
+modify it under the terms of the GNU General Public License |
+as published by the Free Software Foundation; either version 2 |
+of the License, or (at your option) any later version. |
+ |
+These programs are distributed in the hope that they will be useful, |
+but WITHOUT ANY WARRANTY; without even the implied warranty of |
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+GNU General Public License for more details. |
+ |
+You should have received a copy of the GNU General Public License |
+along with this program; if not, write to the Free Software |
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ |
+The author's email address is steve.no.spam.sharples@nottingham.ac.uk |
+(you can work it out!) |
Index: sipmscan/trunk/vxi11_x86_64/vxi11.x |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/vxi11.x (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/vxi11.x (revision 118) |
@@ -0,0 +1,317 @@ |
+/* This file, vxi11.x, is the amalgamation of vxi11core.rpcl and vxi11intr.rpcl |
+ * which are part of the asynDriver (R4-5) EPICS module, which, at time of |
+ * writing, is available from: |
+ * http://www.aps.anl.gov/epics/modules/soft/asyn/index.html |
+ * More general information about EPICS is available from: |
+ * http://www.aps.anl.gov/epics/ |
+ * This code is open source, and is covered under the copyright notice and |
+ * software license agreement shown below, and also at: |
+ * http://www.aps.anl.gov/epics/license/open.php |
+ * |
+ * In order to comply with section 4.3 of the software license agreement, here |
+ * is a PROMINENT NOTICE OF CHNAGES TO THE SOFTWARE |
+ * =========================================== |
+ * (1) This file, vxi11.x, is the concatenation of the files vxi11core.rpcl and |
+ * vxi11intr.rpcl |
+ * (2) Tab spacing has been tidied up |
+ * |
+ * It is intended as a lightweight base for the vxi11 rpc protocol. If you |
+ * run rpcgen on this file, it will generate C files and headers, from which |
+ * it is relatively simple to write C programs to communicate with a range |
+ * of ethernet-enabled instruments, such as oscilloscopes and function |
+ * generated by manufacturers such as Agilent and Tektronix (amongst many |
+ * others). |
+ * |
+ * For what it's worth, this concatenation was done by Steve Sharples at |
+ * the University of Nottingham, UK, on 1 June 2006. |
+ * |
+ * Copyright notice and software license agreement follow, then the |
+ * original comments from vxi11core.rpcl etc. |
+ * |
+ ****************************************************************************** |
+ * Copyright © 2006 <University of Chicago and other copyright holders>. All |
+ * rights reserved. |
+ ****************************************************************************** |
+ * |
+ ****************************************************************************** |
+ * vxi11.x is distributed subject to the following license conditions: |
+ * SOFTWARE LICENSE AGREEMENT |
+ * Software: vxi11.x |
+ * |
+ * 1. The "Software", below, refers to vxi11.x (in either source code, or |
+ * binary form and accompanying documentation). Each licensee is addressed |
+ * as "you" or "Licensee." |
+ * |
+ * 2. The copyright holders shown above and their third-party licensors hereby |
+ * grant Licensee a royalty-free nonexclusive license, subject to the |
+ * limitations stated herein and U.S. Government license rights. |
+ * |
+ * 3. You may modify and make a copy or copies of the Software for use within |
+ * your organization, if you meet the following conditions: |
+ * 1. Copies in source code must include the copyright notice and this |
+ * Software License Agreement. |
+ * 2. Copies in binary form must include the copyright notice and this |
+ * Software License Agreement in the documentation and/or other |
+ * materials provided with the copy. |
+ * |
+ * 4. You may modify a copy or copies of the Software or any portion of it, |
+ * thus forming a work based on the Software, and distribute copies of such |
+ * work outside your organization, if you meet all of the following |
+ * conditions: |
+ * 1. Copies in source code must include the copyright notice and this |
+ * Software License Agreement; |
+ * 2. Copies in binary form must include the copyright notice and this |
+ * Software License Agreement in the documentation and/or other |
+ * materials provided with the copy; |
+ * 3. Modified copies and works based on the Software must carry |
+ * prominent notices stating that you changed specified portions of |
+ * the Software. |
+ * |
+ * 5. Portions of the Software resulted from work developed under a U.S. |
+ * Government contract and are subject to the following license: the |
+ * Government is granted for itself and others acting on its behalf a |
+ * paid-up, nonexclusive, irrevocable worldwide license in this computer |
+ * software to reproduce, prepare derivative works, and perform publicly |
+ * and display publicly. |
+ * |
+ * 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF |
+ * ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE UNITED |
+ * STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR EMPLOYEES: (1) |
+ * DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO |
+ * ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
+ * PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY |
+ * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF THE |
+ * SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE |
+ * PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION |
+ * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. |
+ * |
+ * 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR |
+ * THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF |
+ * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, |
+ * CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, |
+ * INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY |
+ * REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF |
+ * CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, |
+ * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE POSSIBILITY OF SUCH |
+ * LOSS OR DAMAGES. |
+ ****************************************************************************** |
+ */ |
+ |
+/****************************************************************************** |
+ * |
+ * vxi11core.rpcl |
+ * |
+ * This file is best viewed with a tabwidth of 4 |
+ * |
+ ****************************************************************************** |
+ * |
+ * TODO: |
+ * |
+ ****************************************************************************** |
+ * |
+ * Original Author: someone from VXIbus Consortium |
+ * Current Author: Benjamin Franksen |
+ * Date: 03-06-97 |
+ * |
+ * RPCL description of the core- and abort-channel of the TCP/IP Instrument |
+ * Protocol Specification. |
+ * |
+ * |
+ * Modification Log: |
+ * ----------------- |
+ * .00 03-06-97 bfr created this file |
+ * |
+ ****************************************************************************** |
+ * |
+ * Notes: |
+ * |
+ * This stuff is literally from |
+ * |
+ * VXI-11, Ref 1.0 : TCP/IP Instrument Protocol Specification |
+ * |
+ */ |
+ |
+typedef long Device_Link; |
+ |
+enum Device_AddrFamily |
+{ |
+ DEVICE_TCP, |
+ DEVICE_UDP |
+}; |
+ |
+typedef long Device_Flags; |
+ |
+typedef long Device_ErrorCode; |
+ |
+struct Device_Error |
+{ |
+ Device_ErrorCode error; |
+}; |
+ |
+struct Create_LinkParms |
+{ |
+ long clientId; /* implementation specific value */ |
+ bool lockDevice; /* attempt to lock the device */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ string device<>; /* name of device */ |
+}; |
+struct Create_LinkResp |
+{ |
+ Device_ErrorCode error; |
+ Device_Link lid; |
+ unsigned short abortPort; /* for the abort RPC */ |
+ unsigned long maxRecvSize; /* max # of bytes accepted on write */ |
+}; |
+struct Device_WriteParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ Device_Flags flags; /* flags with options */ |
+ opaque data<>; /* the data length and the data itself */ |
+}; |
+struct Device_WriteResp |
+{ |
+ Device_ErrorCode error; |
+ unsigned long size; /* # of bytes written */ |
+}; |
+struct Device_ReadParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ unsigned long requestSize; /* # of bytes requested */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ Device_Flags flags; /* flags with options */ |
+ char termChar; /* valid if flags & termchrset */ |
+}; |
+struct Device_ReadResp |
+{ |
+ Device_ErrorCode error; |
+ long reason; /* why read completed */ |
+ opaque data<>; /* the data length and the data itself */ |
+}; |
+struct Device_ReadStbResp |
+{ |
+ Device_ErrorCode error; |
+ unsigned char stb; /* the returned status byte */ |
+}; |
+struct Device_GenericParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* flags with options */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+}; |
+struct Device_RemoteFunc |
+{ |
+ unsigned long hostAddr; /* host servicing interrupt */ |
+ unsigned long hostPort; /* valid port # on client */ |
+ unsigned long progNum; /* DEVICE_INTR */ |
+ unsigned long progVers; /* DEVICE_INTR_VERSION */ |
+ Device_AddrFamily progFamily; /* DEVICE_UDP | DEVICE_TCP */ |
+}; |
+struct Device_EnableSrqParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ bool enable; /* enable or disable intr's */ |
+ opaque handle<40>; /* host specific data */ |
+}; |
+struct Device_LockParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* contains the waitlock flag */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+}; |
+struct Device_DocmdParms |
+{ |
+ Device_Link lid; /* link id from create_link */ |
+ Device_Flags flags; /* flags with options */ |
+ unsigned long io_timeout; /* time to wait for I/O */ |
+ unsigned long lock_timeout; /* time to wait for lock */ |
+ long cmd; /* which command to execute */ |
+ bool network_order; /* client's byte order */ |
+ long datasize; /* size of individual data elements */ |
+ opaque data_in<>; /* docmd data parameters */ |
+}; |
+struct Device_DocmdResp |
+{ |
+ Device_ErrorCode error; |
+ opaque data_out<>; /* returned data parameters */ |
+}; |
+ |
+program DEVICE_ASYNC |
+{ |
+ version DEVICE_ASYNC_VERSION |
+ { |
+ Device_Error device_abort (Device_Link) = 1; |
+ } = 1; |
+} = 0x0607B0; |
+ |
+program DEVICE_CORE |
+{ |
+ version DEVICE_CORE_VERSION |
+ { |
+ Create_LinkResp create_link (Create_LinkParms) = 10; |
+ Device_WriteResp device_write (Device_WriteParms) = 11; |
+ Device_ReadResp device_read (Device_ReadParms) = 12; |
+ Device_ReadStbResp device_readstb (Device_GenericParms) = 13; |
+ Device_Error device_trigger (Device_GenericParms) = 14; |
+ Device_Error device_clear (Device_GenericParms) = 15; |
+ Device_Error device_remote (Device_GenericParms) = 16; |
+ Device_Error device_local (Device_GenericParms) = 17; |
+ Device_Error device_lock (Device_LockParms) = 18; |
+ Device_Error device_unlock (Device_Link) = 19; |
+ Device_Error device_enable_srq (Device_EnableSrqParms) = 20; |
+ Device_DocmdResp device_docmd (Device_DocmdParms) = 22; |
+ Device_Error destroy_link (Device_Link) = 23; |
+ Device_Error create_intr_chan (Device_RemoteFunc) = 25; |
+ Device_Error destroy_intr_chan (void) = 26; |
+ } = 1; |
+} = 0x0607AF; |
+ |
+/****************************************************************************** |
+ * |
+ * vxi11intr.rpcl |
+ * |
+ * This file is best viewed with a tabwidth of 4 |
+ * |
+ ****************************************************************************** |
+ * |
+ * TODO: |
+ * |
+ ****************************************************************************** |
+ * |
+ * Original Author: someone from VXIbus Consortium |
+ * Current Author: Benjamin Franksen |
+ * Date: 03-06-97 |
+ * |
+ * RPCL description of the intr-channel of the TCP/IP Instrument Protocol |
+ * Specification. |
+ * |
+ * |
+ * Modification Log: |
+ * ----------------- |
+ * .00 03-06-97 bfr created this file |
+ * |
+ ****************************************************************************** |
+ * |
+ * Notes: |
+ * |
+ * This stuff is literally from |
+ * |
+ * "VXI-11, Ref 1.0 : TCP/IP Instrument Protocol Specification" |
+ * |
+ */ |
+ |
+struct Device_SrqParms |
+{ |
+ opaque handle<>; |
+}; |
+ |
+program DEVICE_INTR |
+{ |
+ version DEVICE_INTR_VERSION |
+ { |
+ void device_intr_srq (Device_SrqParms) = 30; |
+ } = 1; |
+} = 0x0607B1; |
Index: sipmscan/trunk/vxi11_x86_64/vxi11_cmd.cc |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/vxi11_cmd.cc (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/vxi11_cmd.cc (revision 118) |
@@ -0,0 +1,83 @@ |
+/* vxi11_cmd.c |
+ * Copyright (C) 2006 Steve D. Sharples |
+ * |
+ * A simple interactive utility that allows you to send commands and queries to |
+ * a device enabled with the VXI11 RPC ethernet protocol. Uses the files |
+ * generated by rpcgen vxi11.x, and the vxi11_user.h user libraries. |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2 |
+ * of the License, or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * The author's email address is steve.sharples@nottingham.ac.uk |
+ */ |
+ |
+#include "vxi11_user.h" |
+#define BUF_LEN 100000 |
+ |
+int main(int argc, char *argv[]) { |
+ |
+static char *device_ip; |
+static char *device_name; |
+char cmd[256]; |
+char buf[BUF_LEN]; |
+int ret; |
+long bytes_returned; |
+CLINK *clink; |
+ |
+ clink = new CLINK; |
+ |
+ if (argc < 2) { |
+ printf("usage: %s your.inst.ip.addr [device_name]\n",argv[0]); |
+ exit(1); |
+ } |
+ |
+ device_ip = argv[1]; |
+ if (argc > 2) { |
+ device_name = argv[2]; |
+ ret=vxi11_open_device(device_ip,clink,device_name); |
+ } |
+ else { |
+ ret=vxi11_open_device(device_ip,clink); |
+ } |
+ |
+ if (ret != 0) { |
+ printf("Error: could not open device %s, quitting\n",device_ip); |
+ exit(2); |
+ } |
+ |
+ while(1){ |
+ memset(cmd, 0, 256); // initialize command string |
+ memset(buf, 0, BUF_LEN); // initialize buffer |
+ printf("Input command or query ('q' to exit): "); |
+ fgets(cmd,256,stdin); |
+ cmd[strlen(cmd)-1] = 0; // just gets rid of the \n |
+ if (strncasecmp(cmd, "q",1) == 0) break; |
+ |
+ if (vxi11_send(clink, cmd) < 0) break; |
+ if (strstr(cmd, "?") != 0) { |
+ bytes_returned = vxi11_receive(clink, buf, BUF_LEN); |
+ if (bytes_returned > 0) { |
+ printf("%s\n",buf); |
+ } |
+ else if (bytes_returned == -15) { |
+ printf("*** [ NOTHING RECEIVED ] ***\n"); |
+ } |
+ else break; |
+ } |
+ } |
+ |
+ ret=vxi11_close_device(device_ip,clink); |
+ return 0; |
+ } |
+ |
Index: sipmscan/trunk/vxi11_x86_64/vxi11_user.cc |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/vxi11_user.cc (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/vxi11_user.cc (revision 118) |
@@ -0,0 +1,589 @@ |
+/* vxi11_user.cc |
+ * Copyright (C) 2006 Steve D. Sharples |
+ * |
+ * User library for opening, closing, sending to and receiving from |
+ * a device enabled with the VXI11 RPC ethernet protocol. Uses the files |
+ * generated by rpcgen vxi11.x. |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2 |
+ * of the License, or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * The author's email address is steve.sharples@nottingham.ac.uk |
+ */ |
+ |
+#include "vxi11_user.h" |
+ |
+/***************************************************************************** |
+ * GENERAL NOTES |
+ ***************************************************************************** |
+ * |
+ * There are four functions at the heart of this library: |
+ * |
+ * int vxi11_open_device(char *ip, CLIENT **client, VXI11_LINK **link) |
+ * int vxi11_close_device(char *ip, CLIENT *client, VXI11_LINK *link) |
+ * int vxi11_send(CLIENT *client, VXI11_LINK *link, char *cmd, unsigned long len) |
+ * long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) |
+ * |
+ * Note that all 4 of these use separate client and link structures. All the |
+ * other functions are built on these four core functions, and the first layer |
+ * of abstraction is to combine the CLIENT and VXI11_LINK structures into a |
+ * single entity, which I've called a CLINK. For the send and receive |
+ * functions, this is just a simple wrapper. For the open and close functions |
+ * it's a bit more complicated, because we somehow have to keep track of |
+ * whether we've already opened a device with the same IP address before (in |
+ * which case we need to recycle a previously created client), or whether |
+ * we've still got any other links to a given IP address left when we are |
+ * asked to close a clink (in which case we can sever the link, but have to |
+ * keep the client open). This is so the person using this library from |
+ * userland does not have to keep track of whether they are talking to a |
+ * different physical instrument or not each time they establish a connection. |
+ * |
+ * So the base functions that the user will probably want to use are: |
+ * |
+ * int vxi11_open_device(char *ip, CLINK *clink) |
+ * int vxi11_close_device(char *ip, CLINK *clink) |
+ * int vxi11_send(CLINK *clink, char *cmd, unsigned long len) |
+ * --- or --- (if sending just text) |
+ * int vxi11_send(CLINK *clink, char *cmd) |
+ * long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) |
+ * |
+ * There are then useful (to me, anyway) more specific functions built on top |
+ * of these: |
+ * |
+ * int vxi11_send_data_block(CLINK *clink, char *cmd, char *buffer, unsigned long len) |
+ * long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) |
+ * long vxi11_send_and_receive(CLINK *clink, char *cmd, char *buf, unsigned long buf_len, unsigned long timeout) |
+ * long vxi11_obtain_long_value(CLINK *clink, char *cmd, unsigned long timeout) |
+ * double vxi11_obtain_double_value(CLINK *clink, char *cmd, unsigned long timeout) |
+ * |
+ * (then there are some shorthand wrappers for the above without specifying |
+ * the timeout due to sheer laziness---explore yourself) |
+ */ |
+ |
+ |
+/* Global variables. Keep track of multiple links per client. We need this |
+ * because: |
+ * - we'd like the library to be able to cope with multiple links to a given |
+ * client AND multiple links to multiple clients |
+ * - we'd like to just refer to a client/link ("clink") as a single |
+ * entity from user land, we don't want to worry about different |
+ * initialisation procedures, depending on whether it's an instrument |
+ * with the same IP address or not |
+ */ |
+char VXI11_IP_ADDRESS[VXI11_MAX_CLIENTS][20]; |
+CLIENT *VXI11_CLIENT_ADDRESS[VXI11_MAX_CLIENTS]; |
+int VXI11_DEVICE_NO = 0; |
+int VXI11_LINK_COUNT[VXI11_MAX_CLIENTS]; |
+ |
+/***************************************************************************** |
+ * KEY USER FUNCTIONS - USE THESE FROM YOUR PROGRAMS OR INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* OPEN FUNCTIONS * |
+ * ============== */ |
+ |
+/* Use this function from user land to open a device and create a link. Can be |
+ * used multiple times for the same device (the library will keep track).*/ |
+int vxi11_open_device(const char *ip, CLINK *clink, char *device) { |
+int ret; |
+int l; |
+int device_no=-1; |
+ |
+// printf("before doing anything, clink->link = %ld\n", clink->link); |
+ /* Have a look to see if we've already initialised an instrument with |
+ * this IP address */ |
+ for (l=0; l<VXI11_MAX_CLIENTS; l++){ |
+ if (strcmp(ip,VXI11_IP_ADDRESS[l]) == 0 ) { |
+ device_no=l; |
+// printf("Open function, search, found ip address %s, device no %d\n",ip,device_no); |
+ } |
+ } |
+ |
+ /* Couldn't find a match, must be a new IP address */ |
+ if (device_no < 0) { |
+ /* Uh-oh, we're out of storage space. Increase the #define |
+ * for VXI11_MAX_CLIENTS in vxi11_user.h */ |
+ if (VXI11_DEVICE_NO >= VXI11_MAX_CLIENTS) { |
+ printf("Error: maximum of %d clients allowed\n",VXI11_MAX_CLIENTS); |
+ ret = -VXI11_MAX_CLIENTS; |
+ } |
+ /* Create a new client, keep a note of where the client pointer |
+ * is, for this IP address. Because it's a new client, this |
+ * must be link number 1. Keep track of how many devices we've |
+ * opened so we don't run out of storage space. */ |
+ else { |
+ ret = vxi11_open_device(ip, &(clink->client), &(clink->link), device); |
+ strncpy(VXI11_IP_ADDRESS[VXI11_DEVICE_NO],ip,20); |
+ VXI11_CLIENT_ADDRESS[VXI11_DEVICE_NO] = clink->client; |
+ VXI11_LINK_COUNT[VXI11_DEVICE_NO]=1; |
+// printf("Open function, could not find ip address %s.\n",ip); |
+// printf("So now, VXI11_IP_ADDRESS[%d]=%s,\n",VXI11_DEVICE_NO,VXI11_IP_ADDRESS[VXI11_DEVICE_NO]); |
+// printf("VXI11_CLIENT_ADDRESS[%d]=%ld,\n",VXI11_DEVICE_NO,VXI11_CLIENT_ADDRESS[VXI11_DEVICE_NO]); |
+// printf(" clink->client=%ld,\n",clink->client); |
+// printf("VXI11_LINK_COUNT[%d]=%d.\n",VXI11_DEVICE_NO,VXI11_LINK_COUNT[VXI11_DEVICE_NO]); |
+ VXI11_DEVICE_NO++; |
+ } |
+ } |
+ /* already got a client for this IP address */ |
+ else { |
+ /* Copy the client pointer address. Just establish a new link |
+ * (not a new client). Add one to the link count */ |
+ clink->client = VXI11_CLIENT_ADDRESS[device_no]; |
+ ret = vxi11_open_link(ip, &(clink->client), &(clink->link), device); |
+// printf("Found an ip address, copying client from VXI11_CLIENT_ADDRESS[%d]\n",device_no); |
+ VXI11_LINK_COUNT[device_no]++; |
+// printf("Have just incremented VXI11_LINK_COUNT[%d], it's now %d\n",device_no,VXI11_LINK_COUNT[device_no]); |
+ } |
+// printf("after creating link, clink->link = %ld\n", clink->link); |
+ return ret; |
+ } |
+ |
+/* This is a wrapper function, used for the situations where there is only one |
+ * "device" per client. This is the case for most (if not all) VXI11 |
+ * instruments; however, it is _not_ the case for devices such as LAN to GPIB |
+ * gateways. These are single clients that communicate to many instruments |
+ * (devices). In order to differentiate between them, we need to pass a device |
+ * name. This gets used in the vxi11_open_link() fn, as the link_parms.device |
+ * value. */ |
+int vxi11_open_device(const char *ip, CLINK *clink) { |
+ char device[6]; |
+ strncpy(device,"inst0",6); |
+ return vxi11_open_device(ip, clink, device); |
+ } |
+ |
+ |
+ |
+/* CLOSE FUNCTION * |
+ * ============== */ |
+ |
+/* Use this function from user land to close a device and/or sever a link. Can |
+ * be used multiple times for the same device (the library will keep track).*/ |
+int vxi11_close_device(const char *ip, CLINK *clink) { |
+int l,ret; |
+int device_no = -1; |
+ |
+ /* Which instrument are we referring to? */ |
+ for (l=0; l<VXI11_MAX_CLIENTS; l++){ |
+ if (strcmp(ip,VXI11_IP_ADDRESS[l]) == 0 ) { |
+ device_no=l; |
+ } |
+ } |
+ /* Something's up if we can't find the IP address! */ |
+ if (device_no == -1) { |
+ printf("vxi11_close_device: error: I have no record of you ever opening device\n"); |
+ printf(" with IP address %s\n",ip); |
+ ret = -4; |
+ } |
+ else { /* Found the IP, there's more than one link to that instrument, |
+ * so keep track and just close the link */ |
+ if (VXI11_LINK_COUNT[device_no] > 1 ) { |
+ ret = vxi11_close_link(ip,clink->client, clink->link); |
+ VXI11_LINK_COUNT[device_no]--; |
+ } |
+ /* Found the IP, it's the last link, so close the device (link |
+ * AND client) */ |
+ else { |
+ ret = vxi11_close_device(ip, clink->client, clink->link); |
+ /* Remove the IP address, so that if we re-open the same device |
+ * we do it properly */ |
+ memset(VXI11_IP_ADDRESS[device_no], 0, 20); |
+ } |
+ } |
+ return ret; |
+ } |
+ |
+ |
+/* SEND FUNCTIONS * |
+ * ============== */ |
+ |
+/* A _lot_ of the time we are sending text strings, and can safely rely on |
+ * strlen(cmd). */ |
+int vxi11_send(CLINK *clink, const char *cmd) { |
+ return vxi11_send(clink, cmd, strlen(cmd)); |
+ } |
+ |
+/* We still need the version of the function where the length is set explicitly |
+ * though, for when we are sending fixed length data blocks. */ |
+int vxi11_send(CLINK *clink, const char *cmd, unsigned long len) { |
+ return vxi11_send(clink->client, clink->link, cmd, len); |
+ } |
+ |
+ |
+/* RECEIVE FUNCTIONS * |
+ * ================= */ |
+ |
+/* Lazy wrapper for when I can't be bothered to specify a read timeout */ |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len) { |
+ return vxi11_receive(clink, buffer, len, VXI11_READ_TIMEOUT); |
+ } |
+ |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) { |
+ return vxi11_receive(clink->client, clink->link, buffer, len, timeout); |
+ } |
+ |
+ |
+ |
+/***************************************************************************** |
+ * USEFUL ADDITIONAL HIGHER LEVER USER FUNCTIONS - USE THESE FROM YOUR * |
+ * PROGRAMS OR INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* SEND FIXED LENGTH DATA BLOCK FUNCTION * |
+ * ===================================== */ |
+int vxi11_send_data_block(CLINK *clink, const char *cmd, char *buffer, unsigned long len) { |
+char *out_buffer; |
+int cmd_len=strlen(cmd); |
+int ret; |
+ |
+ out_buffer=new char[cmd_len+10+len]; |
+ sprintf(out_buffer,"%s#8%08lu",cmd,len); |
+ memcpy(out_buffer+cmd_len+10,buffer,(unsigned long) len); |
+ ret = vxi11_send(clink, out_buffer, (unsigned long) (cmd_len+10+len)); |
+ delete[] out_buffer; |
+ return ret; |
+ } |
+ |
+ |
+/* RECEIVE FIXED LENGTH DATA BLOCK FUNCTION * |
+ * ======================================== */ |
+ |
+/* This function reads a response in the form of a definite-length block, such |
+ * as when you ask for waveform data. The data is returned in the following |
+ * format: |
+ * #800001000<1000 bytes of data> |
+ * ||\______/ |
+ * || | |
+ * || \---- number of bytes of data |
+ * |\--------- number of digits that follow (in this case 8, with leading 0's) |
+ * \---------- always starts with # |
+ */ |
+long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout) { |
+/* I'm not sure what the maximum length of this header is, I'll assume it's |
+ * 11 (#9 + 9 digits) */ |
+unsigned long necessary_buffer_size; |
+char *in_buffer; |
+int ret; |
+int ndigits; |
+unsigned long returned_bytes; |
+int l; |
+char scan_cmd[20]; |
+ necessary_buffer_size=len+12; |
+ in_buffer=new char[necessary_buffer_size]; |
+ ret=vxi11_receive(clink, in_buffer, necessary_buffer_size, timeout); |
+ if (ret < 0) return ret; |
+ if (in_buffer[0] != '#') { |
+ printf("vxi11_user: data block error: data block does not begin with '#'\n"); |
+ printf("First 20 characters received were: '"); |
+ for(l=0;l<20;l++) { |
+ printf("%c",in_buffer[l]); |
+ } |
+ printf("'\n"); |
+ return -3; |
+ } |
+ |
+ /* first find out how many digits */ |
+ sscanf(in_buffer,"#%1d",&ndigits); |
+ /* some instruments, if there is a problem acquiring the data, return only "#0" */ |
+ if (ndigits > 0) { |
+ /* now that we know, we can convert the next <ndigits> bytes into an unsigned long */ |
+ sprintf(scan_cmd,"#%%1d%%%dlu",ndigits); |
+ sscanf(in_buffer,scan_cmd,&ndigits,&returned_bytes); |
+ memcpy(buffer, in_buffer+(ndigits+2), returned_bytes); |
+ delete[] in_buffer; |
+ return (long) returned_bytes; |
+ } |
+ else return 0; |
+ } |
+ |
+ |
+/* SEND AND RECEIVE FUNCTION * |
+ * ========================= */ |
+ |
+/* This is mainly a useful function for the overloaded vxi11_obtain_value() |
+ * fn's, but is also handy and useful for user and library use */ |
+long vxi11_send_and_receive(CLINK *clink, const char *cmd, char *buf, unsigned long buf_len, unsigned long timeout) { |
+int ret; |
+long bytes_returned; |
+ do { |
+ ret = vxi11_send(clink, cmd); |
+ if (ret != 0) { |
+ if (ret != -VXI11_NULL_WRITE_RESP) { |
+ printf("Error: vxi11_send_and_receive: could not send cmd.\n"); |
+ printf(" The function vxi11_send returned %d. ",ret); |
+ return -1; |
+ } |
+ else printf("(Info: VXI11_NULL_WRITE_RESP in vxi11_send_and_receive, resending query)\n"); |
+ } |
+ |
+ bytes_returned = vxi11_receive(clink, buf, buf_len, timeout); |
+ if (bytes_returned <= 0) { |
+ if (bytes_returned >-VXI11_NULL_READ_RESP) { |
+ printf("Error: vxi11_send_and_receive: problem reading reply.\n"); |
+ printf(" The function vxi11_receive returned %ld. ",bytes_returned); |
+ return -2; |
+ } |
+ else printf("(Info: VXI11_NULL_READ_RESP in vxi11_send_and_receive, resending query)\n"); |
+ } |
+ } while (bytes_returned == -VXI11_NULL_READ_RESP || ret == -VXI11_NULL_WRITE_RESP); |
+ return 0; |
+ } |
+ |
+ |
+/* FUNCTIONS TO RETURN A LONG INTEGER VALUE SENT AS RESPONSE TO A QUERY * |
+ * ==================================================================== */ |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd, unsigned long timeout) { |
+char buf[50]; /* 50=arbitrary length... more than enough for one number in ascii */ |
+ memset(buf, 0, 50); |
+ if (vxi11_send_and_receive(clink, cmd, buf, 50, timeout) != 0) { |
+ printf("Returning 0\n"); |
+ return 0; |
+ } |
+ return strtol(buf, (char **)NULL, 10); |
+ } |
+ |
+/* Lazy wrapper function with default read timeout */ |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd) { |
+ return vxi11_obtain_long_value(clink, cmd, VXI11_READ_TIMEOUT); |
+ } |
+ |
+ |
+/* FUNCTIONS TO RETURN A DOUBLE FLOAT VALUE SENT AS RESPONSE TO A QUERY * |
+ * ==================================================================== */ |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd, unsigned long timeout) { |
+char buf[50]; /* 50=arbitrary length... more than enough for one number in ascii */ |
+double val; |
+ memset(buf, 0, 50); |
+ if (vxi11_send_and_receive(clink, cmd, buf, 50, timeout) != 0) { |
+ printf("Returning 0.0\n"); |
+ return 0.0; |
+ } |
+ val = strtod(buf, (char **)NULL); |
+ return val; |
+ } |
+ |
+/* Lazy wrapper function with default read timeout */ |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd) { |
+ return vxi11_obtain_double_value(clink, cmd, VXI11_READ_TIMEOUT); |
+ } |
+ |
+ |
+/***************************************************************************** |
+ * CORE FUNCTIONS - YOU SHOULDN'T NEED TO USE THESE FROM YOUR PROGRAMS OR * |
+ * INSTRUMENT LIBRARIES * |
+ *****************************************************************************/ |
+ |
+/* OPEN FUNCTIONS * |
+ * ============== */ |
+int vxi11_open_device(const char *ip, CLIENT **client, VXI11_LINK **link, char *device) { |
+ |
+ *client = clnt_create(ip, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp"); |
+ |
+ if (*client == NULL) { |
+ clnt_pcreateerror(ip); |
+ return -1; |
+ } |
+ |
+ return vxi11_open_link(ip, client, link, device); |
+ } |
+ |
+int vxi11_open_link(const char *ip, CLIENT **client, VXI11_LINK **link, char *device) { |
+ |
+Create_LinkParms link_parms; |
+ |
+ /* Set link parameters */ |
+ link_parms.clientId = (long) *client; |
+ link_parms.lockDevice = 0; |
+ link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; |
+ link_parms.device = device; |
+ |
+ *link = (Create_LinkResp *) calloc(1, sizeof(Create_LinkResp)); |
+ |
+ if (create_link_1(&link_parms, *link, *client) != RPC_SUCCESS) { |
+ clnt_perror(*client, ip); |
+ return -2; |
+ } |
+ return 0; |
+ } |
+ |
+ |
+/* CLOSE FUNCTIONS * |
+ * =============== */ |
+int vxi11_close_device(const char *ip, CLIENT *client, VXI11_LINK *link) { |
+int ret; |
+ |
+ ret = vxi11_close_link(ip, client, link); |
+ |
+ clnt_destroy(client); |
+ |
+ return ret; |
+ } |
+ |
+int vxi11_close_link(const char *ip, CLIENT *client, VXI11_LINK *link) { |
+Device_Error dev_error; |
+ memset(&dev_error, 0, sizeof(dev_error)); |
+ |
+ if (destroy_link_1(&link->lid, &dev_error, client) != RPC_SUCCESS) { |
+ clnt_perror(client,ip); |
+ return -1; |
+ } |
+ |
+ return 0; |
+ } |
+ |
+ |
+/* SEND FUNCTIONS * |
+ * ============== */ |
+ |
+/* A _lot_ of the time we are sending text strings, and can safely rely on |
+ * strlen(cmd). */ |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd) { |
+ return vxi11_send(client, link, cmd, strlen(cmd)); |
+ } |
+ |
+/* We still need the version of the function where the length is set explicitly |
+ * though, for when we are sending fixed length data blocks. */ |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len) { |
+Device_WriteParms write_parms; |
+unsigned int bytes_left = len; |
+char *send_cmd; |
+ |
+ send_cmd = new char[len]; |
+ memcpy(send_cmd, cmd, len); |
+ |
+ write_parms.lid = link->lid; |
+ write_parms.io_timeout = VXI11_DEFAULT_TIMEOUT; |
+ write_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; |
+ |
+/* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop, |
+ * writing a chunk at a time, until we're done. */ |
+ |
+ do { |
+ Device_WriteResp write_resp; |
+ memset(&write_resp, 0, sizeof(write_resp)); |
+ |
+ if (bytes_left <= link->maxRecvSize) { |
+ write_parms.flags = 8; |
+ write_parms.data.data_len = bytes_left; |
+ } |
+ else { |
+ write_parms.flags = 0; |
+ /* We need to check that maxRecvSize is a sane value (ie >0). Believe it |
+ * or not, on some versions of Agilent Infiniium scope firmware the scope |
+ * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless |
+ * we need to catch this, otherwise the program just hangs. */ |
+ if (link->maxRecvSize > 0) { |
+ write_parms.data.data_len = link->maxRecvSize; |
+ } |
+ else { |
+ write_parms.data.data_len = 4096; /* pretty much anything should be able to cope with 4kB */ |
+ } |
+ } |
+ write_parms.data.data_val = send_cmd + (len - bytes_left); |
+ |
+ if(device_write_1(&write_parms, &write_resp, client) != RPC_SUCCESS) { |
+ delete[] send_cmd; |
+ return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely |
+ dropped it. There was no vxi11 comms error as such, the |
+ instrument is just being rude. Usually occurs when the instrument |
+ is busy. If we don't check this first, then the following |
+ line causes a seg fault */ |
+ } |
+ if (write_resp.error != 0) { |
+ printf("vxi11_user: write error: %d\n", (int)write_resp.error); |
+ delete[] send_cmd; |
+ return -(write_resp.error); |
+ } |
+ bytes_left -= write_resp.size; |
+ } while (bytes_left > 0); |
+ |
+ delete[] send_cmd; |
+ return 0; |
+ } |
+ |
+ |
+/* RECEIVE FUNCTIONS * |
+ * ================= */ |
+ |
+// It appeared that this function wasn't correctly dealing with more data available than specified in len. |
+// This patch attempts to fix this issue. RDP 2007/8/13 |
+ |
+/* wrapper, for default timeout */ long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len) { return vxi11_receive(client, link, buffer, len, VXI11_READ_TIMEOUT); |
+ } |
+ |
+#define RCV_END_BIT 0x04 // An end indicator has been read |
+#define RCV_CHR_BIT 0x02 // A termchr is set in flags and a character which matches termChar is transferred |
+#define RCV_REQCNT_BIT 0x01 // requestSize bytes have been transferred. This includes a request size of zero. |
+ |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) { |
+Device_ReadParms read_parms; |
+Device_ReadResp read_resp; |
+unsigned long curr_pos = 0; |
+ |
+ read_parms.lid = link->lid; |
+ read_parms.requestSize = len; |
+ read_parms.io_timeout = timeout; /* in ms */ |
+ read_parms.lock_timeout = timeout; /* in ms */ |
+ read_parms.flags = 0; |
+ read_parms.termChar = 0; |
+ |
+ do { |
+ memset(&read_resp, 0, sizeof(read_resp)); |
+ |
+ read_resp.data.data_val = buffer + curr_pos; |
+ read_parms.requestSize = len - curr_pos; // Never request more total data than originally specified in len |
+ |
+ if(device_read_1(&read_parms, &read_resp, client) != RPC_SUCCESS) { |
+ return -VXI11_NULL_READ_RESP; /* there is nothing to read. Usually occurs after sending a query |
+ which times out on the instrument. If we don't check this first, |
+ then the following line causes a seg fault */ |
+ } |
+ if (read_resp.error != 0) { |
+ /* Read failed for reason specified in error code. |
+ * (From published VXI-11 protocol, section B.5.2) |
+ * 0 no error |
+ * 1 syntax error |
+ * 3 device not accessible |
+ * 4 invalid link identifier |
+ * 5 parameter error |
+ * 6 channel not established |
+ * 8 operation not supported |
+ * 9 out of resources |
+ * 11 device locked by another link |
+ * 12 no lock held by this link |
+ * 15 I/O timeout |
+ * 17 I/O error |
+ * 21 invalid address |
+ * 23 abort |
+ * 29 channel already established |
+ */ |
+ |
+ printf("vxi11_user: read error: %d\n", (int)read_resp.error); |
+ return -(read_resp.error); |
+ } |
+ |
+ if((curr_pos + read_resp.data.data_len) <= len) { |
+ curr_pos += read_resp.data.data_len; |
+ } |
+ if( (read_resp.reason & RCV_END_BIT) || (read_resp.reason & RCV_CHR_BIT) ) { |
+ break; |
+ } |
+ else if( curr_pos == len ) { |
+ printf("xvi11_user: read error: buffer too small. Read %d bytes without hitting terminator.\n", (int)curr_pos ); |
+ return -100; |
+ } |
+ } while(1); |
+ return (curr_pos); /*actual number of bytes received*/ |
+ |
+ } |
+ |
Index: sipmscan/trunk/vxi11_x86_64/vxi11_user.h |
=================================================================== |
--- sipmscan/trunk/vxi11_x86_64/vxi11_user.h (nonexistent) |
+++ sipmscan/trunk/vxi11_x86_64/vxi11_user.h (revision 118) |
@@ -0,0 +1,87 @@ |
+/* vxi11_user.h |
+ * Copyright (C) 2006 Steve D. Sharples |
+ * |
+ * User library for opening, closing, sending to and receiving from |
+ * a device enabled with the VXI11 RPC ethernet protocol. Uses the files |
+ * generated by rpcgen vxi11.x. |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2 |
+ * of the License, or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * The author's email address is steve.sharples@nottingham.ac.uk |
+ */ |
+ |
+#ifndef __VXI11_USER__ |
+#define __VXI11_USER__ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+#include <rpc/rpc.h> |
+#include "vxi11.h" |
+ |
+#define VXI11_DEFAULT_TIMEOUT 10000 /* in ms */ |
+#define VXI11_READ_TIMEOUT 2000 /* in ms */ |
+#define VXI11_CLIENT CLIENT |
+#define VXI11_LINK Create_LinkResp |
+#define VXI11_MAX_CLIENTS 256 /* maximum no of unique IP addresses/clients */ |
+#define VXI11_NULL_READ_RESP 50 /* vxi11_receive() return value if a query |
+ * times out ON THE INSTRUMENT (and so we have |
+ * to resend the query again) */ |
+#define VXI11_NULL_WRITE_RESP 51 /* vxi11_send() return value if a sent command |
+ * times out ON THE INSTURMENT. */ |
+ |
+struct CLINK { |
+ VXI11_CLIENT *client; |
+ VXI11_LINK *link; |
+ } ; |
+typedef struct CLINK CLINK; |
+ |
+/* The four main functions: open, close, send, receieve (plus a couple of wrappers) */ |
+/* In fact all 6 of these are wrappers to the original functions listed at the |
+ * bottom, that use separate CLIENT and VXI11_LINK structures. It was easier to |
+ * write wrappers for these functions than to re-write the original functions |
+ * themselves. These are the 4 (or 6 if you like) key user functions that you |
+ * should probably be using. They all use the CLINK structure. */ |
+int vxi11_open_device(const char *ip, CLINK *clink); |
+int vxi11_open_device(const char *ip, CLINK *clink, char *device); |
+int vxi11_close_device(const char *ip, CLINK *clink); |
+int vxi11_send(CLINK *clink, const char *cmd); |
+int vxi11_send(CLINK *clink, const char *cmd, unsigned long len); |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len); |
+long vxi11_receive(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout); |
+ |
+/* Utility functions, that use send() and receive(). Use these too. */ |
+int vxi11_send_data_block(CLINK *clink, const char *cmd, char *buffer, unsigned long len); |
+long vxi11_receive_data_block(CLINK *clink, char *buffer, unsigned long len, unsigned long timeout); |
+long vxi11_send_and_receive(CLINK *clink, const char *cmd, char *buf, unsigned long buf_len, unsigned long timeout); |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd, unsigned long timeout); |
+double vxi11_obtain_double_value(CLINK *clink, const char *cmd, unsigned long timeout); |
+long vxi11_obtain_long_value(CLINK *clink, const char *cmd); |
+double vxi11_obtain_double_value(CLINK *link, const char *cmd); |
+ |
+/* When I first wrote this library I used separate client and links. I've |
+ * retained the original functions and just written clink wrappers for them |
+ * (see above) as it's perhaps a little clearer this way. Probably not worth |
+ * delving this deep in use, but it's where the real nitty gritty is. */ |
+int vxi11_open_device(const char *ip, CLIENT **client, VXI11_LINK **link, char *device); |
+int vxi11_open_link(const char *ip, CLIENT **client, VXI11_LINK **link, char *device); |
+int vxi11_close_device(const char *ip, CLIENT *client, VXI11_LINK *link); |
+int vxi11_close_link(const char *ip, CLIENT *client, VXI11_LINK *link); |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd); |
+int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len); |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len); |
+long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout); |
+ |
+#endif |
Index: sipmscan/trunk/windowed_test.C |
=================================================================== |
--- sipmscan/trunk/windowed_test.C (nonexistent) |
+++ sipmscan/trunk/windowed_test.C (revision 118) |
@@ -0,0 +1,3483 @@ |
+#include "workstation.h" |
+#include "daq.h" |
+#include "root_include.h" |
+#include "windowed_test.h" |
+ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <time.h> |
+#include <unistd.h> |
+ |
+#include "daqscope.h" |
+ |
+//--------------------------------------------------------------- |
+// Subwindow layout class |
+ |
+class TGMdiSubwindow |
+{ |
+RQ_OBJECT("TGMdiSubwindow") |
+ |
+protected: |
+ TGMdiFrame *fMdiFrame; |
+ |
+public: |
+ TGMdiSubwindow(TGMdiMainFrame *main, int w, int h); |
+ |
+ TGMdiFrame *GetMdiFrame() const { return fMdiFrame; } |
+ virtual Bool_t CloseWindow(); |
+}; |
+ |
+//--------------------------------------------------------------- |
+// Main window class |
+ |
+class TGAppMainFrame |
+{ |
+RQ_OBJECT("TGAppMainFrame") |
+ |
+protected: |
+ TGMainFrame *fMain; |
+ TGMdiMainFrame *fMainFrame; |
+ TGMdiMenuBar *fMenuBar; |
+ TGLayoutHints *fMenuBarItemLayout; |
+ TGPopupMenu *fMenuFile, *fMenuAnalysis, *fMenuWindow, *fMenuHelp; |
+ TGPopupMenu *fMenuHisttype; |
+ TGMdiSubwindow *settingsPane, *mainSubwindow, *histogramPane, *histogramPaneFile, *histogramPaneCtr; |
+ |
+ void InitMenu(); |
+ void MeasurementLayout(); |
+ void CloseWindow(); |
+ Bool_t About(); |
+public: |
+ TGAppMainFrame(const TGWindow *p, int w, int h); |
+ |
+ void HandleMenu(Int_t id); |
+ |
+ void EnableVoltScan(); |
+ void EnableSurfScan(); |
+ void EnableZaxisScan(); |
+ void VoltageLimit(); |
+ void ChannelLimit(); |
+ void CleanPlotToggle(); |
+ void ConnectToScope(); |
+ |
+ void SetVoltOut(); |
+ void GetVoltOut(); |
+ void ResetVoltOut(); |
+ void SetPosition(); |
+ void GetPosition(); |
+ void HomePosition(); |
+ void SaveFile(); |
+ void StartAcq(); |
+ |
+ void SelectDirectory(); |
+ void ListMultiSelect(); |
+ void ListSelectAll(); |
+ void FileListNavigation(int pn); |
+ |
+ void DisplayHistogram(char *histfile, int histtype); |
+ void SetHistRange(); |
+ void ChangeHisttype(int type); |
+ void ChangeChannel(); |
+ void HistogramExport(); |
+ void MakeSurfPlot(TList *files); |
+ void MakeBreakdownPlot(int nrp, double *volt, double *volterr, double *psep1, double *pseperr1, double *psep2, double *pseperr2, double *psep3, double *pseperr3, char *plotfile); |
+ |
+ void FitSpectrum(TList *files, int q); |
+ void EdgeDetection(TGraph *pdf, TGraph *cdf, char *outname, TCanvas *g1dCanvas, double pdfmax, int direction); |
+ void IntegSpectrum(TList *files, int direction); |
+ |
+ void RunMeas(void *ptr, int runCase, int zaxisscan); |
+}; |
+ |
+const char *histExt = ".root"; |
+const char *histExtAll = "*.root"; |
+daq *gDaq; |
+daqscope *gScopeDaq; |
+int debugSig = 0; |
+int retTemp; |
+int gStop=0; |
+unsigned int gBuf[BSIZE]; |
+int logchange = 0; |
+double tdctimeconversion = 45.0909; |
+double lenconversion = 0.3595; |
+int oscOn; |
+ |
+// ROOT file variable structure ----------- |
+struct EventHeader { |
+ int nrch; |
+ int timestamp; |
+ double biasvolt; |
+ int xpos; |
+ int ypos; |
+ int zpos; |
+ double temperature; |
+ char laserinfo[256]; |
+} evtheader; |
+ |
+struct EventData { |
+ int adcdata[8]; |
+ int tdcdata[8]; |
+} evtdata; |
+ |
+TFile *inroot; |
+TFile *outroot; |
+ |
+//--------------------------------------------------------------- |
+// Global variables |
+ |
+TGCheckButton *voltscanOn; |
+TGCheckButton *surfscanOn; |
+TGCheckButton *zscanOn; |
+TGTextEntry *oscIP; |
+TGTextButton *oscConnect; |
+TGCheckButton *histogramOn; |
+TGNumberEntry *vHardlimit; |
+TGNumberEntry *NCH; |
+TGTextEntry *laserInfo; |
+TGCheckButton *cleanOn; |
+ |
+TGTab *setTab; |
+TGComboBox *vOutCh; |
+TGNumberEntry *vOut; |
+TGCheckButton *vOutOnOff; |
+TGTextButton *vOutSet; |
+TGTextButton *vOutGet; |
+TGTextButton *vOutReset; |
+TGNumberEntry *vOutStart; |
+TGNumberEntry *vOutStop; |
+TGNumberEntry *vOutStep; |
+TGNumberEntry *xPos; |
+TGNumberEntry *yPos; |
+TGNumberEntry *zPos; |
+TGTextButton *positionSet; |
+TGTextButton *positionGet; |
+TGTextButton *positionHome; |
+TGNumberEntry *xPosMin; |
+TGNumberEntry *xPosMax; |
+TGNumberEntry *xPosStep; |
+TGNumberEntry *yPosMin; |
+TGNumberEntry *yPosMax; |
+TGNumberEntry *yPosStep; |
+TGNumberEntry *zPosMin; |
+TGNumberEntry *zPosMax; |
+TGNumberEntry *zPosStep; |
+TGNumberEntry *evtNum; |
+TGTextEntry *timeStamp; |
+TGTextEntry *fileName; |
+TGTextButton *saveFile; |
+TGTextButton *measStart; |
+TGLabel *busyLabel; |
+TGHProgressBar *curProgress; |
+ |
+TRootEmbeddedCanvas *histCanvas; |
+ |
+TGTextButton *selectDir; |
+TGListBox *fileList; |
+TGCheckButton *multiSelect; |
+TGCheckButton *multiSelectAll; |
+TGTextButton *prevFile; |
+TGTextButton *nextFile; |
+ |
+TGNumberEntry *adcMinRange; |
+TGNumberEntry *adcMaxRange; |
+TGNumberEntry *tdcMinwindow; |
+TGNumberEntry *tdcMaxwindow; |
+TGNumberEntry *yMinRange; |
+TGNumberEntry *yMaxRange; |
+TGNumberEntry *selectCh; |
+TGTextButton *changeADC; |
+TGTextButton *changeTDC; |
+TGTextButton *changeADCTDC; |
+TGTextButton *change2Dsurf; |
+TGCheckButton *logscale; |
+TGTextButton *exportHist; |
+TGNumberEntry *fitSigma; |
+TGNumberEntry *fitTresh; |
+TGNumberEntry *fitInter; |
+TGNumberEntry *accError; |
+TGCheckButton *exfitplots; |
+ |
+Bool_t firstrun = kTRUE; |
+Bool_t started; |
+Bool_t cleanPlots = kTRUE; |
+ |
+// Layout hints definitions |
+TGLayoutHints *f0 = new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2); |
+TGLayoutHints *f0centerx = new TGLayoutHints(kLHintsCenterX,2,2,2,2); |
+TGLayoutHints *f0centery = new TGLayoutHints(kLHintsLeft | kLHintsCenterY,2,2,2,2); |
+TGLayoutHints *f0center2d = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY,2,2,2,2); |
+TGLayoutHints *f0right = new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2); |
+TGLayoutHints *f1 = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2); |
+TGLayoutHints *f2 = new TGLayoutHints(kLHintsExpandX,2,2,2,2); |
+TGLayoutHints *f3 = new TGLayoutHints(kLHintsCenterY,2,2,20,2); |
+TGLayoutHints *f3notop = new TGLayoutHints(kLHintsCenterY,4,4,2,30); |
+ |
+// Separate functions ----------------------------------------- |
+void GetTime(int intime, char *outtime) |
+{ |
+ time_t rawtime; |
+ struct tm * timeinfo; |
+ if(intime < 0) |
+ time(&rawtime); |
+ else |
+ rawtime = (time_t)intime; |
+ timeinfo = localtime(&rawtime); |
+ sprintf(outtime, "%s", asctime(timeinfo)); |
+ int len = strlen(outtime); |
+ if(len) outtime[len-1] = 0; |
+} |
+ |
+int MyTimer() |
+{ |
+ char cmd[100]; |
+ GetTime(-1, cmd); |
+ if (timeStamp) timeStamp->SetText(cmd); |
+ return 0; |
+} |
+ |
+int GetChannel() |
+{ |
+ int selectedOutput; |
+ if(vOutCh->GetSelected() < 8) selectedOutput = (vOutCh->GetSelected())+1; |
+ else if( (vOutCh->GetSelected() >= 8) && (vOutCh->GetSelected() < 16) ) selectedOutput = (vOutCh->GetSelected())+93; |
+ else selectedOutput = 1; |
+ |
+ return selectedOutput; |
+} |
+ |
+void remove_ext(char *inname, char *outname) |
+{ |
+ char ctemp[256]; |
+ for(int i = 0; i < (int)strlen(inname); i++) |
+ { |
+ if( (inname[i] == '.') && (i > (int)(strlen(inname)-6)) ) |
+ { |
+ ctemp[i] = '\0'; |
+ sprintf(outname, "%s", ctemp); |
+ break; |
+ } |
+ else |
+ ctemp[i] = inname[i]; |
+ } |
+ |
+ if(debugSig) |
+ printf("Outfile (remove_ext): %s\n", outname); |
+} |
+ |
+void remove_from_last(char *inname, char search, char *outname) |
+{ |
+ char ctemp[256]; |
+ int searchpos = -1; |
+ for(int i = (int)strlen(inname); i >= 0; i--) |
+ { |
+ if(inname[i] == search) |
+ { |
+ searchpos = i; |
+ break; |
+ } |
+ } |
+ |
+ for(int i = 0; i < searchpos; i++) |
+ ctemp[i] = inname[i]; |
+ |
+ ctemp[searchpos] = '\0'; |
+ sprintf(outname, "%s", ctemp); |
+ |
+ if(debugSig) |
+ printf("Outfile (remove_from_last): %s\n", outname); |
+} |
+ |
+// Peak detection function |
+int npeaks; |
+double FindPeaks(double *x, double *par) |
+{ |
+ double result = 0; |
+ for(int i = 0; i < npeaks; i++) |
+ { |
+ double norm = par[3*i]; |
+ double mean = par[3*i+1]; |
+ double sigma = par[3*i+2]; |
+ result += norm*TMath::Gaus(x[0], mean, sigma); |
+ } |
+ return result; |
+} |
+ |
+// Class related functions -------------------------------------- |
+ |
+// Apply the upper voltage limit from settings pane to main window |
+void TGAppMainFrame::VoltageLimit() |
+{ |
+ vOut->SetLimitValues(0, vHardlimit->GetNumber() ); |
+} |
+ |
+// Apply the upper channel limit from settings pane to histogram settings |
+void TGAppMainFrame::ChannelLimit() |
+{ |
+ selectCh->SetLimitValues(0, (NCH->GetNumber()-1) ); |
+} |
+ |
+// Enable or disable voltage scan controls |
+void TGAppMainFrame::EnableVoltScan() |
+{ |
+ if(voltscanOn->IsOn()) |
+ { |
+ vOutStart->SetState(kTRUE); |
+ vOutStop->SetState(kTRUE); |
+ vOutStep->SetState(kTRUE); |
+ } |
+ else |
+ { |
+ vOutStart->SetState(kFALSE); |
+ vOutStop->SetState(kFALSE); |
+ vOutStep->SetState(kFALSE); |
+ } |
+} |
+ |
+// Enable or disable surface scan controls |
+void TGAppMainFrame::EnableSurfScan() |
+{ |
+ if(surfscanOn->IsOn()) |
+ { |
+ xPosMin->SetState(kTRUE); |
+ xPosMax->SetState(kTRUE); |
+ xPosStep->SetState(kTRUE); |
+ yPosMin->SetState(kTRUE); |
+ yPosMax->SetState(kTRUE); |
+ yPosStep->SetState(kTRUE); |
+ } |
+ else |
+ { |
+ xPosMin->SetState(kFALSE); |
+ xPosMax->SetState(kFALSE); |
+ xPosStep->SetState(kFALSE); |
+ yPosMin->SetState(kFALSE); |
+ yPosMax->SetState(kFALSE); |
+ yPosStep->SetState(kFALSE); |
+ } |
+} |
+ |
+// Enable or disable Z axis scan controls |
+void TGAppMainFrame::EnableZaxisScan() |
+{ |
+ if(zscanOn->IsOn()) |
+ { |
+ zPosMin->SetState(kTRUE); |
+ zPosMax->SetState(kTRUE); |
+ zPosStep->SetState(kTRUE); |
+ } |
+ else |
+ { |
+ zPosMin->SetState(kFALSE); |
+ zPosMax->SetState(kFALSE); |
+ zPosStep->SetState(kFALSE); |
+ } |
+} |
+ |
+// Toggle clean plots on/off |
+void TGAppMainFrame::CleanPlotToggle() |
+{ |
+ cleanPlots = cleanOn->IsDown(); |
+} |
+ |
+// Connect to oscilloscope |
+void TGAppMainFrame::ConnectToScope() |
+{ |
+ int scopeState = -1; |
+ char *IPaddr = (char*)oscIP->GetText(); |
+ int IPcorr = 0; |
+ char buf[BSIZE]; |
+ |
+ if(oscOn == 0) |
+ { |
+ // Check if the IP address has the required three . |
+ for(int i = 0; i < (int)strlen(IPaddr); i++) |
+ if(IPaddr[i] == '.') |
+ IPcorr++; |
+ |
+ if( (IPaddr != NULL) && (IPcorr == 3) ) |
+ { |
+#if WORKSTAT == 'I' |
+ printf("Connecting to oscilloscope.\n"); |
+ retTemp = gScopeDaq->connect(IPaddr); |
+ scopeState = 1; // For testing instead of making a real connection |
+#else |
+ scopeState = 1; |
+#endif |
+ } |
+ else |
+ { |
+ scopeState = -1; |
+ printf("Please enter a valid scope IP address.\n"); |
+ } |
+ } |
+ else if(oscOn == 1) |
+ { |
+#if WORKSTAT == 'I' |
+ printf("Disconnecting from oscilloscope.\n"); |
+ retTemp = gScopeDaq->disconnect(IPaddr); |
+ scopeState = -1; // For testing instead of making a real disconnection |
+#else |
+ scopeState = -1; |
+#endif |
+ } |
+ |
+ if(scopeState >= 0) |
+ { |
+ setTab->SetEnabled(1, kTRUE); |
+ setTab->SetEnabled(2, kTRUE); |
+ oscIP->SetEnabled(kFALSE); |
+ oscConnect->SetText("Disconnect"); |
+ oscConnect->SetTextJustify(36); |
+ oscConnect->SetWrapLength(-1); |
+ oscConnect->Resize(60,22); |
+ oscOn = 1; |
+ } |
+ else |
+ { |
+ setTab->SetEnabled(1, kFALSE); |
+ setTab->SetEnabled(2, kFALSE); |
+ oscIP->SetEnabled(kTRUE); |
+ oscConnect->SetText("Connect"); |
+ oscConnect->SetTextJustify(36); |
+ oscConnect->SetWrapLength(-1); |
+ oscConnect->Resize(60,22); |
+ oscOn = 0; |
+ } |
+} |
+ |
+// Set the output voltage |
+void TGAppMainFrame::SetVoltOut() |
+{ |
+ char cmd[256]; |
+ int outOn; |
+ float outputVoltage; |
+ |
+ outputVoltage = vOut->GetNumber(); |
+ |
+ if(vOutOnOff->IsOn()) outOn = 1; |
+ else outOn = 0; |
+ |
+ fflush(stdout); |
+ sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -v %f -s %d", rootdir, GetChannel(), outputVoltage, outOn); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+} |
+ |
+// Get the output voltage |
+void TGAppMainFrame::GetVoltOut() |
+{ |
+ char cmd[256]; |
+ |
+ fflush(stdout); |
+ sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -g > %s/curvolt.txt", rootdir, GetChannel(), rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+#if WORKSTAT == 'I' |
+ FILE* fvolt; |
+ double dtemp; |
+ char ctemp[24]; |
+ sprintf(cmd, "%s/curvolt.txt", rootdir); |
+ fvolt = fopen(cmd, "r"); |
+ |
+ if(fvolt != NULL) |
+ { |
+ sprintf(cmd, "WIENER-CRATE-MIB::outputVoltage.u%d = Opaque: Float: %s V\n", GetChannel()-1, "%lf" ); |
+ retTemp = fscanf(fvolt, cmd, &dtemp); |
+ vOut->SetNumber(dtemp); |
+ sprintf(cmd, "WIENER-CRATE-MIB::outputSwitch.u%d = INTEGER: %s\n", GetChannel()-1, "%s" ); |
+ retTemp = fscanf(fvolt, cmd, ctemp); |
+ if( strcmp(ctemp, "On(1)") == 0 ) |
+ vOutOnOff->SetState(kButtonDown); |
+ else if( strcmp(ctemp, "Off(0)") == 0 ) |
+ vOutOnOff->SetState(kButtonUp); |
+ } |
+ |
+ fclose(fvolt); |
+#endif |
+} |
+ |
+// Reset the output voltage |
+void TGAppMainFrame::ResetVoltOut() |
+{ |
+ char cmd[256]; |
+ |
+ vOut->SetNumber(0.000); |
+ vOutOnOff->SetState(kButtonUp); |
+ |
+ fflush(stdout); |
+ sprintf(cmd, "%s/mpod/mpod_voltage.sh -r %d", rootdir, GetChannel()); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+} |
+ |
+// Get the current table position |
+void TGAppMainFrame::GetPosition() |
+{ |
+ char cmd[256]; |
+ |
+ fflush(stdout); |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -p > %s/curpos.txt", rootdir, rootdir); // X-axis |
+ fflush(stdout); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -p >> %s/curpos.txt", rootdir, rootdir); // Y-axis |
+ fflush(stdout); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -p >> %s/curpos.txt", rootdir, rootdir); // Z-axis |
+ fflush(stdout); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+#if WORKSTAT == 'I' |
+ FILE* fpos; |
+ int itemp; |
+ sprintf(cmd, "%s/curpos.txt", rootdir); |
+ fpos = fopen(cmd, "r"); |
+ |
+ if(fpos != NULL) |
+ { |
+ retTemp = fscanf(fpos, "%d\n", &itemp); |
+ xPos->SetNumber(itemp); |
+ retTemp = fscanf(fpos, "%d\n", &itemp); |
+ yPos->SetNumber(itemp); |
+ retTemp = fscanf(fpos, "%d\n", &itemp); |
+ zPos->SetNumber(itemp); |
+ } |
+ |
+ fclose(fpos); |
+#endif |
+} |
+ |
+// Set the current table position |
+void TGAppMainFrame::SetPosition() |
+{ |
+ char cmd[256]; |
+ int positX, positY, positZ; |
+ |
+ positX = xPos->GetNumber(); |
+ positY = yPos->GetNumber(); |
+ positZ = zPos->GetNumber(); |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/MIKRO/mikro_ctrl -n 1 -c m", rootdir, positX, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/MIKRO/mikro_ctrl -n 2 -c m", rootdir, positY, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/MIKRO/mikro_ctrl -n 3 -c m", rootdir, positZ, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+} |
+ |
+// Set the current table position to a predetermined HOME position |
+void TGAppMainFrame::HomePosition() |
+{ |
+ char cmd[256]; |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -h", rootdir); // X-axis |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -h", rootdir); // Y-axis |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -h", rootdir); // Z-axis |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+} |
+ |
+// Make breakdown voltage plot |
+void TGAppMainFrame::MakeBreakdownPlot(int nrp, double *volt, double *volterr, double *psep1, double *pseperr1, double *psep2, double *pseperr2, double *psep3, double *pseperr3, char *plotfile) |
+{ |
+ double fparam[2], fparamerr[2], meanval; |
+ TLatex *latex; |
+ char ctemp[256]; |
+ int sortindex[nrp]; |
+ |
+ TCanvas *canvas = new TCanvas("canv","canv",900,1200); |
+ canvas->Divide(1,3); |
+ |
+ TGraphErrors *gr1 = new TGraphErrors(nrp, volt, psep1, volterr, pseperr1); |
+ TGraphErrors *gr2 = new TGraphErrors(nrp, volt, psep2, volterr, pseperr2); |
+ TGraphErrors *gr3 = new TGraphErrors(nrp, volt, psep3, volterr, pseperr3); |
+ |
+ if(!cleanPlots) |
+ gr1->SetTitle("1st - 2nd peak separation"); |
+ else |
+ gr1->SetTitle(); |
+ gr1->SetLineColor(kBlue); |
+ gr1->SetMarkerColor(kBlue); |
+ gr1->SetMarkerStyle(20); |
+ gr1->SetMarkerSize(0.6); |
+ |
+ |
+ if(!cleanPlots) |
+ gr2->SetTitle("2nd - 3rd peak separation"); |
+ else |
+ gr2->SetTitle(); |
+ gr2->SetLineColor(kMagenta); |
+ gr2->SetMarkerColor(kMagenta); |
+ gr2->SetMarkerStyle(21); |
+ gr2->SetMarkerSize(0.4); |
+ |
+ if(!cleanPlots) |
+ gr3->SetTitle("3rd - 4th peak separation"); |
+ else |
+ gr3->SetTitle(); |
+ gr3->SetLineColor(kGreen); |
+ gr3->SetMarkerColor(kGreen); |
+ gr3->SetMarkerStyle(22); |
+ gr3->SetMarkerSize(0.6); |
+ |
+ // Plotting the first breakdown voltage plot |
+ canvas->cd(1); |
+ gPad->SetGridx(1); |
+ gPad->SetGridy(1); |
+ |
+ gr1->Draw("AP"); |
+ gr1->GetXaxis()->SetTitle("Bias voltage (V)"); |
+ gr1->GetYaxis()->SetTitle("Peak separation"); |
+ gr1->GetYaxis()->CenterTitle(); |
+ gr1->Fit("pol1","Q"); |
+ |
+ TF1 *fit1 = gr1->GetFunction("pol1"); |
+ fparam[0] = fit1->GetParameter(0); |
+ fparamerr[0] = fit1->GetParError(0); |
+ fparam[1] = fit1->GetParameter(1); |
+ fparamerr[1] = fit1->GetParError(1); |
+ |
+ TMath::Sort(nrp, psep1, sortindex, kFALSE); |
+ |
+ meanval = -fparam[0]/fparam[1]; |
+ if(!cleanPlots) |
+ { |
+ sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ latex = new TLatex(); |
+ latex->SetTextSize(0.039); |
+ latex->DrawLatex(volt[0]-(volt[1]-volt[0]), 0.97*psep1[sortindex[nrp-1]], ctemp); |
+ } |
+ else |
+ printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ |
+ // Plotting the second breakdown voltage plot |
+ canvas->cd(2); |
+ gPad->SetGridx(1); |
+ gPad->SetGridy(1); |
+ |
+ gr2->Draw("AP"); |
+ gr2->GetXaxis()->SetTitle("Bias voltage (V)"); |
+ gr2->GetYaxis()->SetTitle("Peak separation"); |
+ gr2->GetYaxis()->CenterTitle(); |
+ gr2->Fit("pol1","Q"); |
+ |
+ TF1 *fit2 = gr2->GetFunction("pol1"); |
+ fparam[0] = fit2->GetParameter(0); |
+ fparamerr[0] = fit2->GetParError(0); |
+ fparam[1] = fit2->GetParameter(1); |
+ fparamerr[1] = fit2->GetParError(1); |
+ |
+ meanval = -fparam[0]/fparam[1]; |
+ if(!cleanPlots) |
+ { |
+ sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ latex = new TLatex(); |
+ latex->SetTextSize(0.039); |
+ latex->DrawLatex(volt[0]-(volt[1]-volt[0]), 0.97*psep2[sortindex[nrp-1]], ctemp); |
+ } |
+ else |
+ printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ |
+ // Plotting the third breakdown voltage plot |
+ canvas->cd(3); |
+ gPad->SetGridx(1); |
+ gPad->SetGridy(1); |
+ |
+ gr3->Draw("AP"); |
+ gr3->GetXaxis()->SetTitle("Bias voltage (V)"); |
+ gr3->GetYaxis()->SetTitle("Peak separation"); |
+ gr3->GetYaxis()->CenterTitle(); |
+ gr3->Fit("pol1","Q"); |
+ |
+ TF1 *fit3 = gr3->GetFunction("pol1"); |
+ fparam[0] = fit3->GetParameter(0); |
+ fparamerr[0] = fit3->GetParError(0); |
+ fparam[1] = fit3->GetParameter(1); |
+ fparamerr[1] = fit3->GetParError(1); |
+ |
+ meanval = -fparam[0]/fparam[1]; |
+ if(!cleanPlots) |
+ { |
+ sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ latex = new TLatex(); |
+ latex->SetTextSize(0.039); |
+ latex->DrawLatex(volt[0]-(volt[1]-volt[0]), 0.97*psep3[sortindex[nrp-1]], ctemp); |
+ } |
+ else |
+ printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) ); |
+ |
+ canvas->SaveAs(plotfile); |
+} |
+ |
+// Fit the ADC spectrum peaks and make a breakdown voltage plot |
+void TGAppMainFrame::FitSpectrum(TList *files, int q) |
+{ |
+ TCanvas *gCanvas = histCanvas->GetCanvas(); |
+ gCanvas->cd(); |
+ TH1F *histtemp; |
+ TSpectrum *spec; |
+ TH1 *histback; |
+ TH1F *h2; |
+ float *xpeaks; |
+ TF1 *fit; |
+ TF1 *fittingfunc; |
+ double *fparam; |
+ double *fparamerr; |
+ double meanparam[20], meanparamerr[20]; |
+ int sortindex[20]; |
+ char exportname[256]; |
+ char paramname[256]; |
+ char ctemp[256]; |
+ |
+ FILE *fp; |
+ remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp); |
+ sprintf(paramname, "%s_fitresult.txt", ctemp); |
+ fp = fopen(paramname, "w"); |
+ fclose(fp); |
+ |
+ int peaklimit = 5; |
+ int p = 0; |
+ double dtemp; |
+ double volt[files->GetSize()], volterr[files->GetSize()], sep[3][files->GetSize()], seperr[3][files->GetSize()]; |
+ for(int m = 0; m < files->GetSize(); m++) |
+ { |
+ volt[m] = 0; volterr[m] = 0; |
+ for(int i = 0; i < 3; i++) |
+ { sep[i][m] = 0; seperr[i][m] = 0; } |
+ } |
+ |
+ for(int m = 0; m < files->GetSize(); m++) |
+ { |
+ for(int i = 0; i < 20; i++) { meanparam[20] = 0; meanparamerr[20] = 0; } |
+ |
+ DisplayHistogram( (char*)(files->At(m)->GetTitle()), 0); |
+ dtemp = evtheader.biasvolt; |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ histtemp = (TH1F*)gCanvas->GetPrimitive(histname); |
+ npeaks = 20; |
+ double par[3000]; |
+ spec = new TSpectrum(npeaks); |
+ // Find spectrum background |
+ histback = spec->Background(histtemp, (int)fitInter->GetNumber(), "same"); |
+ // Clone histogram and subtract background from it |
+ h2 = (TH1F*)histtemp->Clone("h2"); |
+ h2->Add(histback, -1); |
+ // Search for the peaks |
+ int found = spec->Search(h2, fitSigma->GetNumber(), "goff", fitTresh->GetNumber() ); |
+ printf("Found %d candidates to fit.\n",found); |
+ npeaks = found; |
+ |
+ xpeaks = spec->GetPositionX(); |
+ for(int i = 0; i < found; i++) |
+ { |
+ float xp = xpeaks[i]; |
+ int bin = h2->GetXaxis()->FindBin(xp); |
+ float yp = h2->GetBinContent(bin); |
+ par[3*i] = yp; |
+ par[3*i+1] = xp; |
+ // par[3*i+2] = 3; |
+ par[3*i+2] = (double)fitSigma->GetNumber(); |
+ // printf("Peak %d: %f\n", i+1, xp); |
+ } |
+ |
+ // Fit the histogram |
+ fit = new TF1("fit", FindPeaks, 0, 400, 3*npeaks); |
+ TVirtualFitter::Fitter(histtemp, 3*npeaks); |
+ fit->SetParameters(par); |
+ fit->SetNpx(300); |
+ h2->Fit("fit","Q"); // for quiet mode, add Q |
+ fittingfunc = h2->GetFunction("fit"); |
+ fparam = fittingfunc->GetParameters(); |
+ fparamerr = fittingfunc->GetParErrors(); |
+ |
+ // Gather the parameters (mean peak value for now) |
+ int j = 1; |
+ int nrfit = 0; |
+ while(1) |
+ { |
+ if( (fparam[j] < 1.E-30) || (fparamerr[j] < 1.E-10) ) |
+ break; |
+ else |
+ { |
+ if(fparam[j] > 0) |
+ { |
+ meanparam[nrfit] = fparam[j]; |
+ meanparamerr[nrfit] = fparamerr[j]; |
+ nrfit++; |
+ } |
+ } |
+ |
+ j+=3; |
+ } |
+ |
+ // Write out parameters to a file |
+ fp = fopen(paramname, "a"); |
+ |
+ fprintf(fp, "%d\t", nrfit); |
+ TMath::Sort(nrfit, meanparam, sortindex, kFALSE); |
+ for(int i = 0; i < nrfit; i++) |
+ { |
+ if(debugSig) |
+ printf("Peak %d: %lf\t%lf\n", i+1, meanparam[sortindex[i]], meanparamerr[sortindex[i]]); |
+ fprintf(fp, "%le\t%le\t", meanparam[sortindex[i]], meanparamerr[sortindex[i]]); |
+ } |
+ printf("\n"); |
+ fprintf(fp, "\n"); |
+ |
+ fclose(fp); |
+ |
+ h2->SetStats(0); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ // Save each fitting plot |
+ if(exfitplots->IsDown()) |
+ { |
+ remove_ext((char*)files->At(m)->GetTitle(), ctemp); |
+ sprintf(exportname, "%s_fit.pdf", ctemp); |
+ gCanvas->SaveAs(exportname); |
+ } |
+ |
+ // Get points for mean peak values and create a breakdown voltage plot |
+ if(nrfit >= peaklimit) |
+ { |
+ sep[0][p] = meanparam[sortindex[2]] - meanparam[sortindex[1]]; |
+ sep[1][p] = meanparam[sortindex[3]] - meanparam[sortindex[2]]; |
+ sep[2][p] = meanparam[sortindex[4]] - meanparam[sortindex[3]]; |
+ |
+ seperr[0][p] = TMath::Abs(meanparamerr[sortindex[2]]) + TMath::Abs(meanparamerr[sortindex[1]]); |
+ seperr[1][p] = TMath::Abs(meanparamerr[sortindex[3]]) + TMath::Abs(meanparamerr[sortindex[2]]); |
+ seperr[2][p] = TMath::Abs(meanparamerr[sortindex[4]]) + TMath::Abs(meanparamerr[sortindex[3]]); |
+ |
+ volt[p] = dtemp; |
+ volterr[p] = 1.e-4; |
+ |
+ if(debugSig) |
+ printf("p=%d:\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", p, volt[p], sep[0][p], seperr[0][p], sep[1][p], seperr[1][p], sep[2][p], seperr[2][p]); |
+ |
+ // Accept only the points with a small enough error |
+ if( (seperr[0][p]/sep[0][p] < accError->GetNumber()) && (seperr[1][p]/sep[1][p] < accError->GetNumber()) && (seperr[2][p]/sep[2][p] < accError->GetNumber()) ) |
+ p++; |
+ else |
+ printf("Point (at %.2lfV) rejected due to errors: %lf, %lf, %lf\n", volt[p], seperr[0][p]/sep[0][p], seperr[1][p]/sep[1][p], seperr[2][p]/sep[2][p]); |
+ } |
+ |
+ if(q == 1) break; |
+ } |
+ |
+ // Plot & fit breakdown voltage plots |
+ if(q > 1) |
+ { |
+ remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp); |
+ sprintf(paramname, "%s_breakdown.pdf", ctemp); |
+ MakeBreakdownPlot(p, volt, volterr, sep[0], seperr[0], sep[1], seperr[1], sep[2], seperr[2], paramname); |
+ } |
+} |
+ |
+// Plotting of PDF and CDF functions for the edge (with the added fit) |
+void TGAppMainFrame::EdgeDetection(TGraph *pdf, TGraph *cdf, char *outname, TCanvas *g1dCanvas, double pdfmax, int direction) |
+{ |
+// double x, y; |
+ |
+ pdf->Fit("gaus","Q"); |
+ pdf->GetFunction("gaus")->SetNpx(400); |
+/* |
+ for(int i = 0; i < nrpoints; i++) |
+ { |
+ pdf->GetPoint(i, x, y); |
+ pdf->SetPoint(i, x, (y/pdfmax) ); |
+ } |
+*/ |
+ gStyle->SetOptFit(1); |
+ |
+ cdf->Draw("AL"); |
+ gPad->Update(); |
+ pdf->Draw("LP"); |
+ |
+ g1dCanvas->Modified(); |
+ g1dCanvas->Update(); |
+ |
+ TPaveStats *stats = (TPaveStats*)pdf->FindObject("stats"); |
+ if(!cleanPlots) |
+ { |
+// stats->SetX1NDC(0.14); stats->SetX2NDC(0.28); |
+// stats->SetY1NDC(0.83); stats->SetY2NDC(0.96); |
+ stats->SetX1NDC(0.86); stats->SetX2NDC(1.0); |
+ stats->SetY1NDC(0.87); stats->SetY2NDC(1.0); |
+ } |
+ else |
+ { |
+ stats->SetX1NDC(1.1); stats->SetX2NDC(1.3); |
+ stats->SetY1NDC(1.1); stats->SetY2NDC(1.3); |
+ } |
+ |
+ g1dCanvas->SetGridx(1); |
+ g1dCanvas->SetGridy(1); |
+ if(direction == 1) |
+ cdf->GetXaxis()->SetTitle("X [#mum]"); |
+ else if(direction == 2) |
+ cdf->GetXaxis()->SetTitle("Y [#mum]"); |
+ cdf->GetXaxis()->CenterTitle(kTRUE); |
+ cdf->GetXaxis()->SetLabelSize(0.022); |
+ cdf->GetYaxis()->SetTitle("Normalized ADC integral"); |
+// cdf->GetYaxis()->SetTitle("Normalized ADC integral (CDF)"); |
+// cdf->GetYaxis()->SetTitleColor(kBlue); |
+ cdf->GetYaxis()->CenterTitle(kTRUE); |
+ cdf->GetYaxis()->SetLabelSize(0.022); |
+ cdf->GetYaxis()->SetRangeUser(0,1); |
+ cdf->GetYaxis()->SetTitleSize(0.030); |
+// cdf->GetYaxis()->SetLabelColor(kBlue); |
+ if(!cleanPlots) |
+ cdf->SetTitle("SiPM edge detection"); |
+ else |
+ cdf->SetTitle(); |
+ cdf->SetLineColor(kBlue); |
+ pdf->SetLineWidth(2); |
+ cdf->SetLineWidth(2); |
+ |
+/* TGaxis *axis = new TGaxis(gPad->GetUxmax(), 0, gPad->GetUxmax(), 1, 0, pdfmax, 510, "+L"); |
+ axis->Draw(); |
+ axis->SetTitle("Normalized ADC integral (PDF)"); |
+ axis->SetTitleSize(0.035); |
+ axis->CenterTitle(); |
+ axis->SetTitleColor(kBlack); |
+ axis->SetTitleFont(42); |
+ axis->SetLabelSize(0.022); |
+ axis->SetLabelColor(kBlack);*/ |
+ |
+ g1dCanvas->Modified(); |
+ g1dCanvas->Update(); |
+ |
+ g1dCanvas->SaveAs(outname); |
+} |
+ |
+// Integrate the spectrum |
+void TGAppMainFrame::IntegSpectrum(TList *files, int direction) |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ char ctemp[256]; |
+ int j, k = 0, m = 0, n = 0; |
+ |
+ TCanvas *gCanvas = new TCanvas("canv","canv",900,900); |
+ TCanvas *g1dCanvas = new TCanvas("canv1d","canv1d",1200,900); |
+ TTree *header_data, *meas_data; |
+ double *integralCount, *integralAcc; |
+ integralCount = new double[nrfiles]; |
+ integralAcc = new double[nrfiles]; |
+// double xsurfmin, ysurfmin, zsurfmin; |
+ double *surfx, *surfy, *surfz; |
+ surfx = new double[nrfiles]; |
+ surfy = new double[nrfiles]; |
+ surfz = new double[nrfiles]; |
+ for(int i = 0; i < (int)nrfiles; i++) {integralCount[i] = 0; integralAcc[i] = 0; } |
+ |
+ TGraph *gScan[2]; // graphs for PDF and CDF functions |
+ double pdfmax = -1; |
+ TGraph2D *gScan2D; |
+ gScan2D = new TGraph2D(); |
+ int nrentries; |
+ double minInteg, maxInteg; |
+ |
+ char exportname[256]; |
+ |
+ if(files->GetSize() > 0) |
+ { |
+ for(int i = 0; i < (int)files->GetSize(); i++) |
+ { |
+ n++; |
+ if(files->At(i)) |
+ { |
+ sprintf(ctemp, "%s", files->At(i)->GetTitle()); |
+ inroot = new TFile(ctemp, "READ"); |
+ |
+ inroot->GetObject("header_data", header_data); |
+ inroot->GetObject("meas_data", meas_data); |
+ |
+ // Reading the header |
+ header_data->SetBranchAddress("xpos", &evtheader.xpos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("ypos", &evtheader.ypos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("zpos", &evtheader.zpos); |
+ header_data->GetEntry(0); |
+ |
+ char rdc[256]; |
+ j = selectCh->GetNumber(); |
+ double rangetdc[2]; |
+ rangetdc[0] = tdcMinwindow->GetNumber(); |
+ rangetdc[1] = tdcMaxwindow->GetNumber(); |
+ |
+ k = 0; |
+ m = 0; |
+ |
+ // Reading the data |
+ for(int e = 0; e < meas_data->GetEntries(); e++) |
+ { |
+ sprintf(rdc, "ADC%d", j); |
+ meas_data->SetBranchAddress(rdc, &evtdata.adcdata[j]); |
+ meas_data->GetEntry(e); |
+ |
+ sprintf(rdc, "TDC%d", j); |
+ meas_data->SetBranchAddress(rdc, &evtdata.tdcdata[j]); |
+ meas_data->GetEntry(e); |
+ |
+ // If our data point is inside the TDC window |
+ if( ((double)evtdata.tdcdata[j]/tdctimeconversion >= rangetdc[0]) && ((double)evtdata.tdcdata[j]/tdctimeconversion <= rangetdc[1]) ) |
+ { |
+ k++; |
+ m += evtdata.adcdata[j]; |
+ } |
+ } |
+ |
+/* if(n == 1) // these values can be used to set 0 value at first X, Y and Z positions |
+ { |
+ xsurfmin = evtheader.xpos; |
+ ysurfmin = evtheader.ypos; |
+ zsurfmin = evtheader.zpos; |
+ } |
+ surfx[i] = (double)(evtheader.xpos-xsurfmin)*lenconversion; |
+ surfy[i] = (double)(evtheader.ypos-ysurfmin)*lenconversion; |
+ surfz[i] = (double)(evtheader.zpos-zsurfmin)*lenconversion;*/ |
+ surfx[i] = (double)(evtheader.xpos*lenconversion); |
+ surfy[i] = (double)(evtheader.ypos*lenconversion); |
+ surfz[i] = (double)(evtheader.zpos*lenconversion); |
+ |
+/* surfx[i] = evtheader.xpos; |
+ surfy[i] = evtheader.ypos; |
+ surfz[i] = evtheader.zpos; |
+*/ |
+ integralCount[i] += ((double)m)/((double)k); |
+ |
+ delete inroot; |
+ } |
+ } |
+ |
+ nrentries = n; |
+ printf("%d files were selected.\n", nrentries); |
+ |
+ double curzval = surfz[0]; |
+ j = 0; |
+ int acc = 0; |
+ int zb; |
+ for(int i = 0; i <= nrentries; i++) |
+ { |
+ if(acc == nrentries) |
+ { |
+ minInteg = TMath::MinElement(j, integralAcc); |
+ |
+ for(int za = 0; za < j; za++) |
+ integralAcc[za] = integralAcc[za] - minInteg; |
+ |
+ maxInteg = TMath::MaxElement(j, integralAcc); |
+ |
+ for(int za = 0; za < j; za++) |
+ { |
+ zb = i-j+za; |
+ integralCount[zb] = integralAcc[za]/maxInteg; |
+ if(debugSig) |
+ printf("Integral check 2 (i=%d,j=%d,za=%d,z=%.2lf,zb=%d): %lf\t%lf\n", i, j, za, surfz[i-j], zb, integralCount[zb], integralAcc[za]/maxInteg); |
+ } |
+ |
+ // Plotting of PDF and CDF functions for the edge (with the added fit) |
+ gScan[1] = new TGraph(); |
+ for(int za = 0; za < j; za++) |
+ { |
+ zb = i-j+za; |
+ if(direction == 1) |
+ gScan[1]->SetPoint(za, (double)surfx[zb], (double)integralAcc[za]/maxInteg); |
+ else if(direction == 2) |
+ gScan[1]->SetPoint(za, (double)surfy[zb], (double)integralAcc[za]/maxInteg); |
+ |
+ if( ((integralAcc[za+1]-integralAcc[za])/maxInteg > pdfmax) && (za < j-1) ) |
+ pdfmax = (integralAcc[za+1]-integralAcc[za])/maxInteg; |
+ } |
+ |
+ pdfmax = (TMath::Ceil(pdfmax*10))/10.; |
+ |
+ gScan[0] = new TGraph(); |
+ for(int za = j-1; za >= 0; za--) |
+ { |
+ zb = (i-1)-(j-1)+za; |
+ if((integralAcc[za]-integralAcc[za-1])/(maxInteg) < 0) |
+ { |
+ if(direction == 1) |
+ gScan[0]->SetPoint(za, (double)surfx[zb], 0); |
+ else if(direction == 2) |
+ gScan[0]->SetPoint(za, (double)surfy[zb], 0); |
+ } |
+ else |
+ { |
+ if(direction == 1) |
+ gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg)); |
+ else if(direction == 2) |
+ gScan[0]->SetPoint(za, (double)surfy[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg)); |
+// gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(pdfmax*maxInteg)); |
+ } |
+ } |
+ |
+ remove_from_last((char*)files->At(i-1)->GetTitle(), '_', ctemp); |
+ sprintf(exportname, "%s_edge.pdf", ctemp); |
+ EdgeDetection(gScan[0], gScan[1], exportname, g1dCanvas, pdfmax, direction); |
+ |
+// delete gScan[0]; |
+// delete gScan[1]; |
+ |
+ i--; |
+ pdfmax = 0; |
+ break; |
+ } |
+ else |
+ { |
+ if(surfz[i] == curzval) |
+ { |
+ integralAcc[j] = integralCount[i]; |
+ if(debugSig) |
+ printf("Integral check 1 (i=%d,j=%d,z=%.2lf): %lf\t%lf\n", i, j, surfz[i], integralCount[i], integralAcc[j]); |
+ j++; |
+ acc++; |
+ } |
+ else |
+ { |
+ minInteg = TMath::MinElement(j, integralAcc); |
+ |
+ for(int za = 0; za < j; za++) |
+ integralAcc[za] = integralAcc[za] - minInteg; |
+ |
+ maxInteg = TMath::MaxElement(j, integralAcc); |
+ |
+ for(int za = 0; za < j; za++) |
+ { |
+ zb = i-j+za; |
+ integralCount[zb] = integralAcc[za]/maxInteg; |
+ if(debugSig) |
+ printf("Integral check 2 (i=%d,j=%d,za=%d,z=%.2lf,zb=%d): %lf\t%lf\n", i, j, za, surfz[i-j], zb, integralCount[zb], integralAcc[za]/maxInteg); |
+ } |
+ |
+ curzval = surfz[i]; |
+ i--; |
+ |
+ // Plotting of PDF and CDF functions for the edge (with the added fit) |
+ gScan[1] = new TGraph(); |
+ for(int za = 0; za < j; za++) |
+ { |
+ zb = i-(j-1)+za; |
+ if(direction == 1) |
+ gScan[1]->SetPoint(za, (double)surfx[zb], (double)integralAcc[za]/maxInteg); |
+ else if(direction == 2) |
+ gScan[1]->SetPoint(za, (double)surfy[zb], (double)integralAcc[za]/maxInteg); |
+ |
+ if( ((integralAcc[za+1]-integralAcc[za])/maxInteg > pdfmax) && (za < j-1) ) |
+ pdfmax = (integralAcc[za+1]-integralAcc[za])/maxInteg; |
+ } |
+ |
+ pdfmax = (TMath::Ceil(pdfmax*10))/10.; |
+ |
+ gScan[0] = new TGraph(); |
+ for(int za = j-1; za >= 0; za--) |
+ { |
+ zb = i-(j-1)+za; |
+ if((integralAcc[za]-integralAcc[za-1])/(maxInteg) < 0) |
+ { |
+ if(direction == 1) |
+ gScan[0]->SetPoint(za, (double)surfx[zb], 0); |
+ else if(direction == 2) |
+ gScan[0]->SetPoint(za, (double)surfy[zb], 0); |
+ } |
+ else |
+ { |
+ if(direction == 1) |
+ gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg)); |
+ else if(direction == 2) |
+ gScan[0]->SetPoint(za, (double)surfy[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg)); |
+// gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(pdfmax*maxInteg)); |
+ } |
+ } |
+ |
+ remove_from_last((char*)files->At(i)->GetTitle(), '_', ctemp); |
+ sprintf(exportname, "%s_edge.pdf", ctemp); |
+ EdgeDetection(gScan[0], gScan[1], exportname, g1dCanvas, pdfmax, direction); |
+ |
+ delete gScan[0]; |
+ delete gScan[1]; |
+ |
+ j = 0; |
+ pdfmax = 0; |
+ } |
+ } |
+ } |
+ |
+// delete g1dCanvas; |
+ |
+ double range[4]; |
+ if(direction == 1) |
+ { |
+ range[0] = TMath::MinElement(nrentries, surfx); |
+ range[1] = TMath::MaxElement(nrentries, surfx); |
+ } |
+ else if(direction == 2) |
+ { |
+ range[0] = TMath::MinElement(nrentries, surfy); |
+ range[1] = TMath::MaxElement(nrentries, surfy); |
+ } |
+ else |
+ { |
+ range[0] = TMath::MinElement(nrentries, surfx); |
+ range[1] = TMath::MaxElement(nrentries, surfx); |
+ } |
+ range[2] = TMath::MinElement(nrentries, surfz); |
+ range[3] = TMath::MaxElement(nrentries, surfz); |
+ |
+ // Plotting of 2D edge plot |
+ for(int i = 0; i < nrentries; i++) |
+ { |
+ if(direction == 1) |
+ { |
+ if(debugSig) |
+ printf("%.2lf\t%.2lf\t%lf\n", surfx[i], surfz[i], integralCount[i]); |
+ gScan2D->SetPoint(i, surfx[i], surfz[i], integralCount[i]); |
+ } |
+ else if(direction == 2) |
+ { |
+ if(debugSig) |
+ printf("%.2lf\t%.2lf\t%lf\n", surfy[i], surfz[i], integralCount[i]); |
+ gScan2D->SetPoint(i, surfy[i], surfz[i], integralCount[i]); |
+ } |
+ } |
+ |
+ gCanvas->cd(); |
+ gStyle->SetPalette(1); |
+ gScan2D->Draw("COLZ"); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ if(direction == 1) |
+ gScan2D->GetXaxis()->SetTitle("X [#mum]"); |
+ else if(direction == 2) |
+ gScan2D->GetXaxis()->SetTitle("Y [#mum]"); |
+ gScan2D->GetXaxis()->CenterTitle(kTRUE); |
+ gScan2D->GetXaxis()->SetLabelSize(0.022); |
+ gScan2D->GetXaxis()->SetRangeUser(range[0], range[1]); |
+ gScan2D->GetXaxis()->SetNoExponent(); |
+ gScan2D->GetYaxis()->SetTitle("Z [#mum]"); |
+ gScan2D->GetYaxis()->SetTitleOffset(1.3); |
+ gScan2D->GetYaxis()->CenterTitle(kTRUE); |
+ gScan2D->GetYaxis()->SetLabelSize(0.022); |
+ gScan2D->GetYaxis()->SetRangeUser(range[2], range[3]); |
+ TGaxis *yax = (TGaxis*)gScan2D->GetYaxis(); |
+ yax->SetMaxDigits(4); |
+ if(!cleanPlots) |
+ gScan2D->SetTitle("Laser focal point"); |
+ else |
+ gScan2D->SetTitle(); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp); |
+ sprintf(exportname, "%s", ctemp); |
+ remove_from_last(exportname, '_', ctemp); |
+ if(direction == 1) |
+ sprintf(exportname, "%s_xdir_focalpoint.pdf", ctemp); |
+ else if(direction == 2) |
+ sprintf(exportname, "%s_ydir_focalpoint.pdf", ctemp); |
+ gCanvas->SaveAs(exportname); |
+ } |
+} |
+ |
+void TGAppMainFrame::RunMeas(void *ptr, int runCase, int zaxisscan) |
+{ |
+ printf("Start of Run, run case %d\n", runCase); |
+ float progVal; |
+ |
+ char ctemp[256]; |
+ char fname[256]; |
+ |
+ remove_ext((char*)fileName->GetText(), ctemp); |
+// printf("Save name: %s\nNo extension: %s\n", fileName->GetText(), ctemp); |
+ |
+ // Open file for writing |
+/* if(runCase == 0) |
+ { |
+ sprintf(fname, "rm %s_%s", ctemp, histExtAll); |
+ retTemp = system(fname); |
+ }*/ // deleting might not be necesary due to RECREATE in root file open |
+ |
+ if( voltscanOn->IsOn() || surfscanOn->IsOn() ) |
+ { |
+ if(zaxisscan == 0) |
+ { |
+ if(runCase < 10) |
+ sprintf(fname, "%s_0000%d%s", ctemp, runCase, histExt); |
+ else if( (runCase >= 10) && (runCase < 100) ) |
+ sprintf(fname, "%s_000%d%s", ctemp, runCase, histExt); |
+ else if( (runCase >= 100) && (runCase < 1000) ) |
+ sprintf(fname, "%s_00%d%s", ctemp, runCase, histExt); |
+ else if( (runCase >= 1000) && (runCase < 10000) ) |
+ sprintf(fname, "%s_0%d%s", ctemp, runCase, histExt); |
+ else if( (runCase >= 10000) && (runCase < 100000) ) |
+ sprintf(fname, "%s_%d%s", ctemp, runCase, histExt); |
+ } |
+ else if(zaxisscan == 1) |
+ { |
+ if(runCase < 10) |
+ sprintf(fname, "%s_z%d_0000%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt); |
+ else if( (runCase >= 10) && (runCase < 100) ) |
+ sprintf(fname, "%s_z%d_000%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt); |
+ else if( (runCase >= 100) && (runCase < 1000) ) |
+ sprintf(fname, "%s_z%d_00%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt); |
+ else if( (runCase >= 1000) && (runCase < 10000) ) |
+ sprintf(fname, "%s_z%d_0%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt); |
+ else if( (runCase >= 10000) && (runCase < 100000) ) |
+ sprintf(fname, "%s_z%d_0%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt); |
+ } |
+ } |
+ else if( !voltscanOn->IsOn() && !surfscanOn->IsOn() ) |
+ sprintf(fname, "%s%s", ctemp, histExt); |
+// printf("Rootfile: %s\n", fname); |
+ |
+ // Check if set voltage is below the hard limit |
+ if( vOut->GetNumber() > vHardlimit->GetNumber() ) |
+ { |
+ printf("Voltage hard limit triggered (%lf > %lf)!\n", vOut->GetNumber(), vHardlimit->GetNumber() ); |
+ vOut->SetNumber( vHardlimit->GetNumber() ); |
+ } |
+ |
+ outroot = new TFile(fname, "RECREATE"); |
+ |
+ TTree *header_data = new TTree("header_data", "Header information for the measurement."); |
+ TTree *meas_data = new TTree("meas_data", "Saved measurement data."); |
+ |
+ // Branches for the header |
+ header_data->Branch("nrch", &evtheader.nrch, "nrch/I"); |
+ header_data->Branch("timestamp", &evtheader.timestamp, "timestamp/I"); |
+ header_data->Branch("biasvolt", &evtheader.biasvolt, "biasvolt/D"); |
+ header_data->Branch("xpos", &evtheader.xpos, "xpos/I"); |
+ header_data->Branch("ypos", &evtheader.ypos, "ypos/I"); |
+ header_data->Branch("zpos", &evtheader.zpos, "zpos/I"); |
+ header_data->Branch("temperature", &evtheader.temperature, "temperature/D"); |
+ header_data->Branch("laserinfo", &evtheader.laserinfo, "laserinfo/C"); |
+ |
+ evtheader.nrch = (int)NCH->GetNumber()*2; |
+ evtheader.timestamp = (int)time(NULL); |
+ evtheader.biasvolt = (double)vOut->GetNumber(); |
+ evtheader.xpos = (int)xPos->GetNumber(); |
+ evtheader.ypos = (int)yPos->GetNumber(); |
+ evtheader.zpos = (int)zPos->GetNumber(); |
+ evtheader.temperature = 25.0; // Still to do!!! |
+ sprintf(evtheader.laserinfo, "%s", laserInfo->GetText()); |
+ |
+ char histtime[256]; |
+ GetTime(evtheader.timestamp, histtime); |
+ |
+ printf("Save file header information:\n"); |
+ printf("- Number of channels: %d\n", evtheader.nrch); |
+ printf("- Timestamp: %d (%s)\n", evtheader.timestamp, histtime); |
+ printf("- Bias voltage: %lf\n", evtheader.biasvolt); |
+ printf("- Table position (X,Y,Z): %d, %d, %d\n", evtheader.xpos, evtheader.ypos, evtheader.zpos); |
+ printf("- Temperature: %lf\n", evtheader.temperature); |
+ printf("- Laser and filter settings: %s\n", evtheader.laserinfo); |
+ |
+ header_data->Fill(); |
+ |
+ // Branches for ADC and TDC data |
+ for(int i = 0; i < evtheader.nrch/2; i++) |
+ { |
+ sprintf(ctemp, "ADC%d", i); |
+ sprintf(fname, "ADC%d/I", i); |
+ meas_data->Branch(ctemp, &evtdata.adcdata[i], fname); |
+ |
+ sprintf(ctemp, "TDC%d", i); |
+ sprintf(fname, "TDC%d/I", i); |
+ meas_data->Branch(ctemp, &evtdata.tdcdata[i], fname); |
+ } |
+ |
+ int neve = (int) evtNum->GetNumber(); |
+ int allEvt, zProg; |
+ zProg = 1; |
+ |
+#if WORKSTAT == 'I' |
+#else |
+// ONLY FOR TESTING! |
+ TRandom *randNum = new TRandom(); |
+ randNum->SetSeed(0); |
+// ONLY FOR TESTING! |
+#endif |
+ |
+ if (gDaq) |
+ { |
+ gDaq->fStop=0; |
+ // Start gathering |
+ gDaq->start(); |
+ |
+ busyLabel->Enable(); |
+ |
+ for (int n=0;n<neve && !gDaq->fStop ;/*n++*/) |
+ { |
+ int nb = gDaq->event(gBuf,BSIZE); |
+ |
+#if WORKSTAT == 'I' |
+#else |
+// ONLY FOR TESTING! |
+ for(int i=0; i < evtheader.nrch; i++) |
+ { |
+ if(i == 1) |
+ gBuf[i] = randNum->Gaus(1500,300); |
+ else if(i == 0) |
+ gBuf[i] = randNum->Poisson(2500); |
+ } |
+// ONLY FOR TESTING! |
+#endif |
+ if (nb<=0) n--; |
+ |
+ int nc=0; |
+ |
+ while ( (nb>0) && (n<neve) ) |
+ { |
+ for(int i = 0; i < evtheader.nrch; i++) |
+ { |
+ unsigned short adc = gBuf[i+nc]&0xFFFF; |
+ if(i % 2 == 0) // TDC |
+ evtdata.tdcdata[i/2] = (int)adc; |
+ else if(i % 2 == 1) // ADC |
+ evtdata.adcdata[i/2] = (int)adc; |
+ } |
+ meas_data->Fill(); |
+ |
+ n++; |
+ nc += evtheader.nrch; |
+ nb -= evtheader.nrch; |
+ } |
+ |
+ MyTimer(); |
+ allEvt = n; |
+ if (gSystem->ProcessEvents()) printf("Run Interrupted\n"); |
+ |
+ if( (started) && (n == (neve*zProg)/10) ) |
+ { |
+ progVal = (float)zProg*10; |
+ curProgress->SetPosition(progVal); |
+ zProg++; |
+ } |
+ } |
+ |
+ printf("Number of gathered events: %d\n", allEvt); |
+ measStart->SetText("Start acquisition"); |
+ started = kFALSE; |
+ |
+ gDaq->stop(); |
+ } |
+ |
+ busyLabel->Disable(); |
+ printf("End of Run neve=%d\n",neve); |
+ |
+ header_data->Write(); |
+ meas_data->Write(); |
+ delete header_data; |
+ delete meas_data; |
+ |
+ outroot->Close(); |
+} |
+ |
+// Start the acquisition |
+void TGAppMainFrame::StartAcq() |
+{ |
+ // Determine the type of measurement to perform |
+ int vscan = 0, pscan = 0, zscan = 0; |
+ if(voltscanOn->IsOn()) vscan = 1; |
+ if(surfscanOn->IsOn()) pscan = 1; |
+ if(zscanOn->IsOn()) zscan = 1; |
+ |
+ char cmd[256]; |
+ int i, j, k; |
+ float progVal; |
+ FILE *pfin; |
+ |
+ // Variables for voltage scan |
+ float currentVoltage, minVoltage, maxVoltage, stepVoltage; |
+ int repetition; |
+ |
+ // Variables for surface scan |
+ int minXpos, maxXpos, stepXpos; |
+ int minYpos, maxYpos, stepYpos; |
+ int minZpos, maxZpos, stepZpos; |
+ int repetX, repetY, repetZ; |
+ |
+ // Voltage scan |
+ if( (vscan == 1) && (pscan == 0) ) |
+ { |
+ if(started) |
+ { |
+ printf("Stopping current voltage scan...\n"); |
+ gROOT->SetInterrupt(); |
+ measStart->SetText("Start acquisition"); |
+ started = kFALSE; |
+ |
+ pfin = fopen("finish_sig.txt","w"); |
+ fprintf(pfin, "%s: Voltage scan stopped.", timeStamp->GetText()); |
+ fclose(pfin); |
+ } |
+ else if(!started) |
+ { |
+ measStart->SetText("Stop acquisition"); |
+ started = kTRUE; |
+ |
+ printf("Running a voltage scan...\n"); |
+ |
+ minVoltage = vOutStart->GetNumber(); |
+ maxVoltage = vOutStop->GetNumber(); |
+ stepVoltage = vOutStep->GetNumber(); |
+ |
+ if(stepVoltage == 0.) |
+ repetition = 1; |
+ else |
+ repetition = ((maxVoltage - minVoltage)/stepVoltage)+1; |
+ |
+ for(i=0; i < repetition; i++) |
+ { |
+ progVal = (float)(100.00/repetition)*i; |
+ curProgress->SetPosition(progVal); |
+ |
+ fflush(stdout); |
+ currentVoltage = minVoltage + stepVoltage*i; |
+ sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -v %f -s 1", rootdir, GetChannel(), currentVoltage); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ printf("Waiting for voltage change...\n"); |
+ sleep(5); |
+ vOut->SetNumber(currentVoltage); |
+ printf("Continuing...\n"); |
+ |
+ // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<< |
+ RunMeas((void*)0, i, 0); |
+ fflush(stdout); |
+ } |
+ |
+ // Set output back to off |
+ fflush(stdout); |
+ printf("Measurement finished, returning to starting voltage...\n"); |
+ sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -v %f -s 1", rootdir, GetChannel(), minVoltage); |
+ vOut->SetNumber(minVoltage); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ progVal = 100.00; |
+ curProgress->SetPosition(progVal); |
+ printf("\n"); |
+ |
+ pfin = fopen("finish_sig.txt","w"); |
+ fprintf(pfin, "%s: Voltage scan finished.", timeStamp->GetText()); |
+ fclose(pfin); |
+ } |
+ } |
+ // Surface scan |
+ else if( (pscan == 1) && (vscan == 0) ) |
+ { |
+ minXpos = xPosMin->GetNumber(); |
+ maxXpos = xPosMax->GetNumber(); |
+ stepXpos = xPosStep->GetNumber(); |
+ minYpos = yPosMin->GetNumber(); |
+ maxYpos = yPosMax->GetNumber(); |
+ stepYpos = yPosStep->GetNumber(); |
+ minZpos = zPosMin->GetNumber(); |
+ maxZpos = zPosMax->GetNumber(); |
+ stepZpos = zPosStep->GetNumber(); |
+ |
+ if(zscan == 1) |
+ { |
+ if(stepZpos == 0.) repetZ = 1; |
+ else repetZ = ((maxZpos - minZpos)/stepZpos)+1; |
+ } |
+ else |
+ { |
+ minZpos = zPos->GetNumber(); |
+ repetZ = 1; |
+ } |
+ |
+ if(stepXpos == 0.) repetX = 1; |
+ else repetX = ((maxXpos - minXpos)/stepXpos)+1; |
+ if(stepYpos == 0.) repetY = 1; |
+ else repetY = ((maxYpos - minYpos)/stepYpos)+1; |
+ |
+ for(k=0; k < repetZ; k++) |
+ { |
+ fflush(stdout); |
+ // Y-axis change |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/MIKRO/mikro_ctrl -n 3 -c m", rootdir, minZpos + stepZpos*k, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ printf("Next Z position...\n"); |
+ zPos->SetNumber(minZpos + stepZpos*k); |
+ fflush(stdout); |
+ |
+ for(j=0; j < repetY; j++) |
+ { |
+ fflush(stdout); |
+ // Y-axis change |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/MIKRO/mikro_ctrl -n 2 -c m", rootdir, minYpos + stepYpos*j, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ sleep(4); |
+ printf("Next Y position...\n"); |
+ yPos->SetNumber(minYpos + stepYpos*j); |
+ fflush(stdout); |
+ |
+ for(i=0; i < repetX; i++) |
+ { |
+ progVal = (float)(100.00/(repetX*repetY))*(j*repetX+i); |
+ curProgress->SetPosition(progVal); |
+ |
+ // X-axis change |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/MIKRO/mikro_ctrl -n 1 -c m", rootdir, minXpos + stepXpos*i, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ printf("Next X position...\n"); |
+ fflush(stdout); |
+ |
+ printf("Waiting for position change...\n"); |
+ sleep(2); |
+ xPos->SetNumber(minXpos + stepXpos*i); |
+ printf("Continuing...\n"); |
+ |
+// for (k=0;k<(NTDCCH+NADCCH);k++) gHisto1D[k]->Reset(); |
+// for (k=0;k<(NTDCCH+NADCCH)/2;k++) gHisto2D[k]->Reset(); |
+ |
+ // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<< |
+ RunMeas((void*)0, (j*repetX + i), zscan ); |
+ |
+ fflush(stdout); |
+ } |
+ |
+ printf("\n"); |
+ } |
+ } |
+ |
+ fflush(stdout); |
+ printf("Measurement finished, returning to starting position...\n"); |
+ // X-axis return |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/MIKRO/mikro_ctrl -n 1 -c m", rootdir, minXpos, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ fflush(stdout); |
+ |
+ // Y-axis return |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/MIKRO/mikro_ctrl -n 2 -c m", rootdir, minYpos, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ |
+ // Z-axis return |
+ sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/MIKRO/mikro_ctrl -n 3 -c m", rootdir, minZpos, rootdir); |
+#if WORKSTAT == 'I' |
+ retTemp = system(cmd); |
+#else |
+ printf("Cmd: %s\n",cmd); |
+#endif |
+ xPos->SetNumber(minXpos); |
+ yPos->SetNumber(minYpos); |
+ zPos->SetNumber(minZpos); |
+ |
+ progVal = 100.00; |
+ curProgress->SetPosition(progVal); |
+ printf("\n"); |
+ |
+ pfin = fopen("finish_sig.txt","w"); |
+ fprintf(pfin, "%s: Surface scan finished.", timeStamp->GetText()); |
+ fclose(pfin); |
+ } |
+ // Normal single measurement |
+ else if( (vscan == 0) && (pscan == 0) ) |
+ { |
+ // Set the start button to stop and enable stopping of measurement |
+ if(started) |
+ { |
+ printf("Stopping current single scan...\n"); |
+ gROOT->SetInterrupt(); |
+// gDaq->fStop=1; |
+ measStart->SetText("Start acquisition"); |
+ started = kFALSE; |
+ } |
+ else if(!started) |
+ { |
+ measStart->SetText("Stop acquisition"); |
+ started = kTRUE; |
+ |
+ printf("Running a single scan...\n"); |
+ RunMeas((void*)0, 0, 0); |
+ printf("Measurement finished...\n"); |
+ printf("\n"); |
+ } |
+ } |
+} |
+ |
+// File browser for opening histograms |
+void TGAppMainFrame::SelectDirectory() |
+{ |
+ int i = fileList->GetNumberOfEntries(); |
+ |
+ TGFileInfo file_info; |
+ const char *filetypes[] = {"Histograms",histExtAll,0,0}; |
+ file_info.fFileTypes = filetypes; |
+ file_info.fIniDir = StrDup("./results"); |
+ file_info.fMultipleSelection = kTRUE; |
+ new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDOpen, &file_info); |
+ |
+ TList *files = file_info.fFileNamesList; |
+ if(files) |
+ { |
+ TSystemFile *file; |
+ TString fname; |
+ TIter next(files); |
+ while(file=(TSystemFile*)next()) |
+ { |
+ fname = file->GetName(); |
+ fileList->AddEntry(fname.Data(), i); |
+ i++; |
+ } |
+ } |
+ fileList->Layout(); |
+} |
+ |
+// File browser for selecting the save file |
+void TGAppMainFrame::SaveFile() |
+{ |
+ TGFileInfo file_info; |
+ const char *filetypes[] = {"Histograms",histExtAll,0,0}; |
+ file_info.fFileTypes = filetypes; |
+ file_info.fIniDir = StrDup("./results"); |
+ new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDSave, &file_info); |
+ |
+ fileName->SetText(file_info.fFilename); |
+} |
+ |
+// Toggle multiple selection in filelist |
+void TGAppMainFrame::ListMultiSelect() |
+{ |
+ fileList->SetMultipleSelections((multiSelect->IsOn())); |
+ |
+ if(multiSelectAll->IsDown()) |
+ multiSelectAll->SetState(kButtonUp); |
+} |
+ |
+// Select all entries in filelist |
+void TGAppMainFrame::ListSelectAll() |
+{ |
+ if(multiSelectAll->IsDown()) |
+ { |
+ multiSelect->SetState(kButtonDown); |
+ fileList->SetMultipleSelections((multiSelect->IsOn())); |
+ for(int i = 0; i < fileList->GetNumberOfEntries(); i++) |
+ fileList->Select(i,kTRUE); |
+ } |
+ else if(!multiSelectAll->IsDown()) |
+ { |
+ multiSelect->SetState(kButtonUp); |
+ fileList->SetMultipleSelections((multiSelect->IsOn())); |
+ for(int i = 0; i < fileList->GetNumberOfEntries(); i++) |
+ fileList->Select(i,kFALSE); |
+ } |
+} |
+ |
+// Navigation buttons for the filelist (<<, >>) and double click |
+void TGAppMainFrame::FileListNavigation(int pn) |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ int curSel; |
+ TList *files; |
+ if( nrfiles > 0 ) |
+ { |
+ if(pn < -1) |
+ { |
+ if(multiSelect->IsOn()) |
+ { |
+ // turn off multiple selection and select first file on list |
+ fileList->SetMultipleSelections(kFALSE); |
+ multiSelect->SetState(kButtonUp); |
+ multiSelectAll->SetState(kButtonUp); |
+ |
+ fileList->Select(0,kTRUE); |
+ } |
+ else |
+ { |
+ // if nothing is selected, curSel will be -1 |
+ curSel = fileList->GetSelected(); |
+ // go to next file on list |
+ if(pn == -3) |
+ { |
+ if( (curSel == (int)(nrfiles-1)) || (curSel == -1) ) |
+ fileList->Select(0); |
+ else |
+ fileList->Select(curSel+1); |
+ } |
+ // go to previous file on list |
+ else if(pn == -2) |
+ { |
+ if( (curSel == 0) || (curSel == -1) ) |
+ fileList->Select(nrfiles-1); |
+ else |
+ fileList->Select(curSel-1); |
+ } |
+ } |
+ } |
+ |
+ // check the newly selected file/files and return its name/their names |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ if(files) |
+ { |
+ for(int i = 0; i < (int)nrfiles; i++) |
+ { |
+ if(files->At(i)) |
+ { |
+ if(debugSig) |
+ printf("Filename: %s\n", files->At(i)->GetTitle()); |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2); |
+ } |
+ } |
+ } |
+ |
+ // Still need to include drawing of histograms we move to!!! |
+ } |
+} |
+ |
+// Display the currently selected histogram in file list |
+void TGAppMainFrame::DisplayHistogram(char* histfile, int histtype) |
+{ |
+ if(debugSig) |
+ printf("Selected file: %s\n", histfile); |
+ |
+ TCanvas *gCanvas = histCanvas->GetCanvas(); |
+ |
+ inroot = new TFile(histfile, "READ"); |
+ |
+ TTree *header_data, *meas_data; |
+ inroot->GetObject("header_data", header_data); |
+ inroot->GetObject("meas_data", meas_data); |
+ |
+ // Reading the header |
+ header_data->SetBranchAddress("nrch", &evtheader.nrch); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("timestamp", &evtheader.timestamp); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("biasvolt", &evtheader.biasvolt); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("xpos", &evtheader.xpos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("ypos", &evtheader.ypos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("zpos", &evtheader.zpos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("temperature", &evtheader.temperature); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("laserinfo", &evtheader.laserinfo); |
+ header_data->GetEntry(0); |
+ |
+ char histtime[256]; |
+ GetTime(evtheader.timestamp, histtime); |
+ |
+ if(debugSig) |
+ { |
+ printf("Opened file header information:\n"); |
+ printf("- Number of channels: %d\n", evtheader.nrch); |
+ printf("- Timestamp: %d (%s)\n", evtheader.timestamp, histtime); |
+ printf("- Bias voltage: %lf\n", evtheader.biasvolt); |
+ printf("- Table position (X,Y,Z): %d, %d, %d\n", evtheader.xpos, evtheader.ypos, evtheader.zpos); |
+ printf("- Temperature: %lf\n", evtheader.temperature); |
+ printf("- Laser and filter settings: %s\n", evtheader.laserinfo); |
+ } |
+ |
+ int j; |
+ char rdc[256]; |
+ char rdcsel[256]; |
+ |
+ j = selectCh->GetNumber(); |
+ |
+ printf("Found %d data points.\n", (int)meas_data->GetEntries()); |
+ |
+ gCanvas->cd(); |
+ double range[4]; |
+ range[0] = adcMinRange->GetNumber(); |
+ range[1] = adcMaxRange->GetNumber(); |
+ range[2] = tdcMinwindow->GetNumber(); |
+ range[3] = tdcMaxwindow->GetNumber(); |
+ |
+ if(histtype == 0) |
+ { |
+ if( range[0] == range[1] ) |
+ sprintf(rdc, "ADC%d>>%s", j, histname); |
+ else |
+ sprintf(rdc, "ADC%d>>%s(%d,%lf,%lf)", j, histname, (int)(range[1]-range[0]), range[0]-0.5, range[1]-0.5); |
+ |
+ sprintf(rdcsel, "(TDC%d>%lf)&&(TDC%d<%lf)", j, range[2]*tdctimeconversion, j, range[3]*tdctimeconversion); |
+ meas_data->Draw(rdc, rdcsel); |
+ |
+ sprintf(rdc, "ADC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);ADC;", j, evtheader.biasvolt, range[2], range[3]); |
+ TH1F *histtemp = (TH1F*)gCanvas->GetPrimitive(histname); |
+ if(!cleanPlots) |
+ histtemp->SetTitle(rdc); |
+ else |
+ histtemp->SetTitle(";ADC;"); |
+ histtemp->GetXaxis()->SetLabelSize(0.025); |
+ histtemp->GetXaxis()->CenterTitle(kTRUE); |
+ histtemp->GetYaxis()->SetLabelSize(0.025); |
+ if(cleanPlots) |
+ { |
+ TGaxis *yax = (TGaxis*)histtemp->GetYaxis(); |
+ yax->SetMaxDigits(4); |
+ } |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ if( yMinRange->GetNumber() != yMaxRange->GetNumber() ) |
+ { |
+ if( (logscale->IsDown()) && (yMinRange->GetNumber() <= 0) ) |
+ { |
+ histtemp->GetYaxis()->SetRangeUser(0.5, yMaxRange->GetNumber()); |
+ yMinRange->SetNumber(0.5); |
+ logchange = 1; |
+ } |
+ else |
+ { |
+ gCanvas->SetLogy(kFALSE); |
+ if(logchange == 1) |
+ { |
+ yMinRange->SetNumber(0.0); |
+ logchange = 0; |
+ } |
+ histtemp->GetYaxis()->SetRangeUser(yMinRange->GetNumber(), yMaxRange->GetNumber()); |
+ } |
+ } |
+ |
+ TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats"); |
+ if(!cleanPlots) |
+ { |
+ stats->SetX1NDC(0.84); stats->SetX2NDC(0.97); |
+ stats->SetY1NDC(0.87); stats->SetY2NDC(0.97); |
+ } |
+ else |
+ { |
+ stats->SetX1NDC(1.1); stats->SetX2NDC(1.3); |
+ stats->SetY1NDC(1.1); stats->SetY2NDC(1.3); |
+ } |
+ } |
+ else if(histtype == 1) |
+ { |
+ if( range[0] == range[1] ) |
+ sprintf(rdc, "(TDC%d/%lf)>>%s", j, tdctimeconversion, histname); |
+ else |
+ sprintf(rdc, "(TDC%d/%lf)>>%s(%d,%lf,%lf)", j, tdctimeconversion, histname, (int)((range[3]-range[2])*tdctimeconversion), range[2], range[3]); |
+ sprintf(rdcsel, "(TDC%d>%lf)&&(TDC%d<%lf)", j, range[2]*tdctimeconversion, j, range[3]*tdctimeconversion); |
+ meas_data->Draw(rdc, rdcsel); |
+ |
+ sprintf(rdc, "TDC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);Time (TDC channel) [ns];", j, evtheader.biasvolt, range[2], range[3]); |
+ TH1F *histtemp = (TH1F*)gCanvas->GetPrimitive(histname); |
+ if(!cleanPlots) |
+ histtemp->SetTitle(rdc); |
+ else |
+ histtemp->SetTitle(";Time (TDC channel) [ns];"); |
+ histtemp->GetXaxis()->SetLabelSize(0.025); |
+ histtemp->GetXaxis()->CenterTitle(kTRUE); |
+ histtemp->GetYaxis()->SetLabelSize(0.025); |
+ if(cleanPlots) |
+ { |
+ TGaxis *yax = (TGaxis*)histtemp->GetYaxis(); |
+ yax->SetMaxDigits(4); |
+ } |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ if( yMinRange->GetNumber() != yMaxRange->GetNumber() ) |
+ { |
+ if( (logscale->IsDown()) && (yMinRange->GetNumber() <= 0) ) |
+ { |
+ histtemp->GetYaxis()->SetRangeUser(0.5, yMaxRange->GetNumber()); |
+ yMinRange->SetNumber(0.5); |
+ logchange = 1; |
+ } |
+ else |
+ { |
+ gCanvas->SetLogy(kFALSE); |
+ if(logchange == 1) |
+ { |
+ yMinRange->SetNumber(0.0); |
+ logchange = 0; |
+ } |
+ histtemp->GetYaxis()->SetRangeUser(yMinRange->GetNumber(), yMaxRange->GetNumber()); |
+ } |
+ } |
+ |
+ TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats"); |
+ if(!cleanPlots) |
+ { |
+ stats->SetX1NDC(0.84); stats->SetX2NDC(0.97); |
+ stats->SetY1NDC(0.87); stats->SetY2NDC(0.97); |
+ } |
+ else |
+ { |
+ stats->SetX1NDC(1.1); stats->SetX2NDC(1.3); |
+ stats->SetY1NDC(1.1); stats->SetY2NDC(1.3); |
+ } |
+ } |
+ else if(histtype == 2) |
+ { |
+ if( ((range[0] == range[1]) && (range[2] == range[3])) || (range[2] == range[3]) || (range[0] == range[1]) ) |
+ sprintf(rdc, "(TDC%d/%lf):ADC%d>>%s", j, tdctimeconversion, j, histname); |
+ else |
+ sprintf(rdc, "(TDC%d/%lf):ADC%d>>%s(%d,%lf,%lf,%d,%lf,%lf)", j, tdctimeconversion, j, histname, (int)(range[1]-range[0])/2, range[0]-0.5, range[1]-0.5, (int)((range[3]-range[2])*tdctimeconversion)/2, range[2], range[3]); |
+ meas_data->Draw(rdc,"","COLZ"); |
+ |
+ sprintf(rdc, "ADC/TDC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);ADC;TDC", j, evtheader.biasvolt, range[2], range[3]); |
+ TH2F *histtemp = (TH2F*)gCanvas->GetPrimitive(histname); |
+ if(!cleanPlots) |
+ histtemp->SetTitle(rdc); |
+ else |
+ histtemp->SetTitle(";ADC;Time (TDC channel) [ns]"); |
+ histtemp->GetXaxis()->SetLabelSize(0.025); |
+ histtemp->GetXaxis()->CenterTitle(kTRUE); |
+ histtemp->GetYaxis()->SetLabelSize(0.025); |
+ histtemp->GetYaxis()->CenterTitle(kTRUE); |
+ histtemp->GetYaxis()->SetTitleOffset(1.35); |
+ if(cleanPlots) |
+ { |
+ TGaxis *yax = (TGaxis*)histtemp->GetYaxis(); |
+ yax->SetMaxDigits(4); |
+ } |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats"); |
+// stats->SetOptStat(0); |
+ stats->SetX1NDC(1.1); stats->SetX2NDC(1.3); |
+ stats->SetY1NDC(1.1); stats->SetY2NDC(1.3); |
+ |
+ TPaletteAxis *gpalette = (TPaletteAxis*)histtemp->GetListOfFunctions()->FindObject("palette"); |
+ gpalette->SetLabelSize(0.022); |
+ } |
+ |
+ if(histtype < 2) |
+ { |
+ if( logscale->IsDown() ) |
+ gCanvas->SetLogy(kTRUE); |
+ else if( !logscale->IsDown() ) |
+ gCanvas->SetLogy(kFALSE); |
+ } |
+ else |
+ gCanvas->SetLogy(kFALSE); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ // If you close the opened file, the data can't be accessed by other functions |
+} |
+ |
+// Create a 2D surface plot and plot it |
+void TGAppMainFrame::MakeSurfPlot(TList *files) |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ int j, k = 0, m = 0, n = 0; |
+ char ctemp[256]; |
+ TCanvas *gCanvas = histCanvas->GetCanvas(); |
+ TTree *header_data, *meas_data; |
+ double *integralCount; |
+ double *surfx, *surfy; |
+ double xsurfmin = 0, ysurfmin = 0; |
+ integralCount = new double[nrfiles]; |
+ for(int i = 0; i < (int)nrfiles; i++) integralCount[i] = 0; |
+ surfx = new double[nrfiles]; |
+ surfy = new double[nrfiles]; |
+ int nrentries; |
+ TGraph2D *gScan2D; |
+ gScan2D = new TGraph2D(); |
+ |
+/* int zProg = 0; |
+ float progVal; |
+ curProgress->SetPosition(zProg);*/ |
+ |
+ char exportname[256]; |
+ |
+ if(multiSelect->IsOn()) |
+ { |
+ printf("Creating a surface plot. Please wait...\n"); |
+ fileList->GetSelectedEntries(files); |
+ if(files) |
+ { |
+ busyLabel->Enable(); |
+ |
+ for(int i = 0; i < (int)nrfiles; i++) |
+ { |
+ if(files->At(i)) |
+ { |
+ n++; |
+// printf("Filename: %s\n", files->At(i)->GetTitle()); |
+ |
+ sprintf(ctemp, "%s", files->At(i)->GetTitle()); |
+ inroot = new TFile(ctemp, "READ"); |
+ |
+ inroot->GetObject("header_data", header_data); |
+ inroot->GetObject("meas_data", meas_data); |
+ |
+ // Reading the header |
+ header_data->SetBranchAddress("xpos", &evtheader.xpos); |
+ header_data->GetEntry(0); |
+ header_data->SetBranchAddress("ypos", &evtheader.ypos); |
+ header_data->GetEntry(0); |
+ |
+ char rdc[256]; |
+ j = selectCh->GetNumber(); |
+ double rangetdc[2]; |
+ rangetdc[0] = tdcMinwindow->GetNumber(); |
+ rangetdc[1] = tdcMaxwindow->GetNumber(); |
+ |
+ k = 0; |
+ m = 0; |
+ |
+ // Reading the data |
+ for(int i = 0; i < meas_data->GetEntries(); i++) |
+ { |
+ sprintf(rdc, "ADC%d", j); |
+ meas_data->SetBranchAddress(rdc, &evtdata.adcdata[j]); |
+ meas_data->GetEntry(i); |
+ |
+ sprintf(rdc, "TDC%d", j); |
+ meas_data->SetBranchAddress(rdc, &evtdata.tdcdata[j]); |
+ meas_data->GetEntry(i); |
+ |
+ // If our data point is inside the TDC window |
+ if( ((double)evtdata.tdcdata[j]/tdctimeconversion >= rangetdc[0]) && ((double)evtdata.tdcdata[j]/tdctimeconversion <= rangetdc[1]) ) |
+ { |
+ k++; |
+ m += evtdata.adcdata[j]; |
+ } |
+ } |
+ |
+ integralCount[n-1] += ((double)m)/((double)k); |
+ if(n == 1) |
+ { |
+ xsurfmin = evtheader.xpos; |
+ ysurfmin = evtheader.ypos; |
+ } |
+ surfx[n-1] = (double)(evtheader.xpos-xsurfmin)*lenconversion; |
+ surfy[n-1] = (double)(evtheader.ypos-ysurfmin)*lenconversion; |
+ |
+/* if( n == (((files->GetSize())*zProg)/20)+1 ) // divide by 20 because files->GetSize() gives a double value of the files selected |
+ { |
+ progVal = (float)n; |
+ curProgress->SetPosition(progVal); |
+ zProg++; |
+ printf("Progress = %lf\n", progVal); |
+ }*/ |
+ |
+ delete inroot; |
+ } |
+ } |
+ |
+ busyLabel->Disable(); |
+ |
+ nrentries = n; |
+ printf("%d files were selected.\n", nrentries); |
+ |
+ for(int i = 0; i < nrentries; i++) |
+ { |
+// printf("At position (%d,%d), the ADC integral is: %lf.\n", surfx[i], surfy[i], integralCount[i]); |
+ gScan2D->SetPoint(i, surfx[i], surfy[i], integralCount[i]); |
+ } |
+ gCanvas->cd(); |
+ gScan2D->Draw("COLZ"); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ gScan2D->GetXaxis()->SetTitle("X [#mum]"); |
+ gScan2D->GetXaxis()->CenterTitle(kTRUE); |
+ gScan2D->GetXaxis()->SetLabelSize(0.022); |
+ gScan2D->GetXaxis()->SetRangeUser(surfx[0], surfx[nrentries-1]); |
+// j = 500+(int)((surfx[nrentries-1]-surfx[0])/(surfx[1]-surfx[0])); |
+// if(j > 510) j = 510; |
+ gScan2D->GetXaxis()->SetNdivisions(510, kTRUE); |
+ gScan2D->GetYaxis()->SetTitle("Y [#mum]"); |
+ gScan2D->GetYaxis()->SetTitleOffset(1.3); |
+ gScan2D->GetYaxis()->CenterTitle(kTRUE); |
+ gScan2D->GetYaxis()->SetLabelSize(0.022); |
+ gScan2D->GetYaxis()->SetRangeUser(surfy[0], surfy[nrentries-1]); |
+// j = 500+(int)((surfy[nrentries-1]-surfy[0])/(surfy[(int)((surfx[nrentries-1]-surfx[0])/(surfx[1]-surfx[0])+1)]-surfy[0])); |
+// if(j > 510) j = 510; |
+ gScan2D->GetYaxis()->SetNdivisions(510, kTRUE); |
+ |
+ TGaxis *yax = (TGaxis*)gScan2D->GetYaxis(); |
+ yax->SetMaxDigits(4); |
+ |
+ if(!cleanPlots) |
+ gScan2D->SetTitle("Surface scan"); |
+ else |
+ gScan2D->SetTitle(); |
+ |
+// TPaletteAxis *gpalette = (TPaletteAxis*)gScan2D->GetListOfFunctions()->FindObject("palette"); |
+// gpalette->SetLabelSize(0.022); |
+ |
+ gCanvas->Modified(); |
+ gCanvas->Update(); |
+ |
+ remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp); |
+ sprintf(exportname, "%s_surfscan.pdf", ctemp); |
+ gCanvas->SaveAs(exportname); |
+ } |
+ } |
+ else |
+ { |
+ printf("To make a 2D surface scan plot, select multiple root files.\n"); |
+ change2Dsurf->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF); |
+ } |
+ |
+ delete[] surfx; |
+ delete[] surfy; |
+ delete[] integralCount; |
+} |
+ |
+// Change histogram when changing the channel |
+void TGAppMainFrame::ChangeChannel() |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ TList *files; |
+ |
+ if( nrfiles > 0 ) |
+ { |
+ // check the newly selected file/files and return its name/their names |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ if(files) |
+ { |
+ for(int i = 0; i < (int)nrfiles; i++) |
+ { |
+ if(files->At(i)) |
+ { |
+ if(debugSig) |
+ printf("Filename: %s\n", files->At(i)->GetTitle()); |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+// Setting a predetermined X range |
+void TGAppMainFrame::SetHistRange() |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ |
+ if(nrfiles > 0) |
+ { |
+ TList *files; |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ if(files) |
+ { |
+ for(int i = 0; i < (int)nrfiles; i++) |
+ { |
+ if(files->At(i)) |
+ { |
+ if(debugSig) |
+ printf("Filename: %s\n", files->At(i)->GetTitle()); |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1); |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) ) |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+// Changing the histogram type to display |
+void TGAppMainFrame::ChangeHisttype(int type) |
+{ |
+ TGTextButton *pressedB = new TGTextButton(); |
+ int menuID = 0; |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ |
+ // ADC histogram |
+ if(type == 0) |
+ { |
+ pressedB = changeADC; |
+ menuID = M_ANALYSIS_HISTTYPE_1DADC; |
+ |
+ changeTDC->SetDown(kFALSE); |
+ changeADCTDC->SetDown(kFALSE); |
+ change2Dsurf->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF); |
+ } |
+ // TDC histogram |
+ else if(type == 1) |
+ { |
+ pressedB = changeTDC; |
+ menuID = M_ANALYSIS_HISTTYPE_1DTDC; |
+ |
+ changeADC->SetDown(kFALSE); |
+ changeADCTDC->SetDown(kFALSE); |
+ change2Dsurf->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF); |
+ } |
+ // ADC vs. TDC histogram |
+ else if(type == 2) |
+ { |
+ pressedB = changeADCTDC; |
+ menuID = M_ANALYSIS_HISTTYPE_2D; |
+ |
+ changeADC->SetDown(kFALSE); |
+ changeTDC->SetDown(kFALSE); |
+ change2Dsurf->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF); |
+ } |
+ // Surface scan plot |
+ else if(type == 3) |
+ { |
+ pressedB = change2Dsurf; |
+ menuID = M_ANALYSIS_HISTTYPE_SURF; |
+ |
+ changeADC->SetDown(kFALSE); |
+ changeTDC->SetDown(kFALSE); |
+ changeADCTDC->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC); |
+ fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D); |
+ } |
+ |
+ if( fMenuHisttype->IsEntryChecked(menuID) ) |
+ { |
+ pressedB->SetDown(kFALSE); |
+ fMenuHisttype->UnCheckEntry(menuID); |
+ } |
+ else if( !fMenuHisttype->IsEntryChecked(menuID) ) |
+ { |
+ pressedB->SetDown(kTRUE); |
+ fMenuHisttype->CheckEntry(menuID); |
+ } |
+ |
+ if(nrfiles > 0) |
+ { |
+ // Still need to add the switch!!! |
+ TList *files; |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ |
+ if(type < 3) |
+ DisplayHistogram( (char*)(files->At(0)->GetTitle()), type); |
+ else if(type == 3) |
+ MakeSurfPlot( files ); |
+ } |
+} |
+ |
+// Changing the histogram type to display |
+void TGAppMainFrame::HistogramExport() |
+{ |
+ unsigned int nrfiles = fileList->GetNumberOfEntries(); |
+ TList *files; |
+ TCanvas *gCanvas = histCanvas->GetCanvas(); |
+ |
+ char exportname[256]; |
+ char ctemp[256]; |
+ |
+ if(nrfiles > 0) |
+ { |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ if(files) |
+ { |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_SURF) ) // for the surface scan, the plot from all selected files is already created |
+ { |
+ remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp); |
+ sprintf(exportname, "%s_surfscan.pdf", ctemp); |
+ gCanvas->SaveAs(exportname); |
+ } |
+ else |
+ { |
+ for(int i = 0; i < (int)nrfiles; i++) |
+ { |
+ if(files->At(i)) |
+ { |
+ remove_ext((char*)files->At(i)->GetTitle(), ctemp); |
+ |
+ if(debugSig) |
+ printf("Filename: %s\n", files->At(i)->GetTitle()); |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) ) |
+ { |
+ sprintf(exportname, "%s_adc%d.pdf", ctemp, (int)selectCh->GetNumber()); |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0); |
+ } |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) ) |
+ { |
+ sprintf(exportname, "%s_tdc%d.pdf", ctemp, (int)selectCh->GetNumber()); |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1); |
+ } |
+ else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) ) |
+ { |
+ sprintf(exportname, "%s_adctdc%d.pdf", ctemp, (int)selectCh->GetNumber()); |
+ DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2); |
+ } |
+ |
+ gCanvas->SaveAs(exportname); |
+ } |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+//--------------------------------------------------------------- |
+// Main window constructor definition (& layout) |
+ |
+TGAppMainFrame::TGAppMainFrame(const TGWindow *p, int w, int h) |
+{ |
+ gDaq = new daq(); |
+ gScopeDaq = new daqscope(); |
+ |
+ // Define the main window and menubar |
+ fMain = new TGMainFrame(p, w, h, kVerticalFrame); // vertical frame split into menubar and main frame |
+ fMenuBar = new TGMdiMenuBar(fMain, 10, 10); // just prepare menubar, draw it with InitMenu() |
+ fMain->AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX)); |
+ |
+ // Define the main frame where opened subwindows will appear |
+ fMainFrame = new TGMdiMainFrame(fMain, fMenuBar, 300, 300); |
+ fMain->AddFrame(fMainFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); |
+ |
+ // Initialize the menubar the initial measurement layout subwindows and display the main window |
+ InitMenu(); |
+ MeasurementLayout(); |
+ fMain->SetWindowName(WINDOW_NAME); |
+ fMain->MapSubwindows(); |
+ fMain->MapWindow(); |
+ fMain->Layout(); |
+ GetPosition(); |
+ GetVoltOut(); |
+} |
+ |
+//--------------------------------------------------------------- |
+// Event handler for menubar actions |
+ |
+void TGAppMainFrame::HandleMenu(Int_t id) |
+{ |
+ TList *files; |
+ |
+ switch (id) { |
+ case M_FILE_NEW: |
+ // Clear any values and histogram |
+ break; |
+ |
+ case M_FILE_EXIT: |
+ CloseWindow(); |
+ break; |
+ |
+ case M_ANALYSIS_HISTTYPE_1DADC: |
+ // Toggles the ADC button |
+ ChangeHisttype(0); |
+ break; |
+ |
+ case M_ANALYSIS_HISTTYPE_1DTDC: |
+ ChangeHisttype(1); |
+ break; |
+ |
+ case M_ANALYSIS_HISTTYPE_2D: |
+ ChangeHisttype(2); |
+ break; |
+ |
+ case M_ANALYSIS_HISTTYPE_SURF: |
+ ChangeHisttype(3); |
+ break; |
+ |
+ case M_ANALYSIS_FIT: |
+ // Fit spectrum |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ |
+ if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) && (files->GetSize() > 0) ) |
+ FitSpectrum(files, 1); |
+ break; |
+ |
+ case M_ANALYSIS_FITSEL: |
+ // Fit all spectra |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ |
+ if( (fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC)) && (files->GetSize() > 1) ) |
+ FitSpectrum(files, files->GetSize()); |
+ break; |
+ |
+ case M_ANALYSIS_INTEGX: |
+ // Integrate the current spectra |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ |
+ IntegSpectrum(files, 1); |
+ break; |
+ |
+ case M_ANALYSIS_INTEGY: |
+ // Integrate the current spectra |
+ files = new TList(); |
+ fileList->GetSelectedEntries(files); |
+ |
+ IntegSpectrum(files, 2); |
+ break; |
+ |
+ case M_WINDOW_HOR: |
+ fMainFrame->TileHorizontal(); |
+ break; |
+ |
+ case M_WINDOW_VERT: |
+ fMainFrame->TileVertical(); |
+ break; |
+ |
+ case M_HELP_ABOUT: |
+ About(); |
+ break; |
+ |
+ default: |
+ fMainFrame->SetCurrent(id); |
+ break; |
+ } |
+} |
+ |
+//--------------------------------------------------------------- |
+// Initialize the main window menu |
+ |
+void TGAppMainFrame::InitMenu() |
+{ |
+ fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0); |
+ |
+ // Popup menu in menubar for File controls |
+ fMenuFile = new TGPopupMenu(gClient->GetRoot()); // adds a new popup menu to the menubar |
+ fMenuFile->AddEntry(new TGHotString("&New Measurement"), M_FILE_NEW); |
+ fMenuFile->AddSeparator(); |
+ fMenuFile->AddEntry(new TGHotString("E&xit"), M_FILE_EXIT); |
+ |
+ // Popup menu in menubar for Analysis controls |
+ fMenuHisttype = new TGPopupMenu(gClient->GetRoot()); // adds a cascade menu that will be incorporated into analysis controls |
+ fMenuHisttype->AddEntry(new TGHotString("1D &ADC histogram"), M_ANALYSIS_HISTTYPE_1DADC); |
+ fMenuHisttype->AddEntry(new TGHotString("1D &TDC histogram"), M_ANALYSIS_HISTTYPE_1DTDC); |
+ fMenuHisttype->AddEntry(new TGHotString("&2D ADC vs. TDC histogram"), M_ANALYSIS_HISTTYPE_2D); |
+ fMenuHisttype->AddEntry(new TGHotString("2D &surface scan plot"), M_ANALYSIS_HISTTYPE_SURF); |
+ |
+ fMenuAnalysis = new TGPopupMenu(gClient->GetRoot()); // adds a new popup menu to the menubar |
+ fMenuAnalysis->AddPopup(new TGHotString("&Histogram type"), fMenuHisttype); |
+ |
+ fMenuAnalysis->AddEntry(new TGHotString("&Fit spectrum"), M_ANALYSIS_FIT); |
+ fMenuAnalysis->AddEntry(new TGHotString("Fit &all selected"), M_ANALYSIS_FITSEL); |
+ fMenuAnalysis->AddEntry(new TGHotString("Integrate spectrum (&X direction)"), M_ANALYSIS_INTEGX); |
+ fMenuAnalysis->AddEntry(new TGHotString("Integrate spectrum (&Y direction)"), M_ANALYSIS_INTEGY); |
+ |
+ // Popup menu in menubar for Window controls |
+ fMenuWindow = new TGPopupMenu(gClient->GetRoot()); // adds a new popup menu to the menubar |
+ fMenuWindow->AddEntry(new TGHotString("Tile &Horizontally"), M_WINDOW_HOR); |
+ fMenuWindow->AddEntry(new TGHotString("Tile &Vertically"), M_WINDOW_VERT); |
+ fMenuWindow->AddPopup(new TGHotString("&Windows"), fMainFrame->GetWinListMenu()); |
+ |
+ // Popup menu in menubar for Help controls |
+ fMenuHelp = new TGPopupMenu(gClient->GetRoot()); |
+ fMenuHelp->AddEntry(new TGHotString("&About"), M_HELP_ABOUT); |
+ |
+ // Connect all menu items with actions - handled by HandleMenu() |
+ fMenuFile->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)"); |
+ fMenuAnalysis->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)"); |
+ fMenuWindow->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)"); |
+ fMenuHelp->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)"); |
+ |
+ // Draw the created popup menus on the menubar |
+ fMenuBar->AddPopup(new TGHotString("&File"), fMenuFile, fMenuBarItemLayout); |
+ fMenuBar->AddPopup(new TGHotString("&Analysis"),fMenuAnalysis,fMenuBarItemLayout); |
+ fMenuBar->AddPopup(new TGHotString("&Windows"),fMenuWindow,fMenuBarItemLayout); |
+ fMenuBar->AddPopup(new TGHotString("&Help"), fMenuHelp, fMenuBarItemLayout); |
+} |
+ |
+//--------------------------------------------------------------- |
+// Set the measurement subwindow layout |
+ |
+void TGAppMainFrame::MeasurementLayout() |
+{ |
+ TGMdiFrame *mdiFrame; |
+ |
+ // Generic horizontal and vertical frames |
+ TGHorizontalFrame *fH1, *fH2, *fH3; |
+ TGVerticalFrame *fV1; |
+ TGGroupFrame *fG1; |
+ TGLabel *lab; |
+ TGCompositeFrame *fT1; |
+ |
+ // Sizes of internal group and subwindow structures |
+ int subwin[2]; |
+ int subgroup[2]; |
+ |
+// Settings pane --------------------------------------------------------------------------- |
+ subwin[0] = (winWidth/6)-5; subwin[1] = 3*((winHeight/5)-5)-10; |
+ settingsPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]); |
+ mdiFrame = settingsPane->GetMdiFrame(); |
+ |
+ // Check button to toggle voltage scan |
+ voltscanOn = new TGCheckButton(mdiFrame, "Voltage scan ON/OFF"); |
+ voltscanOn->Resize(50,22); |
+ voltscanOn->SetState(kButtonUp); |
+ mdiFrame->AddFrame(voltscanOn, f0centerx); |
+ |
+ // Check button to toggle surface scan |
+ surfscanOn = new TGCheckButton(mdiFrame, "Surface scan ON/OFF"); |
+ surfscanOn->Resize(50,22); |
+ surfscanOn->SetState(kButtonUp); |
+ mdiFrame->AddFrame(surfscanOn, f0centerx); |
+ |
+ // Check button to toggle Z direction scan |
+ zscanOn = new TGCheckButton(mdiFrame, "Z-axis scan ON/OFF"); |
+ zscanOn->Resize(50,22); |
+ zscanOn->SetState(kButtonUp); |
+ mdiFrame->AddFrame(zscanOn, f0centerx); |
+ |
+ // Check button to toggle (open) the histogram window |
+// histogramOn = new TGCheckButton(mdiFrame, "Histogram display ON/OFF"); |
+// histogramOn->Resize(50,22); |
+// histogramOn->SetState(kButtonUp); |
+// mdiFrame->AddFrame(histogramOn, f0centerx); |
+ |
+ subgroup[0] = subwin[0]-10; |
+ // Hard limit for maximum voltage we can set |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Voltage limit:"); |
+ fH1->AddFrame(lab, f0center2d); |
+ vHardlimit = new TGNumberEntry(fH1, 70.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber); |
+ vHardlimit->Resize(80,22); |
+ fH1->AddFrame(vHardlimit, f0center2d); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ // Number of used channels |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Nr. of channels:"); |
+ fH1->AddFrame(lab, f0center2d); |
+ NCH = new TGNumberEntry(fH1, 1, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 8); |
+ NCH->Resize(40,22); |
+ fH1->AddFrame(NCH, f0center2d); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ // Check button to toggle plots with additional information or clean plots |
+ cleanOn = new TGCheckButton(mdiFrame, "Clean plots ON/OFF"); |
+ cleanOn->Resize(50,22); |
+ cleanOn->SetState(kButtonDown); |
+ cleanPlots = 1; |
+ mdiFrame->AddFrame(cleanOn, f0centerx); |
+ |
+ // Button and textbox to enter the oscilloscope IP address |
+ lab = new TGLabel(mdiFrame, "Scope IP:"); |
+ mdiFrame->AddFrame(lab, f0); |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ oscIP = new TGTextEntry(fH1, "178.172.43.157"); |
+ oscIP->Resize(110,22); |
+ fH1->AddFrame(oscIP, f0); |
+ oscConnect = new TGTextButton(fH1, "Connect"); |
+ oscConnect->SetTextJustify(36); |
+ oscConnect->SetWrapLength(-1); |
+ oscConnect->Resize(60,22); |
+ fH1->AddFrame(oscConnect, f0); |
+ oscOn = 0; |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ // Laser settings (freq., tune, ND filter) |
+ lab = new TGLabel(mdiFrame, "Laser settings:"); |
+ mdiFrame->AddFrame(lab, f0); |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ laserInfo = new TGTextEntry(fH1, "kHz, tune, ND"); |
+ fH1->AddFrame(laserInfo, f2); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ mdiFrame->SetMdiHints(kMdiMinimize); |
+ mdiFrame->SetWindowName("Settings pane"); |
+ mdiFrame->MapSubwindows(); |
+ mdiFrame->Layout(); |
+ mdiFrame->Move(0,0); |
+// Settings pane --------------------------------------------------------------------------- |
+ |
+// Main window ----------------------------------------------------------------------------- |
+ subwin[0] = 3*((winWidth/6)-5); subwin[1] = 3*((winHeight/5)-5)-10; |
+ mainSubwindow = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]); |
+ mdiFrame = mainSubwindow->GetMdiFrame(); |
+ |
+ // Voltage and position tab |
+ subgroup[0] = 2*subwin[0]/5-12; |
+ subgroup[1] = (subwin[1]+15)/2+5; |
+ setTab = new TGTab(mdiFrame, subgroup[0], subgroup[1]); |
+ |
+ fT1 = setTab->AddTab("Voltage + Position"); |
+ |
+ fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight); |
+ // Left pane (Bias voltage controls) |
+ fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1], kFixedWidth | kFixedHeight); |
+ fG1 = new TGGroupFrame(fV1, "Bias voltage controls"); |
+ |
+ // Output voltage supply channel |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "Output channel:"); |
+ fH2->AddFrame(lab, f0center2d); |
+ vOutCh = new TGComboBox(fH2, 200); |
+ vOutCh->AddEntry("1", 0); |
+ vOutCh->AddEntry("2", 1); |
+ vOutCh->AddEntry("3", 2); |
+ vOutCh->AddEntry("4", 3); |
+ vOutCh->AddEntry("5", 4); |
+ vOutCh->AddEntry("6", 5); |
+ vOutCh->AddEntry("7", 6); |
+ vOutCh->AddEntry("8", 7); |
+ vOutCh->AddEntry("101", 8); |
+ vOutCh->AddEntry("102", 9); |
+ vOutCh->AddEntry("103", 10); |
+ vOutCh->AddEntry("104", 11); |
+ vOutCh->AddEntry("105", 12); |
+ vOutCh->AddEntry("106", 13); |
+ vOutCh->AddEntry("107", 14); |
+ vOutCh->AddEntry("108", 15); |
+ vOutCh->Resize(50,22); |
+ vOutCh->Select(0); |
+ fH2->AddFrame(vOutCh, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Output voltage setting |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "Output voltage:"); |
+ fH2->AddFrame(lab, f0center2d); |
+ vOut = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, 0, vHardlimit->GetNumber()); |
+ vOut->Resize(80,22); |
+ fH2->AddFrame(vOut, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ vOutOnOff = new TGCheckButton(fH2, "Output ON/OFF"); |
+ vOutOnOff->Resize(subgroup[0]-10,22); |
+ vOutOnOff->SetState(kButtonUp); |
+ fH2->AddFrame(vOutOnOff, f0centerx); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Set, get and reset voltage buttons |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ fH3 = new TGHorizontalFrame(fH2, subgroup[0], 30); |
+ vOutSet = new TGTextButton(fH3, "Set"); |
+ vOutSet->SetTextJustify(36); |
+ vOutSet->SetWrapLength(-1); |
+ vOutSet->Resize(60,22); |
+ fH3->AddFrame(vOutSet, f0); |
+ vOutGet = new TGTextButton(fH3, "Get"); |
+ vOutGet->SetTextJustify(36); |
+ vOutGet->SetWrapLength(-1); |
+ vOutGet->Resize(60,22); |
+ fH3->AddFrame(vOutGet, f0); |
+ vOutReset = new TGTextButton(fH3, "Reset"); |
+ vOutReset->SetTextJustify(36); |
+ vOutReset->SetWrapLength(-1); |
+ vOutReset->Resize(60,22); |
+ fH3->AddFrame(vOutReset, f0); |
+ fH2->AddFrame(fH3, f0centerx); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Voltage scan controls |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "V (min):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ vOutStart = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber); |
+ vOutStart->Resize(80,22); |
+ fH2->AddFrame(vOutStart, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "V (max):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ vOutStop = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber); |
+ vOutStop->Resize(80,22); |
+ fH2->AddFrame(vOutStop, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "V (step):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ vOutStep = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber); |
+ vOutStep->Resize(80,22); |
+ fH2->AddFrame(vOutStep, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fV1->AddFrame(fG1, f1); |
+ // Left pane (Bias voltage controls) |
+ fH1->AddFrame(fV1, f0); |
+ |
+ // Right pane (Table position controls) |
+ subgroup[0] = 3*subwin[0]/5-12; |
+ fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1], kFixedWidth | kFixedHeight); |
+ fG1 = new TGGroupFrame(fV1, "Table position controls"); |
+ |
+ // X, Y and Z positions |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "X:"); |
+ fH2->AddFrame(lab, f0center2d); |
+ xPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ xPos->Resize(80,22); |
+ fH2->AddFrame(xPos, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Z (min):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ zPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000); |
+ zPosMin->Resize(80,22); |
+ fH2->AddFrame(zPosMin, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "Y:"); |
+ fH2->AddFrame(lab, f0center2d); |
+ yPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ yPos->Resize(80,22); |
+ fH2->AddFrame(yPos, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Z (max):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ zPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000); |
+ zPosMax->Resize(80,22); |
+ fH2->AddFrame(zPosMax, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0] ,30); |
+ lab = new TGLabel(fH2, "Z:"); |
+ fH2->AddFrame(lab, f0center2d); |
+ zPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000); |
+ zPos->Resize(80,22); |
+ fH2->AddFrame(zPos, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Z (step):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ zPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); |
+ zPosStep->Resize(80,22); |
+ fH2->AddFrame(zPosStep, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Set, Get and Home the table position |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ fH3 = new TGHorizontalFrame(fH2, subgroup[0], 30); |
+ positionSet = new TGTextButton(fH3, "Set"); |
+ positionSet->SetTextJustify(36); |
+ positionSet->SetWrapLength(-1); |
+ positionSet->Resize(60,22); |
+ fH3->AddFrame(positionSet, f0); |
+ positionGet = new TGTextButton(fH3, "Get"); |
+ positionGet->SetTextJustify(36); |
+ positionGet->SetWrapLength(-1); |
+ positionGet->Resize(60,22); |
+ fH3->AddFrame(positionGet, f0); |
+ positionHome = new TGTextButton(fH3, "Home"); |
+ positionHome->SetTextJustify(36); |
+ positionHome->SetWrapLength(-1); |
+ positionHome->Resize(60,22); |
+ fH3->AddFrame(positionHome, f0); |
+ fH2->AddFrame(fH3, f0centerx); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Position scan controls |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "X (min):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ xPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ xPosMin->Resize(80,22); |
+ fH2->AddFrame(xPosMin, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Y (min):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ yPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ yPosMin->Resize(80,22); |
+ fH2->AddFrame(yPosMin, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "X (max):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ xPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ xPosMax->Resize(80,22); |
+ fH2->AddFrame(xPosMax, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Y (max):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ yPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000); |
+ yPosMax->Resize(80,22); |
+ fH2->AddFrame(yPosMax, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "X (step):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ xPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); |
+ xPosStep->Resize(80,22); |
+ fH2->AddFrame(xPosStep, f0center2d); |
+ |
+ lab = new TGLabel(fH2, "Y (step):"); |
+ fH2->AddFrame(lab, f0center2d); |
+ yPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); |
+ yPosStep->Resize(80,22); |
+ fH2->AddFrame(yPosStep, f0center2d); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ fV1->AddFrame(fG1, f1); |
+ // Right pane (Table position controls) |
+ fH1->AddFrame(fV1, f0); |
+ fT1->AddFrame(fH1, f1); |
+ |
+ // Waveform tab |
+ fT1 = setTab->AddTab("Waveform"); |
+ fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight); |
+ lab = new TGLabel(fH1, "Waveform controls"); |
+ fH1->AddFrame(lab, f0center2d); |
+ fT1->AddFrame(fH1, f0); |
+ |
+ // Wave measurements tab |
+ fT1 = setTab->AddTab("Measurement"); |
+ fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight); |
+ lab = new TGLabel(fH1, "Waveform measurement controls"); |
+ fH1->AddFrame(lab, f0center2d); |
+ fT1->AddFrame(fH1, f0); |
+ |
+ mdiFrame->AddFrame(setTab, f0); |
+ // Disable the two tabs regarding the Scope if not connected to one |
+ setTab->SetEnabled(1,kFALSE); |
+ setTab->SetEnabled(2,kFALSE); |
+ |
+ // Bottom pane (File controls) |
+ subgroup[0] = subwin[0]-20; |
+ subgroup[1] = subwin[1]/3-30; //2*(3*((winWidth/6)-5))/5+10; |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], subgroup[1] /*1*(3*((winWidth/6)-5))/5+15*/ , kFixedWidth | kFixedHeight); |
+ fG1 = new TGGroupFrame(fH1, "Event/Data file controls"); |
+ |
+ // Number of events |
+ fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH2, "Number of events:"); |
+ fH2->AddFrame(lab, f0centery); |
+ evtNum = new TGNumberEntry(fH2, 10000, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); |
+ evtNum->Resize(80,22); |
+ fH2->AddFrame(evtNum, f0centery); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Time stamp display |
+ fH2 = new TGHorizontalFrame(fG1,600,200); |
+ lab = new TGLabel(fH2, "Time stamp:"); |
+ fH2->AddFrame(lab, f0centery); |
+ timeStamp = new TGTextEntry(fH2, ""); |
+ timeStamp->Resize(440,22); |
+ timeStamp->SetState(kFALSE); // time stamp is read-only |
+ fH2->AddFrame(timeStamp, f0centery); |
+ fG1->AddFrame(fH2, f2); |
+ |
+ // Save to file |
+ fH2 = new TGHorizontalFrame(fG1,600,200); |
+ lab = new TGLabel(fH2, "Save to file:"); |
+ fH2->AddFrame(lab, f0centery); |
+ char *cTemp; |
+ cTemp = new char[256]; |
+ sprintf(cTemp, "./results/test%s", histExt); |
+ fileName = new TGTextEntry(fH2, cTemp); |
+ delete[] cTemp; |
+ fileName->Resize(400,22); |
+ fileName->SetState(kFALSE); |
+ fH2->AddFrame(fileName, f0centery); |
+ saveFile = new TGTextButton(fH2, "..."); |
+ saveFile->SetTextJustify(36); |
+ saveFile->SetWrapLength(-1); |
+ saveFile->Resize(80,22); |
+ fH2->AddFrame(saveFile, f0centery); |
+// mdiFrame->AddFrame(fH2, f0); |
+ fG1->AddFrame(fH2, f2); |
+ fH1->AddFrame(fG1, f1); |
+ // Bottom pane (File controls) |
+ mdiFrame->AddFrame(fH1, f0); |
+ |
+ subgroup[0] = subwin[0]-70; |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ fH2 = new TGHorizontalFrame(fH1, 3*subgroup[0]/4, 30, kFixedWidth); |
+ measStart = new TGTextButton(fH2, "Start acquisition"); |
+ measStart->SetTextJustify(36); |
+ measStart->SetWrapLength(-1); |
+ measStart->Resize(80,22); |
+ fH2->AddFrame(measStart, f0center2d); |
+ |
+ ULong_t fcolor; |
+ gClient->GetColorByName("red", fcolor); |
+ |
+ busyLabel = new TGLabel(fH2, "Busy"); //, fTextGC->GetGC(), labelfont, kChildFrame); |
+ busyLabel->SetTextJustify(36); |
+ busyLabel->Resize(80,22); |
+ busyLabel->Disable(); |
+ busyLabel->SetTextColor(fcolor); |
+ fH2->AddFrame(busyLabel, f0center2d); |
+ |
+ curProgress = new TGHProgressBar(fH2, TGProgressBar::kStandard, 150); |
+ curProgress->ShowPosition(); |
+ curProgress->SetRange(0,100); |
+ curProgress->SetBarColor("green"); |
+ fH2->AddFrame(curProgress, f0center2d); |
+ fH1->AddFrame(fH2, f0centerx); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize); |
+ mdiFrame->SetWindowName("Main measurement window"); |
+ mdiFrame->MapSubwindows(); |
+ mdiFrame->Layout(); |
+ mdiFrame->Move((winWidth/6),0); |
+// Main window ----------------------------------------------------------------------------- |
+ |
+// Histogram pane -------------------------------------------------------------------------- |
+ subwin[0] = 2*((winWidth/6)-5); subwin[1] = (int)(2.5*((winHeight/5)-5))-5; |
+ histogramPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]); |
+ mdiFrame = histogramPane->GetMdiFrame(); |
+ |
+ histCanvas = new TRootEmbeddedCanvas("histCanvas",mdiFrame,900,900); |
+ mdiFrame->AddFrame(histCanvas, f1); |
+ TCanvas *gCanvas = histCanvas->GetCanvas(); |
+ gCanvas->SetGridx(); |
+ gCanvas->SetGridy(); |
+ |
+ mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize); |
+ mdiFrame->SetWindowName("Histogram"); |
+ mdiFrame->MapSubwindows(); |
+ mdiFrame->Layout(); |
+ mdiFrame->Move(4*((winWidth/6)-5)+10,0); |
+// Histogram pane -------------------------------------------------------------------------- |
+ |
+// Histogram file selection pane ----------------------------------------------------------- |
+ subwin[0] = 4*((winWidth/6)-5); subwin[1] = 2*((winHeight/5)-5)+15; |
+ histogramPaneFile = new TGMdiSubwindow(fMainFrame, subwin[0]+5, subwin[1]); |
+ mdiFrame = histogramPaneFile->GetMdiFrame(); |
+ |
+ // Open browser for file selection |
+ subgroup[0] = subwin[0]-10; |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "File selection:"); |
+ fH1->AddFrame(lab, f0centery); |
+ |
+ selectDir = new TGTextButton(fH1, "..."); |
+ selectDir->SetTextJustify(36); |
+ selectDir->SetWrapLength(-1); |
+ selectDir->Resize(80,22); |
+ fH1->AddFrame(selectDir, f0centery); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ // List view of the opened files |
+ fileList = new TGListBox(mdiFrame,1); |
+ fileList->GetVScrollbar(); |
+ fileList->Resize(300, (subwin[1]/2)-10 ); |
+ mdiFrame->AddFrame(fileList, f2); |
+ |
+ // Multiple file selection toggle, previous/next controls and clear list |
+ fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30); |
+ multiSelect = new TGCheckButton(fH1, "Multiple file select"); |
+ multiSelect->Resize(50,22); |
+ multiSelect->SetState(kButtonUp); |
+ fH1->AddFrame(multiSelect, f0); |
+ |
+ multiSelectAll = new TGCheckButton(fH1, "Select all listed files"); |
+ multiSelectAll->Resize(50,22); |
+ multiSelectAll->SetState(kButtonUp); |
+ fH1->AddFrame(multiSelectAll, f0); |
+ |
+ TGTextButton *clearList = new TGTextButton(fH1, "Clear list"); |
+ clearList->SetTextJustify(36); |
+ clearList->SetWrapLength(-1); |
+ clearList->Resize(80,22); |
+ fH1->AddFrame(clearList, f0right); |
+ |
+ nextFile = new TGTextButton(fH1, ">>"); |
+ nextFile->SetTextJustify(36); |
+ nextFile->SetWrapLength(-1); |
+ nextFile->Resize(80,22); |
+ fH1->AddFrame(nextFile, f0right); |
+ |
+ prevFile = new TGTextButton(fH1, "<<"); |
+ prevFile->SetTextJustify(36); |
+ prevFile->SetWrapLength(-1); |
+ prevFile->Resize(80,22); |
+ fH1->AddFrame(prevFile, f0right); |
+ mdiFrame->AddFrame(fH1, f2); |
+ |
+ mdiFrame->SetMdiHints(kMdiMinimize); |
+ mdiFrame->SetWindowName("Histogram file selection"); |
+ mdiFrame->MapSubwindows(); |
+ mdiFrame->Layout(); |
+ mdiFrame->Move(0,3*((winHeight/5)-5)-5); |
+// Histogram file selection pane ----------------------------------------------------------- |
+ |
+// Histogram controls pane ----------------------------------------------------------------- |
+ subwin[0] = 2*((winWidth/6)-5); subwin[1] = (int)(2.5*((winHeight/5)-5))+10; |
+ histogramPaneCtr = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]); |
+ mdiFrame = histogramPaneCtr->GetMdiFrame(); |
+ |
+ // Control for histogram X range |
+ subgroup[0] = subwin[0]-10; |
+ fG1 = new TGGroupFrame(mdiFrame, "Histogram display"); |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "ADC range (min, max):"); |
+ fH1->AddFrame(lab, f0centery); |
+ adcMinRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber); |
+ adcMinRange->Resize(80,22); |
+ fH1->AddFrame(adcMinRange, f0centery); |
+ adcMaxRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber); |
+ adcMaxRange->Resize(80,22); |
+ fH1->AddFrame(adcMaxRange, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ // TDC window for getting data |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "TDC range (min, max):"); |
+ fH1->AddFrame(lab, f0centery); |
+ tdcMinwindow = new TGNumberEntry(fH1, 0.0, 6, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); |
+ tdcMinwindow->Resize(80,22); |
+ fH1->AddFrame(tdcMinwindow, f0centery); |
+ tdcMaxwindow = new TGNumberEntry(fH1, 221.8, 6, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber); |
+ tdcMaxwindow->Resize(80,22); |
+ fH1->AddFrame(tdcMaxwindow, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ // Y axis range settings |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Y range (min, max):"); |
+ fH1->AddFrame(lab, f0centery); |
+ yMinRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber); |
+ yMinRange->Resize(80,22); |
+ fH1->AddFrame(yMinRange, f0centery); |
+ yMaxRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber); |
+ yMaxRange->Resize(80,22); |
+ fH1->AddFrame(yMaxRange, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ // Select the channel to display |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Display channel:"); |
+ fH1->AddFrame(lab, f0centery); |
+ selectCh = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, (NCH->GetNumber())-1); |
+ selectCh->Resize(40,22); |
+ fH1->AddFrame(selectCh, f0centery); |
+ |
+ changeADC = new TGTextButton(fH1, "ADC"); |
+ changeADC->AllowStayDown(kTRUE); |
+ changeADC->SetDown(kTRUE); |
+ fMenuHisttype->CheckEntry(M_ANALYSIS_HISTTYPE_1DADC); |
+ changeADC->SetTextJustify(36); |
+ changeADC->SetWrapLength(-1); |
+ changeADC->Resize(60,22); |
+ fH1->AddFrame(changeADC, f0centery); |
+ |
+ changeTDC = new TGTextButton(fH1, "TDC"); |
+ changeTDC->AllowStayDown(kTRUE); |
+ changeTDC->SetTextJustify(36); |
+ changeTDC->SetWrapLength(-1); |
+ changeTDC->Resize(60,22); |
+ fH1->AddFrame(changeTDC, f0centery); |
+ |
+ changeADCTDC = new TGTextButton(fH1, "ADC/TDC"); |
+ changeADCTDC->AllowStayDown(kTRUE); |
+ changeADCTDC->SetTextJustify(36); |
+ changeADCTDC->SetWrapLength(-1); |
+ changeADCTDC->Resize(60,22); |
+ fH1->AddFrame(changeADCTDC, f0centery); |
+ |
+ change2Dsurf = new TGTextButton(fH1, "Surf 2D"); |
+ change2Dsurf->AllowStayDown(kTRUE); |
+ change2Dsurf->SetTextJustify(36); |
+ change2Dsurf->SetWrapLength(-1); |
+ change2Dsurf->Resize(60,22); |
+ fH1->AddFrame(change2Dsurf, f0); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ logscale = new TGCheckButton(fG1, "Logarithmic scale ON/OFF"); |
+ logscale->Resize(50,22); |
+ logscale->SetState(kButtonUp); |
+ fG1->AddFrame(logscale, f0centerx); |
+ |
+ // Export the selected files |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 100); |
+ fH2 = new TGHorizontalFrame(fH1, subgroup[0], 100); |
+ lab = new TGLabel(fH2, "Export selected histograms:"); |
+ fH2->AddFrame(lab, f0centery); |
+ |
+ exportHist = new TGTextButton(fH2, "Export"); |
+ exportHist->SetTextJustify(36); |
+ exportHist->SetWrapLength(-1); |
+ exportHist->Resize(80,22); |
+ fH2->AddFrame(exportHist, f0centery); |
+ fH1->AddFrame(fH2, f0centerx); |
+ fG1->AddFrame(fH1, f2); |
+ mdiFrame->AddFrame(fG1, f2); |
+ |
+ // Fitting controls for ADC spectrum |
+ fG1 = new TGGroupFrame(mdiFrame, "Fit Settings"); |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Peak sigma:"); |
+ fH1->AddFrame(lab, f0centery); |
+ fitSigma = new TGNumberEntry(fH1, 1.5, 3, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEANonNegative); |
+ fitSigma->Resize(60,22); |
+ fH1->AddFrame(fitSigma, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Signal/Noise treshold:"); |
+ fH1->AddFrame(lab, f0centery); |
+ fitTresh = new TGNumberEntry(fH1, 5.0E-3, 3, 999, TGNumberFormat::kNESReal, TGNumberFormat::kNEANonNegative); |
+ fitTresh->Resize(60,22); |
+ fH1->AddFrame(fitTresh, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Background interpolation:"); |
+ fH1->AddFrame(lab, f0centery); |
+ fitInter = new TGNumberEntry(fH1, 8, 3, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); |
+ fitInter->Resize(60,22); |
+ fH1->AddFrame(fitInter, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30); |
+ lab = new TGLabel(fH1, "Peak fit max. acceptable error:"); |
+ fH1->AddFrame(lab, f0centery); |
+ accError = new TGNumberEntry(fH1, 0.15, 3, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative); |
+ accError->Resize(60,22); |
+ fH1->AddFrame(accError, f0centery); |
+ fG1->AddFrame(fH1, f2); |
+ |
+ exfitplots = new TGCheckButton(fG1, "Export fitting plots ON/OFF"); |
+ exfitplots->Resize(50,22); |
+ exfitplots->SetState(kButtonDown); |
+ fG1->AddFrame(exfitplots, f0centerx); |
+ mdiFrame->AddFrame(fG1, f2); |
+ |
+ mdiFrame->SetMdiHints(kMdiMinimize); |
+ mdiFrame->SetWindowName("Histogram controls"); |
+ mdiFrame->MapSubwindows(); |
+ mdiFrame->Layout(); |
+ mdiFrame->Move(4*((winWidth/6)-5)+10,(int)(2.5*((winHeight/5)-5))); |
+// Histogram controls pane ----------------------------------------------------------------- |
+ |
+ // Action connections |
+ voltscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableVoltScan()"); |
+ surfscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableSurfScan()"); |
+ zscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableZaxisScan()"); |
+// histogramOn->Connect("Clicked()", "TGAppMainFrame", this, "HistogramToggle()"); |
+ vHardlimit->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "VoltageLimit()"); |
+ (vHardlimit->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "VoltageLimit()"); |
+ NCH->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "ChannelLimit()"); |
+ (NCH->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "ChannelLimit()"); |
+ cleanOn->Connect("Clicked()", "TGAppMainFrame", this, "CleanPlotToggle()"); |
+ oscConnect->Connect("Clicked()", "TGAppMainFrame", this, "ConnectToScope()"); |
+ vOutSet->Connect("Clicked()", "TGAppMainFrame", this, "SetVoltOut()"); |
+ vOutGet->Connect("Clicked()", "TGAppMainFrame", this, "GetVoltOut()"); |
+ vOutReset->Connect("Clicked()", "TGAppMainFrame", this, "ResetVoltOut()"); |
+ positionSet->Connect("Clicked()", "TGAppMainFrame", this, "SetPosition()"); |
+ positionGet->Connect("Clicked()", "TGAppMainFrame", this, "GetPosition()"); |
+ positionHome->Connect("Clicked()", "TGAppMainFrame", this, "HomePosition()"); |
+ saveFile->Connect("Clicked()", "TGAppMainFrame", this, "SaveFile()"); |
+ measStart->Connect("Clicked()", "TGAppMainFrame", this, "StartAcq()"); |
+ selectDir->Connect("Clicked()", "TGAppMainFrame", this, "SelectDirectory()"); |
+ multiSelect->Connect("Clicked()", "TGAppMainFrame", this, "ListMultiSelect()"); |
+ multiSelectAll->Connect("Clicked()", "TGAppMainFrame", this, "ListSelectAll()"); |
+ prevFile->Connect("Clicked()", "TGAppMainFrame", this, "FileListNavigation(=-2)"); |
+ nextFile->Connect("Clicked()", "TGAppMainFrame", this, "FileListNavigation(=-3)"); |
+ fileList->Connect("DoubleClicked(Int_t)", "TGAppMainFrame", this, "FileListNavigation(Int_t)"); |
+ clearList->Connect("Clicked()", "TGListBox", fileList, "RemoveAll()"); |
+ |
+ adcMinRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (adcMinRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ adcMaxRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (adcMaxRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ yMinRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (yMinRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ yMaxRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (yMaxRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ tdcMinwindow->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (tdcMinwindow->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ tdcMaxwindow->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()"); |
+ (tdcMaxwindow->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()"); |
+ changeADC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=0)"); |
+ changeTDC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=1)"); |
+ changeADCTDC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=2)"); |
+ change2Dsurf->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=3)"); |
+ selectCh->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "ChangeChannel()"); |
+ (selectCh->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "ChangeChannel()"); |
+ logscale->Connect("Clicked()", "TGAppMainFrame", this, "SetHistRange()"); |
+ exportHist->Connect("Clicked()", "TGAppMainFrame", this, "HistogramExport()"); |
+ |
+ started = kFALSE; |
+ EnableVoltScan(); |
+ EnableSurfScan(); |
+ EnableZaxisScan(); |
+} |
+ |
+//--------------------------------------------------------------- |
+// Closing the main application window and checking the about information |
+ |
+void TGAppMainFrame::CloseWindow() |
+{ |
+ gApplication->Terminate(0); |
+} |
+ |
+Bool_t TGAppMainFrame::About() |
+{ |
+ int ret = 0; |
+ |
+ new TGMsgBox(gClient->GetRoot(), fMain, |
+ fMain->GetWindowName(), "This is an application.", |
+ kMBIconQuestion, kMBClose, &ret); |
+ |
+ if(debug == 1) |
+ if(ret == kMBClose) |
+ printf("Closing the About window (%d).\n", ret); |
+ |
+ return kFALSE; |
+} |
+ |
+//--------------------------------------------------------------- |
+// Subwindow constructor definition (& layout) and close subwindow action |
+ |
+TGMdiSubwindow::TGMdiSubwindow(TGMdiMainFrame *main, int w, int h) |
+{ |
+ // Create a new subwindow |
+ fMdiFrame = new TGMdiFrame(main, w, h); |
+ fMdiFrame->Connect("CloseWindow()", "TGMdiSubwindow", this, "CloseWindow()"); // setting here to =0 -> will always ask before closing window |
+ fMdiFrame->DontCallClose(); // only let this window close if Yes is pressed when closing window |
+ |
+} |
+ |
+Bool_t TGMdiSubwindow::CloseWindow() |
+{ |
+ int ret = 0; |
+ |
+// if(noq == 0) |
+// { |
+ new TGMsgBox(gClient->GetRoot(), fMdiFrame, |
+ fMdiFrame->GetWindowName(), "Really want to close the window?", |
+ kMBIconExclamation, kMBYes | kMBNo, &ret); |
+ if (ret == kMBYes) return fMdiFrame->CloseWindow(); |
+ |
+ return kFALSE; |
+// } |
+// else |
+// return fMdiFrame->CloseWindow(); |
+} |
+ |
+//--------------------------------------------------------------- |
+// Main function |
+ |
+void windowed_test() |
+{ |
+ new TGAppMainFrame(gClient->GetRoot(), winWidth, winHeight); |
+} |
+ |
+//#ifdef STANDALONE |
+int main(int argc, char **argv) |
+{ |
+ TApplication theApp("MdiTest", &argc, argv); |
+ |
+ windowed_test(); |
+ |
+ theApp.Run(); |
+ |
+ return 0; |
+} |
+//#endif |
Index: sipmscan/trunk/windowed_test.h |
=================================================================== |
--- sipmscan/trunk/windowed_test.h (nonexistent) |
+++ sipmscan/trunk/windowed_test.h (revision 118) |
@@ -0,0 +1,32 @@ |
+#ifndef _windowedtest_h_ |
+#define _windowedtest_h_ |
+ |
+#define debug 1 |
+#define winWidth 1200 |
+#define winHeight 800 |
+#define WINDOW_NAME "CAMAC/MPOD/4MM DAQ software" |
+#define BSIZE 10000 |
+#define histname "hdata" |
+ |
+enum EMenuIds { |
+ M_FILE_NEW, |
+// M_FILE_CLOSE, |
+ M_FILE_EXIT, |
+ |
+ M_ANALYSIS_HISTTYPE, |
+ M_ANALYSIS_HISTTYPE_1DADC, |
+ M_ANALYSIS_HISTTYPE_1DTDC, |
+ M_ANALYSIS_HISTTYPE_2D, |
+ M_ANALYSIS_HISTTYPE_SURF, |
+ M_ANALYSIS_FIT, |
+ M_ANALYSIS_FITSEL, |
+ M_ANALYSIS_INTEGX, |
+ M_ANALYSIS_INTEGY, |
+ |
+ M_WINDOW_HOR, |
+ M_WINDOW_VERT, |
+ |
+ M_HELP_ABOUT |
+}; |
+ |
+#endif |
Index: sipmscan/trunk/wusbcc.h |
=================================================================== |
--- sipmscan/trunk/wusbcc.h (nonexistent) |
+++ sipmscan/trunk/wusbcc.h (revision 118) |
@@ -0,0 +1,15 @@ |
+#ifndef _WUSBCC_H |
+#define _WUSBCC_H |
+ |
+#define NAF(N,A,F) 0x4000+(N)*0x200+(A)*0x20+(F) |
+#define NAFS(N,A,F) (N)*0x200+(A)*0x20+(F) |
+ |
+#define CSSA_RQX(N,A,F,DATA,Q,X) CAMAC_read(udev,(N),(A),(F),(DATA),(Q),(X)) |
+#define CSSA_WQX(N,A,F,DATA,Q,X) CAMAC_write(udev,(N),(A),(F),(DATA),(Q),(X)) |
+ |
+#define CCCZ CAMAC_Z(udev) |
+#define CCCC CAMAC_C(udev) |
+#define CSET_I CAMAC_I(udev,1) |
+#define CREM_I CAMAC_I(udev,0) |
+ |
+#endif |
Index: sipmscan/trunk/wusbxx_dll.c |
=================================================================== |
--- sipmscan/trunk/wusbxx_dll.c (nonexistent) |
+++ sipmscan/trunk/wusbxx_dll.c (revision 118) |
@@ -0,0 +1,104 @@ |
+#include "wusbxx_dll.h" |
+ |
+usb_dev_handle *udev; |
+ |
+ |
+ |
+void _VI_FUNC 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"))) exit(1); |
+ if (!(xxusb_stack_read_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_stack_read"))) exit(1); |
+ if (!(xxusb_stack_write_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_stack_write"))) exit(1); |
+ if (!(xxusb_stack_execute_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_stack_execute"))) exit(1); |
+ if (!(xxusb_register_write_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_register_write"))) exit(1); |
+ if (!(xxusb_usbfifo_read_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_usbfifo_read"))) exit(1); |
+ if (!(xxusb_bulk_read_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_bulk_read"))) exit(1); |
+ if (!(xxusb_bulk_write_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_bulk_write"))) exit(1); |
+ if (!(xxusb_reset_toggle_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_reset_toggle"))) exit(1); |
+ |
+ if (!(xxusb_devices_find_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_devices_find"))) exit(1); |
+ if (!(xxusb_device_close_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_device_close"))) exit(1); |
+ if (!(xxusb_device_open_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_device_open"))) exit(1); |
+ if (!(xxusb_flash_program_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_flash_program"))) exit(1); |
+ if (!(xxusb_flashblock_program_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_flashblock_program"))) exit(1); |
+ if (!(xxusb_serial_open_Ptr = (void*) GetProcAddress(DLLHandle,"xxusb_serial_open"))) exit(1); |
+ |
+ if (!(VME_register_write_Ptr = (void*) GetProcAddress(DLLHandle,"VME_register_write"))) exit(1); |
+ if (!(VME_register_read_Ptr = (void*) GetProcAddress(DLLHandle,"VME_register_read"))) exit(1); |
+ if (!(VME_LED_settings_Ptr = (void*) GetProcAddress(DLLHandle,"VME_LED_settings"))) exit(1); |
+ if (!(VME_DGG_Ptr = (void*) GetProcAddress(DLLHandle,"VME_DGG"))) exit(1); |
+ if (!(VME_Output_settings_Ptr = (void*) GetProcAddress(DLLHandle,"VME_Output_settings"))) exit(1); |
+ if (!(VME_read_16_Ptr = (void*) GetProcAddress(DLLHandle,"VME_read_16"))) exit(1); |
+ if (!(VME_read_32_Ptr = (void*) GetProcAddress(DLLHandle,"VME_read_32"))) exit(1); |
+ if (!(VME_BLT_read_32_Ptr = (void*) GetProcAddress(DLLHandle,"VME_BLT_read_32"))) exit(1); |
+ if (!(VME_write_16_Ptr = (void*) GetProcAddress(DLLHandle,"VME_write_16"))) exit(1); |
+ if (!(VME_write_32_Ptr = (void*) GetProcAddress(DLLHandle,"VME_write_32"))) exit(1); |
+ |
+ if (!(CAMAC_DGG_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_DGG"))) exit(1); |
+ if (!(CAMAC_register_read_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_register_read"))) exit(1); |
+ if (!(CAMAC_register_write_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_register_write"))) exit(1); |
+ if (!(CAMAC_LED_settings_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_LED_settings"))) exit(1); |
+ if (!(CAMAC_Output_settings_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_Output_settings"))) exit(1); |
+ if (!(CAMAC_read_LAM_mask_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_read_LAM_mask"))) exit(1); |
+ if (!(CAMAC_write_LAM_mask_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_write_LAM_mask"))) exit(1); |
+ if (!(CAMAC_write_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_write"))) exit(1); |
+ if (!(CAMAC_read_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_read"))) exit(1); |
+ if (!(CAMAC_Z_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_Z"))) exit(1); |
+ if (!(CAMAC_C_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_C"))) exit(1); |
+ if (!(CAMAC_I_Ptr = (void*) GetProcAddress(DLLHandle,"CAMAC_I"))) exit(1); |
+*/ |
+} |
+ |
+void _VI_FUNC WUSBXX_open (char *serial) |
+{ |
+ if (serial != NULL) |
+ udev = xxusb_serial_open(serial); |
+} |
+ |
+void _VI_FUNC WUSBXX_close (void) |
+{ |
+ if (udev) xxusb_device_close(udev); |
+} |
+ |
+int _VI_FUNC WUSBXX_CCread (int n, int a, int f, unsigned long *data) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+ // CAMAC direct read function |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(f+a*32+n*512 + 0x4000); |
+ ret = xxusb_stack_execute(udev, intbuf); |
+ if (f < 16) |
+ { |
+ *data=intbuf[0] + intbuf[1] * 0x10000; //24-bit word |
+// *Q = ((intbuf[1] >> 8) & 1); |
+// *X = ((intbuf[1] >> 9) & 1); |
+ } |
+ return ret; |
+} |
+ |
+int _VI_FUNC WUSBXX_CCwrite (int n, int a, int f, unsigned long data) |
+{ |
+ long intbuf[4]; |
+ int ret; |
+// CAMAC direct write function |
+ intbuf[0]=1; |
+ intbuf[1]=(long)(f+a*32+n*512 + 0x4000); |
+ if ((f > 15) && (f < 24)) |
+ { |
+ 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); |
+ } |
+ return ret; |
+} |
Index: sipmscan/trunk/wusbxx_dll.h |
=================================================================== |
--- sipmscan/trunk/wusbxx_dll.h (nonexistent) |
+++ sipmscan/trunk/wusbxx_dll.h (revision 118) |
@@ -0,0 +1,19 @@ |
+#ifndef _WUSBXX_DLL_H |
+#define _WUSBXX_DLL_H |
+ |
+#include <stdlib.h> |
+#include <stdio.h> |
+ |
+#include "libxxusb.h" |
+#include "wusbcc.h" |
+#define _VI_FUNC |
+extern usb_dev_handle *udev; |
+ |
+void _VI_FUNC WUSBXX_load (char *module_path); |
+void _VI_FUNC WUSBXX_open (char *serial); |
+void _VI_FUNC WUSBXX_close (void); |
+int _VI_FUNC WUSBXX_CCread (int n, int a, int f, unsigned long *data); |
+int _VI_FUNC WUSBXX_CCwrite (int n, int a, int f, unsigned long data); |
+ |
+#endif |
+ |