Skip to content
Snippets Groups Projects
TangoSerialLink.cpp 9.8 KiB
Newer Older
LE's avatar
LE committed
// ============================================================================
//
// = CONTEXT
//    TANGO Project - Keithley Electrometer Support Library
//
// = FILENAME
//    TangoSerialLink.cpp
//
// = AUTHOR
//    X. Elattaoui
//
// ============================================================================

// ============================================================================
// DEPENDENCIES
// ============================================================================
#include <string>
#include <iostream>
#include "TangoSerialLink.h"

ELATTAOUI's avatar
ELATTAOUI committed
//- Read serial data in mode LINE (i.e SerialLine device wait until EOF is received from instrument)
LE's avatar
LE committed

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;
	}
}
LE's avatar
LE committed

// ============================================================================
// TangoSerialLink::TangoSerialLink
// ============================================================================
TangoSerialLink::TangoSerialLink (std::string& serial_device_name) 
:	CommunicationLink(serial_device_name),
	_serial_proxy (0),
	_is_serial_proxy_created (false)
{
ELATTAOUI's avatar
ELATTAOUI committed
//	//std::cout << "TangoSerialLink::TangoSerialLink <-" << std::endl;
LE's avatar
LE committed

	response.erase();

ELATTAOUI's avatar
ELATTAOUI committed
//	//std::cout << "TangoSerialLink::TangoSerialLink ->" << std::endl;
LE's avatar
LE committed
}

// ============================================================================
// TangoSerialLink::~TangoSerialLink
// ============================================================================
TangoSerialLink::~TangoSerialLink (void)
{
ELATTAOUI's avatar
ELATTAOUI committed
	//std::cout << "TangoSerialLink::~TangoSerialLink <-" << std::endl;
LE's avatar
LE committed

ELATTAOUI's avatar
ELATTAOUI committed
	if(_serial_proxy)
LE's avatar
LE committed
	{
		delete _serial_proxy;
		_serial_proxy = 0;
		_is_serial_proxy_created = false;
	}

ELATTAOUI's avatar
ELATTAOUI committed
	//std::cout << "TangoSerialLink::~TangoSerialLink ->" << std::endl;
LE's avatar
LE committed
}


// ============================================================================
// TangoSerialLink::create_serial_proxy
// ============================================================================
void TangoSerialLink::create_serial_proxy (void)  throw (Tango::DevFailed)
{
ELATTAOUI's avatar
ELATTAOUI committed
  std::string description("");
LE's avatar
LE committed

	try
	{
		//- try
		this->_serial_proxy = new Tango::DeviceProxy(_communication_Device_name.c_str());
		//(*_serial_proxy)->ping();
LE's avatar
LE committed
		_is_serial_proxy_created = true;
	}
	catch(Tango::DevFailed& df )
	{
ELATTAOUI's avatar
ELATTAOUI committed
		if( this->_serial_proxy )
		{
			delete this->_serial_proxy;
			this->_serial_proxy = 0;
		}
LE's avatar
LE committed
		_is_serial_proxy_created = false;
ELATTAOUI's avatar
ELATTAOUI committed
		description = "Unable to create proxy on : " + _communication_Device_name;
LE's avatar
LE committed
		Tango::Except::re_throw_exception (df,
ELATTAOUI's avatar
ELATTAOUI committed
										(const char*)"ALLOCATION_ERROR",
ELATTAOUI's avatar
ELATTAOUI committed
										description.c_str(),
LE's avatar
LE committed
										(const char*)"TangoSerialLink::create_serial_proxy");

	}
ELATTAOUI's avatar
ELATTAOUI committed
	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");
	}
LE's avatar
LE committed
}

// ============================================================================
// TangoSerialLink::write
// ============================================================================
void TangoSerialLink::write (std::string command_to_send)  throw (Tango::DevFailed)
{
ELATTAOUI's avatar
ELATTAOUI committed
  std::string description("");
LE's avatar
LE committed

ELATTAOUI's avatar
ELATTAOUI committed
	if(!_serial_proxy)
LE's avatar
LE committed
		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 )
	{
ELATTAOUI's avatar
ELATTAOUI committed
		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");
	}
LE's avatar
LE committed

	try
	{
		//- try
		dd_in << argin;
		this->_serial_proxy->command_inout("DevSerWriteString", dd_in);
ELATTAOUI's avatar
ELATTAOUI committed
		if( argin ) 
		{
			delete [] argin;
			argin = 0;
		}
		//std::cout << "TangoSerialLink::write -> argin = *\"" << argin << "\"*" << std::endl;
LE's avatar
LE committed
	}
	catch(Tango::DevFailed& df )
	{
ELATTAOUI's avatar
ELATTAOUI committed
		if( argin ) 
		{
			delete [] argin;
			argin = 0;
		}
ELATTAOUI's avatar
ELATTAOUI committed
		description = "Unable to write command : " + command_to_send;
LE's avatar
LE committed
		Tango::Except::re_throw_exception (df,
										(const char*)"COMMUNICATION_ERROR",
ELATTAOUI's avatar
ELATTAOUI committed
										description.c_str(),
LE's avatar
LE committed
										(const char*)"TangoSerialLink::write");

	}
ELATTAOUI's avatar
ELATTAOUI committed
	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");
	}
LE's avatar
LE committed
}


// ============================================================================
// TangoSerialLink::read
// ============================================================================
std::string TangoSerialLink::read (void) throw (Tango::DevFailed)
{

ELATTAOUI's avatar
ELATTAOUI committed
	if(!_serial_proxy)
LE's avatar
LE committed
		create_serial_proxy();
LE's avatar
LE committed

	try
	{
		//- try in mode LINE
		dd_out = this->_serial_proxy->command_inout("DevSerReadLine");
		dd_out >> this->response;
LE's avatar
LE committed
	}
	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");
	}
ELATTAOUI's avatar
ELATTAOUI committed
	catch(...)
	{
		Tango::Except::throw_exception (
										(const char*)"COMMUNICATION_ERROR",
										(const char*)"Unable to perform a read operation",
										(const char*)"TangoSerialLink::read");
	}
LE's avatar
LE committed

	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 ;
}

LE's avatar
LE committed
// ============================================================================
// TangoSerialLink::write_read
// ============================================================================
std::string TangoSerialLink::write_read (std::string command_to_send) throw (Tango::DevFailed)
{
ELATTAOUI's avatar
ELATTAOUI committed
	if(!_serial_proxy)
		create_serial_proxy();
ELATTAOUI's avatar
ELATTAOUI committed

LE's avatar
LE committed
	std::string respTmp("");
ELATTAOUI's avatar
ELATTAOUI committed
	long flush_in_out = 2;
ELATTAOUI's avatar
ELATTAOUI committed

	//- Flush buffers ( In & Out = 2 )
	this->_serial_proxy->command_inout("DevSerFlush", dd_in);
LE's avatar
LE committed

	omni_thread::sleep(0, 200000000); //200 milliseconds
	write(command_to_send);
ELATTAOUI's avatar
ELATTAOUI committed

LE's avatar
LE committed
	//- sleep a little bit to let the adapter(RS232/485) to switch mode
	omni_thread::sleep(0, 100000000); //100 milliseconds
ELATTAOUI's avatar
ELATTAOUI committed
	
LE's avatar
LE committed
	// now read response from HW 
ELATTAOUI's avatar
ELATTAOUI committed
	return this->read();
LE's avatar
LE committed
}

// ============================================================================
// 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);
}