...
 
Commits (3)
...@@ -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;
......
...@@ -38,6 +38,21 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -38,6 +38,21 @@ class Camera : public HwMaxImageSizeCallbackGen
DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Frelon"); DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Frelon");
public: public:
class DeadTimeChangedCallback {
DEB_CLASS_NAMESPC(DebModCamera, "DeadTimeChangedCallback",
"Frelon::Camera");
public:
DeadTimeChangedCallback();
virtual ~DeadTimeChangedCallback();
protected:
virtual void deadTimeChanged(double dead_time) = 0;
private:
friend class Camera;
Camera *m_cam;
};
Camera(Espia::SerialLine& espia_ser_line); Camera(Espia::SerialLine& espia_ser_line);
~Camera(); ~Camera();
...@@ -45,6 +60,7 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -45,6 +60,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 +114,13 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -98,8 +114,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);
...@@ -123,6 +144,9 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -123,6 +144,9 @@ class Camera : public HwMaxImageSizeCallbackGen
void stop(); void stop();
bool isRunning(); bool isRunning();
void registerDeadTimeChangedCallback(DeadTimeChangedCallback& cb);
void unregisterDeadTimeChangedCallback(DeadTimeChangedCallback& cb);
protected: protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active); virtual void setMaxImageSizeCallbackActive(bool cb_active);
...@@ -187,6 +211,8 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -187,6 +211,8 @@ class Camera : public HwMaxImageSizeCallbackGen
bool waitIdleStatus(Status& status, bool use_ser_line=false, bool waitIdleStatus(Status& status, bool use_ser_line=false,
bool read_spb2=false); bool read_spb2=false);
void deadTimeChanged();
AutoMutex lock(); AutoMutex lock();
SerialLine m_ser_line; SerialLine m_ser_line;
...@@ -199,6 +225,8 @@ class Camera : public HwMaxImageSizeCallbackGen ...@@ -199,6 +225,8 @@ class Camera : public HwMaxImageSizeCallbackGen
bool m_mis_cb_act; bool m_mis_cb_act;
Mutex m_lock; Mutex m_lock;
bool m_started; bool m_started;
double m_dead_time;
DeadTimeChangedCallback *m_dead_time_cb;
}; };
inline bool Camera::isChanActive(InputChan curr, InputChan chan) inline bool Camera::isChanActive(InputChan curr, InputChan chan)
......
...@@ -177,8 +177,22 @@ class SyncCtrlObj : public HwSyncCtrlObj ...@@ -177,8 +177,22 @@ class SyncCtrlObj : public HwSyncCtrlObj
virtual void getValidRanges(ValidRangesType& valid_ranges); virtual void getValidRanges(ValidRangesType& valid_ranges);
private: private:
class DeadTimeChangedCallback : public Camera::DeadTimeChangedCallback
{
DEB_CLASS_NAMESPC(DebModCamera, "DeadTimeChangedCallback",
"Frelon::SynCtrlObj");
public:
DeadTimeChangedCallback(SyncCtrlObj *sync);
protected:
virtual void deadTimeChanged(double dead_time);
private:
friend class SyncCtrlObj;
SyncCtrlObj *m_sync;
};
Espia::Acq& m_acq; Espia::Acq& m_acq;
Camera& m_cam; Camera& m_cam;
DeadTimeChangedCallback m_dead_time_cb;
}; };
......
...@@ -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;
......
...@@ -32,6 +32,15 @@ class Camera ...@@ -32,6 +32,15 @@ class Camera
%End %End
public: public:
class DeadTimeChangedCallback {
public:
DeadTimeChangedCallback();
virtual ~DeadTimeChangedCallback();
protected:
virtual void deadTimeChanged(double dead_time) = 0;
};
Camera(Espia::SerialLine& espia_ser_line); Camera(Espia::SerialLine& espia_ser_line);
~Camera(); ~Camera();
...@@ -39,6 +48,7 @@ class Camera ...@@ -39,6 +48,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 +103,13 @@ class Camera ...@@ -93,8 +103,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/);
...@@ -119,6 +134,9 @@ class Camera ...@@ -119,6 +134,9 @@ class Camera
void stop(); void stop();
bool isRunning(); bool isRunning();
void registerDeadTimeChangedCallback(Frelon::Camera::DeadTimeChangedCallback& cb);
void unregisterDeadTimeChangedCallback(Frelon::Camera::DeadTimeChangedCallback& cb);
protected: protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active); virtual void setMaxImageSizeCallbackActive(bool cb_active);
......
...@@ -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),
......
...@@ -32,10 +32,24 @@ const double Camera::UpdateCcdStatusTime = 0.1; ...@@ -32,10 +32,24 @@ const double Camera::UpdateCcdStatusTime = 0.1;
const double Camera::MaxIdleWaitTime = 2.5; const double Camera::MaxIdleWaitTime = 2.5;
const double Camera::MaxBusyRetryTime = 0.2; // 16 Mpixel image Aurora Xfer const double Camera::MaxBusyRetryTime = 0.2; // 16 Mpixel image Aurora Xfer
Camera::DeadTimeChangedCallback::DeadTimeChangedCallback()
: m_cam(NULL)
{
DEB_CONSTRUCTOR();
}
Camera::DeadTimeChangedCallback::~DeadTimeChangedCallback()
{
DEB_DESTRUCTOR();
if (m_cam)
m_cam->unregisterDeadTimeChangedCallback(*this);
}
Camera::Camera(Espia::SerialLine& espia_ser_line) Camera::Camera(Espia::SerialLine& espia_ser_line)
: m_ser_line(espia_ser_line), m_timing_ctrl(m_model, m_ser_line), : m_ser_line(espia_ser_line), m_timing_ctrl(m_model, m_ser_line),
m_mis_cb_act(false) m_mis_cb_act(false), m_dead_time(0), m_dead_time_cb(NULL)
{ {
DEB_CONSTRUCTOR(); DEB_CONSTRUCTOR();
...@@ -45,6 +59,9 @@ Camera::Camera(Espia::SerialLine& espia_ser_line) ...@@ -45,6 +59,9 @@ Camera::Camera(Espia::SerialLine& espia_ser_line)
Camera::~Camera() Camera::~Camera()
{ {
DEB_DESTRUCTOR(); DEB_DESTRUCTOR();
if (m_dead_time_cb)
unregisterDeadTimeChangedCallback(*m_dead_time_cb);
} }
void Camera::sync() void Camera::sync()
...@@ -120,6 +137,7 @@ void Camera::syncRegs() ...@@ -120,6 +137,7 @@ void Camera::syncRegs()
Sleep(UpdateCcdStatusTime); Sleep(UpdateCcdStatusTime);
getRoiBinOffset(m_roi_bin_offset); getRoiBinOffset(m_roi_bin_offset);
deadTimeChanged();
} }
void Camera::syncRegsGoodHTD() void Camera::syncRegsGoodHTD()
...@@ -273,6 +291,12 @@ void Camera::readRegister(Reg reg, int& val) ...@@ -273,6 +291,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();
...@@ -363,6 +387,7 @@ void Camera::setChanMode(int chan_mode) ...@@ -363,6 +387,7 @@ void Camera::setChanMode(int chan_mode)
<< "not supported in " << m_model.getName(); << "not supported in " << m_model.getName();
} }
writeRegister(ChanMode, chan_mode); writeRegister(ChanMode, chan_mode);
deadTimeChanged();
} }
void Camera::getChanMode(int& chan_mode) void Camera::getChanMode(int& chan_mode)
...@@ -642,6 +667,8 @@ void Camera::setBin(const Bin& bin) ...@@ -642,6 +667,8 @@ void Camera::setBin(const Bin& bin)
writeRegister(BinVert, bin.getY()); writeRegister(BinVert, bin.getY());
resetRoiBinOffset(); resetRoiBinOffset();
deadTimeChanged();
} }
void Camera::getBin(Bin& bin) void Camera::getBin(Bin& bin)
...@@ -670,6 +697,8 @@ void Camera::setRoiMode(RoiMode roi_mode) ...@@ -670,6 +697,8 @@ void Camera::setRoiMode(RoiMode roi_mode)
if (roi_mode == None) if (roi_mode == None)
resetRoiBinOffset(); resetRoiBinOffset();
deadTimeChanged();
} }
void Camera::getRoiMode(RoiMode& roi_mode) void Camera::getRoiMode(RoiMode& roi_mode)
...@@ -1001,6 +1030,8 @@ void Camera::writeChanRoi(const Roi& chan_roi) ...@@ -1001,6 +1030,8 @@ void Camera::writeChanRoi(const Roi& chan_roi)
writeRegister(RoiPixelWidth, size.getWidth()); writeRegister(RoiPixelWidth, size.getWidth());
writeRegister(RoiLineBegin, tl.y); writeRegister(RoiLineBegin, tl.y);
writeRegister(RoiLineWidth, size.getHeight()); writeRegister(RoiLineWidth, size.getHeight());
deadTimeChanged();
} }
void Camera::readChanRoi(Roi& chan_roi) void Camera::readChanRoi(Roi& chan_roi)
...@@ -1129,6 +1160,8 @@ void Camera::resetRoiBinOffset() ...@@ -1129,6 +1160,8 @@ void Camera::resetRoiBinOffset()
DEB_TRACE() << "Forcing alignment " << DEB_VAR2(bin_y, DEB_TRACE() << "Forcing alignment " << DEB_VAR2(bin_y,
roi_line_beg); roi_line_beg);
writeRegister(RoiLineBegin, roi_line_beg); writeRegister(RoiLineBegin, roi_line_beg);
deadTimeChanged();
} }
} }
...@@ -1159,6 +1192,7 @@ void Camera::setTimeUnitFactor(TimeUnitFactor time_unit_factor) ...@@ -1159,6 +1192,7 @@ void Camera::setTimeUnitFactor(TimeUnitFactor time_unit_factor)
DEB_PARAM() << DEB_VAR1(time_unit_factor); DEB_PARAM() << DEB_VAR1(time_unit_factor);
int time_unit = int(time_unit_factor); int time_unit = int(time_unit_factor);
writeRegister(TimeUnit, time_unit); writeRegister(TimeUnit, time_unit);
deadTimeChanged();
} }
void Camera::getTimeUnitFactor(TimeUnitFactor& time_unit_factor) void Camera::getTimeUnitFactor(TimeUnitFactor& time_unit_factor)
...@@ -1269,7 +1303,7 @@ void Camera::getShutCloseTime(double& shut_time) ...@@ -1269,7 +1303,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 +1313,7 @@ void Camera::setLatTime(double lat_time) ...@@ -1279,7 +1313,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 +1324,60 @@ void Camera::getLatTime(double& lat_time) ...@@ -1290,6 +1324,60 @@ 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 = max(0.0, lat_time - dead_time);
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();
...@@ -1320,6 +1408,7 @@ void Camera::setSPB2Config(SPB2Config spb2_config) ...@@ -1320,6 +1408,7 @@ void Camera::setSPB2Config(SPB2Config spb2_config)
DEB_PARAM() << DEB_VAR1(spb2_config) DEB_PARAM() << DEB_VAR1(spb2_config)
<< " [" << getSPB2ConfigName(spb2_config) << "]"; << " [" << getSPB2ConfigName(spb2_config) << "]";
writeRegister(ConfigHD, int(spb2_config)); writeRegister(ConfigHD, int(spb2_config));
deadTimeChanged();
} }
void Camera::getSPB2Config(SPB2Config& spb2_config) void Camera::getSPB2Config(SPB2Config& spb2_config)
...@@ -1554,3 +1643,40 @@ double Camera::getMaxIdleWaitTime() ...@@ -1554,3 +1643,40 @@ double Camera::getMaxIdleWaitTime()
DEB_RETURN() << DEB_VAR1(max_wait_time); DEB_RETURN() << DEB_VAR1(max_wait_time);
return max_wait_time; return max_wait_time;
} }
void Camera::registerDeadTimeChangedCallback(DeadTimeChangedCallback& cb)
{
DEB_MEMBER_FUNCT();
if (m_dead_time_cb)
THROW_HW_ERROR(InvalidValue) << "a cb is already registered";
cb.m_cam = this;
m_dead_time_cb = &cb;
}
void Camera::unregisterDeadTimeChangedCallback(DeadTimeChangedCallback& cb)
{
DEB_MEMBER_FUNCT();
if (&cb != m_dead_time_cb)
THROW_HW_ERROR(InvalidValue) << "the cb is not registered";
m_dead_time_cb = NULL;
cb.m_cam = NULL;
}
void Camera::deadTimeChanged()
{
DEB_MEMBER_FUNCT();
double dead_time;
getDeadTime(dead_time);
DEB_TRACE() << DEB_VAR2(dead_time, m_dead_time);
if (dead_time == m_dead_time)
return;
m_dead_time = dead_time;
if (m_dead_time_cb)
m_dead_time_cb->deadTimeChanged(dead_time);
}
...@@ -265,15 +265,36 @@ void BufferCtrlObj::unregisterFrameCallback(HwFrameCallback& frame_cb) ...@@ -265,15 +265,36 @@ void BufferCtrlObj::unregisterFrameCallback(HwFrameCallback& frame_cb)
* \brief SyncCtrlObj constructor * \brief SyncCtrlObj constructor
*******************************************************************/ *******************************************************************/
SyncCtrlObj::DeadTimeChangedCallback::DeadTimeChangedCallback(SyncCtrlObj *sync)
: m_sync(sync)
{
DEB_CONSTRUCTOR();
}
void SyncCtrlObj::DeadTimeChangedCallback::deadTimeChanged(double dead_time)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(dead_time);
if (!m_sync)
return;
ValidRangesType valid_ranges;
m_sync->getValidRanges(valid_ranges);
m_sync->validRangesChanged(valid_ranges);
}
SyncCtrlObj::SyncCtrlObj(Acq& acq, Camera& cam) SyncCtrlObj::SyncCtrlObj(Acq& acq, Camera& cam)
: HwSyncCtrlObj(), m_acq(acq), m_cam(cam) : HwSyncCtrlObj(), m_acq(acq), m_cam(cam), m_dead_time_cb(this)
{ {
DEB_CONSTRUCTOR(); DEB_CONSTRUCTOR();
m_cam.registerDeadTimeChangedCallback(m_dead_time_cb);
} }
SyncCtrlObj::~SyncCtrlObj() SyncCtrlObj::~SyncCtrlObj()
{ {
DEB_DESTRUCTOR(); DEB_DESTRUCTOR();
m_dead_time_cb.m_sync = NULL;
} }
bool SyncCtrlObj::checkTrigMode(TrigMode trig_mode) bool SyncCtrlObj::checkTrigMode(TrigMode trig_mode)
...@@ -330,13 +351,13 @@ void SyncCtrlObj::getExpTime(double& exp_time) ...@@ -330,13 +351,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 +393,10 @@ void SyncCtrlObj::getValidRanges(ValidRangesType& valid_ranges) ...@@ -372,8 +393,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 +887,8 @@ void Interface::resetDefaults() ...@@ -864,8 +887,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";
......
############################################################################
# This file is part of LImA, a Library for Image Acquisition
#
# Copyright (C) : 2009-2011
# European Synchrotron Radiation Facility
# BP 220, Grenoble 38043
# FRANCE
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
############################################################################
import sys
import getopt
from Lima import Core, Frelon
import time
Core.DEB_GLOBAL(Core.DebModTest)
class ImageStatusCallback(Core.CtControl.ImageStatusCallback):
Core.DEB_CLASS(Core.DebModTest, "ImageStatusCallback")
@Core.DEB_MEMBER_FUNCT
def __init__(self, ct, acq_state):
Core.CtControl.ImageStatusCallback.__init__(self)
self.m_ct = ct
self.m_acq_state = acq_state
self.m_nb_frames = 0
@Core.DEB_MEMBER_FUNCT
def start(self):
self.m_acq_state.set(Core.AcqState.Acquiring)
self.m_start_time = time.time()
self.m_stat_acc = [0.0] * 4
ct_acq = self.m_ct.acquisition()
self.m_nb_frames = ct_acq.getAcqNbFrames()
@Core.DEB_MEMBER_FUNCT
def imageStatusChanged(self, cb_img_status):
t = time.time()
global_status = self.m_ct.getStatus()
acq_status = global_status.AcquisitionStatus
img_status = global_status.ImageCounters
last_acq_frame_nb = img_status.LastImageAcquired;
last_base_frame_nb = img_status.LastBaseImageReady;
last_ready_frame_nb = img_status.LastImageReady;
dt = t - self.m_start_time
n = last_acq_frame_nb + 1
acc = self.m_stat_acc
acc[0] += n
acc[1] += n**2
acc[2] += dt
acc[3] += n * dt
acq_state_changed = False
if last_ready_frame_nb == self.m_nb_frames - 1:
self.m_acq_state.set(Core.AcqState.Finished)
acq_state_changed = True
pt = t0 = 0
if n > 1:
pt = (acc[0] * acc[2] - n * acc[3]) / (acc[0]**2 - n * acc[1])
t0 = (acc[2] - pt * acc[0]) / n
if True:
deb.Always("Last Acquired: %8d, Last Base: %8d, " \
"Last Ready: %8d, Status: %s, PT: %.6f, T0: %.6f" %
(last_acq_frame_nb, last_base_frame_nb,
last_ready_frame_nb, acq_status, pt, t0))
@Core.DEB_GLOBAL_FUNCT
def test_frelon_acc(enable_debug, espia_dev_nb, vert_bin, exp_time,
acc_max_exp_time, nb_frames, acc_time_mode):
if enable_debug:
Core.DebParams.enableModuleFlags(Core.DebParams.AllFlags)
Core.DebParams.enableTypeFlags(Core.DebParams.AllFlags)
else:
Core.DebParams.disableModuleFlags(Core.DebParams.AllFlags)
deb.Always("Creating FrelonAcq")
acq = Frelon.FrelonAcq(espia_dev_nb)
deb.Trace("Done!")
cam = acq.getFrelonCamera()
ct = acq.getGlobalControl()
ct_image = ct.image()
ct_acq = ct.acquisition()
acq_state = Core.AcqState()
status_cb = ImageStatusCallback(ct, acq_state)
ct.registerImageStatusCallback(status_cb)
deb.Always("Setting Full Frame Mode - Speed - Chan 3&4")
cam.setSPB2Config(Frelon.SPB2Speed)
cam.setFrameTransferMode(Frelon.FFM)
cam.setInputChan(Frelon.Chan34)
deb.Trace("Done!")
frame_dim = acq.getFrameDim(max_dim=True)
bin = Core.Bin(1, vert_bin)
deb.Always("Setting binning %s" % bin)
ct_image.setBin(bin);
deb.Trace("Done!")
image_size = frame_dim.getSize()
nb_cols = image_size.getWidth()
nb_lines = image_size.getHeight() / vert_bin
roi = Core.Roi(Core.Point(0, nb_lines - 2), Core.Size(nb_cols, 1));
deb.Always("Setting RoI %s" % roi)
ct_image.setRoi(roi);
deb.Trace("Done!")
deb.Always("Setting Kinetic RoI mode")
cam.setRoiMode(Frelon.Kinetic);
deb.Trace("Done!")
deb.Always("Setting Acc. mode")
ct_acq.setAcqMode(Core.Accumulation)
deb.Trace("Done!")
deb.Always("Setting %s Acc. Time mode" % acc_time_mode)
acc_mode = Core.CtAcquisition.Live \
if acc_time_mode == 'Live' \
else Core.CtAcquisition.Real
ct_acq.setAccTimeMode(acc_mode)
deb.Trace("Done!")
deb.Always("Setting Acc. max. exp. time %s" % acc_max_exp_time)
ct_acq.setAccMaxExpoTime(acc_max_exp_time)
deb.Trace("Done!")
deb.Always("Setting exp. time %s" % exp_time)
ct_acq.setAcqExpoTime(exp_time)
deb.Trace("Done!")
deb.Always("Setting nb. frames %s" % nb_frames)
ct_acq.setAcqNbFrames(nb_frames)
deb.Trace("Done!")
acc_nb_frames = ct_acq.getAccNbFrames()
acc_dead_time = ct_acq.getAccDeadTime()
acc_live_time = ct_acq.getAccLiveTime()
deb.Always("AccNbFrames: %d, AccDeadTime: %.6f, AccLiveTime: %.6f" %
(acc_nb_frames, acc_dead_time, acc_live_time))
deb.Always("Preparing acq.")
ct.prepareAcq()
deb.Trace("Done!")
deb.Always("Starting acq.")
status_cb.start()
ct.startAcq()
deb.Trace("Done!")
state_mask = Core.AcqState.Acquiring
acq_state.waitNot(state_mask)
deb.Always("Finished!")
dead_time = cam.getDeadTime()
read_time = cam.getReadoutTime()
xfer_time = cam.getTransferTime()
deb.Always("Dead Time: %.6f, Readout Time: %.6f, Transfer Time: %.6f" %
(dead_time, read_time, xfer_time))
def main(argv):
enable_debug = False
espia_dev_nb = 0
vert_bin = 64
exp_time = 20e-3
acc_max_exp_time = 2e-3
nb_frames = 10
acc_time_mode = 'Live'
opts, args = getopt.getopt(argv[1:], 'de:v:t:m:n:r')
for opt, val in opts:
if opt == '-d':
enable_debug = True
if opt == '-e':
espia_dev_nb = int(val)
if opt == '-v':
vert_bin = int(val)
if opt == '-t':
exp_time = float(val)
if opt == '-m':
acc_max_exp_time = float(val)
if opt == '-n':
nb_frames = int(val)
if opt == '-r':
acc_time_mode = 'Real'
test_frelon_acc(enable_debug, espia_dev_nb, vert_bin, exp_time,
acc_max_exp_time, nb_frames, acc_time_mode)
if __name__ == '__main__':
main(sys.argv)
############################################################################
# This file is part of LImA, a Library for Image Acquisition
#
# Copyright (C) : 2009-2011
# European Synchrotron Radiation Facility
# BP 220, Grenoble 38043
# FRANCE
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
############################################################################
import sys
from Lima import Core, Espia, Frelon
Core.DEB_GLOBAL(Core.DebModTest)
class DeadTimeChangedCallback(Frelon.Camera.DeadTimeChangedCallback):
Core.DEB_CLASS(Core.DebModTest, "DeadTimeChangedCallback")
@Core.DEB_MEMBER_FUNCT
def __init__(self, cam):
Frelon.Camera.DeadTimeChangedCallback.__init__(self)
self.m_cam = cam
@Core.DEB_MEMBER_FUNCT
def deadTimeChanged(self, dead_time):
cam = self.m_cam
deb.Always("dead_time=%.6f, readout_time=%.6f, xfer_time=%.6f" %
(dead_time, cam.getReadoutTime(), cam.getTransferTime()))
def main():
edev_nr = 0
enable_debug = False
if len(sys.argv) > 1:
edev_nr = int(sys.argv[1])
if enable_debug:
Core.DebParams.enableModuleFlags(Core.DebParams.AllFlags)
Core.DebParams.enableTypeFlags(Core.DebParams.AllFlags)
else:
Core.DebParams.disableModuleFlags(Core.DebParams.AllFlags)
edev = Espia.Dev(edev_nr)
eserline = Espia.SerialLine(edev)
cam = Frelon.Camera(eserline)
dt_cb = DeadTimeChangedCallback(cam)
cam.registerDeadTimeChangedCallback(dt_cb)
cam.setFrameTransferMode(Frelon.FTM)
cam.setFrameTransferMode(Frelon.FFM)
if __name__ == '__main__':
main()