This commit is contained in:
Timur A. Fatkhullin 2024-12-06 18:44:21 +03:00
parent c6c825faee
commit fd8c2c7996
3 changed files with 194 additions and 14 deletions

View File

@ -131,10 +131,14 @@ RaptorEagleCCD::RaptorEagleCCD(const adc::traits::adc_input_char_range auto& epi
logDebug("CTOR: Create RaptorEagleCCD class instance");
if (_epixFmtVideoFilename.empty()) {
logDebug("Video format filename is not set! Use of default: {}", DEFAULT_EPIX_VIDEO_FMT_FILE);
logInfo("Video format filename is not given! Use of default: {}", DEFAULT_EPIX_VIDEO_FMT_FILE);
} else {
logDebug("Set video format filename: {}", _epixFmtVideoFilename);
logInfo("Set video format filename: {}", _epixFmtVideoFilename);
}
initAttrComm();
openPIXCI();
}
@ -146,6 +150,8 @@ RaptorEagleCCD::RaptorEagleCCD(std::shared_ptr<spdlog::logger> logger)
RaptorEagleCCD::~RaptorEagleCCD()
{
closePIXCI();
logDebug("DTOR: Delete RaptorEagleCCD class instance");
}
@ -300,7 +306,7 @@ void RaptorEagleCCD::flipFPGAStateBit(const size_t pos)
/* PRIVATE METHODS */
void RaptorEagleCCD::initCamera(int unitmap)
bool RaptorEagleCCD::initCamera(int unitmap)
{
logInfo("Try to init camera with unitmap: {} ...", unitmap);
@ -316,6 +322,18 @@ void RaptorEagleCCD::initCamera(int unitmap)
std::format("pxd_serialConfigure({}, 0, {}, {}, 0, {}, 0, 0, 0)", _cameraUnitmap, CL_DEFAULT_BAUD_RATE,
CL_DEFAULT_DATA_BITS, CL_DEFAULT_STOP_BIT));
bool ok = resetMicro();
if (!ok) {
logError("Cannot reset microcontroller!");
return ok;
}
ok = resetFPGA();
if (!ok) {
logError("Cannot reboot FPGA!");
return ok;
}
getSystemState();
getHardwareInfo();
@ -323,11 +341,15 @@ void RaptorEagleCCD::initCamera(int unitmap)
getFPGAVersion();
logInfo("Camera with unitmap '{}' is initialized", _cameraUnitmap);
return true;
}
void RaptorEagleCCD::openPIXCI()
{
logDebug("Initialize EPIX library and camera system device ...");
if (_epixFmtVideoFilename.size()) {
xclibApiCall(pxd_PIXCIopen("", nullptr, _epixFmtVideoFilename.c_str()),
std::format("pxd_PIXCIopen(\"\", NULL, {})", _epixFmtVideoFilename));
@ -343,6 +365,8 @@ void RaptorEagleCCD::openPIXCI()
void RaptorEagleCCD::closePIXCI()
{
logDebug("Close EPIX library and camera system device ...");
// no exception here!!!
xclibApiCall<true>(pxd_PIXCIclose(), "pxd_PIXCIclose()");
}
@ -549,8 +573,18 @@ bool RaptorEagleCCD::resetMicro(const std::chrono::milliseconds& timeout)
{
std::lock_guard lock_guard(_camlinkMutex);
std::chrono::milliseconds tm = timeout;
if (tm < MICRO_RESET_TIME_CONSTANT) { // must be greater than ~100ms
logWarn("Microcontroller reset timeout must be greater than {}", MICRO_RESET_TIME_CONSTANT);
logWarn("Use of default value {}", MICRO_RESET_DEFAULT_TIMEOUT);
tm = std::chrono::milliseconds(MICRO_RESET_DEFAULT_TIMEOUT);
}
byte_seq_t ack;
std::chrono::milliseconds sleep_dur = timeout.count() < 10 ? timeout : std::chrono::milliseconds(10);
std::chrono::milliseconds::rep cnt = (tm - MICRO_RESET_TIME_CONSTANT).count();
std::chrono::milliseconds sleep_dur =
cnt > 10 ? std::chrono::milliseconds(cnt / 10) : std::chrono::milliseconds(10);
uint8_t cksum_old = _clChecksumBit;
_clChecksumBit = 1; // to compute mandatory checksum in clWrite below!
@ -565,12 +599,58 @@ bool RaptorEagleCCD::resetMicro(const std::chrono::milliseconds& timeout)
// poll controller
auto start = std::chrono::steady_clock::now();
do {
clWrite({0x4F, 0x51});
// poll camera with 'set-system-status'
// clWrite({0x4F, 0x51});
clWrite({0x4F, 0x50});
std::this_thread::sleep_for(sleep_dur);
clRead(ack);
if (ack[0] == CL_ETX)
if (ack[0] == CL_ETX) {
logInfo("Camera microcontroller is reset successfully!");
return true;
}
} while ((std::chrono::steady_clock::now() - start) < timeout);
return false;
}
bool RaptorEagleCCD::resetFPGA(const std::chrono::milliseconds& timeout)
{
std::lock_guard lock_guard(_camlinkMutex);
std::chrono::milliseconds tm = timeout;
if (tm < FPGA_RESET_TIME_CONSTANT) { // must be greater than ~100ms
logWarn("FPGA reset timeout must be greater than {} millisecs", FPGA_RESET_TIME_CONSTANT.count());
logWarn("Use of default value {}", FPGA_RESET_DEFAULT_TIMEOUT);
tm = std::chrono::milliseconds(FPGA_RESET_DEFAULT_TIMEOUT);
}
byte_seq_t ack;
std::chrono::milliseconds::rep cnt = (tm - FPGA_RESET_TIME_CONSTANT).count();
std::chrono::milliseconds sleep_dur =
cnt > 10 ? std::chrono::milliseconds(cnt / 10) : std::chrono::milliseconds(10);
clearSystemStateBit(CL_SYSTEM_STATUS_FPGA_RST_HOLD_BIT); // set bit to 0 to hold FPGA in reset state
std::this_thread::sleep_for(std::chrono::milliseconds(100));
setSystemStateBit(CL_SYSTEM_STATUS_FPGA_RST_HOLD_BIT); // set bit to 1 to boot FPGA
// according to instruction manual rev 1.1 FPGA will take approximately 500msecs to reset
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// poll controller
auto start = std::chrono::steady_clock::now();
do {
clWrite({0x4F, 0x52});
std::this_thread::sleep_for(sleep_dur);
clRead(ack);
if (ack[0] == CL_ETX) {
logInfo("Camera FPGA is reset successfully!");
return true;
}
} while ((std::chrono::steady_clock::now() - start) < timeout);
@ -584,6 +664,9 @@ void RaptorEagleCCD::getHardwareInfo()
{
std::lock_guard lock_guard(_camlinkMutex);
logDebug("Try to get manufacturer EPROM data ...");
// first, according to instruction manual, set FPGA comms bit
setSystemStateBit(CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS_BIT);
@ -630,6 +713,8 @@ void RaptorEagleCCD::getHardwareInfo()
logDebug("Computed DAC-to-Temp linear relation: DAC(counts) = {}*Temp(C)+{}");
logDebug("---------------------------------");
clearSystemStateBit(CL_SYSTEM_STATUS_FPGA_EEPROM_COMMS_BIT);
}
@ -638,8 +723,12 @@ void RaptorEagleCCD::getMicroVersion()
{
std::lock_guard lock_guard(_camlinkMutex);
logDebug("Try to get microcontroller version ...");
clWrite({0x56});
clReadAndCheckAck(_microVersion);
logDebug("Microcontroller version: {}.{}", _microVersion[0], _microVersion[1]);
}
@ -647,7 +736,11 @@ void RaptorEagleCCD::getFPGAVersion()
{
std::lock_guard lock_guard(_camlinkMutex);
logDebug("Try to get FPGA version ...");
_FPGAVersion = readRegisters({0x7E, 0x7F});
logDebug("FPGA version: {}.{}", _FPGAVersion[0], _FPGAVersion[1]);
}
@ -656,6 +749,8 @@ void RaptorEagleCCD::getFPGAVersion()
void RaptorEagleCCD::initAttrComm()
{
logDebug("Try to create attributes and commands ...");
// helper to setup 8-bit register attributes
// 'validator' is a callable with signature: std::pair<uchar, std::string> validator(const uchar&)
auto create8BitAttr = [this](attr_ident_t name, auto reg_addr, auto&& validator, std::string_view log_mark) {
@ -737,15 +832,64 @@ void RaptorEagleCCD::initAttrComm()
addCommand(CAMERA_CMD_CLEAR_PERM_KEYW, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_CLEAR_PERM_KEYW);
auto N = _permanentFitsKeywords.size();
_permanentFitsKeywords.clear();
logInfo("Permanent FITS keywords are deleted! ({} keywords were cleared)", N);
});
addCommand(CAMERA_CMD_START_RESET_MICRO, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_START_RESET_MICRO);
if (resetMicro())
return;
throw std::error_code(RaptorEagleCCDError::ERROR_CANNOT_RESET_MICRO);
});
addCommand(CAMERA_CMD_START_RESET_FPGA, [this]() {
logDebug("Try to execute '{}' command", CAMERA_CMD_START_RESET_FPGA);
if (resetFPGA())
return;
throw std::error_code(RaptorEagleCCDError::ERROR_CANNOT_RESET_FPGA);
});
/* ------- ATTRIBUTES ------- */
/* PERMANENT AND CURRENT USER FITS KEYWORDS */
/* CURRENT FITS IMAGE FILENAME AND ITS HEADER TEMPLATE, PERMANENT AND CURRENT USER FITS KEYWORDS */
addAttribute(
CAMERA_ATTR_FITS_FILENAME,
[this]() {
logTrace("Return current FITS-image filename as {}", _currentFitsFile);
return _currentFitsFile;
},
[this](const std::string& filename) {
logDebug("Set current FITS-image filename to {}", filename);
if (filename.empty()) {
logWarn("An empty FITS filename! Acquisition process is disabled!");
}
_currentFitsFile = filename;
});
addAttribute(
CAMERA_ATTR_FITS_TEMPLATE,
[this]() {
logTrace("Return current FITS-image header template filename as {}", _currentTemplateFile);
return _currentTemplateFile;
},
[this](const std::string& filename) {
logDebug("Set current FITS-image header template filename to {}", filename);
_currentTemplateFile = filename;
});
// NOTE: setter and deserializer adds keywords to the end of current array!!!
addAttribute(
@ -1395,4 +1539,6 @@ void RaptorEagleCCD::initAttrComm()
logDebug("Trigger mode bits are set to 0b{:08b}", bits);
});
logDebug("Attributes and commands are successfully created!");
}

