// DigMemWrite.cpp : Example of using the 34950A to write digital memory to 
// a receiving instrument or card.

// NOTE: Is .cpp file, but really uses ANSI C syntax
//
// """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
//  © Agilent Technologies Inc. 2005, 2006
//  All rights reserved.
//
// You have a royalty-free right to use, modify, reproduce and distribute
// the Sample Application Files (and/or any modified version) in any way
// you find useful, provided that you agree that Agilent Technologies has no
// warranty, obligations or liability for any Sample Application Files.
//
// Agilent Technologies provides programming examples for illustration only,
// This sample program assumes that you are familiar with the programming
// language being demonstrated and the tools used to create and debug
// procedures. Agilent Technologies support engineers can help explain the
// functionality of Agilent Technologies software components and associated
// commands, but they will not modify these samples to provide added
// functionality or construct procedures to meet your specific needs.
// """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

// This program demonstrates how to transfer digital data from 
// the 34950A memory to a receiving module or computer.  The program 
// first creates the data in memory that is to be sent by using one
// of the "patterns" supplied by the 34950A (a sequential count
// pattern).
//

#include "stdafx.h"
#include "ag34980a.h"
// NOTE: The above include (ag34980A.h) needs some IVI includes.  The path to these
// is often something like "C:\Program Files\IVI\Include".  You need to add this to your includes path at
// either the project level or the system level.  For project level, select Tools\Options, then click
// on "Projects" file tab, select "VC++ Directories".  This brings up a dialog box.  In the upper
// right of this dialog, there is a "Show Directories for" drop down -- select Include files. Then 
// input the include path desired in the window beneath.  You may also need to add an include path
// for Visa.h (if you are using Agilent's Visa, this is often in C:\Program Files\Visa\winnt\include).
// If you are using NI's Visa, then try looking for the include directory somewhere beneath "C:\vxipnp"

ViSession vi;  // needs to be global so can print errors out

void printErrs(ViStatus s)
{
	char errMssg[300];
	ViInt32 errCode = -1;
	ViStatus s2;

	s2 = ag34980a_GetError(vi, &errCode, (ViInt32)300, errMssg);
	printf("Got Visa error: %ld, %s\n", errCode, errMssg);
	if (errCode = -1074135039)  // instr has errors in its queue
	{
		// print out the instr specific errors
		while ((s2 >= 0) && (errCode != 0))
		{
			s2 = ag34980a_error_query(vi, &errCode, errMssg);
			if ( (s2 > -1) && (errCode != 0) )
				printf("Instr reported err: %ld, %s\n", errCode, errMssg);
		}
	}
}
   
#define	CHECK(func)	\
do {\
    ViStatus _s = (func);\
    if (_s < 0)\
    {\
	printf("Error calling function: %s\n", #func);\
	printErrs(_s);\
    }\
} while (0)
 // Uncomment and add the following two lines before the "while" above if you wish to exit when
 // you detect an error.
 //	_s = ag34980a_close(vi);\
 //   exit(0);



int main(int argc, char* argv[])
{
    // This example assumes a 34950A is present in slot 3 

	ViStatus viStatus;
	
	//Open a session to the mainframe using the IVI-C host driver, Reset the instrument
	// If third parameter VI_TRUE, then *RST is done
	viStatus = ag34980a_InitWithOptions( "TCPIP0::156.140.92.131::inst0::INSTR", VI_FALSE, VI_TRUE,"QueryInstrStatus=true", &vi );
	
	if (viStatus < 0)
	{
		fprintf(stderr,"Failed to open the instrument.");
		exit(0);
	}

	// set timeout to 5 seconds
    CHECK( ag34980a_SetAttributeViInt32(vi, "", AG34980A_ATTR_TIMEOUT_MILLISECONDS,5000) );

//	Configure sender for Output, width = byte
	CHECK(ag34980a_ConfigureOutput(vi,"1101",AG34980A_VAL_CHANNEL_WIDTH_BYTE, 5.0) );

//				Create a waveform to output, size = 3000
	CHECK(ag34980a_CreateStandardTrace34950A( vi,"1101",AG34980A_VAL_TRACE_TYPE_COUNT,
			"Count3000", 3000) );

//				Set up handshaking
	CHECK(ag34980a_ConfigureHandshake(vi,"1101",AG34980A_VAL_HANDSHAKE_MODE_SYNCHRONOUS,2.5,5.0) );

	// set up receiver, rate is 500K
	// NOTE the sender will output on the rising edge of the clock.  The receiver will
	// need to make certain the data is stable before reading it, so the receiver 
	// should not use the same edge of the same clock to "read" the data.

//	Disable memory and set sync strobe source INTernal
	CHECK(ag34980a_SetAttributeViBoolean(vi,"1101",AG34980A_ATTR_OUTPUT_ENABLE,false ) );
	CHECK(ag34980a_SetAttributeViInt32(vi,"1101",AG34980A_ATTR_HANDSHAKE_SYNC_STROBE ,AG34980A_VAL_HANDSHAKE_STROBE_SOURCE_INTERNAL ) );

//	Select the name of the trace to output and set cycle count to '1'
	//CHECK(ag34980a_ConfigureOutputMemory(vi,"1101","Count3000", 1) );
	CHECK(ag34980a_SetAttributeViString(vi,"1101",AG34980A_ATTR_OUTPUT_TRACE_SELECT, "Count3000") );
	//CHECK(ag34980a_SetAttributeViInt32(vi,"1101",AG34980A_ATTR_NUM_CYCLES,1) ); 
	CHECK(ag34980a_SystemWrite(vi, ":SOUR:DIG:MEM:NCYC 1,(@1101)") );

		//	Enable the output memory on this card (the sender)
	CHECK(ag34980a_SetAttributeViBoolean(vi,"1101",AG34980A_ATTR_OUTPUT_ENABLE,true ) );
	
//	Start the receiver (on another device/module) now if not already started 

//	Now Start this card (the sender), we will pace the transfer
	CHECK(ag34980a_StartOutput(vi,"1101") );

//				Data will now be transmitted to the receiver

		//  Exit and close session
	viStatus = ag34980a_close(vi);

	printf("\n Done -- press enter to exit program.");
	getchar();

	return 0;
}
