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

// ============================================================================
// DEPENDENCIES
// ============================================================================
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
#include <Xstring.h>
#include "KeithleyDDCProtocol.h"
#include "Keithley_485.h"
/*
* Valid Range values for a K_485
*/
static const std::string K485_rangeValue[] = {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3"};

/*
* Range limit
*/
static const short K485_rangeLimit	= 7;

ELATTAOUI's avatar
ELATTAOUI committed
/*
* Trigger Moded limit
*/
static const short K485_triggerModeLimit	= 5;

LE's avatar
LE committed
// ============================================================================
// Keithley_485::Keithley_485
// ============================================================================
Keithley_485::Keithley_485 (std::string& comLink_device_name):AbstractElectrometerClass(comLink_device_name) 

{
	std::cout << "Keithley_485::Keithley_485 <-" << std::endl;
	
	std::cout << "Keithley_485::Keithley_485 ->" << std::endl;
}

// ============================================================================
// Keithley_485::~Keithley_485
// ============================================================================
Keithley_485::~Keithley_485 (void)
{
	std::cout << "Keithley_485::~Keithley_485 <-" << std::endl;

	std::cout << "Keithley_485::~Keithley_485 ->" << std::endl;
}

ELATTAOUI's avatar
ELATTAOUI committed
// ============================================================================
// Keithley_485::init_protocol
// ============================================================================
bool Keithley_485::init_protocol (void)
{
  std::string description("");
  bool success = false;
  try
  {
	  //- build the keithley Electrometer protocol obj
  	_electrometerProtocol = new KeithleyDDCProtocol (_device_proxy_name);
     
    if(_electrometerProtocol)
      success = _electrometerProtocol->build_communicationLink();
  }
  catch(Tango::DevFailed& df)
  {
		description = "FAILED to create proxy on : " + _device_proxy_name;
		
		Tango::Except::re_throw_exception (df,
			(const char*)"COMMUNICATION_ERROR",
			description.c_str(),
			(const char*)"Keithley_485::init_protocol");
  }
  catch(...)
  {
		description = "FAILED to create proxy on : " + _device_proxy_name + ". Caught [...].";
		
		Tango::Except::throw_exception (
			(const char*)"COMMUNICATION_ERROR",
			description.c_str(),
			(const char*)"Keithley_485::init_protocol");
  }
  return success;
}

LE's avatar
LE committed
// ============================================================================
// Keithley_485::range_up
// ============================================================================
void Keithley_485::range_up (void) 
{
std::stringstream cmd_to_send;

	// force read of range on instrument to update _range variable 
	electrometer_status();

	_range += 1;

	if(_range > K485_rangeLimit)
	{
		_range = K485_rangeLimit;
		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
												"Range up limit reached.",
												"Keithley_485::range_up( ).");
	}

	//- build and send the command
	cmd_to_send << _range << std::endl;
	_electrometerProtocol->set_range(cmd_to_send.str());
}

// ============================================================================
// Keithley_485::range_down
// ============================================================================
void Keithley_485::range_down (void) 
{

std::stringstream cmd_to_send;

	// force read of range on instrument to update _range variable
	electrometer_status();

	_range -= 1;

	if(_range < 0)
	{
		_range=0;
		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
												"Range down limit reached.",
												"Keithley_485::range_down( ).");
	}
	//- build and send the command
	cmd_to_send << _range << std::endl;
	_electrometerProtocol->set_range(cmd_to_send.str());
}

// ============================================================================
// Keithley_485::get_ElectroMeterRange
// ============================================================================
std::string Keithley_485::get_ElectroMeterRange (void) 
{
	// force read of range on instrument to update _range variable
	electrometer_status();

	return _rangeStr;
}

ELATTAOUI's avatar
ELATTAOUI committed
// ============================================================================
// Keithley_485::set_triggerMode
// ============================================================================
void Keithley_485::set_triggerMode (short trigMod) 
{
std::stringstream cmd_to_send;

  if(trigMod<0 || trigMod>K485_triggerModeLimit)
		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
												"Trigger mode value invalid. Please enter a value in the range 0 - 5.",
												"Keithley_485::set_triggerMode( ).");

  cmd_to_send << trigMod <<std::endl;

  _electrometerProtocol->set_triggerMode(cmd_to_send.str());

}

