// ============================================================================ // // = CONTEXT // TANGO Project - Keithley Electrometer Support Library // // = FILENAME // TangoSerialLink.cpp // // = AUTHOR // X. Elattaoui // // ============================================================================ // ============================================================================ // DEPENDENCIES // ============================================================================ #include <string> #include <iostream> #include "TangoSerialLink.h" //- Read serial data in mode LINE (i.e SerialLine device wait until EOF is received from instrument) static const long MODE_LINE = 2; //- init of the static instance TangoSerialLink* TangoSerialLink::tsl_Instance = 0; //- ptr on the TangoSerialLink instance // ============================================================================ // TangoSerialLink::get_instance // ============================================================================ TangoSerialLink* TangoSerialLink::get_instance(std::string & serial_dev_name) { if( !tsl_Instance ) tsl_Instance = new TangoSerialLink(serial_dev_name); return tsl_Instance; } // ============================================================================ // TangoSerialLink::delete_instance // ============================================================================ void TangoSerialLink::delete_instance(CommunicationLink* tsl_Instance) { if(tsl_Instance) { delete tsl_Instance ; tsl_Instance = 0; } } // ============================================================================ // TangoSerialLink::TangoSerialLink // ============================================================================ TangoSerialLink::TangoSerialLink (std::string& serial_device_name) : CommunicationLink(serial_device_name), _serial_proxy (0), _is_serial_proxy_created (false) { // //std::cout << "TangoSerialLink::TangoSerialLink <-" << std::endl; response.erase(); // //std::cout << "TangoSerialLink::TangoSerialLink ->" << std::endl; } // ============================================================================ // TangoSerialLink::~TangoSerialLink // ============================================================================ TangoSerialLink::~TangoSerialLink (void) { //std::cout << "TangoSerialLink::~TangoSerialLink <-" << std::endl; if(_serial_proxy) { delete _serial_proxy; _serial_proxy = 0; _is_serial_proxy_created = false; } //std::cout << "TangoSerialLink::~TangoSerialLink ->" << std::endl; } // ============================================================================ // TangoSerialLink::create_serial_proxy // ============================================================================ void TangoSerialLink::create_serial_proxy (void) throw (Tango::DevFailed) { std::string description(""); try { //- try this->_serial_proxy = new Tango::DeviceProxy(_communication_Device_name.c_str()); //(*_serial_proxy)->ping(); _is_serial_proxy_created = true; } catch(Tango::DevFailed& df ) { if( this->_serial_proxy ) { delete this->_serial_proxy; this->_serial_proxy = 0; } _is_serial_proxy_created = false; description = "Unable to create proxy on : " + _communication_Device_name; Tango::Except::re_throw_exception (df, (const char*)"ALLOCATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::create_serial_proxy"); } catch(...) { if( this->_serial_proxy ) { delete this->_serial_proxy; this->_serial_proxy = 0; } _is_serial_proxy_created = false; description = "Unable to write command : " + command_to_send + "\nmemory allocation failed."; Tango::Except::throw_exception ( (const char*)"ALLOCATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::write"); } } // ============================================================================ // TangoSerialLink::write // ============================================================================ void TangoSerialLink::write (std::string command_to_send) throw (Tango::DevFailed) { std::string description(""); if(!_serial_proxy) create_serial_proxy(); Tango::DeviceData dd_in; Tango::DevString argin = 0; try { argin = new char [command_to_send.size() + 1]; strcpy(argin, command_to_send.c_str()); } catch(Tango::DevFailed& df ) { if( argin ) { delete [] argin; argin = 0; } description = "Unable to write command : " + command_to_send + + "\nmemory allocation failed."; Tango::Except::re_throw_exception (df, (const char*)"ALLOCATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::write"); } catch(...) { description = "Unable to write command : " + command_to_send + "\nmemory allocation failed."; Tango::Except::throw_exception ( (const char*)"ALLOCATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::write"); } try { //- try dd_in << argin; this->_serial_proxy->command_inout("DevSerWriteString", dd_in); if( argin ) { delete [] argin; argin = 0; } //std::cout << "TangoSerialLink::write -> argin = *\"" << argin << "\"*" << std::endl; } catch(Tango::DevFailed& df ) { if( argin ) { delete [] argin; argin = 0; } description = "Unable to write command : " + command_to_send; Tango::Except::re_throw_exception (df, (const char*)"COMMUNICATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::write"); } catch(...) { if( argin ) { delete [] argin; argin = 0; } description = "Unable to write command : " + command_to_send; Tango::Except::throw_exception ( (const char*)"COMMUNICATION_ERROR", description.c_str(), (const char*)"TangoSerialLink::write"); } } // ============================================================================ // TangoSerialLink::read // ============================================================================ std::string TangoSerialLink::read (void) throw (Tango::DevFailed) { if(!_serial_proxy) create_serial_proxy(); Tango::DeviceData dd_out; try { //- try in mode LINE dd_out = this->_serial_proxy->command_inout("DevSerReadLine"); dd_out >> this->response; } catch(Tango::DevFailed& df ) { Tango::Except::re_throw_exception (df, (const char*)"COMMUNICATION_ERROR", (const char*)"Unable to perform a read operation", (const char*)"TangoSerialLink::read"); } catch(...) { Tango::Except::throw_exception ( (const char*)"COMMUNICATION_ERROR", (const char*)"Unable to perform a read operation", (const char*)"TangoSerialLink::read"); } return this->response ; } // ============================================================================ // TangoSerialLink::read // ============================================================================ std::string TangoSerialLink::read (long nbCharToRead) throw (Tango::DevFailed) { if(!_serial_proxy) create_serial_proxy(); Tango::DeviceData dd_in; Tango::DeviceData dd_out; try { dd_in << nbCharToRead; //- try get the specified nb characters dd_out = this->_serial_proxy->command_inout("DevSerReadNChar", dd_in); dd_out >> this->response; //std::cout << "TangoSerialLink::read -> nb_char = " << nbCharToRead << " and resp : \"" << this->response << "\"" << std::endl; } catch(Tango::DevFailed& df ) { Tango::Except::re_throw_exception (df, (const char*)"COMMUNICATION_ERROR", (const char*)"Unable to perform a read operation", (const char*)"TangoSerialLink::read(nChar)"); } return this->response ; } // ============================================================================ // TangoSerialLink::write_read // ============================================================================ std::string TangoSerialLink::write_read (std::string command_to_send) throw (Tango::DevFailed) { if(!_serial_proxy) create_serial_proxy(); Tango::DeviceData dd_in; std::string respTmp(""); long flush_in_out = 2; dd_in << flush_in_out; //- Flush buffers ( In & Out = 2 ) this->_serial_proxy->command_inout("DevSerFlush", dd_in); omni_thread::sleep(0, 200000000); //200 milliseconds write(command_to_send); //- sleep a little bit to let the adapter(RS232/485) to switch mode omni_thread::sleep(0, 100000000); //100 milliseconds // now read response from HW return this->read(); } // ============================================================================ // TangoSerialLink::write_read : read N char // ============================================================================ std::string TangoSerialLink::write_read (std::string command_to_send, long nbChar) throw (Tango::DevFailed) { if(!_serial_proxy) create_serial_proxy(); Tango::DeviceData dd_in; Tango::DeviceData dd_out; std::string respTmp(""); long flush_in_out = 2; dd_in << flush_in_out; //- Flush buffers ( In & Out = 2 ) this->_serial_proxy->command_inout("DevSerFlush", dd_in); //omni_thread::sleep(0, 200000000); //200 milliseconds write(command_to_send); //- sleep a little bit to let the adapter(RS232/485) to switch mode //omni_thread::sleep(0, 100000000); //100 milliseconds //- wait till characters are available in the input buffer (max 30 retries !) size_t nbRetries = 0; Tango::DevLong nbCharReceived = 0; dd_out = this->_serial_proxy->command_inout("DevSerGetNChar"); dd_out >> nbCharReceived; while ( !nbCharReceived && nbRetries < 50 ) { dd_out = this->_serial_proxy->command_inout("DevSerGetNChar"); dd_out >> nbCharReceived; nbRetries++; //std::cout << "TangoSerialLink::write_read -> nbRetries = " << nbRetries << " & nbCharReceived = " << nbCharReceived << std::endl; } //std::cout << "END WHILE -> nbRetries = " << nbRetries << " & nbCharReceived = " << nbCharReceived << std::endl; // now read response from HW return this->read(nbChar); }