source: fact/BIASctrl/Crate.cc@ 10011

Last change on this file since 10011 was 9917, checked in by ogrimm, 14 years ago
Initial commit of BIASctrl
File size: 6.6 KB
Line 
1/********************************************************************\
2
3 Interface to FACT bias voltage crate
4
5\********************************************************************/
6
7#include "Crate.h"
8#include "ProcessIO.h" // Must be not in HV.h to avoid problem with declaring class ProcessIO
9
10using namespace std;
11
12//
13// Constructor
14//
15Crate::Crate(string CrateName, int Number, class ProcessIO *PIO) {
16
17 struct termios tio;
18
19 // Initialize
20 InitOK = false;
21 m = PIO;
22 Name = new char [CrateName.size()+1];
23 strcpy(Name, CrateName.c_str());
24 CrateNumber = Number;
25 WrapCount = -1;
26
27 for (int i=0; i<MAX_NUM_BOARDS; i++) {
28 for (int j=0; j<NUM_CHANNELS; j++) {
29 OC[i][j] = false;
30 Current[i][j] = 0;
31 }
32 }
33 ResetHit = false;
34 WrapOK = true;
35 WrapCount = -1;
36 ErrorCount = 0;
37
38 // Create DIM services
39 stringstream ID;
40 ID << setfill('0') << setw(2) << CrateNumber;
41
42 NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name);
43 BiasVolt = new DimService ((char *) (SERVER_NAME"/VOLT/ID"+ID.str()).c_str(), (char *) "D", Volt, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(double));
44
45 ClearVoltageArrays();
46
47 // Open device
48 if ((fDescriptor = open(("/dev/"+CrateName).c_str(), O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
49 if(errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", CrateNumber, Name, strerror(errno));
50 return;
51 }
52
53 // Get current serial port settings
54 if (tcgetattr(fDescriptor, &tio) == -1) {
55 m->PrintMessage("Error: tcgetattr() failed on device %s (%s)\n", Name, strerror(errno));
56 return;
57 }
58
59 // Set baudrate and raw mode
60 if (cfsetspeed(&tio, BAUDRATE) == -1) {
61 m->PrintMessage("Error: Could not set baud rate of device %s (%s)\n", Name, strerror(errno));
62 return;
63 }
64 cfmakeraw(&tio);
65 if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) {
66 m->PrintMessage("Error: tcsetattr() failed on device %s (%s)\n", Name, strerror(errno));
67 return;
68 }
69
70 InitOK = true;
71}
72
73//
74// Destructor (Resets board)
75//
76Crate::~Crate() {
77
78 if(fDescriptor != -1) {
79 SystemReset();
80 close(fDescriptor);
81 }
82
83 delete NameService;
84 delete BiasVolt;
85 delete[] Name;
86}
87
88
89// Communicate: Write and read from HV Board until time-out has been reached
90//
91// Returns: 0 error, 1 success, -1 time-out exceeded
92int Crate::Communicate(unsigned char* wbuf, int Bytes) {
93
94 unsigned char rbuf[3];
95 int N, Ret = 0;
96 fd_set SelectDescriptor;
97 struct timeval WaitTime = {(long) m->fTimeOut, (long) ((m->fTimeOut-(long) m->fTimeOut)*1e6)};
98
99 // === Lock file descriptor ===
100 if (lockf(fDescriptor, F_LOCK, 0) == -1) {
101 m->Message(m->ERROR, "Failed to lock file descriptor (%s)", strerror(errno));
102 return 0;
103 }
104
105 // === Write data ===
106 if ((N = write(fDescriptor, wbuf, Bytes)) < Bytes) {
107 if (N == -1) m->Message(m->ERROR, "Could not write data to crate (%s)", strerror(errno));
108 else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Bytes);
109 ErrorCount++;
110 goto ExitCommunicate;
111 }
112
113 // === Try to read until time-out ===
114 FD_ZERO(&SelectDescriptor); FD_SET(fDescriptor, &SelectDescriptor);
115 if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
116 m->Message(m->ERROR, "Error with select() (%s)", strerror(errno));
117 goto ExitCommunicate;
118 }
119 // Time-out expired?
120 if (!FD_ISSET(fDescriptor, &SelectDescriptor)) {
121 Ret = -1;
122 goto ExitCommunicate;
123 }
124
125 // Read data
126 if ((N = read(fDescriptor, &rbuf, 1)) == -1) {
127 m->Message(m->ERROR, "Read error (%s)", strerror(errno));
128 ErrorCount++;
129 goto ExitCommunicate;
130 }
131
132 // === Update status information if three bytes were returned ===
133 if (N == 3) {
134 // This data only valid for channel set or channel read
135 LastCurrent = rbuf[1] + (rbuf[0]&15)*256;
136 LastOC = rbuf[0] & 128;
137 ResetHit = rbuf[2] & 128;
138
139 // Check wrap counter
140 if (WrapCount != -1) {
141 if ((WrapCount+1)%8 == ((rbuf[0]>>4) & 7)) WrapOK = true;
142 else WrapOK = false;
143 }
144 WrapCount = (rbuf[0]>>4) & 7;
145 Ret = 1;
146 }
147
148 // === UnLock file descriptor ===
149 ExitCommunicate:
150 if (lockf(fDescriptor, F_LOCK, 0) == -1) {
151 m->Message(m->ERROR, "Failed to lock file descriptor (%s)", strerror(errno));
152 return 0;
153 }
154
155 return Ret;
156}
157
158//
159// System reset of bias crate
160//
161int Crate::SystemReset() {
162
163 unsigned char wbuf[] = {0,0,0};
164 int ret;
165
166 if((ret = Communicate(wbuf, 3)) == 1) {
167 ClearVoltageArrays();
168 ErrorCount = 0;
169 }
170 return ret;
171}
172
173//
174// Read channel status
175//
176int Crate::ReadChannel(unsigned int Board, unsigned int Channel) {
177
178 // Check limits
179 if (Board > MAX_NUM_BOARDS) {
180 m->PrintMessage("Error: Board number out of range\n");
181 return 0;
182 }
183 if (Channel > NUM_CHANNELS) {
184 m->PrintMessage("Error: Channel number out of range\n");
185 return 0;
186 }
187
188 // Execute command
189 unsigned char wbuf[] = {1<<5 | Board<<1 | (Channel&16)>>4, Channel<<4, 0};
190 int ret;
191
192 if ((ret = Communicate(wbuf, 3)) == 1) {
193 Current[Board][Channel] = LastCurrent;
194 OC[Board][Channel] = LastOC;
195 }
196 return ret;
197}
198
199
200// ***** Global set *****
201int Crate::GlobalSet(unsigned int SetPoint) {
202
203 // Check limit
204 if (SetPoint > 0x0FFF) {
205 m->PrintMessage("Error: Voltage DAC value above 0x0FFF\n");
206 return 0;
207 }
208
209 // Execute command
210 unsigned char wbuf[] = {1<<6 , SetPoint>>8, SetPoint};
211 int ret;
212
213 if ((ret = Communicate(wbuf, 3)) == 1) {
214 for (int i=0; i<MAX_NUM_BOARDS; i++) {
215 for (int j=0; j<NUM_CHANNELS; j++) DAC[i][j] = SetPoint;
216 }
217 }
218 return ret;
219}
220
221
222// ***** Channel set *****
223int Crate::ChannelSet(int Board, int Channel, unsigned int SetPoint) {
224
225 // Check limits
226 if (SetPoint > 0x0FFF) {
227 m->PrintMessage("Error: Voltage DAC value above 0x0FFF\n");
228 return 0;
229 }
230 if (Board > MAX_NUM_BOARDS) {
231 m->PrintMessage("Error: Board number out of range\n");
232 return 0;
233 }
234 if (Channel > NUM_CHANNELS) {
235 m->PrintMessage("Error: Channel number out of range\n");
236 return 0;
237 }
238
239 // Execute command
240 unsigned char wbuf[] = {3<<5 | Board<<1 | (Channel&16)>>4, Channel<<4 | SetPoint>>8, SetPoint};
241 int ret;
242
243 if ((ret = Communicate(wbuf, 3)) == 1) {
244 DAC[Board][Channel] = SetPoint;
245 Current[Board][Channel] = LastCurrent;
246 OC[Board][Channel] = LastOC;
247 }
248 return ret;
249}
250
251
252// ***** Synchronize board *****
253bool Crate::Synch() {
254
255 unsigned char wbuf = 0;
256 int Trial = 0, ret;
257
258 while(++Trial <= 3) {
259 if((ret = Communicate(&wbuf, 1)) == 1) return true;
260 if (ret == 0) break;
261 }
262 return false;
263}
264
265
266// ***** Set all voltages of board to zero *****
267void Crate::ClearVoltageArrays() {
268
269 for (int i=0; i<MAX_NUM_BOARDS; i++) {
270 for (int j=0; j<NUM_CHANNELS; j++){
271 DAC[i][j] = 0;
272 //Volt[i][j] = 0.0;
273 }
274 }
275 // Update DIM services
276 BiasVolt->updateService();
277}
Note: See TracBrowser for help on using the repository browser.