diff --git a/raptor_eagle_cameralink.h b/raptor_eagle_cameralink.h index 59ff57c..40ffa41 100644 --- a/raptor_eagle_cameralink.h +++ b/raptor_eagle_cameralink.h @@ -113,15 +113,15 @@ static constexpr char CL_SHUTTER_EXP = 0x2; // readout rate (registers values) -static constexpr char CL_READOUT_CLOCK_RATE_A3_2MHZ = 0x02; -static constexpr char CL_READOUT_CLOCK_RATE_A4_2MHZ = 0x02; -static constexpr char CL_READOUT_CLOCK_RATE_A3_75KHZ = 0x43; -static constexpr char CL_READOUT_CLOCK_RATE_A4_75KHZ = 0x80; +static constexpr unsigned char CL_READOUT_CLOCK_RATE_A3_2MHZ = 0x02; +static constexpr unsigned char CL_READOUT_CLOCK_RATE_A4_2MHZ = 0x02; +static constexpr unsigned char CL_READOUT_CLOCK_RATE_A3_75KHZ = 0x43; +static constexpr unsigned char CL_READOUT_CLOCK_RATE_A4_75KHZ = 0x80; // readout mode -static constexpr char CL_READOUT_MODE_NORMAL = 0x01; -static constexpr char CL_READOUT_MODE_TEST = 0x04; +static constexpr unsigned char CL_READOUT_MODE_NORMAL = 0x01; +static constexpr unsigned char CL_READOUT_MODE_TEST = 0x04; static constexpr double ADC_CALIBRATION_POINT_1 = 0.0; // at 0 Celcius degree @@ -144,6 +144,15 @@ static constexpr std::initializer_list CL_ROIHEIGHT_ADDR = {0xB8, static constexpr std::initializer_list CL_XBIN_ADDR = {0xA1}; static constexpr std::initializer_list CL_YBIN_ADDR = {0xA2}; +static constexpr std::initializer_list CL_TECPOINT_ADDR = {0x03, 0x04}; + +static constexpr std::initializer_list CL_READMODE_ADDR = {0xF7}; + +static constexpr std::initializer_list CL_READRATE_ADDR = {0xA3, 0xA4}; + +static constexpr std::initializer_list CL_SHUTTER_CONTROL_ADDR = {0xA5}; + + /* COMMANDS */ static unsigned char CL_COMMAND_SET_ADDRESS[] = { diff --git a/raptor_eagle_ccd.cpp b/raptor_eagle_ccd.cpp index 1b9bcdb..1303487 100644 --- a/raptor_eagle_ccd.cpp +++ b/raptor_eagle_ccd.cpp @@ -169,6 +169,9 @@ std::bitset<8> RaptorEagleCCD::getSystemState() logDebug("Get system state as 0b{} bits", bits.to_string()); + _clCommandAckBit = bits.test(CL_SYSTEM_STATUS_ACK_BIT) ? 1 : 0; + _clChecksumBit = bits.test(CL_SYSTEM_STATUS_CK_SUM_BIT) ? 1 : 0; + return bits; } @@ -183,6 +186,9 @@ void RaptorEagleCCD::setSystemState(const std::bitset<8>& bits) clWrite({0x4F, status}); clReadAndCheckAck(); + + _clCommandAckBit = bits.test(CL_SYSTEM_STATUS_ACK_BIT) ? 1 : 0; + _clChecksumBit = bits.test(CL_SYSTEM_STATUS_CK_SUM_BIT) ? 1 : 0; } @@ -304,6 +310,7 @@ void RaptorEagleCCD::initCamera(int unitmap) _cameraUnitmap = unitmap; + // configure CameraLink serial connection xclibApiCall(pxd_serialConfigure(_cameraUnitmap, 0, CL_DEFAULT_BAUD_RATE, CL_DEFAULT_DATA_BITS, 0, CL_DEFAULT_STOP_BIT, 0, 0, 0), std::format("pxd_serialConfigure({}, 0, {}, {}, 0, {}, 0, 0, 0)", _cameraUnitmap, CL_DEFAULT_BAUD_RATE, @@ -335,60 +342,6 @@ void RaptorEagleCCD::closePIXCI() } -/* SYSTEM STATUS */ - - -/*------------*/ - -const RaptorEagleCCD::SystemStatus RaptorEagleCCD::getSystemStatus() -{ - std::lock_guard lock_guard(_camlinkMutex); - - byte_seq_t ans; - - clWrite({0x49}); - clReadAndCheckAck(ans); - - SystemStatus status; - status.ackEnabled = ans[0] & CL_SYSTEM_STATUS_ACK; - status.checkSumEnabled = ans[0] & CL_SYSTEM_STATUS_CK_SUM; - status.bootedFPGA = ans[0] & CL_SYSTEM_STATUS_FPGA_BOOT_OK; - status.commsFPGAEnabled = ans[0] & CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS; - status.holdFPGAInReset = !(ans[0] & CL_SYSTEM_STATUS_FPGA_RST_HOLD); // hold in RESET if bit is 0 - - return status; -} - -void RaptorEagleCCD::setSystemStatus(const RaptorEagleCCD::SystemStatus& status) -{ - uint8_t st = 0; - - if (status.ackEnabled) - st |= CL_SYSTEM_STATUS_ACK; - - if (status.checkSumEnabled) - st |= CL_SYSTEM_STATUS_CK_SUM; - - if (status.bootedFPGA) - st |= CL_SYSTEM_STATUS_FPGA_BOOT_OK; - - if (status.commsFPGAEnabled) - st |= CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS; - - if (status.holdFPGAInReset) - st &= ~CL_SYSTEM_STATUS_FPGA_RST_HOLD; - - setSystemStatus(st); -} - -void RaptorEagleCCD::setSystemStatus(const uint8_t& status) -{ - std::lock_guard lock_guard(_camlinkMutex); - - clWrite({0x4F, status}); - clReadAndCheckAck(); -} - /* CameraLink-RELATED METHODS */ @@ -535,8 +488,8 @@ RaptorEagleCCD::byte_seq_t RaptorEagleCCD::readRegisters(const RaptorEagleCCD::b } // from Eagle V 4240 instruction manual (rev 1.1) - byte_seq_t set_addr_comm = std::move(set_addr_cmd); // set address controller command - static const byte_seq_t read_reg_comm{0x53, 0xE1, 0x01}; // read register controller command + byte_seq_t set_addr_comm = std::move(set_addr_cmd); // set-address controller command + static const byte_seq_t read_reg_comm{0x53, 0xE1, 0x01}; // read-register controller command reg_vals.resize(addrs.size()); @@ -588,6 +541,67 @@ void RaptorEagleCCD::writeRegisters(const byte_seq_t& addrs, const byte_seq_t& v void RaptorEagleCCD::initAttrComm() { + // helper to setup 8-bit register attributes + // 'validator' is a callable with signature: std::pair validator(const uchar&) + auto create8BitAttr = [this](attr_ident_t name, auto reg_addr, auto&& validator, std::string_view log_mark) { + return RaptorEagleCCD::attribute_t( + name, + [this, reg_addr, log_mark]() { + auto bytes = readRegisters(reg_addr); + + logTrace("Return {} (current value: {})", log_mark, bytes[0]); + + return bytes[0]; + }, + [this, reg_addr, log_mark, + wrapper = + adc::traits::adc_pf_wrapper(std::forward(validator))](const uchar& val) mutable { + logDebug("Try to set {} to {} ...", log_mark, val); + + // call perfectly-forwarded validator + auto v_res = std::forward>(std::get<0>(wrapper))(val); + if (v_res.second.size()) { // warning + logWarn("{}", v_res.second); + } + + writeRegisters(reg_addr, {v_res.first}); + + logDebug("{} is set to {}", log_mark, v_res.first); + }); + }; + + // helper to setup 12-bit register attributes + // 'validator' is a callable with signature: std::pair validator(const uint16_t&) + auto create12BitAttr = [this](attr_ident_t name, auto reg_addrs, auto&& validator, std::string_view log_mark) { + return RaptorEagleCCD::attribute_t( + name, + [this, reg_addrs, log_mark]() { + auto bytes = readRegisters(reg_addrs); + uint16_t v = details::convert12BitToUInt(bytes); + + logTrace("Return {} (current value: {})", log_mark, v); + + return v; + }, + [this, reg_addrs, log_mark, + wrapper = adc::traits::adc_pf_wrapper(std::forward(validator))]( + const uint16_t& val) mutable { + logDebug("Try to set {} to {} ...", log_mark, val); + + // call perfectly-forwarded validator + auto v_res = std::forward>(std::get<0>(wrapper))(val); + if (v_res.second.size()) { // warning + logWarn("{}", v_res.second); + } + + auto bytes = details::convertUIntTo12Bit(v_res.first); + writeRegisters(reg_addrs, bytes); + + logDebug("{} is set to {}", log_mark, v_res.first); + }); + }; + + /* commands */ @@ -615,6 +629,9 @@ void RaptorEagleCCD::initAttrComm() logDebug("Set CameraLink setup bits to: command-ack = {}, checksum = {}", _clCommandAckBit, _clChecksumBit); }); + + /* EXPOSURE AND FRAMERATE */ + // exposure time addAttribute( CAMERA_ATTR_EXPTIME, @@ -702,41 +719,13 @@ void RaptorEagleCCD::initAttrComm() }); - // helper to setup 12-bit register attributes - auto create12BitAttr = [this](std::string_view name, auto reg_addrs, auto&& validator, std::string_view log_mark) { - return RaptorEagleCCD::attribute_t( - name, - [this, reg_addrs, log_mark]() { - auto bytes = readRegisters(reg_addrs); - uint16_t v = details::convert12BitToUInt(bytes); - - logTrace("Return {} (current value: {})", log_mark, v); - - return v; - }, - [this, reg_addrs, log_mark, - wrapper = adc::traits::adc_pf_wrapper(std::forward(validator))]( - const uint16_t& val) mutable { - logDebug("Try to set {} to {} ...", log_mark, val); - - // call perfectly-forwarded validator - auto v_res = std::forward>(std::get<0>(wrapper))(val); - if (v_res.second.size()) { // warning - logWarn("{}", v_res.second); - } - - auto bytes = details::convertUIntTo12Bit(v_res.first); - writeRegisters(reg_addrs, bytes); - - logDebug("{} is set to {}", log_mark, v_res.first); - }); - }; + /* FRAME GEOMETRY RELATED ATTRIBUTES */ // ROI left addAttribute(create12BitAttr( CAMERA_ATTR_ROI_STARTX, CL_ROI_STARTX_ADDR, - [this](const uint16_t& val) { // validator - std::pair res{val, ""}; + [this](const T& val) { // validator + std::pair res{val, ""}; if (val < 1) { res.first = 1; @@ -756,8 +745,8 @@ void RaptorEagleCCD::initAttrComm() // ROI top addAttribute(create12BitAttr( CAMERA_ATTR_ROI_STARTY, CL_ROI_STARTY_ADDR, - [this](const uint16_t& val) { // validator - std::pair res{val, ""}; + [this](const T& val) { // validator + std::pair res{val, ""}; if (val < 1) { res.first = 1; @@ -777,8 +766,8 @@ void RaptorEagleCCD::initAttrComm() // ROI width addAttribute(create12BitAttr( CAMERA_ATTR_ROI_WIDTH, CL_ROIWIDTH_ADDR, - [this](const uint16_t& val) { // validator - std::pair res{val, ""}; + [this](const T& val) { // validator + std::pair res{val, ""}; if (val < 1) { res.first = 1; @@ -796,8 +785,8 @@ void RaptorEagleCCD::initAttrComm() // ROI height addAttribute(create12BitAttr( CAMERA_ATTR_ROI_HEIGHT, CL_ROIHEIGHT_ADDR, - [this](const uint16_t& val) { // validator - std::pair res{val, ""}; + [this](const T& val) { // validator + std::pair res{val, ""}; // ROI height can be 0 (see Eagle V 4240 instruction manual) if (val > _dimCCD[1]) { @@ -811,10 +800,10 @@ void RaptorEagleCCD::initAttrComm() "ROI height")); // X-bin - addAttribute(create12BitAttr( + addAttribute(create8BitAttr( CAMERA_ATTR_XBIN, CL_XBIN_ADDR, - [this](const uint16_t& val) { // validator (1-32, 64) - std::pair res{val, ""}; + [](const T& val) { // validator (1-32, 64) + std::pair res{val, ""}; if (val < 1) { res.first = 1; @@ -838,10 +827,10 @@ void RaptorEagleCCD::initAttrComm() // Y-bin - addAttribute(create12BitAttr( + addAttribute(create8BitAttr( CAMERA_ATTR_YBIN, CL_YBIN_ADDR, - [this](const uint16_t& val) { // validator (1-32, 64) - std::pair res{val, ""}; + [](const T& val) { // validator (1-32, 64) + std::pair res{val, ""}; if (val < 1) { res.first = 1; @@ -862,4 +851,215 @@ void RaptorEagleCCD::initAttrComm() return res; }, "YBIN")); + + + /* TEC SET POINT */ + + // DAC counts + addAttribute(create12BitAttr( + CAMERA_ATTR_TECPOINT_DAC, CL_TECPOINT_ADDR, + [](const T& counts) { + std::pair res{counts, ""}; + + if (counts > 0x0FFF) { + res.second = std::format("TEC set point counts must not be greater than {}", 0x0FFF); + res.first = 0x0FFF; + } + + return res; + }, + "TEC set point")); + + // floating-point value + addAttribute( + CAMERA_ATTR_TECPOINT, + [this]() { + double counts = (*this)[CAMERA_ATTR_TECPOINT_DAC]; + + double k = (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1) / + (_dacTECSetPointCalibData[1] - _dacTECSetPointCalibData[0]); + double b = _dacTECSetPointCalibData[0] - k * DAC_CALIBRATION_POINT_1; + + double temp = k * counts + b; + + logTrace("Computed Temp-to-DAC linear relation: DAC = {}*Temp + {}", k, b); + + logDebug("Return TEC set point as {} Celsius degrees", temp); + + return temp; + }, + [this](const double& temp) { + double k = (_dacTECSetPointCalibData[1] - _dacTECSetPointCalibData[0]) / + (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1); + double b = DAC_CALIBRATION_POINT_1 - k * _dacTECSetPointCalibData[0]; + + logTrace("Computed DAC-to-Temp linear relation: Temp = {}*DAC + {}", k, b); + + uint64_t v = static_cast(temp * k + b); + + uint16_t counts = v & 0x0FFF; // extract 12-bits + + (*this)[CAMERA_ATTR_TECPOINT_DAC] = counts; + }); + + + /* CCD and PCB temperature (read-only) */ + + addAttribute(CAMERA_ATTR_PCB_TEMP, [this]() { + uint16_t bits = 0x0FFF; + double val = -1000; // impossible value + + try { + // unusual set-address command (extra 0x00 byte after the address)! + auto bytes = readRegisters({0x70, 0x71}, {0x53, 0xE0, 0x02, 0x00, 0x00}); + bits = details::convert12BitToUInt(bytes); + val = bits / 16.0; + } catch (const std::system_error& ex) { + logError("An error occured while trying to get PCB temperature! (code = {}, category = {}, msg = {})", + ex.code().value(), ex.code().category().name(), ex.code().message()); + } + + logTrace("Return PCB temperature (current value: {}; bits: {})", val, bits); + + return val; + }); + + + addAttribute(CAMERA_ATTR_CCD_TEMP, [this]() { + uint16_t bits = 0xFFFF; + double val = -1000; // impossible value + + try { + // unusual set-address command (extra 0x00 byte after the address)! + auto bytes = readRegisters({0x6E, 0x6F}, {0x53, 0xE0, 0x02, 0x00, 0x00}); + bits = (bytes[0] << 8) + bytes[1]; + + val = _adcCCDTempCalibCoeffs[0] * bits + _adcCCDTempCalibCoeffs[1]; + } catch (const std::system_error& ex) { + logError("An error occured while trying to get CCD temperature! (code = {}, category = {}, msg = {})", + ex.code().value(), ex.code().category().name(), ex.code().message()); + } + + logTrace("Return CCD temperature (current value: {}; bits: {})", val, bits); + + return val; + }); + + + /* READ-OUT MODE (std::string_view "NORMAL" or "TEST") */ + + addAttribute( + CAMERA_ATTR_READ_MODE, + [this]() -> std::string_view { + auto bytes = readRegisters(CL_READMODE_ADDR); + std::string_view val = CAMERA_ATTR_READ_MODE_NORMAL; + + if (bytes[0] == CL_READOUT_MODE_NORMAL) { + } else if (bytes[0] == CL_READOUT_MODE_TEST) { + val = CAMERA_ATTR_READ_MODE_TEST; + } else { + logError("Invalid bits in readout mode register! (reg = 0x{:02X})", bytes[0]); + + val = CAMERA_ATTR_READ_MODE_INVALID; + } + + logTrace("Return readout mode as '{}' string", val); + + return val; + }, + [this](const std::string_view& mode) { + uchar bits; + + if (mode == CAMERA_ATTR_READ_MODE_NORMAL) { + bits = CL_READOUT_MODE_NORMAL; + } + if (mode == CAMERA_ATTR_READ_MODE_TEST) { + bits = CL_READOUT_MODE_TEST; + } else { + logWarn("Invalid '{}' string for readout mode! Use of '{}'!", mode, CAMERA_ATTR_READ_MODE_NORMAL); + bits = CL_READOUT_MODE_NORMAL; + } + + writeRegisters(CL_READMODE_ADDR, {bits}); + + logDebug("Readout mode is set to 0x{:02X} bits", bits); + }); + + + /* READOUT RATE (std::string_view "FAST" or "SLOW") */ + + addAttribute( + CAMERA_ATTR_READ_RATE, + [this]() { + auto bytes = readRegisters(CL_FRAMERATE_ADDR); + std::string_view val; + + if ((bytes[0] == CL_READOUT_CLOCK_RATE_A3_2MHZ) && (bytes[1] == CL_READOUT_CLOCK_RATE_A4_2MHZ)) { + val = CAMERA_ATTR_READ_RATE_FAST; + } else if ((bytes[0] == CL_READOUT_CLOCK_RATE_A3_75KHZ) && (bytes[1] == CL_READOUT_CLOCK_RATE_A4_75KHZ)) { + val = CAMERA_ATTR_READ_RATE_SLOW; + } else { + logError("Invalid bits in readout rate registers! (A3 = 0x{:02X}, A4 = 0x{:02X})", bytes[0], bytes[1]); + + val = CAMERA_ATTR_READ_RATE_INVALID; + } + + logTrace("Return readout rate as '()' string", val); + + return val; + }, + [this](const std::string_view& rate) { + byte_seq_t bytes({CL_READOUT_CLOCK_RATE_A3_2MHZ, CL_READOUT_CLOCK_RATE_A4_2MHZ}); + if (rate == CAMERA_ATTR_READ_RATE_FAST) { + } else if (rate == CAMERA_ATTR_READ_RATE_SLOW) { + bytes[0] = CL_READOUT_CLOCK_RATE_A3_75KHZ; + bytes[1] = CL_READOUT_CLOCK_RATE_A4_75KHZ; + } else { + logWarn("Invalid '{}' string for readout rate! Use of '{}'!", rate, CAMERA_ATTR_READ_RATE_FAST); + } + + writeRegisters(CL_FRAMERATE_ADDR, bytes); + + logDebug("Readout rate is set to [0x{:02X}, 0x{:02X}] bytes", bytes[0], bytes[1]); + }); + + + /* SHUTTER CONTROL (std::string_view "OPEN", "CLOSED", "EXP") */ + + addAttribute( + CAMERA_ATTR_SHUTTER_STATE, + [this]() { + auto bytes = readRegisters(CL_SHUTTER_CONTROL_ADDR); + std::string_view val; + + if (bytes[0] == CL_SHUTTER_CLOSED) { + val = CAMERA_ATTR_SHUTTER_STATE_CLOSED; + } else if (bytes[0] == CL_SHUTTER_OPEN) { + val = CAMERA_ATTR_SHUTTER_STATE_OPEN; + } else if (bytes[0] == CL_SHUTTER_EXP) { + val = CAMERA_ATTR_SHUTTER_STATE_EXP; + } else { + logError("Invalid bits in shhutter control register! (reg = 0x{:02X})", bytes[0]); + val = CAMERA_ATTR_SHUTTER_STATE_INVALID; + } + + logTrace("Return shutter state as '{}' string (bits = 0x{:02X})", val, bytes[0]); + + return val; + }, + [this](const std::string_view& state) { + byte_seq_t bytes{CL_SHUTTER_EXP}; + if (state == CAMERA_ATTR_SHUTTER_STATE_EXP) { + } else if (state == CAMERA_ATTR_SHUTTER_STATE_CLOSED) { + bytes[0] = CL_SHUTTER_CLOSED; + } else if (state == CAMERA_ATTR_SHUTTER_STATE_OPEN) { + bytes[0] = CL_SHUTTER_OPEN; + } else { + logWarn("Invalid '{}' string for shutter state! Use of '{}'!", state, CL_SHUTTER_EXP); + } + + writeRegisters(CL_SHUTTER_CONTROL_ADDR, bytes); + + logDebug("Shutter state is set to 0x{:02X}", bytes[0]); + }); } diff --git a/raptor_eagle_ccd.h b/raptor_eagle_ccd.h index 1b08dfc..32678fb 100644 --- a/raptor_eagle_ccd.h +++ b/raptor_eagle_ccd.h @@ -29,8 +29,14 @@ public: static constexpr size_t EAGLE_CAMERA_MAX_FRAMERATE = 0xFFFFFFFFFF * 40; // in MHz (0xFFFFFFFFFF * 40MHz) static constexpr uint16_t EAGLE_CAMERA_CCDDIM[] = {2048, 2048}; - static constexpr uint16_t EAGLE_CAMERA_MAX_XBIN[] = {32, 64}; - static constexpr uint16_t EAGLE_CAMERA_MAX_YBIN[] = {32, 64}; + static constexpr uchar EAGLE_CAMERA_MAX_XBIN[] = {32, 64}; + static constexpr uchar EAGLE_CAMERA_MAX_YBIN[] = {32, 64}; + + static constexpr double ADC_CALIBRATION_POINT_1 = 0.0; + static constexpr double ADC_CALIBRATION_POINT_2 = 40.0; + + static constexpr double DAC_CALIBRATION_POINT_1 = 0.0; + static constexpr double DAC_CALIBRATION_POINT_2 = 40.0; static constexpr std::string_view CAMERA_ATTR_XBIN{"XBIN"}; static constexpr std::string_view CAMERA_ATTR_YBIN{"YBIN"}; @@ -40,6 +46,9 @@ public: 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_READ_MODE{"READ_MODE"}; + static constexpr std::string_view CAMERA_ATTR_TECPOINT{"TECPOINT"}; + static constexpr std::string_view CAMERA_ATTR_TECPOINT_DAC{"TECPOINT_DAC"}; 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"}; @@ -49,26 +58,23 @@ public: 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_INITCAM{"INITCAM"}; 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; - }; + // some character attributes values + static constexpr std::string_view CAMERA_ATTR_READ_MODE_NORMAL{"NORMAL"}; + static constexpr std::string_view CAMERA_ATTR_READ_MODE_TEST{"TEST"}; + static constexpr std::string_view CAMERA_ATTR_READ_MODE_INVALID{"INVALID"}; - // FPGA status bits - struct FPGAStatus { - bool highGainEnabled; - bool overTemp; - bool TECEnabled; - }; + static constexpr std::string_view CAMERA_ATTR_READ_RATE_SLOW{"SLOW"}; + static constexpr std::string_view CAMERA_ATTR_READ_RATE_FAST{"FAST"}; + static constexpr std::string_view CAMERA_ATTR_READ_RATE_INVALID{"INVALID"}; + + static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_OPEN{"OPEN"}; // always open + static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_CLOSED{"CLOSED"}; // always closed + static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_EXP{"EXP"}; // open during acquisition + static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_INVALID{"INVALID"}; RaptorEagleCCD(const adc::traits::adc_input_char_range auto& epix_video_fmt_filename, std::shared_ptr logger = spdlog::null_logger_mt("EAGLE_CCD_NULLLOGGER")); @@ -77,21 +83,6 @@ public: ~RaptorEagleCCD(); - std::bitset<8> getSystemState(); - void setSystemState(const std::bitset<8>& bits); - void setSystemStateBit(const size_t bit_pos); - void clearSystemStateBit(const size_t bit_pos); - void flipSystemStateBit(const size_t bit_pos); - - std::bitset<8> getFPGAState(); - void setFPGAState(const std::bitset<8>& bits); - void setFPGAStateBit(const size_t bit_pos); - void clearFPGAStateBit(const size_t bit_pos); - void flipFPGAStateBit(const size_t bit_pos); - - const SystemStatus getSystemStatus(); - void setSystemStatus(const SystemStatus&); - void setSystemStatus(const uint8_t&); private: typedef std::vector byte_seq_t; @@ -101,6 +92,13 @@ private: uint16_t _dimCCD[2] = {2048, 2048}; // init to E2V 4240 CCD dimension + // CCD temperature and TEC set point calibration data + uint16_t _adcCCDTempCalibData[2] = {0, 0}; // [at 0C, at +40C] + double _adcCCDTempCalibCoeffs[2] = {0, 0}; // [k, b], Temp(degs C) = k*ADC + b + + uint16_t _dacTECSetPointCalibData[2] = {0, 0}; // [at 0C, at +40C] + double _dacTECSetPointCalibCoeffs[2] = {0, 0}; // [k, b], Temp(degs C) = k*DAC + b + // CameraLink read/write setup flags uint8_t _clCommandAckBit; uint8_t _clChecksumBit; @@ -138,6 +136,20 @@ private: void writeRegisters(const byte_seq_t& addrs, const byte_seq_t& values); + // camera and FPGA control registers getter/setter + + std::bitset<8> getSystemState(); + void setSystemState(const std::bitset<8>& bits); + void setSystemStateBit(const size_t bit_pos); + void clearSystemStateBit(const size_t bit_pos); + void flipSystemStateBit(const size_t bit_pos); + + std::bitset<8> getFPGAState(); + void setFPGAState(const std::bitset<8>& bits); + void setFPGAStateBit(const size_t bit_pos); + void clearFPGAStateBit(const size_t bit_pos); + void flipFPGAStateBit(const size_t bit_pos); + // logging helper methods