This commit is contained in:
Timur A. Fatkhullin 2024-12-05 11:22:11 +03:00
parent e834f2c5d6
commit 5f6b7fa4cf
3 changed files with 249 additions and 57 deletions

View File

@ -95,13 +95,18 @@ static constexpr std::string_view cl_fpga_ctrl_reg_bit(const size_t pos)
// trigger mode // trigger mode
static constexpr char CL_TRIGGER_MODE_ENABLE_RISING_EDGE = 0x80; // 7-th bit static constexpr size_t CL_TRIGGER_MODE_ENABLE_RISING_EDGE_BIT = 7;
static constexpr char CL_TRIGGER_MODE_EXT_TRIGGER = 0x40; // 6-th bit static constexpr size_t CL_TRIGGER_MODE_EXT_TRIGGER_BIT = 6;
static constexpr char CL_TRIGGER_MODE_ABORT_CURRENT_EXP = 0x8; // 3-rd bit static constexpr size_t CL_TRIGGER_MODE_ABORT_CURRENT_EXP_BIT = 3;
static constexpr char CL_TRIGGER_MODE_CONTINUOUS_SEQ = 0x4; // 2-nd bit static constexpr size_t CL_TRIGGER_MODE_CONTINUOUS_SEQ_BIT = 2;
static constexpr char CL_TRIGGER_MODE_FIXED_FRAME_RATE = 0x2; // 1-st bit static constexpr size_t CL_TRIGGER_MODE_FIXED_FRAME_RATE_BIT = 1;
static constexpr char CL_TRIGGER_MODE_SNAPSHOT = 0x1; // 0-th bit static constexpr size_t CL_TRIGGER_MODE_SNAPSHOT_BIT = 0;
static constexpr unsigned char CL_TRIGGER_MODE_EXT_RISING_EDGE = 0b11000000;
static constexpr unsigned char CL_TRIGGER_MODE_EXT_FALLING_EDGE = 0b01000000;
static constexpr unsigned char CL_TRIGGER_MODE_FFR = 0b00000110;
static constexpr unsigned char CL_TRIGGER_MODE_ITR = 0b00000100;
static constexpr unsigned char CL_TRIGGER_MODE_SNAPSHOT = 0; // just clear all bits
/* SETUP CONTROL VALUES */ /* SETUP CONTROL VALUES */

View File

