Commit 43b4ae3c authored by Jean-Luc Pons's avatar Jean-Luc Pons

Initial import

parents
.idea/
bin/
cmake-build-debug/
obj/
//+=============================================================================
//
// file : ADCThread.cpp
//
// description : Include for the ADCThread class.
// This class is used for reading ADC data
//
// project : LiberaSparkSRBPM TANGO Device Server
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//-=============================================================================
namespace LiberaSparkSRBPM_ns
{
class ADCThread;
}
#include <ADCThread.h>
namespace LiberaSparkSRBPM_ns
{
// ----------------------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------------------
ADCThread::ADCThread(LiberaSparkSRBPM *libera, omni_mutex &m):
Tango::LogAdapter(libera), mutex(m), ds(libera)
{
INFO_STREAM << "ADCThread: Starting ADC Thread." << endl;
// Initialise connection parameters
m_dod = std::dynamic_pointer_cast<RADC>(ds->adcSignal);
m_dodClient = NULL;
threadStatus = "ADCThread: acquiring";
start_undetached();
}
// ----------------------------------------------------------------------------------------
// Main loop
// ----------------------------------------------------------------------------------------
void *ADCThread::run_undetached(void *arg) {
exitThread = false;
isConnected = false;
cout << "ADCThread: entering." << endl;
while(!exitThread) {
isConnected = OpenDod();
if( isConnected ) {
// Read data
isig::SignalMeta signal_meta;
size_t offset_read = 0;
if (m_buf->GetLength() != (size_t)ds->attr_ADC_BufSize_read[0])
m_buf->Resize((size_t)ds->attr_ADC_BufSize_read[0]);
isig::SuccessCode_e res = isig::eSuccess;
try {
res = m_dodClient->Read(*m_buf, signal_meta, offset_read);
if (res != isig::eSuccess) {
if( !exitThread ) {
cerr << "ADCThread: Failed to read buffer, Error:" << res << endl;
mutex.lock();
threadStatus = "Failed to read buffer, Error code:" + std::to_string(res);
mutex.unlock();
m_dodClient->Close();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
} else {
mutex.lock();
adcValues.clear();
for (int i = 0; i < (int)m_buf->GetLength(); i++) {
ADC p;
p.va = (*m_buf)[i][0];
p.vb = (*m_buf)[i][1];
p.vc = (*m_buf)[i][2];
p.vd = (*m_buf)[i][3];
adcValues.push_back(p);
}
mutex.unlock();
}
} catch (istd::Exception &e) {
if( !exitThread ) {
mutex.lock();
threadStatus = "Failed to read buffer, Error :" + string(e.what());
mutex.unlock();
cerr << "ADCThread: Failed to read buffer, Error:" << e.what() << endl;
m_dodClient->Close();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
} else {
// Connection failure
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
cout << "ADCThread: disconnecting." << endl;
if (m_dodClient && m_dodClient->IsOpen())
m_dodClient->Close();
cout << "ADCThread: exiting." << endl;
return NULL;
}
// ----------------------------------------------------------------------------------------
bool ADCThread::OpenDod() {
if (m_dodClient && m_dodClient->IsOpen()) {
// Already connected
return true;
}
size_t length = (size_t)ds->attr_ADC_BufSize_read[0];
m_dodClient = std::make_shared<ADCClient>(m_dod, "dod_client", m_dod->GetTraits());
m_buf = std::make_shared<Int16Buffer>(m_dodClient->CreateBuffer(length));
isig::SuccessCode_e res = m_dodClient->Open(isig::eModeDodOnEvent,length,0);
if (res != isig::eSuccess) {
mutex.lock();
threadStatus = "Failed to open DoD, Error :" + std::to_string(res);
mutex.unlock();
cerr << "ADCThread::Failed to open DoD " << endl;
return false;
}
cout << "ADCThread: " << m_dod->GetName() << " DoD opened succesfully." << endl;
return true;
}
// ----------------------------------------------------------------------------------------
#define GET_VALUES(field) \
int16_t *ret = NULL; \
omni_mutex_lock l(mutex); \
*length = adcValues.size(); \
if(adcValues.size()>0) { \
ret = new int16_t[adcValues.size()]; \
for(int i=0;i<(int)adcValues.size();i++) \
ret[i] = adcValues[i].field; \
} \
return ret;
int16_t *ADCThread::getVa(int *length) {
GET_VALUES(va);
}
int16_t *ADCThread::getVb(int *length) {
GET_VALUES(vb);
}
int16_t *ADCThread::getVc(int *length) {
GET_VALUES(vc);
}
int16_t *ADCThread::getVd(int *length) {
GET_VALUES(vd);
}
// ----------------------------------------------------------------------------------------
void ADCThread::wakeup() {
// Wake up thread
cout << "ADCThread: wake up." << endl;
if (m_dodClient && m_dodClient->IsOpen()) {
m_dodClient->Close();
}
}
} // namespace LiberaSparkSRBPM_ns
//+=============================================================================
//
// file : ADCThread.h
//
// description : Include for the ADCThread class.
// This class is used for reading ADC data
//
// project : LiberaSparkSRBPM TANGO Device Server
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//-=============================================================================
#ifndef LIBERASPARKSRBPM_ADCTHREAD_H
#define LIBERASPARKSRBPM_ADCTHREAD_H
#include <LiberaSparkSRBPM.h>
namespace LiberaSparkSRBPM_ns {
class ADCThread : public omni_thread, public Tango::LogAdapter {
public:
// Constructor
ADCThread(LiberaSparkSRBPM *, omni_mutex &);
void *run_undetached(void *);
bool exitThread;
string threadStatus;
bool isConnected;
private:
vector<ADC> adcValues;
LiberaSparkSRBPM *ds;
omni_mutex &mutex;
std::shared_ptr<RADC> m_dod;
std::shared_ptr<ADCClient> m_dodClient;
std::shared_ptr<Int16Buffer> m_buf;
bool OpenDod();
public:
int16_t *getVa(int *length);
int16_t *getVb(int *length);
int16_t *getVc(int *length);
int16_t *getVd(int *length);
void wakeup();
}; // class ADCThread
} // namespace LiberaSparkSRBPM_ns
#endif //LIBERASPARKSRBPM_ADCTHREAD_H
#=============================================================================
#
# file : CMakeLists.txt
#
# description : File to generate a TANGO device server using cmake.
#
# project : LiberaSparkSRBPM
#
#=============================================================================
# This file is generated by POGO
# (Program Obviously used to Generate tango Object)
#=============================================================================
#
#
cmake_minimum_required (VERSION 2.8)
set(CMAKE_SKIP_RPATH TRUE)
# MAKE_ENV is the path to find common environment to build project
#
set(MAKE_ENV /segfs/tango/cppserver/env)
#
# Project definitions
#
project(LiberaSparkSRBPM)
#
# optional compiler flags
#
set(CXXFLAGS_USER -g)
#
# Get global information
#
include(${MAKE_ENV}/cmake_tango.opt)
#
# Files for LiberaSparkSRBPM TANGO class
#
set(LIBERASPARKSRBPM LiberaSparkSRBPM)
set(LIBERASPARKSRBPM_INCLUDE ${CMAKE_SOURCE_DIR})
set(LIBERASPARKSRBPM_SRC ${LIBERASPARKSRBPM}.cpp ${LIBERASPARKSRBPM}Class.cpp ${LIBERASPARKSRBPM}StateMachine.cpp)
#
# User additional include, link folders/libraries and source files
#
set(USER_INCL_DIR /segfs/linux/libera/LiberaPlatformC/libera3.0/arm/include /segfs/linux/libera/LiberaPlatformC/boost_1_60_0/arm/include)
set(USER_LIB_DIR )
set(USER_LIBS )
set(USER_SRC_FILES PosCalculation.cpp SAThread.cpp DDThread.cpp ADCThread.cpp IQThread.cpp)
#
# Set global info and include directories
#
set(ALL_CLASS_INCLUDE ${LIBERASPARKSRBPM_INCLUDE} ${USER_INCL_DIR})
set(SERVER_SRC ${LIBERASPARKSRBPM_SRC} ${USER_SRC_FILES} ClassFactory.cpp main.cpp)
include_directories(${ALL_CLASS_INCLUDE} ${USER_INCL_DIR} ${TANGO_INCLUDES})
#
# Device Server generation
#
set(SERVER_NAME LiberaSparkSRBPM)
include(${MAKE_ENV}/cmake_common_target.opt)
/*----- PROTECTED REGION ID(LiberaSparkSRBPM::ClassFactory.cpp) ENABLED START -----*/
//=============================================================================
//
// file : ClassFactory.cpp
//
// description : C++ source for the class_factory method of the DServer
// device class. This method is responsible for the creation of
// all class singleton for a device server. It is called
// at device server startup.
//
// project : LiberaSparkBPM
//
// This file is part of Tango device class.
//
// Tango 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.
//
// Tango 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 Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
// Copyright (C): 2019
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// France
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <tango.h>
#include <LiberaSparkSRBPMClass.h>
// Add class header files if needed
/**
* Create LiberaSparkSRBPM Class singleton and store it in DServer object.
*/
void Tango::DServer::class_factory()
{
// Add method class init if needed
add_class(LiberaSparkSRBPM_ns::LiberaSparkSRBPMClass::init("LiberaSparkSRBPM"));
}
/*----- PROTECTED REGION END -----*/ // LiberaSparkSRBPM::ClassFactory.cpp
//+=============================================================================
//
// file : DDThread.cpp
//
// description : Include for the DDThread class.
// This class is used for reading DD data (TBT)
//
// project : LiberaSparkSRBPM TANGO Device Server
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//-=============================================================================
namespace LiberaSparkSRBPM_ns
{
class DDThread;
}
#include <DDThread.h>
namespace LiberaSparkSRBPM_ns
{
// ----------------------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------------------
DDThread::DDThread(LiberaSparkSRBPM *libera, PosCalculation *pc,omni_mutex &m):
Tango::LogAdapter(libera), mutex(m), PC(pc), ds(libera)
{
INFO_STREAM << "DDThread: Starting DD Thread." << endl;
// Initialise connection parameters
if( ds->attr_TBT_Dec_Enable_read[0])
// Decimated data
m_dod = std::dynamic_pointer_cast<RSource>(ds->tbtdecSignal);
else
// Normal data
m_dod = std::dynamic_pointer_cast<RSource>(ds->tbtSignal);
m_dodClient = NULL;
threadStatus = "DDThread: acquiring";
start_undetached();
}
// ----------------------------------------------------------------------------------------
// Main loop
// ----------------------------------------------------------------------------------------
void *DDThread::run_undetached(void *arg) {
string errorStr;
exitThread = false;
isConnected = false;
cout << "DDThread: entering." << endl;
while(!exitThread) {
isConnected = OpenDod();
if( isConnected ) {
// Read data
isig::SignalMeta signal_meta;
size_t offset_read = (size_t)ds->attr_TBT_Offset_read[0];
if (m_buf->GetLength() != (size_t)ds->attr_TBT_BufSize_read[0])
m_buf->Resize((size_t)ds->attr_TBT_BufSize_read[0]);
isig::SuccessCode_e res = isig::eSuccess;
try {
res = m_dodClient->Read(*m_buf, signal_meta, offset_read);
if (res != isig::eSuccess) {
if( !exitThread ) {
cerr << "DDThread: Failed to read buffer, Error:" << res << endl;
mutex.lock();
threadStatus = "Failed to read buffer, Error code:" + std::to_string(res);
mutex.unlock();
m_dodClient->Close();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
} else {
computePosition(m_buf, m_buf->GetLength());
}
} catch (istd::Exception &e) {
if( !exitThread ) {
mutex.lock();
threadStatus = "Failed to read buffer, Error :" + string(e.what());
mutex.unlock();
cerr << "DDThread: Failed to read buffer, Error:" << e.what() << endl;
m_dodClient->Close();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
} else {
// Connection failure
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
cout << "DDThread: disconnecting." << endl;
if (m_dodClient && m_dodClient->IsOpen())
m_dodClient->Close();
cout << "DDThread: exiting." << endl;
return NULL;
}
// ----------------------------------------------------------------------------------------
bool DDThread::OpenDod() {
if (m_dodClient && m_dodClient->IsOpen()) {
// Already connected
return true;
}
size_t length = (size_t)ds->attr_TBT_BufSize_read[0];
size_t offset = (size_t)ds->attr_TBT_Offset_read[0];
m_dodClient = std::make_shared<DodClient>(m_dod, "dod_client", m_dod->GetTraits());
m_buf = std::make_shared<Int32Buffer>(m_dodClient->CreateBuffer(length));
isig::SuccessCode_e res = m_dodClient->Open(isig::eModeDodOnEvent,length,offset);
if (res != isig::eSuccess) {
mutex.lock();
threadStatus = "Failed to open DoD, Error :" + std::to_string(res);
mutex.unlock();
cerr << "DDThread::Failed to open DoD " << endl;
return false;
}
cout << "DDThread: " << m_dod->GetName() << " DoD opened succesfully." << endl;
return true;
}
// ----------------------------------------------------------------------------------------
#define GET_VALUES(field) \
double *ret = NULL; \
omni_mutex_lock l(mutex); \
*length = ddValues.size(); \
if(ddValues.size()>0) { \
ret = new double[ddValues.size()]; \
for(int i=0;i<(int)ddValues.size();i++) \
ret[i] = ddValues[i].field; \
} \
return ret;
double *DDThread::getVa(int *length) {
GET_VALUES(va);
}
double *DDThread::getVb(int *length) {
GET_VALUES(vb);
}
double *DDThread::getVc(int *length) {
GET_VALUES(vc);
}
double *DDThread::getVd(int *length) {
GET_VALUES(vd);
}
double *DDThread::getSum(int *length) {
GET_VALUES(sum);
}
double *DDThread::getQ(int *length) {
GET_VALUES(q);
}
double *DDThread::getH(int *length) {
GET_VALUES(x);
}
double *DDThread::getV(int *length) {
GET_VALUES(z);
}
// ----------------------------------------------------------------------------------------
void DDThread::computePosition(std::shared_ptr<Int32Buffer> dd,size_t nb) {
mutex.lock();
ddValues.clear();
ddValues.reserve(nb);
for (int i = 0; i < (int) nb; i++) {
BP p;
p.va = (*dd)[i][0];
p.vb = (*dd)[i][1];
p.vc = (*dd)[i][2];
p.vd = (*dd)[i][3];
PC->ComputeDDPosition(p);
ddValues.push_back(p);
}
mutex.unlock();
}
// ----------------------------------------------------------------------------------------
void DDThread::wakeup() {
// Wake up thread
cout << "DDThread: wake up." << endl;
if (m_dodClient && m_dodClient->IsOpen()) {
m_dodClient->Close();
}
}
} // namespace LiberaSparkSRBPM_ns
//+=============================================================================
//
// file : DDThread.h
//
// description : Include for the DDThread class.
// This class is used for reading DD data (TBT)
//
// project : LiberaSparkSRBPM TANGO Device Server
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//-=============================================================================
#ifndef LIBERASPARKSRBPM_DDTHREAD_H
#define LIBERASPARKSRBPM_DDTHREAD_H
#include <LiberaSparkSRBPM.h>
namespace LiberaSparkSRBPM_ns {
class DDThread : public omni_thread, public Tango::LogAdapter {
public:
// Constructor
DDThread(LiberaSparkSRBPM *,PosCalculation *, omni_mutex &);
void *run_undetached(void *);
bool exitThread;
string threadStatus;
bool isConnected;
private:
vector<BP> ddValues;
LiberaSparkSRBPM *ds;
omni_mutex &mutex;
PosCalculation *PC;
std::shared_ptr<RSource> m_dod;
std::shared_ptr<DodClient> m_dodClient;
std::shared_ptr<Int32Buffer> m_buf;
bool OpenDod();
void computePosition(std::shared_ptr<Int32Buffer> dd,size_t nb);