Commit 7f045032 authored by Samuel Debionne's avatar Samuel Debionne

Merge branch 'add_frelon16' into 'master'

Frelon16: support MultiLineCmds and dual SPB8 configuration

See merge request !10
parents 6e3a7fe5 dd04b873
Pipeline #8293 passed with stages
in 8 minutes and 50 seconds
......@@ -77,8 +77,12 @@ extern CmdStrMapType CmdStrMap;
enum MultiLineCmd {
Help, Config, Dac, Volt,
Help, Config, Dac, MonitorVolt,
Aoi, PLL, Timing, StatusCam,
SampWeight, ConfigSeq, ConfigSPB, ConfigDLine,
ConfigDAC, ConfigADC, ConfigPLL, ConfigSWeight,
ConfigVCXO, ConfigAlarm, ConfigAoi, UserInfo,
MonitorADC,
};
typedef std::map<MultiLineCmd, std::string> MultiLineCmdStrMapType;
......@@ -160,7 +164,7 @@ enum GeomType {
SPB12_4_Quad,
Hamamatsu,
SPB2_F16,
SPB8_F16_Half,
SPB8_F16_Single,
SPB8_F16_Dual,
};
......
......@@ -111,7 +111,7 @@ class Geometry : public HwMaxImageSizeCallbackGen
protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active);
bool isFrelon16(SPBType spb_type);
bool isFrelon16();
void writeRegister(Reg reg, int val);
void readRegister (Reg reg, int& val);
......@@ -169,12 +169,9 @@ inline bool Geometry::isChanActive(InputChan curr, InputChan chan)
return (curr & chan) == chan;
};
inline bool Geometry::isFrelon16(SPBType spb_type)
inline bool Geometry::isFrelon16()
{
GeomType geom_type = m_model.getGeomType();
return (((geom_type == SPB2_F16) && (spb_type == SPBType2)) ||
(((geom_type == SPB8_F16_Half) ||
(geom_type == SPB8_F16_Dual)) && (spb_type == SPBType8)));
return (m_model.getChipType() == Andanta_CcdFT2k);
}
......
......@@ -126,7 +126,10 @@ class Model
void setCamChar(int cam_char);
void getCamChar(int& cam_char);
void setF16ForceSingle(bool f16_force_single);
void getF16ForceSingle(bool& f16_force_single);
void reset();
bool isValid();
......@@ -151,6 +154,7 @@ class Model
Firmware m_firmware;
int m_complex_ser_nb;
int m_cam_char;
bool m_f16_force_single;
bool m_valid;
SPBType m_spb_type;
......
......@@ -119,7 +119,11 @@ class FrelonAcq:
@DEB_MEMBER_FUNCT
def __init__(self, espia_dev_nb):
def __init__(self, espia_dev_nb, *args, **kws):
espia_dev_nb2 = kws.get('espia_dev_nb2', None)
if len(args) > 0:
espia_dev_nb2 = args[0]
self.m_cam_inited = False
self.m_e2v_corr = None
......@@ -129,11 +133,21 @@ class FrelonAcq:
self.m_bpm_mgr = Tasks.BpmManager()
self.m_bpm_task = Tasks.BpmTask(self.m_bpm_mgr)
self.m_edev = Espia.Dev(espia_dev_nb)
self.m_acq = Espia.Acq(self.m_edev)
self.m_buffer_cb_mgr = Espia.BufferMgr(self.m_acq)
self.m_eserline = Espia.SerialLine(self.m_edev)
self.m_ser_edev = Espia.Dev(espia_dev_nb)
self.m_eserline = Espia.SerialLine(self.m_ser_edev)
self.m_cam = Frelon.Camera(self.m_eserline)
self.m_acq_edev = self.m_ser_edev
model = self.m_cam.getModel()
f16 = (model.getChipType() == Frelon.Andanta_CcdFT2k)
if f16:
if espia_dev_nb2 is not None:
self.m_acq_edev = Espia.Meta([espia_dev_nb, espia_dev_nb2])
else:
model.setF16ForceSingle(True);
self.m_acq = Espia.Acq(self.m_acq_edev)
self.m_buffer_cb_mgr = Espia.BufferMgr(self.m_acq)
self.m_buffer_mgr = BufferCtrlMgr(self.m_buffer_cb_mgr)
self.m_hw_inter = Frelon.Interface(self.m_acq, self.m_buffer_mgr,
self.m_cam)
......@@ -158,7 +172,8 @@ class FrelonAcq:
del self.m_eserline; gc.collect()
del self.m_buffer_cb_mgr; gc.collect()
del self.m_acq; gc.collect()
del self.m_edev; gc.collect()
del self.m_acq_edev; gc.collect()
del self.m_ser_edev; gc.collect()
if self.m_e2v_corr:
del self.m_e2v_corr_update
......@@ -167,8 +182,11 @@ class FrelonAcq:
del self.m_bpm_task; gc.collect()
del self.m_bpm_mgr; gc.collect()
def getEspiaDev(self):
return self.m_edev
def getEspiaSerDev(self):
return self.m_ser_edev
def getEspiaAcqDev(self):
return self.m_acq_edev
def getEspiaAcq(self):
return self.m_acq
......
......@@ -89,8 +89,12 @@ extern CmdStrMapType CmdStrMap;
*/
enum MultiLineCmd {
Help, Config, Dac, Volt,
Help, Config, Dac, MonitorVolt,
Aoi, PLL, Timing, StatusCam,
SampWeight, ConfigSeq, ConfigSPB, ConfigDLine,
ConfigDAC, ConfigADC, ConfigPLL, ConfigSWeight,
ConfigVCXO, ConfigAlarm, ConfigAoi, UserInfo,
MonitorADC,
};
/*
typedef std::map<MultiLineCmd, std::string> MultiLineCmdStrMapType;
......@@ -167,7 +171,7 @@ enum GeomType {
SPB12_4_Quad,
Hamamatsu,
SPB2_F16,
SPB8_F16_Half,
SPB8_F16_Single,
SPB8_F16_Dual,
};
......
......@@ -78,6 +78,9 @@ class Model
void setCamChar(int cam_char);
void getCamChar(int& cam_char /Out/);
void setF16ForceSingle(bool f16_force_single);
void getF16ForceSingle(bool& f16_force_single /Out/);
void reset();
bool isValid();
......
......@@ -153,11 +153,24 @@ static const MLCmdPair MLCmdStrCList[] = {
MLCmdPair(Help, "H"),
MLCmdPair(Config, "C"),
MLCmdPair(Dac, "D"),
MLCmdPair(Volt, "V"),
MLCmdPair(MonitorVolt, "V"),
MLCmdPair(Aoi, "AOI"),
MLCmdPair(PLL, "PLL"),
MLCmdPair(Timing, "TIM"),
MLCmdPair(StatusCam, "STC"),
MLCmdPair(SampWeight, "WGT"),
MLCmdPair(ConfigSeq, "CSEQ"),
MLCmdPair(ConfigSPB, "CSPB"),
MLCmdPair(ConfigDLine, "CDL"),
MLCmdPair(ConfigDAC, "CDAC"),
MLCmdPair(ConfigADC, "CADC"),
MLCmdPair(ConfigPLL, "CPLL"),
MLCmdPair(ConfigSWeight,"CWGT"),
MLCmdPair(ConfigVCXO, "CVCX"),
MLCmdPair(ConfigAlarm, "CALR"),
MLCmdPair(ConfigAoi, "CAOI"),
MLCmdPair(UserInfo, "UINF"),
MLCmdPair(MonitorADC, "RADC"),
};
MultiLineCmdStrMapType
lima::Frelon::MultiLineCmdStrMap(C_LIST_ITERS(MLCmdStrCList));
......
......@@ -111,7 +111,7 @@ void Camera::syncRegs()
case SPB12_4_Quad:
case Hamamatsu:
case SPB2_F16:
case SPB8_F16_Half:
case SPB8_F16_Single:
case SPB8_F16_Dual:
m_geom = new Geometry(*this);
break;
......
......@@ -322,9 +322,10 @@ void Geometry::getMaxFrameDim(FrameDim& max_frame_dim)
ChipType chip_type = m_model.getChipType();
max_frame_dim = ChipMaxFrameDimMap[chip_type];
if (isFrelon16(SPBType2))
GeomType geom_type = m_model.getGeomType();
if (geom_type == SPB2_F16)
max_frame_dim /= Point(2, 2);
else if (isFrelon16(SPBType8))
else if (geom_type == SPB8_F16_Single)
max_frame_dim /= Point(1, 2);
DEB_RETURN() << DEB_VAR1(max_frame_dim);
......@@ -361,7 +362,7 @@ void Geometry::checkFlip(Flip& flip)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(flip);
if (isFrelon16(SPBType2) || isFrelon16(SPBType8)) {
if (isFrelon16()) {
DEB_TRACE() << "No flip is supported";
flip = Flip(false);
} else {
......@@ -395,7 +396,7 @@ void Geometry::checkBin(Bin& bin)
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(bin);
bool frelon16 = (isFrelon16(SPBType2) || isFrelon16(SPBType8));
bool frelon16 = (isFrelon16());
int max_bin_x = frelon16 ? 1 : int(MaxBinX);
int max_bin_y = frelon16 ? 1 : int(MaxBinY);
int bin_x = min(bin.getX(), max_bin_x);
......@@ -494,7 +495,7 @@ Flip Geometry::getMirror()
Flip mirror;
mirror.x = isChanActive(curr, Chan12) || isChanActive(curr, Chan34);
mirror.y = isChanActive(curr, Chan13) || isChanActive(curr, Chan24);
if (isFrelon16(SPBType2) || isFrelon16(SPBType8))
if (isFrelon16())
mirror = Flip(false);
DEB_RETURN() << DEB_VAR1(mirror);
return mirror;
......@@ -935,7 +936,7 @@ void Geometry::getReadoutTime(double& readout_time)
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "readout time calculation";
if (isFrelon16(SPBType2) || isFrelon16(SPBType8)) {
if (isFrelon16()) {
readout_time = 100e-3;
} else {
readFloatRegister(ReadoutTime, readout_time);
......@@ -951,7 +952,7 @@ void Geometry::getTransferTime(double& xfer_time)
THROW_HW_ERROR(NotSupported) << "Camera does not have "
<< "shift time calculation";
if (isFrelon16(SPBType2) || isFrelon16(SPBType8)) {
if (isFrelon16()) {
xfer_time = 100e-3;
} else {
readFloatRegister(TransferTime, xfer_time);
......
......@@ -811,6 +811,15 @@ Interface::Interface(Espia::Acq& acq, BufferCtrlMgr& buffer_mgr,
{
DEB_CONSTRUCTOR();
bool f16_dual = (m_cam.getModel().getGeomType() == SPB8_F16_Dual);
if (f16_dual != m_acq.getDev().isMeta())
THROW_HW_ERROR(Error) << "Frelon16 2xSPB8 / Espia mismatch";
Espia::SGImgConfig img_config = (f16_dual ? Espia::SGImgConcatVert2 :
Espia::SGImgNorm);
FrameDim det_frame_dim;
m_cam.getFrameDim(det_frame_dim);
m_acq.setSGImgConfig(img_config, det_frame_dim.getSize());
m_acq.registerAcqEndCallback(m_acq_end_cb);
m_acq.registerEventCallback(m_event_cb);
......
......@@ -139,6 +139,7 @@ void Firmware::checkValid()
}
Model::Model()
: m_f16_force_single(false)
{
DEB_CONSTRUCTOR();
......@@ -197,6 +198,22 @@ void Model::getCamChar(int& cam_char)
DEB_RETURN() << DEB_VAR1(DEB_HEX(cam_char));
}
void Model::setF16ForceSingle(bool f16_force_single)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(f16_force_single);
m_f16_force_single = f16_force_single;
update();
}
void Model::getF16ForceSingle(bool& f16_force_single)
{
DEB_MEMBER_FUNCT();
f16_force_single = m_f16_force_single;
DEB_RETURN() << DEB_VAR1(f16_force_single);
}
void Model::reset()
{
DEB_MEMBER_FUNCT();
......@@ -204,6 +221,7 @@ void Model::reset()
m_firmware.reset();
m_complex_ser_nb = 0;
m_cam_char = 0;
update();
}
......@@ -251,6 +269,10 @@ void Model::update()
if (has(CamChar) && m_cam_char) {
int type_bits = (m_cam_char >> 8) & SPBConXY;
SPBConType spb_con_type = SPBConType(type_bits);
if ((spb_con_type == SPBConXY) && m_f16_force_single) {
DEB_TRACE() << "Limiting to single SPB8";
spb_con_type = SPBConX;
}
if (spb_con_type != SPBConNone)
m_spb_con_type = spb_con_type;
}
......@@ -367,7 +389,7 @@ GeomType Model::getGeomType()
THROW_HW_ERROR(Error) << "SPB8 only supports Frelon16";
SPBConType spb_con_type = getSPBConType();
bool dual_spb = (spb_con_type == SPBConXY);
geom_type = dual_spb ? SPB8_F16_Dual : SPB8_F16_Half;
geom_type = dual_spb ? SPB8_F16_Dual : SPB8_F16_Single;
}
DEB_RETURN() << DEB_VAR1(geom_type);
......
......@@ -42,7 +42,7 @@
import time, string
import PyTango
from Lima import Core
from Lima import Frelon as FrelonAcq
from Lima import Frelon as FrelonHw
from Lima.Server import AttrHelper
class Frelon(PyTango.Device_4Impl):
......@@ -56,34 +56,35 @@ class Frelon(PyTango.Device_4Impl):
def __init__(self,*args) :
PyTango.Device_4Impl.__init__(self,*args)
self.__ImageMode = {'FRAME TRANSFER': FrelonAcq.FTM,
'FULL FRAME': FrelonAcq.FFM}
self.__ImageMode = {'FRAME TRANSFER': FrelonHw.FTM,
'FULL FRAME': FrelonHw.FFM}
self.__RoiMode = {'NONE' : 0,
'SLOW' : FrelonAcq.Slow,
'FAST' : FrelonAcq.Fast,
'KINETIC' : FrelonAcq.Kinetic}
self.__RoiMode = {'NONE' : FrelonHw.None,
'SLOW' : FrelonHw.Slow,
'FAST' : FrelonHw.Fast,
'KINETIC' : FrelonHw.Kinetic}
self.__InputChannel = {'1' : 0x1,
'2' : 0x2,
'3' : 0x4,
'4' : 0x8,
'1-2' : 0x3,
'3-4' : 0xc,
'1-3' : 0x5,
'2-4' : 0xA,
'1-2-3-4' : 0xf}
self.__InputChannel = {'1' : FrelonHw.Chan1,
'2' : FrelonHw.Chan2,
'3' : FrelonHw.Chan3,
'4' : FrelonHw.Chan4,
'1-2' : FrelonHw.Chan12,
'3-4' : FrelonHw.Chan34,
'1-3' : FrelonHw.Chan13,
'2-4' : FrelonHw.Chan24,
'1-2-3-4' : FrelonHw.Chan1234}
self.__E2VCorrection = {'ON' : True,
'OFF' : False}
self.__Spb2Config = {'PRECISION' : 0,
'SPEED' : 1}
self.__Spb2Config = {'PRECISION' : FrelonHw.SPB2Precision,
'SPEED' : FrelonHw.SPB2Speed}
self.__Attribute2FunctionBase = {'image_mode' : 'FrameTransferMode',
'input_channel' : 'InputChan',
'e2v_correction' : 'E2VCorrectionActive',
'spb2_config' : 'SPB2Config'}
'spb2_config' : 'SPB2Config',
'seq_status' : 'Status'}
self.init_device()
......@@ -107,7 +108,9 @@ class Frelon(PyTango.Device_4Impl):
return AttrHelper.get_attr_string_value_list(self, attr_name)
def __getattr__(self,name) :
return AttrHelper.get_attr_4u(self, name, _FrelonAcq)
obj = _FrelonAcq if name == 'E2VCorrectionActive' \
else _FrelonAcq.getFrelonCamera()
return AttrHelper.get_attr_4u(self, name, obj)
@Core.DEB_MEMBER_FUNCT
def execSerialCommand(self, command_string) :
......@@ -115,7 +118,8 @@ class Frelon(PyTango.Device_4Impl):
@Core.DEB_MEMBER_FUNCT
def resetLink(self) :
_FrelonAcq.getEspiaDev().resetLink()
edev = _FrelonAcq.getEspiaDev()
edev.resetLink()
time.sleep(self.ResetLinkWaitTime)
## @brief read the espia board id
......@@ -127,29 +131,18 @@ class Frelon(PyTango.Device_4Impl):
attr.set_value(espia_dev_nb)
def read_roi_bin_offset(self,attr) :
roi_bin_offset = _FrelonAcq.getRoiBinOffset()
cam = _FrelonAcq.getFrelonCamera()
roi_bin_offset = cam.getRoiBinOffset()
attr.set_value(roi_bin_offset.y)
def write_roi_bin_offset(self,attr) :
roi_bin_offset = Core.Point(0, attr.get_write_value())
_FrelonAcq.setRoiBinOffset(roi_bin_offset)
def read_seq_status(self,attr) :
seq_status = _FrelonAcq.getCcdStatus()
attr.set_value(seq_status)
def read_readout_time(self,attr):
cam = _FrelonAcq.getFrelonCamera()
readout_time = cam.getReadoutTime()
attr.set_value(readout_time)
def read_transfer_time(self,attr):
cam = _FrelonAcq.getFrelonCamera()
transfer_time = cam.getTransferTime()
attr.set_value(transfer_time)
cam.setRoiBinOffset(roi_bin_offset)
def read_camera_serial(self,attr):
serial = _FrelonAcq.m_cam.getModel().getSerialNb()
model = _FrelonAcq.getCameraModel()
serial = model.getSerialNb()
attr.set_value("%d" % serial)
class FrelonClass(PyTango.DeviceClass):
......@@ -302,15 +295,18 @@ class FrelonTacoProxy:
kin_win_size, kin_line_beg, kin_stripes = self.getKinPars()
flip_mode, kin_line_beg, kin_stripes, d0, roi_mode_int = hw_par
flip = Core.Flip(flip_mode >> 1, flip_mode & 1)
_FrelonAcq.setFlip(flip)
roi_mode = FrelonAcq.RoiMode(roi_mode_int)
_FrelonAcq.setRoiMode(roi_mode)
if roi_mode == FrelonAcq.Kinetic:
control = _FrelonAcq.getGlobalControl()
ct_image = control.image()
ct_image.setFlip(flip)
roi_mode = FrelonHw.RoiMode(roi_mode_int)
cam = _FrelonAcq.getFrelonCamera()
cam.setRoiMode(roi_mode)
if roi_mode == FrelonHw.Kinetic:
max_frame_dim = _FrelonAcq.getFrameDim(max_dim=True)
frame_height = max_frame_dim.getSize().getHeight()
if kin_line_beg + kin_win_size > frame_height:
kin_win_size = frame_height - kin_line_beg
bin_y = _FrelonAcq.getBin().getY()
bin_y = self.getBin().getY()
kin_win_size = (kin_win_size / bin_y) * bin_y
deb.Trace('Re-adjusting kin_win_size to %d to fit chip' %
kin_win_size)
......@@ -320,9 +316,12 @@ class FrelonTacoProxy:
@Core.DEB_MEMBER_FUNCT
def DevCcdGetHwPar(self):
flip = _FrelonAcq.getFlip()
control = _FrelonAcq.getGlobalControl()
ct_image = control.image()
flip = ct_image.getFlip()
flip_mode = flip.x << 1 | flip.y
roi_mode = _FrelonAcq.getRoiMode()
cam = _FrelonAcq.getFrelonCamera()
roi_mode = cam.getRoiMode()
kin_win_size, kin_line_beg, kin_stripes = self.getKinPars()
hw_par = [flip_mode, kin_line_beg, kin_stripes, 0, roi_mode]
deb.Return('Getting hw par: %s' % hw_par)
......@@ -333,9 +332,9 @@ class FrelonTacoProxy:
def DevCcdSetKinetics(self, kinetics):
deb.Param('Setting the profile: %s' % kinetics)
if kinetics == 0:
ftm = FrelonAcq.FFM
ftm = FrelonHw.FFM
elif kinetics == 3:
ftm = FrelonAcq.FTM
ftm = FrelonHw.FTM
else:
raise Core.Exception('Invalid profile value: %s' % kinetics)
_FrelonAcq.setFrameTransferMode(ftm)
......@@ -343,7 +342,7 @@ class FrelonTacoProxy:
@Core.DEB_MEMBER_FUNCT
def DevCcdGetKinetics(self):
ftm = _FrelonAcq.getFrameTransferMode()
if ftm == FrelonAcq.FTM:
if ftm == FrelonHw.FTM:
kinetics = 3
else:
kinetics = 0
......@@ -370,7 +369,7 @@ class FrelonTacoProxy:
if kin_stripes > 1:
deb.Warning('Ignoring kin_stripes=%d' % kin_stripes)
bin = _FrelonAcq.getBin()
bin = self.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()
......@@ -388,7 +387,7 @@ class FrelonTacoProxy:
@Core.DEB_MEMBER_FUNCT
def getKinPars(self):
bin = _FrelonAcq.getBin()
bin = self.getBin()
roi = _FrelonAcq.getRoi()
roi = roi.getUnbinned(bin)
kin_win_size = roi.getSize().getHeight()
......@@ -399,6 +398,14 @@ class FrelonTacoProxy:
(kin_win_size, kin_line_beg, kin_stripes))
return kin_win_size, kin_line_beg, kin_stripes
@Core.DEB_MEMBER_FUNCT
def getBin(self):
control = _FrelonAcq.getGlobalControl()
ct_image = control.image()
bin = ct_image.getBin()
deb.Return('Getting binning: %s' % bin)
return bin
@Core.DEB_MEMBER_FUNCT
def DevCcdCommand(self, cmd):
return _FrelonAcq.execFrelonSerialCmd(cmd)
......@@ -424,7 +431,7 @@ _FrelonAcq = None
def get_control(espia_dev_nb = 0,**keys) :
global _FrelonAcq
if _FrelonAcq is None:
_FrelonAcq = FrelonAcq.FrelonAcq(int(espia_dev_nb))
_FrelonAcq = FrelonHw.FrelonAcq(int(espia_dev_nb))
return _FrelonAcq.getGlobalControl()
def get_tango_specific_class_n_device():
......
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