@ -316,6 +316,12 @@ void RaptorEagleCCD::initCamera(int unitmap)
std::format("pxd_serialConfigure({}, 0, {}, {}, 0, {}, 0, 0, 0)", _cameraUnitmap, CL_DEFAULT_BAUD_RATE, std::format("pxd_serialConfigure({}, 0, {}, {}, 0, {}, 0, 0, 0)", _cameraUnitmap, CL_DEFAULT_BAUD_RATE,
CL_DEFAULT_DATA_BITS, CL_DEFAULT_STOP_BIT)); CL_DEFAULT_DATA_BITS, CL_DEFAULT_STOP_BIT));
getSystemState();
getHardwareInfo();
getMicroVersion();
getFPGAVersion();
logInfo("Camera with unitmap '{}' is initialized", _cameraUnitmap); logInfo("Camera with unitmap '{}' is initialized", _cameraUnitmap);
} }
@ -578,23 +584,17 @@ void RaptorEagleCCD::getHardwareInfo()
{ {
std::lock_guard lock_guard(_camlinkMutex); std::lock_guard lock_guard(_camlinkMutex);
static byte_seq_t bytes(20);
// first, according to instruction manual, set FPGA comms bit // first, according to instruction manual, set FPGA comms bit
setSystemStateBit(CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS_BIT); setSystemStateBit(CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS_BIT);
// get manufacturer data // get manufacturer data
clWrite({0x53, 0xAE, 0x05, 0x01, 0x00, 0x00, 0x02, 0x00}); clWrite({0x53, 0xAE, 0x05, 0x01, 0x00, 0x00, 0x02, 0x00});
clWrite({0x53, 0xAF, 0x12}); clWrite({0x53, 0xAF, 0x12});
clReadAndCheckAck(bytes); clReadAndCheckAck(_manufacturerData);
// NOTE: works only for little-endian platforms!!! _buildDate =
_cameraSerialNumber = *reinterpret_cast<uint16_t*>(bytes.data()); std::chrono::year_month_day(std::chrono::year(2000 + _manufacturerData[4]) /
std::chrono::month(_manufacturerData[3]) / std::chrono::day(_manufacturerData[2]));
_buildDate = std::chrono::year_month_day(std::chrono::year(2000 + bytes[4]) / std::chrono::month(bytes[3]) /
std::chrono::day(bytes[2]));
_buildCode = std::string_view(reinterpret_cast<char*>(bytes.data() + 5), 5);
logDebug("------- Manufacturer data -------"); logDebug("------- Manufacturer data -------");
logDebug("Camerial serial number: {}", _cameraSerialNumber); logDebug("Camerial serial number: {}", _cameraSerialNumber);
@ -602,24 +602,33 @@ void RaptorEagleCCD::getHardwareInfo()
logDebug("Build code: {}", _buildCode); logDebug("Build code: {}", _buildCode);
// ADC calibration data // ADC calibration data
double cnt1 = *reinterpret_cast<uint16_t*>(bytes.data() + 10); // at 0C double cnt1 = *reinterpret_cast<uint16_t*>(_manufacturerData.data() + 10); // at 0C
double cnt2 = *reinterpret_cast<uint16_t*>(bytes.data() + 12); // at +40C double cnt2 = *reinterpret_cast<uint16_t*>(_manufacturerData.data() + 12); // at +40C
logDebug(""); logDebug("");
logDebug("ADC calib data {} counts at 0C", cnt1); logDebug("ADC calib data [{}, {}] counts at [{}C, {}C]", _adcCCDTempCalibData[0], _adcCCDTempCalibData[1],
logDebug("ADC calib data {} counts at +40C", cnt2); ADC_CALIBRATION_POINT_1, ADC_CALIBRATION_POINT_2);
// compute linear relation: Temp = k*ADC + b // compute linear relation: Temp = k*ADC + b
_adcCCDTempCalibCoeffs[0] = (cnt2 - cnt1) / (ADC_CALIBRATION_POINT_2 - ADC_CALIBRATION_POINT_1); // k _adcCCDTempCalibCoeffs[0] = (cnt2 - cnt1) / (ADC_CALIBRATION_POINT_2 - ADC_CALIBRATION_POINT_1); // k
_adcCCDTempCalibCoeffs[1] = ADC_CALIBRATION_POINT_2 - _adcCCDTempCalibCoeffs[0] * cnt2; _adcCCDTempCalibCoeffs[1] = ADC_CALIBRATION_POINT_2 - _adcCCDTempCalibCoeffs[0] * cnt2;
logDebug("Computed ADC-to-Temp linear relation: Temp(C) = {:7.4}*ADC(counts)+{:6.2}");
// DAC calibration data
_dacTECSetPointCalibData[0] = *reinterpret_cast<uint16_t*>(bytes.data() + 14); // at 0C
_dacTECSetPointCalibData[1] = *reinterpret_cast<uint16_t*>(bytes.data() + 16); // at +40C
logDebug(""); logDebug("");
logDebug("DAC calib data {} counts at 0C", _dacTECSetPointCalibData[0]); logDebug("DAC calib data [{}, {}] counts at [{}C, {}C]", _dacTECSetPointCalibData[0], _dacTECSetPointCalibData[1],
logDebug("DAC calib data {} counts at +40C", _dacTECSetPointCalibData[1]); DAC_CALIBRATION_POINT_1, DAC_CALIBRATION_POINT_2);
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[1] = DAC_CALIBRATION_POINT_2 - _dacTECSetPointCalibCoeffs[0] * cnt2;
logDebug("Computed DAC-to-Temp linear relation: Temp(C) = {:7.4}*DAC(counts)+{:6.2}");
_dacTECSetPointCalibCoeffs[2] = (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1) / (cnt2 - cnt1);
_dacTECSetPointCalibCoeffs[3] = cnt2 - _dacTECSetPointCalibCoeffs[0] * DAC_CALIBRATION_POINT_2;
logDebug("Computed DAC-to-Temp linear relation: DAC(counts) = {}*Temp(C)+{}");
logDebug("---------------------------------"); logDebug("---------------------------------");
} }
@ -710,6 +719,21 @@ void RaptorEagleCCD::initAttrComm()
/* commands */ /* commands */
addCommand(CAMERA_CMD_INITCAM, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_INITCAM);
initCamera();
});
addCommand(CAMERA_CMD_START_EXP, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_START_EXP);
//
});
addCommand(CAMERA_CMD_STOP_EXP, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_STOP_EXP);
//
});
/* attributes */ /* attributes */
@ -959,7 +983,7 @@ void RaptorEagleCCD::initAttrComm()
"YBIN")); "YBIN"));
/* TEC SET POINT */ /* TEC SET POINT AND STATE */
// DAC counts // DAC counts
addAttribute(create12BitAttr( addAttribute(create12BitAttr(
@ -968,7 +992,8 @@ void RaptorEagleCCD::initAttrComm()
std::pair<T, std::string> res{counts, ""}; std::pair<T, std::string> res{counts, ""};
if (counts > 0x0FFF) { if (counts > 0x0FFF) {
res.second = std::format("TEC set point counts must not be greater than {}", 0x0FFF); res.second =
std::format("TEC set point counts must not be greater than {}. Set it to {}!", 0x0FFF, 0x0FFF);
res.first = 0x0FFF; res.first = 0x0FFF;
} }
@ -982,33 +1007,45 @@ void RaptorEagleCCD::initAttrComm()
[this]() { [this]() {
double counts = (*this)[CAMERA_ATTR_TECPOINT_DAC]; double counts = (*this)[CAMERA_ATTR_TECPOINT_DAC];
double k = (DAC_CALIBRATION_POINT_2 - DAC_CALIBRATION_POINT_1) / double temp = _dacTECSetPointCalibCoeffs[0] * counts + _dacTECSetPointCalibCoeffs[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); logDebug("Return TEC set point as {} Celsius degrees", temp);
return temp; return temp;
}, },
[this](const double& temp) { [this](const double& temp) {
double k = (_dacTECSetPointCalibData[1] - _dacTECSetPointCalibData[0]) / uint64_t v = static_cast<uint64_t>(temp * _dacTECSetPointCalibCoeffs[2] + _dacTECSetPointCalibCoeffs[3]);
(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<uint64_t>(temp * k + b);
uint16_t counts = v & 0x0FFF; // extract 12-bits uint16_t counts = v & 0x0FFF; // extract 12-bits
logInfo("Set TEC setup point to {} C", temp);
(*this)[CAMERA_ATTR_TECPOINT_DAC] = counts; (*this)[CAMERA_ATTR_TECPOINT_DAC] = counts;
}); });
addAttribute(
CAMERA_ATTR_TECSTATE,
[this]() {
bool bit = getFPGAState().test(CL_FPGA_CTRL_REG_ENABLE_TEC_BIT);
if (bit) {
return CAMERA_ATTR_TECSTATE_ON;
} else {
return CAMERA_ATTR_TECSTATE_OFF;
}
},
[this](const std::string_view& state) {
if (state == CAMERA_ATTR_TECSTATE_ON) {
logInfo("Turn ON TEC");
setFPGAStateBit(CL_FPGA_CTRL_REG_ENABLE_TEC_BIT);
} else if (state == CAMERA_ATTR_TECSTATE_OFF) {
logInfo("Turn OFF TEC");
clearFPGAStateBit(CL_FPGA_CTRL_REG_ENABLE_TEC_BIT);
} else {
logWarn("Invalid TEC state string value! Ignore!");
}
});
/* CCD and PCB temperature (read-only) */ /* CCD and PCB temperature (read-only) */
addAttribute(CAMERA_ATTR_PCB_TEMP, [this]() { addAttribute(CAMERA_ATTR_PCB_TEMP, [this]() {
@ -1056,7 +1093,7 @@ void RaptorEagleCCD::initAttrComm()
addAttribute( addAttribute(
CAMERA_ATTR_READ_MODE, CAMERA_ATTR_READ_MODE,
[this]() -> std::string_view { [this]() {
auto bytes = readRegisters(CL_READMODE_ADDR); auto bytes = readRegisters(CL_READMODE_ADDR);
std::string_view val = CAMERA_ATTR_READ_MODE_NORMAL; std::string_view val = CAMERA_ATTR_READ_MODE_NORMAL;
@ -1066,7 +1103,7 @@ void RaptorEagleCCD::initAttrComm()
} else { } else {
logError("Invalid bits in readout mode register! (reg = 0x{:02X})", bytes[0]); logError("Invalid bits in readout mode register! (reg = 0x{:02X})", bytes[0]);
val = CAMERA_ATTR_READ_MODE_INVALID; val = CAMERA_ATTR_STR_INVALID;
} }
logTrace("Return readout mode as '{}' string", val); logTrace("Return readout mode as '{}' string", val);
@ -1078,12 +1115,14 @@ void RaptorEagleCCD::initAttrComm()
if (mode == CAMERA_ATTR_READ_MODE_NORMAL) { if (mode == CAMERA_ATTR_READ_MODE_NORMAL) {
bits = CL_READOUT_MODE_NORMAL; bits = CL_READOUT_MODE_NORMAL;
} logInfo("Readout mode is set to {}", mode);
if (mode == CAMERA_ATTR_READ_MODE_TEST) { } else if (mode == CAMERA_ATTR_READ_MODE_TEST) {
bits = CL_READOUT_MODE_TEST; bits = CL_READOUT_MODE_TEST;
logInfo("Readout mode is set to {}", mode);
} else { } else {
logWarn("Invalid '{}' string for readout mode! Use of '{}'!", mode, CAMERA_ATTR_READ_MODE_NORMAL); logWarn("Invalid '{}' string for readout mode! Use of '{}'!", mode, CAMERA_ATTR_READ_MODE_NORMAL);
bits = CL_READOUT_MODE_NORMAL; bits = CL_READOUT_MODE_NORMAL;
logInfo("Readout mode is set to {}", CAMERA_ATTR_READ_MODE_NORMAL);
} }
writeRegisters(CL_READMODE_ADDR, {bits}); writeRegisters(CL_READMODE_ADDR, {bits});
@ -1107,7 +1146,7 @@ void RaptorEagleCCD::initAttrComm()
} else { } else {
logError("Invalid bits in readout rate registers! (A3 = 0x{:02X}, A4 = 0x{:02X})", bytes[0], bytes[1]); logError("Invalid bits in readout rate registers! (A3 = 0x{:02X}, A4 = 0x{:02X})", bytes[0], bytes[1]);
val = CAMERA_ATTR_READ_RATE_INVALID; val = CAMERA_ATTR_STR_INVALID;
} }
logTrace("Return readout rate as '()' string", val); logTrace("Return readout rate as '()' string", val);
@ -1117,11 +1156,14 @@ void RaptorEagleCCD::initAttrComm()
[this](const std::string_view& rate) { [this](const std::string_view& rate) {
byte_seq_t bytes({CL_READOUT_CLOCK_RATE_A3_2MHZ, CL_READOUT_CLOCK_RATE_A4_2MHZ}); byte_seq_t bytes({CL_READOUT_CLOCK_RATE_A3_2MHZ, CL_READOUT_CLOCK_RATE_A4_2MHZ});
if (rate == CAMERA_ATTR_READ_RATE_FAST) { if (rate == CAMERA_ATTR_READ_RATE_FAST) {
logInfo("Set readout rate to {}", rate);
} else if (rate == CAMERA_ATTR_READ_RATE_SLOW) { } else if (rate == CAMERA_ATTR_READ_RATE_SLOW) {
bytes[0] = CL_READOUT_CLOCK_RATE_A3_75KHZ; bytes[0] = CL_READOUT_CLOCK_RATE_A3_75KHZ;
bytes[1] = CL_READOUT_CLOCK_RATE_A4_75KHZ; bytes[1] = CL_READOUT_CLOCK_RATE_A4_75KHZ;
logInfo("Set readout rate to {}", rate);
} else { } else {
logWarn("Invalid '{}' string for readout rate! Use of '{}'!", rate, CAMERA_ATTR_READ_RATE_FAST); logWarn("Invalid '{}' string for readout rate! Use of '{}'!", rate, CAMERA_ATTR_READ_RATE_FAST);
logInfo("Set readout rate to {}", CAMERA_ATTR_READ_RATE_FAST);
} }
writeRegisters(CL_FRAMERATE_ADDR, bytes); writeRegisters(CL_FRAMERATE_ADDR, bytes);
@ -1130,7 +1172,7 @@ void RaptorEagleCCD::initAttrComm()
}); });
/* SHUTTER CONTROL (std::string_view "OPEN", "CLOSED", "EXP") */ /* SHUTTER CONTROL (std::string_view "OPEN", "CLOSED", "EXP") AND OPEN/CLOSE DELAY */
addAttribute( addAttribute(
CAMERA_ATTR_SHUTTER_STATE, CAMERA_ATTR_SHUTTER_STATE,
@ -1146,7 +1188,7 @@ void RaptorEagleCCD::initAttrComm()
val = CAMERA_ATTR_SHUTTER_STATE_EXP; val = CAMERA_ATTR_SHUTTER_STATE_EXP;
} else { } else {
logError("Invalid bits in shhutter control register! (reg = 0x{:02X})", bytes[0]); logError("Invalid bits in shhutter control register! (reg = 0x{:02X})", bytes[0]);
val = CAMERA_ATTR_SHUTTER_STATE_INVALID; val = CAMERA_ATTR_STR_INVALID;
} }
logTrace("Return shutter state as '{}' string (bits = 0x{:02X})", val, bytes[0]); logTrace("Return shutter state as '{}' string (bits = 0x{:02X})", val, bytes[0]);
@ -1156,16 +1198,139 @@ void RaptorEagleCCD::initAttrComm()
[this](const std::string_view& state) { [this](const std::string_view& state) {
byte_seq_t bytes{CL_SHUTTER_EXP}; byte_seq_t bytes{CL_SHUTTER_EXP};
if (state == CAMERA_ATTR_SHUTTER_STATE_EXP) { if (state == CAMERA_ATTR_SHUTTER_STATE_EXP) {
logInfo("Set shutter state to {}", state);
} else if (state == CAMERA_ATTR_SHUTTER_STATE_CLOSED) { } else if (state == CAMERA_ATTR_SHUTTER_STATE_CLOSED) {
bytes[0] = CL_SHUTTER_CLOSED; bytes[0] = CL_SHUTTER_CLOSED;
logInfo("Set shutter state to {}", state);
} else if (state == CAMERA_ATTR_SHUTTER_STATE_OPEN) { } else if (state == CAMERA_ATTR_SHUTTER_STATE_OPEN) {
bytes[0] = CL_SHUTTER_OPEN; bytes[0] = CL_SHUTTER_OPEN;
logInfo("Set shutter state to {}", state);
} else { } else {
logWarn("Invalid '{}' string for shutter state! Use of '{}'!", state, CL_SHUTTER_EXP); logWarn("Invalid '{}' string for shutter state! Use of '{}'!", state, CL_SHUTTER_EXP);
logInfo("Set shutter state to {}", CL_SHUTTER_EXP);
} }
writeRegisters(CL_SHUTTER_CONTROL_ADDR, bytes); writeRegisters(CL_SHUTTER_CONTROL_ADDR, bytes);
logDebug("Shutter state is set to 0x{:02X}", bytes[0]); logDebug("Shutter state is set to 0x{:02X}", bytes[0]);
}); });
// floating-point, value is expected in millisecs
addAttribute(
CAMERA_ATTR_SHUTTER_CLOSEDELAY,
[this]() {
auto bytes = readRegisters({0xA7});
double delay = SHUTTER_DELAY_PERIOD * bytes[0];
logTrace("Return shutter closed delay duration as {} milliseconds", delay);
return delay;
},
[this](const double& delay) {
double d = SHUTTER_DEFAULT_DELAY_PERIOD;
if (delay < 0) {
logWarn("Shutter closed delay dration must be a non-negatve value! Use of default value {}",
SHUTTER_DEFAULT_DELAY_PERIOD);
} else if (delay > SHUTTER_MAX_DELAY_PERIOD) {
logWarn("Shutter closed delay dration must not be greater than {} value! Use of default value {}",
SHUTTER_MAX_DELAY_PERIOD, SHUTTER_DEFAULT_DELAY_PERIOD);
} else {
d = delay;
}
uchar counts = static_cast<uchar>(std::round(d / SHUTTER_DELAY_PERIOD));
writeRegisters({0xA7}, {counts});
logInfo("Shutter closed delay is set to {} msecs", d);
logDebug("Shutter closed delay bits are set to 0x{:02X}", counts);
});
// floating-point, value is expected in millisecs
addAttribute(
CAMERA_ATTR_SHUTTER_OPENDELAY,
[this]() {
auto bytes = readRegisters({0xA6});
double delay = SHUTTER_DELAY_PERIOD * bytes[0];
logTrace("Return shutter open delay duration as {} milliseconds", delay);
return delay;
},
[this](const double& delay) {
double d = SHUTTER_DEFAULT_DELAY_PERIOD;
if (delay < 0) {
logWarn("Shutter open delay dration must be a non-negatve value! Use of default value {}",
SHUTTER_DEFAULT_DELAY_PERIOD);
} else if (delay > SHUTTER_MAX_DELAY_PERIOD) {
logWarn("Shutter open delay dration must not be greater than {} value! Use of default value {}",
SHUTTER_MAX_DELAY_PERIOD, SHUTTER_DEFAULT_DELAY_PERIOD);
} else {
d = delay;
}
uchar counts = static_cast<uchar>(std::round(d / SHUTTER_DELAY_PERIOD));
writeRegisters({0xA6}, {counts});
logInfo("Shutter open delay is set to {} msecs", d);
logDebug("Shutter open delay bits are set to 0x{:02X}", counts);
});
/* TRIGGER MODE */
addAttribute(
CAMERA_ATTR_TRIGGER_MODE,
[this]() {
auto bytes = readRegisters({0xD4});
std::bitset<8> bits{bytes[0]};
std::string_view trigger_mode;
if (bits.test(CL_TRIGGER_MODE_EXT_TRIGGER_BIT)) { // external trigger enabled, what is the edge?
if (bits.test(CL_TRIGGER_MODE_ENABLE_RISING_EDGE_BIT)) {
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_EXT_RISING;
} else {
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_EXT_FALLING;
}
} else if (bits.test(CL_TRIGGER_MODE_CONTINUOUS_SEQ_BIT)) { // continuous sequence enabled
if (bits.test(CL_TRIGGER_MODE_FIXED_FRAME_RATE_BIT)) {
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_FFR;
} else {
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_ITR;
}
} else {
trigger_mode = CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT;
}
logTrace("Return trigger mode as '{}' string (bits = 0b{:08b})", trigger_mode, bytes[0]);
return trigger_mode;
},
[this](const std::string_view& mode) {
uchar bits = CL_TRIGGER_MODE_SNAPSHOT;
if (mode == CAMERA_ATTR_TRIGGER_MODE_EXT_RISING) {
bits = CL_TRIGGER_MODE_EXT_RISING_EDGE;
logInfo("Trigger mode is set to {}", mode);
} else if (mode == CAMERA_ATTR_TRIGGER_MODE_EXT_FALLING) {
bits = CL_TRIGGER_MODE_EXT_FALLING_EDGE;
logInfo("Trigger mode is set to {}", mode);
} else if (mode == CAMERA_ATTR_TRIGGER_MODE_FFR) {
bits = CL_TRIGGER_MODE_FFR;
logInfo("Trigger mode is set to {}", mode);
} 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) {
logInfo("Trigger mode is set to {}", mode);
} else {
logWarn("Invalid trigger mode! Set it to {}!", CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT);
}
writeRegisters({0xD4}, {bits});
logDebug("Trigger mode bits are set to 0b{:08b}", bits);
});
} }

