#ifndef _MSAIO_
#define _MSAIO_

// plagiarised from the TAPR VNA design.
// as a consequence, the rights of Thomas C. McDermott, N5EG are acknowledged.
// Here is the licence text from his code. The only part used in this way
// is the basic structure of the VNA device and helper.
// All else is different 
// All the other code is Copyright (C) Dave Roberts G8KBB 2004
//
// ----------------- Extract from USB_EZ_interface.cpp -----------------
//    Copyright 2004, Thomas C. McDermott, N5EG
//    This file is part of VNAR - the Vector Network Analyzer program.
//
//    VNAR is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    VNAR is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with VNAR, if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// ------------------------End Extract ----------------------------------

#include "stdafx.h"

extern "C"
{
    // Declare USB constants and structures
	#include "ezusbsys.h"  // Ezusb IOCTL codes
}

#define DLL_VERSION 02

#define USB_STRING			char[256]

// This is the structure used for messages returned to the caller
// from the USB chip.

typedef struct _MSA_RXBUFFER {
	unsigned char last_command;		// command type last received
	unsigned char return_status;	// see below for status flag defintions
	unsigned char ioa;				// FX2 PortA data
	unsigned char iob;				// FX2 PortB data
	unsigned char ioc;				// FX2 PortC data
	unsigned char iod;				// FX2 PortD data
	unsigned char ioe;				// FX2 PortE data
	unsigned char ADC_reads_done;	// Number of ADC reads performed
	unsigned char data[240];		// VARIABLE nuumber of ADC reads performed
} MSA_RXBUFFER;

// bit definitions in MSA_RXBUFFER.return_status
//
//#define bMsaStatusAdcTimeoutFlag	0x80	// If set, FX2 timed out ADC read operation
//#define bMsaStatusNoMSAPowerFlag	0x40	// If set, portB bit 7 is low so no MSA power
#define bMsnaStatusAdcDataReadyFlag	0x20	// If set, the data[] part conatins ADC data
//#define bMsaStatusAdcConvPendFlag	0x10	// Internal flag, if high FX2 is waiting to start ADC read operations

// There are two types of message that we may send to the MSA. This is managed as a union.
// The first one is a raw port write to FX2 ports A and/or B.

typedef struct _MSA_TXBUFFER_RAW {
	unsigned char command_code;		// set to 0x5A to signal raw write
	unsigned char flags;			// see below for definitions		
	unsigned char portA;			// value to write to port A if flag set
	unsigned char portB;			// value to write to port B if flag set
	unsigned char portC;			// value to write to port B if flag set
	unsigned char portD;			// value to write to port B if flag set
	unsigned char portE;			// value to write to port B if flag set
} MSA_TXBUFFER_RAW;
//
// bit definitions for Flags for raw command
//
#define CmdMSARawDataFlagsWriteA 0x80              //if set, write specifiied value to port A
#define CmdMSARawDataFlagsWriteB 0x40              //if set, write specifiied value to port B
#define CmdMSARawDataFlagsWriteC 0x20              //if set, write specifiied value to port C
#define CmdMSARawDataFlagsWriteD 0x10              //if set, write specifiied value to port D
#define CmdMSARawDataFlagsWriteE 0x08              //if set, write specifiied value to port E

// This is the second message type we might send. A high level command to the FX2 CPU
// The flags tell the FX2 what to do with the DDS (reset them / write to them )
// After this, it will delay at least adc_del msec before doing ADC reads
// It then performs a series of back to back ADC reads before returning the result
// of all ADC reads in a message as structured above (MSA_RXBUFFER).

typedef struct _MSA_TXBUFFER_SET {
	unsigned char command_code;		// command code 0xa0-A4 for Set command
	unsigned char length;			// see belo for definitions
	unsigned char data[254];			// LO data to write to DDS
} MSA_TXBUFFER_SET;


typedef union _MSA_TXBUFFER {
	MSA_TXBUFFER_RAW raw;
	MSA_TXBUFFER_SET set;
} MSA_TXBUFFER;

// ****************************************************************
// Here is the main interface to the MSA - the MSADevice class.
// the IO32 and MSAwrapper functions use this. Use it if you can
// otherwise use MSAwrapper, and if all else fails use IO32 but it is slow


