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; m_error_message = "An error has occured"; // Initialise variables to default values //-------------------------------------------- get_device_property(); //- create a continuous analog output daq ao = new ADLinkContinuousAO(this); //- check memory allocation if (ao == 0) { on_fault("ContinuousAO::init_device\nout of memory error while initializing ADLinkContinuousAO"); return; } asl::ContinuousAOConfig config; ch0 = new double[bufferDepth]; ch1 = new double[bufferDepth]; ch2 = new double[bufferDepth]; ch3 = new double[bufferDepth]; ch4 = new double[bufferDepth]; ch5 = new double[bufferDepth]; ch6 = new double[bufferDepth]; ch7 = new double[bufferDepth]; if(ch0 == 0 || ch1 == 0 || ch2 == 0 || ch3 == 0 || ch4 == 0 || ch5 == 0 ||ch6 == 0 || ch7 == 0) { on_fault("ContinuousAO::init_device\nout of memory error while initializing channel's datas"); return; } // default waveform for group A (channel 0 to 3) asl::AOScaledData default_waveformA(bufferDepth); double max_valA; if(aORefSource == adl::external_reference) max_valA = aORefA ; else max_valA = 10.0; // fill buffer with a sin signal for (unsigned long i = 0; i < bufferDepth; i++) { (default_waveformA)[i] = ::sin((double)i * 2. * 3.14159 / (double) bufferDepth) * max_valA; } ACE_OS::memcpy(ch0, default_waveformA.base(), default_waveformA.size()); ACE_OS::memcpy(ch1, default_waveformA.base(), default_waveformA.size()); ACE_OS::memcpy(ch2, default_waveformA.base(), default_waveformA.size()); ACE_OS::memcpy(ch3, default_waveformA.base(), default_waveformA.size()); // default waveform for group A (channel 4 to 7) asl::AOScaledData default_waveformB(bufferDepth); double max_valB; if(aORefSource == adl::external_reference) max_valB = aORefB; else max_valB = 10.0; // fill buffer with a square signal for (i = 0; i < bufferDepth/2; i++) { default_waveformB[i] = max_valB - 0.01; } for (i = bufferDepth/2; i < bufferDepth; i++) { default_waveformB[i] = -max_valB + 0.01; } ACE_OS::memcpy(ch4, default_waveformB.base(), default_waveformB.size()); ACE_OS::memcpy(ch5, default_waveformB.base(), default_waveformB.size()); ACE_OS::memcpy(ch6, default_waveformB.base(), default_waveformB.size()); ACE_OS::memcpy(ch7, default_waveformB.base(), default_waveformB.size()); //--------------------------channels config------------------------------------ asl::ActiveAOChannel ac; // configure all channels ac.polarity = (adl::OutputPolarity)polarity; ac.volt_ref_src = (adl::VoltageReferenceSource)aORefSource; ac.volt_ref = 10.0; //- active/config. channel 0 if(channel0Enable) { ac.id = 0; if(aORefSource == adl::external_reference) ac.volt_ref = aORefA; config.add_active_channel(ac); if(channel0Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 0, using a default one"<<endl; config.set_channel_periodic_data(0, default_waveformA); } else if(channel0Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 0 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(0, default_waveformA); } else //put waveform of the Tango database in ch0 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel0Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(0, data); //cpy data in the attribute of the device ::memcpy(ch0, data.base(), data.size()); } } //- active/config. channel 1 if(channel1Enable) { ac.id = 1; if(aORefSource == adl::external_reference) ac.volt_ref = aORefA; config.add_active_channel(ac); if(channel1Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 1, using a default one"<<endl; config.set_channel_periodic_data(1, default_waveformA); } else if(channel1Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 1 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(1, default_waveformA); } else //put waveform of the Tango database in ch1 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel1Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(1, data); //cpy data in the attribute of the device ::memcpy(ch1, data.base(), data.size()); } } //- active/config. channel 2 if(channel2Enable) { ac.id = 2; if(aORefSource == adl::external_reference) ac.volt_ref = aORefA; config.add_active_channel(ac); config.set_channel_periodic_data(2, default_waveformA); if(channel2Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 2, using a default one"<<endl; config.set_channel_periodic_data(2, default_waveformA); } else if(channel2Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 2 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(2, default_waveformA); } else //put waveform of the Tango database in ch2 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel2Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(2, data); //cpy data in the attribute of the device ::memcpy(ch2, data.base(), data.size()); } } //- active/config. channel 3 if(channel3Enable) { ac.id = 3; if(aORefSource == adl::external_reference) ac.volt_ref = aORefA; config.add_active_channel(ac); if(channel3Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 3, using a default one"<<endl; config.set_channel_periodic_data(3, default_waveformA); } else if(channel3Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 3 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(3, default_waveformA); } else //put waveform of the Tango database in ch3 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel3Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(3, data); //cpy data in the attribute of the device ::memcpy(ch3, data.base(), data.size()); } } //- active/config. channel 4 if(channel4Enable) { ac.id = 4; if(aORefSource == adl::external_reference) ac.volt_ref = aORefB; config.add_active_channel(ac); if(channel4Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 4, using a default one"<<endl; config.set_channel_periodic_data(4, default_waveformB); } else if(channel4Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 4 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(4, default_waveformB); } else //put waveform of the Tango database in ch4 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel4Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(4, data); //cpy data in the attribute of the device ::memcpy(ch4, data.base(), data.size()); } } //- active/config. channel 5 if(channel5Enable) { ac.id = 5; if(aORefSource == adl::external_reference) ac.volt_ref = aORefB; config.add_active_channel(ac); if(channel5Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 5, using a default one"<<endl; config.set_channel_periodic_data(5, default_waveformB); } else if(channel5Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 5 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(5, default_waveformB); } else //put waveform of the Tango database in ch5 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel5Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(5, data); //cpy data in the attribute of the device ::memcpy(ch5, data.base(), data.size()); } } //- active/config. channel 6 if(channel6Enable) { ac.id = 6; if(aORefSource == adl::external_reference) ac.volt_ref = aORefB; config.add_active_channel(ac); if(channel6Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 6, using a default one"<<endl; config.set_channel_periodic_data(6, default_waveformB); } else if(channel6Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 6 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(6, default_waveformB); } else //put waveform of the Tango database in ch6 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel6Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(6, data); //cpy data in the attribute of the device ::memcpy(ch6, data.base(), data.size()); } } //- active/config. channel 7 if(channel7Enable) { ac.id = 7; if(aORefSource == adl::external_reference) ac.volt_ref = aORefB; config.add_active_channel(ac); if(channel7Waveform.empty()) { WARN_STREAM<<"No waveform is saved in database for channel 7, using a default one"<<endl; config.set_channel_periodic_data(7, default_waveformB); } else if(channel7Waveform.size() != bufferDepth) { WARN_STREAM<<"The waveform saved in database for channel 7 has a different size from property BufferDepth, "<< "using default waveform"<<endl; config.set_channel_periodic_data(7, default_waveformB); } else //put waveform of the Tango database in ch7 { // copy the input data in a buffer of type asl::AOScaledData asl::AOScaledData data(bufferDepth); for(int i=0; i<bufferDepth; i++) data[i] = channel7Waveform[i]; // put the waveform in the configuration config.set_channel_periodic_data(7, data); //cpy data in the attribute of the device ::memcpy(ch7, data.base(), data.size()); } } //--------------------------------start trigger config--------------------------------- if(startTrigger) { config.set_trigger_source((adl::AIOTriggerSource)startTriggerSource); config.set_trigger_mode(adl::ao_post); if(startTriggerSource == adl::external_digital) { config.set_trigger_polarity((adl::AOTriggerPolarity)dTRIGPolarity); } else if(startTriggerSource == adl::external_analog) { config.set_analog_trigger_source(adl::analog_trigger_ext); config.set_analog_trigger_condition((adl::AnalogTriggerCondition)aTRIGSelection); unsigned short level; if(aTRIGLevel>=0) level = (aTRIGLevel / 0.078125) + 127; else // v < 0 level = (-aTRIGLevel / 0.078125); //the voltage is converted in digital value (8 bits of resolution on EXTATRIG with +/-10 V (256/20 = 0.078125)) config.set_analog_low_level_condition(level); config.set_analog_high_level_condition(level); } } //--------------------------------stop trigger config--------------------------------- if(stopTrigger) { config.set_stop_mode(adl::wait_end_waveform); config.set_stop_source ((adl::StopSource)stopTriggerSource); } config.set_output_rate(frequency); DEBUG_STREAM<<"ContinuousAO::init_device : init acq"<<std::endl; try{ ao->init(adl::DAQ2502, boardNum); DEBUG_STREAM<<"ContinuousAO::init_device : config acq"<<std::endl; try{ ao->configure(config); } catch (...) { on_fault("ContinuousAO::init_device\nError while configuring driver"); return; } } catch (...) { on_fault("ContinuousAO::init_device\nError while initializing the driver"); return; } //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); 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::on_fault(std::string p_error_message) { m_error_message = p_error_message; set_state(Tango::FAULT); } } // namespace