LE's avatar
LE committed
// ============================================================================
// Keithley_485::electrometer_status
// ============================================================================
std::string Keithley_485::electrometer_status (void)
{ 
	std::string _kstatus("undefined status");
ELATTAOUI's avatar
ELATTAOUI committed
	std::string defaultStatus("0000000000");
	std::string argout("");
LE's avatar
LE committed
	std::string tmp("");

	//- read keithley status from HW	
ELATTAOUI's avatar
ELATTAOUI committed
	_kstatus = _electrometerProtocol->get_DDC_configuration();
LE's avatar
LE committed

	//- build status
	try
	{
		//- model number :
ELATTAOUI's avatar
ELATTAOUI committed
		//std::string modelNum = _kstatus.substr(0,3);
		////- if not expected data (here model number)
		//if(modelNum.find("485") == std::string::npos)
		//{
		//	set_electroState(ALARM);
		//	argout = "Invalid status string received";
		//	return argout;
		//}
		//argout = "Keithley Type : " + modelNum + "\n";
		if ( _kstatus.size() < defaultStatus.size() )
LE's avatar
LE committed
		{
ELATTAOUI's avatar
ELATTAOUI committed
			argout = _kstatus;
LE's avatar
LE committed
			set_electroState(ALARM);
			return argout;
		}
		//- Zero check state
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(0,1);
LE's avatar
LE committed
		if(XString<short>::convertFromString(tmp))
			argout += "Zero Check : ON\n";
		else
			argout += "Zero Check : OFF\n";
		//- Log state
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(1,1);
LE's avatar
LE committed
		if(XString<short>::convertFromString(tmp))
			argout += "Log : ON\n";
		else
			argout += "Log : OFF\n";
		//- Range
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(2,1);
LE's avatar
LE committed
		 _range = XString<short>::convertFromString(tmp);
		_rangeStr = K485_rangeValue[_range];
		argout   += _rangeStr + "\n";
		//- Relative (baseline suppress)
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(3,1);
LE's avatar
LE committed
		if(XString<short>::convertFromString(tmp))
			argout += "Relative ON\n";
		else
			argout += "Relative OFF\n";
		//- Relative (baseline suppress)
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(4,1);
LE's avatar
LE committed
		if(XString<short>::convertFromString(tmp))
			argout += "EOI : Send\n";
		else
			argout += "EOI : Do Not Send\n";
		//- Trigger
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(5,1);
ELATTAOUI's avatar
ELATTAOUI committed
    short trigg = XString<short>::convertFromString(tmp);
		if(!trigg)
LE's avatar
LE committed
			argout += "Trigger : Continuous on Talk\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(trigg == 1)
LE's avatar
LE committed
				argout += "Trigger :One-Shot on Talk\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(trigg == 2)
LE's avatar
LE committed
				argout += "Trigger :Continuous on Get\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(trigg == 3)
LE's avatar
LE committed
				argout += "Trigger :One-Shot on Get\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(trigg == 4)
LE's avatar
LE committed
				argout += "Trigger :Continuous on \"X\"\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(trigg == 5)
LE's avatar
LE committed
				argout += "Trigger :One-Shot on \"X\"\n";
		//- SRQ Data Mask
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(6,2);
ELATTAOUI's avatar
ELATTAOUI committed
    short srqInfo = XString<short>::convertFromString(tmp);
		if(!srqInfo)
LE's avatar
LE committed
			argout += "SRQ Data Mask : SRQ Disabled\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 1)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Reading Overflow\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 8)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Reading Done\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 9)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Reading Done or Reading Overflow\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 16)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Busy\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 17)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Busy or Reading Overflow\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 24)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Busy or Reading Done\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqInfo == 25)
LE's avatar
LE committed
				argout += "SRQ Data Mask : Busy, Reading Done or Reading Overflow\n";
		//- SRQ Error Mask
ELATTAOUI's avatar
ELATTAOUI committed
		tmp = _kstatus.substr(6,2);
ELATTAOUI's avatar
ELATTAOUI committed
    short srqMaskErr = XString<short>::convertFromString(tmp);
		if(!srqMaskErr)
LE's avatar
LE committed
			argout += "SRQ Error Mask : SRQ Disabled\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 1)
LE's avatar
LE committed
				argout += "SRQ Error Mask : IDDCO\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 2)
LE's avatar
LE committed
				argout += "SRQ Error Mask : IDDC\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 3)
LE's avatar
LE committed
				argout += "SRQ Error Mask : IDDCO or IDDC\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 4)
LE's avatar
LE committed
				argout += "SRQ Error Mask : Not in Remote\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 5)
LE's avatar
LE committed
				argout += "SRQ Error Mask : Not in Remote or IDDCO\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 6)
LE's avatar
LE committed
				argout += "SRQ Error Mask : Not in Remote or IDDC\n";
		else
ELATTAOUI's avatar
ELATTAOUI committed
			if(srqMaskErr == 7)
LE's avatar
LE committed
				argout += "SRQ Error Mask : Not in Remote, IDDCO or IDDC\n";
	}
	catch(std::out_of_range)
	{
		set_electroState(ALARM);

		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
												"Cannot extract device status [find or substr failed !].",
												"Keithley_485::electrometer_status( ).");
	}

	set_electroState(ON);
	return argout;
}