// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include "Completion.h" #include "../../common/JFJochException.h" #include "../../common/Definitions.h" inline uint64_t bit_concat(uint32_t high, uint32_t low) { return (uint64_t(high) << 32) | low; } Completion parse_hw_completion(uint32_t tmp[16]) { Completion c{}; c.handle = tmp[0]; c.module = tmp[1] & 0xFF; c.packet_count = (tmp[1] & (0xFFFF0000)) >> 16; uint64_t detector_frame_number = bit_concat(tmp[2], tmp[3]); uint32_t parity = (std::bitset<32>(tmp[0]).count() + std::bitset<32>(tmp[1]).count() + std::bitset<32>(tmp[2]).count() + std::bitset<32>(tmp[3]).count()) % 2; if (parity == 1) throw JFJochException(JFJochExceptionCategory::HardwareParityError, "Wrong parity in work completion"); if (c.handle == HANDLE_START) { c.type = Completion::Type::Start; } else if (c.handle == HANDLE_END) { c.type = Completion::Type::End; c.frame_number = detector_frame_number; } else { c.type = Completion::Type::Image; if (detector_frame_number == 0) throw JFJochException(JFJochExceptionCategory::HardwareParityError, "Detector frame number cannot be zero"); else c.frame_number = detector_frame_number - 1; c.timestamp = bit_concat(tmp[4], tmp[5]); c.bunchid = bit_concat(tmp[6], tmp[7]); c.exptime = tmp[8]; c.debug = tmp[9]; c.packet_mask[0] = bit_concat(tmp[14], tmp[15]); c.packet_mask[1] = bit_concat(tmp[12], tmp[13]); } return c; }