Skip to content
Snippets Groups Projects
Select Git revision
  • 741b2a84c4d78035e449650fa17a1ddfccebf221
  • main default protected
  • release_1_0_5
  • release_1_0_4
  • release_1_0_3
  • release_1_0_2
  • release_1_0_1
  • release_1_0_0
  • release_0_2
  • release_0_1
  • v0
11 results

ContinuousAO.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ContinuousAO.cpp 43.96 KiB
    static const char *RcsId = "$Header: /users/chaize/newsvn/cvsroot/InputOutput/ADLINK/ContinuousAO/src/ContinuousAO.cpp,v 1.8 2005-06-15 10:22:16 abeilleg Exp $";
    //+=============================================================================
    //
    // file :	  ContinuousAO.cpp
    //
    // description :  C++ source for the ContinuousAO and its commands. 
    //		  The class is derived from Device. It represents the
    //		  CORBA servant object which will be accessed from the
    //		  network. All commands which can be executed on the
    //		  ContinuousAO are implemented in this file.
    //
    // project :	  TANGO Device Server
    //
    // $Author: abeilleg $
    //
    // $Revision: 1.8 $
    //
    // $Log: not supported by cvs2svn $
    // Revision 1.7  2005/04/21 08:33:44  abeilleg
    // update state in always_exe_hk
    //
    // Revision 1.6  2005/01/25 10:12:58  abeilleg
    // status changed.
    //
    // Revision 1.5  2005/01/20 13:21:51  abeilleg
    // following ASL modifications (states management).
    //
    // Revision 1.4  2004/12/21 13:06:59  abeilleg
    // minor bugs fixed
    //
    //
    // copyleft :	  Synchrotron SOLEIL
    //		  L'Orme des Merisiers
    //		  Saint-Aubin - BP 48
    
    //
    //-=============================================================================
    //
    //		This file is generated by POGO
    //	(Program Obviously used to Generate tango Object)
    //
    //	   (c) - Software Engineering Group - ESRF
    //=============================================================================
    
    
    //===================================================================
    //
    //	The folowing table gives the correspondance
    //	between commands and method's name.
    //
    //	Command's name	|	Method's name
    //	----------------------------------------
    //	State	|	dev_state()
    //	Status	|	dev_status()
    //	Start	|	start()
    //	Stop	|	stop()
    //	SetAOScaledData	|	set_aoscaled_data()
    //
    //===================================================================
    #include <ContinuousAO.h>
    #include <TangoExceptionsHelper.h>
    #include <asl/ASLExceptionsHandler.h>
    #include <asl/AOData.h>
    #include <math.h>
    namespace ContinuousAO
    {
    
    //+----------------------------------------------------------------------------
    //
    // method :		ContinuousAO::ContinuousAO(string &s)
    // 
    // description :	constructor for simulated ContinuousAO
    //
    // in : - cl : Pointer to the DeviceClass object
    //	- s : Device name 
    //
    //-----------------------------------------------------------------------------
    ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,string &s):Tango::Device_2Impl(cl,s.c_str())
    {
    	init_device();
    }
    
    ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,const char *s):Tango::Device_2Impl(cl,s)
    {
    	init_device();
    }
    
    ContinuousAO::ContinuousAO(Tango::DeviceClass *cl,const char *s,const char *d)
    :Tango::Device_2Impl(cl,s,d)
    {
    	init_device();
    }
    //+----------------------------------------------------------------------------
    //
    // method :		ContinuousAO::delete_device()
    // 
    // description :	will be called at device destruction or at init command.
    //
    //-----------------------------------------------------------------------------
    void ContinuousAO::delete_device()
    {
    	//	Delete device's allocated object
      if(ao)
      {
        delete ao;
        ao = 0;
      }
      if(ch0)
      {
        delete ch0;
        ch0 = 0;
      }
      if(ch1)
      {
        delete ch1;
        ch1 = 0;
      }
      if(ch2)
      {
        delete ch2;
        ch2 = 0;
      }
      if(ch3)
      {
        delete ch3;
        ch3 = 0;
      }
      if(ch4)
      {
        delete ch4;
        ch4 = 0;
      }
      if(ch5)
      {
        delete ch5;
        ch5 = 0;
      }
      if(ch6)
      {
        delete ch6;
        ch6 = 0;
      }
      if(ch7)
      {
        delete ch7;
        ch7 = 0;
      }
    }
    
    //+----------------------------------------------------------------------------
    //
    // method :		ContinuousAO::init_device()
    // 
    // description :	will be called at device initialization.
    //
    //-----------------------------------------------------------------------------
    void ContinuousAO::init_device()
    {
      INFO_STREAM << "ContinuousAO::ContinuousAO() create device " << device_name << endl;
      
      ao = 0;
      ch0 = 0;
      ch1 = 0;
      ch2 = 0;
      ch3 = 0;
      ch4 = 0;
      ch5 = 0;
      ch6 = 0;
      ch7 = 0;
      error_message = "";
      
      // Initialise variables to default values
      //--------------------------------------------
      get_device_property();
      
      //- create a continuous analog output daq
      ao = new ADLinkContinuousAO(this);
      
      //- check memory allocation
      if (ao == 0)
      {
        set_internal_state();
        Tango::Except::throw_exception(
          (const char*)("OUT_OF_MEMORY"),
          (const char*)("out of memory error"),
          (const char*)("ContinuousAO::init_device")
          );
      }
      
      asl::ContinuousAOConfig config;
      ch0 = new double[bufferDepth];
      ch1 = new double[bufferDepth];
      ch2 = new double[bufferDepth];
      ch3 = new double[bufferDepth];
      ch4 = new double[bufferDepth];
      ch5 = new double[bufferDepth];
      ch6 = new double[bufferDepth];
      ch7 = new double[bufferDepth];
      if(ch0 == 0 || ch1 == 0 || ch2 == 0 || ch3 == 0 || ch4 == 0 || ch5 == 0 ||ch6 == 0 || ch7 == 0)
      {
        set_internal_state();
        delete_device();
        Tango::Except::throw_exception(
          (const char*)("OUT_OF_MEMORY"),
          (const char*)("out of memory error"),
          (const char*)("ContinuousAO::init_device")
          );
      }
      
      
      // default waveform for group A (channel 0 to 3)
      asl::AOScaledData default_waveformA(bufferDepth);
      double max_valA;
      if(aORefSource == adl::external_reference)
        max_valA = aORefA ;
      else
        max_valA = 10.0;
      
      // fill buffer with a sin signal 
      for (unsigned long i = 0; i < bufferDepth; i++)
      {
        (default_waveformA)[i] = ::sin((double)i * 2. * 3.14159 / (double) bufferDepth) * max_valA;
      }
      
      ACE_OS::memcpy(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 //_ACTION
    		(
    		ao->init(adl::DAQ2502, boardNum),
    		"init", 
    		"ContinuousAO::init_device",
    		set_internal_state()
    		);
    	
      
    	  DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl;
    	  try{
    	  _ASL_TRY //_ACTION
    		(
    		ao->configure(config),
    		"configure", 
    		"ContinuousAO::init_device",
    		set_internal_state()
    		);	 
    	  }
    	  catch (...)
    	  {
    		error_message = "Error while configuring driver";
    	  }
      }
      catch (...)
      {
    	error_message = "Error while init driver";
      }
    
      //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 = 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();
    }
    
    //+----------------------------------------------------------------------------
    //
    // 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")
    	{
        // 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);
    	}
    	else
    	if (attr_name == "channel0Enable")
    	{
    		attr.set_value(&channel0Enable);
    	}
    	else
    	if (attr_name == "channel1Enable")
    	{
    		attr.set_value(&channel1Enable);
    	}
    	else
    	if (attr_name == "channel2Enable")
    	{
    		attr.set_value(&channel2Enable);
    	}
    	else
    	if (attr_name == "channel3Enable")
    	{
    		attr.set_value(&channel3Enable);
    	}
    	else
    	if (attr_name == "channel4Enable")
    	{
    		attr.set_value(&channel4Enable);
    	}
    	else
    	if (attr_name == "channel5Enable")
    	{
    		attr.set_value(&channel5Enable);
    	}
    	else
    	if (attr_name == "channel6Enable")
    	{
    		attr.set_value(&channel6Enable);
    	}
    	else
    	if (attr_name == "channel7Enable")
    	{
    		attr.set_value(&channel7Enable);
    	}
    }
    
    //+------------------------------------------------------------------
    /**
     *	method:	ContinuousAO::start
     *
     *	description:	method to execute "Start"
     *	start the generation.
     *
     *
     */
    //+------------------------------------------------------------------
    void ContinuousAO::start()
    {
      DEBUG_STREAM << "ContinuousAO::start(): entering... !" << endl;
      
      ao->lock_data();
    
      ao->err_ctr = 0;
      
      ao->unlock_data();
    
      _ASL_TRY_ACTION
        (
        ao->start(),
        "start", 
        "ContinuousAO::start",
        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);
    	  if (error_message == "")
    		set_status("An error has occured");
    	  else
    		set_status(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",
        );
    }
    }	//	namespace