Skip to content
Snippets Groups Projects

Refactoring of ContinuousAO code : Communalisation of copy/pasted portions of code

2 files
+ 8
16
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 1089
1371
@@ -65,1402 +65,1120 @@ static const char *RcsId = "$Header: /users/chaize/newsvn/cvsroot/InputOutput/AD
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();
}
//+----------------------------------------------------------------------------
//
// 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()),
m_default_waveform(2, asl::AOScaledData(0))
{
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) : Tango::Device_2Impl(cl,s),
m_default_waveform(2, asl::AOScaledData(0))
{
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;
m_error_message = "An error has occured";
// Initialise variables to default values
//--------------------------------------------
get_device_property();
//- create a continuous analog output daq
ao = new ADLinkContinuousAO(this);
//- check memory allocation
if (ao == 0)
{
raise_error("ContinuousAO::init_device\nout of memory error while initializing ADLinkContinuousAO");
return;
}
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)
{
raise_error("ContinuousAO::init_device\nout of memory error while initializing channel's datas");
return;
}
// 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(ch0, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(ch1, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(ch2, default_waveformA.base(), default_waveformA.size());
ACE_OS::memcpy(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(ch4, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(ch5, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(ch6, default_waveformB.base(), default_waveformB.size());
ACE_OS::memcpy(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;
try{
_ASL_TRY(
ao->init(adl::DAQ2502, boardNum),
"init",
"ContinuousAO::init_device"
);
DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl;
try{
_ASL_TRY(
ao->configure(config),
"configure",
"ContinuousAO::init_device"
);
ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,const char *s,const char *d) : Tango::Device_2Impl(cl,s,d),
m_default_waveform(2, asl::AOScaledData(0))
{
init_device();
}
catch (...)
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::delete_device()
//
// description : will be called at device destruction or at init command.
//
//-----------------------------------------------------------------------------
void ContinuousAO::delete_device()
{
raise_error("ContinuousAO::init_device\nError while configuring driver");
return;
if(m_ao)
{
delete m_ao;
m_ao = 0;
}
for (int i = 0; i < 8; i++)
{
if (m_channel[i] != nullptr)
{
delete m_channel[i];
m_channel[i] = nullptr;
}
}
}
}
catch (...)
{
raise_error("ContinuousAO::init_device\nError while initializing the driver");
return;
}
//ao->configure(config);
}
asl::AOScaledData ContinuousAO::assign_default_waveform(Tango::DevDouble p_ref, std::function <double(int, int)> p_lambda, int p_first_channel, int p_last_channel)
{
// default waveform for group defined
asl::AOScaledData result = asl::AOScaledData(bufferDepth);
//+----------------------------------------------------------------------------
//
// 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()
{
set_internal_state();
}
double max_val;
//+----------------------------------------------------------------------------
//
// 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();
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")
if(aORefSource == adl::external_reference)
max_val = p_ref;
else
max_val = 10.0;
// fill buffer with a sin signal
for (unsigned long i = 0; i < bufferDepth; i++)
{
(result)[i] = p_lambda(i, max_val);
}
//Assignation of waveform for group
for (int i = p_first_channel; i <= p_last_channel; i++)
{
ACE_OS::memcpy(m_channel[i], result.base(), result.size());
}
return (result);
}
void ContinuousAO::activate_channel(int p_channel_index, vector<double>& p_channel_wave_form, asl::AOScaledData& p_default_waveform)
{
// the information about data loading on fifo in available only after Start command.
if(get_state() == Tango::RUNNING)
attr.set_value(&use_fifo);
else
attr.set_quality(Tango::ATTR_INVALID);
m_ac.id = p_channel_index;
if(aORefSource == adl::external_reference)
m_ac.volt_ref = aORefA;
m_config.add_active_channel(m_ac);
if(p_channel_wave_form.empty())
{
WARN_STREAM<<"No waveform is saved in database for channel " << p_channel_index << ", using a default one"<<endl;
m_config.set_channel_periodic_data(p_channel_index, p_default_waveform);
}
else if(p_channel_wave_form.size() != bufferDepth)
{
WARN_STREAM<<"The waveform saved in database for channel " << p_channel_index << " has a different size from property BufferDepth, using default waveform"<<endl;
m_config.set_channel_periodic_data(p_channel_index, p_default_waveform);
}
else
{
asl::AOScaledData data(bufferDepth);
for(int i=0; i<bufferDepth; i++)
data[i] = p_channel_wave_form[i];
// put the waveform in the configuration
m_config.set_channel_periodic_data(p_channel_index, data);
//cpy data in the attribute of the device
::memcpy(m_channel[p_channel_index], data.base(), data.size());
}
}
else
if (attr_name == "channel0Enable")
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::init_device()
//
// description : will be called at device initialization.
//
//-----------------------------------------------------------------------------
void ContinuousAO::init_device()
{
attr.set_value(&channel0Enable);
INFO_STREAM << "ContinuousAO::ContinuousAO() create device " << device_name << endl;
m_ao = nullptr;
m_error_message = "An error has occured";
// Initialise variables to default values
//--------------------------------------------
get_device_property();
//- create a continuous analog output daq
m_ao = new ADLinkContinuousAO(this);
//- check memory allocation
if (m_ao == nullptr)
{
on_fault("ContinuousAO::init_device\nout of memory error while initializing ADLinkContinuousAO");
return;
}
asl::ContinuousAOConfig config;
for (int i = 0; i < 8; i++)
{
m_channel[i] = new double[bufferDepth];
if(m_channel[i] == nullptr)
{
on_fault("ContinuousAO::init_device\nout of memory error while initializing channel's datas");
return;
}
}
// default waveform for group A (channel 0 to 3)
m_default_waveform[0] = assign_default_waveform(aORefA, [&](int p_value, int p_max_value){
return (::sin((double)p_value * 2. * 3.14159 / (double) bufferDepth) * p_max_value);
}, 0, 3);
// default waveform for group A (channel 0 to 3)
m_default_waveform[1] = assign_default_waveform(aORefB, [&](int p_value, int p_max_value){
if (p_value < bufferDepth/2)
return (p_max_value - 0.01);
else
return (-p_max_value + 0.01);
}, 4, 7);
//--------------------------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/m_config. channel 0---------
if(channel0Enable)
activate_channel(0, channel0Waveform, m_default_waveform[0]);
//------active/m_config. channel 1---------
if(channel1Enable)
activate_channel(1, channel1Waveform, m_default_waveform[0]);
//------active/m_config. channel 2---------
if(channel2Enable)
activate_channel(2, channel2Waveform, m_default_waveform[0]);
//------active/m_config. channel 3---------
if(channel3Enable)
activate_channel(3, channel3Waveform, m_default_waveform[0]);
//------active/m_config. channel 4---------
if(channel4Enable)
activate_channel(4, channel4Waveform, m_default_waveform[1]);
//------active/m_config. channel 5---------
if(channel5Enable)
activate_channel(5, channel5Waveform, m_default_waveform[1]);
//------active/m_config. channel 6---------
if(channel6Enable)
activate_channel(6, channel6Waveform, m_default_waveform[1]);
//------active/m_config. channel 7---------
if(channel7Enable)
activate_channel(7, channel7Waveform, m_default_waveform[1]);
//--------------------------------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;
try{
m_ao->init(adl::DAQ2502, boardNum);
DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl;
try{
m_ao->configure(config);
}
catch (...)
{
on_fault("ContinuousAO::init_device\nError while configuring driver");
return;
}
}
catch (...)
{
on_fault("ContinuousAO::init_device\nError while initializing the driver");
return;
}
//m_ao->configure(config);
}
else
if (attr_name == "channel1Enable")
//+----------------------------------------------------------------------------
//
// method : ContinuousAO::readDeviceProperies()
//
// description : Read the device properties from database.
//
//-----------------------------------------------------------------------------
void ContinuousAO::get_device_property()
{
attr.set_value(&channel1Enable);
// 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 = true;
channel1Enable = false;
channel2Enable = false;
channel3Enable = false;
channel4Enable = false;
channel5Enable = false;
channel6Enable = false;
channel7Enable = false;
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()
{
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
//---------------------------------
m_ao->lock_data();
m_err_ctr = m_ao->err_ctr;
m_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(m_channel[0], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel1")
{
if(channel1Enable)
attr.set_value(m_channel[1], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel2")
{
if(channel2Enable)
attr.set_value(m_channel[2], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel3")
{
if(channel3Enable)
attr.set_value(m_channel[3], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel4")
{
if(channel4Enable)
attr.set_value(m_channel[4], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel5")
{
if(channel5Enable)
attr.set_value(m_channel[5], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel6")
{
if(channel6Enable)
attr.set_value(m_channel[6], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "channel7")
{
if(channel7Enable)
attr.set_value(m_channel[7], bufferDepth);
else
attr.set_quality(Tango::ATTR_INVALID);
}
else if (attr_name == "errorCounter")
{
attr.set_value(&m_err_ctr);
}
else if (attr_name == "useBoardFifo")
{
// the information about data loading on fifo in available only after Start command.
if(get_state() == Tango::RUNNING)
attr.set_value(&m_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);
}
}
else
if (attr_name == "channel2Enable")
//+------------------------------------------------------------------
/**
* method: ContinuousAO::start
*
* description: method to execute "Start"
* start the generation.
*
*
*/
//+------------------------------------------------------------------
void ContinuousAO::start()
{
attr.set_value(&channel2Enable);
DEBUG_STREAM << "ContinuousAO::start(): entering... !" << endl;
m_ao->lock_data();
m_ao->err_ctr = 0;
m_ao->unlock_data();
_ASL_TRY_ACTION
(
m_ao->start(),
"start",
"ContinuousAO::start",
set_internal_state()
);
// get if the output data have been loaded in the onboard FIFO.
// depends on the size of the buffer.
m_use_fifo = m_ao->use_board_fifo();
}
else
if (attr_name == "channel3Enable")
//+------------------------------------------------------------------
/**
* method: ContinuousAO::stop
*
* description: method to execute "Stop"
* stop the generation.
*
*
*/
//+------------------------------------------------------------------
void ContinuousAO::stop()
{
attr.set_value(&channel3Enable);
DEBUG_STREAM << "ContinuousAO::stop(): entering... !" << endl;
_ASL_TRY_ACTION
(
m_ao->stop(),
"stop",
"ContinuousAO::stop",
set_internal_state()
);
}
else
if (attr_name == "channel4Enable")
//+------------------------------------------------------------------
/**
* 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)
{
attr.set_value(&channel4Enable);
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];
int channel_index = chan_s[0] - '0';
if(channel_index < 0 || channel_index > 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
(
m_ao->stop(),
"stop",
"ContinuousAO::set_aoscaled_data",
set_internal_state()
);
// get the configuration
asl::ContinuousAOConfig config = m_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, 'm_ao' will do nothing
config.set_channel_periodic_data(channel_index, data);
// copy the new data in the attributes of the device.
::memcpy(m_channel[channel_index], data.base(), data.size());
//save the waveform in the database
save_waveform(m_channel[channel_index], "Channel" + std::to_string(channel_index) + "Waveform");
// give the configuration with a new channel
_ASL_TRY_ACTION
(
m_ao->configure(config),
"configure",
"ContinuousAO::set_aoscaled_data",
set_internal_state()
);
}
else
if (attr_name == "channel5Enable")
//+------------------------------------------------------------------
/**
* method: ContinuousAO::set_internal_state
*/
//+------------------------------------------------------------------
void ContinuousAO::set_internal_state(void)
{
attr.set_value(&channel5Enable);
if(m_ao == 0)
{
set_state(Tango::UNKNOWN);
set_status("The acquisition was not initialized properly");
}
else
{
switch(m_ao->state())
{
case asl::ContinuousAO::STANDBY:
set_state(Tango::STANDBY);
set_status("The generation is stopped");
break;
case asl::ContinuousAO::RUNNING:
case asl::ContinuousAO::ABORTING:
set_state(Tango::RUNNING);
set_status("The generation is running");
break;
case asl::ContinuousAO::FAULT:
set_state(Tango::FAULT);
set_status(m_error_message);
break;
case asl::ContinuousAO::UNKNOWN:
default:
set_state(Tango::UNKNOWN);
set_status("The generation is in an unknown state");
break;
}
}
}
else
if (attr_name == "channel6Enable")
//+------------------------------------------------------------------
/**
* method: ContinuousAO::save_waveform
* Save a waveform in tango database
*/
//+------------------------------------------------------------------
void ContinuousAO::save_waveform(double* waveform, string wfm_channel)
{
attr.set_value(&channel6Enable);
// 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()->get_dbase()->set_timeout_millis(30000);
// put the waveform in the database
_DEV_TRY
(
get_db_device()->put_property(db_data),
"put_property",
"ContinuousAO::save_waveform",
);
}
else
if (attr_name == "channel7Enable")
void ContinuousAO::on_fault(std::string p_error_message)
{
attr.set_value(&channel7Enable);
m_error_message = p_error_message;
set_state(Tango::FAULT);
}
}
//+------------------------------------------------------------------
/**
* 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",
set_internal_state()
);
// get if the output data have been loaded in the onboard FIFO.
// depends on the size of the buffer.
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",
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",
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
save_waveform(ch0, "Channel0Waveform");
break;
case '1':
::memcpy(ch1, data.base(), data.size());
//save the waveform in the database
save_waveform(ch1, "Channel1Waveform");
break;
case '2':
::memcpy(ch2, data.base(), data.size());
//save the waveform in the database
save_waveform(ch2, "Channel2Waveform");
break;
case '3':
::memcpy(ch3, data.base(), data.size());
//save the waveform in the database
save_waveform(ch3, "Channel3Waveform");
break;
case '4':
::memcpy(ch4, data.base(), data.size());
//save the waveform in the database
save_waveform(ch4, "Channel4Waveform");
break;
case '5':
::memcpy(ch5, data.base(), data.size());
//save the waveform in the database
save_waveform(ch5, "Channel5Waveform");
break;
case '6':
::memcpy(ch6, data.base(), data.size());
//save the waveform in the database
save_waveform(ch6, "Channel6Waveform");
break;
case '7':
::memcpy(ch7, data.base(), data.size());
//save the waveform in the database
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",
set_internal_state()
);
}
//+------------------------------------------------------------------
/**
* method: ContinuousAO::set_internal_state
*/
//+------------------------------------------------------------------
void ContinuousAO::set_internal_state(void)
{
if(ao == 0)
{
set_state(Tango::UNKNOWN);
set_status("The acquisition was not initialized properly");
}
else
{
switch(ao->state())
{
case asl::ContinuousAO::STANDBY:
set_state(Tango::STANDBY);
set_status("The generation is stopped");
break;
case asl::ContinuousAO::RUNNING:
case asl::ContinuousAO::ABORTING:
set_state(Tango::RUNNING);
set_status("The generation is running");
break;
case asl::ContinuousAO::FAULT:
set_state(Tango::FAULT);
set_status(m_error_message);
break;
case asl::ContinuousAO::UNKNOWN:
default:
set_state(Tango::UNKNOWN);
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()->get_dbase()->set_timeout_millis(30000);
// put the waveform in the database
_DEV_TRY
(
get_db_device()->put_property(db_data),
"put_property",
"ContinuousAO::save_waveform",
);
}
void ContinuousAO::raise_error(std::string p_error_message)
{
m_error_message = p_error_message;
set_state(Tango::FAULT);
}
} // namespace
Loading