View File

@ -47,6 +47,19 @@ public:
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::chrono::milliseconds MICRO_RESET_TIME_CONSTANT{100};
// microcontroller reset timeout
// NOTE: the timeout must not be lesser then ~100msecs duration of reset process
// (see instruction manual rev 1.1)
static constexpr std::chrono::milliseconds MICRO_RESET_DEFAULT_TIMEOUT{MICRO_RESET_TIME_CONSTANT +
std::chrono::milliseconds(100)};
static constexpr std::chrono::milliseconds FPGA_RESET_TIME_CONSTANT{500};
// FPGA reset timeout
// NOTE: the timeout must not be lesser then ~500msecs duration of reset process
// (see instruction manual rev 1.1)
static constexpr std::chrono::milliseconds FPGA_RESET_DEFAULT_TIMEOUT{FPGA_RESET_TIME_CONSTANT +
std::chrono::milliseconds(1000)};
static constexpr std::string_view CAMERA_ATTR_XBIN{"XBIN"};
@ -55,23 +68,28 @@ public:
static constexpr std::string_view CAMERA_ATTR_ROI_STARTY{"ROI_STARTY"};
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_TRIGGER_MODE{"TRIGGER_MODE"};
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_TECSTATE{"TECSTATE"};
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"};
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_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_CAMLINK_SETUP{"CAMLINK_SETUP"};
static constexpr std::string_view CAMERA_ATTR_FITS_FILENAME{"FITS_FILENAME"};
static constexpr std::string_view CAMERA_ATTR_FITS_TEMPLATE{"FITS_TEMPLATE"};
static constexpr std::string_view CAMERA_ATTR_PERM_KEYW{"PERM_FITS_KEY"};
static constexpr std::string_view CAMERA_ATTR_CURR_KEYW{"CURR_FITS_KEY"};
@ -79,6 +97,8 @@ public:
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_CLEAR_PERM_KEYW{"CLEAR_PERM_FITS_KEYW"};
static constexpr std::string_view CAMERA_CMD_START_RESET_MICRO{"RESET_MICRO"};
static constexpr std::string_view CAMERA_CMD_START_RESET_FPGA{"RESET_FPGA"};
// some character attributes values
static constexpr std::string_view CAMERA_ATTR_STR_INVALID{"INVALID"};
@ -140,7 +160,7 @@ private:
// attributes inner variables
std::atomic_size_t _frameNumbers;
std::string _currentFitsFile; // current acquisition FITS filename
std::vector<std::string> _currentTemplateFile; // CFITSIO template filename
std::string _currentTemplateFile; // CFITSIO template filename
std::vector<std::string> _currentFitsKeywords; // current acquisition FITS keywords
std::vector<std::string> _permanentFitsKeywords; // permanent user FITS keywords
@ -163,7 +183,7 @@ private:
void initAttrComm();
void initCamera(int unitmap = 1);
bool initCamera(int unitmap = 1);
void openPIXCI();
void closePIXCI();
@ -207,8 +227,8 @@ private:
// reset hardware methods
// returns true if OK, false - timeout
bool resetMicro(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(5000));
bool resetMicro(const std::chrono::milliseconds& timeout = MICRO_RESET_DEFAULT_TIMEOUT);
bool resetFPGA(const std::chrono::milliseconds& timeout = FPGA_RESET_DEFAULT_TIMEOUT);
// hardware info methods