View File

@ -38,6 +38,12 @@ public:
static constexpr double DAC_CALIBRATION_POINT_1 = 0.0; static constexpr double DAC_CALIBRATION_POINT_1 = 0.0;
static constexpr double DAC_CALIBRATION_POINT_2 = 40.0; static constexpr double DAC_CALIBRATION_POINT_2 = 40.0;
static constexpr double SHUTTER_DELAY_PERIOD = 1.6384; // in millisecs
static constexpr double SHUTTER_MAX_DELAY_PERIOD = SHUTTER_DELAY_PERIOD * 0xFF; // in millisecs
static constexpr double SHUTTER_DEFAULT_DELAY_PERIOD = 19.66; // in millisecs
static constexpr std::string_view CAMERA_ATTR_XBIN{"XBIN"}; static constexpr std::string_view CAMERA_ATTR_XBIN{"XBIN"};
static constexpr std::string_view CAMERA_ATTR_YBIN{"YBIN"}; static constexpr std::string_view CAMERA_ATTR_YBIN{"YBIN"};
static constexpr std::string_view CAMERA_ATTR_ROI_STARTX{"ROI_STARTX"}; static constexpr std::string_view CAMERA_ATTR_ROI_STARTX{"ROI_STARTX"};
@ -49,6 +55,7 @@ public:
static constexpr std::string_view CAMERA_ATTR_READ_RATE{"READ_RATE"}; 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_READ_MODE{"READ_MODE"};
static constexpr std::string_view CAMERA_ATTR_TECPOINT{"TECPOINT"}; static constexpr std::string_view CAMERA_ATTR_TECPOINT{"TECPOINT"};
static constexpr std::string_view CAMERA_ATTR_TECSTATE{"TECSTATE"};
static constexpr std::string_view CAMERA_ATTR_TECPOINT_DAC{"TECPOINT_DAC"}; 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_CCD_TEMP{"CCD_TEMP"};
static constexpr std::string_view CAMERA_ATTR_PCB_TEMP{"PCB_TEMP"}; static constexpr std::string_view CAMERA_ATTR_PCB_TEMP{"PCB_TEMP"};
@ -56,6 +63,8 @@ public:
static constexpr std::string_view CAMERA_ATTR_FRAME_RATE{"FRAME_RATE"}; 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_NEXP{"NEXP"};
static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE{"SHUTTER_STATE"}; static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE{"SHUTTER_STATE"};
static constexpr std::string_view CAMERA_ATTR_SHUTTER_OPENDELAY{"SHUTTER_OPEN_DELAY"};
static constexpr std::string_view CAMERA_ATTR_SHUTTER_CLOSEDELAY{"SHUTTER_CLOSE_DELAY"};
static constexpr std::string_view CAMERA_ATTR_CCDDIM{"CCDDIM"}; 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_ATTR_CAMLINK_SETUP{"CAMLINK_SETUP"};
@ -64,18 +73,20 @@ public:
static constexpr std::string_view CAMERA_CMD_STOP_EXP{"STOP_EXP"}; static constexpr std::string_view CAMERA_CMD_STOP_EXP{"STOP_EXP"};
// some character attributes values // some character attributes values
static constexpr std::string_view CAMERA_ATTR_STR_INVALID{"INVALID"};
static constexpr std::string_view CAMERA_ATTR_READ_MODE_NORMAL{"NORMAL"}; 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_TEST{"TEST"};
static constexpr std::string_view CAMERA_ATTR_READ_MODE_INVALID{"INVALID"};
static constexpr std::string_view CAMERA_ATTR_READ_RATE_SLOW{"SLOW"}; 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_FAST{"FAST"};
static constexpr std::string_view CAMERA_ATTR_READ_RATE_INVALID{"INVALID"};
static constexpr std::string_view CAMERA_ATTR_TECSTATE_ON{"ON"};
static constexpr std::string_view CAMERA_ATTR_TECSTATE_OFF{"OFF"};
static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_OPEN{"OPEN"}; // always open 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_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_EXP{"EXP"}; // open during acquisition
static constexpr std::string_view CAMERA_ATTR_SHUTTER_STATE_INVALID{"INVALID"};
// external trigger, rising edge enabled // external trigger, rising edge enabled
static constexpr std::string_view CAMERA_ATTR_TRIGGER_MODE_EXT_RISING{"EXTERNAL_RISING"}; static constexpr std::string_view CAMERA_ATTR_TRIGGER_MODE_EXT_RISING{"EXTERNAL_RISING"};
@ -105,10 +116,12 @@ private:
uint16_t _dimCCD[2] = {2048, 2048}; // init to E2V 4240 CCD dimension uint16_t _dimCCD[2] = {2048, 2048}; // init to E2V 4240 CCD dimension
// CCD temperature and TEC set point calibration data // 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 double _adcCCDTempCalibCoeffs[2] = {0, 0}; // [k, b], Temp(degs C) = k*ADC + b
double _dacTECSetPointCalibData[2] = {0, 0}; // [at 0C, at +40C] // [k, b, k_rev, b_rev]
// Temp = k*DAC + b
// DAC = k_rev*Temp + b_rev
double _dacTECSetPointCalibCoeffs[4] = {0, 0};
// CameraLink read/write setup flags // CameraLink read/write setup flags
uint8_t _clCommandAckBit; uint8_t _clCommandAckBit;
@ -120,13 +133,22 @@ private:
size_t _frameNumbers; size_t _frameNumbers;
// hardware version info // hardware version info
byte_seq_t _microVersion; // microcontroller version: _microVersion[0] - major, _microVersion[1] - minor byte_seq_t _microVersion; // microcontroller version: _microVersion[0] - major, _microVersion[1] - minor
byte_seq_t _FPGAVersion; // same for FPGA version byte_seq_t _FPGAVersion; // same for FPGA version
uint16_t _cameraSerialNumber = 0; // camera serial number // man data is 18-byte array + 2 possible bytes (ETX and checksum)
std::chrono::year_month_day _buildDate; byte_seq_t _manufacturerData = byte_seq_t(20);
std::string_view _buildCode; // extract fields according to instruction manual (WARNING: works only for little-endian platforms!)
const uint16_t& _cameraSerialNumber{
*reinterpret_cast<const uint16_t*>(_manufacturerData.data())}; // camera serial number (the first 2 bytes)
std::chrono::year_month_day _buildDate; // 3 bytes
const std::string_view _buildCode{reinterpret_cast<const char*>(_manufacturerData.data() + 5), 5}; // 5 bytes
// must be interpretated as 2-element array of calibration points [at 0C, at +40C] (4 bytes)
const uint16_t* _adcCCDTempCalibData{reinterpret_cast<const uint16_t*>(_manufacturerData.data() + 10)};
// must be interpretated as 2-element array of calibration points [at 0C, at +40C] (4 bytes)
const uint16_t* _dacTECSetPointCalibData{reinterpret_cast<const uint16_t*>(_manufacturerData.data() + 14)};
void initAttrComm(); void initAttrComm();