/******************************************************************************
 *
 *	NDT Solutions Pulser/Receiver Software Development Kit v1.0beta
 *
 ******************************************************************************
 *
 *  File:        PRX.h.
 *
 *  Description: Primary header file for PRX SDK.
 *
 *	Revision:    14/06/05 - Jonathan Welch (jonathan@ndtsolutions.com).
 *
 ******************************************************************************/

#ifndef PRX_H
#define PRX_H

/*
 *	 __cplusplus, __declspec(...), and __stdcall are Microsoft specific.
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef PRX_EXPORTS
	#define PRX_API __declspec(dllexport)
#else
	#define PRX_API __declspec(dllimport)
#endif

#ifdef STDCALL
	#define CALL_CONV __stdcall
#else
	#define CALL_CONV
#endif

#include "NDTSEnums.h"
#include "PRXEnums.h"
#include "PRXStructs.h"

/*
 *	Functions 
 */

// Administration

// This function enumerates the PRX cards and allocates some structures for them
// PRX_pciInitialise() should then be called for each card that is to be used
PRX_API NDTS_Boolean CALL_CONV PRX_PCIEnumerate(unsigned long *numberOfCards);

PRX_API char * CALL_CONV PRX_GetPRXCodeString(PRX_ReturnCode errorCode);
PRX_API PRX_ReturnCode CALL_CONV PRX_GetLastError();
PRX_API unsigned long PRX_ReturnNumberOfErrorLogLines();
PRX_API NDTS_Boolean PRX_GetErrorLogLine(unsigned long  lineNumber, char *pMessageBuffer, unsigned long  numberOfBytesInMessageBuffer);
PRX_API NDTS_Boolean PRX_ClearErrorLog() ;



PRX_API NDTS_Boolean CALL_CONV PRX_Initialise(unsigned long card) ;
PRX_API NDTS_Boolean CALL_CONV PRX_Uninitialise(unsigned long card) ;
PRX_API NDTS_Boolean CALL_CONV PRX_GetIsInitialised(unsigned long card) ;

PRX_API NDTS_Boolean CALL_CONV PRX_SetManualCommit(unsigned long card, NDTS_Boolean isManual);
PRX_API NDTS_Boolean CALL_CONV PRX_Commit(unsigned long card);

PRX_API NDTS_Boolean CALL_CONV PRX_GetHVStatus(unsigned long card, unsigned long *flag);

PRX_API NDTS_Boolean CALL_CONV PRX_SetGlobalRegs(unsigned long card, PRX_GlobalRegs *pRegs, NDTS_Boolean commit);
PRX_API NDTS_Boolean CALL_CONV PRX_GetGlobalRegs(unsigned long card, PRX_GlobalRegs *pRegs);

// Higher level functions - read/write individual values to the Global register.  These always commit immediately
// since they are designed for use by the UI

PRX_API NDTS_Boolean CALL_CONV PRX_SetPulseEchoEnable(unsigned long card, unsigned long flags);
PRX_API NDTS_Boolean CALL_CONV PRX_GetPulseEchoEnable(unsigned long card, unsigned long *flags);
PRX_API NDTS_Boolean CALL_CONV PRX_SetExternalTrigger(unsigned long card, unsigned long flag);
PRX_API NDTS_Boolean CALL_CONV PRX_GetExternalTrigger(unsigned long card, unsigned long *flag);
PRX_API NDTS_Boolean CALL_CONV PRX_SetHVEnable(unsigned long card, unsigned long flag);
PRX_API NDTS_Boolean CALL_CONV PRX_GetHVEnable(unsigned long card, unsigned long *flag);
PRX_API NDTS_Boolean CALL_CONV PRX_SetHVLevel(unsigned long card, unsigned long level);
PRX_API NDTS_Boolean CALL_CONV PRX_GetHVLevel(unsigned long card, unsigned long *level);

// Lowest level functions - read/write entire block sequence

PRX_API NDTS_Boolean CALL_CONV PRX_SetSequence(unsigned long card, unsigned long blocks, PRX_SequenceTableBlock *pRegs, NDTS_Boolean commit);
PRX_API NDTS_Boolean CALL_CONV PRX_GetSequence(unsigned long card, unsigned long blocks, PRX_SequenceTableBlock *pRegs);

// Mid level functions - read/write one sequence block at a time

