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

* Support Frelon reg. write FAIlure response (previously was Warning)

  by retrying (only) once the same command
* Manage mixing of BuSY and FAIlure responses in a consistent way
* Added (unused) Reload command in firmware v3.0l
* Added Frelon::SerialLine::getRegCacheValSafe helper
parent f73d7504
......@@ -64,7 +64,7 @@ extern RegDoubleMapType RegSleepMap;
extern const int MaxRegVal;
enum Cmd {
Reset, Start, Stop, Save,
Reset, Start, Stop, Save, Reload,
};
typedef std::map<Cmd, std::string> CmdStrMapType;
......
......@@ -51,6 +51,7 @@ class Firmware
static const Firmware v2_1b;
static const Firmware v3_0i;
static const Firmware v3_0l;
private:
void checkValid();
......@@ -127,6 +128,7 @@ class Model
bool hasModesAvail();
bool hasTimeCalc();
bool hasGoodHTD();
bool hasReload();
double getPixelSize();
......@@ -145,6 +147,7 @@ class Model
bool m_modes_avail;
bool m_time_calc;
bool m_good_htd;
bool m_reload;
};
......
......@@ -131,6 +131,7 @@ class SerialLine : public HwSerialLine
bool isRegCacheable(Reg reg);
bool getRegCacheVal(Reg reg, int& val);
bool getRegCacheValSafe(Reg reg, int& val);
double getRegSleepTime(Reg reg);
......
......@@ -56,7 +56,7 @@ extern RegListType NonCacheableRegList;
const int MaxRegVal;
enum Cmd {
Reset, Start, Stop, Save,
Reset, Start, Stop, Save, Reload,
};
/*
typedef std::map<Cmd, std::string> CmdStrMapType;
......
......@@ -46,6 +46,7 @@ class Firmware
static const Frelon::Firmware v2_1b;
static const Frelon::Firmware v3_0i;
static const Frelon::Firmware v3_0l;
};
......@@ -78,6 +79,7 @@ class Model
bool hasModesAvail();
bool hasTimeCalc();
bool hasGoodHTD();
bool hasReload();
double getPixelSize();
......
......@@ -124,6 +124,7 @@ static const CmdPair CmdStrCList[] = {
CmdPair(Start, "S"),
CmdPair(Stop, "O"),
CmdPair(Save, "SAV"),
CmdPair(Reload, "RLD"),
};
CmdStrMapType lima::Frelon::CmdStrMap(C_LIST_ITERS(CmdStrCList));
......
......@@ -182,30 +182,52 @@ void Camera::writeRegister(Reg reg, int val)
{
DEB_MEMBER_FUNCT();
static const string busy_msg = "Frelon Error: BSY";
Timestamp t0 = Timestamp::now();
int retry = 0;
do {
int retry;
bool end, prev_busy = false;
for (retry = 0, end = false; !end; retry++) {
bool fail, busy;
try {
m_ser_line.writeRegister(reg, val);
if (retry > 0)
DEB_WARNING() << "Succeeded after " << retry
<< " retries";
<< " retrie(s)";
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)
static const string fail_msg = "Frelon Error: FAI";
fail = (err_msg.find(fail_msg) != string::npos);
static const string busy_msg = "Frelon Error: BSY";
busy = (err_msg.find(busy_msg) != string::npos);
if (!fail && !busy)
throw;
DEB_TRACE() << "Retrying ...";
retry++;
}
} while (Timestamp::now() - t0 < MaxBusyRetryTime);
THROW_HW_ERROR(Error) << "Frelon Camera still busy after "
<< MaxBusyRetryTime << " sec";
if ((prev_busy != busy) && (retry > 0)) {
DEB_WARNING() << "Write error type changed after "
<< retry << " retrie(s)! Restarting ...";
retry = 0;
t0 = Timestamp::now();
}
prev_busy = busy;
if (busy)
end = ((Timestamp::now() - t0) >= MaxBusyRetryTime);
else
end = (retry > 0);
if (!end)
DEB_TRACE() << "Retrying ...";
}
if (prev_busy)
THROW_HW_ERROR(Error) << "Frelon Camera still busy after "
<< MaxBusyRetryTime << " sec";
else
THROW_HW_ERROR(Error) << "Frelon Camera still failing after "
<< retry << " retrie(s)";
}
void Camera::readRegister(Reg reg, int& val)
......
......@@ -28,6 +28,7 @@ using namespace std;
const Firmware Firmware::v2_1b("2.1b");
const Firmware Firmware::v3_0i("3.0i");
const Firmware Firmware::v3_0l("3.0l");
Firmware::Firmware()
{
......@@ -206,6 +207,9 @@ void Model::update()
bool firm_v3_0i = (is_spb2 && (m_firmware >= Firmware::v3_0i));
m_good_htd = firm_v3_0i;
bool firm_v3_0l = (is_spb2 && (m_firmware >= Firmware::v3_0l));
m_reload = firm_v3_0l;
DEB_TRACE() << DEB_VAR4(m_chip_type, m_modes_avail, m_time_calc,
m_good_htd);
}
......@@ -327,6 +331,16 @@ bool Model::hasGoodHTD()
return m_good_htd;
}
bool Model::hasReload()
{
DEB_MEMBER_FUNCT();
checkValid();
DEB_RETURN() << DEB_VAR1(m_reload);
return m_reload;
}
double Model::getPixelSize()
{
DEB_MEMBER_FUNCT();
......
......@@ -287,6 +287,12 @@ bool SerialLine::getRegCacheVal(Reg reg, int& val)
return in_cache;
}
bool SerialLine::getRegCacheValSafe(Reg reg, int& val)
{
AutoMutex l = lock(AutoMutex::Locked);
return (isRegCacheable(reg) && getRegCacheVal(reg, val));
}
double SerialLine::getRegSleepTime(Reg reg)
{
DEB_MEMBER_FUNCT();
......@@ -453,21 +459,19 @@ void SerialLine::writeRegister(Reg reg, int val)
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)) {
bool in_cache = getRegCacheValSafe(reg, cache_val);
if (in_cache && (cache_val == val)) {
DEB_TRACE() << "Value already in cache";
} else {
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid "
<< DEB_VAR1(reg);
ostringstream cmd;
cmd << reg_str << val;
string resp;
sendFmtCmd(cmd.str(), resp);
}
return;
}
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(reg);
ostringstream cmd;
cmd << reg_str << val;
string resp;
sendFmtCmd(cmd.str(), resp);
}
void SerialLine::readRegister(Reg reg, int& val)
......@@ -476,22 +480,20 @@ void SerialLine::readRegister(Reg reg, int& val)
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) {
bool in_cache = getRegCacheValSafe(reg, val);
if (in_cache) {
DEB_TRACE() << "Using cache value";
} else {
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);
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);
}
......
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