51 lines
1.6 KiB
C++
51 lines
1.6 KiB
C++
// Copyright (2019-2022) Paul Scherrer Institute
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include <bitset>
|
|
|
|
#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;
|
|
} |