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



/// <summary>
/// Configures the buffered memory for input.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
/// <param name="Action">
///	Specifies the action to be taken when a pattern comparison match occurs. A pattern
/// comparison match  may have one of three actions on input memory: 1) Start reading
/// on comparison match, 2) Stop reading on comparison match , 3) Continue in present
/// condition (either running or stoped) effectively taking no action on the pattern
/// comparison match.
/// </param>
/// <param name="Count">
///	Count of samples to be read into memory.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_Configure(BSTR ChannelList, Agilent34950AActionEnum Action, long Count)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Clears the buffered memory.
/// </summary>
/// <remarks>
/// Can be called while a buffered input is in progress.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_Clear(BSTR ChannelList)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Set or gets the action taken on a pattern match for the buffered input memory.
/// </summary>
/// <remarks>
///	A pattern comparison match  may have one of three actions on input memory: 1)
/// Start reading on comparison match, 2) Stop reading on comparison match , 3)
/// Continue in present condition (either running or stoped) effectively taking
/// no action on the pattern comparison match.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_CompareAction(BSTR ChannelList, Agilent34950AActionEnum* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(val);

	return hr;
}

/// <summary>
///	Set or gets the action taken on a pattern match for the buffered input memory.
/// </summary>
/// <remarks>
///	A pattern comparison match  may have one of three actions on input memory: 1)
/// Start reading on comparison match, 2) Stop reading on comparison match , 3)
/// Continue in present condition (either running or stoped) effectively taking
/// no action on the pattern comparison match.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_CompareAction(BSTR ChannelList, Agilent34950AActionEnum val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Selects the format of data returned by buffered input operation on the 34950A
/// Digital IO module.
/// </summary>
/// <remarks>
///	Applies to data returned by ReadAllData and ReadSelectedData methods. Select
/// LIST (default) t return data in comma-separrated ASCII format. Select BLOCk
/// type to return data in floating point IEEE488.2 format.
/// </remarks>
/// <param name="Channel">
///	Single Channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_DataFormat(BSTR Channel, Agilent34950ADataFormatEnum* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(val);

	return hr;
}

/// <summary>
///	Selects the format of data returned by buffered input operation on the 34950A
/// Digital IO module.
/// </summary>
/// <remarks>
///	Applies to data returned by ReadAllData and ReadSelectedData methods. Select
/// LIST (default) t return data in comma-separrated ASCII format. Select BLOCk
/// type to return data in floating point IEEE488.2 format.
/// </remarks>
/// <param name="Channel">
///	Single Channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_DataFormat(BSTR Channel, Agilent34950ADataFormatEnum val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Returns the number of samples currently in memory.
/// </summary>
/// <remarks>
///	This query maybe called anytime.
/// </remarks>
/// <param name="Channel">
///	Single Channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_DataPoints(BSTR Channel, long* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(val);

	return hr;
}

/// <summary>
///	Enables or disables buffered reads (aka memory capture) on the bank, clears
/// memory, applies the sample count, and puts the bank into the ready for trigger
/// state.
/// </summary>
/// <remarks>
///	The first channel on the bank must be an input before enabling memory.  Repeated
/// enables are ignored.  The query form returns 0 or 1.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_Enable(BSTR ChannelList, VARIANT_BOOL* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(val);

	return hr;
}

/// <summary>
///	Enables or disables buffered reads (aka memory capture) on the bank, clears
/// memory, applies the sample count, and puts the bank into the ready for trigger
/// state.
/// </summary>
/// <remarks>
///	The first channel on the bank must be an input before enabling memory.  Repeated
/// enables are ignored.  The query form returns 0 or 1.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_Enable(BSTR ChannelList, VARIANT_BOOL val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}




