/******************************************************************************
 *                                                                         
 *               Copyright 2004-2006 Agilent Technologies
 *               All rights reserved.
 *
 *****************************************************************************/
 
#include "stdafx.h"
#include "CoAgilent34980A.h"



/// <summary>
/// Configures the specified channels for frequency measurements but  does not 
///   initiate the scan.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
/// <param name="Range">
///	Desired range in hertz.
/// </param>
/// <param name="Resolution">
///	Select from Least (4.5 digits), Default (5.5 digits) and Best (6.5 digits).
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_Configure(BSTR ChannelList, double Range, Agilent34980AResolutionEnum Resolution)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	if( Range<0 )
	{ // get rid of neg sign
		CString sCmd = PopInstrCommand();
		sCmd.Delete( sCmd.Find( '-' ) );
		PushInstrCommand( sCmd );
		hr = InstrPrintCommand();
		// set autorange ON
		if( ::SysStringLen( ChannelList ) )
		{
			RETURN_IF_FAIL( InstrPrintf( "FREQ:VOLT:RANG:AUTO 1, (@%s)", LPCTSTR(COLE2T(ChannelList)) ) );
		}
		else
		{
			RETURN_IF_FAIL( InstrPrintf( "FREQ:VOLT:RANG:AUTO 1" ) );
		}
	}
	else
	{
		hr = InstrPrintCommand();
	}


	return hr;
}

/// <summary>
///	Sets or gets the gate time for a period or frequency measurement.
/// </summary>
/// <remarks>
///	Allowable values are 10E-3 seconds, 100E-3 seconds, and 1 second.  These values
/// are also used and set by the Configure and Measurement routine’s resolution
/// settings of LEAST, DEFAULT, and BEST respectively.\r\n
/// If the ChannelList parameter is empty, this command applies to the internal
/// DMM, independent of any channels or a scan list.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_get_Aperture(BSTR ChannelList, double* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AFrequency_get_Aperture"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the gate time for a period or frequency measurement.
/// </summary>
/// <remarks>
///	Allowable values are 10E-3 seconds, 100E-3 seconds, and 1 second.  These values
/// are also used and set by the Configure and Measurement routine’s resolution
/// settings of LEAST, DEFAULT, and BEST respectively.\r\n
/// If the ChannelList parameter is empty, this command applies to the internal
/// DMM, independent of any channels or a scan list.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_put_Aperture(BSTR ChannelList, double Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Enables/Disables autoranging on the specified channel.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_get_AutoRange(BSTR ChannelList, VARIANT_BOOL* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AFrequency_get_AutoRange"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	hr = InstrQueryCommandBool(Val);

	return hr;
}

/// <summary>
///	Enables/Disables autoranging on the specified channel.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_put_AutoRange(BSTR ChannelList, VARIANT_BOOL Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the lowest frequency expected in the input signal for frequency
/// measurements on the specified channel.
/// </summary>
/// <remarks>
///	The instrument selects a slow, medium (default), or fast measurement timeout
/// based on the frequency specified.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_get_LowRange(BSTR ChannelList, long* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AFrequency_get_LowRange"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the lowest frequency expected in the input signal for frequency
/// measurements on the specified channel.
/// </summary>
/// <remarks>
///	The instrument selects a slow, medium (default), or fast measurement timeout
/// based on the frequency specified.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_put_LowRange(BSTR ChannelList, long Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	hr = InstrPrintCommand();

	return hr;
}


/// <summary>
///	Returns the frequency range, this is always 3.0 Hz.
/// </summary>
/// <remarks>
///	If the ChannelList parameter is empty, this command applies to the internal
/// DMM, independent of any channels or a scan list.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_get_Range(BSTR ChannelList, double* val)
{
	HRESULT hr = S_OK;
/*
	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AFrequency_get_Range"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	RETURN_IF_FAIL( InstrQueryCommand(Val) );
	long lAuto;
	if( ::SysStringLen( ChannelList ) )
		hr = InstrQueryf( "FREQ:VOLT:RANG:AUTO? (@%s)", &lAuto, LPCTSTR(COLE2T(ChannelList)) );
	else
		hr = InstrQuery( "FREQ:VOLT:RANG:AUTO?", &lAuto );
	if( lAuto )
		*Val = -(*Val);
*/
	*val = 3.0;
	return hr;
}

/// <summary>
/// Resets all measurement parameters on the specified channels to their default
///  values. Then, configures the channels    for frequency measurements and immediately
/// sweeps through the specified channels  one time.
/// </summary>
/// <remarks>
/// The results are sent directly to the instrument's output buffer. If you supply
///  empty ChannelList,    this method applies to the internal DMM, independent
/// of any channels or a scan  list.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
/// <param name="Range">
///	Desired range in hertz.
/// </param>
/// <param name="Resolution">
///	Select from Least (4.5 digits), Default (5.5 digits) and Best (6.5 digits).
/// </param>
HRESULT Agilent34980A::IAgilent34980AFrequency_Measure(BSTR ChannelList, double Range, Agilent34980AResolutionEnum Resolution, SAFEARRAY** val)
{
	HRESULT hr = S_OK;

	CString sList = CorrectChannelList( ChannelList );

	if( Range<0 )
	{ // get rid of neg sign
		CString sCmd = PopInstrCommand();
		sCmd.Delete( sCmd.Find( '-' ) );
		PushInstrCommand( sCmd );
		// prepare new command for AUTO ranging
		PopInstrCommand();
		sCmd.Format("MEAS:FREQ? AUTO, %s, (@%s)", EnumToString<Agilent34980AResolutionEnum>(Resolution), sList );
		PushInstrCommand( sCmd ); // pop is in ForwardingShims.h
	}

	RETURN_IF_FAIL( InstrPrintCommandNoPoll() );

	hr = FormattedReadList( NtlAsciiType_R8, ",", val );

	return hr;
}

