Commit dd2b1d2b authored by Laurent Claustre's avatar Laurent Claustre
Browse files

Merge branch '4-export-tucam-trigger-mode-and-trigger-edge' into 'master'

Resolve "export Tucam trigger mode and trigger edge"

Closes #4

See merge request !4
parents ac228e50 12327169
Pipeline #51750 passed with stages
in 14 minutes and 1 second
......@@ -70,6 +70,40 @@ public:
Ready, Exposure, Readout, Latency, Fault
} ;
enum TucamTriggerMode
{
TriggerStandard = TUCCM_TRIGGER_STANDARD,
TriggerSynchronous = TUCCM_TRIGGER_SYNCHRONOUS,
TriggerGlobal = TUCCM_TRIGGER_GLOBAL,
//TriggerSoftware = TUCCM_TRIGGER_SOFTWARE, do not map, this mode is used for Lima IntTrigSingle and Timer to retrig
};
enum TucamTriggerEdge
{
EdgeRising = TUCTD_RISING,
EdgeFalling = TUCTD_FAILING,
};
enum TucamSignal
{
SignalTrigIn = TUOPT_IN, //copy of the trigger IN
SignalStart = TUOPT_EXPSTART, // Exposure start (rolling)
SignalGlobal = TUOPT_EXPGLOBAL, // Global exposure
SignalReadEnd = TUOPT_READEND // readout end
};
enum TucamSignalEdge
{
SignalEdgeRising = TUOPT_RISING,
SignalEdgeFalling = TUOPT_FAILING,
};
enum TucamGain
{
GainHDR = TUGAIN_HDR,
GainHigh = TUGAIN_HIGH,
GainLow = TUGAIN_LOW
};
Camera(unsigned short timer_period_ms);
virtual ~Camera();
......@@ -129,33 +163,30 @@ public:
void getTemperature(double& temp);
void setFanSpeed(unsigned speed);
void getFanSpeed(unsigned& speed);
void setGlobalGain(unsigned gain);
void getGlobalGain(unsigned& gain);
void setGlobalGain(TucamGain gain);
void getGlobalGain(TucamGain& gain);
void getTucamVersion(std::string& version);
void getFirmwareVersion(std::string& version);
void getTriggerMode(TucamTriggerMode& mode){mode = m_tucam_trigger_mode;};
void setTriggerMode(TucamTriggerMode mode){m_tucam_trigger_mode = mode;};
void getTriggerEdge(TucamTriggerEdge& edge){edge = m_tucam_trigger_edge_mode;};
void setTriggerEdge(TucamTriggerEdge edge){m_tucam_trigger_edge_mode = edge;};
void getOutputSignal(int port, TucamSignal& signal, TucamSignalEdge& edge, int& delay, int& width);
void setOutputSignal(int port, TucamSignal signal, TucamSignalEdge edge=SignalEdgeRising, int delay=-1, int width=-1);
bool isAcqRunning() const;
//TUCAM stuff, use TUCAM notations !
TUCAM_INIT m_itApi; // TUCAM handle Api
TUCAM_OPEN m_opCam; // TUCAM handle camera
TUCAM_FRAME m_frame; // TUCAM frame structure
pthread_cond_t m_hThdEvent; // TUCAM handle event
//TUCAM stuff, use TUCAM notations !
TUCAM_INIT m_itApi; // TUCAM handle Api
TUCAM_OPEN m_opCam; // TUCAM handle camera
TUCAM_FRAME m_frame; // TUCAM frame structure
pthread_cond_t m_hThdEvent; // TUCAM handle event
bool m_signalled;
private:
//read/copy frame
bool readFrame(void *bptr, int& frame_nb);
void setStatus(Camera::Status status, bool force);
inline bool IS_POWER_OF_2(long x)
{
if( ((x ^ (x - 1)) == x + (x - 1)) && (x != 0) )
{
return true;
}
else
{
return false;
}
}
pthread_mutex_t m_hThdLock;
//////////////////////////////
......@@ -180,10 +211,13 @@ private:
Bin m_bin;
double m_temperature_target;
bool m_prepared;
bool m_cold_start;
TucamTriggerMode m_tucam_trigger_mode;
TucamTriggerEdge m_tucam_trigger_edge_mode;
// Buffer control object
SoftBufferCtrlObj m_bufferCtrlObj;
CSoftTriggerTimer* m_internal_trigger_timer;
unsigned short m_timer_period_ms;
unsigned short m_timer_period_ms;
} ;
......
......@@ -12,6 +12,41 @@ namespace Dhyana
Ready, Exposure, Readout, Latency, Fault
} ;
enum TucamTriggerMode
{
TriggerStandard = TUCCM_TRIGGER_STANDARD,
TriggerSynchronous = TUCCM_TRIGGER_SYNCHRONOUS,
TriggerGlobal = TUCCM_TRIGGER_GLOBAL,
//TriggerSoftware = TUCCM_TRIGGER_SOFTWARE, do not map, this mode is used for Lima IntTrigSingle and Timer to retrig
};
enum TucamTriggerEdge
{
EdgeRising = TUCTD_RISING,
EdgeFalling = TUCTD_FAILING,
};
enum TucamSignal
{
SignalTrigIn = TUOPT_IN, //copy of the trigger IN
SignalStart = TUOPT_EXPSTART, // Exposure start (rolling)
SignalGlobal = TUOPT_EXPGLOBAL, // Global exposure
SignalReadEnd = TUOPT_READEND // readout end
};
enum TucamSignalEdge
{
SignalEdgeRising = TUOPT_RISING,
SignalEdgeFalling = TUOPT_FAILING,
};
enum TucamGain
{
GainHDR = TUGAIN_HDR,
GainHigh = TUGAIN_HIGH,
GainLow = TUGAIN_LOW
};
Camera(unsigned short timer_period_ms);
virtual ~Camera();
......@@ -69,10 +104,17 @@ namespace Dhyana
void getTemperature(double& temp /Out/);
void setFanSpeed(unsigned speed);
void getFanSpeed(unsigned& speed /Out/);
void setGlobalGain(unsigned gain);
void getGlobalGain(unsigned& gain /Out/);
void setGlobalGain(TucamGain gain);
void getGlobalGain(TucamGain& gain /Out/);
void getTucamVersion(std::string& version /Out/);
void getFirmwareVersion(std::string& version /Out/);
void getTriggerMode(TucamTriggerMode& mode /Out/);
void setTriggerMode(TucamTriggerMode mode);
void getTriggerEdge(TucamTriggerEdge& edge /Out/);
void setTriggerEdge(TucamTriggerEdge edge);
void getOutputSignal(int port, TucamSignal& signal, TucamSignalEdge& edge, int& delay, int& width);
void setOutputSignal(int port, TucamSignal signal, TucamSignalEdge edge=SignalEdgeRising, int delay=-1, int width=-1);
bool isAcqRunning() const;
};
};
\ No newline at end of file
......@@ -49,9 +49,11 @@ m_status(Ready),
m_acq_frame_nb(0),
m_temperature_target(0),
m_timer_period_ms(timer_period_ms),
m_prepared(false)
m_prepared(false),
m_tucam_trigger_mode(TriggerStandard),
m_tucam_trigger_edge_mode(EdgeRising),
m_cold_start(true)
{
DEB_CONSTRUCTOR();
//Init TUCAM
init();
......@@ -145,20 +147,67 @@ void Camera::prepareAcq()
Timestamp t0 = Timestamp::now();
if (!m_prepared)
{
if (m_cold_start)
{
//At cold start we must trig a fake capture, otherwise the camera will never capture frames
m_cold_start = false;
DEB_TRACE() << "Cold start";
TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_SOFTWARE);
TUCAM_Cap_Stop(m_opCam.hIdxTUCam);
}
m_frame.pBuffer = NULL;
m_frame.ucFormatGet = TUFRM_FMT_RAW;
m_frame.uiRsdSize = 1;// how many frames do you want
// Alloc buffer after set resolution or set ROI attribute
DEB_TRACE() << "TUCAM_Buf_Alloc";
TUCAM_Buf_Alloc(m_opCam.hIdxTUCam, &m_frame);
if(TUCAMRET_SUCCESS != TUCAM_Buf_Alloc(m_opCam.hIdxTUCam, &m_frame))
{
THROW_HW_ERROR(Error) << "Buff_Alloc failed";
}
m_prepared = true;
Timestamp t1 = Timestamp::now();
double delta_time = t1 - t0;
DEB_TRACE() << "Buff_Alloc = " << (int) (delta_time * 1000) << " (ms)";
t0 = t1;
}
TUCAM_TRIGGER_ATTR tgrAttr;
if (TUCAMRET_SUCCESS != TUCAM_Cap_GetTrigger(m_opCam.hIdxTUCam, &tgrAttr))
{
THROW_HW_ERROR(Error) << "Cap_GetTrigger failed";
}
tgrAttr.nTgrMode = -1;//NOT DEFINED (see below)
tgrAttr.nFrames = 1;
tgrAttr.nDelayTm = 0;
tgrAttr.nExpMode = -1;//NOT DEFINED (see below)
tgrAttr.nEdgeMode = m_tucam_trigger_edge_mode;
switch(m_trigger_mode)
{
case IntTrig:
tgrAttr.nTgrMode = TUCCM_TRIGGER_SOFTWARE;
tgrAttr.nExpMode = TUCTE_EXPTM;
break;
case ExtTrigMult :
tgrAttr.nTgrMode = m_tucam_trigger_mode;
tgrAttr.nExpMode = TUCTE_EXPTM;
break;
case ExtGate:
tgrAttr.nTgrMode = m_tucam_trigger_mode;
tgrAttr.nExpMode = TUCTE_WIDTH;
break;
case ExtTrigSingle :
tgrAttr.nFrames = m_nb_frames;
tgrAttr.nTgrMode = m_tucam_trigger_mode;
tgrAttr.nExpMode = TUCTE_EXPTM;
break;
}
if(TUCAMRET_SUCCESS != TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr))
{
THROW_HW_ERROR(Error) << "Cap_SetTrigger failed";
}
DEB_TRACE() << "TUCAM_Cap_SetTrigger : " << m_trigger_mode << ", " << tgrAttr.nTgrMode << ", " << tgrAttr.nExpMode;
}
//-----------------------------------------------------
......@@ -176,31 +225,21 @@ void Camera::startAcq()
if(m_trigger_mode == IntTrig)
{
// Start capture in software trigger
TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_SOFTWARE);
}
else if(m_trigger_mode == ExtTrigSingle)
{
TUCAM_TRIGGER_ATTR tgrAttr;
tgrAttr.nDelayTm = 0;
tgrAttr.nEdgeMode = TUCTD_RISING;
tgrAttr.nFrames = m_nb_frames;
tgrAttr.nTgrMode = TUCCM_TRIGGER_STANDARD;
tgrAttr.nExpMode = TUCTE_EXPTM;
TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr);
// Start capture in external trigger single (EXPOSURE SOFT)
TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_STANDARD);
}
else if(m_trigger_mode == ExtTrigMult)
{
// Start capture in external trigger STANDARD (EXPOSURE SOFT)
TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_STANDARD);
}
else if(m_trigger_mode == ExtGate)
if(TUCAMRET_SUCCESS !=TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_SOFTWARE))
{
THROW_HW_ERROR(Error) << "Cap_SetTrigger failed";
}
}
else
{
// Start capture in external trigger STANDARD (EXPOSURE WIDTH)
TUCAM_Cap_Start(m_opCam.hIdxTUCam, TUCCM_TRIGGER_STANDARD);
if(TUCAMRET_SUCCESS !=TUCAM_Cap_Start(m_opCam.hIdxTUCam, m_tucam_trigger_mode))
{
THROW_HW_ERROR(Error) << "Cap_SetTrigger failed";
}
}
// Cap_Start is not synchronous enough with the real camera status, so the camera can miss the trigger
usleep(1e5);
////DEB_TRACE() << "TUCAM CreateEvent";
pthread_cond_init(&m_hThdEvent, NULL);
......@@ -582,8 +621,8 @@ void Camera::getPixelSize(double& sizex, double& sizey)
{
DEB_MEMBER_FUNCT();
//@BEGIN : Get Pixels size in micron from Driver/API
sizex = PIXEL_SIZE_WIDTH_MICRON;
sizey = PIXEL_SIZE_HEIGHT_MICRON;
sizex = PIXEL_SIZE_WIDTH_MICRON*1e-6;
sizey = PIXEL_SIZE_HEIGHT_MICRON*1e-6;
//@END
}
......@@ -630,45 +669,7 @@ void Camera::setTrigMode(TrigMode mode)
DEB_TRACE() << "setTrigMode() " << DEB_VAR1(mode);
DEB_PARAM() << DEB_VAR1(mode);
//@BEGIN
TUCAM_TRIGGER_ATTR tgrAttr;
tgrAttr.nTgrMode = -1;//NOT DEFINED (see below)
tgrAttr.nFrames = 1;
tgrAttr.nDelayTm = 0;
tgrAttr.nExpMode = -1;//NOT DEFINED (see below)
tgrAttr.nEdgeMode = TUCTD_RISING;
switch(mode)
{
case IntTrig:
tgrAttr.nTgrMode = TUCCM_TRIGGER_SOFTWARE;
tgrAttr.nExpMode = TUCTE_EXPTM;
TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr);
DEB_TRACE() << "TUCAM_Cap_SetTrigger : TUCCM_TRIGGER_SOFTWARE (EXPOSURE SOFTWARE)";
break;
case ExtTrigMult :
tgrAttr.nTgrMode = TUCCM_TRIGGER_STANDARD;
tgrAttr.nExpMode = TUCTE_EXPTM;
TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr);
DEB_TRACE() << "TUCAM_Cap_SetTrigger : TUCCM_TRIGGER_STANDARD (EXPOSURE SOFTWARE: "<<tgrAttr.nExpMode<<")";
break;
case ExtGate:
tgrAttr.nTgrMode = TUCCM_TRIGGER_STANDARD;
tgrAttr.nExpMode = TUCTE_WIDTH;
TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr);
DEB_TRACE() << "TUCAM_Cap_SetTrigger : TUCCM_TRIGGER_STANDARD (EXPOSURE TRIGGER WIDTH: "<<tgrAttr.nExpMode<<")";
break;
case ExtTrigSingle :
tgrAttr.nFrames = m_nb_frames;
tgrAttr.nTgrMode = TUCCM_TRIGGER_STANDARD;
tgrAttr.nExpMode = TUCTE_EXPTM;
TUCAM_Cap_SetTrigger(m_opCam.hIdxTUCam, tgrAttr);
DEB_TRACE() << "TUCAM_Cap_SetTrigger : TUCCM_TRIGGER_STANDARD (EXPOSURE SOFTWARE: "<<tgrAttr.nExpMode<<")";
break;
case IntTrigMult:
case ExtTrigReadout:
default:
THROW_HW_ERROR(NotSupported) << DEB_VAR1(mode);
}
m_trigger_mode = mode;
//@END
......@@ -1064,15 +1065,10 @@ void Camera::getFanSpeed(unsigned& speed)
//-----------------------------------------------------
//
//-----------------------------------------------------
void Camera::setGlobalGain(unsigned gain)
void Camera::setGlobalGain(TucamGain gain)
{
DEB_MEMBER_FUNCT();
if(gain != 0 && gain != 1 && gain != 2)
{
THROW_HW_ERROR(Error) << "Available gain values are : 0:HDR\n1:HIGH\n2: LOW !";
}
double dbVal = (double) gain;
if(TUCAMRET_SUCCESS != TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_GLOBALGAIN, dbVal))
{
......@@ -1083,7 +1079,7 @@ void Camera::setGlobalGain(unsigned gain)
//-----------------------------------------------------
//
//-----------------------------------------------------
void Camera::getGlobalGain(unsigned& gain)
void Camera::getGlobalGain(TucamGain& gain)
{
DEB_MEMBER_FUNCT();
......@@ -1092,7 +1088,7 @@ void Camera::getGlobalGain(unsigned& gain)
{
THROW_HW_ERROR(Error) << "Unable to Read TUIDP_GLOBALGAIN from the camera !";
}
gain = (unsigned) dbVal;
gain = (TucamGain)dbVal;
}
//-----------------------------------------------------
......@@ -1123,8 +1119,49 @@ void Camera::getFirmwareVersion(std::string& version)
THROW_HW_ERROR(Error) << "Unable to Read TUIDI_VERSION_FRMW from the camera !";
}
version = valInfo.nValue;
version = valInfo.pText;
}
//-----------------------------------------------------
//
//-----------------------------------------------------
void Camera::setOutputSignal(int port, TucamSignal signal, TucamSignalEdge edge, int delay, int width)
{
DEB_MEMBER_FUNCT();
TUCAM_TRGOUT_ATTR tgroutAttr;
if (port <0 || port >2)
{
THROW_HW_ERROR(Error) << "Invalid output port number range is [0-2]";
}
tgroutAttr.nTgrOutPort = port;
tgroutAttr.nTgrOutMode = (int)signal;
tgroutAttr.nEdgeMode = (int)edge;
tgroutAttr.nDelayTm = delay;
tgroutAttr.nWidth = width;
if(TUCAMRET_SUCCESS != TUCAM_Cap_SetTriggerOut (m_opCam.hIdxTUCam, tgroutAttr))
{
THROW_HW_ERROR(Error) << "Unable to set Output signal port "<< port;
}
}
void Camera::getOutputSignal(int port, TucamSignal& signal, TucamSignalEdge& edge, int& delay, int& width)
{
DEB_MEMBER_FUNCT();
TUCAM_TRGOUT_ATTR tgroutAttr;
tgroutAttr.nTgrOutPort = port;
if(TUCAMRET_SUCCESS != TUCAM_Cap_GetTriggerOut (m_opCam.hIdxTUCam, &tgroutAttr))
{
THROW_HW_ERROR(Error) << "Unable to get Output signal port "<< port;
}
signal = (TucamSignal) tgroutAttr.nTgrOutMode;
edge = (TucamSignalEdge)tgroutAttr.nEdgeMode;
delay = tgroutAttr.nDelayTm;
width =tgroutAttr.nWidth;
}
......@@ -14,7 +14,18 @@ class Dhyana(PyTango.Device_4Impl):
#------------------------------------------------------------------
def __init__(self,*args) :
PyTango.Device_4Impl.__init__(self,*args)
# dictionnaries to be used with AttrHelper.get_attr_4u
self.__TriggerMode = {'STANDARD': _DhyanaCam.TriggerStandard,
'GLOBAL': _DhyanaCam.TriggerGlobal,
'SYNCHRONOUS': _DhyanaCam.TriggerSynchronous
}
self.__TriggerEdge = {'RISING': _DhyanaCam.EdgeRising,
'FALLING': _DhyanaCam.EdgeFalling
}
self.__GlobalGain = {'HDR': _DhyanaCam.GainHDR,
'HIGH': _DhyanaCam.GainHigh,
'LOW': _DhyanaCam.GainLow
}
# self.__Attribute2FunctionBase = {
# }
......@@ -36,6 +47,10 @@ class Dhyana(PyTango.Device_4Impl):
if self.temperature_target:
_DhyanaCam.setTemperatureTarget(self.temperature_target)
if self.trigger_mode:
_DhyanaCam.setTriggerMode(self.__TriggerMode[self.trigger_mode.upper()])
if self.trigger_edge:
_DhyanaCam.setTriggerEdge(self.__TriggerEdge[self.trigger_edge.upper()])
#------------------------------------------------------------------
# getAttrStringValueList command:
......@@ -73,6 +88,12 @@ class DhyanaClass(PyTango.DeviceClass):
'temperature_target':
[PyTango.DevDouble,
"Temperature set point", -10],
'trigger_mode':
[PyTango.DevString,
"Tucam trigger mode", "STANDARD"],
'trigger_edge':
[PyTango.DevString,
"trigger edge", "RISING"],
}
cmd_list = {
......@@ -119,11 +140,11 @@ class DhyanaClass(PyTango.DeviceClass):
'description': 'Temperature target',
}],
'global_gain':
[[PyTango.DevUShort,
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE],
{
'unit': 'C',
'unit': 'n/a',
'format': '',
'description': 'Global gain setting',
}],
......@@ -136,6 +157,24 @@ class DhyanaClass(PyTango.DeviceClass):
'format': '',
'description': 'FAN speed',
}],
'trigger_mode':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE],
{
'unit': 'mode',
'format': '',
'description': 'Tucam trigger mode (standard, global or synchronize)',
}],
'trigger_edge':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE],
{
'unit': 'edge',
'format': '',
'description': 'Detection edge mode, rising or falling',
}],
}
......
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