// basics.cpp : main project file.
// Demonstrates features of the DSM API
// User will use the intermediate class MyDSM to interact with the DSM API


//---- DECLARATIONS
using namespace System;
using namespace System::Threading;  // For Threading

#include <stdio.h>
#include <iostream>

#include "dsmgroup.h"
#include "cldsm.h"



//**********************************************************************************
//
// Main method
//
//**********************************************************************************


int main(array<System::String ^> ^args)
{
    // New MyGroup object "group0"
    MyGroup group0;

    // New MyDSM objects "dsm0"
    MyDSM dsm0;
    
    
    //******************************************************************************
    // Initialization of board(s)
    //******************************************************************************

    int numOfBoards = group0.boardsConnected();
    int boardSeriesNumber = 0;
    String ^indexTemp;
    int indexNumSelected = 0;

    if (numOfBoards == 0)
    {
        Console::WriteLine( "There are no DSMs present" );
        Console::ReadLine();
        return 1;
    }
    else if ( numOfBoards > 0 )
    {
         Console::WriteLine( "There is/are {0} DSM(s) present", numOfBoards );

	    // List all available DSM's series number
	    for( int i = 0; i < numOfBoards; i++ )
	    {
            boardSeriesNumber = group0.getSeriesNumber( i );
            Console::WriteLine( "Board Index: [{0}],  Series Number: {1}", i, boardSeriesNumber );
	    }
        
        Console::WriteLine( "Please enter the Board Index Number of the board you would like to run: " );
        indexTemp = Console::ReadLine();
        indexNumSelected = Convert::ToInt32( indexTemp );
    }

    boardSeriesNumber = group0.getSeriesNumber( indexNumSelected );

	if ( !dsm0.initializeDSM( boardSeriesNumber ) )
	{
		Console::WriteLine( "Error in Initializing DSM {0}!!", boardSeriesNumber);
		return 0;
	}

	dsm0.getDeviceInfo();
	dsm0.getFirmwareInfo();


    // Set number of pages, should match with hardware paging configuration
	int numOfPages = 4;

	if ( numOfPages == 1 )
	{
		dsm0.setNumOfPages( 1 );
	}
	else if ( numOfPages == 2 )
	{
		dsm0.setNumOfPages( 2 );
	}
	else if ( numOfPages == 4)
	{
		dsm0.setNumOfPages( 4 );
	}
	else
	{
		Console::WriteLine( "Invalid number of page selection" );
		return 0;
	}
	
    
	
    /*
    ***Following example uses all parser commands to create chirp. This is not recommended and the code is only
    included as a demostration.

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "\nExample 1:" );
    Console::WriteLine( "This example uses the parser commands to access the DSM" );

	// Stop the DSM memory
    dsm0.parserCmd("!stop");

	// Switch to page 0
	dsm0.parserCmd( "!page 0" );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );
    
    // Disable the Data Length
	dsm0.parserCmd( "!datalengthenable 0" );
    
	// Set the oversampling factor to 1
	dsm0.parserCmd( "@div 1" );
    
	// Stop the DSM memory
    dsm0.parserCmd("!stop");
    
	// Setup the built-in waveform parameters
	dsm0.parserCmd( "d1 1000000" );	    // set the Chirp1		(d1)	0x1000000
	dsm0.parserCmd( "d2 10000000" );	// set the Chirp2		(d2)	0x10000000
	dsm0.parserCmd( "d3 1000000" );	    // set the Chirp3		(d3)	0x1000000
	dsm0.parserCmd( "d4  0" );			// set the Wavform Code	(d4)	0
	dsm0.parserCmd( "d5  0" );			// set the Delay		(d5)	0x0
	dsm0.parserCmd( "d6 10" );			// set the Data Length	(d6)	0x10
	dsm0.parserCmd( "d7 10" );			// set the Memory Depth (d7)	0x10
	dsm0.parserCmd( "d8  0" );			// set the Marker1		(d8)	0x0
	dsm0.parserCmd( "d9  7" );			// set the Marker2		(d9)	0x7

    
	// Download the waveform
	dsm0.parserCmd( "xgo" );

    // Pauses computer for 1 sec
	Thread::Sleep( 1000 );
    
	// Resets and runs the memory
	dsm0.parserCmd( "!flush" );
	dsm0.parserCmd( "!restart" );

	Console::WriteLine( "\nYou should see the 16-point chirping now..." );
    
    dsm0.askResponse();

	// Stop the Memory
	dsm0.parserCmd( "!stop" );
	Console::WriteLine( "\nDSM Should Stop chirping" );
    
	// Cycle the 16 Frequency Codes with 1 second interval
	Console::WriteLine( "Point-wise marching ..." );

    // Go back to memory address 0
	dsm0.parserCmd( "!flush" );

	for( int i = 0; i < 16; i++ )
	{
        // Toggles memory
		dsm0.parserCmd( "kk" );

        // Wait 500 ms (0.5 second) between each chirp
		Thread::Sleep( 500 );
	}

    // Stop the Memory
	dsm0.parserCmd( "!stop" );

    */




    //******************************************************************************
    // EXAMPLE 1: Non-Parser Command Chirping
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 1:" );
    Console::WriteLine( "This example chirps a simple 16-point waveform" );

	// Stop DSM memory
	dsm0.stopMem();
    
    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );
	
	// Switch to page 0
	dsm0.switchToPage( 0 );
	
	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Disable the Data Length
	dsm0.setDataLengthEnable( false );
	
	// Set the oversampling factor to 1
	dsm0.setOversampleFactor( 1 );

	// Stop DSM memory
	dsm0.stopMem();
    
	// Setup the built-in waveform parameters
	dsm0.setStartFreq( 0x1000000 );     // set start frequency  	0x1000000
	dsm0.setStopFreq( 0x10000000 );	    // set stop frequency    	0x10000000
    dsm0.setStepFreq( 0x1000000 );	    // set step frequency       0x1000000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0 );				    // set delay			    0x0
    dsm0.setDataLength( 0x10 );			// set Data Length		    0x10
    dsm0.setMemoryDepth( 0x10 );		// set Memory Depth 	    0x10
    dsm0.setMarker( 0x0, 0x07 );		// set markers			    0x0, 0x07
    
	// Download the waveform
    dsm0.download();

    // Pauses computer for 1 sec
	Thread::Sleep( 1000 );
    
	// Resets and runs the memory
	dsm0.memAddReset();
	dsm0.startMem();
	Console::WriteLine( "\nYou should see the 16-point chirping now..." );
    
    dsm0.askResponse();
    
	// Stop the Memory
	dsm0.stopMem();
	Console::WriteLine( "\nDSM Should Stop chirping" );
    
	// Cycle the 16 Frequency Codes with 1 second interval
	Console::WriteLine( "Point-wise marching ..." );

    // Go back to memory address 0
	dsm0.memAddReset();

    // Loop to create point-wise chirping
	for( int i=0; i<16; i++ )
	{
        // Toggles memory
		dsm0.memClkToggle();

        // Wait 500 ms (0.5 second) between each chirp
		Thread::Sleep( 500 );
	}

    // Stops the DSM memory
    dsm0.stopMem();
    
    
   
    //******************************************************************************
    // EXAMPLE 2: Simple User Bulk Chirping
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 2:" );
    Console::WriteLine( "An user_define_bulk function example" );
	
	// Stop DSM memory
	dsm0.stopMem();
    
    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );
	
	// Switch to page 0
	dsm0.switchToPage( 0 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

	// Set the oversampling factor to 1
	dsm0.setOversampleFactor( 1 );
    
    // Set Data Length to enabled
	dsm0.setDataLengthEnable( false );

	// Stop DSM memory
	dsm0.stopMem();

	// Set the Memory Depth, Data Length, and Markers
	dsm0.setMemoryDepth( 0x10 );
	dsm0.setDataLength( 0x10);
	dsm0.setMarker( 0x0, 0x07 );
    
	
    // Define bulk chirping properties
	int	bulkNumOfPoints = 16;
	unsigned freqStart = 0x1000000;
	unsigned freqStep =  0x1000000;

	// Download the user defined data to DSM with the userChirp method
	dsm0.userChirpCustom( freqStart, freqStep, bulkNumOfPoints, bulkNumOfPoints, 0 );
	Thread::Sleep( 2000 );

	// Reset and run memory
	dsm0.memAddReset();
	dsm0.startMem();

	Console::WriteLine( "\nThe 16-point user-defined BULK waveform is running" );

	dsm0.askResponse();

    // Stops the DSM memory
    dsm0.stopMem();


 
    //******************************************************************************
    // EXAMPLE 3: Duty Cycle User Bulk Chirp
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 3:" );
    Console::WriteLine( "Duty cycle user_define_bulk function example" );

	dsm0.stopMem();

	dsm0.setLoopCount( 0 );

	// Set to page 0
	dsm0.switchToPage( 0 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );
    
    // Set Data Length Enable
	dsm0.setDataLengthEnable( true );

    // Stop memory
    dsm0.stopMem();

	// Set Memory Depth, note that it is a power of 2
    dsm0.setMemoryDepth( 65536 );
	
    // Set Data Length
    dsm0.setDataLength( 25000 );
	
    // Set markers
    dsm0.setMarker( 0, 12500 );

    // Use userChirp for custom chirping, assuming clock is 2 GHz
    // Start Freq:		450,000,000 Hz		FW: 966367642
    // Step Freq:		25,000 Hz			FW: 53687
    // Num of Freqs:    15,000
    // Num of Points:   25,000
    // Constant Freq:	10,000,000 Hz		FW: 21474836
	// Note that the user_define_bulk uses FREQUENCY WORDS, not the absolute frequencies
    dsm0.userChirpCustom( 966367642, 53687, 15000, 25000, 21474836 );

    // Pauses Computer for 1 second
	Thread::Sleep( 3000 );
	
    // Starts memory
    dsm0.startMem();

    dsm0.askResponse();
    
    // Stops memory
    dsm0.stopMem();



    //******************************************************************************
    // EXAMPLE 4: Period defined user bulk chirping
    //
    // For this example we will have the following conditions:
    //
    // Start Freq = 400 MHz
    // Stop Freq = 800 Mhz
    // Chirping Period = 20 us 
    // Total Period = 30 us
    // Loop = 128
    //
    //
    // Note that the total period is equal to the following equation:
    //
    // T = 8 * (Tclock) * (# of points) * (oversampling factor)
    // 
    // where T is the total period and Tclock is the clock period
    //
    // 
    // We have one undefined variable, Tclock, which the user will have to specify
    //
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 4:" );
    Console::WriteLine( "Advanced user_define_bulk function example" );

	// Stop memory
	dsm0.stopMem();

    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );

	// Switch to page 0
	dsm0.switchToPage( 0 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

	// BEGING PARAMETER CALCULATIONS
    // The following section is just an example of calulating the various parameters needed for the chirp
    // It has nothing to do with the DSM other than to create the frequency word array and get the number of
    // frequencies to chirp.
    double perFreqStart = 400000000;
    double perFreqStop = 800000000;
    double perFreqConst = 600000000;
    double perFreqStep;
	
	// Chirp variables
    double perOversampleFactor = 1;
    double perNumOfPointsTemp;
	unsigned perNumOfPoints;
    double perNumOfFreqsTemp;
	unsigned perNumOfFreqs;

    double chirpPeriod = 20e-6;
    double totalPeriod = 30e-6;
    double clockFreq = 2000000000;
    double Tclock = 1 / clockFreq;
	
	// Convert to Frequency Words
	double fwConv = Math::Pow( 2, 32 );

    // Calculate the start frequency word
	double perStartFWTemp = Math::Round( (perFreqStart * fwConv) / clockFreq ) ;
	unsigned perStartFW = Convert::ToInt32( perStartFWTemp );
	
    // Calculate the stop frequency word
    double perStopFWTemp = Math::Round( (perFreqStop * fwConv) / clockFreq );
	unsigned perStopFW = Convert::ToInt32( perStopFWTemp );

    // Calculate the constant frequency word
    double perConstFWTemp = Math::Round( (perFreqConst * fwConv) / clockFreq );
	unsigned perConstFW = Convert::ToInt32( perConstFWTemp );
    
    double perStepFWTemp;
	unsigned perStepFW;
    
    // Calculate the number of points for non-constant frequencies
    perNumOfFreqsTemp = Math::Ceiling( chirpPeriod / (8 * Tclock * perOversampleFactor) );
	perNumOfFreqs = Convert::ToInt32( perNumOfFreqsTemp );
    Console::WriteLine( "\nNumber of frequencies to chirp:\t\t{0}", perNumOfFreqs );

    // Calculate the total number of points
    perNumOfPointsTemp = Math::Ceiling( totalPeriod / (8 * Tclock * perOversampleFactor) );
	perNumOfPoints = Convert::ToInt32( perNumOfPointsTemp );
    Console::WriteLine( "Total number of points to chirp:\t{0}", perNumOfPoints );

    // Calculate the step frequency word
    perFreqStep = (perFreqStop - perFreqStart) / (perNumOfFreqs - 1);
	perStepFWTemp = Math::Round( (perFreqStep * fwConv) / clockFreq );
	perStepFW = Convert::ToInt32( perStepFWTemp);
	

	Console::WriteLine( "\nStart Freq:\t\t{0}", perFreqStart );
	Console::WriteLine( "Stop Freq:\t\t{0}", perFreqStop );
	Console::WriteLine( "Step Freq:\t\t{0}", perFreqStep );

    // END PARAMETER CALCULATIONS 
	

    unsigned *freqArray = new unsigned[ perNumOfPoints ];

    unsigned i, j;
    
    // Create the frequency word array for non-constant frequencies
    for( i = 0, j = perStartFW ; i < perNumOfFreqs; i++ )
	{
		freqArray[i] = j;
		j += perStepFW;
	}
    
    // Finish frequency word array with constant frequencies
	for( ; i < perNumOfPoints; i++ )
	{
	    freqArray[ i ] = perConstFW;
	}

	// Stop DSM memory
	dsm0.stopMem();

	// Memory Depth, Data Length, and marker options are set BEFORE the call to user_define_bulk
	dsm0.setMemoryDepth( 16384 );
	dsm0.setDataLengthEnable( true );
	dsm0.setDataLength( perNumOfPoints );
	dsm0.setMarker( 0, perNumOfFreqs );

	// Call userChirp method to download data into DSM memory
	dsm0.userChirp( freqArray, perNumOfPoints );

    // Pause computer for 2 secs
	Thread::Sleep( 2000 );

    // Start memory
    dsm0.startMem();
	Console::WriteLine( "\nRunning now..." );

	dsm0.askResponse();
    
    // Stops memory
	dsm0.stopMem();

    // Deletes array
	delete freqArray;
	

  
    //******************************************************************************
    // EXAMPLE 5: User File Chirping
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************" );
    Console::WriteLine( "Example 5:" );
    Console::WriteLine( "This example uses the user_define_file function" );

    // Stop memory
	dsm0.stopMem();

    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );

	// Set to page 0
	dsm0.switchToPage( 0 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

	// Enable Data Length
	dsm0.setDataLengthEnable( true );
	    
    // 2 GHz Clock
	double clock = 2e9;
    unsigned userNumOfPoints;
    String ^userFile;
	
    // Import the user file
    // Note that none of the waveform control settings have been set yet
    // This is because we do not know how many frequency points there are in the .uwf
    // Only after calling the .uwf file do we know how many points there are
    userFile = "demo.uwf";
	dsm0.stopMem();
    userNumOfPoints = dsm0.userFileChirp( userFile, clock );

	// Now that we know how many total points there are, we can set up the control settings
	dsm0.stopMem();
	dsm0.setMemoryDepth( 0x40 );
	dsm0.setDataLength( userNumOfPoints );
	dsm0.setMarker( 0, 32 );

    // We need to call the user_define_file method again to download the data to DSM but this 
    // time with the correct Memory Depth and Data Length information 
	userNumOfPoints = dsm0.userFileChirp( userFile, clock );

    // Pause computer for 2 secs
	Thread::Sleep( 1000 );
    
	// Start memory
	dsm0.startMem();
	Console::WriteLine( "\nThe {0}-point user-defined file waveform is running", userNumOfPoints );

	dsm0.askResponse();

    // Stop memory
	dsm0.stopMem();



    //******************************************************************************
    // EXAMPLE 6: Multi-Waveform Chirping with Paging
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************" );
    Console::WriteLine( "Example 6:" );
    Console::WriteLine( "This example uses the paging feature to output multiple waveforms" );

    // Stop memory
	dsm0.stopMem();

    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );



	// FOR PAGE 0
	
	// Switch to Page 0
	dsm0.switchToPage( 0 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Enable the Data Length
	dsm0.setDataLengthEnable( false );

	// Stop DSM memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x0 );			// set start frequency  	0x0
	dsm0.setStopFreq( 0x20000000 );	    // set stop frequency    	0x20000000
    dsm0.setStepFreq( 0x2000 );			// set step frequency       0x2000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0x0 );			    // set delay			    0x0
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth			0x10000
    dsm0.setDataLength( 0x10000 );		// set Data Length		    0x10000
	dsm0.setMarker( 0x0, 0x8000 );
    
	// Download the waveform
    dsm0.download();

    // Pause for 1 sec
	Thread::Sleep( 1000 );



	// FOR PAGE 1

	dsm0.stopMem();
	
	// Switch to Page 1
	dsm0.switchToPage( 1 );

    // Set phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Enable Data Length
	dsm0.setDataLengthEnable( false );

    // Stop memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x20000000 );	// set start frequency  	0x20000000
	dsm0.setStopFreq( 0x40000000 );	    // set stop frequency    	0x40000000
    dsm0.setStepFreq( 0x2000 );			// set step frequency       0x2000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0x0 );			    // set delay			    0x0
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth			0x10000
    dsm0.setDataLength( 0x10000 );		// set Data Length		    0x10000
	dsm0.setMarker( 0x0, 0x8000 );
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );



	// FOR PAGE 2
	
	// Switch to Page 2
	dsm0.switchToPage( 2 );

    // Stop memory
	dsm0.stopMem();

    // Set phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Set Data Length Enable
	dsm0.setDataLengthEnable( false );

    // Stop memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x40000000 );	// set start frequency  	0x40000000
	dsm0.setStopFreq( 0x60000000 );	    // set stop frequency    	0x60000000
    dsm0.setStepFreq( 0x2000 );			// set step frequency       0x2000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0x0 );			    // set delay			    0x0
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth			0x10000
    dsm0.setDataLength( 0x10000 );		// set Data Length		    0x10000
	dsm0.setMarker( 0x0, 0x8000 );
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );



	// FOR PAGE 3
	
	// Switch to Page 3
	dsm0.switchToPage( 3 );

    // Stop memory
	dsm0.stopMem();

    // Set phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Enable Data Length
	dsm0.setDataLengthEnable( true );

    // Stop memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x60000000 );			// set start frequency  	0x60000000
	dsm0.setStopFreq( 0x80000000 );	    // set stop frequency    	0x80000000
    dsm0.setStepFreq( 0x2000 );			// set step frequency       0x2000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0x0 );			    // set delay			    0x0
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth			0x10000
    dsm0.setDataLength( 0x10000 );		// set Data Length		    0x10000
	dsm0.setMarker( 0x0, 0x8000 );
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );


    // Switch back to Page 0 and start memory
	dsm0.switchToPage( 0 );
	dsm0.stopMem();
	dsm0.startMem();
	dsm0.askResponse();

    // Switch to Page 1 and start memory
	dsm0.switchToPage( 1 );
	dsm0.startMem();
	dsm0.askResponse();

    // Switch to Page 2 and start memory
	dsm0.switchToPage( 2 );
	dsm0.startMem();
	dsm0.askResponse();

    // Switch to Page 3 and start memory
	dsm0.switchToPage( 3 );
	dsm0.startMem();
	dsm0.askResponse();

    // Stops the DSM memory
    dsm0.stopMem();



	//******************************************************************************
    // EXAMPLE 7: Combined
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 7:" );
    Console::WriteLine( "This example will demonstrate the features above combined" );



	// PAGE 0

    // Stop memory
	dsm0.stopMem();	

    // Set to infinite loop aka Free Run mode
	dsm0.setLoopCount( 0 );
	
	// Switch to Page 0
	dsm0.switchToPage( 0 );

    // Set phase reset optins
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );
    
    // Enable Data Length
	dsm0.setDataLengthEnable( true );

    // Stop memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x1000000 );     // set start frequency
	dsm0.setStopFreq( 0x10000000 );	    // set stop frequency
    dsm0.setStepFreq( 0x1000000 );	    // set step frequency
    dsm0.setWaveformCode( 0 );			// set wavform code
    dsm0.setDelay( 0x0 );			    // set delay
    dsm0.setMemoryDepth( 0x10 );		// set Memory Depth
	dsm0.setDataLength( 0x10 );			// set Data Length
    dsm0.setMarker( 0x0, 0x7 );		// set markers
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );



	// PAGE 1
	
	// Switch to Page 1
	dsm0.switchToPage( 1 );

    // Stop memory
	dsm0.stopMem();

    // Set phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Enable Data Length
	dsm0.setDataLengthEnable( true );
    
    // BEGIN PARAMETER CALCULATIONS
	double comPerFreqStart = 250000000;
    double comPerFreqStop = 750000000;
    double comPerFreqConst = 500000000;
    double comPerFreqStep;
	
	// Chirp variables
    double comPerOverSampleFactor = 1;
    double comPerNumOfPointsTemp;
	unsigned comPerNumOfPoints;
    double comPerNumOfFreqsTemp;
	unsigned comPerNumOfFreqs;

    double comChirpPeriod = 20e-6;
    double comTotalPeriod = 30e-6;
    double comClockFreq = 2e9;
    double comTclock = 1 / comClockFreq;
	
	// Convert to Frequency Words
	double comFWConv = Math::Pow( 2, 32 );

    // Calculate start frequency word
	double comPerStartFWTemp = Math::Round( (comPerFreqStart * comFWConv) / comClockFreq ) ;
	unsigned comPerStartFW = Convert::ToInt32( comPerStartFWTemp );
	
    // Calculate stop frequency word
    double comPerStopFWTemp = Math::Round( (comPerFreqStop * comFWConv) / comClockFreq );
	unsigned comPerStopFW = Convert::ToInt32( comPerStopFWTemp );

    // Calculate constant frequency word
    double comPerConstFWTemp = Math::Round( (comPerFreqConst * comFWConv) / comClockFreq );
	unsigned comPerConstFW = Convert::ToInt32( comPerConstFWTemp );

    double comPerStepFWTemp;
	unsigned comPerStepFW;
	
    // Calculate number of non-constant frequency points
    comPerNumOfFreqsTemp = Math::Ceiling( comChirpPeriod / (8 * comTclock * comPerOverSampleFactor) );
	comPerNumOfFreqs = Convert::ToInt32( comPerNumOfFreqsTemp );
    
    // Calculate number of total number of points
    comPerNumOfPointsTemp = Math::Ceiling( comTotalPeriod / (8 * comTclock * comPerOverSampleFactor) );
	comPerNumOfPoints = Convert::ToInt32( comPerNumOfPointsTemp );

    // Calculate step frequency word
    comPerFreqStep = (comPerFreqStop - comPerFreqStart) / (comPerNumOfFreqs - 1);
	comPerStepFWTemp = Math::Round( (comPerFreqStep * comFWConv) / comClockFreq );
	comPerStepFW = Convert::ToInt32( comPerStepFWTemp);

    // END PARAMETER CALCULATIONS
	
	
    unsigned *comFreqArray = new unsigned[ comPerNumOfPoints ];

    unsigned l, m;
    
    // Create frequency word array for non-constant frequencies
    for( l = 0, m = comPerStartFW ; l < comPerNumOfFreqs; l++ )
	{
		comFreqArray[l] = m;
		m += comPerStepFW;
	}

    // Finish array with constant frequencies
	for( ; l < comPerNumOfPoints; l++ )
	{
	    comFreqArray[ l ] = comPerConstFW;
	}

    // Stop frequency
	dsm0.stopMem();

	// Memory Depth, Data Length and marker options are set BEFORE the call to user_define_bulk
	dsm0.setMemoryDepth( 16384 );
	dsm0.setDataLength( comPerNumOfPoints );
	dsm0.setMarker( 0, comPerNumOfFreqs );

	// Call userChirp method to download data into DSM memory
	dsm0.userChirp( comFreqArray, comPerNumOfPoints );
	Thread::Sleep( 1000 );



	// PAGE 2
	
	// Switch to Page 2
	dsm0.switchToPage( 2 );

    // Stop memory
	dsm0.stopMem();

    // Set phase reset options
    dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

    // Enable Data Length
	dsm0.setDataLengthEnable( true );
    
    // 2 GHz Clock
	double comClock = 2e9;				
    unsigned comUserNumOfPoints;

	// Stop DSM memory
	dsm0.stopMem();
	
    // Get total number of points by calling user_define_file method
    comUserNumOfPoints = dsm0.userFileChirp( "demo.uwf", comClock );

	// Set Memory Depth, Data Length, and markers
	dsm0.setMemoryDepth( 0x40 );
	dsm0.setDataLength( comUserNumOfPoints );
	dsm0.setMarker( 0, 32 );

    // Call user_define_file method again but this time with the Memory Depth, Data Length and markers set correctly
	comUserNumOfPoints = dsm0.userFileChirp( "demo.uwf", comClock );
	Thread::Sleep( 1000 );



	// PAGE 3
	
	// Switch to Page 3
	dsm0.switchToPage( 3 );

    // Stop memory
	dsm0.stopMem();

    // Set phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );
	
    // Enable Data Length
	dsm0.setDataLengthEnable( false );

    // Stop memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x60000000 );	// set start frequency
	dsm0.setStopFreq( 0x80000000 );	    // set stop frequency
    dsm0.setStepFreq( 0x2000 );			// set step frequency
    dsm0.setWaveformCode( 0 );			// set wavform code
    dsm0.setDelay( 0x0 );			    // set delay
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth
	dsm0.setDataLength( 0x10000 );		// set Data Length
	dsm0.setMarker( 0x0, 0x8000 );		// set markers
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );



	// Run memory for page 0
	dsm0.switchToPage( 0 );	
	dsm0.stopMem();
	dsm0.startMem();
	dsm0.askResponse();

    // Run memory for page 0
	dsm0.switchToPage( 1 );
	dsm0.startMem();
	dsm0.askResponse();

    // Run memory for page 0
	dsm0.switchToPage( 2 );
	dsm0.startMem();
	dsm0.askResponse();

	// Run memory for page 0
	dsm0.switchToPage( 3 );
	dsm0.startMem();
	dsm0.askResponse();

    // Stops the DSM memory
    dsm0.stopMem();




	//******************************************************************************
    // EXAMPLE 8: Multiboard Functions
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 8a:" );
    Console::WriteLine( "This example will demonstrate the master board features" );
	
    // Stop memory
	dsm0.stopMem();

	// Switch to Page 0
	dsm0.switchToPage( 0 );

	// Turn on Master mode
	dsm0.setToMaster( true );

	// Set loop count to non-zero, non-negative value
	dsm0.setLoopCount( 2 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

	// Set oversampling factor
	dsm0.setOversampleFactor( 1 );

	// Enable Data Length
	dsm0.setDataLengthEnable( true );

	// Set up SYNCO options
	dsm0.setSyncout( true );
	dsm0.setSyncoutParams( 0x0, 0xFF );

    // Stop memory
    dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 0x00000000 );	// set start frequency  	0x0
	dsm0.setStopFreq( 0x20000000 );	    // set stop frequency    	0x20000000
    dsm0.setStepFreq( 0x2000 );			// set step frequency       0x2000
    dsm0.setWaveformCode( 0 );			// set wavform code		    0
    dsm0.setDelay( 0x0 );			    // set delay			    0x0
	dsm0.setMemoryDepth( 0x10000 );		// set Memory Depth			0x10000
    dsm0.setDataLength( 0x10000 );		// set Data Length		    0x10000
	dsm0.setMarker( 0x0, 0x4000 );		// set Markers				0x0, 0x4000
    
	// Download the waveform
    dsm0.download();
	Thread::Sleep( 1000 );
	
    // Stop memory before arming
	dsm0.stopMem();

    // Arms Master board, note that the "!arm" parser command is used, not the "!restart" command
    dsm0.armMasterBoard();
	
	Console::WriteLine( "\nWaiting for trigger..." );

	dsm0.askResponse();
    
    // Stop memory
	dsm0.stopMem();

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 8b:" );
    Console::WriteLine( "This example will demonstrate the slave board features" );
	
    // Stop memory
	dsm0.stopMem();

	// Set page options
	dsm0.switchToPage( 0 );

	// Turn on Slave mode
	dsm0.setToSlave( true );

	// Set loop count to non-zero, non-negative number
	dsm0.setLoopCount( 2 );

	// Phase reset options
	dsm0.setReset( false );
	dsm0.setResetParams( 0, 0, 0 );

	// Enable Data Length
	dsm0.setDataLengthEnable( false );
	
	// Stop memory
	dsm0.stopMem();

	// Setup the waveform parameters
	dsm0.setStartFreq( 0x0 );
	dsm0.setStopFreq( 0x20000000 );
    dsm0.setStepFreq( 0x2000 );
	dsm0.setWaveformCode( 0 );
    dsm0.setDelay( 0x0 );
	dsm0.setMemoryDepth( 0x10000 );
    dsm0.setDataLength( 0x10000 );
	dsm0.setMarker( 0x0, 0x8000 );

    
	// Download the waveform
	dsm0.download();
	Thread::Sleep( 1000 );

    // Stop memory before arming
	dsm0.stopMem();

	// Arm the slave board, notice that the "!slave" parser command is used, not "!restart" or "!arm" commands
    dsm0.setToSlave( true );
	
	Console::WriteLine( "\nWaiting for SYNCI..." );

	dsm0.askResponse();
    
    // Stop memory
	dsm0.stopMem();


    return 0;
}
