Commit d2268c29 authored by ahoms's avatar ahoms
Browse files

* set CtSaving m_ready_flag to true in _setSavingError (unblock next start)

* protect CtSaving::_SaveContainter::_close when m_fout is not open
* added CtControl::resetStatus to return acq. to Ready after Failed
* isolated code for operator os << CtControl::ErrorCode
* signal error conditions in FrelonTacoAcq::getState
* changed Frelon::SerialLine reg. cache to numeric values instead of str.
* enumerate cacheable Frelon registers instead of non-cacheable ones
* write/readRegister now check directly the reg. cache (avoid ASCII conv.)
* implemented AutoLock copy (operator =) 


git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@217 45c4679d-1946-429d-baad-37912b19538b
parent a5e81fe1
......@@ -31,8 +31,14 @@ class FrelonTacoAcq(TacoCcdAcq):
acq_status = ct_status.AcquisitionStatus
if acq_status == AcqRunning:
self.state = DevCcdAcquiring
else:
elif acq_status == AcqReady:
self.state = DevCcdReady
else:
msg = 'Acquisition error: %s' % (ct_status)
end = index(msg, ', ImageCounters')
msg = msg[:end] + '>'
ct.resetStatus(True)
raise Exception, msg
deb.Return('Device state: 0x%08x (%d)' % (self.state, self.state))
return self.state
......
......@@ -33,7 +33,7 @@ typedef std::map<Reg, std::string> RegStrMapType;
extern RegStrMapType RegStrMap;
typedef std::vector<Reg> RegListType;
extern RegListType NonCacheableRegList;
extern RegListType CacheableRegList;
extern const int MaxRegVal;
......
......@@ -67,6 +67,9 @@ class SerialLine : public HwSerialLine
void sendFmtCmd(const std::string& cmd, std::string& resp);
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
int getLastWarning();
void clearCache();
......@@ -79,7 +82,7 @@ class SerialLine : public HwSerialLine
};
friend std::ostream& operator <<(std::ostream& os, RegOp op);
typedef std::map<Reg, std::string> RegRespMapType;
typedef std::map<Reg, int> RegValMapType;
AutoMutex lock(int mode);
......@@ -90,12 +93,13 @@ class SerialLine : public HwSerialLine
double timeout = TimeoutDefault);
bool isRegCacheable(Reg reg);
bool getRegCacheVal(Reg reg, int& val);
Espia::SerialLine& m_espia_ser_line;
Cond m_cond;
int m_last_warn;
RegRespMapType m_reg_cache;
RegValMapType m_reg_cache;
bool m_cache_act;
RegOp m_curr_op;
Reg m_curr_reg;
......
......@@ -65,6 +65,9 @@ class SerialLine : HwSerialLine
void sendFmtCmd(const std::string& cmd, std::string& resp /Out/);
void writeRegister(Frelon::Reg reg, int val);
void readRegister (Frelon::Reg reg, int& val /Out/);
int getLastWarning();
void clearCache();
......
......@@ -69,13 +69,15 @@ static const RegPair RegStrCList[] = {
};
RegStrMapType lima::Frelon::RegStrMap(C_LIST_ITERS(RegStrCList));
static Reg NonCacheableRegCList[] = {
Warn,
AoiLineBegin, AoiLineWidth, AoiPixelBegin, AoiPixelWidth,
AoiImageHeight, AoiImageWidth, ChanOnImage, ChanOnCcd,
static Reg CacheableRegCList[] = {
NbFrames, ExpTime, ShutCloseTime, LatencyTime,
RoiLineBegin, RoiLineWidth, RoiPixelBegin, RoiPixelWidth,
ChanMode, TimeUnit, RoiEnable, RoiFast,
RoiKinetic, BinVert, BinHorz, ConfigHD,
ShutEnable, HardTrigDisable, FlipMode, CompSerNb,
};
RegListType
lima::Frelon::NonCacheableRegList(C_LIST_ITERS(NonCacheableRegCList));
lima::Frelon::CacheableRegList(C_LIST_ITERS(CacheableRegCList));
const int lima::Frelon::MaxRegVal = (1 << 16) - 1;
......
......@@ -74,36 +74,13 @@ void Camera::sendCmd(Cmd cmd)
void Camera::writeRegister(Reg reg, int val)
{
DEB_MEMBER_FUNCT();
const string& reg_str = RegStrMap[reg];
DEB_PARAM() << DEB_VAR3(reg, reg_str, val);
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
ostringstream cmd;
cmd << reg_str << val;
string resp;
m_ser_line.sendFmtCmd(cmd.str(), resp);
m_ser_line.writeRegister(reg, val);
}
void Camera::readRegister(Reg reg, int& val)
{
DEB_MEMBER_FUNCT();
const string& reg_str = RegStrMap[reg];
DEB_PARAM() << DEB_VAR2(reg, reg_str);
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
string resp;
m_ser_line.sendFmtCmd(reg_str + "?", resp);
istringstream is(resp);
is >> val;
DEB_RETURN() << DEB_VAR1(val);
m_ser_line.readRegister(reg, val);
}
void Camera::hardReset()
......
......@@ -93,13 +93,18 @@ void SerialLine::writeCmd(const string& buffer, bool no_wait)
if (reg_found && isRegCacheable(m_curr_reg)) {
bool is_req = !msg_parts[MsgReq].empty();
m_curr_op = is_req ? ReadReg : WriteReg;
const string& cache_val = m_reg_cache[m_curr_reg];
if (is_req) {
m_curr_resp = cache_val;
m_curr_cache = !m_curr_resp.empty();
} else {
m_curr_resp = msg_parts[MsgVal];
m_curr_cache = (m_curr_resp == cache_val);
int cache_val;
m_curr_cache = getRegCacheVal(m_curr_reg, cache_val);
if (m_curr_cache) {
ostringstream os;
os << cache_val;
const string& cache_str = os.str();
if (is_req) {
m_curr_resp = cache_str;
} else {
m_curr_resp = msg_parts[MsgVal];
m_curr_cache = (m_curr_resp == cache_str);
}
}
if (m_curr_cache) {
DEB_TRACE() << "Skipping " << m_curr_op
......@@ -188,8 +193,11 @@ void SerialLine::readSingleLine(string& buffer, int max_len, double timeout)
if (!reg_op || !isRegCacheable(m_curr_reg))
return;
string& cache_val = m_reg_cache[m_curr_reg];
cache_val = is_req ? m_curr_fmt_resp : m_curr_resp;
const string& cache_str = is_req ? m_curr_fmt_resp : m_curr_resp;
int cache_val;
istringstream is(cache_str);
is >> cache_val;
m_reg_cache[m_curr_reg] = cache_val;
DEB_TRACE() << "New " << DEB_VAR1(cache_val);
}
......@@ -230,12 +238,22 @@ bool SerialLine::isRegCacheable(Reg reg)
return false;
}
const RegListType& list = NonCacheableRegList;
bool cacheable = (find(list.begin(), list.end(), reg) == list.end());
const RegListType& list = CacheableRegList;
bool cacheable = (find(list.begin(), list.end(), reg) != list.end());
DEB_RETURN() << DEB_VAR1(cacheable);
return cacheable;
}
bool SerialLine::getRegCacheVal(Reg reg, int& val)
{
DEB_MEMBER_FUNCT();
RegValMapType::const_iterator it = m_reg_cache.find(reg);
bool in_cache = (it != m_reg_cache.end());
val = in_cache ? it->second : 0;
DEB_RETURN() << DEB_VAR2(in_cache, val);
return in_cache;
}
void SerialLine::flush()
{
DEB_MEMBER_FUNCT();
......@@ -390,6 +408,59 @@ void SerialLine::getCacheActive(bool& cache_act)
DEB_RETURN() << DEB_VAR1(cache_act);
}
void SerialLine::writeRegister(Reg reg, int val)
{
DEB_MEMBER_FUNCT();
const string& reg_str = RegStrMap[reg];
DEB_PARAM() << DEB_VAR3(reg, reg_str, val);
int cache_val;
AutoMutex l = lock(AutoMutex::Locked);
bool ok = (isRegCacheable(reg) && getRegCacheVal(reg, cache_val));
l.unlock();
if (ok && (cache_val == val)) {
DEB_TRACE() << "Value already in cache";
} else {
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
ostringstream cmd;
cmd << reg_str << val;
string 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);
AutoMutex l = lock(AutoMutex::Locked);
bool ok = (isRegCacheable(reg) && getRegCacheVal(reg, val));
l.unlock();
if (ok) {
DEB_TRACE() << "Using cache value";
} else {
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
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)
{
......
......@@ -65,6 +65,14 @@ public:
void leaveLocked()
{ d->leaveLocked(); }
AutoLock& operator =(const AutoLock& o)
{
AutoLockData *od = o.getData(); // protects against "a = a"
putData();
d = od;
return *this;
}
private:
class AutoLockData
{
......
......@@ -19,6 +19,7 @@ def DEB_FUNCT(fn, in_global=True, frame=1):
filename = os.path.basename(code.co_filename)
lineno = frame.f_lineno
def real_fn(*arg, **kw):
sys.exc_clear()
fn_globals = dict(fn.func_globals)
fn_globals['deb'] = DebObj(deb_params, fn.func_name, '',
filename, lineno)
......
......@@ -109,6 +109,7 @@ namespace lima
void ReadBaseImage(Data&,long frameNumber = -1);
void reset();
void resetStatus(bool only_acq_status);
void registerImageStatusCallback(ImageStatusCallback& cb);
void unregisterImageStatusCallback(ImageStatusCallback& cb);
......@@ -180,36 +181,34 @@ namespace lima
return os;
}
inline std::ostream& operator<<(std::ostream &os,
const CtControl::ErrorCode &err_code)
{
const char *desc = "Unknown";
switch (err_code)
{
case CtControl::NoError: desc = "No error"; break;
case CtControl::SaveUnknownError: desc = "Saving error"; break;
case CtControl::SaveAccessError: desc = "Save access error"; break;
case CtControl::SaveOverwriteError: desc = "Save overwrite error"; break;
case CtControl::SaveDiskFull: desc = "Save disk full"; break;
case CtControl::SaveOverun: desc = "Save overrun"; break;
case CtControl::ProcessingOverun: desc = "Soft Processing overrun"; break;
// should read CameraStatus instead @todo fix me
case CtControl::CameraError: desc = "Camera Error"; break;
}
return os << desc;
}
inline std::ostream& operator<<(std::ostream &os,
const CtControl::Status &status)
{
os << "<";
switch(status.AcquisitionStatus)
{
case AcqReady:
os << "AcquisitionStatus=" << "Ready";break;
case AcqRunning:
os << "AcquisitionStatus=" << "Running";break;
default:
os << "AcquisitionStatus=" << "Failed";break;
}
os << "AcquisitionStatus=" << status.AcquisitionStatus;
if(status.AcquisitionStatus == AcqFault)
{
os << ", ";
switch(status.Error)
{
case(CtControl::SaveUnknownError): os << "Error=" << "Saving error";break;
case(CtControl::SaveAccessError): os << "Error=" << "Save access error";break;
case(CtControl::SaveOverwriteError): os << "Error=" << "Save overwrite error";break;
case(CtControl::SaveDiskFull): os << "Error=" << "Save disk full";break;
case(CtControl::SaveOverun): os << "Error=" << "Save overrun";break;
case(CtControl::ProcessingOverun): os << "Error=" << "Soft Processing overrun";break;
// should read CameraStatus instead @todo fix me
case(CtControl::CameraError): os << "Error=" << "Camera Error";break;
default: break;
}
}
os << status.ImageCounters;
os << ", Error=" << status.Error;
os << ", ImageCounters=" << status.ImageCounters;
return os;
}
} // namespace lima
......
......@@ -86,6 +86,7 @@ using namespace lima;
void ReadBaseImage(Data& data /Out/,long frameNumber = -1);
void reset();
void resetStatus(bool only_acq_status);
void registerImageStatusCallback(ImageStatusCallback& cb);
void unregisterImageStatusCallback(ImageStatusCallback& cb);
......
......@@ -142,9 +142,10 @@ void CtControl::getApplyPolicy(ApplyPolicy &policy) const
void CtControl::prepareAcq()
{
DEB_MEMBER_FUNCT();
m_status.reset();
resetStatus(false);
DEB_TRACE() << "Apply Acquisition Parameters";
m_ct_acq->apply(m_policy);
DEB_TRACE() << "Apply hardware bin/roi";
m_ct_image->applyHard();
......@@ -344,6 +345,18 @@ void CtControl::reset()
DEB_TRACE() << "Reseting display";
m_ct_sps_image->reset();
resetStatus(false);
}
void CtControl::resetStatus(bool only_acq_status)
{
DEB_MEMBER_FUNCT();
DEB_TRACE() << "Reseting the status";
if (only_acq_status)
m_status.AcquisitionStatus = AcqReady;
else
m_status.reset();
}
bool CtControl::newFrameReady(Data& fdata)
......
......@@ -616,11 +616,15 @@ void CtSaving::_setSavingError(CtControl::ErrorCode anErrorCode)
DEB_ERROR() << DEB_VAR1(m_ctrl.m_status);
}
aLock.unlock();
m_ctrl.stopAcq();
DEB_TRACE() << "Setting ready flag";
aLock = AutoMutex(m_cond.mutex());
m_ready_flag = true;
m_cond.signal();
}
/** @brief saving container
......@@ -706,6 +710,11 @@ void CtSaving::_SaveContainer::_close()
{
DEB_MEMBER_FUNCT();
if (!m_fout.is_open()) {
DEB_TRACE() << "Nothing to do";
return;
}
DEB_TRACE() << "Close current file";
m_fout.close();
......
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