PRX_API NDTS_Boolean CALL_CONV PRX_SetSequenceBlock(unsigned long card, unsigned long block, PRX_SequenceTableBlock *pRegs, NDTS_Boolean commit);
PRX_API NDTS_Boolean CALL_CONV PRX_GetSequenceBlock(unsigned long card, unsigned long block, PRX_SequenceTableBlock *pRegs);

// Higher level functions - read/write individual values to a sequence block.  These always commit imediately
// since they are designed for use by the UI

PRX_API NDTS_Boolean CALL_CONV PRX_SetTransmitPulseEnable(unsigned long card, unsigned long block, unsigned long flags);
PRX_API NDTS_Boolean CALL_CONV PRX_GetTransmitPulseEnable(unsigned long card, unsigned long block, unsigned long *flags);
PRX_API NDTS_Boolean CALL_CONV PRX_SetStepSkipCount(unsigned long card, unsigned long block, unsigned long value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetStepSkipCount(unsigned long card, unsigned long block, unsigned long *value);
PRX_API NDTS_Boolean CALL_CONV PRX_SetReceiveChannel(unsigned long card, unsigned long block, unsigned long channel);
PRX_API NDTS_Boolean CALL_CONV PRX_GetReceiveChannel(unsigned long card, unsigned long block, unsigned long *channel);
PRX_API NDTS_Boolean CALL_CONV PRX_SetMpxGain(unsigned long card, unsigned long block, unsigned long gain);
PRX_API NDTS_Boolean CALL_CONV PRX_GetMpxGain(unsigned long card, unsigned long block, unsigned long *gain);
//PRX_API NDTS_Boolean CALL_CONV PRX_SetEndOfSequence(unsigned long card, unsigned long block, unsigned long flag);
//PRX_API NDTS_Boolean CALL_CONV PRX_GetEndOfSequence(unsigned long card, unsigned long block, unsigned long *flag);
PRX_API NDTS_Boolean CALL_CONV PRX_GetNumberOfSequenceSteps(unsigned long card, unsigned long *pnSteps);

PRX_API NDTS_Boolean CALL_CONV PRX_SetFineGain(unsigned long card, unsigned long block, unsigned long gain);
PRX_API NDTS_Boolean CALL_CONV PRX_GetFineGain(unsigned long card, unsigned long block, unsigned long *gain);
PRX_API NDTS_Boolean CALL_CONV PRX_SetExternalTCG(unsigned long card, unsigned long block, unsigned long flag);
PRX_API NDTS_Boolean CALL_CONV PRX_GetExternalTCG(unsigned long card, unsigned long block, unsigned long *flag);

PRX_API NDTS_Boolean CALL_CONV PRX_SetBackendLowpassFilter(unsigned long card, unsigned long block, PRX_BackEndLowPassFilter value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetBackendLowpassFilter(unsigned long card, unsigned long block, PRX_BackEndLowPassFilter *value);
PRX_API NDTS_Boolean CALL_CONV PRX_SetBackendHighpassFilter(unsigned long card, unsigned long block, PRX_BackEndHighPassFilter value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetBackendHighpassFilter(unsigned long card, unsigned long block, PRX_BackEndHighPassFilter *value);
PRX_API NDTS_Boolean CALL_CONV PRX_SetFrontendLowpassFilter(unsigned long card, unsigned long block, PRX_FrontEndLowPassFilter value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetFrontendLowpassFilter(unsigned long card, unsigned long block, PRX_FrontEndLowPassFilter *value);
PRX_API NDTS_Boolean CALL_CONV PRX_SetFrontendHighpassFilter(unsigned long card, unsigned long block, PRX_FrontEndHighPassFilter value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetFrontendHighpassFilter(unsigned long card, unsigned long block, PRX_FrontEndHighPassFilter *value);

PRX_API NDTS_Boolean CALL_CONV PRX_SetInputImpedance(unsigned long card, unsigned long block, unsigned long value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetInputImpedance(unsigned long card, unsigned long block, unsigned long *value);
PRX_API NDTS_Boolean CALL_CONV PRX_SetCoarseGain(unsigned long card, unsigned long block, unsigned long value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetCoarseGain(unsigned long card, unsigned long block, unsigned long *value);

PRX_API NDTS_Boolean CALL_CONV PRX_SetOversamplingDelay(unsigned long card, unsigned long block, unsigned long jiffies);
PRX_API NDTS_Boolean CALL_CONV PRX_GetOversamplingDelay(unsigned long card, unsigned long block, unsigned long *jiffies);

PRX_API NDTS_Boolean CALL_CONV PRX_SetNumberOfOversamples(unsigned long card, unsigned long block, unsigned long numberOfOversamples);
PRX_API NDTS_Boolean CALL_CONV PRX_GetNumberOfOversamples(unsigned long card, unsigned long block, unsigned long *numberOfOversamples);

PRX_API NDTS_Boolean CALL_CONV PRX_SetPulseWidth(unsigned long card, unsigned long block, unsigned long fiveNanoSecTicks);
PRX_API NDTS_Boolean CALL_CONV PRX_GetPulseWidth(unsigned long card, unsigned long block, unsigned long *fiveNanoSecTicks);
PRX_API NDTS_Boolean CALL_CONV PRX_SetPulseTrainLength(unsigned long card, unsigned long block, unsigned long value);
PRX_API NDTS_Boolean CALL_CONV PRX_GetPulseTrainLength(unsigned long card, unsigned long block, unsigned long *value);

PRX_API NDTS_Boolean CALL_CONV PRX_SetRepetitionTime(unsigned long card, unsigned long block, unsigned long ticks);
PRX_API NDTS_Boolean CALL_CONV PRX_GetRepetitionTime(unsigned long card, unsigned long block, unsigned long *ticks);

PRX_API NDTS_Boolean CALL_CONV PRX_GetSystemFPGAVersionNumber(unsigned long card, unsigned long *versionNumber);

// Firmware controlled safe operating mode.  
// The firmware counts the on time over 1M (0xfffff) steps.  It has a table of pulses that the FET may be on for
// various voltage levels.  If the on time is exceeded, it cuts power to the FET.
// If isAutoReset has been set true, the output will be re-enabled once the 1M steps are up.  Otherwise, the output will remain off
// until PRX_ResetFETOverload is called.
// If the on time is exceeded, PRX_GetFETOverloadStatus will return isOverload = true.  This is only 
// reset when PRX_ResetFETOverload is called, even if isAutoReset is true.
PRX_API NDTS_Boolean CALL_CONV PRX_SetAutoResetForFETOverload(unsigned long card, NDTS_Boolean isAutoReset);
PRX_API NDTS_Boolean CALL_CONV PRX_ResetFETOverload(unsigned long card);
PRX_API NDTS_Boolean CALL_CONV PRX_GetFETOverloadStatus(unsigned long card, NDTS_Boolean *isOverload);

// Software controlled safe operating mode.
// The software controlled safe operating mode limits the pulse width, using the same rules as the firmware.
// This gives a smoother result when the operating limit is exceeded.
// It is enabled separately to the firmware, however it is advisable to use PRX_SetAutoResetForFETOverload isAutoReset = true
// in the firmwar eas the firmware may trip as parameters are changed.
// If the PRX is a slave to another device, repetition time and the pulse width are controlled by the external master.
// PRX_SetMasterRepetitionTime and PRX_SetPulseWidth must be called to keep the PRX SDK up to date with the master settings.
// The SDK will call back via limitPulseWidthCallback to inform the external master of the pulse rate to use to 
// keep within the safe operating area.  
// This is all taken care of via the HLSDK when using a RapiDAQ / PRX combo.
PRX_API NDTS_Boolean CALL_CONV PRX_SetSoftwareFETOverloadProtectionEnabled(unsigned long card, NDTS_Boolean isSoftwareFETOverloadProtectionEnabled);
// Get a bit mask of any channels that have been pulse width limited due to FET overload.
PRX_API NDTS_Boolean CALL_CONV PRX_GetSoftwareFETOverloadOutputMask(unsigned long card, unsigned long *softwareFETOverloadOutputMask);
PRX_API NDTS_Boolean CALL_CONV PRX_SetMasterRepetitionTime(unsigned long card, unsigned long ticks);
typedef void (*PRX_limitPulseWidthCallback)(unsigned long prxCard, unsigned long step, unsigned long tenNanoSecTicks);
PRX_API NDTS_Boolean CALL_CONV PRX_SetLimitPulseWidthCallback(unsigned long prxCard, PRX_limitPulseWidthCallback pfn);


#ifdef __cplusplus
}
#endif


#endif


