source: hvcontrol/src/HV.cc@ 228

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