#pragma once #include #include #include #include #include #include #include "raptor_eagle_exception.h" class RaptorEagleCCD : public adc::AdcGenericDevice, adc::AdcDeviceCommand<>>, adc::AdcSpdlogLogger { typedef adc::AdcGenericDevice, adc::AdcDeviceCommand<>> base_t; public: /* some Eagle V camera constants */ static constexpr double EAGLE_CAMERA_MAX_EXPTIME = 27487.7906944; // in seconds (0xFFFFFFFFFF * 25nsec) static constexpr std::string_view CAMERA_ATTR_HBIN{"HBIN"}; static constexpr std::string_view CAMERA_ATTR_VBIN{"VBIN"}; static constexpr std::string_view CAMERA_ATTR_ROI_LEFT{"ROI_LEFT"}; static constexpr std::string_view CAMERA_ATTR_ROI_TOP{"ROI_TOP"}; static constexpr std::string_view CAMERA_ATTR_ROI_WIDTH{"ROI_WIDTH"}; static constexpr std::string_view CAMERA_ATTR_ROI_HEIGHT{"ROI_HEIGHT"}; static constexpr std::string_view CAMERA_ATTR_GAIN{"GAIN"}; static constexpr std::string_view CAMERA_ATTR_READ_RATE{"READ_RATE"}; static constexpr std::string_view CAMERA_ATTR_CCD_TEMP{"CCD_TEMP"}; static constexpr std::string_view CAMERA_ATTR_PCB_TEMP{"PCB_TEMP"}; static constexpr std::string_view CAMERA_ATTR_EXPTIME{"EXPTIME"}; static constexpr std::string_view CAMERA_ATTR_FRAME_RATE{"FRAME_RATE"}; static constexpr std::string_view CAMERA_ATTR_NEXP{"NEXP"}; static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE{"SHUTTER_STATE"}; static constexpr std::string_view CAMERA_ATTR_CCDDIM{"CCDDIM"}; static constexpr std::string_view CAMERA_ATTR_CAMLINK_SETUP{"CAMLINK_SETUP"}; static constexpr std::string_view CAMERA_CMD_START_EXP{"START_EXP"}; static constexpr std::string_view CAMERA_CMD_STOP_EXP{"STOP_EXP"}; // static constexpr std::string_view CAMERA_CMD_OPEN_SHUTTER{"OPEN_SHUTTER"}; // static constexpr std::string_view CAMERA_CMD_CLOSE_SHUTTER{"CLOSE_SHUTTER"}; // system status byte bits struct SystemStatus { bool checkSumEnabled; bool ackEnabled; bool bootedFPGA; bool holdFPGAInReset; bool commsFPGAEnabled; }; // FPGA status bits struct FPGAStatus { bool highGainEnabled; bool overTemp; bool TECEnabled; }; RaptorEagleCCD(const adc::traits::adc_input_char_range auto& epix_video_fmt_filename, std::shared_ptr logger = spdlog::null_logger_mt("EAGLE_CCD_NULLLOGGER")); RaptorEagleCCD(std::shared_ptr logger = spdlog::null_logger_mt("EAGLE_CCD_NULLLOGGER")); ~RaptorEagleCCD(); private: typedef std::vector byte_seq_t; std::string _epixFmtVideoFilename; int _cameraUnitmap; // CameraLink read/write setup flags uint8_t _clCommandAckBit; uint8_t _clChecksumBit; std::mutex _camlinkMutex; // attributes inner variables double _expTime; size_t _frameNumbers; void initAttrComm(); void initCamera(int unitmap = 1); void openPIXCI(); void closePIXCI(); // CameraLink-related low-level methods size_t clRead(byte_seq_t& bytes); size_t clReadAndCheckAck(byte_seq_t& bytes); size_t clReadAndCheckAck(); size_t clWrite(const byte_seq_t& bytes); // CameraLink-related registers read/write methods // there are two kind of SET-READ_REGISTER-ADDRESS command in the current version of the camera controller firmware: // {0x53, 0xE0, 0x01} and // {0x53, 0xE0, 0x02} // // NOTE: given 'set_addr_cmd' byte sequence must be one-byte longer than the command itself!!! byte_seq_t readRegisters(const byte_seq_t& addrs, byte_seq_t set_addr_cmd = {0x53, 0xE0, 0x01, 0x00}); void writeRegisters(const byte_seq_t& addrs, const byte_seq_t& values); // logging helper methods template void xclibApiCall(int err, const adc::traits::adc_input_char_range auto& func_name) { if (err < 0) { if (std::ranges::size(func_name)) { logError("XCLIB API call ('{}') returns: {} ({})", func_name, err, pxd_mesgErrorCode(err)); } else { logError("XCLIB API call returns: {} ({})", err, pxd_mesgErrorCode(err)); } if constexpr (!NOEXCEPT) { throw std::error_code(err, XCLIBErrorCategory::get()); } } else { if (std::ranges::size(func_name)) { logDebug("XCLIB API call ('{}') finished successfully", func_name); } } } template void xclibApiCall(int err) { xclibApiCall(err, std::string_view("")); } };