source: hvcontrol/src/HV.cc@ 107

Last change on this file since 107 was 100, checked in by ogrimm, 15 years ago
Number of HV boards (almost) unlimited.
File size: 5.4 KB
Line 
1
2/********************************************************************\
3
4 Name: HV.cc
5
6 Created by: Sebastian Commichau, November 2008
7 commichau@phys.ethz.ch
8
9 Contents: Main class for HV supply
10
11\********************************************************************/
12
13#include "HV.h"
14#include "ProcessIO.h" // Must be not in HV.h to avoid problem with declaring class ProcessIO
15
16// Constructor
17HVBoard::HVBoard(int DeviceNumber, char *DeviceName, class ProcessIO *PIO) {
18
19 char Buffer[BUFFER_LENGTH];
20 struct termios tio;
21
22 m = PIO;
23
24 SetTimeOut(m->config->fTimeOut);
25 BoardNumber = DeviceNumber;
26 BoardName = DeviceName;
27
28 for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i] = false;
29 ResetButton = false;
30 WrapOK = true;
31 LastWrapCount = -1;
32
33 ClearVoltageArrays();
34
35 // Open device (do not warn on non-existing device)
36 snprintf(Buffer, BUFFER_LENGTH, "/dev/%s",DeviceName);
37 if ((fDescriptor = open(Buffer, O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
38 if(errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", DeviceNumber,DeviceName, strerror(errno));
39 return;
40 }
41
42 // Get current serial port settings
43 if (tcgetattr(fDescriptor, &tio) == -1) {
44 m->PrintMessage("Error: tcgetattr() failed (%d/%s)\n", errno, strerror(errno));
45 return;
46 }
47
48 // Set baudrate and raw mode
49 if (cfsetspeed(&tio, BAUDRATE) == -1) m->PrintMessage("Error: Could not set baud rate (%s)\n", strerror(errno));
50 cfmakeraw(&tio);
51 if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) m->PrintMessage("Error: tcsetattr() failed (%s)\n", strerror(errno));
52
53 // Synchronize HV board (if fails, closes device and sets fDescriptor to -2)
54 unsigned char wbuf = REG_STATUS;
55 int trial = 0, ret;
56
57 while(++trial<=3) {
58 if((ret = Communicate(&wbuf, 1)) == 1) {
59 Reset();
60 return;
61 }
62 if (ret==0) break;
63 wbuf = 0;
64 }
65 close(fDescriptor);
66 fDescriptor = -2;
67 return;
68}
69
70// Destructor (Resetting board)
71HVBoard::~HVBoard() {
72 if(fDescriptor >= 0) {
73 Reset();
74 close(fDescriptor);
75 }
76}
77
78
79// Communicate: Write and read from HV Board until fTimeOut has been reached
80//
81// Returns: 0 error, 1 success, -1 fTimeOut exceeded
82int HVBoard::Communicate(unsigned char* wbuf, int Bytes) {
83
84 unsigned char rbuf;
85 int ret;
86 fd_set SelectDescriptor;
87
88 // === Write data ===
89 if (write(fDescriptor, wbuf, Bytes) < Bytes) {
90 m->PrintMessage("Error: Could not write (all) data to HV board\n");
91 return 0;
92 }
93 if (m->Verbose) {
94 m->PrintMessage("%d bytes written:\n", Bytes);
95 for (int i=0; i<Bytes; i++) m->PrintMessage(" Byte %d: %#.2x\n",i,wbuf[i]);
96 }
97
98 // === Try to read until time-out ===
99 FD_ZERO(&SelectDescriptor); FD_SET(fDescriptor, &SelectDescriptor);
100 struct timeval WaitTime = {(long) fTimeOut, (long) ((fTimeOut-(long) fTimeOut)*1e6)};
101 if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
102 m->PrintMessage("Error with select() (%d/%s)\n", errno,strerror(errno));
103 return 0;
104 }
105 // Time-out expired?
106 if (!FD_ISSET(fDescriptor, &SelectDescriptor)) {
107 if (m->Verbose) m->PrintMessage("Time-out of %.2f seconds expired while reading\n", fTimeOut);
108 return -1;
109 }
110 // Read error?
111 if ((ret = read(fDescriptor, &rbuf, 1)) == -1) {
112 m->PrintMessage("Read error (%s)\n", strerror(errno));
113 return 0;
114 }
115
116 // === Update status information ===
117 if (LastWrapCount != -1) {
118 if ((LastWrapCount+1)%8 == (rbuf & 0X07)) WrapOK = true;
119 else WrapOK = false;
120 }
121 LastWrapCount = rbuf & 0X07;
122 for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i] = (rbuf & (0X08 << i));
123 ResetButton = (bool) (rbuf & 0X80);
124
125 if (m->Verbose && ret==1) m->PrintMessage(" 1 byte read: %#.2x\n", rbuf);
126
127 return 1;
128}
129
130
131/* Reset HV board - uses TRead() and has same return values */
132int HVBoard::Reset() {
133
134 unsigned char wbuf[] = {REG_RESET,0,0};
135 int ret;
136
137 if((ret = Communicate(wbuf, 3)) == 1) ClearVoltageArrays();
138 return ret;
139}
140
141
142/* Read status register - uses TRead() and has same return values */
143int HVBoard::GetStatus() {
144
145 unsigned char wbuf[] = {REG_STATUS,0,0};
146
147 return Communicate(wbuf, 3);
148}
149
150
151/* Set high voltage - uses TRead() and has same return values */
152int HVBoard::SetHV(int chain, unsigned int channel, int hv) {
153
154 unsigned char wbuf[] = {0,0,0};
155 int ret;
156
157 if (hv<0 || hv > 0x3FFF) {
158 m->PrintMessage("Error: Voltage out of range 0-0x3FFF\n");
159 return 0;
160 }
161
162 switch (chain) {
163 case 0: wbuf[0] = REG_HV0; break;
164 case 1: wbuf[0] = REG_HV1; break;
165 case 2: wbuf[0] = REG_HV2; break;
166 case 3: wbuf[0] = REG_HV3; break;
167
168 default : m->PrintMessage(" Error: Chain %d does not exist\n",chain); return 0;
169 }
170
171 // Assemble bytes
172 wbuf[0] |= (unsigned char)((channel >> 2) & 0X00000007); // Add address [A4-A3]
173 wbuf[1] |= (unsigned char)((hv >> 8) & 0X000000FF); // Add [D13-D8]
174 wbuf[1] |= (unsigned char)((channel << 6) & 0X000000C0); // Add [A1-A0]
175 wbuf[2] |= (unsigned char)(hv & 0X000000FF); // Add [D7-D0]
176
177 if ((ret = Communicate(wbuf, 3)) == 1) HV[chain][channel] = hv;
178 return ret;
179}
180
181
182// Set all voltages of board to zero
183void HVBoard::ClearVoltageArrays() {
184
185 for (int j=0; j<NUM_CHAINS; j++) {
186 for (int k=0; k<NUM_CHANNELS; k++){
187 HV[j][k] = 0;
188 HVV[j][k] = 0.0;
189 }
190 }
191}
192
193
194// Set time-out to wait for read
195void HVBoard::SetTimeOut(double t) {
196
197 if (t >= MIN_TIMEOUT && t <= MAX_TIMEOUT) fTimeOut = t;
198 else fTimeOut = 1.0;
199}
Note: See TracBrowser for help on using the repository browser.