View File

@ -5,7 +5,15 @@
#include "raptor_eagle_cameralink.h"
enum class RaptorEagleCCDError : int { ERROR_OK, ERROR_INVALID_UNITMAP, ERROR_INVALID_ATTR_VALUE, ERROR_CAMLINK_WRITE };
enum class RaptorEagleCCDError : int {
ERROR_OK,
ERROR_INVALID_UNITMAP,
ERROR_INVALID_ATTR_VALUE,
ERROR_CAMLINK_WRITE,
ERROR_CANNOT_INIT_CAMERA,
ERROR_CANNOT_RESET_MICRO,
ERROR_CANNOT_RESET_FPGA
};
namespace std
@ -39,6 +47,12 @@ struct RaptorEagleCCDErrorCategory : std::error_category {
return "invalid camera attribute value";
case RaptorEagleCCDError::ERROR_CAMLINK_WRITE:
return "not all data were transmitted via CameraLink connection";
case RaptorEagleCCDError::ERROR_CANNOT_INIT_CAMERA:
return "cannot initialize camera hardware";
case RaptorEagleCCDError::ERROR_CANNOT_RESET_MICRO:
return "cannot reset camera microcontroller";
case RaptorEagleCCDError::ERROR_CANNOT_RESET_FPGA:
return "cannot reset FPGA board";
default:
return "UNKNOWN ERROR";
}