CbmRoot
Loading...
Searching...
No Matches
CbmTrdUnpackFaspAlgo.cxx
Go to the documentation of this file.
1/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pascal Raisig [committer], Alexandru Bercuci */
4
5
7
8#include "CbmTrdDigi.h"
9#include "CbmTrdParFasp.h"
10#include "CbmTrdParModAsic.h"
11#include "CbmTrdParModDigi.h"
12#include "CbmTrdParSetDigi.h"
13#include "CbmTrdParSetGain.h"
14#include "CbmTrdParSetGas.h"
15#include "CbmTrdParSpadic.h"
16
17#include <FairParAsciiFileIo.h>
18#include <FairParGenericSet.h>
19#include <FairParamList.h>
20#include <FairRuntimeDb.h>
21#include <FairTask.h>
22#include <Logger.h>
23
24#include <Rtypes.h>
25#include <RtypesCore.h>
26
27#include <boost/format.hpp>
28
29// select verbosity level
30// 0 : none
31// 1 : data unpacker
32// 2 : digi packing
33#define VERBOSE 0
34
35using namespace std;
36
37CbmTrdUnpackFaspAlgo::CbmTrdUnpackFaspAlgo() : CbmRecoUnpackAlgo("CbmTrdUnpackFaspAlgo") {}
38
39//_________________________________________________________________________________
41
42//_________________________________________________________________________________
43Bool_t CbmTrdUnpackFaspAlgo::initParSet(FairParGenericSet* parset)
44{
45 Int_t nModules(0), nAsics(0);
46 if (strcmp(parset->ClassName(), "CbmTrdParSetAsic") == 0) {
47 CbmTrdParSetAsic* setPar = static_cast<CbmTrdParSetAsic*>(parset);
48 for (auto did : fModuleId) {
49 auto setDet = static_cast<CbmTrdParModAsic*>(setPar->GetModulePar(did));
50 if (!setDet) continue;
51 if (setDet->GetAsicType() != CbmTrdDigi::eCbmTrdAsicType::kFASP) continue;
52 if (fMonitor) fMonitor->addParam(did, setDet);
53 fAsicSet.addParam(setDet);
54 nAsics += setDet->GetNofAsicsOnModule();
55 nModules++;
56 }
57 // fAsicSet.printParams();
58 LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << nModules
59 << " asics " << nAsics;
60 }
61 else if (strcmp(parset->ClassName(), "CbmTrdParSetDigi") == 0) {
62 fDigiSet = static_cast<CbmTrdParSetDigi*>(parset);
63 map<Int_t, CbmTrdParMod*> digiPar = fDigiSet->GetModuleMap();
64 for (auto digi : digiPar) {
65 fModuleId.emplace_back(digi.first);
66 if (fMonitor) fMonitor->addParam(digi.first, (CbmTrdParModDigi*) digi.second);
67 }
68 // setPar->printParams();
69 LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << fModuleId.size();
70 }
71 else if (strcmp(parset->ClassName(), "CbmTrdParSetGas") == 0) {
72 CbmTrdParSetGas* setPar = static_cast<CbmTrdParSetGas*>(parset);
73 setPar->printParams();
74 nModules = setPar->GetNrOfModules();
75 }
76 else if (strcmp(parset->ClassName(), "CbmTrdParSetGain") == 0) {
77 CbmTrdParSetGain* setPar = static_cast<CbmTrdParSetGain*>(parset);
78 setPar->printParams();
79 nModules = setPar->GetNrOfModules();
80 }
81 else {
82 LOG(error) << "Parameter set " << parset->ClassName() << " not known. Skip.";
83 return kFALSE;
84 }
85 return kTRUE;
86}
87
88//_________________________________________________________________________________
89std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
90CbmTrdUnpackFaspAlgo::GetParContainerRequest(std::string geoTag, std::uint32_t runId)
91{
92 LOG(info) << GetName() << "::GetParContainerRequest - for container " << geoTag.data() << " run " << runId << " "
93 << fParFilesBasePath.data();
94
95 // Basepath for default Trd parameter sets (those connected to a geoTag)
96 std::string basepath = Form("%s/trd_%s", fParFilesBasePath.data(), geoTag.data());
97 std::string temppath = "";
98
99 // Digest the runId information in case of runId = 0 we use the default fall back
100 std::string runpath = "";
101 if (runId != 0) {
102 runpath = ".run" + std::to_string(runId);
103 }
104
105 temppath = basepath + runpath + ".digi" + ".par";
106 fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetDigi>()));
107 temppath = basepath + runpath + ".asic" + ".par";
108 fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetAsic>()));
109 // temppath = basepath + runpath + ".gas" + ".par";
110 // fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGas>()));
111 // temppath = basepath + runpath + ".gain" + ".par";
112 // fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGain>()));
113
114 return &fParContVec;
115}
116
117//_________________________________________________________________________________
118bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspMessage> messes, const uint16_t mod_id)
119{
120 const UChar_t lFasp = messes[0].getFaspIdMod();
121 const CbmTrdParModAsic* asicPar = (CbmTrdParModAsic*) fAsicSet.GetModulePar(mod_id);
122 const CbmTrdParFasp* faspPar = (CbmTrdParFasp*) asicPar->GetAsicPar(mod_id * 1000 + lFasp);
123 const CbmTrdParModDigi* digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(mod_id);
124
125 // link data to the position on the padplane
126 if (!faspPar) {
127 LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << mod_id
128 << " missing. Skip.";
129 return false;
130 }
131 if (!digiPar) {
132 LOG(error) << GetName() << "::pushDigis - DIGI par for module " << mod_id << " missing. Skip.";
133 return false;
134 }
135
136 ULong64_t tdaqOffset(0);
138 // Add DAQ time calibration for legacy FASPRO.
139 if (digiPar->GetPadRow(faspPar->GetPadAddress(messes[0].ch)) % 2 == 0) tdaqOffset = 3;
140 }
141 if (VERBOSE) faspPar->Print();
142
143 for (auto imess : messes) {
144 const Int_t pad = faspPar->GetPadAddress(imess.ch);
145 const CbmTrdParFaspChannel* chCalib = faspPar->GetChannel(imess.ch);
146 if (chCalib->IsMasked()) {
147 LOG(warn) << GetName() << "::pushDigis - FASP par " << mod_id * 1000 + lFasp << " ch " << int(imess.ch)
148 << " masked but have data. Masks need attention.";
149 }
150 const ULong64_t lTime = fTime + tdaqOffset + imess.tlab;
151 const UShort_t lchR = chCalib->HasPairingR() ? imess.data : 0;
152 const UShort_t lchT = chCalib->HasPairingR() ? 0 : imess.data;
153 std::vector<CbmTrdDigi>& digiBuffer = fDigiBuffer[pad];
154
155 if (VERBOSE) {
156 const Int_t ch = 2 * pad + chCalib->HasPairingR();
157 imess.print();
158 printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] %c[%4d]\n", lFasp, ch, imess.ch, pad,
159 digiPar->GetPadRow(pad), digiPar->GetPadColumn(pad), (chCalib->HasPairingT() ? 'T' : 'R'),
160 lchT > 0 ? lchT : lchR);
161 }
162
163 if (digiBuffer.size() == 0) { // init pad position in map and build digi for message
164 digiBuffer.emplace_back(pad, lchT, lchR, lTime);
165 digiBuffer.back().SetAddressModule(mod_id);
166 continue;
167 }
168
169 // check if last digi has both R/T message components. Update if not and is within time window
170 auto id = digiBuffer.rbegin(); // Should always be valid here.
171 // No need to extra check
172 Double_t r, t;
173 Int_t dt;
174 const Int_t dtime = (*id).GetTimeDAQ() - lTime;
175 bool use(false);
176
177 if (TMath::Abs(dtime) < 5) { // test message part of (last) digi
178 r = (*id).GetCharge(t, dt);
179 if (lchR && r < 0.1) { // set R charge on an empty slot
180 (*id).SetCharge(t, lchR, -dtime);
181 use = true;
182 }
183 else if (lchT && t < 0.1) { // set T charge on an empty slot
184 (*id).SetCharge(lchT, r, +dtime);
185 (*id).SetTimeDAQ(ULong64_t((*id).GetTimeDAQ() - dtime));
186 use = true;
187 }
188 }
189
190 // build digi for message when update failed
191 if (!use) {
192 digiBuffer.emplace_back(pad, lchT, lchR, lTime);
193 digiBuffer.back().SetAddressModule(mod_id);
194 id = digiBuffer.rbegin();
195 }
196
197 // LEGACY CODE:
199 // update charge for previously allocated digis
200 // to account for FASPRO ADC buffering and read-out feature
201 for (++id; id != digiBuffer.rend(); ++id) {
202 r = (*id).GetCharge(t, dt);
203 if (lchR && int(r)) { // update R charge and mark on digi
204 (*id).SetCharge(t, lchR, dt);
205 (*id).SetFlag(1);
206 break;
207 }
208 else if (lchT && int(t)) { // update T charge and mark on digi
209 (*id).SetCharge(lchT, r, dt);
210 (*id).SetFlag(0);
211 break;
212 }
213 }
214 }
215 }
216 messes.clear();
217
218 return true;
219}
220
222{
223 uint32_t uNbLostDigis = 0;
226
227 for (auto pad_id(0); pad_id < NFASPMOD * NFASPCH; pad_id++) {
228 if (!fDigiBuffer[pad_id].size()) continue;
229
230 LOG(warn) << fName << "::ResetTimeslice - buffered digi pad=" << pad_id << " store " << fDigiBuffer[pad_id].size()
231 << " unprocessed digi.";
232 uNbLostDigis += fDigiBuffer[pad_id].size();
233
234 fDigiBuffer[pad_id].clear();
235 }
236 return uNbLostDigis;
237}
238
240{
241 Double_t r, t;
242 Int_t dt;
243 // push finalized digits to the next level
244 for (uint16_t ipad(0); ipad < NFASPMOD * NFASPCH; ipad++) {
245 if (!fDigiBuffer[ipad].size()) continue;
246 uint nIncomplete(0);
247 for (auto id = fDigiBuffer[ipad].begin(); id != fDigiBuffer[ipad].end(); id++) {
248 r = (*id).GetCharge(t, dt);
249
250 // LEGACY CODE:
252 // check if digi has all signals CORRECTED
253 if (((t > 0) != (*id).IsFlagged(0)) || ((r > 0) != (*id).IsFlagged(1))) {
254 nIncomplete++;
255 continue;
256 }
257 }
258 if (fMonitor) fMonitor->FillHistos((&(*id)));
259 // reset flags as they were used only to mark the correctly setting of the charge/digi
260 (*id).SetFlag(0, false);
261 (*id).SetFlag(1, false);
262 fOutputVec.emplace_back(std::move((*id)));
263 }
264 // clear digi buffer wrt the digi which was forwarded to higher structures
265 fDigiBuffer[ipad].clear();
266 if (nIncomplete > 2) {
267 LOG(warn) << fName << "FinalizeComponent() skip " << nIncomplete << " incomplete digi at pad " << ipad << ".\n";
268 }
269 }
270}
271
272// ----unpack----
273bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice)
274{
275 if (VERBOSE) printf("CbmTrdUnpackFaspAlgo::unpack 0x%04x %d\n", icomp, imslice);
276 LOG(debug2) << "Component " << icomp << " connected to config CbmTrdUnpackConfig2D. Slice " << imslice;
277
278 bool unpackOk = true;
279 //Double_t fdMsSizeInNs = 1.28e6;
280
281 auto msdesc = ts->descriptor(icomp, imslice);
282
283 // Cast required to silence a warning on macos (there a uint64_t is a llu)
284 if (VERBOSE)
285 printf("time start %lu system[0x%x] version[0x%x]\n", static_cast<size_t>(msdesc.idx), msdesc.sys_id,
286 msdesc.sys_ver);
287
288 // this is executed only once, at the beginning, after discovering the packing version of the data
289 if (!fMess) {
290 switch (msdesc.sys_ver) {
292 LOG(info) << "CbmTrdUnpackFaspAlgo::unpack : Legacy version.";
293 fMess = new CbmTrdFaspMessage();
294 break;
295 case (int) eMessageVersion::kMess24:
296 LOG(info) << "CbmTrdUnpackFaspAlgo::unpack : 06.2024 version.";
298 break;
299 default: LOG(fatal) << "CbmTrdUnpackFaspAlgo::unpack : Un-registered version " << msdesc.sys_ver; break;
300 }
301 }
302 // define time wrt start of time slice in TRD/FASP clks [80 MHz]
303 fTime = ULong64_t((msdesc.idx - fTsStartTime - fSystemTimeOffset) / 12.5);
304
305 // get MOD_id and ROB id from the equipment, using the comp map: eq_id -> (mod_id, rob_id)
306 fMess->mod = fAsicSet.FindModuleByEqId(msdesc.eq_id, fMess->rob, fMess->elink);
307 //printf("AB :: eq_id[0x%x] -> rob[%d] link[%d] mod[%d]\n", msdesc.eq_id, fMess->rob, fMess->elink, fMess->mod);
308 // Get the µslice size in bytes to calculate the number of completed words
309 auto mssize = msdesc.size;
310
311 // Get the number of complete words in the input MS buffer.
312 std::uint32_t nwords = mssize / 4; //fBytesPerWord;
313
314 const auto mspointer = ts->content(icomp, imslice);
315
316 // We have 32 bit spadic frames in this readout version
317 const auto mscontent = reinterpret_cast<const size_t*>(mspointer);
318
319 const uint32_t* wd = reinterpret_cast<const uint32_t*>(mscontent);
320
321
322 uint8_t lFaspOld(0xff);
323 vector<CbmTrdFaspMessage> vMess;
324 for (uint64_t j = 0; j < nwords; j++, wd++) {
325 uint32_t w = *wd;
326 // Select the appropriate conversion type of the word according to
327 // the message version and type
328 switch (fMess->getType(w)) {
329 case eMessageType::kData: fMess->readDW(w); break;
330 case eMessageType::kEpoch: fMess->readEW(w); break;
331 default: break;
332 }
333
334 // uint8_t ch_id = w & 0xf;
335 // uint8_t isaux = (w >> 4) & 0x1;
336 // uint8_t slice = (w >> 5) & 0x7f;
337 // uint16_t data = (w >> 12) & 0x3fff;
338 // uint32_t epoch = (w >> 5) & 0x1fffff;
339 // uint8_t fasp_id = ((w >> 26) & 0x3f) + crob_id * NFASPCROB;
340 // std::cout<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl;
341 if (fMess->type == (int) eMessageType::kEpoch) {
342 if (!fMess->ch) {
343 // clear buffer
344 if (vMess.size()) pushDigis(vMess, fMess->mod);
345 vMess.clear();
346
347 if (VERBOSE) fMess->print();
348
349 lFaspOld = 0xff;
351 }
352 else {
353 LOG(error) << "CbmTrdUnpackFaspAlgo::unpack : Epoch message with wrong signature. Ask an expert.";
354 }
355 continue;
356 }
357
358 if (lFaspOld != fMess->getFaspIdMod()) {
359 // push
360 if (vMess.size()) pushDigis(vMess, fMess->mod);
361 vMess.clear();
362 lFaspOld = fMess->getFaspIdMod();
363 }
364 if (VERBOSE) fMess->print();
365 vMess.emplace_back(*fMess);
366 //vMess.emplace_back(crob_id, lFaspOld, ch_id, kData, slice, data >> 1);
367 }
368 return unpackOk;
369}
370
371//_________________________________________________________________________________
372CbmTrdUnpackFaspAlgo::CbmTrdFaspMessage::CbmTrdFaspMessage(uint8_t rdaq, uint8_t asic, uint8_t c, uint8_t typ,
373 uint8_t t, uint16_t d, uint8_t lnk)
374 : ch(c)
375 , type(typ)
376 , tlab(t)
377 , data(d)
378 , rob(rdaq)
379 , elink(lnk)
380 , fasp(asic)
381{
382}
383
384//_________________________________________________________________________________
390
391//_____________________________________________________________
393{
394 uint8_t shift(0);
395 ch = w & 0xf;
396 shift += uint8_t(eMessageLength::kMessCh);
397 type = (w >> shift) & 0x1;
398 shift += uint8_t(eMessageLength::kMessType);
399 tlab = (w >> shift) & 0x7f;
400 shift += uint8_t(eMessageLength::kMessTlab);
401 data = (w >> shift) & 0x3fff;
402 data = data >> 1;
403 shift += uint8_t(eMessageLength::kMessData);
404 fasp = ((w >> shift) & 0x3f);
405
406 if (VERBOSE >= 2) {
407 printf("legacyMess_readDW[%x]\n", w);
408 print();
409 }
410}
411
412//_________________________________________________________________________________
414{
415 uint8_t shift(0);
416 ch = w & 0xf;
417 shift += uint8_t(eMessageLength::kMessCh);
418 type = (w >> shift) & 0x1;
419 shift += uint8_t(eMessageLength::kMessType);
420 epoch = (w >> shift) & 0x1fffff;
421 shift += uint8_t(eMessageLength::kMessEpoch);
422 fasp = (w >> shift) & 0x3f;
423
424 if (VERBOSE >= 2) {
425 printf("legacyMess_readEW[%x]\n", w);
426 print();
427 }
428}
429
430//_________________________________________________________________________________
432{
433 if (type == (uint8_t) eMessageType::kData)
434 cout << Form(" DATA : rob=%d%c fasp_id=%02d [%03d] ch_id=%02d tclk=%03d data=%4d\n", rob, (elink ? 'u' : 'd'),
435 fasp, getFaspIdMod(), ch, tlab, data);
436 else if (type == (uint8_t) eMessageType::kEpoch)
437 cout << Form(" EPOCH: eq_id=%d%c ch_id=%02d epoch=%05d\n", rob, (elink ? 'u' : 'd'), ch, epoch);
438 else
439 cout << " MTYPE: unknown";
440}
441
442//_________________________________________________________________________________
447
448//_________________________________________________________________________________
450{
451 //printf("mess_type[%x]\n", wd);
452 if ((wd >> 31) & 0x1) return eMessageType::kEpoch;
453 return eMessageType::kData;
454}
455
456//_____________________________________________________________
458{
459 uint8_t shift(0);
460 uint16_t adc_data = (w >> shift) & 0x3fff;
461 // TODO This data format version delivers the ADC value as bit_sgn + 13 significant bits
462 // TODO The CbmTrdDigi supports digi data with only 12bits unsigned. The first tests will
463 // TODO convert the measurement to the old format leaving the implementation of the new storage to // TODO later time. (AB 14.06.2024)
464 uint16_t sign = adc_data >> 13; // sign
465 int value_i;
466 if (!sign)
467 value_i = adc_data;
468 else
469 value_i = (-1) * ((adc_data ^ 0xffff) & 0x1fff);
470 // convert to 12bit unsigned
471 data = (value_i + 0x1fff) >> 2;
472 shift += uint8_t(eMessageLength::kMessData);
473 tlab = (w >> shift) & 0x7f;
474 shift += uint8_t(eMessageLength::kMessTlab);
475 ch = (w >> shift) & 0xf;
476 shift += uint8_t(eMessageLength::kMessCh);
477 fasp = ((w >> shift) & 0x3f);
478 shift += uint8_t(eMessageLength::kMessFasp);
479 type = (w >> shift) & 0x1;
480 shift += uint8_t(eMessageLength::kMessType);
481
482 if (VERBOSE >= 2) {
483 printf("v06.24Mess_readDW[%x] signed charge = %+d\n", w, value_i);
484 print();
485 }
486}
487
488//_________________________________________________________________________________
490{
491 uint8_t shift(0);
492 epoch = (w >> shift) & 0x1fffff;
493 shift += uint8_t(eMessageLength::kMessEpoch);
494 ch = (w >> shift) & 0xf;
495 shift += uint8_t(eMessageLength::kMessCh);
496 fasp = (w >> shift) & 0x3f;
497 shift += uint8_t(eMessageLength::kMessFasp);
498 type = (w >> shift) & 0x1;
499 shift += uint8_t(eMessageLength::kMessType);
500
501 if (VERBOSE >= 2) {
502 printf("v06.24Mess_readEW[%x]\n", w);
503 print();
504 }
505}
506
ClassImp(CbmConverterManager)
#define VERBOSE
Trd FASP unpacking algorithm.
static constexpr size_t size()
Definition KfSimdPseudo.h:2
Definition of FASP channel calibration container.
Bool_t HasPairingR() const
Query pad pairing type.
bool IsMasked() const
Bool_t HasPairingT() const
Definition of FASP parameters.
virtual void Print(Option_t *opt="") const
const CbmTrdParFaspChannel * GetChannel(Int_t pad_address, UChar_t pair) const
Query the calibration for one FASP RO channel.
int GetPadAddress(Int_t ich) const
Describe TRD module ASIC settings (electronic gain, delays, etc)
virtual const CbmTrdParAsic * GetAsicPar(Int_t address) const
Look for the ASIC parameters of a given DAQ id It applies to the list of ASICs.
Definition of chamber gain conversion for one TRD module.
Int_t GetPadRow(const Int_t channelNumber) const
Int_t GetPadColumn(const Int_t channelNumber) const
Describe TRD module ASIC settings (electronic gain, delays, etc)
virtual int FindModuleByEqId(uint16_t eqid, uint8_t &rob_id, uint8_t &lnk_id) const
Search for the module in the setup parameters by equipement id.
Describe TRD module working settings (HV, etc)
virtual Int_t GetNrOfModules() const
virtual const CbmTrdParMod * GetModulePar(Int_t detId) const
std::map< Int_t, CbmTrdParMod * > GetModuleMap()
virtual void addParam(CbmTrdParMod *mod)
virtual eMessageType getType(uint32_t w) const
Data structure for unpacking the FASP word.
uint8_t elink
optical link for read-out unit (up or down, starting with v2024)
uint8_t type
message type 0 = data, 1 = epoch
uint8_t rob
Read-Out unit id in the module.
virtual eMessageType getType(uint32_t w) const
uint32_t mod
full module address according to CbmTrdAddress
std::array< std::vector< CbmTrdDigi >, NFASPMOD *NFASPCH > fDigiBuffer
uint32_t ResetTimeslice()
Check and assure there are no data left-overs.
virtual std::vector< std::pair< std::string, std::shared_ptr< FairParGenericSet > > > * GetParContainerRequest(std::string geoTag, std::uint32_t runId)
Get the requested parameter containers. Return the required parameter containers together with the pa...
bool unpack(const fles::Timeslice *ts, std::uint16_t icomp, UInt_t imslice)
Unpack a given microslice.
@ kMess24
unpacker version for 2-board FASPRO+GETS HW
CbmTrdUnpackFaspAlgo()
Create the Cbm Trd Unpack AlgoBase object.
std::vector< uint16_t > fModuleId
CbmTrdFaspMessage * fMess
Bool_t initParSet(FairParGenericSet *parset)
Handles the distribution of the hidden derived classes to their explicit functions.
void FinalizeComponent()
Finalize component (e.g. copy from temp buffers)
std::shared_ptr< CbmTrdUnpackFaspMonitor > fMonitor
Potential (online) monitor for the unpacking process.
bool pushDigis(std::vector< CbmTrdUnpackFaspAlgo::CbmTrdFaspMessage > messages, const uint16_t mod_id)
CbmTrdParSetDigi * fDigiSet
virtual ~CbmTrdUnpackFaspAlgo()
Destroy the Cbm Trd Unpack Task object.
ULong64_t fTime
Time offset for digi wrt the TS start, expressed in 80 MHz clks. It contains:
Hash for CbmL1LinkKey.
#define NFASPCH
#define NFASPMOD
#define FASP_EPOCH_LENGTH