class MSADevice
{
private:
	bool Result;					// DeviceIoControl result
	int state;						// -1=no device +1=device OK
	class Helper * d;				// holds the USB device state

	void GetHandle(void);
	void ReleaseHandle(void);
	bool ToggleReset(bool hold);
public:
	char *pAllArray; 
	int nSteps;
	int nArrayCols;

public:
	__declspec(dllexport) _stdcall MSADevice();			// Constructor: open device, set state
	__declspec(dllexport) _stdcall ~MSADevice();		// Destructor: release __nogc objects and structs
	__declspec(dllexport) bool _stdcall  Init(void);	// Build descriptors, get pipes
	__declspec(dllexport) int _stdcall get_State();		// -1 = no device  +1 = device OK
	__declspec(dllexport)  bool _stdcall Start();		// Release reset of the 8051 processor on MSA
	__declspec(dllexport)  bool _stdcall Stop();		// Halt the 8051 processor on MSA
	__declspec(dllexport) int _stdcall get_Instance();	// get instance of MSA (0..9)
	__declspec(dllexport) bool _stdcall set_Instance(int instance); // set instance (0..9)
	__declspec(dllexport)  int _stdcall get_BytesReturned(); // tell me how many bytes were read last time
	__declspec(dllexport)  bool _stdcall Read(MSA_RXBUFFER * readbuf);		// read the MSA
	__declspec(dllexport)  bool _stdcall Write(MSA_TXBUFFER * writebuf, int message_size); // write to the MSA
	__declspec(dllexport) int _stdcall MSADevice::GetVersions();
	__declspec(dllexport) int _stdcall MSADevice::GetDeviceId();
};

// emulation of parallel port driver interface
bool __declspec(dllexport) _stdcall Out32(short PortAddress, short data);
short __declspec(dllexport) _stdcall Inp32(short PortAddress);

// simple MSA usb interface
bool __declspec(dllexport) _stdcall vnawrite(void *message, short bytecount);
bool __declspec(dllexport) _stdcall vnaread(void *message, short *bytecount);
extern "C" __declspec(dllexport) int  UsbMSADeviceWriteString( void *pMSAData, char *data, int message_size );
extern "C" __declspec(dllexport) int  UsbMSADeviceReadAdcs( void *pMSAData, char *data, int message_size, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceAllSlims( void *pMSAData, unsigned short thisstep, unsigned short filtbank, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceSetAllArrayPtr( void *pMSAData, void *pAllArray, short nArrayRows, short nArrayCols, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADevicePopulateDDSArray( void *pMSAData, __int64 *pArray, unsigned long *pData, unsigned short step, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADevicePopulateDDSArrayBitReverse( void *pMSAData, __int64 *pArray, unsigned long *pData, unsigned short step, unsigned short bits, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceWriteInt64LsbFirst( void *pMSAData, short nUsbCommandByte, unsigned long *data, 
															 short nBits, short clock, short fixeddata, short vardata, 
															 unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceWriteInt64MsbFirst( void *pMSAData, short nUsbCommandByte, unsigned long *data, 
															 short nBits, short clock, short fixeddata, short vardata, 
															 unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADevicePopulateAllArray( void *pMSAData, unsigned short Steps, unsigned short bits,
																   __int64 *pBit0Array, 
																   __int64 *pBit1Array, 
																   __int64 *pBit2Array, 
																   __int64 *pBit3Array, 
																   __int64 *pBit4Array, 
																   __int64 *pBit5Array, 
																   __int64 *pBit6Array, 
																   __int64 *pBit7Array, 
																	   unsigned long *pResults );
inline void ProcessBitArray( unsigned char *pVal, int bits, __int64 x, int bit );
extern "C" __declspec(dllexport) int  UsbMSADeviceAllSlimsAndLoad( void *pMSAData, unsigned short thisstep, unsigned short filtbank, unsigned short latch, unsigned short pdmcmd, unsigned short pdmlatch, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceAllSlimsAndLoadStruct( void *pMSAData, unsigned short *pData, unsigned long *pResults );
extern "C" __declspec(dllexport) int  UsbMSADeviceReadAdcsStruct( void *pMSAData, unsigned short *pData, unsigned long *pResults );

#endif
