source: hvcontrol/src/HV.cc@ 154

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