Commit d3a2a598 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron

* Using proper Frelon implementation of HardTrigDisable

  when TriggerMode is IntTrig or while Idle (not running),
  implemented through set/getExtSyncEnable methods
* Always call Frelon::Camera::stop at the end of acq.;
  hardware layer acq. status is now given by the camera
* Implement automatic register write retry if seq. is BuSY
* Force an Aurora link reset at startup only if CHAN_UP_LED
  is detected inactive; wait 5 seconds for Frelon AMT resetup
* Added new Sequencer and AMT (SPB2) status commands,
  including getImageCount method
* Test seq. & AMT status at startup; perform HardReset if not idle
* Added SPB2 (HD) Precision/Speed config settings
* Replaced FrelonAcq.set/getKinPars by set/getRoiBinOffset;
  implemented set/getRoiLineBegin
* Removed setting (the ignored) RoiFast in Kinetic RoiMode
* Added E2V_4k / NotMPP chips, as well as the Hamamatsu
  linear detector; implemented (non-tested) variable
  MaxFrameDim depending of the detected chip
parent d5a1a64b
......@@ -47,7 +47,9 @@ enum Reg {
Version, CompSerNb, Warn, LastWarn,
LineClockPer, PixelClockPer, FirstPHIVLen, PHIHSetupLen,
SingleVertXfer, SingleHorzXfer, AllVertXfer, AllHorzXfer,
ReadoutTime, TransferTime, CcdModesAvail,
ReadoutTime, TransferTime, CcdModesAvail, StatusSeqA,
StatusAMTA, StatusAMTB, StatusAMTC, StatusAMTD,
LookUpTable,
};
typedef std::map<Reg, std::string> RegStrMapType;
......@@ -71,7 +73,7 @@ extern CmdStrMapType CmdStrMap;
enum MultiLineCmd {
Help, Config, Dac, Volt,
Aoi, PLL, Timing,
Aoi, PLL, Timing, StatusCam,
};
typedef std::map<MultiLineCmd, std::string> MultiLineCmdStrMapType;
......@@ -127,14 +129,19 @@ typedef std::map<TimeUnitFactor, double> TimeUnitFactorMapType;
extern TimeUnitFactorMapType TimeUnitFactorMap;
extern const FrameDim MaxFrameDim;
enum ChipType {
Atmel,
Kodak,
E2V,
E2V_2k,
E2V_2kNotMPP,
E2V_4k,
E2V_4kNotMPP,
Hama,
};
typedef std::map<ChipType, FrameDim> ChipMaxFrameDimMapType;
extern ChipMaxFrameDimMapType ChipMaxFrameDimMap;
typedef std::map<ChipType, double> ChipPixelSizeMapType;
extern ChipPixelSizeMapType ChipPixelSizeMap;
......@@ -148,22 +155,56 @@ enum {
MaxBinY = 1024,
};
enum ExtSync {
ExtSyncNone = 0,
ExtSyncStart = 1,
ExtSyncStop = 2,
ExtSyncBoth = 3,
};
enum Status {
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
StatusMask = 0xff,
InInit = 0x200,
EspiaXfer = 0x100,
Wait = 0x080,
Transfer = 0x040,
Exposure = 0x020,
Shutter = 0x010,
Readout = 0x008,
Latency = 0x004,
ExtStart = 0x002,
ExtStop = 0x001,
StatusMask = 0x3ff,
};
enum StatusSPB2 {
SPB2_GBitFifoPixEmpty = 0x8000,
SPB2_FifoOutEmpty = 0x4000,
SPB2_FifoInEmpty = 0x2000,
SPB2_FifoLUTEmpty = 0x1000,
SPB2_FifoChan4Empty = 0x0800,
SPB2_FifoChan3Empty = 0x0400,
SPB2_FifoChan2Empty = 0x0200,
SPB2_FifoChan1Empty = 0x0100,
SPB2_FifoEmptyMask = 0xff00,
SPB2_TstEnvFrmOut = 0x0040,
SPB2_TstEnvFrmIn = 0x0020,
SPB2_TstEnvMask = 0x0060,
SPB2_TstFlashUsrReady = 0x0010,
SPB2_EndInitRam = 0x0008,
SPB2_EndFlashRead = 0x0004,
SPB2_AuroraChanUp = 0x0002,
SPB2_DcmLocked = 0x0001,
SPB2_TstInitMask = 0x001f,
SPB2_TstInitGood = 0x001f,
};
enum ShutMode {
Off, AutoFrame,
};
enum SPB2Config {
SPB2Precision, SPB2Speed,
};
} // namespace Frelon
......
......@@ -63,6 +63,7 @@ class Camera : public HwMaxImageSizeCallbackGen
static std::string getInputChanModeName(FrameTransferMode ftm,
InputChan input_chan);
void getMaxFrameDim(FrameDim& max_frame_dim);
void getFrameDim(FrameDim& frame_dim);
bool isChanActive(InputChan curr, InputChan chan);
......@@ -103,23 +104,37 @@ class Camera : public HwMaxImageSizeCallbackGen
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void getStatus(Status& status);
bool waitStatus(Status& status, Status mask, double timeout);
void setSPB2Config(SPB2Config spb2_config);
void getSPB2Config(SPB2Config& spb2_config);
void setExtSyncEnable(ExtSync ext_sync_ena);
void getExtSyncEnable(ExtSync& ext_sync_ena);
void getStatus(Status& status, bool use_ser_line=false,
bool read_spb2=false);
bool waitStatus(Status& status, Status mask, double timeout,
bool use_ser_line=false, bool read_spb2=false);
void getImageCount(unsigned int& img_count, bool only_lsw=false);
void start();
void stop();
bool isRunning();
protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active);
private:
static const double ResetLinkWaitTime;
static const double UpdateCcdStatusTime;
static const double MaxIdleWaitTime;
static const double MaxBusyRetryTime;
Espia::Dev& getEspiaDev();
void sync();
void syncRegs();
void syncRegsGoodHTD();
void sendCmd(Cmd cmd);
......@@ -160,10 +175,11 @@ class Camera : public HwMaxImageSizeCallbackGen
void processSetRoi(const Roi& req_roi, Roi& hw_roi, Roi& chan_roi,
Point& roi_offset);
void setTimeUnitFactor(TimeUnitFactor time_unit_factor);
void getTimeUnitFactor(TimeUnitFactor& time_unit_factor);
AutoMutex lock();
SerialLine m_ser_line;
Model m_model;
TimingCtrl m_timing_ctrl;
......@@ -171,6 +187,8 @@ class Camera : public HwMaxImageSizeCallbackGen
TrigMode m_trig_mode;
int m_nb_frames;
bool m_mis_cb_act;
Mutex m_lock;
bool m_started;
};
inline bool Camera::isChanActive(InputChan curr, InputChan chan)
......@@ -178,6 +196,10 @@ inline bool Camera::isChanActive(InputChan curr, InputChan chan)
return (curr & chan) == chan;
};
inline AutoMutex Camera::lock()
{
return AutoMutex(m_lock);
}
} // namespace Frelon
......
......@@ -34,6 +34,27 @@ namespace Frelon
class Interface;
/*******************************************************************
* \class AcqEndCallback
* \brief Class executing camera commands at the end of acq.
*******************************************************************/
class AcqEndCallback : public Espia::AcqEndCallback
{
DEB_CLASS_NAMESPC(DebModCamera, "AcqEndCallback", "Frelon");
public:
AcqEndCallback(Camera& cam);
virtual ~AcqEndCallback();
protected:
virtual void acqFinished(const HwFrameInfoType& /*finfo*/);
private:
Camera& m_cam;
};
/*******************************************************************
* \class DetInfoCtrlObj
* \brief Control object providing Frelon detector info interface
......@@ -135,22 +156,8 @@ class SyncCtrlObj : public HwSyncCtrlObj
virtual void getValidRanges(ValidRangesType& valid_ranges);
private:
class AcqEndCallback : public Espia::AcqEndCallback
{
DEB_CLASS_NAMESPC(DebModCamera, "SyncCtrlObj::AcqEndCallback",
"Frelon");
public:
AcqEndCallback(Camera& cam);
virtual ~AcqEndCallback();
protected:
virtual void acqFinished(const HwFrameInfoType& /*finfo*/);
private:
Camera& m_cam;
};
Espia::Acq& m_acq;
Camera& m_cam;
AcqEndCallback m_acq_end_cb;
};
......@@ -323,6 +330,8 @@ class Interface : public HwInterface
BufferCtrlMgr& m_buffer_mgr;
Camera& m_cam;
Frelon::AcqEndCallback m_acq_end_cb;
CapList m_cap_list;
DetInfoCtrlObj m_det_info;
BufferCtrlObj m_buffer;
......
......@@ -123,6 +123,7 @@ class Model
bool hasTaper();
bool hasModesAvail();
bool hasTimeCalc();
bool hasGoodHTD();
double getPixelSize();
......
......@@ -198,7 +198,7 @@ class FrelonAcq:
raise Exception, 'Acquisition is running'
chip_type = self.m_cam.getModel().getChipType()
is_e2v = (chip_type == Frelon.E2V)
is_e2v = (chip_type == Frelon.E2V_2k)
corr_act = (is_e2v and self.m_e2v_corr_act)
deb.Param('is_e2v=%s, self.m_e2v_corr_act=%s' % (is_e2v,
self.m_e2v_corr_act))
......@@ -315,54 +315,45 @@ class FrelonAcq:
return roi_mode
@DEB_MEMBER_FUNCT
def setKinPars(self, kin_win_size, kin_line_beg, kin_stripes):
deb.Param('Setting kin pars: ' +
'kin_win_size=%s, kin_line_beg=%s, kin_stripes=%s' % \
(kin_win_size, kin_line_beg, kin_stripes))
if kin_stripes > 1:
deb.Warning('Ignoring kin_stripes=%d' % kin_stripes)
bin = self.m_ct_image.getBin()
if kin_win_size % bin.getY() != 0:
msg = 'Invalid kinetics window size (%d): ' % kin_win_size + \
'must be multiple of vert. bin (%d)' % bin.getY()
raise Exception, msg
def setRoiBinOffset(self, roi_bin_offset):
deb.Param('Setting Roi-Bin offset: %s' % roi_bin_offset)
self.m_cam.setRoiBinOffset(roi_bin_offset)
roi = self.m_ct_image.getRoi()
if roi.isEmpty():
roi = self.getMaxRoi()
@DEB_MEMBER_FUNCT
def getRoiBinOffset(self):
roi_bin_offset = self.m_cam.getRoiBinOffset()
deb.Return('Getting Roi-Bin offset: %s' % roi_bin_offset)
return roi_bin_offset
@DEB_MEMBER_FUNCT
def setRoiLineBegin(self, roi_line_beg):
deb.Param('Setting Roi line begin: %s' % roi_line_beg)
bin = self.m_ct_image.getBin()
roi = self.getRoi()
roi = roi.getUnbinned(bin)
tl = Point(roi.getTopLeft().x, kin_line_beg)
tl = Point(roi.getTopLeft().x, roi_line_beg)
tl_aligned = Point(tl)
tl_aligned.alignTo(Point(bin), Floor)
size = Size(roi.getSize().getWidth(), kin_win_size)
roi = Roi(tl_aligned, size)
roi.setTopLeft(tl_aligned)
roi = roi.getBinned(bin)
self.m_ct_image.setRoi(roi)
roi_bin_offset = tl
roi_bin_offset -= tl_aligned
self.m_cam.setRoiBinOffset(roi_bin_offset)
self.setRoiBinOffset(roi_bin_offset)
@DEB_MEMBER_FUNCT
def getKinPars(self):
def getRoiLineBegin(self):
bin = self.m_ct_image.getBin()
roi = self.m_ct_image.getRoi()
if roi.isEmpty():
roi = self.getMaxRoi()
roi = self.getRoi()
roi = roi.getUnbinned(bin)
kin_win_size = roi.getSize().getHeight()
tl = roi.getTopLeft()
tl += self.m_cam.getRoiBinOffset()
kin_line_beg = tl.y
kin_stripes = 1
deb.Return('Getting kin pars: ' +
'kin_win_size=%s, kin_line_beg=%s, kin_stripes=%s' % \
(kin_win_size, kin_line_beg, kin_stripes))
return kin_win_size, kin_line_beg, kin_stripes
tl += self.getRoiBinOffset()
roi_line_beg = tl.y
deb.Return('Getting Roi line begin: %s' % roi_line_beg)
return roi_line_beg
@DEB_MEMBER_FUNCT
def setFrameTransferMode(self, ftm):
......
......@@ -42,7 +42,8 @@ enum Reg {
Version, CompSerNb, Warn, LastWarn,
LineClockPer, PixelClockPer, FirstPHIVLen, PHIHSetupLen,
SingleVertXfer, SingleHorzXfer, AllVertXfer, AllHorzXfer,
ReadoutTime, TransferTime, CcdModesAvail,
ReadoutTime, TransferTime, CcdModesAvail, StatusSeqA,
StatusAMTA, StatusAMTB, StatusAMTC, StatusAMTD,
};
/*
typedef std::map<Reg, std::string> RegStrMapType;
......@@ -64,7 +65,7 @@ extern CmdStrMapType CmdStrMap;
enum MultiLineCmd {
Help, Config, Dac, Volt,
Aoi, PLL, Timing,
Aoi, PLL, Timing, StatusCam,
};
/*
typedef std::map<MultiLineCmd, std::string> MultiLineCmdStrMapType;
......@@ -117,37 +118,81 @@ typedef std::map<TimeUnitFactor, double> TimeUnitFactorMapType;
extern TimeUnitFactorMapType TimeUnitFactorMap;
extern const FrameDim MaxFrameDim;
*/
enum ChipType {
Atmel,
Kodak,
E2V,
E2V_2k,
E2V_2kNotMPP,
E2V_4k,
E2V_4kNotMPP,
Hama,
};
/*
typedef std::map<ChipType, FrameDim> ChipMaxFrameDimMapType;
extern ChipMaxFrameDimMapType ChipMaxFrameDimMap;
typedef std::map<ChipType, double> ChipPixelSizeMapType;
extern ChipPixelSizeMapType ChipPixelSizeMap;
*/
enum {
AtmelModesAvail = 0x0fff,
KodakModesAvail = 0x0100,
};
enum {
MaxBinX = 8,
MaxBinY = 1024,
};
enum ExtSync {
ExtSyncNone = 0,
ExtSyncStart = 1,
ExtSyncStop = 2,
ExtSyncBoth = 3,
};
enum Status {
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
StatusMask = 0xff,
InInit = 0x200,
EspiaXfer = 0x100,
Wait = 0x080,
Transfer = 0x040,
Exposure = 0x020,
Shutter = 0x010,
Readout = 0x008,
Latency = 0x004,
ExtStart = 0x002,
ExtStop = 0x001,
StatusMask = 0x3ff,
};
enum StatusSPB2 {
SPB2_GBitFifoPixEmpty = 0x8000,
SPB2_FifoOutEmpty = 0x4000,
SPB2_FifoInEmpty = 0x2000,
SPB2_FifoLUTEmpty = 0x1000,
SPB2_FifoChan4Empty = 0x0800,
SPB2_FifoChan3Empty = 0x0400,
SPB2_FifoChan2Empty = 0x0200,
SPB2_FifoChan1Empty = 0x0100,
SPB2_TstEnvFrmOut = 0x0040,
SPB2_TstEnvFrmIn = 0x0020,
SPB2_TstEnvMask = 0x0060,
SPB2_TstFlashUsrReady = 0x0010,
SPB2_EndInitRam = 0x0008,
SPB2_EndFlashRead = 0x0004,
SPB2_AuroraChanUp = 0x0002,
SPB2_DcmLocked = 0x0001,
SPB2_TstInitMask = 0x001f,
SPB2_TstInitGood = 0x001f,
};
enum ShutMode {
Off, AutoFrame,
};
enum SPB2Config {
SPB2Precision, SPB2Speed,
};
}; // namespace Frelon
......@@ -58,6 +58,7 @@ class Camera
static std::string getInputChanModeName(Frelon::FrameTransferMode ftm,
Frelon::InputChan input_chan);
void getMaxFrameDim(FrameDim& max_frame_dim /Out/);
void getFrameDim(FrameDim& frame_dim /Out/);
bool isChanActive(Frelon::InputChan curr, Frelon::InputChan chan);
......@@ -98,12 +99,23 @@ class Camera
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames /Out/);
void getStatus(Frelon::Status& status /Out/);
void setSPB2Config(Frelon::SPB2Config spb2_config);
void getSPB2Config(Frelon::SPB2Config& spb2_config /Out/);
void setExtSyncEnable(Frelon::ExtSync ext_sync_ena);
void getExtSyncEnable(Frelon::ExtSync& ext_sync_ena /Out/);
void getStatus(Frelon::Status& status /Out/, bool use_ser_line=false,
bool read_spb2=false);
bool waitStatus(Frelon::Status& status /In,Out/, Frelon::Status mask,
double timeout);
double timeout, bool user_ser_line=false,
bool read_spb2=false);
void getImageCount(unsigned int& img_count /Out/, bool only_lsw=false);
void start();
void stop();
bool isRunning();
protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active);
......
......@@ -27,6 +27,23 @@ namespace Frelon
//class Interface;
class AcqEndCallback : Espia::AcqEndCallback
{
%TypeHeaderCode
#include "FrelonInterface.h"
#include <algorithm>
%End
public:
AcqEndCallback(Frelon::Camera& cam);
virtual ~AcqEndCallback();
protected:
virtual void acqFinished(const HwFrameInfoType& /*finfo*/);
};
class DetInfoCtrlObj : HwDetInfoCtrlObj
{
......
......@@ -75,6 +75,7 @@ class Model
bool hasTaper();
bool hasModesAvail();
bool hasTimeCalc();
bool hasGoodHTD();
double getPixelSize();
......
......@@ -87,6 +87,13 @@ static const RegPair RegStrCList[] = {
RegPair(TransferTime, "TTR"),
RegPair(CcdModesAvail, "CMA"),
RegPair(StatusSeqA, "SSA"),
RegPair(StatusAMTA, "SAA"),
RegPair(StatusAMTB, "SAB"),
RegPair(StatusAMTC, "SAC"),
RegPair(StatusAMTD, "SAD"),
RegPair(LookUpTable, "LUT"),
};
RegStrMapType lima::Frelon::RegStrMap(C_LIST_ITERS(RegStrCList));
......@@ -103,8 +110,9 @@ lima::Frelon::CacheableRegList(C_LIST_ITERS(CacheableRegCList));
typedef pair<Reg, double> RegSleepPair;
static const RegSleepPair RegSleepCList[] = {
RegSleepPair(ConfigHD, 2.0),
RegSleepPair(BinHorz, 2.0),
RegSleepPair(ConfigHD, 2.0),
RegSleepPair(BinHorz, 2.0),
RegSleepPair(LookUpTable, 2.0),
};
RegDoubleMapType lima::Frelon::RegSleepMap(C_LIST_ITERS(RegSleepCList));
......@@ -129,6 +137,7 @@ static const MLCmdPair MLCmdStrCList[] = {
MLCmdPair(Aoi, "AOI"),
MLCmdPair(PLL, "PLL"),
MLCmdPair(Timing, "TIM"),
MLCmdPair(StatusCam, "STC"),
};
MultiLineCmdStrMapType
lima::Frelon::MultiLineCmdStrMap(C_LIST_ITERS(MLCmdStrCList));
......@@ -170,15 +179,28 @@ static const FactorPair TimeUnitFactorCList[] = {
TimeUnitFactorMapType
lima::Frelon::TimeUnitFactorMap(C_LIST_ITERS(TimeUnitFactorCList));
const FrameDim lima::Frelon::MaxFrameDim(2048, 2048, Bpp16);
typedef pair<ChipType, FrameDim> ChipFrameDimPair;
static const ChipFrameDimPair ChipMaxFrameDimCList[] = {
ChipFrameDimPair(Atmel, FrameDim(2048, 2048, Bpp16)),
ChipFrameDimPair(Kodak, FrameDim(2048, 2048, Bpp16)),
ChipFrameDimPair(E2V_2k, FrameDim(2048, 2048, Bpp16)),
ChipFrameDimPair(E2V_2kNotMPP, FrameDim(2048, 2048, Bpp16)),
ChipFrameDimPair(E2V_4k, FrameDim(4096, 4096, Bpp16)),
ChipFrameDimPair(E2V_4kNotMPP, FrameDim(4096, 4096, Bpp16)),
ChipFrameDimPair(Hama, FrameDim(2048, 1, Bpp16)),
};
ChipMaxFrameDimMapType
lima::Frelon::ChipMaxFrameDimMap(C_LIST_ITERS(ChipMaxFrameDimCList));
typedef pair<ChipType, double> ChipSizePair;
static const ChipSizePair ChipPixelSizeCList[] = {
ChipSizePair(Atmel, 14e-6),
ChipSizePair(Kodak, 24e-6),
ChipSizePair(E2V, 15e-6),
ChipSizePair(Atmel, 14e-6),
ChipSizePair(Kodak, 24e-6),
ChipSizePair(E2V_2k, 15e-6),
ChipSizePair(E2V_2kNotMPP, 15e-6),
ChipSizePair(E2V_4k, 15e-6),
ChipSizePair(E2V_4kNotMPP, 15e-6),
ChipSizePair(Hama, 14e-6),
};
ChipPixelSizeMapType
lima::Frelon::ChipPixelSizeMap(C_LIST_ITERS(ChipPixelSizeCList));
......@@ -27,13 +27,15 @@ using namespace lima;
using namespace lima::Frelon;
using namespace std;
const double Camera::ResetLinkWaitTime = 5;
const double Camera::UpdateCcdStatusTime = 0.1;
const double Camera::MaxIdleWaitTime = 1.5;
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_mis_cb_act(false)
m_mis_cb_act(false), m_started(false)
{
DEB_CONSTRUCTOR();
......@@ -43,21 +45,28 @@ Camera::Camera(Espia::SerialLine& espia_ser_line)
Camera::~Camera()
{
DEB_DESTRUCTOR();
}
void Camera::sync()
{
DEB_MEMBER_FUNCT();
DEB_TRACE() << "Forcing a link reset";
Espia::Dev& dev = getEspiaDev();
dev.resetLink();
int chan_up_led;
dev.getChanUpLed(chan_up_led);
if (!chan_up_led) {
DEB_WARNING() << "Aurora link down. Forcing a link reset!";
dev.resetLink();
DEB_TRACE() << "Sleeping additional "
<< DEB_VAR1(Frelon::Camera::ResetLinkWaitTime);
Sleep(ResetLinkWaitTime);
}
DEB_TRACE() << "Synchronizing with the camera";
m_model.reset();
m_roi_offset = 0;
m_started = false;
try {
syncRegs();
......@@ -93,6 +102,9 @@ void Camera::syncRegs()
getComplexSerialNb(complex_ser_nb);
m_model.setComplexSerialNb(complex_ser_nb);
if (m_model.hasGoodHTD())
syncRegsGoodHTD();
double exp_time;
getExpTime(exp_time);
m_trig_mode = (exp_time == 0) ? ExtGate : IntTrig;
......@@ -105,6 +117,40 @@ void Camera::syncRegs()
Sleep(UpdateCcdStatusTime);
}
void Camera::syncRegsGoodHTD()
{
DEB_MEMBER_FUNCT();
Status status;
bool use_ser_line, read_spb2;
use_ser_line = read_spb2 = true;
getStatus(status, use_ser_line, read_spb2);
if (status != Wait)
DEB_WARNING() << "Camera not IDLE: "
<< DEB_VAR1(DEB_HEX(status));
int retry = 0;
do {
setExtSyncEnable(ExtSyncNone);
sendCmd(Stop);
status = Wait;
waitStatus(status, StatusMask, MaxIdleWaitTime,
use_ser_line, read_spb2);
if (status == Wait) {
if (retry > 0)
DEB_TRACE() << "Succeeded after " << retry
<< " retries";
break;
} else if (retry == 0) {
DEB_WARNING() << "Tyring a hard reset ...";
sendCmd(Reset);
}
} while (++retry < 2);
if (status != Wait)
THROW_HW_ERROR(Error) << "Wrong camera BUSY status: "
<< DEB_VAR1(DEB_HEX(status));
}
SerialLine& Camera::getSerialLine()
{
return m_ser_line;
......@@ -133,7 +179,31 @@ void Camera::sendCmd(Cmd cmd)
void Camera::writeRegister(Reg reg, int val)
{
DEB_MEMBER_FUNCT();
m_ser_line.writeRegister(reg, val);
static const string busy_msg = "Frelon Error: BSY";
Timestamp t0 = Timestamp::now();
int retry = 0;
do {
try {
m_ser_line.writeRegister(reg, val);
if (retry > 0)
DEB_WARNING() << "Succeeded after " << retry
<< " retries";
return;
} catch (Exception e) {
string err_msg = e.getErrMsg();
DEB_TRACE() << "Error in write: " << DEB_VAR1(err_msg);
bool busy = (err_msg.find(busy_msg) != string::npos);
if (!busy)
throw;
DEB_TRACE() << "Retrying ...";
retry++;
}
} while (Timestamp::now() - t0 < MaxBusyRetryTime);
THROW_HW_ERROR(Error) << "Frelon Camera still busy after "
<< MaxBusyRetryTime << " sec";
}
void Camera::readRegister(Reg reg, int& val)
......@@ -402,11 +472,21 @@ void Camera::getFrameTransferMode(FrameTransferMode& ftm)
THROW_HW_ERROR(Error) << "Invalid " << DEB_VAR1(chan_mode);
}
void Camera::getMaxFrameDim(FrameDim& max_frame_dim)
{
DEB_MEMBER_FUNCT();
ChipType chip_type = m_model.getChipType();
max_frame_dim = ChipMaxFrameDimMap[chip_type];
DEB_RETURN() << DEB_VAR1(max_frame_dim);
}
void Camera::getFrameDim(FrameDim& frame_dim)
{
DEB_MEMBER_FUNCT();
frame_dim = MaxFrameDim;
getMaxFrameDim(frame_dim);
FrameTransferMode ftm;
getFrameTransferMode(ftm);
if (ftm == FTM)
......@@ -508,7 +588,7 @@ void Camera::setRoiMode(RoiMode roi_mode)
DEB_PARAM() << DEB_VAR1(roi_mode);
bool roi_hw = (roi_mode == Slow) || (roi_mode == Fast);
bool roi_fast = (roi_mode == Fast) || (roi_mode == Kinetic);
bool roi_fast = (roi_mode == Fast);
bool roi_kin = (roi_mode == Kinetic);
DEB_TRACE() << DEB_VAR3(roi_hw, roi_fast, roi_kin);
......@@ -527,7 +607,7 @@ void Camera::getRoiMode(RoiMode& roi_mode)
readRegister(RoiKinetic, roi_kin);