/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 |
+* |
\ No newline at end of property |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/lab/sipmscan/trunk/MIKRO/mikro_ctrl.c |
---|
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; |
} |
/lab/sipmscan/trunk/MIKRO/mikro_ctrl_d |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/lab/sipmscan/trunk/MIKRO/quick_scan.sh |
---|
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 |
/lab/sipmscan/trunk/MIKRO/rs232.c |
---|
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; |
} |
/lab/sipmscan/trunk/MIKRO/rs232.h |
---|
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 |
/lab/sipmscan/trunk/MIKRO/test.txt |
---|
0,0 → 1,4 |
125877 50001 |
0 3 |
0 3 |
0 3 |
/lab/sipmscan/trunk/configure |
---|
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 |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/lab/sipmscan/trunk/daq.h |
---|
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 |
/lab/sipmscan/trunk/daqscope.h |
---|
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 |
/lab/sipmscan/trunk/input/Makefile.in |
---|
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 |
# ----------------------------------------------------------------------------- |
/lab/sipmscan/trunk/input/daqscope.C.in |
---|
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); |
} |
/lab/sipmscan/trunk/input/daqusb.C.offline |
---|
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 |
/lab/sipmscan/trunk/input/daqusb.C.online |
---|
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 |
/lab/sipmscan/trunk/input/start.sh.offline |
---|
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\")" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/lab/sipmscan/trunk/input/start.sh.online |
---|
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\")" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/lab/sipmscan/trunk/input/workstation.h.in |
---|
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 |
/lab/sipmscan/trunk/libxxusb.cpp |
---|
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; |
} |
/lab/sipmscan/trunk/libxxusb.h |
---|
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); |
/lab/sipmscan/trunk/mpod/WIENER-CRATE-MIB.txt |
---|
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 |
/lab/sipmscan/trunk/mpod/instructions_mpod.txt |
---|
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 |
/lab/sipmscan/trunk/mpod/mpod_voltage.sh |
---|
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 |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/lab/sipmscan/trunk/mpod/test.sh |
---|
0,0 → 1,7 |
#!/bin/bash |
echo "Bash start." |
sleep $1 |
echo "Bash end." |
exit 0 |
/lab/sipmscan/trunk/mpod/test.sh.bak |
---|
0,0 → 1,7 |
#!/bin/bash |
echo "Bash start." |
sleep 5 |
echo "Bash end." |
exit 0 |
/lab/sipmscan/trunk/root_include.h |
---|
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 |
/lab/sipmscan/trunk/start.cxx |
---|
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(); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/lab/sipmscan/trunk/usb.h |
---|
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__ */ |
/lab/sipmscan/trunk/vxi11_i686/CHANGELOG.txt |
---|
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. |
------------------------------------------------------------------------------ |
/lab/sipmscan/trunk/vxi11_i686/GNU_General_Public_License.txt |
---|
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. |
/lab/sipmscan/trunk/vxi11_i686/Makefile |
---|
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 |
/lab/sipmscan/trunk/vxi11_i686/Makefile.old |
---|
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/ |
/lab/sipmscan/trunk/vxi11_i686/vxi11.x |
---|
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; |
/lab/sipmscan/trunk/vxi11_i686/vxi11_cmd.cc |
---|
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; |
} |
/lab/sipmscan/trunk/vxi11_i686/vxi11_user.cc |
---|
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*/ |
} |
/lab/sipmscan/trunk/vxi11_i686/vxi11_user.h |
---|
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 |
/lab/sipmscan/trunk/vxi11_x86_64/CHANGELOG.txt |
---|
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. |
------------------------------------------------------------------------------ |
/lab/sipmscan/trunk/vxi11_x86_64/GNU_General_Public_License.txt |
---|
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. |
/lab/sipmscan/trunk/vxi11_x86_64/Makefile |
---|
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 |
/lab/sipmscan/trunk/vxi11_x86_64/Makefile.old |
---|
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 |
/lab/sipmscan/trunk/vxi11_x86_64/README.txt |
---|
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!) |
/lab/sipmscan/trunk/vxi11_x86_64/vxi11.x |
---|
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; |
/lab/sipmscan/trunk/vxi11_x86_64/vxi11_cmd.cc |
---|
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; |
} |
/lab/sipmscan/trunk/vxi11_x86_64/vxi11_user.cc |
---|
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*/ |
} |
/lab/sipmscan/trunk/vxi11_x86_64/vxi11_user.h |
---|
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 |
/lab/sipmscan/trunk/windowed_test.C |
---|
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, TGNumberForm |