Select Git revision
ADLinkContinuousAO.cpp
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ContinuousAO.cpp 43.96 KiB
static const char *RcsId = "$Header: /users/chaize/newsvn/cvsroot/InputOutput/ADLINK/ContinuousAO/src/ContinuousAO.cpp,v 1.8 2005-06-15 10:22:16 abeilleg Exp $";
//+=============================================================================
//
// file : ContinuousAO.cpp
//
// description : C++ source for the ContinuousAO and its commands.
// The class is derived from Device. It represents the
// CORBA servant object which will be accessed from the
// network. All commands which can be executed on the
// ContinuousAO are implemented in this file.
//
// project : TANGO Device Server
//
// $Author: abeilleg $
//
// $Revision: 1.8 $
//
// $Log: not supported by cvs2svn $
// Revision 1.7 2005/04/21 08:33:44 abeilleg
// update state in always_exe_hk
//
// Revision 1.6 2005/01/25 10:12:58 abeilleg
// status changed.
//
// Revision 1.5 2005/01/20 13:21:51 abeilleg
// following ASL modifications (states management).
//
// Revision 1.4 2004/12/21 13:06:59 abeilleg
// minor bugs fixed
//
//
// copyleft : Synchrotron SOLEIL
// L'Orme des Merisiers
// Saint-Aubin - BP 48
//
//-=============================================================================
//
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//
// (c) - Software Engineering Group - ESRF
//=============================================================================
//===================================================================
//
// The folowing table gives the correspondance
// between commands and method's name.
//
// Command's name | Method's name
// ----------------------------------------
// State | dev_state()
// Status | dev_status()
// Start | start()
// Stop | stop()
// SetAOScaledData | set_aoscaled_data()
//
//===================================================================
#include <ContinuousAO.h>
#include <TangoExceptionsHelper.h>
#include <asl/ASLExceptionsHandler.h>
#include <asl/AOData.h>
#include <math.h>
namespace ContinuousAO
{
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::ContinuousAO(string &s)
//
// description : constructor for simulated ContinuousAO
//
// in : - cl : Pointer to the DeviceClass object
// - s : Device name
//
//-----------------------------------------------------------------------------
ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,string &s):Tango::Device_2Impl(cl,s.c_str())
{
init_device();
}
ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,const char *s):Tango::Device_2Impl(cl,s)
{
init_device();
}
ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,const char *s,const char *d)
:Tango::Device_2Impl(cl,s,d)
{
init_device();
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::delete_device()
//
// description : will be called at device destruction or at init command.
//
//-----------------------------------------------------------------------------
void ContinuousAO::delete_device()
{
// Delete device's allocated object
if(ao)
{
delete ao;
ao = 0;
}
if(ch0)
{
delete ch0;
ch0 = 0;
}
if(ch1)
{
delete ch1;
ch1 = 0;
}
if(ch2)
{
delete ch2;
ch2 = 0;
}
if(ch3)
{
delete ch3;
ch3 = 0;
}
if(ch4)
{
delete ch4;
ch4 = 0;
}
if(ch5)
{
delete ch5;
ch5 = 0;
}
if(ch6)
{
delete ch6;
ch6 = 0;
}
if(ch7)
{
delete ch7;
ch7 = 0;
}
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::init_device()
//
// description : will be called at device initialization.
//
//-----------------------------------------------------------------------------
void ContinuousAO::init_device()
{
INFO_STREAM << "ContinuousAO::ContinuousAO() create device " << device_name << endl;
ao = 0;
ch0 = 0;
ch1 = 0;
ch2 = 0;
ch3 = 0;
ch4 = 0;
ch5 = 0;
ch6 = 0;
ch7 = 0;
// Initialise variables to default values
//--------------------------------------------
get_device_property();
//- create a continuous analog output daq
ao = new ADLinkContinuousAO(this);
//- check memory allocation
if (ao == 0)
{
this->set_internal_state();
Tango::Except::throw_exception(
(const char*)("OUT_OF_MEMORY"),
(const char*)("out of memory error"),
(const char*)("ContinuousAO::init_device")
);
}
asl::ContinuousAOConfig config;
ch0 = new double[bufferDepth];
ch1 = new double[bufferDepth];
ch2 = new double[bufferDepth];
ch3 = new double[bufferDepth];
ch4 = new double[bufferDepth];
ch5 = new double[bufferDepth];
ch6 = new double[bufferDepth];
ch7 = new double[bufferDepth];
if(ch0 == 0 || ch1 == 0 || ch2 == 0 || ch3 == 0 || ch4 == 0 || ch5 == 0 ||ch6 == 0 || ch7 == 0)
{
this->set_internal_state();
this->delete_device();
Tango::Except::throw_exception(
(const char*)("OUT_OF_MEMORY"),
(const char*)("out of memory error"),
(const char*)("ContinuousAO::init_device")
);
}
// default waveform for group A (channel 0 to 3)
asl::AOScaledData default_waveformA(bufferDepth);
double max_valA;
if(aORefSource == adl::external_reference)
max_valA = aORefA ;
else
max_valA = 10.0;
// fill buffer with a sin signal
for (unsigned long i = 0; i < bufferDepth; i++)
{
(default_waveformA)[i] = ::sin((double)i * 2. * 3.14159 / (double) bufferDepth) * max_valA;
}
ACE_OS::memcpy(this->ch0, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(this->ch1, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(this->ch2, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(this->ch3, default_waveformA.base(), default_waveformA.size());
// default waveform for group A (channel 4 to 7)
asl::AOScaledData default_waveformB(bufferDepth);
double max_valB;
if(aORefSource == adl::external_reference)
max_valB = aORefB;
else
max_valB = 10.0;
// fill buffer with a square signal
for (i = 0; i < bufferDepth/2; i++)
{
default_waveformB[i] = max_valB - 0.01;
}
for (i = bufferDepth/2; i < bufferDepth; i++)
{
default_waveformB[i] = -max_valB + 0.01;
}
ACE_OS::memcpy(this->ch4, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(this->ch5, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(this->ch6, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(this->ch7, default_waveformB.base(), default_waveformB.size());
//--------------------------channels config------------------------------------
asl::ActiveAOChannel ac;
// configure all channels
ac.polarity = (adl::OutputPolarity)polarity;
ac.volt_ref_src = (adl::VoltageReferenceSource)aORefSource;
ac.volt_ref = 10.0;
//- active/config. channel 0
if(channel0Enable)
{
ac.id = 0;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefA;
config.add_active_channel(ac);
if(channel0Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 0, using a default one"<<endl;
config.set_channel_periodic_data(0, default_waveformA);
}
else if(channel0Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 0 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(0, default_waveformA);
}
else //put waveform of the Tango database in ch0
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel0Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(0, data);
//cpy data in the attribute of the device
::memcpy(ch0, data.base(), data.size());
}
}
//- active/config. channel 1
if(channel1Enable)
{
ac.id = 1;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefA;
config.add_active_channel(ac);
if(channel1Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 1, using a default one"<<endl;
config.set_channel_periodic_data(1, default_waveformA);
}
else if(channel1Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 1 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(1, default_waveformA);
}
else //put waveform of the Tango database in ch1
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel1Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(1, data);
//cpy data in the attribute of the device
::memcpy(ch1, data.base(), data.size());
}
}
//- active/config. channel 2
if(channel2Enable)
{
ac.id = 2;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefA;
config.add_active_channel(ac);
config.set_channel_periodic_data(2, default_waveformA);
if(channel2Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 2, using a default one"<<endl;
config.set_channel_periodic_data(2, default_waveformA);
}
else if(channel2Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 2 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(2, default_waveformA);
}
else //put waveform of the Tango database in ch2
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel2Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(2, data);
//cpy data in the attribute of the device
::memcpy(ch2, data.base(), data.size());
}
}
//- active/config. channel 3
if(channel3Enable)
{
ac.id = 3;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefA;
config.add_active_channel(ac);
if(channel3Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 3, using a default one"<<endl;
config.set_channel_periodic_data(3, default_waveformA);
}
else if(channel3Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 3 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(3, default_waveformA);
}
else //put waveform of the Tango database in ch3
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel3Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(3, data);
//cpy data in the attribute of the device
::memcpy(ch3, data.base(), data.size());
}
}
//- active/config. channel 4
if(channel4Enable)
{
ac.id = 4;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefB;
config.add_active_channel(ac);
if(channel4Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 4, using a default one"<<endl;
config.set_channel_periodic_data(4, default_waveformB);
}
else if(channel4Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 4 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(4, default_waveformB);
}
else //put waveform of the Tango database in ch4
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel4Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(4, data);
//cpy data in the attribute of the device
::memcpy(ch4, data.base(), data.size());
}
}
//- active/config. channel 5
if(channel5Enable)
{
ac.id = 5;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefB;
config.add_active_channel(ac);
if(channel5Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 5, using a default one"<<endl;
config.set_channel_periodic_data(5, default_waveformB);
}
else if(channel5Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 5 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(5, default_waveformB);
}
else //put waveform of the Tango database in ch5
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel5Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(5, data);
//cpy data in the attribute of the device
::memcpy(ch5, data.base(), data.size());
}
}
//- active/config. channel 6
if(channel6Enable)
{
ac.id = 6;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefB;
config.add_active_channel(ac);
if(channel6Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 6, using a default one"<<endl;
config.set_channel_periodic_data(6, default_waveformB);
}
else if(channel6Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 6 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(6, default_waveformB);
}
else //put waveform of the Tango database in ch6
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel6Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(6, data);
//cpy data in the attribute of the device
::memcpy(ch6, data.base(), data.size());
}
}
//- active/config. channel 7
if(channel7Enable)
{
ac.id = 7;
if(aORefSource == adl::external_reference)
ac.volt_ref = aORefB;
config.add_active_channel(ac);
if(channel7Waveform.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel 7, using a default one"<<endl;
config.set_channel_periodic_data(7, default_waveformB);
}
else if(channel7Waveform.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel 7 has a different size from property BufferDepth, "<<
"using default waveform"<<endl;
config.set_channel_periodic_data(7, default_waveformB);
}
else //put waveform of the Tango database in ch7
{
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = channel7Waveform[i];
// put the waveform in the configuration
config.set_channel_periodic_data(7, data);
//cpy data in the attribute of the device
::memcpy(ch7, data.base(), data.size());
}
}
//--------------------------------start trigger config---------------------------------
if(startTrigger)
{
config.set_trigger_source((adl::AIOTriggerSource)startTriggerSource);
config.set_trigger_mode(adl::ao_post);
if(startTriggerSource == adl::external_digital)
{
config.set_trigger_polarity((adl::AOTriggerPolarity)dTRIGPolarity);
}
else if(startTriggerSource == adl::external_analog)
{
config.set_analog_trigger_source(adl::analog_trigger_ext);
config.set_analog_trigger_condition((adl::AnalogTriggerCondition)aTRIGSelection);
unsigned short level;
if(aTRIGLevel>=0)
level = (aTRIGLevel / 0.078125) + 127;
else // v < 0
level = (-aTRIGLevel / 0.078125);
//the voltage is converted in digital value (8 bits of resolution on EXTATRIG with +/-10 V (256/20 = 0.078125))
config.set_analog_low_level_condition(level);
config.set_analog_high_level_condition(level);
}
}
//--------------------------------stop trigger config---------------------------------
if(stopTrigger)
{
config.set_stop_mode(adl::wait_end_waveform);
config.set_stop_source ((adl::StopSource)stopTriggerSource);
}
config.set_output_rate(frequency);
DEBUG_STREAM<<"ContinuousAO::init_device : init acq"<<std::endl;
_ASL_TRY //_ACTION
(
ao->init(adl::DAQ2502, boardNum),
"init",
"ContinuousAO::init_device" //,
// this->set_internal_state()
);
//ao->configure(config);
DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl;
_ASL_TRY //_ACTION
(
ao->configure(config),
"configure",
"ContinuousAO::init_device" //,
//this->set_internal_state()
);
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::readDeviceProperies()
//
// description : Read the device properties from database.
//
//-----------------------------------------------------------------------------
void ContinuousAO::get_device_property()
{
// Initialize your default values here.
//------------------------------------------
boardNum = 0;
frequency = 50000.0; //50 kHz
startTrigger = 0; //no start trigger
stopTrigger = 0; //no stop trigger
string default_start_source = "DTRIG";
startTriggerSource = adl::external_digital;
string default_stop_source = "AFI1";
stopTriggerSource = adl::afi1_termination;
string default_atrig_select = "BELOW";
aTRIGSelection = adl::below_low_level;
aTRIGLevel = 5.0;
string default_dtrig_pol = "RISING";
dTRIGPolarity = adl::ao_rising_edge ;
aORefA = 10.0;
aORefB = 10.0;
string default_pol = "BP";
polarity = adl::bipolar;
string default_aoref = "INTERN";
aORefSource = adl::internal_reference;
channel0Enable = 1;
channel1Enable = 0;
channel2Enable = 0;
channel3Enable = 0;
channel4Enable = 0;
channel5Enable = 0;
channel6Enable = 0;
channel7Enable = 0;
bufferDepth = 4096;
// Read device properties from database.(Automatic code generation)
//-------------------------------------------------------------
Tango::DbData data;
data.push_back(Tango::DbDatum("BoardNum"));
data.push_back(Tango::DbDatum("Frequency"));
data.push_back(Tango::DbDatum("StartTrigger"));
data.push_back(Tango::DbDatum("StopTrigger"));
data.push_back(Tango::DbDatum("StartTriggerSource"));
data.push_back(Tango::DbDatum("StopTriggerSource"));
data.push_back(Tango::DbDatum("ATRIGSelection"));
data.push_back(Tango::DbDatum("ATRIGLevel"));
data.push_back(Tango::DbDatum("DTRIGPolarity"));
data.push_back(Tango::DbDatum("AORefA"));
data.push_back(Tango::DbDatum("AORefB"));
data.push_back(Tango::DbDatum("Polarity"));
data.push_back(Tango::DbDatum("AORefSource"));
data.push_back(Tango::DbDatum("Channel0Enable"));
data.push_back(Tango::DbDatum("Channel1Enable"));
data.push_back(Tango::DbDatum("Channel2Enable"));
data.push_back(Tango::DbDatum("Channel3Enable"));
data.push_back(Tango::DbDatum("Channel4Enable"));
data.push_back(Tango::DbDatum("Channel5Enable"));
data.push_back(Tango::DbDatum("Channel6Enable"));
data.push_back(Tango::DbDatum("Channel7Enable"));
data.push_back(Tango::DbDatum("BufferDepth"));
data.push_back(Tango::DbDatum("Channel0Waveform"));
data.push_back(Tango::DbDatum("Channel1Waveform"));
data.push_back(Tango::DbDatum("Channel2Waveform"));
data.push_back(Tango::DbDatum("Channel3Waveform"));
data.push_back(Tango::DbDatum("Channel4Waveform"));
data.push_back(Tango::DbDatum("Channel5Waveform"));
data.push_back(Tango::DbDatum("Channel6Waveform"));
data.push_back(Tango::DbDatum("Channel7Waveform"));
// Call database and extract values
//--------------------------------------------
get_db_device()->get_property(data);
if (data[0].is_empty()==false) data[0] >> boardNum;
if (data[1].is_empty()==false) data[1] >> frequency;
if (data[2].is_empty()==false) data[2] >> startTrigger;
if (data[3].is_empty()==false) data[3] >> stopTrigger;
if (data[4].is_empty()==false) data[4] >> startTriggerSource;
if (data[5].is_empty()==false) data[5] >> stopTriggerSource;
if (data[6].is_empty()==false) data[6] >> aTRIGSelection;
if (data[7].is_empty()==false) data[7] >> aTRIGLevel;
if (data[8].is_empty()==false) data[8] >> dTRIGPolarity;
if (data[9].is_empty()==false) data[9] >> aORefA;
if (data[10].is_empty()==false) data[10] >> aORefB;
if (data[11].is_empty()==false) data[11] >> polarity;
if (data[12].is_empty()==false) data[12] >> aORefSource;
if (data[13].is_empty()==false) data[13] >> channel0Enable;
if (data[14].is_empty()==false) data[14] >> channel1Enable;
if (data[15].is_empty()==false) data[15] >> channel2Enable;
if (data[16].is_empty()==false) data[16] >> channel3Enable;
if (data[17].is_empty()==false) data[17] >> channel4Enable;
if (data[18].is_empty()==false) data[18] >> channel5Enable;
if (data[19].is_empty()==false) data[19] >> channel6Enable;
if (data[20].is_empty()==false) data[20] >> channel7Enable;
if (data[21].is_empty()==false) data[21] >> bufferDepth;
if (data[22].is_empty()==false) data[22] >> channel0Waveform;
if (data[23].is_empty()==false) data[23] >> channel1Waveform;
if (data[24].is_empty()==false) data[24] >> channel2Waveform;
if (data[25].is_empty()==false) data[25] >> channel3Waveform;
if (data[26].is_empty()==false) data[26] >> channel4Waveform;
if (data[27].is_empty()==false) data[27] >> channel5Waveform;
if (data[28].is_empty()==false) data[28] >> channel6Waveform;
if (data[29].is_empty()==false) data[29] >> channel7Waveform;
// End of Automatic code generation
//-------------------------------------------------------------
Tango::DbData data_put;
//-------------------------------------------------------------
if (data[0].is_empty()==false)
{
unsigned short bnum;
data[0] >> bnum;
//check value
if(bnum<0 || bnum>= 7)//num max of boards in chassis
{
WARN_STREAM<<"ContinuousAO::get_device_property: the value of BoardNum is invalid"
<<"using default value "<<boardNum<<endl;
}
else
{
boardNum = bnum;
}
}
else
{
Tango::DbDatum property("BoardNum");
property << boardNum;
data_put.push_back(property);
WARN_STREAM<<"BoardNum property is not set in database, loading default value in database:"
<<boardNum<<endl;
}
//-------------------------------------------------------------
if (data[1].is_empty()==false)
{
data[1] >> frequency;
}
else
{
Tango::DbDatum property("Frequency");
property << frequency;
data_put.push_back(property);
WARN_STREAM<<"Frequency property is not set in database, loading default value in database:"
<<frequency<<endl;
}
//-------------------------------------------------------------
if (data[2].is_empty()==false)
{
data[2] >> startTrigger;
}
else
{
Tango::DbDatum property("StartTrigger");
property << startTrigger;
data_put.push_back(property);
WARN_STREAM<<"StartTrigger property is not set in database, loading default value in database:"
<<startTrigger<<endl;
}
//-------------------------------------------------------------
if (data[3].is_empty()==false)
{
data[3] >> stopTrigger;
}
else
{
Tango::DbDatum property("StopTrigger");
property << stopTrigger;
data_put.push_back(property);
WARN_STREAM<<"StopTrigger property is not set in database, loading default value in database:"
<<stopTrigger<<endl;
}
//-------------------------------------------------------------
if (data[4].is_empty()==false)
{
data[4] >> startTriggerSource;
string start_source;
data[4] >> start_source;
if(start_source == "DTRIG")
startTriggerSource = adl::external_digital;
else if(start_source == "ATRIG")
startTriggerSource = adl::external_analog;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of StartTriggerSource is not valid"
<<"using default value "<<default_start_source<<endl;
}
else
{
Tango::DbDatum property("StartTriggerSource");
property << default_start_source;
data_put.push_back(property);
WARN_STREAM<<"StartTriggerSource property is not set in database, loading default value in database:"
<<default_start_source<<endl;
}
//-------------------------------------------------------------
if (data[5].is_empty()==false)
{
string stop_source;
data[5] >> stop_source;
if(stop_source == "ATRIG")
stopTriggerSource = adl::analog_trigger_termination;
else if(stop_source == "AFI0")
stopTriggerSource = adl::afi0_termination;
else if(stop_source == "AFI1")
stopTriggerSource = adl::afi1_termination;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of StopTriggerSource is not valid"
<<"using default value "<<default_stop_source<<endl;
}
else
{
Tango::DbDatum property("StopTriggerSource");
property << default_stop_source;
data_put.push_back(property);
WARN_STREAM<<"StopTriggerSource property is not set in database, loading default value in database:"
<<default_stop_source<<endl;
}
//-------------------------------------------------------------
if (data[6].is_empty()==false)
{
string atrig_select;
data[6] >> atrig_select;
if(atrig_select == "BELOW")
aTRIGSelection = adl::below_low_level;
else if(atrig_select == "ABOVE")
aTRIGSelection = adl::above_high_level;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of ATRIGSelection is not valid"
<<"using default value "<<default_atrig_select<<endl;
}
else
{
Tango::DbDatum property("ATRIGSelection");
property << default_atrig_select;
data_put.push_back(property);
WARN_STREAM<<"ATRIGSelection property is not set in database, loading default value in database:"
<<default_atrig_select<<endl;
}
//-------------------------------------------------------------
if (data[7].is_empty()==false)
{
data[7] >> aTRIGLevel;
}
else
{
Tango::DbDatum property("ATRIGLevel");
property << aTRIGLevel;
data_put.push_back(property);
WARN_STREAM<<"ATRIGLevel property is not set in database, loading default value in database:"
<<aTRIGLevel<<endl;
}
//-------------------------------------------------------------
if (data[8].is_empty()==false)
{
string dtrig_pol;
data[8] >> dtrig_pol;
if(dtrig_pol == "RISING")
dTRIGPolarity = adl::ao_rising_edge;
else if(dtrig_pol == "FALLING")
dTRIGPolarity = adl::ao_falling_edge;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of DTRIGPolarity is not valid"
<<"using default value "<<default_dtrig_pol<<endl;
}
else
{
Tango::DbDatum property("DTRIGPolarity");
property << default_dtrig_pol;
data_put.push_back(property);
WARN_STREAM<<"DTRIGPolarity property is not set in database, loading default value in database:"
<<default_dtrig_pol<<endl;
}
//-------------------------------------------------------------
if (data[9].is_empty()==false)
{
double ref;
data[9] >> ref;
if(ref >= -10.0 || ref <= 10.0)
aORefA = ref;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of AORefA is not valid"
<<"using default value "<<aORefA<<endl;
}
else
{
Tango::DbDatum property("AORefA");
property << aORefA;
data_put.push_back(property);
WARN_STREAM<<"AORefA property is not set in database, loading default value in database:"
<<aORefA<<endl;
}
//-------------------------------------------------------------
if (data[10].is_empty()==false)
{
double ref;
data[9] >> ref;
if(ref >= -10.0 || ref <= 10.0)
aORefB = ref;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of AORefB is not valid"
<<"using default value "<<aORefB<<endl;
}
else
{
Tango::DbDatum property("AORefB");
property << aORefB;
data_put.push_back(property);
WARN_STREAM<<"AORefB property is not set in database, loading default value in database:"
<<aORefB<<endl;
}
//-------------------------------------------------------------
if (data[11].is_empty()==false)
{
string pol;
data[11] >> pol;
if(pol == "BP")
polarity = adl::bipolar;
else if(pol == "UP")
polarity = adl::unipolar;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of Polarity is not valid"
<<"using default value "<<default_pol<<endl;
}
else
{
Tango::DbDatum property("Polarity");
property << default_pol;
data_put.push_back(property);
WARN_STREAM<<"Polarity property is not set in database, loading default value in database:"
<<default_pol<<endl;
}
//-------------------------------------------------------------
if (data[12].is_empty()==false)
{
string aoref;
data[12] >> aoref;
if(aoref == "INTERN")
aORefSource = adl::internal_reference;
else if(aoref == "EXTERN")
aORefSource = adl::external_reference;
else
WARN_STREAM<<"ContinuousAO::get_device_property: the value of AORefSource is not valid"
<<"using default value "<<default_aoref<<endl;
}
else
{
Tango::DbDatum property("AORefSource");
property << default_aoref;
data_put.push_back(property);
WARN_STREAM<<"AORefSource property is not set in database, loading default value in database:"
<<default_aoref<<endl;
}
//-------------------------------------------------------------
if (data[13].is_empty()==false)
{
data[13] >> channel0Enable;
}
else
{
Tango::DbDatum property("Channel0Enable");
property << channel0Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel0Enable property is not set in database, loading default value in database:"
<<channel0Enable<<endl;
}
//-------------------------------------------------------------
if (data[14].is_empty()==false)
{
data[14] >> channel1Enable;
}
else
{
Tango::DbDatum property("Channel1Enable");
property << channel1Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel1Enable property is not set in database, loading default value in database:"
<<channel1Enable<<endl;
}
//-------------------------------------------------------------
if (data[15].is_empty()==false)
{
data[15] >> channel2Enable;
}
else
{
Tango::DbDatum property("Channel2Enable");
property << channel2Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel2Enable property is not set in database, loading default value in database:"
<<channel2Enable<<endl;
}
//-------------------------------------------------------------
if (data[16].is_empty()==false)
{
data[16] >> channel3Enable;
}
else
{
Tango::DbDatum property("Channel3Enable");
property << channel3Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel3Enable property is not set in database, loading default value in database:"
<<channel3Enable<<endl;
}
//-------------------------------------------------------------
if (data[17].is_empty()==false)
{
data[17] >> channel4Enable;
}
else
{
Tango::DbDatum property("Channel4Enable");
property << channel4Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel4Enable property is not set in database, loading default value in database:"
<<channel4Enable<<endl;
}
//-------------------------------------------------------------
if (data[18].is_empty()==false)
{
data[18] >> channel5Enable;
}
else
{
Tango::DbDatum property("Channel5Enable");
property << channel5Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel5Enable property is not set in database, loading default value in database:"
<<channel5Enable<<endl;
}
//-------------------------------------------------------------
if (data[19].is_empty()==false)
{
data[19] >> channel6Enable;
}
else
{
Tango::DbDatum property("Channel6Enable");
property << channel6Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel6Enable property is not set in database, loading default value in database:"
<<channel6Enable<<endl;
}
//-------------------------------------------------------------
if (data[20].is_empty()==false)
{
data[20] >> channel7Enable;
}
else
{
Tango::DbDatum property("Channel7Enable");
property << channel7Enable;
data_put.push_back(property);
WARN_STREAM<<"Channel7Enable property is not set in database, loading default value in database:"
<<channel7Enable<<endl;
}
//-------------------------------------------------------------
if (data[21].is_empty()==false)
{
data[21] >> bufferDepth;
}
else
{
Tango::DbDatum property("BufferDepth");
property << bufferDepth;
data_put.push_back(property);
WARN_STREAM<<"BufferDepth property is not set in database, loading default value in database:"
<<bufferDepth<<endl;
}
//update database for not initiliazed properties
get_db_device()->put_property(data_put);
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::always_executed_hook()
//
// description : method always executed before any command is executed
//
//-----------------------------------------------------------------------------
void ContinuousAO::always_executed_hook()
{
this->set_internal_state();
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::read_attr_hardware()
//
// description : Hardware acquisition for attributes.
//
//-----------------------------------------------------------------------------
void ContinuousAO::read_attr_hardware(vector<long> &attr_list)
{
DEBUG_STREAM << "In read_attr_hardware for " << attr_list.size();
DEBUG_STREAM << " attribute(s)" << endl;
// Add your own code here
//---------------------------------
ao->lock_data();
this->err_ctr = ao->err_ctr;
ao->unlock_data();
}
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::read_attr()
//
// description : Extract real attribute values from
// hardware acquisition result.
//
//-----------------------------------------------------------------------------
void ContinuousAO::read_attr(Tango::Attribute &attr)
{
string &attr_name = attr.get_name();
DEBUG_STREAM << "In read_attr for attribute " << attr_name << endl;
// Switch on attribute name
//---------------------------------
if (attr_name == "channel0")
{
if(channel0Enable)
attr.set_value(ch0, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel1")
{
if(channel1Enable)
attr.set_value(ch1, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel2")
{
if(channel2Enable)
attr.set_value(ch2, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel3")
{
if(channel3Enable)
attr.set_value(ch3, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel4")
{
if(channel4Enable)
attr.set_value(ch4, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel5")
{
if(channel5Enable)
attr.set_value(ch5, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel6")
{
if(channel6Enable)
attr.set_value(ch6, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel7")
{
if(channel7Enable)
attr.set_value(ch7, bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "errorCounter")
{
attr.set_value(&err_ctr);
}
else if (attr_name == "useBoardFifo")
{
// the information about data loading on fifo in available only after Start command.
if(this->get_state() == Tango::RUNNING)
attr.set_value(&use_fifo);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else
if (attr_name == "channel0Enable")
{
attr.set_value(&channel0Enable);
}
else
if (attr_name == "channel1Enable")
{
attr.set_value(&channel1Enable);
}
else
if (attr_name == "channel2Enable")
{
attr.set_value(&channel2Enable);
}
else
if (attr_name == "channel3Enable")
{
attr.set_value(&channel3Enable);
}
else
if (attr_name == "channel4Enable")
{
attr.set_value(&channel4Enable);
}
else
if (attr_name == "channel5Enable")
{
attr.set_value(&channel5Enable);
}
else
if (attr_name == "channel6Enable")
{
attr.set_value(&channel6Enable);
}
else
if (attr_name == "channel7Enable")
{
attr.set_value(&channel7Enable);
}
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::start
*
* description: method to execute "Start"
* start the generation.
*
*
*/
//+------------------------------------------------------------------
void ContinuousAO::start()
{
DEBUG_STREAM << "ContinuousAO::start(): entering... !" << endl;
ao->lock_data();
ao->err_ctr = 0;
ao->unlock_data();
_ASL_TRY_ACTION
(
ao->start(),
"start",
"ContinuousAO::start",
this->set_internal_state()
);
// get if the output data have been loaded in the onboard FIFO.
// depends on the size of the buffer.
this->use_fifo = ao->use_board_fifo();
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::stop
*
* description: method to execute "Stop"
* stop the generation.
*
*
*/
//+------------------------------------------------------------------
void ContinuousAO::stop()
{
DEBUG_STREAM << "ContinuousAO::stop(): entering... !" << endl;
_ASL_TRY_ACTION
(
ao->stop(),
"stop",
"ContinuousAO::stop",
this->set_internal_state()
);
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::set_aoscaled_data
*
* description: method to execute "SetAOScaledData"
* Give one period of the signal to generated of a specified channel in volts.
*
* @param argin The channel number ,in string). The output data in volts ,in double)
*
*/
//+------------------------------------------------------------------
void ContinuousAO::set_aoscaled_data(const Tango::DevVarDoubleStringArray *argin)
{
DEBUG_STREAM << "ContinuousAO::set_aoscaled_data(): entering... !" << endl;
if((*argin).svalue.length() != 1)
{
Tango::Except::throw_exception(
(const char*)("OPERATION_NOT_ALLOWED"),
(const char*)("The size of the string argument must be 1"),
(const char*)("ContinuousAO::set_aoscaled_data")
);
}
Tango::DevVarStringArray chan_dvsa = (*argin).svalue;
string chan_s = chan_dvsa[0];
char chan = chan_s[0];
if(chan < '0' || chan > '7')
{
Tango::Except::throw_exception(
(const char*)("OPERATION_NOT_ALLOWED"),
(const char*)("The string argument must be between 0 and 7"),
(const char*)("ContinuousAO::set_aoscaled_data")
);
}
if((*argin).dvalue.length() != bufferDepth)
{
Tango::Except::throw_exception(
(const char*)("OPERATION_NOT_ALLOWED"),
(const char*)("The depth of the given buffer must be the same as specified in Device Properties"),
(const char*)("ContinuousAO::set_aoscaled_data")
);
}
// stop the current generation
_ASL_TRY_ACTION
(
ao->stop(),
"stop",
"ContinuousAO::set_aoscaled_data",
this->set_internal_state()
);
// get the configuration
asl::ContinuousAOConfig config = ao->configuration();
// copy the input data in a buffer of type asl::AOScaledData
asl::AOScaledData data(bufferDepth);
::memcpy(data.base(), (*argin).dvalue.get_buffer(), ((*argin).dvalue.length())*sizeof(double));
//NB: if a chan hasn't been enable with properties, 'ao' will do nothing
config.set_channel_periodic_data(chan - '0', data);
// copy the new data in the attributes of the device.
switch(chan)
{
case '0':
::memcpy(ch0, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch0, "Channel0Waveform");
break;
case '1':
::memcpy(ch1, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch1, "Channel1Waveform");
break;
case '2':
::memcpy(ch2, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch2, "Channel2Waveform");
break;
case '3':
::memcpy(ch3, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch3, "Channel3Waveform");
break;
case '4':
::memcpy(ch4, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch4, "Channel4Waveform");
break;
case '5':
::memcpy(ch5, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch5, "Channel5Waveform");
break;
case '6':
::memcpy(ch6, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch6, "Channel6Waveform");
break;
case '7':
::memcpy(ch7, data.base(), data.size());
//save the waveform in the database
this->save_waveform(ch7, "Channel7Waveform");
break;
default:
Tango::Except::throw_exception(
(const char*)("OPERATION_NOT_ALLOWED"),
(const char*)("The string argument must be between 0 and 7"),
(const char*)("ContinuousAO::set_aoscaled_data")
);
break;
}
// give the configuration with a new channel
_ASL_TRY_ACTION
(
ao->configure(config),
"configure",
"ContinuousAO::set_aoscaled_data",
this->set_internal_state()
);
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::set_internal_state
*/
//+------------------------------------------------------------------
void ContinuousAO::set_internal_state(void)
{
if(ao == 0)
{
this->set_state(Tango::UNKNOWN);
this->set_status("The acquisition was not initialized properly");
}
else
{
switch(ao->state())
{
case asl::ContinuousAO::STANDBY:
this->set_state(Tango::STANDBY);
this->set_status("The generation is stopped");
break;
case asl::ContinuousAO::RUNNING:
case asl::ContinuousAO::ABORTING:
this->set_state(Tango::RUNNING);
this->set_status("The generation is running");
break;
case asl::ContinuousAO::FAULT:
this->set_state(Tango::FAULT);
this->set_status("An error has occured");
break;
case asl::ContinuousAO::UNKNOWN:
default:
this->set_state(Tango::UNKNOWN);
this->set_status("The generation is in an unknown state");
break;
}
}
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::save_waveform
* Save a waveform in tango database
*/
//+------------------------------------------------------------------
void ContinuousAO::save_waveform(double* waveform, string wfm_channel)
{
// cpy the waveform in a double vector
vector<double> vec;
for(int i=0; i<bufferDepth; i++)
vec.push_back(waveform[i]);
//put the vector in a DBDatum
Tango::DbDatum dbdatum(wfm_channel);
dbdatum << vec;
// put it in a DbData
Tango::DbData db_data;
db_data.push_back(dbdatum);
get_db_device()->set_timeout_millis(30000);
// put the waveform in the database
_DEV_TRY
(
get_db_device()->put_property(db_data),
"put_property",
"ContinuousAO::save_waveform",
);
}
} // namespace