Commit 31fdd944 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

* Added Frelon Readout & Charge-Transfer times by means of float registers

* Frelon::SyncCtrlObj latency time now includes the detector dead time
parent e05bde7d
...@@ -57,6 +57,7 @@ extern RegStrMapType RegStrMap; ...@@ -57,6 +57,7 @@ extern RegStrMapType RegStrMap;
typedef std::vector<Reg> RegListType; typedef std::vector<Reg> RegListType;
extern RegListType CacheableRegList; extern RegListType CacheableRegList;
extern RegListType FloatRegList;
typedef std::map<Reg, double> RegDoubleMapType; typedef std::map<Reg, double> RegDoubleMapType;
extern RegDoubleMapType RegSleepMap; extern RegDoubleMapType RegSleepMap;
......
...@@ -45,6 +45,7 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -45,6 +45,7 @@ class Camera : public HwMaxImageSizeCallbackGen
void writeRegister(Reg reg, int val); void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val); void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
void hardReset(); void hardReset();
void getVersionStr(std::string& ver); void getVersionStr(std::string& ver);
...@@ -98,8 +99,13 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -98,8 +99,13 @@ class Camera : public HwMaxImageSizeCallbackGen
void setShutCloseTime(double shut_time); void setShutCloseTime(double shut_time);
void getShutCloseTime(double& shut_time); void getShutCloseTime(double& shut_time);
void setLatTime(double lat_time); void setUserLatTime(double lat_time);
void getLatTime(double& lat_time); void getUserLatTime(double& lat_time);
void getReadoutTime(double& readout_time);
void getTransferTime(double& xfer_time);
void getDeadTime(double& dead_time);
void setTotalLatTime(double lat_time);
void getTotalLatTime(double& lat_time);
void setNbFrames(int nb_frames); void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames); void getNbFrames(int& nb_frames);
......
...@@ -37,7 +37,7 @@ class SerialLine : public HwSerialLine ...@@ -37,7 +37,7 @@ class SerialLine : public HwSerialLine
public: public:
enum MsgPart { enum MsgPart {
MsgSync, MsgCmd, MsgVal, MsgReq, MsgTerm, MsgSync, MsgCmd, MsgVal, MsgDec, MsgReq, MsgTerm,
}; };
enum AnsPart { enum AnsPart {
...@@ -90,6 +90,7 @@ class SerialLine : public HwSerialLine ...@@ -90,6 +90,7 @@ class SerialLine : public HwSerialLine
void writeRegister(Reg reg, int val); void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val); void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
int getLastWarning(); int getLastWarning();
...@@ -129,12 +130,21 @@ class SerialLine : public HwSerialLine ...@@ -129,12 +130,21 @@ class SerialLine : public HwSerialLine
void readRespCleanup(); void readRespCleanup();
bool isFloatReg(Reg reg);
template <class T>
void checkRegType(Reg reg);
bool isRegCacheable(Reg reg); bool isRegCacheable(Reg reg);
bool getRegCacheVal(Reg reg, int& val); template <class T>
bool getRegCacheValSafe(Reg reg, int& val); bool getRegCacheVal(Reg reg, T& val);
template <class T>
bool getRegCacheValSafe(Reg reg, T& val);
double getRegSleepTime(Reg reg); double getRegSleepTime(Reg reg);
template <class T>
void readCameraRegister(Reg reg, T& val);
Espia::SerialLine& m_espia_ser_line; Espia::SerialLine& m_espia_ser_line;
Cond m_cond; Cond m_cond;
int m_last_warn; int m_last_warn;
...@@ -148,6 +158,16 @@ class SerialLine : public HwSerialLine ...@@ -148,6 +158,16 @@ class SerialLine : public HwSerialLine
std::string m_curr_fmt_resp; std::string m_curr_fmt_resp;
}; };
inline void SerialLine::readRegister(Reg reg, int& val)
{
readCameraRegister(reg, val);
}
inline void SerialLine::readFloatRegister(Reg reg, double& val)
{
readCameraRegister(reg, val);
}
std::ostream& operator <<(std::ostream& os, SerialLine::RegOp op); std::ostream& operator <<(std::ostream& os, SerialLine::RegOp op);
......
...@@ -67,13 +67,18 @@ public: ...@@ -67,13 +67,18 @@ public:
/* /*
typedef std::vector<Reg> RegListType; typedef std::vector<Reg> RegListType;
extern RegListType NonCacheableRegList; extern RegListType CacheableRegList;
extern RegListType FloatRegList;
typedef std::map<Reg, double> RegDoubleMapType;
extern RegDoubleMapType RegSleepMap;
*/ */
const int MaxRegVal; const int MaxRegVal;
enum Cmd { enum Cmd {
Reset, Start, Stop, Save, Reload, Reset, Start, Stop, Save, Reload,
SendEOF,
}; };
/* /*
typedef std::map<Cmd, std::string> CmdStrMapType; typedef std::map<Cmd, std::string> CmdStrMapType;
......
...@@ -39,6 +39,7 @@ class Camera ...@@ -39,6 +39,7 @@ class Camera
void writeRegister(Frelon::Reg reg, int val); void writeRegister(Frelon::Reg reg, int val);
void readRegister (Frelon::Reg reg, int& val /Out/); void readRegister (Frelon::Reg reg, int& val /Out/);
void readFloatRegister(Frelon::Reg reg, double& val /Out/);
void hardReset(); void hardReset();
void getVersionStr(std::string& ver /Out/); void getVersionStr(std::string& ver /Out/);
...@@ -93,8 +94,13 @@ class Camera ...@@ -93,8 +94,13 @@ class Camera
void setShutCloseTime(double shut_time); void setShutCloseTime(double shut_time);
void getShutCloseTime(double& shut_time /Out/); void getShutCloseTime(double& shut_time /Out/);
void setLatTime(double lat_time); void setUserLatTime(double lat_time);
void getLatTime(double& lat_time /Out/); void getUserLatTime(double& lat_time /Out/);
void getReadoutTime(double& readout_time /Out/);
void getTransferTime(double& xfer_time /Out/);
void getDeadTime(double& dead_time /Out/);
void setTotalLatTime(double lat_time);
void getTotalLatTime(double& lat_time /Out/);
void setNbFrames(int nb_frames); void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames /Out/); void getNbFrames(int& nb_frames /Out/);
......
...@@ -32,7 +32,7 @@ class SerialLine : HwSerialLine ...@@ -32,7 +32,7 @@ class SerialLine : HwSerialLine
public: public:
enum MsgPart { enum MsgPart {
MsgSync, MsgCmd, MsgVal, MsgReq, MsgTerm, MsgSync, MsgCmd, MsgVal, MsgDec, MsgReq, MsgTerm,
}; };
enum AnsPart { enum AnsPart {
...@@ -93,6 +93,7 @@ class SerialLine : HwSerialLine ...@@ -93,6 +93,7 @@ class SerialLine : HwSerialLine
void writeRegister(Frelon::Reg reg, int val); void writeRegister(Frelon::Reg reg, int val);
void readRegister (Frelon::Reg reg, int& val /Out/); void readRegister (Frelon::Reg reg, int& val /Out/);
void readFloatRegister(Frelon::Reg reg, double& val /Out/);
int getLastWarning(); int getLastWarning();
......
...@@ -109,6 +109,11 @@ static Reg CacheableRegCList[] = { ...@@ -109,6 +109,11 @@ static Reg CacheableRegCList[] = {
RegListType RegListType
lima::Frelon::CacheableRegList(C_LIST_ITERS(CacheableRegCList)); lima::Frelon::CacheableRegList(C_LIST_ITERS(CacheableRegCList));
static Reg FloatRegCList[] = {
ReadoutTime,
};
RegListType lima::Frelon::FloatRegList(C_LIST_ITERS(FloatRegCList));
typedef pair<Reg, double> RegSleepPair; typedef pair<Reg, double> RegSleepPair;
static const RegSleepPair RegSleepCList[] = { static const RegSleepPair RegSleepCList[] = {
RegSleepPair(ConfigHD, 2.0), RegSleepPair(ConfigHD, 2.0),
......
...@@ -273,6 +273,12 @@ void Camera::readRegister(Reg reg, int& val) ...@@ -273,6 +273,12 @@ void Camera::readRegister(Reg reg, int& val)
m_ser_line.readRegister(reg, val); m_ser_line.readRegister(reg, val);
} }
void Camera::readFloatRegister(Reg reg, double& val)
{
DEB_MEMBER_FUNCT();
m_ser_line.readFloatRegister(reg, val);
}
void Camera::hardReset() void Camera::hardReset()
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
...@@ -1269,7 +1275,7 @@ void Camera::getShutCloseTime(double& shut_time) ...@@ -1269,7 +1275,7 @@ void Camera::getShutCloseTime(double& shut_time)
DEB_RETURN() << DEB_VAR1(shut_time); DEB_RETURN() << DEB_VAR1(shut_time);
} }
void Camera::setLatTime(double lat_time) void Camera::setUserLatTime(double lat_time)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(lat_time); DEB_PARAM() << DEB_VAR1(lat_time);
...@@ -1279,7 +1285,7 @@ void Camera::setLatTime(double lat_time) ...@@ -1279,7 +1285,7 @@ void Camera::setLatTime(double lat_time)
writeRegister(LatencyTime, lat_val); writeRegister(LatencyTime, lat_val);
} }
void Camera::getLatTime(double& lat_time) void Camera::getUserLatTime(double& lat_time)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
TimeUnitFactor time_unit_factor; TimeUnitFactor time_unit_factor;
...@@ -1290,6 +1296,65 @@ void Camera::getLatTime(double& lat_time) ...@@ -1290,6 +1296,65 @@ void Camera::getLatTime(double& lat_time)
DEB_RETURN() << DEB_VAR1(lat_time); DEB_RETURN() << DEB_VAR1(lat_time);
} }
void Camera::getReadoutTime(double& readout_time)
{
DEB_MEMBER_FUNCT();
if (!m_model.hasTimeCalc())
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "readout time calculation";
readFloatRegister(ReadoutTime, readout_time);
readout_time *= 1e-6;
DEB_RETURN() << DEB_VAR1(readout_time);
}
void Camera::getTransferTime(double& xfer_time)
{
DEB_MEMBER_FUNCT();
if (!m_model.hasTimeCalc())
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "shift time calculation";
readFloatRegister(TransferTime, xfer_time);
xfer_time *= 1e-6;
DEB_RETURN() << DEB_VAR1(xfer_time);
}
void Camera::getDeadTime(double& dead_time)
{
DEB_MEMBER_FUNCT();
getTransferTime(dead_time);
if (dead_time == 0)
getReadoutTime(dead_time);
DEB_RETURN() << DEB_VAR1(dead_time);
}
void Camera::setTotalLatTime(double lat_time)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(lat_time);
double dead_time;
getDeadTime(dead_time);
double user_lat_time = lat_time - dead_time;
if (user_lat_time < -1e-6)
THROW_HW_ERROR(InvalidValue) << "Total latency time cannot be "
<< "smaller than dead time";
else if (user_lat_time < 0)
user_lat_time = 0;
setUserLatTime(user_lat_time);
}
void Camera::getTotalLatTime(double& lat_time)
{
DEB_MEMBER_FUNCT();
double user_lat_time;
getUserLatTime(user_lat_time);
double dead_time;
getDeadTime(dead_time);
lat_time = dead_time + user_lat_time;
DEB_RETURN() << DEB_VAR1(lat_time);
}
void Camera::setNbFrames(int nb_frames) void Camera::setNbFrames(int nb_frames)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
......
...@@ -330,13 +330,13 @@ void SyncCtrlObj::getExpTime(double& exp_time) ...@@ -330,13 +330,13 @@ void SyncCtrlObj::getExpTime(double& exp_time)
void SyncCtrlObj::setLatTime(double lat_time) void SyncCtrlObj::setLatTime(double lat_time)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
m_cam.setLatTime(lat_time); m_cam.setTotalLatTime(lat_time);
} }
void SyncCtrlObj::getLatTime(double& lat_time) void SyncCtrlObj::getLatTime(double& lat_time)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
m_cam.getLatTime(lat_time); m_cam.getTotalLatTime(lat_time);
} }
void SyncCtrlObj::setNbHwFrames(int nb_frames) void SyncCtrlObj::setNbHwFrames(int nb_frames)
...@@ -372,8 +372,10 @@ void SyncCtrlObj::getValidRanges(ValidRangesType& valid_ranges) ...@@ -372,8 +372,10 @@ void SyncCtrlObj::getValidRanges(ValidRangesType& valid_ranges)
valid_ranges.min_exp_time = 1 * MinTimeUnit; valid_ranges.min_exp_time = 1 * MinTimeUnit;
valid_ranges.max_exp_time = MaxRegVal * MaxTimeUnit; valid_ranges.max_exp_time = MaxRegVal * MaxTimeUnit;
valid_ranges.min_lat_time = 0 * LatTimeUnit; double dead_time;
valid_ranges.max_lat_time = MaxRegVal * LatTimeUnit; m_cam.getDeadTime(dead_time);
valid_ranges.min_lat_time = dead_time;
valid_ranges.max_lat_time = dead_time + MaxRegVal * LatTimeUnit;
DEB_RETURN() << DEB_VAR2(valid_ranges.min_exp_time, DEB_RETURN() << DEB_VAR2(valid_ranges.min_exp_time,
valid_ranges.max_exp_time); valid_ranges.max_exp_time);
...@@ -864,8 +866,8 @@ void Interface::resetDefaults() ...@@ -864,8 +866,8 @@ void Interface::resetDefaults()
m_sync.setNbFrames(1); m_sync.setNbFrames(1);
m_sync.setExpTime(1.0); m_sync.setExpTime(1.0);
m_sync.setLatTime(0.0);
m_sync.setTrigMode(IntTrig); m_sync.setTrigMode(IntTrig);
m_cam.setUserLatTime(0.0);
m_shutter.setMode(ShutterAutoFrame); m_shutter.setMode(ShutterAutoFrame);
m_shutter.setCloseTime(0.0); m_shutter.setCloseTime(0.0);
......
...@@ -116,11 +116,18 @@ void SerialLine::writeCmd(const string& buffer, bool no_wait) ...@@ -116,11 +116,18 @@ void SerialLine::writeCmd(const string& buffer, bool no_wait)
m_curr_op = is_req ? ReadReg : WriteReg; m_curr_op = is_req ? ReadReg : WriteReg;
if (!is_req) if (!is_req)
m_curr_resp = msg_parts[MsgVal]; m_curr_resp = msg_parts[MsgVal];
int cache_val; int cache_int;
m_curr_cache = getRegCacheVal(m_curr_reg, cache_val); double cache_float;
if (isFloatReg(m_curr_reg))
m_curr_cache = getRegCacheVal(m_curr_reg, cache_float);
else
m_curr_cache = getRegCacheVal(m_curr_reg, cache_int);
if (m_curr_cache) { if (m_curr_cache) {
ostringstream os; ostringstream os;
os << cache_val; if (isFloatReg(m_curr_reg))
os << cache_float;
else
os << cache_int;
const string& cache_str = os.str(); const string& cache_str = os.str();
if (is_req) if (is_req)
m_curr_resp = cache_str; m_curr_resp = cache_str;
...@@ -277,9 +284,37 @@ bool SerialLine::isRegCacheable(Reg reg) ...@@ -277,9 +284,37 @@ bool SerialLine::isRegCacheable(Reg reg)
return cacheable; return cacheable;
} }
bool SerialLine::getRegCacheVal(Reg reg, int& val)
bool SerialLine::isFloatReg(Reg reg)
{
const RegListType& list = FloatRegList;
return (find(list.begin(), list.end(), reg) != list.end());
}
namespace lima
{
namespace Frelon
{
template <>
void SerialLine::checkRegType<int>(Reg reg)
{
DEB_MEMBER_FUNCT();
if (isFloatReg(reg))
THROW_HW_ERROR(InvalidValue) << "Invalid int-call for a "
"float-register";
}
template <>
void SerialLine::checkRegType<double>(Reg reg)
{
}
template <class T>
bool SerialLine::getRegCacheVal(Reg reg, T& val)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
checkRegType<T>(reg);
RegValMapType::const_iterator it = m_reg_cache.find(reg); RegValMapType::const_iterator it = m_reg_cache.find(reg);
bool in_cache = (it != m_reg_cache.end()); bool in_cache = (it != m_reg_cache.end());
val = in_cache ? it->second : 0; val = in_cache ? it->second : 0;
...@@ -287,12 +322,44 @@ bool SerialLine::getRegCacheVal(Reg reg, int& val) ...@@ -287,12 +322,44 @@ bool SerialLine::getRegCacheVal(Reg reg, int& val)
return in_cache; return in_cache;
} }
bool SerialLine::getRegCacheValSafe(Reg reg, int& val) template <class T>
bool SerialLine::getRegCacheValSafe(Reg reg, T& val)
{ {
AutoMutex l = lock(AutoMutex::Locked); AutoMutex l = lock(AutoMutex::Locked);
return (isRegCacheable(reg) && getRegCacheVal(reg, val)); return (isRegCacheable(reg) && getRegCacheVal(reg, val));
} }
template <class T>
void SerialLine::readCameraRegister(Reg reg, T& val)
{
DEB_MEMBER_FUNCT();
const string& reg_str = RegStrMap[reg];
DEB_PARAM() << DEB_VAR2(reg, reg_str);
bool in_cache = getRegCacheValSafe(reg, val);
if (in_cache) {
DEB_TRACE() << "Using cache value";
DEB_RETURN() << DEB_VAR1(val);
return;
}
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(reg);
string resp;
sendFmtCmd(reg_str + "?", resp);
istringstream is(resp);
is >> val;
DEB_RETURN() << DEB_VAR1(val);
}
template void SerialLine::readCameraRegister<int>(Reg reg, int& val);
template void SerialLine::readCameraRegister<double>(Reg reg, double& val);
} // namespace Frelon
} // namespace lima
double SerialLine::getRegSleepTime(Reg reg) double SerialLine::getRegSleepTime(Reg reg)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
...@@ -341,7 +408,8 @@ void SerialLine::splitMsg(const string& msg, ...@@ -341,7 +408,8 @@ void SerialLine::splitMsg(const string& msg,
const static RegEx re("^(?P<sync>>)?" const static RegEx re("^(?P<sync>>)?"
"(?P<cmd>[A-Za-z]+)" "(?P<cmd>[A-Za-z]+)"
"((?P<req>\\?)|(?P<val>[0-9]+))?" "((?P<req>\\?)|"
"(?P<val>[0-9]+(\\.(?P<dec>[0-9]+))?))?"
"(?P<term>[\r\n]+)?$"); "(?P<term>[\r\n]+)?$");
RegEx::FullNameMatchType match; RegEx::FullNameMatchType match;
...@@ -352,8 +420,8 @@ void SerialLine::splitMsg(const string& msg, ...@@ -352,8 +420,8 @@ void SerialLine::splitMsg(const string& msg,
typedef pair<MsgPart, string> KeyPair; typedef pair<MsgPart, string> KeyPair;
static const KeyPair key_list[] = { static const KeyPair key_list[] = {
KeyPair(MsgSync, "sync"), KeyPair(MsgCmd, "cmd"), KeyPair(MsgSync, "sync"), KeyPair(MsgCmd, "cmd"),
KeyPair(MsgVal, "val"), KeyPair(MsgReq, "req"), KeyPair(MsgVal, "val"), KeyPair(MsgDec, "dec"),
KeyPair(MsgTerm, "term"), KeyPair(MsgReq, "req"), KeyPair(MsgTerm, "term"),
}; };
const KeyPair *it, *end = C_LIST_END(key_list); const KeyPair *it, *end = C_LIST_END(key_list);
for (it = key_list; it != end; ++it) { for (it = key_list; it != end; ++it) {
...@@ -363,7 +431,8 @@ void SerialLine::splitMsg(const string& msg, ...@@ -363,7 +431,8 @@ void SerialLine::splitMsg(const string& msg,
} }
DEB_RETURN() << DEB_VAR2(msg_parts[MsgSync], msg_parts[MsgCmd]); DEB_RETURN() << DEB_VAR2(msg_parts[MsgSync], msg_parts[MsgCmd]);
DEB_RETURN() << DEB_VAR2(msg_parts[MsgReq], msg_parts[MsgVal]); DEB_RETURN() << DEB_VAR3(msg_parts[MsgReq], msg_parts[MsgVal],
msg_parts[MsgDec]);
} }
void SerialLine::decodeFmtResp(const string& ans, string& fmt_resp) void SerialLine::decodeFmtResp(const string& ans, string& fmt_resp)
...@@ -474,30 +543,6 @@ void SerialLine::writeRegister(Reg reg, int val) ...@@ -474,30 +543,6 @@ void SerialLine::writeRegister(Reg reg, int val)
sendFmtCmd(cmd.str(), resp); sendFmtCmd(cmd.str(), resp);
} }
void SerialLine::readRegister(Reg reg, int& val)
{
DEB_MEMBER_FUNCT();
const string& reg_str = RegStrMap[reg];
DEB_PARAM() << DEB_VAR2(reg, reg_str);
bool in_cache = getRegCacheValSafe(reg, val);
if (in_cache) {
DEB_TRACE() << "Using cache value";
DEB_RETURN() << DEB_VAR1(val);
return;
}
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(reg);
string resp;
sendFmtCmd(reg_str + "?", resp);
istringstream is(resp);
is >> val;
DEB_RETURN() << DEB_VAR1(val);
}
ostream& lima::Frelon::operator <<(ostream& os, SerialLine::RegOp op) ostream& lima::Frelon::operator <<(ostream& os, SerialLine::RegOp op)
{ {
const char *name = "Unknown"; const char *name = "Unknown";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment