Commit a3ed988e authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by Laurent Claustre
Browse files

Add SeqTim support: latch/measureSeqTimValues

* Move timing code from Geometry to TimingCtrl
parent 997bc916
......@@ -39,6 +39,7 @@ enum Reg {
ChanMode, TimeUnit, RoiEnable, RoiFast,
AntiBloom, BinVert, BinHorz, ConfigHD,
RoiKinetic, ShutEnable, HardTrigDisable,
NbLinesXfer, ShutElecSelect,
PixelFreq, LineFreq, FlipMode, IntCalib,
DisplayImage, AdcFloatDiode, AdcSignal,
DarkPixelCalib, DarkPixelMode, ChanControl, Mire,
......@@ -52,6 +53,11 @@ enum Reg {
StatusAMTE,
LookUpTable, ImagesPerEOF, WeightValDFl, WeightValSig,
SeqClockFreq, CamChar,
SeqTimRdOutH, SeqTimRdOutL,
SeqTimTransferH, SeqTimTransferL,
SeqTimEShutH, SeqTimEShutL,
SeqTimExposureH, SeqTimExposureL,
SeqTimFramePeriodH, SeqTimFramePeriodL,
};
typedef std::map<Reg, std::string> RegStrMapType;
......@@ -272,6 +278,16 @@ enum SPB2Config {
typedef std::map<SPB2Config, std::string> SPB2ConfigStrMapType;
extern SPB2ConfigStrMapType SPB2ConfigNameMap;
struct SeqTimValues {
double readout_time;
double transfer_time;
double electronic_shutter_time;
double exposure_time;
double frame_period;
};
std::ostream& operator <<(std::ostream& os, const SeqTimValues& tm);
} // namespace Frelon
} // namespace lima
......
......@@ -39,6 +39,30 @@ class Camera
DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Frelon");
public:
class TempRegVal
{
public:
TempRegVal(Camera& cam, Reg r, int val);
~TempRegVal();
void restore();
private:
Camera& m_cam;
Reg m_reg;
int m_orig_val;
bool m_changed;
};
class AcqSeq
{
public:
AcqSeq(Camera& cam);
~AcqSeq();
bool wait(double timeout);
void stop();
private:
Camera& m_cam;
};
Camera(Espia::SerialLine& espia_ser_line);
~Camera();
......@@ -48,13 +72,13 @@ class Camera
void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
TempRegVal getTempRegVal(Reg reg, int val);
void hardReset();
void getVersionStr(std::string& ver);
void getComplexSerialNb(int& complex_ser_nb);
Model& getModel();
TimingCtrl& getTimingCtrl();
bool getDefInputChan(FrameTransferMode ftm, InputChan& input_chan);
void setInputChan(InputChan input_chan);
void getInputChan(InputChan& input_chan);
......@@ -130,6 +154,11 @@ class Camera
void stop();
bool isRunning();
AcqSeq startAcqSeq();
void latchSeqTimValues(SeqTimValues& st);
void measureSeqTimValues(SeqTimValues& st, double timeout);
void registerDeadTimeChangedCallback(DeadTimeChangedCallback& cb);
void unregisterDeadTimeChangedCallback(DeadTimeChangedCallback& cb);
......@@ -165,7 +194,7 @@ class Camera
SerialLine m_ser_line;
Model m_model;
TimingCtrl m_timing_ctrl;
AutoPtr<TimingCtrl> m_timing_ctrl;
AutoPtr<Geometry> m_geom;
TrigMode m_trig_mode;
int m_nb_frames;
......@@ -186,6 +215,15 @@ inline bool Camera::waitIdleStatus(Status& status, bool use_ser_line,
use_ser_line, read_spb);
}
inline Camera::TempRegVal Camera::getTempRegVal(Reg reg, int val)
{
return TempRegVal(*this, reg, val);
}
inline Camera::AcqSeq Camera::startAcqSeq()
{
return AcqSeq(*this);
}
} // namespace Frelon
......
......@@ -56,7 +56,7 @@ class Geometry : public HwMaxImageSizeCallbackGen
public:
Geometry(Camera& cam);
~Geometry();
virtual ~Geometry();
void sync();
......@@ -99,10 +99,6 @@ class Geometry : public HwMaxImageSizeCallbackGen
std::string getSPB2ConfigName(SPB2Config spb2_config);
void getReadoutTime(double& readout_time);
void getTransferTime(double& xfer_time);
void getDeadTime(double& dead_time);
void deadTimeChanged();
void registerDeadTimeChangedCallback(DeadTimeChangedCallback& cb);
......@@ -115,7 +111,6 @@ class Geometry : public HwMaxImageSizeCallbackGen
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
int getModesAvail();
......@@ -154,7 +149,7 @@ class Geometry : public HwMaxImageSizeCallbackGen
void processSetRoi(const Roi& req_roi, Roi& hw_roi, Roi& chan_roi,
Point& roi_offset);
void resetRoiBinOffset();
Camera& m_cam;
Model& m_model;
Point m_chan_roi_offset;
......
......@@ -113,6 +113,7 @@ class Model
Taper, HamaChip,
ModesAvail, TimeCalc, HTDCmd, GoodHTD, ImagesPerEOF, CamChar,
SPB1, SPB2, SPB8,
SeqTim,
};
Model();
......
......@@ -23,7 +23,6 @@
#define FRELONTIMINGCTRL_H
#include "FrelonModel.h"
#include "FrelonSerialLine.h"
namespace lima
{
......@@ -31,17 +30,47 @@ namespace lima
namespace Frelon
{
class Camera;
class TimingCtrl
{
DEB_CLASS_NAMESPC(DebModCamera, "TimingCtrl", "Frelon");
public:
TimingCtrl(Model& model, SerialLine& ser_line);
~TimingCtrl();
struct SeqTim {
typedef std::pair<Reg, Reg> RegPair;
typedef std::vector<RegPair> RegPairList;
typedef std::pair<int, int> ValPair;
typedef std::vector<ValPair> ValPairList;
static RegPairList RegList;
static const double ClockPeriod;
static SeqTimValues calcValues(const ValPairList& l);
static double calcSeqTim(const ValPair& v)
{
unsigned long v_first = v.first;
return ((v_first << 16) + v.second) * ClockPeriod;
}
};
TimingCtrl(Camera& cam);
virtual ~TimingCtrl();
void getReadoutTime(double& readout_time);
void getTransferTime(double& xfer_time);
void getDeadTime(double& dead_time);
void latchSeqTimValues(SeqTimValues& st);
void measureSeqTimValues(SeqTimValues& st, double timeout);
protected:
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
void readFloatRegister(Reg reg, double& val);
private:
Camera& m_cam;
Model& m_model;
SerialLine& m_ser_line;
};
......
......@@ -51,6 +51,9 @@ enum Reg {
StatusAMTE,
LookUpTable, ImagesPerEOF, WeightValDFl, WeightValSig,
SeqClockFreq, CamChar,
SeqTimRdOutH, SeqTimRdOutL, SeqTimTransferH,SeqTimTransferL,
SeqTimEShutH, SeqTimEShutL, SeqTimExposureH,SeqTimExposureL,
SeqTimFramePeriodH, SeqTimFramePeriodL,
};
/*
typedef std::map<Reg, std::string> RegStrMapType;
......@@ -277,4 +280,12 @@ enum SPB2Config {
SPB2Precision, SPB2Speed,
};
struct SeqTimValues {
double readout_time;
double transfer_time;
double electronic_shutter_time;
double exposure_time;
double frame_period;
};
}; // namespace Frelon
......@@ -45,8 +45,6 @@ class Camera
void getComplexSerialNb(int& complex_ser_nb /Out/);
Frelon::Model& getModel();
Frelon::TimingCtrl& getTimingCtrl();
bool getDefInputChan(Frelon::FrameTransferMode ftm,
Frelon::InputChan& input_chan /Out/);
void setInputChan(Frelon::InputChan input_chan);
......@@ -124,6 +122,9 @@ class Camera
void stop();
bool isRunning();
void latchSeqTimValues(Frelon::SeqTimValues& st /Out/);
void measureSeqTimValues(Frelon::SeqTimValues& st /Out/, double timeout);
void registerDeadTimeChangedCallback(Frelon::DeadTimeChangedCallback& cb);
void unregisterDeadTimeChangedCallback(Frelon::DeadTimeChangedCallback& cb);
void registerMaxImageSizeCallback(HwMaxImageSizeCallback& cb);
......
......@@ -64,6 +64,7 @@ class Model
Taper, HamaChip,
ModesAvail, TimeCalc, HTDCmd, GoodHTD, ImagesPerEOF, CamChar,
SPB1, SPB2, SPB8,
SeqTim,
};
Model();
......
//###########################################################################
// 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/>.
//###########################################################################
namespace Frelon
{
class TimingCtrl
{
%TypeHeaderCode
#include "FrelonTimingCtrl.h"
%End
public:
TimingCtrl(Frelon::Model& model, Frelon::SerialLine& ser_line);
~TimingCtrl();
};
}; // namespace Frelon
......@@ -48,6 +48,9 @@ static const RegPair RegStrCList[] = {
RegPair(ShutEnable, "U"),
RegPair(HardTrigDisable,"HTD"),
RegPair(NbLinesXfer, "NLT"),
RegPair(ShutElecSelect, "SES"),
RegPair(PixelFreq, "P"),
RegPair(LineFreq, "L"),
......@@ -101,6 +104,18 @@ static const RegPair RegStrCList[] = {
RegPair(SeqClockFreq, "FSC"),
RegPair(CamChar, "CCH"),
RegPair(SeqTimRdOutH, "SETA"),
RegPair(SeqTimRdOutL, "SETB"),
RegPair(SeqTimTransferH, "SETC"),
RegPair(SeqTimTransferL, "SETD"),
RegPair(SeqTimEShutH, "SETE"),
RegPair(SeqTimEShutL, "SETF"),
RegPair(SeqTimExposureH, "SETG"),
RegPair(SeqTimExposureL, "SETH"),
RegPair(SeqTimFramePeriodH, "SETI"),
RegPair(SeqTimFramePeriodL, "SETJ"),
};
RegStrMapType lima::Frelon::RegStrMap(C_LIST_ITERS(RegStrCList));
......@@ -261,3 +276,16 @@ static const SPB2ConfigStrPair SPB2ConfigNameCList[] = {
};
SPB2ConfigStrMapType
lima::Frelon::SPB2ConfigNameMap(C_LIST_ITERS(SPB2ConfigNameCList));
std::ostream& lima::Frelon::operator <<(std::ostream& os,
const SeqTimValues& st)
{
return os << "<"
<< "readout_time=" << st.readout_time << ", "
<< "transfer_time=" << st.transfer_time << ", "
<< "electronic_shutter_time=" << st.electronic_shutter_time
<< ", "
<< "exposure_time=" << st.exposure_time << ", "
<< "frame_period=" << st.frame_period << ", "
<< ">";
}
......@@ -25,17 +25,66 @@ using namespace lima;
using namespace lima::Frelon;
using namespace std;
Camera::TempRegVal::TempRegVal(Camera& cam, Reg r, int val)
: m_cam(cam), m_reg(r)
{
m_cam.readRegister(m_reg, m_orig_val);
m_changed = (m_orig_val != val);
if (m_changed)
m_cam.writeRegister(m_reg, val);
}
Camera::TempRegVal::~TempRegVal()
{
restore();
}
void Camera::TempRegVal::restore()
{
if (m_changed) {
m_cam.writeRegister(m_reg, m_orig_val);
m_changed = false;
}
}
Camera::AcqSeq::AcqSeq(Camera& cam)
: m_cam(cam)
{
Status status;
m_cam.getStatus(status);
if (status != Wait)
throw LIMA_EXC(Hardware, Error, "Camera is not idle");
m_cam.start();
}
Camera::AcqSeq::~AcqSeq()
{
stop();
}
void Camera::AcqSeq::stop()
{
m_cam.stop();
}
bool Camera::AcqSeq::wait(double timeout)
{
Status status = Wait;
return m_cam.waitStatus(status, StatusMask, timeout);
}
const double Camera::ResetLinkWaitTime = 5;
const double Camera::UpdateCcdStatusTime = 0.1;
const double Camera::MaxIdleWaitTime = 2.5;
const double Camera::MaxBusyRetryTime = 0.2; // 16 Mpixel image Aurora Xfer
Camera::Camera(Espia::SerialLine& espia_ser_line)
: m_ser_line(espia_ser_line), m_timing_ctrl(m_model, m_ser_line),
m_geom(NULL)
: m_ser_line(espia_ser_line)
{
DEB_CONSTRUCTOR();
m_timing_ctrl = new TimingCtrl(*this);
sync();
}
......@@ -323,11 +372,6 @@ Model& Camera::getModel()
return m_model;
}
TimingCtrl& Camera::getTimingCtrl()
{
return m_timing_ctrl;
}
string Camera::getInputChanModeName(FrameTransferMode ftm,
InputChan input_chan)
{
......@@ -623,19 +667,19 @@ void Camera::getUserLatTime(double& lat_time)
void Camera::getReadoutTime(double& readout_time)
{
DEB_MEMBER_FUNCT();
m_geom->getReadoutTime(readout_time);
m_timing_ctrl->getReadoutTime(readout_time);
}
void Camera::getTransferTime(double& xfer_time)
{
DEB_MEMBER_FUNCT();
m_geom->getTransferTime(xfer_time);
m_timing_ctrl->getTransferTime(xfer_time);
}
void Camera::getDeadTime(double& dead_time)
{
DEB_MEMBER_FUNCT();
m_geom->getDeadTime(dead_time);
m_timing_ctrl->getDeadTime(dead_time);
}
void Camera::setTotalLatTime(double lat_time)
......@@ -940,6 +984,18 @@ double Camera::getMaxIdleWaitTime()
return max_wait_time;
}
void Camera::latchSeqTimValues(SeqTimValues& st)
{
DEB_MEMBER_FUNCT();
m_timing_ctrl->latchSeqTimValues(st);
}
void Camera::measureSeqTimValues(SeqTimValues& st, double timeout)
{
DEB_MEMBER_FUNCT();
m_timing_ctrl->measureSeqTimValues(st, timeout);
}
void Camera::registerDeadTimeChangedCallback(DeadTimeChangedCallback& cb)
{
DEB_MEMBER_FUNCT();
......
......@@ -67,11 +67,6 @@ void Geometry::readRegister(Reg reg, int& val)
m_cam.readRegister(reg, val);
}
void Geometry::readFloatRegister(Reg reg, double& val)
{
m_cam.readFloatRegister(reg, val);
}
void Geometry::sync()
{
DEB_MEMBER_FUNCT();
......@@ -927,47 +922,6 @@ void Geometry::resetRoiBinOffset()
}
}
void Geometry::getReadoutTime(double& readout_time)
{
DEB_MEMBER_FUNCT();
if (!m_model.has(Model::TimeCalc))
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "readout time calculation";
if (isFrelon16()) {
readout_time = 100e-3;
} else {
readFloatRegister(ReadoutTime, readout_time);
readout_time *= 1e-6;
}
DEB_RETURN() << DEB_VAR1(readout_time);
}
void Geometry::getTransferTime(double& xfer_time)
{
DEB_MEMBER_FUNCT();
if (!m_model.has(Model::TimeCalc))
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "shift time calculation";
if (isFrelon16()) {
xfer_time = 100e-3;
} else {
readFloatRegister(TransferTime, xfer_time);
xfer_time *= 1e-6;
}
DEB_RETURN() << DEB_VAR1(xfer_time);
}
void Geometry::getDeadTime(double& dead_time)
{
DEB_MEMBER_FUNCT();
getTransferTime(dead_time);
if (dead_time == 0)
getReadoutTime(dead_time);
DEB_RETURN() << DEB_VAR1(dead_time);
}
void Geometry::setSPB2Config(SPB2Config spb2_config)
{
DEB_MEMBER_FUNCT();
......@@ -1038,7 +992,7 @@ void Geometry::deadTimeChanged()
DEB_MEMBER_FUNCT();
double dead_time;
getDeadTime(dead_time);
m_cam.getDeadTime(dead_time);
DEB_TRACE() << DEB_VAR2(dead_time, m_dead_time);
if (dead_time == m_dead_time)
return;
......@@ -1047,3 +1001,4 @@ void Geometry::deadTimeChanged()
if (m_dead_time_cb)
m_dead_time_cb->deadTimeChanged(dead_time);
}
......@@ -277,14 +277,19 @@ void Model::update()
m_spb_con_type = spb_con_type;
}
m_feature[SeqTim] = firm_v4_1;
if (has(SeqTim))
m_feature[TimeCalc] = 0;
DEB_TRACE() << DEB_VAR3(m_spb_type, m_spb_con_type, m_chip_type);
bool has_Taper = has(Taper), has_HamaChip = has(HamaChip);
bool has_ModesAvail = has(ModesAvail), has_TimeCalc = has(TimeCalc);
bool has_HTDCmd = has(HTDCmd), has_GoodHTD = has(GoodHTD);
bool has_ImagesPerEOF = has(ImagesPerEOF), has_CamChar = has(CamChar);
bool has_SeqTim = has(SeqTim);
DEB_TRACE() << DEB_VAR6(has_Taper, has_HamaChip, has_ModesAvail,
has_TimeCalc, has_HTDCmd, has_GoodHTD);
DEB_TRACE() << DEB_VAR2(has_ImagesPerEOF, has_CamChar);
DEB_TRACE() << DEB_VAR3(has_ImagesPerEOF, has_CamChar, has_SeqTim);
}
bool Model::isValid()
......
......@@ -20,13 +20,45 @@
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#include "FrelonTimingCtrl.h"
#include "FrelonCamera.h"
#include "lima/MiscUtils.h"
using namespace lima;
using namespace lima::Frelon;
using namespace std;
TimingCtrl::TimingCtrl(Model& model, SerialLine& ser_line)
: m_model(model), m_ser_line(ser_line)
const double TimingCtrl::SeqTim::ClockPeriod = 100e-9;
typedef TimingCtrl::SeqTim::RegPair SeqTimRegPair;
static SeqTimRegPair SeqTimRegPairCList[] = {
SeqTimRegPair(SeqTimRdOutH, SeqTimRdOutL),
SeqTimRegPair(SeqTimTransferH, SeqTimTransferL),
SeqTimRegPair(SeqTimEShutH, SeqTimEShutL),
SeqTimRegPair(SeqTimExposureH, SeqTimExposureL),
SeqTimRegPair(SeqTimFramePeriodH, SeqTimFramePeriodL),
};
TimingCtrl::SeqTim::RegPairList
TimingCtrl::SeqTim::RegList(C_LIST_ITERS(SeqTimRegPairCList));
SeqTimValues TimingCtrl::SeqTim::calcValues(const ValPairList& l)
{
if (l.size() != RegList.size())
throw LIMA_EXC(Hardware, InvalidValue,
"SeqTim::calcValues: bad val list");
SeqTimValues st;
ValPairList::const_iterator it = l.begin();
st.readout_time = calcSeqTim(*it++);
st.transfer_time = calcSeqTim(*it++);
st.electronic_shutter_time = calcSeqTim(*it++);
st.exposure_time = calcSeqTim(*it++);
st.frame_period = calcSeqTim(*it++);
return st;
}
TimingCtrl::TimingCtrl(Camera& cam)
: m_cam(cam), m_model(cam.getModel())
{
DEB_CONSTRUCTOR();
}
......@@ -35,3 +67,100 @@ TimingCtrl::~TimingCtrl()
{
DEB_DESTRUCTOR();