/// <summary>
/// Confogures the Interrupt Settings.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
/// <param name="State">
///	Enables (ON) or disables (OFF) the interrupt line on the bank as an output.
/// </param>
/// <param name="Mode">
///	Sets the condition to be reported by the interrupt line.
/// </param>
/// <param name="Drive">
///	Sets the drive mode for the interrupt line when it is enabled as an output.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_InterruptSettings(BSTR ChannelList, VARIANT_BOOL State, Agilent34950AReportConditionEnum Mode, Agilent34950AHandshakeLineTypeEnum Drive)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the condition to be reported by the interrupt line
/// </summary>
/// <remarks>
///	When the bank is in buffered input mode, the interrupt line (if enabled), can
/// be used to provide a hardware indication that memory is full or that a valid
/// pattern compare has occurred.  The line is asserted when the selected condition
/// is true, and is de-asserted as soon as the condition goes false.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_InterruptMode(BSTR ChannelList, Agilent34950AReportConditionEnum* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(val);

	return hr;
}


/// <summary>
///	Sets or gets the condition to be reported by the interrupt line
/// </summary>
/// <remarks>
///	When the bank is in buffered input mode, the interrupt line (if enabled), can
/// be used to provide a hardware indication that memory is full or that a valid
/// pattern compare has occurred.  The line is asserted when the selected condition
/// is true, and is de-asserted as soon as the condition goes false.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_InterruptMode(BSTR ChannelList, Agilent34950AReportConditionEnum val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Enables (ON) or disables (OFF) the interrupt line on the bank as an output.
/// </summary>
/// <remarks>
///	The line goes to HiZ when disabled.  When enabled, the interrupt line acts as
/// a hardware indication of either pattern compare match or memory full. The query
/// returns 0 or 1
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_InterruptEnable(BSTR ChannelList, VARIANT_BOOL* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(val);

	return hr;
}

/// <summary>
///	Enables (ON) or disables (OFF) the interrupt line on the bank as an output.
/// </summary>
/// <remarks>
///	The line goes to HiZ when disabled.  When enabled, the interrupt line acts as
/// a hardware indication of either pattern compare match or memory full. The query
/// returns 0 or 1
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_InterruptEnable(BSTR ChannelList, VARIANT_BOOL val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the polarity of the interrupt line on the bank.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_InterruptPolarity(BSTR ChannelList, Agilent34950APolarityEnum* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(val);

	return hr;
}

/// <summary>
///	Sets or gets the polarity of the interrupt line on the bank.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_InterruptPolarity(BSTR ChannelList, Agilent34950APolarityEnum val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Queries the state of the interrupt line.
/// </summary>
/// <remarks>
///	Returns 1 if the line is enabled and asserted, and 0 if de-asserted or disabled.
///  This query can be sent at any time.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_InterruptStatus(BSTR ChannelList, VARIANT_BOOL* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(val);

	return hr;
}





/// <summary>
/// Non-destructive read all of the data currently stored in the bank memory.
/// </summary>
/// <remarks>
/// This method is not valid while memory transfers are taking place.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_ReadAllData(BSTR Channel, SAFEARRAY** val)
{
	HRESULT hr = S_OK;

	Agilent34950AChannelWidthEnum eWidth = Agilent34950AChannelWidthWord;
	hr = _IAgilent34950ADigital::get_Width(Channel, &eWidth);
	if (SUCCEEDED(hr))
	{
		hr = InstrPrintCommandNoPoll();
		if (SUCCEEDED(hr))
		{
			switch (eWidth)
			{
			case Agilent34950AChannelWidthByte: 
			case Agilent34950AChannelWidthWord: 
				{
					hr = FormattedReadList( NtlAsciiType_I4, ",", val );
				}
				break;
			case Agilent34950AChannelWidthLWord: 
				{
					SAFEARRAY* psa = NULL;
					hr = FormattedReadList( NtlAsciiType_R8, ",", &psa );
					if (SUCCEEDED(hr))
					{
						CComSafeArray<double> saDouble;
						saDouble.Attach(psa);

						CComSafeArray<long> saLong;
						saLong.Create(saDouble.GetCount());

						for (long i = 0; i < (long)saDouble.GetCount(); i++)
						{
							saLong[i] = (long)saDouble[i];
						}

						*val = saLong.Detach();
					}
				}
				break;
			}
		}
	}

	return hr;
}




