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

* 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;
typedef std::vector<Reg> RegListType;
extern RegListType CacheableRegList;
extern RegListType FloatRegList;
typedef std::map<Reg, double> RegDoubleMapType;
extern RegDoubleMapType RegSleepMap;
......
......@@ -45,6 +45,7 @@ class Camera : public HwMaxImageSizeCallbackGen
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
void hardReset();
void getVersionStr(std::string& ver);
......@@ -98,8 +99,13 @@ class Camera : public HwMaxImageSizeCallbackGen
void setShutCloseTime(double shut_time);
void getShutCloseTime(double& shut_time);
void setLatTime(double lat_time);
void getLatTime(double& lat_time);
void setUserLatTime(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 getNbFrames(int& nb_frames);
......
......@@ -37,7 +37,7 @@ class SerialLine : public HwSerialLine
public:
enum MsgPart {
MsgSync, MsgCmd, MsgVal, MsgReq, MsgTerm,
MsgSync, MsgCmd, MsgVal, MsgDec, MsgReq, MsgTerm,
};
enum AnsPart {
......@@ -90,6 +90,7 @@ class SerialLine : public HwSerialLine
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
int getLastWarning();
......@@ -129,12 +130,21 @@ class SerialLine : public HwSerialLine
void readRespCleanup();
bool isFloatReg(Reg reg);
template <class T>
void checkRegType(Reg reg);
bool isRegCacheable(Reg reg);
bool getRegCacheVal(Reg reg, int& val);
bool getRegCacheValSafe(Reg reg, int& val);
template <class T>
bool getRegCacheVal(Reg reg, T& val);
template <class T>
bool getRegCacheValSafe(Reg reg, T& val);
double getRegSleepTime(Reg reg);
template <class T>
void readCameraRegister(Reg reg, T& val);
Espia::SerialLine& m_espia_ser_line;
Cond m_cond;
int m_last_warn;
......@@ -148,6 +158,16 @@ class SerialLine : public HwSerialLine
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);
......
......@@ -67,13 +67,18 @@ public:
/*
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;
enum Cmd {
Reset, Start, Stop, Save, Reload,
SendEOF,
};
/*
typedef std::map<Cmd, std::string> CmdStrMapType;
......
......@@ -39,6 +39,7 @@ class Camera
void writeRegister(Frelon::Reg reg, int val);
void readRegister (Frelon::Reg reg, int& val /Out/);
void readFloatRegister(Frelon::Reg reg, double& val /Out/);
void hardReset();
void getVersionStr(std::string& ver /Out/);
......@@ -93,8 +94,13 @@ class Camera
void setShutCloseTime(double shut_time);
void getShutCloseTime(double& shut_time /Out/);
void setLatTime(double lat_time);
void getLatTime(double& lat_time /Out/);
void setUserLatTime(double lat_time);
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 getNbFrames(int& nb_frames /Out/);
......
......@@ -32,7 +32,7 @@ class SerialLine : HwSerialLine
public:
enum MsgPart {
MsgSync, MsgCmd, MsgVal, MsgReq, MsgTerm,
MsgSync, MsgCmd, MsgVal, MsgDec, MsgReq, MsgTerm,
};
enum AnsPart {
......@@ -93,6 +93,7 @@ class SerialLine : HwSerialLine
void writeRegister(Frelon::Reg reg, int val);
void readRegister (Frelon::Reg reg, int& val /Out/);
void readFloatRegister(Frelon::Reg reg, double& val /Out/);
int getLastWarning();
......
......@@ -109,6 +109,11 @@ static Reg CacheableRegCList[] = {
RegListType
lima::Frelon::CacheableRegList(C_LIST_ITERS(CacheableRegCList));
static Reg FloatRegCList[] = {
ReadoutTime,
};
RegListType lima::Frelon::FloatRegList(C_LIST_ITERS(FloatRegCList));
typedef pair<Reg, double> RegSleepPair;
static const RegSleepPair RegSleepCList[] = {
RegSleepPair(ConfigHD, 2.0),
......
......@@ -273,6 +273,12 @@ void Camera::readRegister(Reg reg, int& 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()
{
DEB_MEMBER_FUNCT();
......@@ -1269,7 +1275,7 @@ void Camera::getShutCloseTime(double& shut_time)
DEB_RETURN() << DEB_VAR1(shut_time);
}
void Camera::setLatTime(double lat_time)
void Camera::setUserLatTime(double lat_time)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(lat_time);
......@@ -1279,7 +1285,7 @@ void Camera::setLatTime(double lat_time)
writeRegister(LatencyTime, lat_val);
}
void Camera::getLatTime(double& lat_time)
void Camera::getUserLatTime(double& lat_time)
{
DEB_MEMBER_FUNCT();
TimeUnitFactor time_unit_factor;
......@@ -1290,6 +1296,65 @@ void Camera::getLatTime(double& 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)
{
DEB_MEMBER_FUNCT();
......
......@@ -330,13 +330,13 @@ void SyncCtrlObj::getExpTime(double& exp_time)
void SyncCtrlObj::setLatTime(double lat_time)
{
DEB_MEMBER_FUNCT();
m_cam.setLatTime(lat_time);
m_cam.setTotalLatTime(lat_time);
}
void SyncCtrlObj::getLatTime(double& lat_time)
{
DEB_MEMBER_FUNCT();
m_cam.getLatTime(lat_time);
m_cam.getTotalLatTime(lat_time);
}
void SyncCtrlObj::setNbHwFrames(int nb_frames)
......@@ -372,8 +372,10 @@ void SyncCtrlObj::getValidRanges(ValidRangesType& valid_ranges)
valid_ranges.min_exp_time = 1 * MinTimeUnit;
valid_ranges.max_exp_time = MaxRegVal * MaxTimeUnit;
valid_ranges.min_lat_time = 0 * LatTimeUnit;
valid_ranges.max_lat_time = MaxRegVal * LatTimeUnit;
double dead_time;
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,
valid_ranges.max_exp_time);
......@@ -864,8 +866,8 @@ void Interface::resetDefaults()
m_sync.setNbFrames(1);
m_sync.setExpTime(1.0);
m_sync.setLatTime(0.0);
m_sync.setTrigMode(IntTrig);
m_cam.setUserLatTime(0.0);
m_shutter.setMode(ShutterAutoFrame);
m_shutter.setCloseTime(0.0);
......
......@@ -116,11 +116,18 @@ void SerialLine::writeCmd(const string& buffer, bool no_wait)
m_curr_op = is_req ? ReadReg : WriteReg;
if (!is_req)
m_curr_resp = msg_parts[MsgVal];
int cache_val;
m_curr_cache = getRegCacheVal(m_curr_reg, cache_val);
int cache_int;
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) {
ostringstream os;
os << cache_val;
if (isFloatReg(m_curr_reg))
os << cache_float;
else
os << cache_int;
const string& cache_str = os.str();
if (is_req)
m_curr_resp = cache_str;
......@@ -277,9 +284,37 @@ bool SerialLine::isRegCacheable(Reg reg)
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();
checkRegType<T>(reg);
RegValMapType::const_iterator it = m_reg_cache.find(reg);
bool in_cache = (it != m_reg_cache.end());
val = in_cache ? it->second : 0;
......@@ -287,12 +322,44 @@ bool SerialLine::getRegCacheVal(Reg reg, int& val)
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);
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)
{
DEB_MEMBER_FUNCT();
......@@ -341,7 +408,8 @@ void SerialLine::splitMsg(const string& msg,
const static RegEx re("^(?P<sync>>)?"
"(?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]+)?$");
RegEx::FullNameMatchType match;
......@@ -352,8 +420,8 @@ void SerialLine::splitMsg(const string& msg,
typedef pair<MsgPart, string> KeyPair;
static const KeyPair key_list[] = {
KeyPair(MsgSync, "sync"), KeyPair(MsgCmd, "cmd"),
KeyPair(MsgVal, "val"), KeyPair(MsgReq, "req"),
KeyPair(MsgTerm, "term"),
KeyPair(MsgVal, "val"), KeyPair(MsgDec, "dec"),
KeyPair(MsgReq, "req"), KeyPair(MsgTerm, "term"),
};
const KeyPair *it, *end = C_LIST_END(key_list);
for (it = key_list; it != end; ++it) {
......@@ -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[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)
......@@ -474,30 +543,6 @@ void SerialLine::writeRegister(Reg reg, int val)
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)
{
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