////////////////////////////////////////////////////////////////////////////////////////////////
// Summer 2008 - CRCStatistics.h contains functions that are used to access the
// statistics related to CRC checks on the data transfer between the card and the PC.
// They are not implemented on the PRX-RQ.

#ifndef CRCSTATS_H
#define CRCSTATS_H

#include "DataCollection.h"


#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
	unsigned long long numberOfGood ;	// Header OK first time
	unsigned long long numberOfRecovered ;	// Header wrong via DMA but correct when read via memcopy
	unsigned long long numberOfDesynchronisations ;	// Header contains ASN OK but the sequence number does not match the expected number
	unsigned long long numberOfUnrecovered ;		// The ASN part of the header is missing both when DMA'd and read via a PCI read.
} DC_HeaderCheckCounters ;

typedef struct
{
	unsigned long long numberOfGood ;  // CRC OK first time
	unsigned long long numberOfRecovered ;  // CRC OK when the block was re-read via a byte copy - likely to be a random PCI error.
	unsigned long long numberOfPseudoRecovered ;  // CRC incorrect but when re-read via a byte copy it comes out with the same value as the original DMA'd CRC 
												  // i.e. error is present in the memory of the card rather than during the transfer over PCI
	unsigned long long numberOfUnrecovered ;      // CRC incorrect and different when DMA's and byte copied, likely that the data has been corrupted in a differente
												  // way on each read?
} DC_MemoryCheckCounters ;

typedef struct 
{
	DC_MemoryCheckCounters aScanSampleCounter ;
	DC_HeaderCheckCounters aScanHeaderCounter ;
	DC_MemoryCheckCounters cScanSampleCounter ;
	DC_HeaderCheckCounters cScanHeaderCounter ;
} DC_CRCStatistics ;

typedef struct 
{
	unsigned long bScanIndex ;
	unsigned long aScanIndex ;
} DC_RawScanAScanIndices ;

typedef struct
{
	unsigned long startAddress ;
	unsigned long endAddress ;
} DC_SRAMMemoryRange ;

typedef enum
{
	DC_MCCUEGood,
	DC_MCCUERecovered,
	DC_MCCUEPseudoRecovered,
	DC_MCCUEUnrecovered,
	DC_MCCUEDesynchronised,
} DC_MemoryCheckCounterUpdateEvent ;


typedef struct 
{
	DC_RawScanAScanIndices indices ;
	DC_SRAMMemoryRange memoryRange ;
	DC_MemoryCheckCounterUpdateEvent event ;
} DC_BadAScanStatistics ;

typedef struct 
{
	unsigned long scanIndex ;
	DC_SRAMMemoryRange memoryRange ;
	DC_MemoryCheckCounterUpdateEvent event ;
} DC_BadCScanStatistics ;

typedef struct 
{
	unsigned long *pCRCTable ;
	DC_CRCStatistics statistics ;
	void (*pCRCBadScanHook)(const DC_BadAScanStatistics *pAScanStatistics, const DC_BadCScanStatistics *pCScanStatistics, void* pContext) ;
	void *pCRCBadScanHookContext ;
} DC_CRCState ;

typedef struct
{
	NDTS_Boolean doTimeAScanDMAs ;
	unsigned long aScanTimingAccumulatedMicros;
	unsigned long aScanTimingAccumulatedBytes;
	unsigned long lastAScanDMAKBPerSec;
	unsigned long bScansPerSecond;
}  DC_AScanDMATiming;


DC_API NDTS_Boolean CALL_CONV DC_GetCRCStatistics(unsigned long cardIndex, DC_CRCStatistics *pStatistics);
DC_API NDTS_Boolean CALL_CONV DC_ResetCRCStatistics(unsigned long cardIndex) ;
DC_API NDTS_Boolean CALL_CONV DC_SetCRCBadScanHook(unsigned long cardIndex, void (*pFN)(const DC_BadAScanStatistics *pAScanStatistics, const DC_BadCScanStatistics *pCScanStatistics, void* pContext), void* pContext) ;
DC_API NDTS_Boolean CALL_CONV DC_SetDoTimeAScanDMAs(unsigned long cardIndex, NDTS_Boolean doTimeAScanDMAs) ;
// Get the DMA and overhead time for the last set of BScans obtained via getRawScan.
DC_API NDTS_Boolean CALL_CONV DC_GetBScansPerSecond(unsigned long cardIndex, int *bScansPerSecond);

#ifdef __cplusplus
}
#endif

#endif
