source: hvcontrol/src/HV.cc@ 98

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