...
This commit is contained in:
parent
2cb6cc2926
commit
41b9c52129
@ -91,6 +91,16 @@ static constexpr double DAC_CALIBRATION_POINT_1 = 0.0; // at 0 Celcius degree
|
|||||||
static constexpr double DAC_CALIBRATION_POINT_2 = 40.0; // at +40 Celcius degree
|
static constexpr double DAC_CALIBRATION_POINT_2 = 40.0; // at +40 Celcius degree
|
||||||
|
|
||||||
|
|
||||||
|
/* REGISTER ADDRESSES */
|
||||||
|
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_EXPTIME_ADDR = {0xED, 0xEE, 0xEF, 0xF0, 0xF1};
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_FRAMERATE_ADDR = {0xDC, 0xDD, 0xDE, 0xDF, 0xE0};
|
||||||
|
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_ROILEFT_ADDR = {0xB6, 0xB7};
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_ROITOP_ADDR = {0xBA, 0xBB};
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_ROIWIDTH_ADDR = {0xB4, 0xB5};
|
||||||
|
static constexpr std::initializer_list<unsigned char> CL_ROIHEIGHT_ADDR = {0xB8, 0xB9};
|
||||||
|
|
||||||
/* COMMANDS */
|
/* COMMANDS */
|
||||||
|
|
||||||
static unsigned char CL_COMMAND_SET_ADDRESS[] = {
|
static unsigned char CL_COMMAND_SET_ADDRESS[] = {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "raptor_eagle_cameralink.h"
|
#include "raptor_eagle_cameralink.h"
|
||||||
@ -32,21 +33,33 @@ auto computeChecksum(const R& bytes, bool final_etx = true)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assume that least significant byte is the last one in 'bytes'
|
// assume that least significant byte is the last one in 'bytes'
|
||||||
|
// only the first 5 elements of the input range are taken
|
||||||
template <std::ranges::input_range R>
|
template <std::ranges::input_range R>
|
||||||
size_t convert40BitToCounts(const R& bytes)
|
size_t convert40BitToCounts(const R& bytes)
|
||||||
requires std::same_as<std::ranges::range_value_t<R>, unsigned char>
|
requires std::same_as<std::ranges::range_value_t<R>, unsigned char>
|
||||||
{
|
{
|
||||||
size_t counts = 0, i = std::ranges::size(bytes);
|
// size_t counts = 0, i = std::ranges::size(bytes);
|
||||||
|
|
||||||
for (auto& byte : bytes) {
|
// for (auto& byte : bytes| std::views::take(5)) {
|
||||||
counts += byte << (--i * 8);
|
// counts += byte << (--i * 8);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (std::ranges::size(bytes) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size_t counts = *bytes.begin();
|
||||||
|
for (auto& byte : bytes | std::views::drop(1) | std::views::take(4)) {
|
||||||
|
counts <<= 8;
|
||||||
|
counts |= byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <std::ranges::output_range<unsigned char> R>
|
// NOTE: it is assumed little-endian host's platform!!!
|
||||||
|
// return an range with least significant byte in the end of the range
|
||||||
|
template <std::ranges::output_range<unsigned char> R = std::vector<unsigned char>>
|
||||||
R convertCountsTo40Bit(uint64_t counts)
|
R convertCountsTo40Bit(uint64_t counts)
|
||||||
{
|
{
|
||||||
R res;
|
R res;
|
||||||
@ -59,6 +72,42 @@ R convertCountsTo40Bit(uint64_t counts)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// assume that least significant byte is the last one in 'bytes'
|
||||||
|
// only the first 2 elements of the input range are taken
|
||||||
|
template <std::ranges::input_range R>
|
||||||
|
uint16_t convert12BitToUInt(const R& bytes)
|
||||||
|
requires std::same_as<std::ranges::range_value_t<R>, unsigned char>
|
||||||
|
{
|
||||||
|
if (std::ranges::size(bytes) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto v = bytes | std::views::reverse | std::views::take(2);
|
||||||
|
|
||||||
|
if (std::ranges::size(bytes) > 1) {
|
||||||
|
return *v.begin() + ((*(++v.begin()) & 0x0F) << 8);
|
||||||
|
} else {
|
||||||
|
return *v.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: it is assumed little-endian host's platform!!!
|
||||||
|
// return an range with least significant byte in the end of the range
|
||||||
|
template <std::ranges::output_range<unsigned char> R = std::vector<unsigned char>>
|
||||||
|
R convertUIntTo12Bit(uint16_t counts)
|
||||||
|
{
|
||||||
|
R res;
|
||||||
|
|
||||||
|
auto sp = std::span(reinterpret_cast<unsigned char*>(&counts), 2);
|
||||||
|
|
||||||
|
// least significant byte in the end of the output range
|
||||||
|
std::ranges::copy(sp | std::views::reverse, std::back_inserter(res));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
|
|
||||||
@ -73,8 +122,7 @@ RaptorEagleCCD::RaptorEagleCCD(const adc::traits::adc_input_char_range auto& epi
|
|||||||
_epixFmtVideoFilename(),
|
_epixFmtVideoFilename(),
|
||||||
_cameraUnitmap(1), // by default only the single camera
|
_cameraUnitmap(1), // by default only the single camera
|
||||||
_clCommandAckBit(1), // enable by default (at camera boot up)
|
_clCommandAckBit(1), // enable by default (at camera boot up)
|
||||||
_clChecksumBit(1), // enable by default (at camera boot up)
|
_clChecksumBit(1) // enable by default (at camera boot up)
|
||||||
_expTime(0.0)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
addMarkToPattern("EAGLE-CCD");
|
addMarkToPattern("EAGLE-CCD");
|
||||||
@ -368,28 +416,74 @@ void RaptorEagleCCD::initAttrComm()
|
|||||||
addAttribute(
|
addAttribute(
|
||||||
CAMERA_ATTR_EXPTIME,
|
CAMERA_ATTR_EXPTIME,
|
||||||
[this]() {
|
[this]() {
|
||||||
logTrace("Return acquision duration (current value is {})", _expTime);
|
auto bytes = readRegisters(CL_EXPTIME_ADDR);
|
||||||
|
size_t counts = details::convert40BitToCounts(bytes);
|
||||||
|
double exp_time = counts * 2.5E-8; // counts of 25nsec ticks
|
||||||
|
|
||||||
return _expTime;
|
logTrace("Return acquision duration (current value is {} seconds ({} 25nsec ticks))", exp_time, counts);
|
||||||
|
|
||||||
|
return exp_time;
|
||||||
},
|
},
|
||||||
[this](const double& exp_time) {
|
[this](const double& exp_time) {
|
||||||
logDebug("Try to set acquisition duration to {} seconds ...", exp_time);
|
logDebug("Try to set acquisition duration to {} seconds ...", exp_time);
|
||||||
|
double etime;
|
||||||
|
|
||||||
if (_expTime < 0.0) {
|
if (exp_time < 0.0) {
|
||||||
logWarn("Acquisition duration must be non-negative!");
|
logWarn("Acquisition duration must be non-negative!");
|
||||||
|
|
||||||
_expTime = 0.0;
|
etime = 0.0;
|
||||||
} else if (_expTime > EAGLE_CAMERA_MAX_EXPTIME) {
|
} else if (exp_time > EAGLE_CAMERA_MAX_EXPTIME) {
|
||||||
logWarn("Acquisition duration must not be greater than {} seconds!", EAGLE_CAMERA_MAX_EXPTIME);
|
logWarn("Acquisition duration must not be greater than {} seconds!", EAGLE_CAMERA_MAX_EXPTIME);
|
||||||
|
|
||||||
_expTime = EAGLE_CAMERA_MAX_EXPTIME;
|
etime = EAGLE_CAMERA_MAX_EXPTIME;
|
||||||
} else {
|
} else {
|
||||||
_expTime = exp_time;
|
etime = exp_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
logDebug("Acquisition duration is set to {} second", _expTime);
|
size_t counts = static_cast<size_t>(std::round(etime / 2.5E-8));
|
||||||
|
auto bytes = details::convertCountsTo40Bit(counts);
|
||||||
|
writeRegisters(CL_EXPTIME_ADDR, bytes);
|
||||||
|
|
||||||
|
logDebug("Acquisition duration is set to {} second ({} 25nsec ticks)", etime, counts);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// frame rate
|
||||||
|
addAttribute(
|
||||||
|
CAMERA_ATTR_FRAME_RATE,
|
||||||
|
[this]() {
|
||||||
|
auto bytes = readRegisters(CL_FRAMERATE_ADDR);
|
||||||
|
size_t counts = details::convert40BitToCounts(bytes);
|
||||||
|
|
||||||
|
size_t rate = counts * 40; // in MHz
|
||||||
|
|
||||||
|
logTrace("Return frame rate (current value is {} MHz ({} 40MHz ticks))", rate, counts);
|
||||||
|
|
||||||
|
return rate;
|
||||||
|
},
|
||||||
|
[this](const size_t& rate) {
|
||||||
|
logDebug("Try to set frame rate to {} MHz ...", rate);
|
||||||
|
|
||||||
|
size_t r;
|
||||||
|
if (rate < 0) {
|
||||||
|
logWarn("Frame rate must be non-negative!");
|
||||||
|
r = 0;
|
||||||
|
} else if (rate > EAGLE_CAMERA_MAX_FRAMERATE) {
|
||||||
|
logWarn("Frame rate must not be greater than {} MHz!", EAGLE_CAMERA_MAX_FRAMERATE);
|
||||||
|
|
||||||
|
r = EAGLE_CAMERA_MAX_FRAMERATE;
|
||||||
|
} else {
|
||||||
|
r = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t counts = r / 40;
|
||||||
|
auto bytes = details::convertCountsTo40Bit(counts);
|
||||||
|
writeRegisters(CL_FRAMERATE_ADDR, bytes);
|
||||||
|
|
||||||
|
logDebug("Frame rate is set to {} MHz ({} 40MHz ticks)", r, counts);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// number of exposures
|
// number of exposures
|
||||||
addAttribute(
|
addAttribute(
|
||||||
CAMERA_ATTR_NEXP,
|
CAMERA_ATTR_NEXP,
|
||||||
@ -403,4 +497,32 @@ void RaptorEagleCCD::initAttrComm()
|
|||||||
|
|
||||||
logDebug("Number of frames in acquisition sequence is set to {}", _frameNumbers);
|
logDebug("Number of frames in acquisition sequence is set to {}", _frameNumbers);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
auto create12BitAttr = [this](std::string_view name, auto reg_addrs, 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](const uint16_t& val) { logDebug("Try to set {} ...", log_mark); });
|
||||||
|
};
|
||||||
|
|
||||||
|
// ROI left
|
||||||
|
addAttribute(
|
||||||
|
CAMERA_ATTR_ROI_LEFT,
|
||||||
|
[this]() {
|
||||||
|
auto bytes = readRegisters(CL_ROILEFT_ADDR);
|
||||||
|
uint16_t v = details::convert12BitToUInt(bytes);
|
||||||
|
|
||||||
|
logTrace("Return ROI X-offset (current value: {})", v);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
},
|
||||||
|
[this](const uint16_t& val) {});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,11 @@ class RaptorEagleCCD : public adc::AdcGenericDevice<std::string, adc::AdcDeviceA
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/* some Eagle V camera constants */
|
/* some Eagle V camera constants */
|
||||||
static constexpr double EAGLE_CAMERA_MAX_EXPTIME = 27487.7906944; // in seconds (0xFFFFFFFFFF * 25nsec)
|
// static constexpr double EAGLE_CAMERA_MAX_EXPTIME = 27487.7906944; // in seconds (0xFFFFFFFFFF * 25nsec)
|
||||||
|
static constexpr double EAGLE_CAMERA_MAX_EXPTIME = 2.5E-8 * 0xFFFFFFFFFF; // in seconds (0xFFFFFFFFFF * 25nsec)
|
||||||
|
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 std::string_view CAMERA_ATTR_HBIN{"HBIN"};
|
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_VBIN{"VBIN"};
|
||||||
@ -79,7 +83,6 @@ private:
|
|||||||
std::mutex _camlinkMutex;
|
std::mutex _camlinkMutex;
|
||||||
|
|
||||||
// attributes inner variables
|
// attributes inner variables
|
||||||
double _expTime;
|
|
||||||
size_t _frameNumbers;
|
size_t _frameNumbers;
|
||||||
|
|
||||||
void initAttrComm();
|
void initAttrComm();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user