Subversion Repositories f9daq

Compare Revisions

Ignore whitespace Rev 116 → Rev 118

/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
+