//
// Copyright (C) Dave Roberts G8KBB 2004
//
// This is a simple demonstration of using
// the vnawrite() function via vnadll.dll
// to send a set message to the VNA.
// then read the adc and loop


#include "stdio.h"

#include "conio.h"
#include "stdafx.h"
#include "objbase.h"
#include "iostream.h"

#include "vnaio.h"


void print_last_error_message(void);

// function takes a list of parameters.
// for example 'vnaloop 1 0 0 0 11 22 33 44 55 66 77 88 99 00 1000
// resets the DDS then writes 1122334455 to LOdds and 6677889900 to RFdds
// using ADC1 with an OSR value of 00
// and repeats it 1000 times
//
// for example 'vnaset 0 200 19 85 11 22 33 44 55 66 77 88 99 00 0
// does not reset the DDS then writes 1122334455 to LOdds and 6677889900 to RFdds
// and then waits 200 msec before performing 19 ADC conversions.
// it does this with ADC2 (the 8) with a speed (if ltc2440) of 220 Hz (OSR=5)
// and loops indefinitely until a key is pressed

int main( int argc, char *argv[])
{
	VNA_TXBUFFER tx_data1, tx_data2;
	VNA_RXBUFFER message;
	VNADevice* VNA;				// Vector Network Analyzer hardware object
	long ltemp;
	char *tmpptr;
	int i;
	int loopcount;

	if( (argc != 16) && (argc != 15))
	{
		printf("Error: Usage is 'vnaset R ADCdel ADCcnt ADCmode LO RF [loop]\n");
		printf("       where R is '1' or '0' - '1' resets DDS, '0' does not\n");
		printf("       ADCdel is ADC read delay in msec - 0 to 255\n");
		printf("       ADCcnt is number of ADC reads to perform (0 to 32)\n");
		printf("       ADCmode (in hex) selects ADC (msbit) and OSR (ls 5 bits)\n");
		printf("       LO & RF are 5 byte hex DDS values in the form\n");
		printf("                   00 11 22 33 44 each\n");
		printf("       [loop] is a loop couunter. If absent loops until key pressed\n");
		return false;
	}

	tx_data1.cmd.command_code = 0x55;
	tx_data1.cmd.flags = 0;
	i = atoi( argv[1]);
	if( i<0 || i>1 )
	{
		printf("Error - invalid DDS reset flag - read '%d', expected '0' or '1'\n", i);
		return false;
	}
	else if( i == 1 )
		tx_data1.cmd.flags |= bCmdVnaSetDdsFlagsReset;

	tx_data1.cmd.flags |= bCmdVnaSetDdsFlagsDdsSet;
	tx_data1.cmd.flags |= bCmdVnaSetDdsFlagsPauseDataIn;
	tx_data1.cmd.flags |= bCmdVnaSetDdsFlagsPauseDataOut;

	if( argc == 15 )
		loopcount = -1;
	else
		loopcount = atoi( argv[15] );
	i = atoi( argv[2]);
	if( i < 0 || i > 255 )
	{
		printf("Error - ADC delay was read as '%d' - must be between 0 and 255\n", i );
		return false;
	}
	else
		tx_data1.cmd.adc_delay = i;

	i = atoi( argv[3]);
	if( i < 0 || i > 32 )
	{
		printf("Error - ADC read count was read as '%d' - must be between 0 and 32\n", i );
		return false;
	}
	else
		tx_data1.cmd.adc_reads = i;

	ltemp = strtol( argv[4], &tmpptr, 16);
	if( ltemp < 0 || ltemp > 0xff )
	{
		printf("Error - ADC mode invalid (hex please!)\n" );
		return false;
	}
	else
		tx_data1.cmd.adc_mode = unsigned char(ltemp);


	for( i=0; i<5; i++)
	{
		ltemp = strtol( argv[5+i], &tmpptr, 16);
		if( ltemp < 0 || ltemp > 255 )
		{
			printf("Invalid hex byte in LO DDS byte %d - '%s'\n", i, argv[4+i]);
			return false;
		}
		else
			tx_data1.cmd.lo[i] = unsigned char(ltemp);
	}
	for( i=0; i<5; i++)
	{
		ltemp = strtol( argv[5+5+i], &tmpptr, 16);
		if( ltemp < 0 || ltemp > 255 )
		{
			printf("Invalid hex byte in RF DDS byte %d - '%s'\n", i, argv[4+5+i]);
			return false;
		}
		else
			tx_data1.cmd.rf[i] = unsigned char(ltemp);
	}

	VNA = new VNADevice;

	if (VNA->get_State() != 1 )
	{
		printf("Sorry - cannot open VNA interface: ");
		print_last_error_message();
		delete VNA;
		return true;
	}

	// reset interface
	tx_data2.cmd.command_code = 0x55; 
	tx_data2.cmd.flags = bCmdVnaSetDdsFlagsReset | bCmdVnaSetDdsFlagsDdsSet;
	tx_data2.cmd.adc_delay = 0;
	tx_data2.cmd.adc_reads = 0;
	memcpy ( tx_data2.cmd.lo,  tx_data1.cmd.lo, sizeof( tx_data2.cmd.lo ) );
	memcpy ( tx_data2.cmd.rf,  tx_data1.cmd.lo, sizeof( tx_data2.cmd.rf ) );

	if( VNA->Write( &tx_data2, sizeof(tx_data2.cmd) ) == false )
	{
		print_last_error_message();
		delete VNA;
		return false;
	}

	if( VNA->Read( &message ) == false )
	{
		print_last_error_message();
		delete VNA;
		return false;
	}
	if( message.return_status & bVnaStatusNoVnaPowerFlag )
	{
		printf("VNA USB interface reports VNA not powered on\n");
		delete VNA;
		return false;
	}

	if( loopcount < 0 )
		printf("VNA responding. Press any key to stop\n");
	else
		printf("VNA responding for up to %d loops or until key pressed.\n",loopcount);

	// START
	CTime tStart = CTime::GetCurrentTime();
	// stack up a couple of writes
	if( VNA->Write( &tx_data1, sizeof(tx_data1.cmd) ) == false )
	{
		print_last_error_message();
		delete VNA;
		return false;
	}
	if( VNA->Write( &tx_data1, sizeof(tx_data1.cmd) ) == false )
	{
		print_last_error_message();
		delete VNA;
		return false;
	}
	while( loopcount != 0 )
	{
		if( VNA->Read( &message ) == false )
		{
			print_last_error_message();
			continue;
		}
		if( message.return_status & bVnaStatusAdcTimeoutFlag )
		{
			printf("ADC timeout\n");
			continue;
		}
		if( message.return_status & bVnaStatusAdcDataReadyFlag )
		{
			if( loopcount > 0 )
				loopcount--;
			if( VNA->Write( &tx_data1, sizeof(tx_data1.cmd) ) == false )
			{
				print_last_error_message();
				continue;
			}
		}
		if( _kbhit() )
			loopcount = 0;
	}
	// STOP
	SYSTEMTIME timeDest;
	CTime tFinish = CTime::GetCurrentTime();
	cTime tInterval = tFinish - tStart;
	tInterval.GetAsSystemTime( & timeDest );
	milliseconds = timeDest.wMilliseconds + 1000*(timeDest.second + 60*(timeDest.wMinute + 24*timeDest.wHour));
jkhfkjahj

	delete VNA;
	return true;
}

void print_last_error_message()
{
	LPVOID lpMsgBuf;
	DWORD LastError;

	LastError = GetLastError();
	printf("IO Error %ld\n", LastError );
	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
	    NULL,
		LastError,
	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
	);
	printf("Error message: %s\n",lpMsgBuf);
	// Free the buffer.
	LocalFree( lpMsgBuf );
}
