source: hvcontrol/src/HV.cc@ 93

Last change on this file since 93 was 93, checked in by ogrimm, 15 years ago
Added writing of slow data
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, unsigned 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>=0 && hv<=0x3FFF)) {
174 m->PrintMessage(" Error: HV beyond limits [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 return Communicate(wbuf, 3);
194}
195
196
197// Set all voltages of board to zero
198void HVBoard::ClearVoltageArrays() {
199
200 for (int j=0; j<NUM_CHAINS; j++) {
201 for (int k=0; k<NUM_CHANNELS; k++){
202 HV[j][k] = 0;
203 HVV[j][k] = 0.0;
204 }
205 }
206}
207
208
209// Set time-out to wait for read
210void HVBoard::SetTimeOut(double t) {
211
212 if (t >= MIN_TIMEOUT && t <= MAX_TIMEOUT) fTimeOut = t;
213 else fTimeOut = 1.0;
214}
Note: See TracBrowser for help on using the repository browser.