#include <crtdbg.h>
#include "HLPRXInternal.h"
#include "RQProtected.h"
#include "PRX.h"

NDTS_Boolean HLPRX_InitialiseSFDInterfaceBoard() 
{
	// The SFD Interface board is a pure write only slave
	if (!RQ_SetPeripheralDDR1(cardSet.rqIndex, 0xffffffff)) return NDTS_BFalse;
	cardSet.isSFDInterfaceBoardInitialised = NDTS_BTrue;
	return NDTS_BTrue;
}


void HLPRX_LimitPulseWidthCallback(unsigned long prxCard, unsigned long step, unsigned long tenNanoSecTicks)
{
	unsigned long oldStep, rqClockFreq, rqTicks;
	float pulseSecs;

	if (prxCard != 0)
		NDTS_LogLine(NDTS_LLEmerg,"Multi Card problem file %s, line %d", __FILE__, __LINE__);

	if (!RQ_GetSequenceStep(cardSet.rqIndex, &oldStep))
		goto error;

	if (!RQ_SetSequenceStep(cardSet.rqIndex, step))
		goto error;

    if (!RQ_GetSamplingFrequency(cardSet.rqIndex, &rqClockFreq))
		goto error;

	pulseSecs = (float)tenNanoSecTicks / (float)100000000.0;
	rqTicks = (unsigned long)(pulseSecs * rqClockFreq);

	if (!RQ_SetTransducerPulseWidth(cardSet.rqIndex, rqTicks))
		goto error;

	if (!RQ_SetSequenceStep(cardSet.rqIndex, oldStep))
		goto error;
	
	return;
error:
	NDTS_LogLine(NDTS_LLEmerg,"HLPRX_LimitPulseWidthCallback a call returned NDTS_BFalse");
	_ASSERTE(0);
}

NDTS_Boolean HLPRX_SetOverSamplingInternal(unsigned long block, unsigned long oversamplingMultiplier)
{
	// This is quicker than calling HLPRX_SetOverSampling because it doesn't rewrite the gates,
	// which needs to be done once all oversampling settings have been asserted
	unsigned long samplingFrequency, prxIndex;
	float jiffies, samplePeriodnS ;
	NDTS_Boolean isOK;

	if (!RQ_GetSamplingFrequency(cardSet.rqIndex, &samplingFrequency)) return NDTS_BFalse;
	samplePeriodnS = 1000000000.0f / (float)samplingFrequency;
	jiffies = 2.0f * samplePeriodnS / (float)(oversamplingMultiplier + 1);  // jiffies in 0.5nS steps

	isOK = RQ_SetSequenceStep(cardSet.rqIndex, block);
	if (isOK == NDTS_BFalse) 
		goto exit;

	isOK = RQ_SetNumberOfOversamples(cardSet.rqIndex, oversamplingMultiplier);
	if (!isOK)
		goto exit;

	for (prxIndex = 0; prxIndex < cardSet.numberOfPRXCards; prxIndex++)
	{
		isOK = PRX_SetNumberOfOversamples(cardSet.prxIndices[0], block, oversamplingMultiplier);
		if (!isOK)
			goto exit; 
		isOK = PRX_SetOversamplingDelay(cardSet.prxIndices[0], block, (unsigned long) jiffies);
		if (!isOK)
			goto exit; 
	}

	isOK = RQ_SetNumberOfAScansPerBScan(cardSet.rqIndex, cardSet.numberOfSteps);
	if (!isOK)
		goto exit; 

exit:
	return isOK;
}

NDTS_Boolean HLPRX_SetPrxRepetitionTimeFromCardSet(int stepIndex)
{
	NDTS_Boolean isOK;
	unsigned long prxRepTime, samplingFrequency, i;
	unsigned long oversamples;

	isOK = RQ_GetSamplingFrequency(cardSet.rqIndex, &samplingFrequency) ;
		if (!isOK) return NDTS_BFalse;

	isOK = RQ_GetNumberOfOversamples(cardSet.rqIndex, &oversamples);
	if (isOK == NDTS_BFalse)
		return NDTS_BFalse;

	// PRX_SetRepetitionTime doesn't allow for oversampling and is always in 100Mhz ticks.
	prxRepTime = (unsigned long)(
		(float)((cardSet.range[stepIndex] + cardSet.delay[stepIndex]) * (100000000.0 / (float)samplingFrequency)) 
		/ (float)oversamples) ;


	for (i = 0; i < cardSet.numberOfPRXCards; i++)
	{
		isOK = PRX_SetRepetitionTime(cardSet.prxIndices[i], stepIndex, prxRepTime);
			if (!isOK) return NDTS_BFalse;
	}
	return NDTS_BTrue;
}
