|
|
|
|
@@ -329,6 +329,77 @@ void RaptorEagleCCD::flipFPGAStateBit(const size_t pos)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::bitset<8> RaptorEagleCCD::getTriggerRegister()
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard log_guard(_camlinkMutex);
|
|
|
|
|
|
|
|
|
|
auto bytes = readRegisters({0xD4});
|
|
|
|
|
|
|
|
|
|
std::bitset<8> bits{bytes[0]};
|
|
|
|
|
|
|
|
|
|
logDebug("Get trigger register as 0b{}", bits.to_string());
|
|
|
|
|
|
|
|
|
|
return bits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::chrono::utc_clock::time_point RaptorEagleCCD::setTriggerRegister(const std::bitset<8> bits)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock_guard(_camlinkMutex);
|
|
|
|
|
|
|
|
|
|
logDebug("Try to set trigger register to 0b{} bits", bits.to_string());
|
|
|
|
|
|
|
|
|
|
uint8_t reg = static_cast<uint8_t>(bits.to_ulong());
|
|
|
|
|
|
|
|
|
|
auto tm = std::chrono::utc_clock::now();
|
|
|
|
|
|
|
|
|
|
writeRegisters({0xD4}, {reg});
|
|
|
|
|
|
|
|
|
|
return tm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::chrono::utc_clock::time_point RaptorEagleCCD::setTriggerRegisterBit(const size_t bit_pos)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock_guard(_camlinkMutex);
|
|
|
|
|
|
|
|
|
|
auto bits = getTriggerRegister();
|
|
|
|
|
|
|
|
|
|
logDebug("Try to set '{}' trigger register", details::cl_trigger_register_bit(bit_pos));
|
|
|
|
|
|
|
|
|
|
bits.set(bit_pos);
|
|
|
|
|
|
|
|
|
|
return setTriggerRegister(bits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::chrono::utc_clock::time_point RaptorEagleCCD::clearTriggerRegisterBit(const size_t bit_pos)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock_guard(_camlinkMutex);
|
|
|
|
|
|
|
|
|
|
auto bits = getTriggerRegister();
|
|
|
|
|
|
|
|
|
|
logDebug("Try to clear '{}' trigger register", details::cl_trigger_register_bit(bit_pos));
|
|
|
|
|
|
|
|
|
|
bits.reset(bit_pos);
|
|
|
|
|
|
|
|
|
|
return setTriggerRegister(bits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::chrono::utc_clock::time_point RaptorEagleCCD::flipTriggerRegisterBit(const size_t bit_pos)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock_guard(_camlinkMutex);
|
|
|
|
|
|
|
|
|
|
auto bits = getTriggerRegister();
|
|
|
|
|
|
|
|
|
|
logDebug("Try to flip '{}' trigger register", details::cl_trigger_register_bit(bit_pos));
|
|
|
|
|
|
|
|
|
|
bits.flip(bit_pos);
|
|
|
|
|
|
|
|
|
|
return setTriggerRegister(bits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* PRIVATE METHODS */
|
|
|
|
|
|
|
|
|
|
bool RaptorEagleCCD::initCamera(int unitmap)
|
|
|
|
|
@@ -389,7 +460,7 @@ bool RaptorEagleCCD::initCamera(int unitmap)
|
|
|
|
|
(*this)[CAMERA_ATTR_YBIN] = 1;
|
|
|
|
|
|
|
|
|
|
// IDLE mode
|
|
|
|
|
(*this)[CAMERA_ATTR_TRIGGER_MODE] = CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT;
|
|
|
|
|
(*this)[CAMERA_ATTR_TRIGGER_MODE] = CAMERA_ATTR_TRIGGER_MODE_IDLE;
|
|
|
|
|
|
|
|
|
|
logInfo("Camera with unitmap '{}' is initialized", _cameraUnitmap);
|
|
|
|
|
|
|
|
|
|
@@ -788,7 +859,7 @@ void RaptorEagleCCD::getHardwareInfo()
|
|
|
|
|
cnt1 = *reinterpret_cast<uint16_t*>(_manufacturerData.data() + 14); // at 0C
|
|
|
|
|
cnt2 = *reinterpret_cast<uint16_t*>(_manufacturerData.data() + 16); // at +40C
|
|
|
|
|
|
|
|
|
|
_dacTECSetPointCalibCoeffs[0] = (cnt2 - cnt1) / (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1);
|
|
|
|
|
_dacTECSetPointCalibCoeffs[0] = (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1) / (cnt2 - cnt1);
|
|
|
|
|
_dacTECSetPointCalibCoeffs[1] = DAC_CALIBRATION_POINT_2 - _dacTECSetPointCalibCoeffs[0] * cnt2;
|
|
|
|
|
if (_dacTECSetPointCalibCoeffs[1] > 0.0) {
|
|
|
|
|
logDebug("Computed DAC-to-Temp linear relation: Temp(C) = {:7.4f}*DAC(counts) + {:6.2f}",
|
|
|
|
|
@@ -798,8 +869,8 @@ void RaptorEagleCCD::getHardwareInfo()
|
|
|
|
|
_dacTECSetPointCalibCoeffs[0], std::abs(_dacTECSetPointCalibCoeffs[1]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dacTECSetPointCalibCoeffs[2] = (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1) / (cnt2 - cnt1);
|
|
|
|
|
_dacTECSetPointCalibCoeffs[3] = cnt2 - _dacTECSetPointCalibCoeffs[0] * DAC_CALIBRATION_POINT_2;
|
|
|
|
|
_dacTECSetPointCalibCoeffs[2] = (cnt2 - cnt1) / (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1);
|
|
|
|
|
_dacTECSetPointCalibCoeffs[3] = cnt2 - _dacTECSetPointCalibCoeffs[2] * DAC_CALIBRATION_POINT_2;
|
|
|
|
|
logDebug("Computed Temp-to-Dac linear relation: DAC(counts) = {}*Temp(C) + {}", _dacTECSetPointCalibCoeffs[2],
|
|
|
|
|
_dacTECSetPointCalibCoeffs[3]);
|
|
|
|
|
|
|
|
|
|
@@ -844,8 +915,10 @@ void RaptorEagleCCD::startAquisition()
|
|
|
|
|
throw std::system_error(RaptorEagleCCDError::ERROR_ACQUISITION_IN_PROGRESS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto bytes = readRegisters({0xD4}); // trigger mode register
|
|
|
|
|
std::bitset<8> bits(bytes[0]);
|
|
|
|
|
// auto bytes = readRegisters({0xD4}); // trigger mode register
|
|
|
|
|
// std::bitset<8> bits(bytes[0]);
|
|
|
|
|
|
|
|
|
|
auto bits = getTriggerRegister();
|
|
|
|
|
|
|
|
|
|
if (bits.test(CL_TRIGGER_MODE_EXT_TRIGGER_BIT)) {
|
|
|
|
|
logError("External trigger mode is set! Nothing to do, exit!");
|
|
|
|
|
@@ -861,10 +934,10 @@ void RaptorEagleCCD::startAquisition()
|
|
|
|
|
.abortTime = std::chrono::utc_clock::time_point(),
|
|
|
|
|
.saveInAbort = false,
|
|
|
|
|
.expTime = (*this)[CAMERA_ATTR_EXPTIME],
|
|
|
|
|
.roiStartX = (*this)[CAMERA_ATTR_ROI_STARTX],
|
|
|
|
|
.roiStartY = (*this)[CAMERA_ATTR_ROI_STARTY],
|
|
|
|
|
.roiWidth = (*this)[CAMERA_ATTR_ROI_WIDTH],
|
|
|
|
|
.roiHeight = (*this)[CAMERA_ATTR_ROI_HEIGHT],
|
|
|
|
|
.roiStartX = (*this)[CAMERA_ATTR_ROI_STARTX], // in CCD pixels (start from 0)
|
|
|
|
|
.roiStartY = (*this)[CAMERA_ATTR_ROI_STARTY], // in CCD pixels (start from 0)
|
|
|
|
|
.roiWidth = (*this)[CAMERA_ATTR_ROI_WIDTH], // in binned pixels
|
|
|
|
|
.roiHeight = (*this)[CAMERA_ATTR_ROI_HEIGHT], // in binned pixels
|
|
|
|
|
.binX = (*this)[CAMERA_ATTR_XBIN],
|
|
|
|
|
.binY = (*this)[CAMERA_ATTR_YBIN],
|
|
|
|
|
.shutterState = (*this)[CAMERA_ATTR_SHUTTER_STATE],
|
|
|
|
|
@@ -883,10 +956,23 @@ void RaptorEagleCCD::startAquisition()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// adjust geometry
|
|
|
|
|
auto w = acq_pars->roiWidth / acq_pars->binX;
|
|
|
|
|
auto dv = std::div(_dimCCD[0] - acq_pars->roiStartX, acq_pars->binX);
|
|
|
|
|
auto width_max = dv.quot + (dv.rem ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
if (acq_pars->binX > 1) {
|
|
|
|
|
dv = std::div(_dimCCD[1] - acq_pars->roiStartY, acq_pars->binY);
|
|
|
|
|
auto height_max = dv.quot + (dv.rem ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
if (acq_pars->roiWidth > width_max) {
|
|
|
|
|
acq_pars->roiWidth = width_max;
|
|
|
|
|
logDebug("Adjust ROI width to {}", acq_pars->roiWidth);
|
|
|
|
|
(*this)[CAMERA_ATTR_ROI_WIDTH] = width_max;
|
|
|
|
|
}
|
|
|
|
|
if (acq_pars->roiHeight > height_max) {
|
|
|
|
|
acq_pars->roiHeight = height_max;
|
|
|
|
|
logDebug("Adjust ROI height to {}", acq_pars->roiHeight);
|
|
|
|
|
(*this)[CAMERA_ATTR_ROI_HEIGHT] = height_max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::lock_guard lock_guard(_acqProcessesMutex);
|
|
|
|
|
|
|
|
|
|
@@ -903,14 +989,17 @@ void RaptorEagleCCD::startAquisition()
|
|
|
|
|
// arm grabber here
|
|
|
|
|
sptr->start(acq_pars);
|
|
|
|
|
|
|
|
|
|
bits.set(CL_TRIGGER_MODE_SNAPSHOT_BIT); // start snapshot bit
|
|
|
|
|
bytes[0] = static_cast<uint8_t>(bits.to_ulong());
|
|
|
|
|
// bits.set(CL_TRIGGER_MODE_SNAPSHOT_BIT); // start snapshot bit
|
|
|
|
|
// bytes[0] = static_cast<uint8_t>(bits.to_ulong());
|
|
|
|
|
|
|
|
|
|
acq_pars->startTime = std::chrono::utc_clock::now();
|
|
|
|
|
writeRegisters({0xD4}, bytes); // write to trigger mode register (start snapshot)
|
|
|
|
|
// acq_pars->startTime = std::chrono::utc_clock::now();
|
|
|
|
|
// writeRegisters({0xD4}, bytes); // write to trigger mode register (start snapshot)
|
|
|
|
|
|
|
|
|
|
// start acquisition here
|
|
|
|
|
acq_pars->startTime = setTriggerRegisterBit(CL_TRIGGER_MODE_SNAPSHOT_BIT);
|
|
|
|
|
|
|
|
|
|
int status;
|
|
|
|
|
xclibApiCall(status = pxd_goneLive(_cameraUnitmap, 0), std::format("psxd_goneLive({}, 0)", _cameraUnitmap));
|
|
|
|
|
xclibApiCall(status = pxd_goneLive(_cameraUnitmap, 0), std::format("pxd_goneLive({}, 0)", _cameraUnitmap));
|
|
|
|
|
if (status == 0) {
|
|
|
|
|
logError("CANNOT START ACQUIRING!!!");
|
|
|
|
|
}
|
|
|
|
|
@@ -1267,14 +1356,19 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
[this]<typename T>(const T& val) { // validator
|
|
|
|
|
std::pair<T, std::string> res{val, ""};
|
|
|
|
|
|
|
|
|
|
if (val < 1) {
|
|
|
|
|
res.first = 1;
|
|
|
|
|
res.second = "The ROI X-offset must start from 1 (FITS notation)";
|
|
|
|
|
} else if (val > _dimCCD[0]) {
|
|
|
|
|
res.first = _dimCCD[0];
|
|
|
|
|
res.second = std::format(
|
|
|
|
|
"The ROI X-offset must not be greater than CCD X-dimension of {} pixels (FITS notation)",
|
|
|
|
|
_dimCCD[0]);
|
|
|
|
|
// if (val < 1) {
|
|
|
|
|
// res.first = 1;
|
|
|
|
|
// res.second = "The ROI X-offset must start from 1 (FITS notation)";
|
|
|
|
|
// } else if (val > _dimCCD[0]) {
|
|
|
|
|
// res.first = _dimCCD[0];
|
|
|
|
|
// res.second = std::format(
|
|
|
|
|
// "The ROI X-offset must not be greater than CCD X-dimension of {} pixels (FITS notation)",
|
|
|
|
|
// _dimCCD[0]);
|
|
|
|
|
// }
|
|
|
|
|
if (val >= _dimCCD[0]) {
|
|
|
|
|
res.first = _dimCCD[0] - 1;
|
|
|
|
|
res.second =
|
|
|
|
|
std::format("The ROI X-offset must be lesser than CCD X-dimension of {} pixels", _dimCCD[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
@@ -1288,14 +1382,19 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
[this]<typename T>(const T& val) { // validator
|
|
|
|
|
std::pair<T, std::string> res{val, ""};
|
|
|
|
|
|
|
|
|
|
if (val < 1) {
|
|
|
|
|
res.first = 1;
|
|
|
|
|
res.second = "The ROI Y-offset must start from 1 (FITS notation)";
|
|
|
|
|
} else if (val > _dimCCD[1]) {
|
|
|
|
|
res.first = _dimCCD[1];
|
|
|
|
|
res.second = std::format(
|
|
|
|
|
"The ROI Y-offset must not be greater than CCD Y-dimension of {} pixels (FITS notation)",
|
|
|
|
|
_dimCCD[1]);
|
|
|
|
|
// if (val < 1) {
|
|
|
|
|
// res.first = 1;
|
|
|
|
|
// res.second = "The ROI Y-offset must start from 1 (FITS notation)";
|
|
|
|
|
// } else if (val > _dimCCD[1]) {
|
|
|
|
|
// res.first = _dimCCD[1];
|
|
|
|
|
// res.second = std::format(
|
|
|
|
|
// "The ROI Y-offset must not be greater than CCD Y-dimension of {} pixels (FITS notation)",
|
|
|
|
|
// _dimCCD[1]);
|
|
|
|
|
// }
|
|
|
|
|
if (val >= _dimCCD[1]) {
|
|
|
|
|
res.first = _dimCCD[1] - 1;
|
|
|
|
|
res.second =
|
|
|
|
|
std::format("The ROI Y-offset must be lesser than CCD Y-dimension of {} pixels", _dimCCD[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
@@ -1314,8 +1413,8 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
res.second = "The ROI width must start from 1";
|
|
|
|
|
} else if (val > _dimCCD[0]) {
|
|
|
|
|
res.first = _dimCCD[0];
|
|
|
|
|
res.second = std::format(
|
|
|
|
|
"The ROI width must not be greater than CCD dimension of {} pixels (FITS notation)", _dimCCD[0]);
|
|
|
|
|
res.second =
|
|
|
|
|
std::format("The ROI width must not be greater than CCD dimension of {} pixels", _dimCCD[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
@@ -1331,8 +1430,8 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
// ROI height can be 0 (see Eagle V 4240 instruction manual)
|
|
|
|
|
if (val > _dimCCD[1]) {
|
|
|
|
|
res.first = _dimCCD[1];
|
|
|
|
|
res.second = std::format(
|
|
|
|
|
"The ROI height must not be greater than CCD dimension of {} pixels (FITS notation)", _dimCCD[1]);
|
|
|
|
|
res.second =
|
|
|
|
|
std::format("The ROI height must not be greater than CCD dimension of {} pixels", _dimCCD[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
@@ -1737,8 +1836,9 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
addAttribute(
|
|
|
|
|
CAMERA_ATTR_TRIGGER_MODE,
|
|
|
|
|
[this]() {
|
|
|
|
|
auto bytes = readRegisters({0xD4});
|
|
|
|
|
std::bitset<8> bits{bytes[0]};
|
|
|
|
|
// auto bytes = readRegisters({0xD4});
|
|
|
|
|
// std::bitset<8> bits{bytes[0]};
|
|
|
|
|
auto bits = getTriggerRegister();
|
|
|
|
|
std::string_view trigger_mode;
|
|
|
|
|
|
|
|
|
|
if (bits.test(CL_TRIGGER_MODE_EXT_TRIGGER_BIT)) { // external trigger enabled, what is the edge?
|
|
|
|
|
@@ -1757,12 +1857,13 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logTrace("Return trigger mode as '{}' string (bits = 0b{:08b})", trigger_mode, bytes[0]);
|
|
|
|
|
// logTrace("Return trigger mode as '{}' string (bits = 0b{:08b})", trigger_mode, bytes[0]);
|
|
|
|
|
logTrace("Return trigger mode as '{}' string (bits = 0b{})", trigger_mode, bits.to_string());
|
|
|
|
|
|
|
|
|
|
return trigger_mode;
|
|
|
|
|
},
|
|
|
|
|
[this](const std::string_view& mode) {
|
|
|
|
|
uchar bits = CL_TRIGGER_MODE_SNAPSHOT;
|
|
|
|
|
uchar bits = CL_TRIGGER_MODE_IDLE;
|
|
|
|
|
if (mode == CAMERA_ATTR_TRIGGER_MODE_EXT_RISING) {
|
|
|
|
|
bits = CL_TRIGGER_MODE_EXT_RISING_EDGE;
|
|
|
|
|
logInfo("Trigger mode is set to {}", mode);
|
|
|
|
|
@@ -1775,18 +1876,20 @@ void RaptorEagleCCD::initAttrComm()
|
|
|
|
|
} else if (mode == CAMERA_ATTR_TRIGGER_MODE_ITR) {
|
|
|
|
|
bits = CL_TRIGGER_MODE_ITR;
|
|
|
|
|
logInfo("Trigger mode is set to {}", mode);
|
|
|
|
|
} else if (mode == CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT) {
|
|
|
|
|
} else if (mode == CAMERA_ATTR_TRIGGER_MODE_IDLE) {
|
|
|
|
|
logInfo("Trigger mode is set to {}", mode);
|
|
|
|
|
} else {
|
|
|
|
|
logWarn("Invalid trigger mode! Set it to {}!", CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT);
|
|
|
|
|
logWarn("Invalid trigger mode! Set it to {}!", CAMERA_ATTR_TRIGGER_MODE_IDLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// // snapshot mode is self-clearing bit so activate it directly in 'startAcquision' method
|
|
|
|
|
// if (mode != CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT) {
|
|
|
|
|
writeRegisters({0xD4}, {bits});
|
|
|
|
|
// writeRegisters({0xD4}, {bits});
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
logDebug("Trigger mode bits are set to 0b{:08b}", bits);
|
|
|
|
|
// logDebug("Trigger mode bits are set to 0b{:08b}", bits);
|
|
|
|
|
|
|
|
|
|
setTriggerRegister(bits);
|
|
|
|
|
},
|
|
|
|
|
adc::utils::AdcDefaultValueConverter<>::serialize<attribute_t::serialized_t, std::string_view>,
|
|
|
|
|
[&comp_case_ignore](const attribute_t::serialized_t& v) {
|
|
|
|
|
|