source: hvcontrol/src/HV.cc@ 162

Last change on this file since 162 was 161, checked in by ogrimm, 15 years ago
Removed local configuration, now dependent on Evidence configuration server
File size: 5.8 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->fTimeOut);
25 BoardNumber = DeviceNumber;
26 BoardName = DeviceName;
27
28 // Create DIM services
29 snprintf(Buffer, sizeof(Buffer), SERVER_NAME"/NAME/ID%.2d", BoardNumber);
30 Name = new DimService (Buffer, BoardName);
31
32 for (int i=0; i<NUM_CHAINS; i++) {
33 for (int j=0; j<NUM_CHANNELS; j++) {
34 snprintf(Buffer, sizeof(Buffer), SERVER_NAME"/VOLT/ID%.2d/%.2d-%.3d", BoardNumber, i, j);
35 BiasVolt[i][j] = new DimService (Buffer, HVV[i][j]);
36 }
37 Overcurrent[i] = false;
38 }
39 ResetButton = false;
40 WrapOK = true;
41 LastWrapCount = -1;
42 ErrorCount = 0;
43
44 ClearVoltageArrays();
45
46 // Open device (do not warn on non-existing device)
47 snprintf(Buffer, BUFFER_LENGTH, "/dev/%s",DeviceName);
48 if ((fDescriptor = open(Buffer, O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
49 if(errno != 2) m->PrintMessage(All, "Error: Could not open device %d/%s (%s)\n", DeviceNumber,DeviceName, strerror(errno));
50 return;
51 }
52
53 // Get current serial port settings
54 if (tcgetattr(fDescriptor, &tio) == -1) {
55 m->PrintMessage(All, "Error: tcgetattr() failed (%d/%s)\n", errno, strerror(errno));
56 return;
57 }
58
59 // Set baudrate and raw mode
60 if (cfsetspeed(&tio, BAUDRATE) == -1) m->PrintMessage(All, "Error: Could not set baud rate (%s)\n", strerror(errno));
61 cfmakeraw(&tio);
62 if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) m->PrintMessage(All, "Error: tcsetattr() failed (%s)\n", strerror(errno));
63
64 // Synchronize HV board (if fails, closes device and sets fDescriptor to -2)
65 unsigned char wbuf = REG_STATUS;
66 int trial = 0, ret;
67
68 while(++trial<=3) {
69 if((ret = Communicate(&wbuf, 1)) == 1) {
70 Reset();
71 return;
72 }
73 if (ret==0) break;
74 wbuf = 0;
75 }
76 close(fDescriptor);
77 fDescriptor = -2;
78 return;
79}
80
81// Destructor (Resetting board)
82HVBoard::~HVBoard() {
83 if(fDescriptor >= 0) {
84 Reset();
85 close(fDescriptor);
86 }
87
88 delete Name;
89 for (int i=0; i<NUM_CHAINS; i++) {
90 for (int j=0; j<NUM_CHANNELS; j++) {
91 delete BiasVolt[i][j];
92 }
93 }
94}
95
96
97// Communicate: Write and read from HV Board until fTimeOut has been reached
98//
99// Returns: 0 error, 1 success, -1 fTimeOut exceeded
100int HVBoard::Communicate(unsigned char* wbuf, int Bytes) {
101
102 unsigned char rbuf;
103 int ret;
104 fd_set SelectDescriptor;
105
106 // === Write data ===
107 if ((ret=write(fDescriptor, wbuf, Bytes)) < Bytes) {
108 if (ret == -1) m->PrintMessage(All, "Could not write data to HV board (%s)\n", strerror(errno));
109 else m->PrintMessage(All, "Could write only %d of %d bytes to HV board\n", ret, Bytes);
110 ErrorCount++;
111 return 0;
112 }
113
114 // === Try to read until time-out ===
115 FD_ZERO(&SelectDescriptor); FD_SET(fDescriptor, &SelectDescriptor);
116 struct timeval WaitTime = {(long) fTimeOut, (long) ((fTimeOut-(long) fTimeOut)*1e6)};
117 if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
118 m->PrintMessage(All, "Error with select() (%s)\n", strerror(errno));
119 return 0;
120 }
121 // Time-out expired?
122 if (!FD_ISSET(fDescriptor, &SelectDescriptor)) return -1;
123
124 // Read error?
125 if ((ret = read(fDescriptor, &rbuf, 1)) == -1) {
126 m->PrintMessage(All, "Read error (%s)\n", strerror(errno));
127 ErrorCount++;
128 return 0;
129 }
130
131 // === Update status information ===
132 if (LastWrapCount != -1) {
133 if ((LastWrapCount+1)%8 == (rbuf & 0X07)) WrapOK = true;
134 else WrapOK = false;
135 }
136 LastWrapCount = rbuf & 0X07;
137 for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i] = (rbuf & (0X08 << i));
138 ResetButton = (bool) (rbuf & 0X80);
139
140 return 1;
141}
142
143
144/* Reset HV board - uses TRead() and has same return values */
145int HVBoard::Reset() {
146
147 unsigned char wbuf[] = {REG_RESET,0,0};
148 int ret;
149
150 if((ret = Communicate(wbuf, 3)) == 1) {
151 ClearVoltageArrays();
152 ErrorCount = 0;
153 }
154 return ret;
155}
156
157
158/* Read status register - uses TRead() and has same return values */
159int HVBoard::GetStatus() {
160
161 unsigned char wbuf[] = {REG_STATUS,0,0};
162
163 return Communicate(wbuf, 3);
164}
165
166
167/* Set high voltage - uses TRead() and has same return values */
168int HVBoard::SetHV(int chain, unsigned int channel, int hv) {
169
170 unsigned char wbuf[] = {0,0,0};
171 int ret;
172
173 if (hv<0 || hv > 0x3FFF) {
174 m->PrintMessage("Error: Voltage out of range 0-0x3FFF\n");
175 return 0;
176 }
177
178 switch (chain) {
179 case 0: wbuf[0] = REG_HV0; break;
180 case 1: wbuf[0] = REG_HV1; break;
181 case 2: wbuf[0] = REG_HV2; break;
182 case 3: wbuf[0] = REG_HV3; break;
183
184 default : m->PrintMessage(" Error: Chain %d does not exist\n",chain); return 0;
185 }
186
187 // Assemble bytes
188 wbuf[0] |= (unsigned char)((channel >> 2) & 0X00000007); // Add address [A4-A3]
189 wbuf[1] |= (unsigned char)((hv >> 8) & 0X000000FF); // Add [D13-D8]
190 wbuf[1] |= (unsigned char)((channel << 6) & 0X000000C0); // Add [A1-A0]
191 wbuf[2] |= (unsigned char)(hv & 0X000000FF); // Add [D7-D0]
192
193 if ((ret = Communicate(wbuf, 3)) == 1) HV[chain][channel] = hv;
194 return ret;
195}
196
197
198// Set all voltages of board to zero
199void HVBoard::ClearVoltageArrays() {
200
201 for (int j=0; j<NUM_CHAINS; j++) {
202 for (int k=0; k<NUM_CHANNELS; k++){
203 HV[j][k] = 0;
204 HVV[j][k] = 0.0;
205
206 // Update DIM services
207 BiasVolt[j][k]->updateService();
208 }
209 }
210}
211
212
213// Set time-out to wait for read
214void HVBoard::SetTimeOut(double t) {
215
216 if (t >= MIN_TIMEOUT && t <= MAX_TIMEOUT) fTimeOut = t;
217 else fTimeOut = 1.0;
218}
Note: See TracBrowser for help on using the repository browser.