/// <summary>
/// Non-destructive read of the data in memory.
/// </summary>
/// <remarks>
/// Returns &lt;Count&gt; worth of readings starting at &lt;Index&gt;.  Oldest captures
/// sample is at index 0. The count specifies the number of samples to read and
/// is in terms of the current width of the channel.  Count + Index must be less
/// than the number of captured points.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Singe channel in the form sccc.
/// </param>
/// <param name="Index">
///	Index to start from.
/// </param>
/// <param name="Count">
///	Count of samples to be taken.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_ReadSelectedData(BSTR Channel, long Index, long Count, SAFEARRAY** val)
{
	HRESULT hr = S_OK;

	Agilent34950AChannelWidthEnum eWidth = Agilent34950AChannelWidthWord;
	hr = _IAgilent34950ADigital::get_Width(Channel, &eWidth);
	if (SUCCEEDED(hr))
	{
		hr = InstrPrintCommandNoPoll();
		if (SUCCEEDED(hr))
		{
			switch (eWidth)
			{
			case Agilent34950AChannelWidthByte: 
			case Agilent34950AChannelWidthWord: 
				{
					hr = FormattedReadList( NtlAsciiType_I4, ",", val );
				}
				break;
			case Agilent34950AChannelWidthLWord: 
				{
					SAFEARRAY* psa = NULL;
					hr = FormattedReadList( NtlAsciiType_R8, ",", &psa );
					if (SUCCEEDED(hr))
					{
						CComSafeArray<double> saDouble;
						saDouble.Attach(psa);

						CComSafeArray<long> saLong;
						saLong.Create(saDouble.GetCount());

						for (long i = 0; i < (long)saDouble.GetCount(); i++)
						{
							saLong[i] = (long)saDouble[i];
						}

						*val = saLong.Detach();
					}
				}
				break;
			}
		}
	}

	return hr;
}

/// <summary>
///	Sets or gets how many samples to read into memory.
/// </summary>
/// <remarks>
///	The sample count maybe set at anytime, but it won’t take affect until the next
/// memory enable.  If the sample count is infinite (default; INF or 0), the bank
/// will capture data into memory until a STOP indication is received. Older samples
/// will be overwritten if memory gets full.  For a finite sample count, the allowable
/// range depends on the channel width.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_SampleCount(BSTR ChannelList, long* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(val);

	return hr;
}

/// <summary>
///	Sets or gets how many samples to read into memory.
/// </summary>
/// <remarks>
///	The sample count maybe set at anytime, but it won’t take affect until the next
/// memory enable.  If the sample count is infinite (default; INF or 0), the bank
/// will capture data into memory until a STOP indication is received. Older samples
/// will be overwritten if memory gets full.  For a finite sample count, the allowable
/// range depends on the channel width.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_put_SampleCount(BSTR ChannelList, long val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Starts the buffered read.
/// </summary>
/// <remarks>
/// If memory is disabled, the method will enable memory and start the read.  Repeated
/// calls will be ignored if memory is already running.  The method overrides pattern
/// compare, so it can be used to start the transfer if configured the bank is configured
/// to start on a pattern compare.  The method can be used to resume a stopped transfer.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_Start(BSTR ChannelList)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}


/// <summary>
///	This query returns 1 if currently reading data into memory or waiting on a handshake
/// and 0 if memory is disabled or stopped.
/// </summary>
/// <remarks>
///	This query is valid at all times.
/// </remarks>
/// <param name="Channel">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_get_Status(BSTR Channel, VARIANT_BOOL* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(val);

	return hr;
}

/// <summary>
/// Steps a buffered read.
/// </summary>
/// <remarks>
/// This method handshakes one sample into memory and then puts the memory into
/// the stopped state.  (This works like most debuggers).  If memory is disabled,
/// it will enable memory, and step once.  If memory is enabled and already running,
/// it will stop memory, and step once.  The method overrides pattern compare, so
/// it can be sent even if configured to start on a pattern compare.  The first
/// channel must be an input when method is called.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_Step(BSTR ChannelList)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Stops a buffered read.
/// </summary>
/// <remarks>
/// The read can be resumed via a start command.  This method can be sent anytime.
///  It will be ignored if it does not apply.  This method overrides the pattern
/// compare stop action.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950AInputMemory_Stop(BSTR ChannelList)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}
