Line data Source code
1 :
2 : #include "TRACE/tracemf.h"
3 :
4 : // #define TRACE_NAME "DTCSoftwareCFO"
5 : // #define TRACE_NAME (strstr(&__FILE__[0], "/srcs/") ? strstr(&__FILE__[0], "/srcs/") + 6 : __FILE__) /* TOO LONG */
6 : #define TRACE_NAME &std::string(__FILE__).substr(std::string(__FILE__).rfind('/', std::string(__FILE__).rfind('/') - 1) + 1)[0]
7 : #include <iostream>
8 : #include "DTCSoftwareCFO.h"
9 :
10 : #define Q(X) #X
11 : #define QUOTE(X) Q(X)
12 : #define VAL(X) QUOTE(X) << " = " << X
13 :
14 : #define TLVL_SendRequestsForTimestamp TLVL_DEBUG + 5
15 : #define TLVL_SendRequestsForTimestamp2 TLVL_DEBUG + 6
16 : #define TLVL_SendRequestsForRange TLVL_DEBUG + 7
17 : #define TLVL_SendRequestsForRange2 TLVL_DEBUG + 8
18 : #define TLVL_SendRequestsForRangeImpl TLVL_DEBUG + 9
19 :
20 0 : DTCLib::DTCSoftwareCFO::DTCSoftwareCFO(DTC* dtc, bool useCFOEmulator, uint16_t debugPacketCount,
21 : DTC_DebugType debugType, bool stickyDebugType, bool quiet, bool asyncRR,
22 0 : bool forceNoDebug, bool useCFODRP)
23 0 : : useCFOEmulator_(useCFOEmulator), debugPacketCount_(debugPacketCount), debugType_(debugType), stickyDebugType_(stickyDebugType), quiet_(quiet), asyncRR_(asyncRR), forceNoDebug_(forceNoDebug), theThread_(nullptr), requestsSent_(false), abort_(false)
24 : {
25 0 : theDTC_ = dtc;
26 0 : for (auto link : DTC_ROC_Links)
27 : {
28 0 : linkMode_[link] = theDTC_->ReadLinkEnabled(link);
29 : }
30 :
31 0 : if (useCFODRP)
32 : {
33 0 : theDTC_->DisableAutogenDRP();
34 0 : theDTC_->EnableCFOEmulatorDRP();
35 : }
36 : else
37 : {
38 0 : theDTC_->DisableCFOEmulatorDRP();
39 0 : theDTC_->EnableAutogenDRP();
40 : }
41 0 : theDTC_->SetAllEventModeWords(1U);
42 0 : theDTC_->SetEventModeWord(0, 0U);
43 0 : }
44 :
45 0 : DTCLib::DTCSoftwareCFO::~DTCSoftwareCFO()
46 : {
47 0 : TLOG(TLVL_TRACE) << "~DTCSoftwareCFO BEGIN";
48 : // theDTC_->DisableAutogenDRP();
49 : // theDTC_->DisableCFOEmulatorDRP();
50 0 : abort_ = true;
51 0 : if (theThread_ && theThread_->joinable()) theThread_->join();
52 0 : TLOG(TLVL_TRACE) << "~DTCSoftwareCFO END";
53 0 : }
54 :
55 0 : void DTCLib::DTCSoftwareCFO::WaitForRequestsToBeSent() const
56 : {
57 0 : while (!requestsSent_)
58 : {
59 0 : usleep(1000);
60 : }
61 0 : }
62 :
63 0 : void DTCLib::DTCSoftwareCFO::SendRequestForTimestamp(DTC_EventWindowTag ts, uint32_t heartbeatsAfter, bool sendHeartbeats /* = true */)
64 : {
65 0 : if (theDTC_->IsDetectorEmulatorInUse())
66 : {
67 0 : TLOG(TLVL_SendRequestsForTimestamp) << "Enabling Detector Emulator for 1 DMA";
68 : // theDTC_->SoftReset();
69 0 : theDTC_->DisableDetectorEmulator();
70 0 : theDTC_->SetDetectorEmulationDMACount(1);
71 0 : theDTC_->EnableDetectorEmulator();
72 0 : return;
73 : }
74 0 : if (!useCFOEmulator_)
75 : {
76 0 : theDTC_->EnableSoftwareDRP();
77 0 : for (auto link : DTC_ROC_Links)
78 : {
79 0 : if (linkMode_[link].TransmitEnable)
80 : {
81 0 : if (sendHeartbeats)
82 : {
83 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp before SendHeartbeatPacket";
84 0 : theDTC_->SendHeartbeatPacket(link, ts, quiet_);
85 : }
86 :
87 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp before DTC_DataRequestPacket req";
88 0 : DTC_DataRequestPacket req(link, ts, !forceNoDebug_, debugPacketCount_, debugType_);
89 0 : if (debugType_ == DTC_DebugType_ExternalSerialWithReset && !stickyDebugType_)
90 : {
91 0 : debugType_ = DTC_DebugType_ExternalSerial;
92 : }
93 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp before WriteDMADAQPacket - DTC_DataRequestPacket";
94 0 : if (!quiet_) std::cout << req.toJSON() << std::endl;
95 0 : theDTC_->WriteDMAPacket(req);
96 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp after WriteDMADAQPacket - DTC_DataRequestPacket";
97 :
98 0 : for (uint32_t ii = 1; sendHeartbeats && ii <= heartbeatsAfter; ++ii)
99 : {
100 0 : theDTC_->SendHeartbeatPacket(link, ts + ii, quiet_);
101 0 : usleep(1000);
102 : }
103 : // usleep(2000);
104 0 : }
105 : }
106 : }
107 : else
108 : {
109 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp setting up DTC CFO Emulator";
110 0 : theDTC_->SetCFOEmulationMode();
111 0 : theDTC_->DisableCFOEmulation();
112 0 : theDTC_->SetCFOEmulationTimestamp(ts);
113 0 : for (auto link : DTC_ROC_Links)
114 : {
115 0 : if (linkMode_[link].TransmitEnable)
116 : {
117 0 : theDTC_->SetROCEmulationNumPackets(link, debugPacketCount_);
118 : }
119 : }
120 0 : theDTC_->SetCFOEmulationNumHeartbeats(1);
121 0 : theDTC_->SetCFOEmulationEventWindowInterval(20000);
122 : // theDTC_->SetCFOEmulationDebugType(debugType_);
123 0 : theDTC_->SetCFOEmulationModeByte(5, 1);
124 0 : theDTC_->SetCFOEmulationNumNullHeartbeats(heartbeatsAfter);
125 : // if (!forceNoDebug_)
126 : // theDTC_->EnableDebugPacketMode();
127 : // else
128 : // theDTC_->DisableDebugPacketMode();
129 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp enabling DTC CFO Emulator";
130 0 : theDTC_->EnableCFOEmulation();
131 0 : TLOG(TLVL_SendRequestsForTimestamp2) << "SendRequestForTimestamp done";
132 : }
133 0 : requestsSent_ = true;
134 : }
135 :
136 0 : void DTCLib::DTCSoftwareCFO::SendRequestsForRange(int count, DTC_EventWindowTag start, bool increment,
137 : uint32_t delayBetweenDataRequests, int requestsAhead,
138 : uint32_t heartbeatsAfter, bool sendHeartbeats /* = true */)
139 : {
140 0 : if (theDTC_->IsDetectorEmulatorInUse())
141 : {
142 0 : TLOG(TLVL_SendRequestsForRange) << "Enabling Detector Emulator for " << count << " DMAs";
143 :
144 : // theDTC_->SoftReset();
145 0 : theDTC_->DisableDetectorEmulator();
146 0 : theDTC_->SetDetectorEmulationDMACount(count + 1);
147 0 : theDTC_->EnableDetectorEmulator();
148 0 : return;
149 : }
150 :
151 : // the minimal heartbeat interval is 0x20, or 800 ns
152 0 : if (delayBetweenDataRequests < 0x20)
153 0 : delayBetweenDataRequests = 0x20;
154 :
155 0 : TLOG(TLVL_SendRequestsForRange2) << VAL(count);
156 0 : TLOG(TLVL_SendRequestsForRange2) << VAL(delayBetweenDataRequests);
157 0 : TLOG(TLVL_SendRequestsForRange2) << VAL(requestsAhead);
158 0 : TLOG(TLVL_SendRequestsForRange2) << VAL(heartbeatsAfter);
159 :
160 0 : if (!useCFOEmulator_)
161 : {
162 0 : requestsSent_ = false;
163 0 : if (asyncRR_)
164 : {
165 0 : if (theThread_ && theThread_->joinable()) theThread_->join();
166 0 : theThread_.reset(new std::thread(&DTCSoftwareCFO::SendRequestsForRangeImplAsync, this, start, count, increment,
167 0 : delayBetweenDataRequests, heartbeatsAfter, sendHeartbeats));
168 : }
169 : else
170 : {
171 0 : if (theThread_ && theThread_->joinable()) theThread_->join();
172 0 : theThread_.reset(new std::thread(&DTCSoftwareCFO::SendRequestsForRangeImplSync, this, start, count, increment,
173 0 : delayBetweenDataRequests, requestsAhead, heartbeatsAfter, sendHeartbeats));
174 : }
175 0 : WaitForRequestsToBeSent();
176 : }
177 : else
178 : {
179 0 : TLOG(TLVL_SendRequestsForRange) << "SendRequestsForRange setting up DTC CFO Emulator";
180 :
181 0 : theDTC_->SetCFOEmulationMode();
182 0 : theDTC_->DisableCFOEmulation();
183 0 : theDTC_->SetCFOEmulationTimestamp(start);
184 0 : for (auto link : DTC_ROC_Links)
185 : {
186 0 : if (linkMode_[link].TransmitEnable)
187 : {
188 0 : theDTC_->SetROCEmulationNumPackets(link, debugPacketCount_);
189 : }
190 : }
191 0 : theDTC_->SetCFOEmulationNumHeartbeats(count);
192 : // theDTC_->SetCFOEmulationDebugType(debugType_);
193 0 : theDTC_->SetCFOEmulationModeByte(5, 1);
194 0 : theDTC_->SetCFOEmulationNumNullHeartbeats(heartbeatsAfter);
195 : // if (!forceNoDebug_)
196 : // theDTC_->EnableDebugPacketMode();
197 : // else
198 : // theDTC_->DisableDebugPacketMode();
199 0 : theDTC_->SetCFOEmulationEventWindowInterval(delayBetweenDataRequests);
200 0 : TLOG(TLVL_SendRequestsForRange) << "SendRequestsForRange enabling DTC CFO Emulator";
201 0 : theDTC_->EnableCFOEmulation();
202 0 : TLOG(TLVL_SendRequestsForRange) << "SendRequestsForRange done";
203 : }
204 : }
205 :
206 0 : void DTCLib::DTCSoftwareCFO::SendRequestsForList(std::set<DTC_EventWindowTag> timestamps,
207 : uint32_t delayBetweenDataRequests,
208 : uint32_t heartbeatsAfter)
209 : {
210 0 : if (theDTC_->IsDetectorEmulatorInUse())
211 : {
212 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "Enabling Detector Emulator for " << timestamps.size() << " DMAs";
213 : // theDTC_->SoftReset();
214 0 : theDTC_->DisableDetectorEmulator();
215 0 : theDTC_->SetDetectorEmulationDMACount(timestamps.size() + 1);
216 0 : theDTC_->EnableDetectorEmulator();
217 0 : return;
218 : }
219 :
220 0 : if (theThread_ && theThread_->joinable()) theThread_->join();
221 0 : theThread_.reset(
222 0 : new std::thread(&DTCSoftwareCFO::SendRequestsForListImplAsync, this, timestamps, delayBetweenDataRequests, heartbeatsAfter));
223 : }
224 :
225 0 : void DTCLib::DTCSoftwareCFO::SendRequestsForListImplAsync(std::set<DTC_EventWindowTag> timestamps,
226 : uint32_t delayBetweenDataRequests,
227 : uint32_t heartbeatsAfter)
228 : {
229 : //-----------------------------------------------------------------------------
230 : // P.Murat: according to Ryan , who referred to Rick K., the minimal heartbeat
231 : // interval is 0x20, or 800 ns
232 : //-----------------------------------------------------------------------------
233 0 : if (delayBetweenDataRequests < 0x20)
234 : {
235 0 : delayBetweenDataRequests = 0x20;
236 : }
237 :
238 0 : auto ii = timestamps.begin();
239 0 : while (ii != timestamps.end() && !abort_)
240 : {
241 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "Setting up CFO Emulator for next entry in list";
242 0 : auto thisTimestamp = *ii;
243 0 : ++ii;
244 0 : DTC_EventWindowTag nextTimestamp = thisTimestamp + 5; // Generate 5 nulls at the end of the list
245 0 : if (ii != timestamps.end())
246 : {
247 0 : nextTimestamp = *ii;
248 : }
249 :
250 0 : theDTC_->SetCFOEmulationMode();
251 0 : theDTC_->DisableCFOEmulation();
252 0 : theDTC_->SetCFOEmulationTimestamp(thisTimestamp);
253 0 : for (auto link : DTC_ROC_Links)
254 : {
255 0 : if (linkMode_[link].TransmitEnable)
256 : {
257 0 : theDTC_->SetROCEmulationNumPackets(link, debugPacketCount_);
258 : }
259 : }
260 0 : theDTC_->SetCFOEmulationNumHeartbeats(1);
261 0 : theDTC_->SetCFOEmulationNumNullHeartbeats(heartbeatsAfter);
262 : // theDTC_->SetCFOEmulationDebugType(debugType_);
263 0 : theDTC_->SetCFOEmulationModeByte(5, 1);
264 : // if (!forceNoDebug_)
265 : // theDTC_->EnableDebugPacketMode();
266 : // else
267 : // theDTC_->DisableDebugPacketMode();
268 0 : theDTC_->SetCFOEmulationEventWindowInterval(delayBetweenDataRequests);
269 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRange enabling DTC CFO Emulator";
270 0 : theDTC_->EnableCFOEmulation();
271 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRange done";
272 0 : }
273 0 : }
274 :
275 0 : void DTCLib::DTCSoftwareCFO::SendRequestsForRangeImplSync(DTC_EventWindowTag start, int count, bool increment,
276 : uint32_t delayBetweenDataRequests, int requestsAhead,
277 : uint32_t heartbeatsAfter, bool sendHeartbeats /* = true */)
278 : {
279 : try
280 : {
281 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImplSync Start";
282 0 : for (auto ii = 0; ii < count; ++ii)
283 : {
284 0 : auto ts = start + (increment ? ii : 0);
285 :
286 0 : SendRequestForTimestamp(ts, heartbeatsAfter, sendHeartbeats);
287 0 : if (ii >= requestsAhead || ii == count - 1)
288 : {
289 0 : requestsSent_ = true;
290 : }
291 :
292 0 : usleep(delayBetweenDataRequests);
293 0 : if (abort_) return;
294 0 : }
295 : }
296 0 : catch (const std::exception& e)
297 : {
298 0 : TLOG(TLVL_ERROR) << e.what() << '\n';
299 0 : }
300 : }
301 :
302 0 : void DTCLib::DTCSoftwareCFO::SendRequestsForRangeImplAsync(DTC_EventWindowTag start, int count, bool increment,
303 : uint32_t delayBetweenDataRequests, uint32_t heartbeatsAfter,
304 : bool sendHeartbeats /* = true */)
305 : {
306 : try
307 : {
308 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImplAsync Start";
309 :
310 : // Send Readout Requests first
311 0 : for (auto ii = 0; ii < count; ++ii)
312 : {
313 0 : auto ts = start + (increment ? ii : 0);
314 0 : for (auto link : DTC_ROC_Links)
315 : {
316 0 : if (linkMode_[link].TransmitEnable && sendHeartbeats)
317 : {
318 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl before SendHeartbeatPacket";
319 0 : theDTC_->SendHeartbeatPacket(link, ts, quiet_);
320 : }
321 0 : if (abort_) return;
322 : }
323 0 : }
324 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl setting RequestsSent flag";
325 0 : requestsSent_ = true;
326 :
327 : // Now do the DataRequests, sleeping for the required delay between each.
328 0 : for (auto ii = 0; ii < count; ++ii)
329 : {
330 0 : auto ts = start + (increment ? ii : 0);
331 0 : for (auto link : DTC_ROC_Links)
332 : {
333 0 : if (linkMode_[link].TransmitEnable)
334 : {
335 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl before DTC_DataRequestPacket req";
336 0 : DTC_DataRequestPacket req(link, ts, !forceNoDebug_, static_cast<uint16_t>(debugPacketCount_), debugType_);
337 0 : if (debugType_ == DTC_DebugType_ExternalSerialWithReset && !stickyDebugType_)
338 : {
339 0 : debugType_ = DTC_DebugType_ExternalSerial;
340 : }
341 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl before WriteDMADAQPacket - DTC_DataRequestPacket";
342 0 : if (!quiet_) std::cout << req.toJSON() << std::endl;
343 0 : theDTC_->WriteDMAPacket(req);
344 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl after WriteDMADAQPacket - DTC_DataRequestPacket";
345 0 : if (abort_) return;
346 0 : }
347 0 : if (abort_) return;
348 : }
349 0 : usleep(delayBetweenDataRequests);
350 0 : }
351 :
352 0 : for (uint32_t ii = 0; ii < heartbeatsAfter; ++ii)
353 : {
354 0 : auto ts = start + (increment ? count + ii : 0);
355 0 : for (auto link : DTC_ROC_Links)
356 : {
357 0 : if (linkMode_[link].TransmitEnable && sendHeartbeats)
358 : {
359 0 : TLOG(TLVL_SendRequestsForRangeImpl) << "SendRequestsForRangeImpl before SendHeartbeatPacket";
360 0 : theDTC_->SendHeartbeatPacket(link, ts, quiet_);
361 : }
362 0 : if (abort_) return;
363 : }
364 0 : }
365 : }
366 0 : catch (const std::exception& e)
367 : {
368 0 : TLOG(TLVL_ERROR) << e.what() << '\n';
369 0 : }
370 : }
|