Commit 47b381a4 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by operator for beamline
Browse files

First Jungfrau detector support: single UDP interface:

* Move Eiger-specific code from Camera to Eiger:
  BebList, TenGigabitEthernet, FlowControl10G
parent 0b5ef6c6
......@@ -104,6 +104,7 @@ add_library(slsdetector SHARED
src/SlsDetectorReceiver.cpp
src/SlsDetectorCamera.cpp
src/SlsDetectorEiger.cpp
src/SlsDetectorJungfrau.cpp
src/SlsDetectorInterface.cpp
${SLSDETECTOR_INCS}
)
......
......@@ -299,12 +299,11 @@ as well as the kernel image:
[ -n "${EIGER_MODULES}" ] || . ${EIGER_HOME}/eiger_setup.sh
base_dir="${HOME}/eiger/log/${EIGER_DETECTOR}"
cd ${SLS_DETECTORS}/eiger/config
fw_ver=$(cat detector/${EIGER_DETECTOR}/setup/${EIGER_DETECTOR_SETUP}/\
detector/fw)
cd ${SLS_DETECTORS}/config/eiger
detector_dir="detector/${EIGER_DETECTOR}/setup/${EIGER_DETECTOR_SETUP}/detector"
fw_ver=$(cat ${detector_dir}/fw)
fw_dir="fw/${fw_ver}"
flash_config="detector/${EIGER_DETECTOR}/setup/${EIGER_DETECTOR_SETUP}/\
detector/flash.config"
flash_config="${detector_dir}/flash.config"
fpga_type=$(python <<EOF
from configparser import ConfigParser
......
......@@ -26,7 +26,6 @@
#include "SlsDetectorArgs.h"
#include "SlsDetectorReceiver.h"
#include "SlsDetectorCPUAffinity.h"
#include "SlsDetectorBebTools.h"
#include "sls/Detector.h"
......@@ -170,13 +169,6 @@ private:
typedef std::queue<int> FrameQueue;
typedef std::vector<AutoPtr<Receiver> > RecvList;
struct Beb {
BebShell shell;
BebFpgaMem fpga_mem;
Beb(const std::string& host_name);
};
typedef std::vector<AutoPtr<Beb> > BebList;
struct AppInputData
{
DEB_CLASS_NAMESPC(DebModCamera, "Camera::AppInputData",
......@@ -292,8 +284,6 @@ private:
}
void setReceiverFifoDepth(int fifo_depth);
bool isTenGigabitEthernetEnabled();
void setFlowControl10G(bool enabled);
void resetFramesCaught();
int m_det_id;
......@@ -301,7 +291,6 @@ private:
Cond m_cond;
AutoPtr<AppInputData> m_input_data;
AutoPtr<sls::Detector> m_det;
BebList m_beb_list;
FrameMap m_frame_map;
RecvList m_recv_list;
TrigMode m_trig_mode;
......
......@@ -24,6 +24,7 @@
#define __SLS_DETECTOR_EIGER_H
#include "SlsDetectorCamera.h"
#include "SlsDetectorBebTools.h"
#include "processlib/LinkTask.h"
......@@ -264,6 +265,9 @@ class Eiger : public Model
void setTxFrameDelay(int tx_frame_delay);
void getTxFrameDelay(int& tx_frame_delay);
bool isTenGigabitEthernetEnabled();
void setFlowControl10G(bool enabled);
Geometry *getGeometry()
{ return &m_geom; }
......@@ -291,6 +295,13 @@ class Eiger : public Model
friend class Correction;
friend class CorrBase;
struct Beb {
BebShell shell;
BebFpgaMem fpga_mem;
Beb(const std::string& host_name);
};
typedef std::vector<AutoPtr<Beb> > BebList;
class Recv
{
DEB_CLASS_NAMESPC(DebModCamera, "Eiger::Recv", "SlsDetector");
......@@ -601,6 +612,7 @@ class Eiger : public Model
static const unsigned long BebFpgaPtrRange;
Cond m_cond;
BebList m_beb_list;
Geometry m_geom;
CorrList m_corr_list;
RecvList m_recv_list;
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#ifndef __SLS_DETECTOR_JUNGFRAU_H
#define __SLS_DETECTOR_JUNGFRAU_H
#include "SlsDetectorCamera.h"
#include "processlib/LinkTask.h"
namespace lima
{
namespace SlsDetector
{
class Jungfrau : public Model
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau", "SlsDetector");
public:
typedef unsigned char Byte;
typedef unsigned short Word;
typedef unsigned int Long;
Jungfrau(Camera *cam);
~Jungfrau();
virtual void getFrameDim(FrameDim& frame_dim, bool raw = false);
virtual std::string getName();
virtual void getPixelSize(double& x_size, double& y_size);
virtual void getDACInfo(NameList& name_list, IntList& idx_list,
IntList& milli_volt_list);
virtual void getADCInfo(NameList& name_list, IntList& idx_list,
FloatList& factor_list,
FloatList& min_val_list);
virtual void getTimeRanges(TimeRanges& time_ranges);
void setHighVoltage(int hvolt);
void getHighVoltage(int& hvolt);
void setThresholdEnergy(int thres);
void getThresholdEnergy(int& thres);
virtual bool isXferActive();
protected:
virtual int getNbFrameMapItems();
virtual void updateFrameMapItems(FrameMap *map);
virtual void processBadItemFrame(FrameType frame, int item,
char *bptr);
virtual void setThreadCPUAffinity(const CPUAffinityList& aff_list);
virtual void updateImageSize();
virtual bool checkSettings(Settings settings);
virtual void prepareAcq();
virtual void startAcq();
virtual void stopAcq();
private:
class Thread : public lima::Thread
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::Thread", "SlsDetector");
public:
enum State {
Init, Ready, Running, Stopping, Quitting, End,
};
Thread(Jungfrau *jungfrau, int idx);
virtual ~Thread();
void setCPUAffinity(CPUAffinity aff);
void prepareAcq();
void startAcq()
{ setState(Running); }
void stopAcq()
{
setState(Stopping);
AutoMutex l = lock();
while (m_state != Ready)
wait();
}
protected:
virtual void threadFunction();
private:
friend class Jungfrau;
AutoMutex lock()
{ return m_jungfrau->lock(); }
void wait()
{ m_jungfrau->wait(); }
void broadcast()
{ m_jungfrau->broadcast(); }
void setState(State state)
{
AutoMutex l = lock();
m_state = state;
broadcast();
}
Jungfrau *m_jungfrau;
int m_idx;
State m_state;
};
typedef std::vector<AutoPtr<Thread> > ThreadList;
AutoMutex lock()
{ return AutoMutex(m_cond.mutex()); }
void wait()
{ m_cond.wait(); }
void broadcast()
{ m_cond.broadcast(); }
bool allFramesAcquired()
{ return m_next_frame == m_nb_frames; }
int getNbProcessingThreads();
void setNbProcessingThreads(int nb_proc_threads);
void processOneFrame(AutoMutex& l);
static const int ChipSize;
static const int ChipGap;
static const int HalfModuleChips;
Cond m_cond;
Receiver *m_recv;
FrameType m_nb_frames;
FrameType m_next_frame;
FrameType m_last_frame;
SortedIntList m_in_process;
FrameMap::Item *m_frame_map_item;
ThreadList m_thread_list;
};
} // namespace SlsDetector
} // namespace lima
#endif // __SLS_DETECTOR_JUNGFRAU_H
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
namespace SlsDetector
{
%TypeHeaderCode
#include "SlsDetectorJungfrau.h"
%End
class Jungfrau : public SlsDetector::Model
{
%TypeHeaderCode
#include "SlsDetectorJungfrau.h"
%End
public:
Jungfrau(SlsDetector::Camera *cam);
virtual void getFrameDim(FrameDim& frame_dim /Out/, bool raw = false);
virtual std::string getName();
virtual void getPixelSize(double& x_size /Out/, double& y_size /Out/);
virtual void getDACInfo(std::vector<std::string>& name_list /Out/,
std::vector<int>& idx_list /Out/,
std::vector<int>& milli_volt_list /Out/);
virtual void getADCInfo(std::vector<std::string>& name_list /Out/,
std::vector<int>& idx_list /Out/,
std::vector<double>& factor_list /Out/,
std::vector<double>& min_val_list /Out/);
virtual void getTimeRanges(SlsDetector::TimeRanges& time_ranges /Out/);
void setHighVoltage(int hvolt);
void getHighVoltage(int& hvolt /Out/);
void setThresholdEnergy(int thres);
void getThresholdEnergy(int& thres /Out/);
virtual bool isXferActive();
protected:
virtual int getNbFrameMapItems();
virtual void updateFrameMapItems(FrameMap *map);
virtual void processBadItemFrame(unsigned long frame, int item,
char *bptr);
virtual void updateImageSize();
virtual bool checkSettings(SlsDetector::Defs::Settings settings);
virtual void setThreadCPUAffinity(const SlsDetector::CPUAffinityList&
det_thread_aff_list);
virtual void prepareAcq();
virtual void startAcq();
virtual void stopAcq();
};
}; // namespace SlsDetector
Subproject commit 97974b4d45af37c9f191b4bae67762bac2029c3b
Subproject commit 53ef69b518173783db09a3fd48fbf23568503b91
......@@ -66,17 +66,20 @@ void Camera::AppInputData::parseConfigFile()
const SingleMatch& single_match = full_match[1];
host_name_list.push_back(single_match);
}
DEB_TRACE() << DEB_VAR1(host_name_list);
continue;
}
re = "([0-9]+):rx_tcpport";
re = "(([0-9]+):)?rx_tcpport";
if (re.match(s, full_match)) {
istringstream is(full_match[1]);
int id;
is >> id;
if (id < 0)
THROW_HW_FATAL(InvalidValue) <<
"Invalid detector id: " << id;
int id = 0;
if (full_match[2].found()) {
istringstream is(full_match[2]);
is >> id;
if (id < 0)
THROW_HW_FATAL(InvalidValue) <<
"Invalid detector id: " << id;
}
int rx_tcpport;
config_file >> rx_tcpport;
recv_port_map[id] = rx_tcpport;
......@@ -85,11 +88,6 @@ void Camera::AppInputData::parseConfigFile()
}
}
Camera::Beb::Beb(const std::string& host_name)
: shell(host_name), fpga_mem(shell)
{
}
Camera::AcqThread::ExceptionCleanUp::ExceptionCleanUp(AcqThread& thread,
AutoMutex& l)
: Thread::ExceptionCleanUp(thread), m_lock(l)
......@@ -373,17 +371,6 @@ Camera::Camera(string config_fname, int det_id)
setNbFrames(1);
setExpTime(0.99);
setFramePeriod(1.0);
if (isTenGigabitEthernetEnabled()) {
DEB_TRACE() << "Forcing 10G Ethernet flow control";
setFlowControl10G(true);
}
for (int i = 0; i < getNbDetModules(); ++i) {
const string& host_name = m_input_data->host_name_list[i];
Beb *beb = new Beb(host_name);
m_beb_list.push_back(beb);
}
}
Camera::~Camera()
......@@ -1327,23 +1314,6 @@ void Camera::setReceiverFifoDepth(int fifo_depth)
EXC_CHECK(m_det->setRxFifoDepth(fifo_depth));
}
bool Camera::isTenGigabitEthernetEnabled()
{
DEB_MEMBER_FUNCT();
bool enabled;
const char *err_msg = "Ten-giga is different";
EXC_CHECK(enabled = m_det->getTenGiga().tsquash(err_msg));
DEB_RETURN() << DEB_VAR1(enabled);
return enabled;
}
void Camera::setFlowControl10G(bool enabled)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(enabled);
EXC_CHECK(m_det->setTenGigaFlowControl(enabled));
}
void Camera::resetFramesCaught()
{
DEB_MEMBER_FUNCT();
......
......@@ -600,6 +600,11 @@ FrameDim Eiger::Geometry::getRecvFrameDim(bool raw)
return frame_dim;
}
Eiger::Beb::Beb(const std::string& host_name)
: shell(host_name), fpga_mem(shell)
{
}
Eiger::Recv::Recv(Eiger *eiger, int idx)
: m_eiger(eiger), m_idx(idx)
{
......@@ -719,6 +724,13 @@ Eiger::Eiger(Camera *cam)
int nb_det_modules = getNbDetModules();
DEB_TRACE() << "Using Eiger detector, " << DEB_VAR1(nb_det_modules);
NameList host_name_list = getCamera()->getHostnameList();
NameList::const_iterator it, end = host_name_list.end();
for (it = host_name_list.begin(); it != end; ++it) {
Beb *beb = new Beb(*it);
m_beb_list.push_back(beb);
}
m_geom.setNbRecvs(nb_det_modules);
for (int i = 0; i < nb_det_modules; ++i) {
......@@ -728,6 +740,11 @@ Eiger::Eiger(Camera *cam)
setNbProcessingThreads(1);
if (isTenGigabitEthernetEnabled()) {
DEB_TRACE() << "Forcing 10G Ethernet flow control";
setFlowControl10G(true);
}
updateCameraModel();
getClockDiv(m_clock_div);
......@@ -1265,6 +1282,23 @@ void Eiger::setThreadCPUAffinity(const CPUAffinityList& aff_list)
(*it)->setCPUAffinity(*rit);
}
bool Eiger::isTenGigabitEthernetEnabled()
{
DEB_MEMBER_FUNCT();
bool enabled;
const char *err_msg = "Ten-giga is different";
EXC_CHECK(enabled = m_det->getTenGiga().tsquash(err_msg));
DEB_RETURN() << DEB_VAR1(enabled);
return enabled;
}
void Eiger::setFlowControl10G(bool enabled)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(enabled);
EXC_CHECK(m_det->setTenGigaFlowControl(enabled));
}
void Eiger::prepareAcq()
{
DEB_MEMBER_FUNCT();
......@@ -1462,9 +1496,8 @@ double Eiger::getBorderCorrFactor(int /*det*/, int line)
void Eiger::getFpgaFramePtrDiff(PtrDiffList& ptr_diff)
{
DEB_MEMBER_FUNCT();
Camera::BebList& beb_list = getCamera()->m_beb_list;
for (unsigned int i = 0; i != beb_list.size(); ++i) {
BebFpgaMem& fpga_mem = beb_list[i]->fpga_mem;
for (unsigned int i = 0; i != m_beb_list.size(); ++i) {
BebFpgaMem& fpga_mem = m_beb_list[i]->fpga_mem;
unsigned long wr_ptr = fpga_mem.read(BebFpgaWritePtrAddr);
unsigned long rd_ptr = fpga_mem.read(BebFpgaReadPtrAddr);
if (rd_ptr > wr_ptr)
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#include "SlsDetectorJungfrau.h"
#include "lima/MiscUtils.h"
#include <emmintrin.h>
#include <sched.h>
using namespace std;
using namespace lima;
using namespace lima::SlsDetector;
using namespace lima::SlsDetector::Defs;
const int Jungfrau::ChipSize = 256;
const int Jungfrau::ChipGap = 2;
const int Jungfrau::HalfModuleChips = 4;
Jungfrau::Thread::Thread(Jungfrau *jungfrau, int idx)
: m_jungfrau(jungfrau), m_idx(idx)
{
DEB_MEMBER_FUNCT();
AutoMutex l = lock();
m_state = Init;
start();
struct sched_param param;
param.sched_priority = 50;
int ret = pthread_setschedparam(m_thread, SCHED_RR, &param);
if (ret != 0)
DEB_ERROR() << "Could not set real-time priority!!";
while (m_state == Init)
wait();
}
Jungfrau::Thread::~Thread()
{
DEB_DESTRUCTOR();
AutoMutex l = lock();
m_state = Quitting;
broadcast();
while (m_state != End)
wait();
}
void Jungfrau::Thread::threadFunction()
{
DEB_MEMBER_FUNCT();
State& s = m_state;
AutoMutex l = lock();
s = Ready;
broadcast();
while (s != Quitting) {
while ((s == Ready) || (s == Stopping)
|| ((s == Running) && m_jungfrau->allFramesAcquired())) {
if (s == Stopping) {
s = Ready;
broadcast();
}
wait();
}
if (s == Running)
m_jungfrau->processOneFrame(l);
}
s = End;
broadcast();
}
void Jungfrau::Thread::setCPUAffinity(CPUAffinity aff)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(aff);
aff.applyToTask(getThreadID(), false);
}
void Jungfrau::Thread::prepareAcq()
{
DEB_MEMBER_FUNCT();
}
Jungfrau::Jungfrau