// new.cpp : demonstrates the new features of the DSM
// 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"



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;
	}


    //******************************************************************************
    // EXAMPLE 1:
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "\nNon-Reset Example:" );
    Console::WriteLine( "This example will demonstrate a normal waveform that is normally difficult to acquire on an oscilloscope even with trigger to marker" );

	// Switch to page 0
	dsm0.switchToPage( 0 );
    
    // Enable Data Length
	dsm0.setDataLengthEnable( true );

    // Disable the reset option
    dsm0.setReset( false );
	
	// Set the oversampling factor to 1
	dsm0.setOversampleFactor( 1 );

	// Stop DSM memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 10000000 );
	dsm0.setStopFreq( 640000000 );
    dsm0.setStepFreq( 10000000 );
    dsm0.setWaveformCode( 0 );
    dsm0.setDelay( 0 );
    dsm0.setDataLength( 64 );
    dsm0.setMemoryDepth( 64 );
    dsm0.setMarker( 32, 64 );
    
	// Download the waveform
    dsm0.download();
    
	// Resets and runs the memory
	dsm0.memAddReset();
	dsm0.startMem();
	Console::WriteLine( "\nYou should now see the waveform..." );
    
    dsm0.askResponse();
    
	//---- Stop the Memory
	dsm0.stopMem();



    Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "\nReset Example:" );
    Console::WriteLine( "This example will demonstrate the same waveform with the phase reset options on" );

	// Switch to page 0
	dsm0.switchToPage( 0 );
    
    // Enable the Data Length
	dsm0.setDataLengthEnable( false );

    // ENABLE PHASE RESET OPTION
    dsm0.setReset( true );

    // SET RESET TIMES
    dsm0.setResetParams( 0, 5, 3 );
	
	// Set the oversampling factor to 1
	dsm0.setOversampleFactor( 1 );

	// Stop DSM memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	dsm0.setStartFreq( 10000000 );
	dsm0.setStopFreq( 640000000 );
    dsm0.setStepFreq( 10000000 );
    dsm0.setWaveformCode( 0 );
    dsm0.setDelay( 0 );
    dsm0.setDataLength( 64 );
    dsm0.setMemoryDepth( 64 );
    dsm0.setMarker( 32, 64 );
    
	// Download the waveform
    dsm0.download();
    
	// Resets and runs the memory
	dsm0.memAddReset();
	dsm0.startMem();
	Console::WriteLine( "\nYou should now see the waveform better assuming you have triggered correctly with your scope." );
    
    dsm0.askResponse();
    
	//---- Stop the Memory
	dsm0.stopMem();


    //******************************************************************************
    // EXAMPLE 2:
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "\nNew User Define Bulk Function:" );
    Console::WriteLine( "This example will demonstrate the new overloaded user define bulk function" );

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

	dsm0.setLoopCount( 0 );
    
    // Enable the Data Length
	dsm0.setDataLengthEnable( true );

	// Disable Markers
	dsm0.setMarkerEnable( false );

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

	// Stop DSM memory
	dsm0.stopMem();

	unsigned startFW = 0x0;
	unsigned stepFW = 0xA7C7;
	unsigned numOfFreqs = 25000;
	unsigned *freqArray = new unsigned[ numOfFreqs ];
	unsigned *contArray = new unsigned[ numOfFreqs ];

	unsigned i, j;

	// Create frequency array
	for ( i = 0, j = startFW; i < numOfFreqs ; i++)
	{
        // Turns phase reset on and marker high for first 50 points
		if (i < 50)
		{
			freqArray[ i ] = 0;
			contArray[ i ] = 3;
			continue;
		}
    
        //Turns marker high for points 10,000 through 10,500
        if ( (i > 10000) && (i<10500) )
		{
			freqArray[ i ] = j;
			contArray[ i ] = 1;
			j += stepFW;
			continue;
		}

		freqArray[ i ] = j;
		contArray[ i ] = 0;
		j += stepFW;
	}

    // Set Data Length and Memory Depth
	dsm0.setDataLength( numOfFreqs );
	dsm0.setMemoryDepth( 65536 );

    // Call user_define_bulk
	dsm0.userChirp( freqArray, contArray, numOfFreqs );
	Thread::Sleep( 2000 );

    // Resets and start memory
	dsm0.memAddReset();
	dsm0.startMem();
	Console::WriteLine( "\nYou should now see the waveform." );

	dsm0.askResponse();

	//---- Stop the Memory
	dsm0.stopMem();


    //******************************************************************************
    // EXAMPLE 3: Reverse Chirp
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 3:" );
    Console::WriteLine( "This example will demonstrate a reverse chirp" );

    // Stop memory
	dsm0.stopMem();

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

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

	// Phase reset by memory is turned on
	dsm0.setReset( true );
	dsm0.setResetParams( 0, 5, 3 );
    
	// Disable Data Length
	dsm0.setDataLengthEnable( false );

	// Stop DSM memory
	dsm0.stopMem();
    
	// Setup the waveform parameters
	// Note that the stop frequency is less than the start frequency
	// This is necessary for the reverse chirp
	dsm0.setStartFreq( 0x8000000 );     // set start frequency
	dsm0.setStopFreq( 0x0000000 );	    // set stop frequency
    dsm0.setStepFreq( 0x200000 );	    // set step frequency

    // set WAVEFORM CODE TO 2 for reverse chirp
    dsm0.setWaveformCode( 2 );			

    dsm0.setDelay( 0x0 );			    // set delay
    dsm0.setMemoryDepth( 0x40 );		// set Memory Depth
	dsm0.setDataLength( 0x40 );			// set Data Length
    dsm0.setMarker( 0x0, 0x20 );		// set markers

    // Downloads data to DSm
	dsm0.download();
	Thread::Sleep( 1000 );

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

	dsm0.askResponse();

    // Stop memory
	dsm0.stopMem();



	//******************************************************************************
    // EXAMPLE 4: User Define Bulk Reverse Chirp
    //******************************************************************************

	Console::WriteLine( "\n\n***********************************************************************\n" );
    Console::WriteLine( "Example 4:" );
    Console::WriteLine( "This example will demonstrate a reverse chirp using the user-bulk function" );
	
    // Stop memory
	dsm0.stopMem();

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

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

	// Phase reset by memory is turned on
	dsm0.setReset( true );
	dsm0.setResetParams( 0, 5, 3 );

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

	// Stop DSM memory
	dsm0.stopMem();
    
	// Set Memory Depth, Data Length and markers
    dsm0.setMemoryDepth( 0x40 );
    dsm0.setDataLength( 0x40 );
    dsm0.setMarker( 0x0, 0x20 );

    unsigned revStopFW = 0x8000000;
	unsigned revStepFW = 0x200000;
	unsigned revNumOfFreqs = 0x40;

	unsigned *revFreqArray = new unsigned[ revNumOfFreqs ];

	unsigned p, q;

    // Create the frequency word array, note the use of the "~" operator for complements
	for ( p = 0, q = revStopFW ; p < revNumOfFreqs; p++ )
	{
		revFreqArray[ p ] = q;
		q += ~revStepFW;
	}

    // Stop memory
	dsm0.stopMem();

    // Call user_define_bulk function
	dsm0.userChirp( revFreqArray, revNumOfFreqs );

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

	dsm0.askResponse();

    // Stop memory
	dsm0.stopMem();

    return 0;
}
