Skip to content
Snippets Groups Projects
Select Git revision
  • main
  • SCAN-820
  • 4.0
  • v3.8.10
  • v3.8.9
  • v3.8.8
  • v3.8.7
  • v3.8.6
  • v3.8.5
  • v3.8.4
  • v3.8.3
  • v3.8.2
  • Salsa-3.8.1
  • Salsa-3.8.0
  • Salsa-3.7.0
  • Salsa-3.6.4
  • Salsa-3.6.3
  • Salsa-3.6.2
  • Salsa-3.6.1
  • Salsa-3.5.32
  • Salsa-3.5.30
  • Salsa-3.5.25
  • Salsa-3.5.24
23 results

pom.xml

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ContinuousAO.cpp 35.48 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()),
    	m_default_waveform(2, asl::AOScaledData(0))
    	{
    		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),
    	m_default_waveform(2, asl::AOScaledData(0))
    	{
    		init_device();
    	}
    	//+----------------------------------------------------------------------------
    	//
    	// method :		ContinuousAO::delete_device()
    	// 
    	// description :	will be called at device destruction or at init command.
    	//
    	//-----------------------------------------------------------------------------
    	void ContinuousAO::delete_device()
    	{
    		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;
    			}
    		}
    	}
    
    
    	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);
    
    		double max_val;
    
    		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)
    	{
    		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());
    		}
    	}
    
    	//+----------------------------------------------------------------------------
    	//
    	// method :		ContinuousAO::init_device()
    	// 
    	// description :	will be called at device initialization.
    	//
    	//-----------------------------------------------------------------------------
    	void ContinuousAO::init_device()
    	{
    		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)
    		{
    			raise_error("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)
    			{
    				raise_error("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{
    			_ASL_TRY(
    					m_ao->init(adl::DAQ2502, boardNum),
    					"init", 
    					"ContinuousAO::init_device"
    				);
    
    			DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl;
    			try{
    				_ASL_TRY(
    						m_ao->configure(config),
    						"configure", 
    						"ContinuousAO::init_device"
    					);	 
    			}
    			catch (...)
    			{
    				raise_error("ContinuousAO::init_device\nError while configuring driver");
    				return;
    			}
    		}
    		catch (...)
    		{
    			raise_error("ContinuousAO::init_device\nError while initializing the driver");
    			return;
    		}
    
    		//m_ao->configure(config);	
    	}
    
    
    	//+----------------------------------------------------------------------------
    	//
    	// 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 = 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);
    										}
    	}
    
    	//+------------------------------------------------------------------
    	/**
    	 *	method:	ContinuousAO::start
    	 *
    	 *	description:	method to execute "Start"
    	 *	start the generation.
    	 *
    	 *
    	 */
    	//+------------------------------------------------------------------
    	void ContinuousAO::start()
    	{
    		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();
    
    	}
    
    	//+------------------------------------------------------------------
    	/**
    	 *	method:	ContinuousAO::stop
    	 *
    	 *	description:	method to execute "Stop"
    	 *	stop the generation.
    	 *
    	 *
    	 */
    	//+------------------------------------------------------------------
    	void ContinuousAO::stop()
    	{
    		DEBUG_STREAM << "ContinuousAO::stop(): entering... !" << endl;
    
    		_ASL_TRY_ACTION
    			(
    			 m_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];
    		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()
    			);
    
    	}
    	//+------------------------------------------------------------------
    	/**
    	 *	method: ContinuousAO::set_internal_state
    	 */
    	//+------------------------------------------------------------------
    	void  ContinuousAO::set_internal_state(void)
    	{
    		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;
    			}
    		}
    	}
    	//+------------------------------------------------------------------
    	/**
    	 *	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