Line data Source code
1 : #include "wibmod/WIB1/WIBBase.hh"
2 : #include "wibmod/WIB1/BNL_UDP_Exception.hh"
3 : #include "wibmod/WIB1/WIBException.hh"
4 :
5 0 : WIBBase::WIBBase(std::string const& address, std::string const& WIBAddressTable, std::string const& FEMBAddressTable)
6 0 : : wib(NULL)
7 0 : , FEMBReadSleepTime(0.01)
8 0 : , FEMBWriteSleepTime(0.01)
9 : {
10 : // Make sure all pointers and NULL before any allocation
11 :
12 0 : for (size_t iFEMB = 0; iFEMB < FEMB_COUNT; iFEMB++) {
13 0 : FEMB[iFEMB] = NULL;
14 : }
15 :
16 : // Create the wib address table interface
17 0 : wib = new AddressTable(WIBAddressTable, address, 0);
18 0 : for (size_t iFEMB = 0; iFEMB < FEMB_COUNT; iFEMB++) {
19 0 : FEMB[iFEMB] = new AddressTable(FEMBAddressTable, address, (iFEMB + 1) * 0x10);
20 : }
21 0 : }
22 :
23 0 : WIBBase::~WIBBase()
24 : {
25 0 : if (wib != NULL) {
26 0 : delete wib;
27 0 : wib = NULL;
28 : }
29 0 : for (size_t iFEMB = 0; iFEMB < FEMB_COUNT; iFEMB++) {
30 0 : if (FEMB[iFEMB] != NULL) {
31 0 : delete FEMB[iFEMB];
32 0 : FEMB[iFEMB] = NULL;
33 : }
34 : }
35 0 : }
36 :
37 : std::string
38 0 : WIBBase::GetAddress()
39 : {
40 0 : return wib->GetRemoteAddress();
41 : }
42 :
43 : uint32_t
44 0 : WIBBase::ReadI2C(std::string const& base_address, uint16_t address, uint8_t byte_count)
45 : {
46 : // This is an incredibly inefficient version of this function since it does a dozen or so UDP transactions.
47 : // This is done to be generic, but it could be hard-coded by assuming address offsets and bit maps and done in one
48 : // write and one read.
49 :
50 : // Set type of read
51 0 : WriteWithRetry(base_address + ".RW", 1);
52 : // Set address
53 0 : WriteWithRetry(base_address + ".ADDR", address);
54 : // Set read size
55 0 : WriteWithRetry(base_address + ".BYTE_COUNT", byte_count);
56 : // Wait for the last transaction to be done
57 0 : while (ReadWithRetry(base_address + ".DONE") == 0x0) {
58 0 : usleep(1000);
59 : }
60 : // Run transaction
61 0 : WriteWithRetry(base_address + ".RUN", 0x1);
62 : // Wait for the last transaction to be done
63 0 : while (ReadWithRetry(base_address + ".DONE") == 0x0) {
64 0 : usleep(1000);
65 : }
66 0 : if (ReadWithRetry(base_address + ".ERROR")) {
67 0 : printf("%s 0x%08X\n", (base_address + ".ERROR").c_str(), ReadWithRetry(base_address + ".ERROR"));
68 : // Reset the I2C firmware
69 0 : WriteWithRetry(base_address + ".RESET", 1);
70 0 : char trans_info[] = "rd @ 0xFFFF";
71 0 : sprintf(trans_info, "rd @ 0x%04X", address & 0xFFFF);
72 0 : BUException::WIB_ERROR e;
73 0 : e.Append("I2C Error on ");
74 0 : e.Append(base_address.c_str());
75 0 : e.Append(trans_info);
76 0 : throw e;
77 0 : }
78 0 : return ReadWithRetry(base_address + ".RD_DATA");
79 : }
80 : void
81 0 : WIBBase::WriteI2C(std::string const& base_address,
82 : uint16_t address,
83 : uint32_t data,
84 : uint8_t byte_count,
85 : bool ignore_error)
86 : {
87 : // This is an incredibly inefficient version of this function since it does a dozen or so UDP transactions.
88 : // This is done to be generic, but it could be hard-coded by assuming address offsets and bit maps and done in one
89 : // write and one read.
90 :
91 : // Set type of read
92 0 : WriteWithRetry(base_address + ".RW", 0);
93 : // Set address
94 0 : WriteWithRetry(base_address + ".ADDR", address);
95 : // Set read size
96 0 : WriteWithRetry(base_address + ".BYTE_COUNT", byte_count);
97 : // Send data to write
98 0 : WriteWithRetry(base_address + ".WR_DATA", data);
99 : // Wait for the last transaction to be done
100 0 : while (ReadWithRetry(base_address + ".DONE") == 0x0) {
101 0 : usleep(1000);
102 : }
103 : // Run transaction
104 0 : WriteWithRetry(base_address + ".RUN", 0x1);
105 :
106 : // Wait for the last transaction to be done
107 0 : while (ReadWithRetry(base_address + ".DONE") == 0x0) {
108 0 : usleep(1000);
109 : }
110 :
111 0 : if (!ignore_error && ReadWithRetry(base_address + ".ERROR")) {
112 : // Reset the I2C firmware
113 0 : WriteWithRetry(base_address + ".RESET", 1);
114 0 : char trans_info[] = "wr 0xFFFFFFFF @ 0xFFFF";
115 0 : sprintf(trans_info, "wr 0x%08X @ 0x%04X", data, address & 0xFFFF);
116 0 : BUException::WIB_ERROR e;
117 0 : e.Append("I2C Error on ");
118 0 : e.Append(base_address.c_str());
119 0 : e.Append(trans_info);
120 0 : throw e;
121 0 : }
122 0 : }
123 :
124 : Item const*
125 0 : WIBBase::GetItem(std::string const& str)
126 : {
127 0 : return wib->GetItem(str);
128 : }
129 :
130 : Item const*
131 0 : WIBBase::GetFEMBItem(int iFEMB, std::string const& str)
132 : {
133 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
134 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
135 0 : e.Append("In WIBBase::ReadFEMB\n");
136 0 : throw e;
137 0 : }
138 0 : return FEMB[iFEMB - 1]->GetItem(str);
139 : }
140 :
141 : uint32_t
142 0 : WIBBase::ReadWithRetry(uint16_t address)
143 : {
144 0 : return wib->ReadWithRetry(address);
145 : }
146 : uint32_t
147 0 : WIBBase::Read(uint16_t address)
148 : {
149 0 : return wib->Read(address);
150 : }
151 : uint32_t
152 0 : WIBBase::ReadWithRetry(std::string const& address)
153 : {
154 0 : return wib->ReadWithRetry(address);
155 : }
156 : uint32_t
157 0 : WIBBase::Read(std::string const& address)
158 : {
159 0 : return wib->Read(address);
160 : }
161 :
162 : void
163 0 : WIBBase::WriteWithRetry(uint16_t address, uint32_t value)
164 : {
165 0 : wib->WriteWithRetry(address, value);
166 0 : }
167 : void
168 0 : WIBBase::Write(uint16_t address, uint32_t value)
169 : {
170 0 : wib->Write(address, value);
171 0 : }
172 : void
173 0 : WIBBase::WriteWithRetry(std::string const& address, uint32_t value)
174 : {
175 0 : wib->WriteWithRetry(address, value);
176 0 : }
177 : void
178 0 : WIBBase::Write(std::string const& address, uint32_t value)
179 : {
180 0 : wib->Write(address, value);
181 0 : }
182 : void
183 0 : WIBBase::Write(uint16_t address, std::vector<uint32_t> const& values)
184 : {
185 0 : wib->Write(address, values);
186 0 : }
187 : void
188 0 : WIBBase::Write(std::string const& address, std::vector<uint32_t> const& values)
189 : {
190 0 : wib->Write(address, values);
191 0 : }
192 : void
193 0 : WIBBase::Write(uint16_t address, uint32_t const* values, size_t word_count)
194 : {
195 0 : wib->Write(address, values, word_count);
196 0 : }
197 : void
198 0 : WIBBase::Write(std::string const& address, uint32_t const* values, size_t word_count)
199 : {
200 0 : wib->Write(address, values, word_count);
201 0 : }
202 :
203 : uint32_t
204 0 : WIBBase::ReadFEMB(int iFEMB, uint16_t address)
205 : {
206 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
207 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
208 0 : e.Append("In WIBBase::ReadFEMB\n");
209 0 : throw e;
210 0 : }
211 0 : return FEMB[iFEMB - 1]->Read(address);
212 : usleep((useconds_t)FEMBReadSleepTime * 1e6);
213 : }
214 : uint32_t
215 0 : WIBBase::ReadFEMB(int iFEMB, std::string const& address)
216 : {
217 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
218 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
219 0 : e.Append("In WIBBase::ReadFEMB\n");
220 0 : throw e;
221 0 : }
222 0 : return FEMB[iFEMB - 1]->Read(address);
223 : usleep((useconds_t)FEMBReadSleepTime * 1e6);
224 : }
225 :
226 : void
227 0 : WIBBase::WriteFEMB(int iFEMB, uint16_t address, uint32_t value)
228 : {
229 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
230 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
231 0 : e.Append("In WIBBase::WriteFEMB\n");
232 0 : throw e;
233 0 : }
234 0 : FEMB[iFEMB - 1]->WriteWithRetry(address, value);
235 0 : usleep((useconds_t)FEMBWriteSleepTime * 1e6);
236 0 : }
237 : void
238 0 : WIBBase::WriteFEMB(int iFEMB, std::string const& address, uint32_t value)
239 : {
240 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
241 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
242 0 : e.Append("In WIBBase::WriteFEMB\n");
243 0 : throw e;
244 0 : }
245 0 : FEMB[iFEMB - 1]->WriteWithRetry(address, value);
246 0 : usleep((useconds_t)FEMBWriteSleepTime * 1e6);
247 0 : }
248 :
249 : void
250 0 : WIBBase::WriteFEMBBits(int iFEMB, uint16_t address, uint32_t pos, uint32_t mask, uint32_t value)
251 : {
252 0 : if ((iFEMB > 4) || (iFEMB < 1)) {
253 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
254 0 : e.Append("In WIBBase::WriteFEMB\n");
255 0 : throw e;
256 0 : }
257 :
258 0 : uint32_t shiftVal = value & mask;
259 0 : uint32_t regMask = (mask << pos);
260 0 : uint32_t initVal = FEMB[iFEMB - 1]->Read(address);
261 0 : uint32_t newVal = ((initVal & ~(regMask)) | (shiftVal << pos));
262 :
263 0 : FEMB[iFEMB - 1]->WriteWithRetry(address, newVal);
264 0 : usleep((useconds_t)FEMBWriteSleepTime * 1e6);
265 0 : }
266 :
267 : void
268 0 : WIBBase::EnableADC(uint64_t iFEMB, uint64_t enable)
269 : {
270 0 : if (iFEMB > 4 || iFEMB < 1) {
271 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
272 0 : e.Append("In WIBBase::Enable_ADC");
273 0 : throw e;
274 0 : }
275 0 : if (bool(enable))
276 0 : FEMB[iFEMB - 1]->Write(0x03, 0x00);
277 : else
278 0 : FEMB[iFEMB - 1]->Write(0x03, 0xFF);
279 0 : usleep((useconds_t)FEMBWriteSleepTime * 1e6);
280 0 : }
|