Commit b856615c authored by ahoms's avatar ahoms

* Using ctypes to call Taco.so dev_error_push and notify client about errors

* Created TACO_SERVER_FUNCT decorator to push TACO error str on exceptions
* Stop a Taco Frelon acq as soon as a Fault state is returned to the client
* Fixed CtControl to properly report AcqReady after stopping an acq in
  AcqFault state (saving error) by introducing the m_started variable
* Frelon DevStatus now also returns the CCD status byte (like in C++ server)
* Implemented Frelon Firmware in Model to check for ModesAvail and TimeCalc
  features; verify that the requested input channel mode is valid for the CCD
* When waiting for a Frelon status, for specifying a bit mask and a timeout;
  avoid endless wait if the camera has never send a status byte to the Espia
* Added kin_win_size and improved kin_line_begin management in Frelon server
* Silence "unused" warning in CtAcquisition::_hwRead()
* Simplified RegEx match string management.



git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@324 45c4679d-1946-429d-baad-37912b19538b
parent ed41a62a
......@@ -111,20 +111,26 @@ enum ChipType {
typedef std::map<ChipType, double> ChipPixelSizeMapType;
extern ChipPixelSizeMapType ChipPixelSizeMap;
enum {
AtmelModesAvail = 0x0fff,
KodakModesAvail = 0x0100,
};
enum {
MaxBinX = 8,
MaxBinY = 1024,
};
enum Status {
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
StatusMask = 0xff,
};
......
......@@ -25,7 +25,7 @@ class Camera : public HwMaxImageSizeCallbackGen
void readRegister (Reg reg, int& val);
void hardReset();
void getVersion(std::string& ver);
void getVersionStr(std::string& ver);
void getComplexSerialNb(int& complex_ser_nb);
Model& getModel();
......@@ -35,6 +35,9 @@ class Camera : public HwMaxImageSizeCallbackGen
void setFrameTransferMode(FrameTransferMode ftm);
void getFrameTransferMode(FrameTransferMode& ftm);
std::string getInputChanModeName(FrameTransferMode ftm,
InputChan input_chan);
void getFrameDim(FrameDim& frame_dim);
bool isChanActive(InputChan curr, InputChan chan);
......@@ -73,7 +76,7 @@ class Camera : public HwMaxImageSizeCallbackGen
void getNbFrames(int& nb_frames);
void getStatus(Status& status);
bool waitStatus(Status& status, double timeout = 0);
bool waitStatus(Status& status, Status mask, double timeout);
void start();
void stop();
......@@ -83,7 +86,7 @@ class Camera : public HwMaxImageSizeCallbackGen
private:
static const double BinChangeTime;
static const double MaxReadoutTime;
static const double MaxIdleWaitTime;
Espia::Dev& getEspiaDev();
......@@ -91,12 +94,16 @@ class Camera : public HwMaxImageSizeCallbackGen
void sendCmd(Cmd cmd);
int getModesAvail();
void setChanMode(int chan_mode);
void getChanMode(int& chan_mode);
void getBaseChanMode(FrameTransferMode ftm, int& base_chan_mode);
void getInputChanMode(FrameTransferMode ftm, InputChan input_chan,
int& chan_mode);
void calcBaseChanMode(FrameTransferMode ftm, int& base_chan_mode);
void calcChanMode(FrameTransferMode ftm, InputChan input_chan,
int& chan_mode);
void calcFTMInputChan(int chan_mode, FrameTransferMode& ftm,
InputChan& input_chan);
void setFlipMode(int flip_mode);
void getFlipMode(int& flip_mode);
......
......@@ -9,6 +9,74 @@ namespace lima
namespace Frelon
{
class Firmware
{
DEB_CLASS_NAMESPC(DebModCamera, "Firmware", "Frelon");
public:
Firmware();
Firmware(const std::string& ver);
~Firmware();
void setVersionStr(const std::string& ver);
void getVersionStr(std::string& ver) const;
void reset();
bool isValid() const;
int getMajor() const;
int getMinor() const;
std::string getRelease() const;
private:
void checkValid();
int m_major;
int m_minor;
std::string m_rel;
};
inline bool operator ==(const Firmware& f1, const Firmware& f2)
{
return ((f1.getMajor() == f2.getMajor()) &&
(f1.getMinor() == f2.getMinor()) &&
(f1.getRelease() == f2.getRelease()));
}
inline bool operator !=(const Firmware& f1, const Firmware& f2)
{
return !(f1 == f2);
}
inline bool operator <(const Firmware& f1, const Firmware& f2)
{
if (f1.getMajor() < f2.getMajor())
return true;
if (f1.getMajor() > f2.getMajor())
return false;
if (f1.getMinor() < f2.getMinor())
return true;
if (f1.getMinor() > f2.getMinor())
return false;
return (f1.getRelease() < f2.getRelease());
}
inline bool operator >(const Firmware& f1, const Firmware& f2)
{
return !((f1 == f2) || (f1 < f2));
}
inline bool operator <=(const Firmware& f1, const Firmware& f2)
{
return ((f1 == f2) || (f1 < f2));
}
inline bool operator >=(const Firmware& f1, const Firmware& f2)
{
return !(f1 < f2);
}
class Model
{
DEB_CLASS_NAMESPC(DebModCamera, "Model", "Frelon");
......@@ -17,8 +85,8 @@ class Model
Model();
~Model();
void setVersion(const std::string& ver);
void getVersion(std::string& ver);
void setVersionStr(const std::string& ver);
Firmware& getFirmware();
void setComplexSerialNb(int complex_ser_nb);
void getComplexSerialNb(int& complex_ser_nb);
......@@ -32,6 +100,8 @@ class Model
int getAdcBits();
ChipType getChipType();
bool hasTaper();
bool hasModesAvail();
bool hasTimeCalc();
double getPixelSize();
......@@ -41,7 +111,7 @@ class Model
void checkValid();
int getSerialNbParam(SerNbParam param);
std::string m_ver;
Firmware m_firmware;
int m_complex_ser_nb;
};
......
......@@ -113,14 +113,15 @@ enum {
};
enum Status {
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
Wait = 0x80,
Transfer = 0x40,
Exposure = 0x20,
Shutter = 0x10,
Readout = 0x08,
Latency = 0x04,
ExtStart = 0x02,
ExtStop = 0x01,
StatusMask = 0xff,
};
......
......@@ -20,7 +20,7 @@ class Camera
void readRegister (Frelon::Reg reg, int& val /Out/);
void hardReset();
void getVersion(std::string& ver /Out/);
void getVersionStr(std::string& ver /Out/);
void getComplexSerialNb(int& complex_ser_nb /Out/);
Frelon::Model& getModel();
......@@ -30,6 +30,9 @@ class Camera
void setFrameTransferMode(Frelon::FrameTransferMode ftm);
void getFrameTransferMode(Frelon::FrameTransferMode& ftm /Out/);
std::string getInputChanModeName(Frelon::FrameTransferMode ftm,
Frelon::InputChan input_chan);
void getFrameDim(FrameDim& frame_dim /Out/);
bool isChanActive(Frelon::InputChan curr, Frelon::InputChan chan);
......@@ -68,7 +71,8 @@ class Camera
void getNbFrames(int& nb_frames /Out/);
void getStatus(Frelon::Status& status /Out/);
bool waitStatus(Frelon::Status& status /InOut/, double timeout = 0);
bool waitStatus(Frelon::Status& status /InOut/, Frelon::Status mask,
double timeout);
void start();
void stop();
......
namespace Frelon
{
class Firmware
{
%TypeHeaderCode
#include "FrelonModel.h"
%End
public:
Firmware();
Firmware(const std::string& ver);
~Firmware();
void setVersionStr(const std::string& ver);
void getVersionStr(std::string& ver /Out/) const;
void reset();
bool isValid() const;
int getMajor() const;
int getMinor() const;
std::string getRelease() const;
};
class Model
{
......@@ -12,8 +37,8 @@ class Model
Model();
~Model();
void setVersion(const std::string& ver);
void getVersion(std::string& ver /Out/);
void setVersionStr(const std::string& ver);
Frelon::Firmware& getFirmware();
void setComplexSerialNb(int complex_ser_nb);
void getComplexSerialNb(int& complex_ser_nb /Out/);
......@@ -27,6 +52,8 @@ class Model
int getAdcBits();
int getChipType();
bool hasTaper();
bool hasModesAvail();
bool hasTimeCalc();
double getPixelSize();
......@@ -34,4 +61,4 @@ class Model
};
}; // namespace Frelon
\ No newline at end of file
}; // namespace Frelon
......@@ -7,7 +7,7 @@ using namespace lima::Frelon;
using namespace std;
const double Camera::BinChangeTime = 2.0;
const double Camera::MaxReadoutTime = 0.7;
const double Camera::MaxIdleWaitTime = 1.5;
Camera::Camera(Espia::SerialLine& espia_ser_line)
......@@ -38,11 +38,11 @@ void Camera::sync()
try {
string ver;
getVersion(ver);
m_model.setVersion(ver);
getVersionStr(ver);
m_model.setVersionStr(ver);
} catch (Exception e) {
string err_msg = e.getErrMsg();
DEB_ERROR() << "Error getting version: " << DEB_VAR1(err_msg);
DEB_TRACE() << "Error getting version: " << DEB_VAR1(err_msg);
string timeout_msg = Espia::StrError(SCDXIPCI_ERR_TIMEOUT);
bool timeout = (err_msg.find(timeout_msg) != string::npos);
if (!timeout)
......@@ -57,7 +57,7 @@ void Camera::sync()
m_model.setComplexSerialNb(complex_ser_nb);
string ver;
m_model.getVersion(ver);
m_model.getFirmware().getVersionStr(ver);
DEB_ALWAYS() << "Found Frelon " << m_model.getName()
<< " #" << m_model.getSerialNb() << ", FW:" << ver;
......@@ -117,7 +117,7 @@ void Camera::hardReset()
sync();
}
void Camera::getVersion(string& ver)
void Camera::getVersionStr(string& ver)
{
DEB_MEMBER_FUNCT();
string cmd = RegStrMap[Version] + "?";
......@@ -137,10 +137,60 @@ Model& Camera::getModel()
return m_model;
}
int Camera::getModesAvail()
{
DEB_MEMBER_FUNCT();
int modes_avail;
if (m_model.hasModesAvail())
readRegister(CcdModesAvail, modes_avail);
else if (m_model.getChipType() == Kodak)
modes_avail = KodakModesAvail;
else
modes_avail = AtmelModesAvail;
DEB_RETURN() << DEB_VAR1(modes_avail);
return modes_avail;
}
string Camera::getInputChanModeName(FrameTransferMode ftm,
InputChan input_chan)
{
DEB_MEMBER_FUNCT();
ostringstream os;
os << ((ftm == FTM) ? "FTM" : "FFM") << "-";
string sep;
for (int chan = 1; chan <= 4; chan++) {
int chan_bit = 1 << (chan - 1);
if ((input_chan & chan_bit) != 0) {
os << sep << chan;
sep = "+";
}
}
string mode_name = os.str();
DEB_RETURN() << DEB_VAR1(mode_name);
return mode_name;
}
void Camera::setChanMode(int chan_mode)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(chan_mode);
int mode_bit = 1 << (chan_mode - 1);
bool valid_mode = ((getModesAvail() & mode_bit) != 0);
if (!valid_mode) {
FrameTransferMode ftm;
InputChan input_chan;
calcFTMInputChan(chan_mode, ftm, input_chan);
string mode_name = getInputChanModeName(ftm, input_chan);
THROW_HW_ERROR(InvalidValue)
<< "Channel mode " << mode_name
<< " [" << DEB_VAR1(chan_mode) << "] "
<< "not supported in " << m_model.getName();
}
writeRegister(ChanMode, chan_mode);
}
......@@ -151,20 +201,20 @@ void Camera::getChanMode(int& chan_mode)
DEB_RETURN() << DEB_VAR1(chan_mode);
}
void Camera::getBaseChanMode(FrameTransferMode ftm, int& base_chan_mode)
void Camera::calcBaseChanMode(FrameTransferMode ftm, int& base_chan_mode)
{
DEB_MEMBER_FUNCT();
base_chan_mode = FTMChanRangeMap[ftm].first;
DEB_RETURN() << DEB_VAR1(base_chan_mode);
}
void Camera::getInputChanMode(FrameTransferMode ftm, InputChan input_chan,
int& chan_mode)
void Camera::calcChanMode(FrameTransferMode ftm, InputChan input_chan,
int& chan_mode)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(ftm, DEB_HEX(input_chan));
getBaseChanMode(ftm, chan_mode);
calcBaseChanMode(ftm, chan_mode);
const InputChanList& chan_list = FTMInputChanListMap[ftm];
InputChanList::const_iterator it;
it = find(chan_list.begin(), chan_list.end(), input_chan);
......@@ -176,6 +226,31 @@ void Camera::getInputChanMode(FrameTransferMode ftm, InputChan input_chan,
DEB_RETURN() << DEB_VAR1(chan_mode);
}
void Camera::calcFTMInputChan(int chan_mode, FrameTransferMode& ftm,
InputChan& input_chan)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(chan_mode);
bool ftm_found = false;
FTMChanRangeMapType::const_iterator it, end = FTMChanRangeMap.end();
for (it = FTMChanRangeMap.begin(); it != end; ++it) {
ftm = it->first;
const ChanRange& range = it->second;
if ((chan_mode >= range.first) && (chan_mode < range.second)) {
ftm_found = true;
break;
}
}
if (!ftm_found)
THROW_HW_ERROR(Error) << "Invalid " << DEB_VAR1(chan_mode);
int base_chan_mode;
calcBaseChanMode(ftm, base_chan_mode);
input_chan = FTMInputChanListMap[ftm][chan_mode - base_chan_mode];
DEB_RETURN() << DEB_VAR2(ftm, DEB_HEX(input_chan));
}
void Camera::setInputChan(InputChan input_chan)
{
DEB_MEMBER_FUNCT();
......@@ -184,7 +259,7 @@ void Camera::setInputChan(InputChan input_chan)
FrameTransferMode ftm;
getFrameTransferMode(ftm);
int chan_mode;
getInputChanMode(ftm, input_chan, chan_mode);
calcChanMode(ftm, input_chan, chan_mode);
setChanMode(chan_mode);
}
......@@ -193,11 +268,9 @@ void Camera::getInputChan(InputChan& input_chan)
DEB_MEMBER_FUNCT();
FrameTransferMode ftm;
getFrameTransferMode(ftm);
int chan_mode, base_chan_mode;
int chan_mode;
getChanMode(chan_mode);
getBaseChanMode(ftm, base_chan_mode);
input_chan = FTMInputChanListMap[ftm][chan_mode - base_chan_mode];
calcFTMInputChan(chan_mode, ftm, input_chan);
DEB_RETURN() << DEB_VAR1(DEB_HEX(input_chan));
}
......@@ -217,7 +290,7 @@ void Camera::setFrameTransferMode(FrameTransferMode ftm)
InputChan input_chan;
getInputChan(input_chan);
int chan_mode;
getInputChanMode(ftm, input_chan, chan_mode);
calcChanMode(ftm, input_chan, chan_mode);
setChanMode(chan_mode);
if (!m_mis_cb_act)
......@@ -910,7 +983,7 @@ void Camera::getStatus(Status& status)
DEB_RETURN() << DEB_VAR1(DEB_HEX(status));
}
bool Camera::waitStatus(Status& status, double timeout)
bool Camera::waitStatus(Status& status, Status mask, double timeout)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(status, timeout);
......@@ -921,9 +994,15 @@ bool Camera::waitStatus(Status& status, double timeout)
bool good_status = false;
Status curr_status;
while (!good_status && !end.isSet() || (Timestamp::now() < end)) {
while (!good_status) {
if (end.isSet() && (Timestamp::now() >= end)) {
DEB_WARNING() << "Timeout waiting for "
<< DEB_VAR1(status);
break;
}
getStatus(curr_status);
good_status = ((curr_status & status) == status);
good_status = ((curr_status & mask) == status);
}
status = curr_status;
......@@ -956,15 +1035,7 @@ void Camera::stop()
DEB_TRACE() << "Waiting for camera to become idle";
Status status = Wait;
waitStatus(status);
FrameTransferMode ftm;
getFrameTransferMode(ftm);
if (ftm == FTM) {
DEB_TRACE() << "Waiting for possible FTM frame readout: "
<< "sleeping " << DEB_VAR1(MaxReadoutTime);
Sleep(MaxReadoutTime);
}
waitStatus(status, StatusMask, MaxIdleWaitTime);
}
void Camera::setMaxImageSizeCallbackActive(bool cb_active)
......
#include "FrelonModel.h"
#include "RegEx.h"
using namespace lima;
using namespace lima::Frelon;
using namespace std;
Model::Model()
Firmware::Firmware()
{
DEB_CONSTRUCTOR();
reset();
}
Model::~Model()
Firmware::Firmware(const string& ver)
{
DEB_CONSTRUCTOR();
DEB_PARAM() << DEB_VAR1(ver);
reset();
setVersionStr(ver);
}
Firmware::~Firmware()
{
DEB_DESTRUCTOR();
reset();
}
void Firmware::reset()
{
DEB_MEMBER_FUNCT();
m_major = m_minor = 0;
m_rel.clear();
}
void Model::setVersion(const std::string& ver)
void Firmware::setVersionStr(const string& ver)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(ver);
m_ver = ver;
RegEx re("(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)(?P<rel>[a-z]+)?");
RegEx::FullNameMatchType match;
if (!re.matchName(ver, match))
THROW_HW_ERROR(InvalidValue) << "Invalid firmware "
<< DEB_VAR1(ver);
m_major = atoi(string(match["major"]).c_str());
m_minor = atoi(string(match["minor"]).c_str());
m_rel = match["rel"];
if (!isValid()) {
reset();
THROW_HW_ERROR(InvalidValue) << "Invalid firmware "
<< DEB_VAR1(ver);
}
}
void Model::getVersion(std::string& ver)
void Firmware::getVersionStr(string& ver) const
{
DEB_MEMBER_FUNCT();
ver = m_ver;
ostringstream os;
if (isValid())
os << m_major << "." << m_minor << m_rel;
else
os << "Unknown";
ver = os.str();
DEB_RETURN() << DEB_VAR1(ver);
}
bool Firmware::isValid() const
{
DEB_MEMBER_FUNCT();
bool valid = (m_major > 0) || (m_minor > 0);
DEB_RETURN() << DEB_VAR1(valid);
return valid;
}
int Firmware::getMajor() const
{
DEB_MEMBER_FUNCT();
DEB_RETURN() << DEB_VAR1(m_major);
return m_major;
}
int Firmware::getMinor() const
{
DEB_MEMBER_FUNCT();
DEB_RETURN() << DEB_VAR1(m_minor);
return m_minor;
}
string Firmware::getRelease() const
{
DEB_MEMBER_FUNCT();
DEB_RETURN() << DEB_VAR1(m_rel);
return m_rel;
}
void Firmware::checkValid()
{
DEB_MEMBER_FUNCT();
if (!isValid())
THROW_HW_ERROR(InvalidValue)
<< "Frelon Firmware not fully initialised yet";
}
Model::Model()
{
DEB_CONSTRUCTOR();
reset();
}
Model::~Model()
{
DEB_DESTRUCTOR();
}
void Model::setVersionStr(const std::string& ver)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(ver);
m_firmware.setVersionStr(ver);
}
Firmware& Model::getFirmware()
{
return m_firmware;
}
void Model::setComplexSerialNb(int complex_ser_nb)
{
DEB_MEMBER_FUNCT();
......@@ -48,7 +157,7 @@ void Model::reset()
{
DEB_MEMBER_FUNCT();
m_ver.clear();
m_firmware.reset();
m_complex_ser_nb = 0;
}
......@@ -56,7 +165,7 @@ bool Model::isValid()
{
DEB_MEMBER_FUNCT();
bool valid = (m_complex_ser_nb > 0) && !m_ver.empty();
bool valid = (m_complex_ser_nb > 0) && m_firmware.isValid();
DEB_RETURN() << DEB_VAR1(valid);
return valid;
}
......@@ -145,6 +254,26 @@ bool Model::hasTaper()
return taper;
}
bool Model::hasModesAvail()
{
DEB_MEMBER_FUNCT();
checkValid();
bool avail_modes = (isSPB2() && (m_firmware >= Firmware("2.1b")));
DEB_RETURN() << DEB_VAR1(avail_modes);
return avail_modes;
}
bool Model::hasTimeCalc()
{
DEB_MEMBER_FUNCT();
checkValid();
bool time_calc = (isSPB2() && (m_firmware >= Firmware("2.1b")));
DEB_RETURN() << DEB_VAR1(time_calc);
return time_calc;
}
double Model::getPixelSize()
{
DEB_MEMBER_FUNCT();
......
......@@ -313,7 +313,7 @@ void SerialLine::splitMsg(const string& msg,
for (it = key_list; it != end; ++it) {
const MsgPart& key = it->first;
const string& grp = it->second;
msg_parts[key] = string(match[grp].start, match[grp].end);
msg_parts[key] = match[grp];
}
DEB_RETURN() << DEB_VAR2(msg_parts[MsgSync], msg_parts[MsgCmd]);
......@@ -337,22 +337,19 @@ void SerialLine::decodeFmtResp(const string& ans, string& fmt_resp)
<< DEB_VAR1(ans);
RegEx::SingleMatchType& err = match["err"];
if (err) {
string err_str(err.start, err.end);
THROW_HW_ERROR(Error) << "Frelon Error: " << err_str;
}
if (err.found())
THROW_HW_ERROR(Error) << "Frelon Error: " << string(err);
RegEx::SingleMatchType& warn = match["warn"];
if (warn) {
string warn_str(warn.start, warn.end);
if (warn.found()) {
string warn_str = warn;