Commit e151726b authored by ahoms's avatar ahoms
Browse files

* added Espia acq start/stop/status, with generic cb dispatcher

  and last frame retrieval through (thread safe) last frame callback


git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@55 45c4679d-1946-429d-baad-37912b19538b
parent 55fd8a23
......@@ -3,7 +3,8 @@
#include "SizeUtils.h"
#include "Exceptions.h"
#include "HwFrameInfo.h"
#include "ThreadUtils.h"
#include "HwFrameCallback.h"
#include "espia_lib.h"
......@@ -16,10 +17,19 @@ class Espia
{
public:
enum {
Invalid = -1,
Invalid = SCDXIPCI_INVALID,
NoBlock = SCDXIPCI_NO_BLOCK,
BlockForever = SCDXIPCI_BLOCK_FOREVER,
};
Espia(int dev_nr);
typedef struct AcqStatus {
bool acq_started;
bool acq_running;
int acq_run_nb;
int last_acq_frame_nb;
} AcqStatusType;
Espia(int dev_nb);
~Espia();
void bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
......@@ -34,6 +44,15 @@ class Espia
void *getAcqFramePtr(int acq_frame_nb);
void getFrameInfo(int acq_frame_nb, HwFrameInfoType& info);
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void startAcq();
void stopAcq();
void getAcqStatus(AcqStatusType& acq_status);
void getStartTimestamp(Timestamp& start_ts);
void serWrite(const std::string& buffer,
int block_size = 0, double block_delay = 0,
bool no_wait = false);
......@@ -46,7 +65,7 @@ class Espia
int line);
private:
void open(int dev_nr);
void open(int dev_nb);
void close();
unsigned long sec2usec(double sec);
double usec2sec(unsigned long usec);
......@@ -59,14 +78,31 @@ class Espia
void real2virtFrameInfo(const struct img_frame_info& real_info,
HwFrameInfoType& virt_info);
void resetFrameInfo(struct img_frame_info& frame_info);
int m_dev_nr;
static int cbDispatch(struct espia_cb_data *cb_data);
void registerLastFrameCb();
void unregisterLastFrameCb();
void lastFrameCb(struct espia_cb_data *cb_data);
AutoMutex acqLock();
int m_dev_nb;
espia_t m_dev;
FrameDim m_frame_dim;
int m_nb_buffers;
int m_buffer_frames;
int m_real_frame_factor;
int m_real_frame_size;
Mutex m_acq_mutex;
int m_nb_frames;
bool m_started;
Timestamp m_start_ts;
struct img_frame_info m_last_frame_info;
int m_last_frame_cb_nr;
};
#define ESPIA_CHECK_CALL(ret) \
......@@ -114,6 +150,16 @@ inline int Espia::virtFrameNb (int real_buffer, int real_frame)
return real_frame % m_buffer_frames;
}
inline void Espia::getStartTimestamp(Timestamp& start_ts)
{
start_ts = m_start_ts;
}
inline AutoMutex Espia::acqLock()
{
return AutoMutex(m_acq_mutex, AutoMutex::Locked);
}
} // namespace lima
#endif // ESPIA_H
......@@ -9,15 +9,22 @@ using namespace std;
#define ESPIA_MIN_BUFFER_SIZE (128 * 1024)
Espia::Espia(int dev_nr)
Espia::Espia(int dev_nb)
{
m_dev_nr = Invalid;
m_dev_nb = Invalid;
m_dev = ESPIA_DEV_INVAL;
m_nb_buffers = m_buffer_frames = 0;
m_real_frame_factor = m_real_frame_size = 0;
open(dev_nr);
m_nb_frames = 0;
m_started = false;
resetFrameInfo(m_last_frame_info);
m_last_frame_cb_nr = Invalid;
open(dev_nb);
registerLastFrameCb();
}
Espia::~Espia()
......@@ -25,28 +32,96 @@ Espia::~Espia()
close();
}
void Espia::open(int dev_nr)
void Espia::open(int dev_nb)
{
if (dev_nr == m_dev_nr)
if (dev_nb == m_dev_nb)
return;
close();
CHECK_CALL(espia_open(dev_nr, &m_dev));
m_dev_nr = dev_nr;
CHECK_CALL(espia_open(dev_nb, &m_dev));
m_dev_nb = dev_nb;
}
void Espia::close()
{
if (m_dev_nr == Invalid)
if (m_dev_nb == Invalid)
return;
bufferFree();
unregisterLastFrameCb();
CHECK_CALL(espia_close(m_dev));
m_dev = ESPIA_DEV_INVAL;
m_dev_nr = Invalid;
m_dev_nb = Invalid;
}
int Espia::cbDispatch(struct espia_cb_data *cb_data)
{
Espia *espia = (Espia *) cb_data->data;
void (Espia::*method)(struct espia_cb_data *cb_data) = NULL;
int& cb_nr = cb_data->cb_nr;
if (cb_nr == espia->m_last_frame_cb_nr)
method = &Espia::lastFrameCb;
if (method) {
try {
(espia->*method)(cb_data);
} catch (...) {
}
}
return ESPIA_OK;
}
void Espia::registerLastFrameCb()
{
if (m_last_frame_cb_nr != Invalid)
return;
struct espia_cb_data cb_data;
cb_data.type = ESPIA_CB_ACQ;
cb_data.cb = cbDispatch;
cb_data.data = this;
cb_data.timeout = BlockForever;
struct img_frame_info& req_finfo = cb_data.info.acq.req_finfo;
req_finfo.buffer_nr = ESPIA_ACQ_ANY;
req_finfo.frame_nr = ESPIA_ACQ_ANY;
req_finfo.round_count = ESPIA_ACQ_ANY;
req_finfo.acq_frame_nr = ESPIA_ACQ_EACH;
int& cb_nr = m_last_frame_cb_nr;
CHECK_CALL(espia_register_callback(m_dev, &cb_data, &cb_nr));
try {
CHECK_CALL(espia_callback_active(m_dev, cb_nr, true));
} catch (...) {
unregisterLastFrameCb();
throw;
}
}
void Espia::unregisterLastFrameCb()
{
if (m_last_frame_cb_nr == Invalid)
return;
CHECK_CALL(espia_unregister_callback(m_dev, m_last_frame_cb_nr));
m_last_frame_cb_nr = Invalid;
}
void Espia::lastFrameCb(struct espia_cb_data *cb_data)
{
AutoMutex l = acqLock();
struct img_frame_info& cb_finfo = cb_data->info.acq.cb_finfo;
if (!finished_espia_frame_info(&cb_finfo, cb_data->ret))
m_last_frame_info = cb_finfo;
}
void Espia::bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
......@@ -100,6 +175,8 @@ void Espia::bufferFree()
if ((m_nb_buffers == 0) || (m_buffer_frames == 0))
return;
stopAcq();
CHECK_CALL(espia_buffer_free(m_dev));
m_frame_dim = FrameDim();
......@@ -146,7 +223,7 @@ void Espia::getFrameInfo(int acq_frame_nb, HwFrameInfoType& info)
finfo.frame_nr = ESPIA_ACQ_ANY;
finfo.round_count = ESPIA_ACQ_ANY;
finfo.acq_frame_nr = acq_frame_nb;
CHECK_CALL(espia_get_frame(m_dev, &finfo, SCDXIPCI_NO_BLOCK));
CHECK_CALL(espia_get_frame(m_dev, &finfo, NoBlock));
real2virtFrameInfo(finfo, info);
}
......@@ -164,6 +241,71 @@ void Espia::real2virtFrameInfo(const struct img_frame_info& real_info,
virt_info.valid_pixels = real_info.pixels;
}
void Espia::resetFrameInfo(struct img_frame_info& frame_info)
{
frame_info.buffer_ptr = NULL;
frame_info.buffer_nr = Invalid;
frame_info.frame_nr = Invalid;
frame_info.round_count = Invalid;
frame_info.acq_frame_nr = Invalid;
frame_info.time_us = 0;
frame_info.pixels = 0;
}
void Espia::setNbFrames(int nb_frames)
{
if (nb_frames < 0)
throw LIMA_HW_EXC(InvalidValue, "Invalid nb of frames");
m_nb_frames = nb_frames;
}
void Espia::getNbFrames(int& nb_frames)
{
nb_frames = m_nb_frames;
}
void Espia::startAcq()
{
AutoMutex l = acqLock();
if (m_started)
throw LIMA_HW_EXC(Error, "Acquisition already running");
resetFrameInfo(m_last_frame_info);
CHECK_CALL(espia_start_acq(m_dev, 0, m_nb_frames, NoBlock));
m_start_ts = Timestamp::now();
m_started = true;
}
void Espia::stopAcq()
{
AutoMutex l = acqLock();
if (!m_started)
return;
CHECK_CALL(espia_stop_acq(m_dev));
m_started = false;
}
void Espia::getAcqStatus(AcqStatusType& acq_status)
{
AutoMutex l = acqLock();
unsigned long acq_run_nb;
int acq_running = espia_acq_active(m_dev, &acq_run_nb);
CHECK_CALL(acq_running);
acq_status.acq_started = m_started;
acq_status.acq_running = acq_running;
acq_status.acq_run_nb = acq_run_nb;
acq_status.last_acq_frame_nb = m_last_frame_info.acq_frame_nr;
}
void Espia::serWrite(const string& buffer, int block_size, double block_delay,
bool no_wait)
{
......
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