11 #include <pxd/unpacking/PXDRawDataStructs.h>
12 #include <pxd/unpacking/PXDRawDataDefinitions.h>
13 #include <framework/logging/Logger.h>
15 #include <boost/crc.hpp>
31 typedef boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false>
dhc_crc_32_type;
33 using boost::spirit::endian::ubig16_t;
34 using boost::spirit::endian::ubig32_t;
35 using namespace Belle2::PXD::PXDError;
40 const char* dhc_type_name[16] = {
41 (
const char*)
"DHP_RAW",
42 (
const char*)
"FCE_RAW",
43 (
const char*)
"GHOST ",
44 (
const char*)
"H_START",
45 (
const char*)
"H_END ",
46 (
const char*)
"DHP_ZSD",
47 (
const char*)
"COMMODE",
48 (
const char*)
"undef ",
49 (
const char*)
"undef ",
50 (
const char*)
"ONS_FCE",
51 (
const char*)
"undef ",
52 (
const char*)
"C_START",
53 (
const char*)
"C_END ",
54 (
const char*)
"ONS_DHP",
55 (
const char*)
"ONS_TRG",
56 (
const char*)
"ONS_ROI"
58 B2DEBUG(99,
"DHC FRAME TYP $" << std::hex << getFrameType() <<
" -> " << dhc_type_name[getFrameType()] <<
" (ERR " << getErrorFlag()
59 <<
") data " << data);
62 bool dhc_start_frame::isFakedData(
void)
const
64 if (word0.data != 0x5800)
return false;
65 if (trigger_nr_lo != 0)
return false;
66 if (trigger_nr_hi != 0)
return false;
67 if (time_tag_lo_and_type != 0)
return false;
68 if (time_tag_mid != 0)
return false;
69 if (time_tag_hi != 0)
return false;
70 if (run_subrun != 0)
return false;
71 if (exp_run != 0)
return false;
72 if (crc32 != 0x4829214d)
return false;
76 void dhc_start_frame::print(
void)
const
79 B2DEBUG(99,
"DHC Start Frame TNRLO $" << std::hex << trigger_nr_lo <<
" TNRHI $" << std::hex << trigger_nr_hi <<
" TTLO $" <<
82 <<
" TTMID $" << std::hex << time_tag_mid <<
" TTHI $" << std::hex << time_tag_hi <<
" Exp/Run/Subrun $" << std::hex << exp_run <<
85 <<
" CRC $" << std::hex << crc32);
88 void dhc_dhe_start_frame::print(
void)
const
91 B2DEBUG(99,
"DHC Event Frame TNRLO $" << std::hex << trigger_nr_lo <<
" DTTLO $" << std::hex << dhe_time_tag_lo <<
" DTTHI $" <<
94 <<
" DHEID $" << std::hex << getDHEId()
95 <<
" DHPMASK $" << std::hex << getActiveDHPMask()
96 <<
" SFNR $" << std::hex << getStartFrameNr()
97 <<
" OFF $" << std::hex << getTriggerGate()
98 <<
" CRC " << std::hex << crc32);
101 void dhc_direct_readout_frame::print(
void)
const
104 B2DEBUG(99,
"DHC Direct Readout (Raw|ZSD|ONS) Frame TNRLO $" << std::hex << trigger_nr_lo <<
" DHE ID $" << getDHEId() <<
105 " DHP port $" << getDHPPort());
108 void dhc_onsen_trigger_frame::print(
void)
const
111 B2DEBUG(99,
"ONSEN Trigger Frame TNRLO $" << std::hex << trignr0);
114 PXDError::PXDErrorFlags dhc_onsen_trigger_frame::check_error(
bool ignore_datcon_flag,
bool ignore_hltroi_magic_flag,
115 bool ignore_merger_mm_flag)
const
117 PXDError::PXDErrorFlags m_errorMask = PXDError::EPXDErrMask::c_NO_ERROR;
118 if ((magic1 & 0xFFFF0000) != 0xCAFE0000) {
119 if (!ignore_hltroi_magic_flag) B2WARNING(
"ONSEN Trigger Magic 1 error $" << std::hex << magic1);
120 m_errorMask |= PXDError::EPXDErrMask::c_HLTROI_MAGIC;
122 if ((magic2 & 0xFFFF0000) != 0xCAFE0000) {
123 if (!ignore_hltroi_magic_flag) B2WARNING(
"ONSEN Trigger Magic 2 error $" << std::hex << magic2);
124 m_errorMask |= PXDError::EPXDErrMask::c_HLTROI_MAGIC;
126 if (is_fake_datcon()) {
127 if (!ignore_datcon_flag) B2INFO(
"ONSEN Trigger Frame: No DATCON data $" << std::hex << trignr1 <<
"!=$" << trignr2);
128 m_errorMask |= PXDError::EPXDErrMask::c_NO_DATCON;
130 if (trignr1 != trignr2) {
131 if (!ignore_merger_mm_flag) B2WARNING(
"ONSEN Trigger Frame Trigger Nr Mismatch $" << std::hex << trignr1 <<
"!=$" << trignr2);
132 m_errorMask |= PXDError::EPXDErrMask::c_MERGER_TRIGNR;
138 PXDError::PXDErrorFlags dhc_onsen_roi_frame::check_error(
int length,
bool ignore_inv_size_flag)
const
140 PXDError::PXDErrorFlags m_errorMask = PXDError::EPXDErrMask::c_NO_ERROR;
142 if (length < getMinSize()) {
143 if (!ignore_inv_size_flag) B2WARNING(
"DHC ONSEN HLT/ROI Frame too small to hold any ROIs!");
144 m_errorMask |= PXDError::c_ROI_PACKET_INV_SIZE;
145 }
else if ((length - getMinSize()) % 8 != 0) {
146 if (!ignore_inv_size_flag) B2WARNING(
"DHC ONSEN HLT/ROI Frame holds fractional ROIs, last ROI might not be saved!");
147 m_errorMask |= PXDError::c_ROI_PACKET_INV_SIZE;
151 void dhc_onsen_roi_frame::print(
void)
const
154 B2DEBUG(99,
"DHC HLT/ROI Frame");
157 void dhc_ghost_frame::print(
void)
const
160 B2DEBUG(99,
"DHC Ghost Frame TNRLO $" << std::hex << trigger_nr_lo <<
" DHE ID $" << getDHEId() <<
" DHP port $" << getDHPPort() <<
164 unsigned short dhc_ghost_frame::getErrorBits(
void)
const
166 unsigned short value = (word0.data & 0xC) >> 2;
167 if (word0.data & 0x0400) value |= 0x4;
171 bool dhc_end_frame::isFakedData(
void)
const
173 if (word0.data != 0x6000)
return false;
174 if (trigger_nr_lo != 0)
return false;
175 if (wordsinevent != 0)
return false;
176 if (errorinfo != 0)
return false;
177 if (crc32 != 0xF7BCA507)
return false;
180 void dhc_end_frame::print(
void)
const
183 B2DEBUG(99,
"DHC End Frame TNRLO $" << std::hex << trigger_nr_lo <<
" WIEVT $" << std::hex << wordsinevent <<
" ERR $" << std::hex
184 << errorinfo <<
" CRC " << std::hex << crc32);
188 void dhc_dhe_end_frame::print(
void)
const
191 B2DEBUG(99,
"DHC DHE End Frame TNRLO $" << std::hex << trigger_nr_lo <<
" WIEVT $" << std::hex << wordsineventhi <<
"." <<
192 wordsineventlo <<
" ERR $" << std::hex << errorinfo <<
" CRC " << std::hex << crc32);
195 unsigned int dhc_dhe_end_frame::getErrorStateMachineDHP(
int dhpid)
const
198 case 0:
return ((uint32_t)errorinfo >> 24) & 0xFF;
199 case 1:
return ((uint32_t)errorinfo >> 16) & 0xFF;
200 case 2:
return ((uint32_t)errorinfo >> 8) & 0xFF;
201 case 3:
return errorinfo & 0xFF;
206 unsigned int dhc_dhe_end_frame::getErrorStateMachineStartDHP(
int dhpid)
const
209 case 0:
return ((uint32_t)errorinfo >> 24) & 0xF;
210 case 1:
return ((uint32_t)errorinfo >> 16) & 0xF;
211 case 2:
return ((uint32_t)errorinfo >> 8) & 0xF;
212 case 3:
return errorinfo & 0xF;
217 unsigned int dhc_dhe_end_frame::getErrorStateMachineEndDHP(
int dhpid)
const
220 case 0:
return ((uint32_t)errorinfo >> 28) & 0xF;
221 case 1:
return ((uint32_t)errorinfo >> 20) & 0xF;
222 case 2:
return ((uint32_t)errorinfo >> 12) & 0xF;
223 case 3:
return ((uint32_t)errorinfo >> 4) & 0xF;
230 unsigned int crc = *(ubig32_t*)(((
unsigned char*)data) + length - 4);
231 if ((crc & 0xFFFF0000) == 0 || (crc & 0xFFFF) == 0) {
233 B2INFO(
"Suspicious Padding $" << std::hex << crc);
234 return PXDError::EPXDErrMask::c_SUSP_PADDING;
236 return PXDError::EPXDErrMask::c_NO_ERROR;
239 PXDError::PXDErrorFlags dhc_frames::check_crc(
bool ignore_crc_flag)
243 if (length > 65536 * 16) {
244 if (!ignore_crc_flag) B2WARNING(
"DHC Data Frame CRC not calculated because of too large packet (>1MB)!");
245 return PXDError::EPXDErrMask::c_NO_ERROR;
247 bocrc.process_bytes(data, length - 4);
250 c = bocrc.checksum();
253 crc32 = *(ubig32_t*)(((
unsigned char*)data) + length - 4);
256 if (!ignore_crc_flag) {
257 B2WARNING(
"DHC Data Frame CRC FAIL");
258 B2DEBUG(1,
"DHC Data Frame CRC FAIL: " << std::hex << c <<
"!=" << crc32 <<
" data "
259 << * (
unsigned int*)(((
unsigned char*)data) + length - 8) <<
" "
260 << * (
unsigned int*)(((
unsigned char*)data) + length - 6) <<
" "
261 << * (
unsigned int*)(((
unsigned char*)data) + length - 4) <<
" len $" << length);
263 return PXDError::EPXDErrMask::c_DHE_CRC;
265 return PXDError::EPXDErrMask::c_NO_ERROR;
272 switch (getFrameType()) {
273 case EDHCFrameHeaderDataType::c_DHP_RAW:
276 case EDHCFrameHeaderDataType::c_ONSEN_DHP:
277 case EDHCFrameHeaderDataType::c_DHP_ZSD:
280 case EDHCFrameHeaderDataType::c_ONSEN_FCE:
281 case EDHCFrameHeaderDataType::c_FCE_RAW:
284 case EDHCFrameHeaderDataType::c_COMMODE:
285 s = data_commode_frame->getFixedSize();
287 case EDHCFrameHeaderDataType::c_GHOST:
288 s = data_ghost_frame->getFixedSize();
290 case EDHCFrameHeaderDataType::c_DHE_START:
291 s = data_dhe_start_frame->getFixedSize();
293 case EDHCFrameHeaderDataType::c_DHE_END:
294 s = data_dhe_end_frame->getFixedSize();
296 case EDHCFrameHeaderDataType::c_DHC_START:
297 s = data_dhc_start_frame->getFixedSize();
299 case EDHCFrameHeaderDataType::c_DHC_END:
300 s = data_dhc_end_frame->getFixedSize();
302 case EDHCFrameHeaderDataType::c_ONSEN_ROI:
305 case EDHCFrameHeaderDataType::c_ONSEN_TRG:
306 s = data_onsen_trigger_frame->getFixedSize();
309 B2INFO(
"Error: not a valid data frame!");