#ifndef __FOUNDATION_H
#define __FOUNDATION_H

/**

@file

@brief   Fundamental interface declaration

Fundamental interface contains base function pointers and some mathematics tools.

*/


#include "i2c_bridge.h"
#include "math_mpi.h"





// Definitions

// Constants
#define INVALID_POINTER_VALUE		0
#define NO_USE						0

#define LEN_1_BYTE					1
#define LEN_2_BYTE					2
#define LEN_3_BYTE					3
#define LEN_4_BYTE					4
#define LEN_5_BYTE					5
#define LEN_11_BYTE					11

#define LEN_1_BIT					1

#define BYTE_MASK					0xff
#define BYTE_SHIFT					8
#define BYTE_BIT_NUM				8
#define LONG_BIT_NUM				32

#define BIT_0_MASK					0x01
#define BIT_7_MASK					0x80
#define BIT_7_SHIFT					7
#define BIT_8_MASK					0x100
#define BIT_8_SHIFT					8



// I2C buffer length
// Note: I2C_BUFFER_LEN must be greater than I2cReadingByteNumMax and I2cWritingByteNumMax in BASE_INTERFACE_MODULE.
#define I2C_BUFFER_LEN				128





/// Module types
enum MODULE_TYPE
{
	// DVB-T demod
	DVBT_DEMOD_TYPE_RTL2830,			///<   RTL2830 DVB-T demod

	// QAM demod
	QAM_DEMOD_TYPE_RTL2840,				///<   RTL2840 DVB-C demod
	QAM_DEMOD_TYPE_RTL2810_OC,			///<   RTL2810 OpenCable demod
	QAM_DEMOD_TYPE_RTL2820_OC,			///<   RTL2820 OpenCable demod

	// OOB demod
	OOB_DEMOD_TYPE_RTL2820_OOB,			///<   RTL2820 OOB demod

	// Tuner
	TUNER_TYPE_TDCGG052D,				///<   TDCG-G052D tuner (QAM)
	TUNER_TYPE_TDCHG001D,				///<   TDCH-G001D tuner (QAM)
	TUNER_TYPE_DCT7045,					///<   DCT-7045 tuner (QAM)
	TUNER_TYPE_TDQE3003A,				///<   TDQE3-003A tuner (QAM)
	TUNER_TYPE_MXL5005S,				///<   MxL5005S tuner (DVB-T, ATSC)
};


// Device type number base
#define DVBT_DEMOD_TYPE_NUM_BASE		DVBT_DEMOD_TYPE_RTL2830
#define QAM_DEMOD_TYPE_NUM_BASE			QAM_DEMOD_TYPE_RTL2840
#define OOB_DEMOD_TYPE_NUM_BASE			OOB_DEMOD_TYPE_RTL2820_OOB
#define TUNER_TYPE_NUM_BASE				TUNER_TYPE_TDCGG052D


// Device type number
#define DVBT_DEMOD_TYPE_NUM			1
#define QAM_DEMOD_TYPE_NUM			3
#define OOB_DEMOD_TYPE_NUM			1
#define TUNER_TYPE_NUM				3





/// On/off status
enum ON_OFF_STATUS
{
	OFF,		///<   Off
	ON,			///<   On
};


/// Yes/no status
enum YES_NO_STATUS
{
	NO,			///<   No
	YES,		///<   Yes
};


/// Lock status
enum LOCK_STATUS
{
	NOT_LOCKED,			///<   Not locked
	LOCKED,				///<   Locked
};


/// Loss status
enum LOSS_STATUS
{
	NOT_LOST,			///<   Not lost
	LOST,				///<   Lost
};


/// Function return status
enum FUNCTION_RETURN_STATUS
{
	FUNCTION_SUCCESS,			///<   Execute function successfully.
	FUNCTION_ERROR,				///<   Execute function unsuccessfully.
};


/// Crystal frequency
enum CRYSTAL_FREQ_HZ
{
	CRYSTAL_FREQ_4000000HZ  =  4000000,			///<   Crystal frequency =  4.0 MHz
	CRYSTAL_FREQ_16000000HZ = 16000000,			///<   Crystal frequency = 16.0 MHz
	CRYSTAL_FREQ_25000000HZ = 25000000,			///<   Crystal frequency = 25.0 MHz
	CRYSTAL_FREQ_28800000HZ = 28800000,			///<   Crystal frequency = 28.8 MHz
};


/// IF frequency
enum IF_FREQ_HZ
{
	IF_FREQ_4570000HZ  =  4570000,			///<   IF frequency =   4.57 MHz
	IF_FREQ_4571429HZ  =  4571429,			///<   IF frequency =  4.571 MHz
	IF_FREQ_36000000HZ = 36000000,			///<   IF frequency = 36.000 MHz
	IF_FREQ_36125000HZ = 36125000,			///<   IF frequency = 36.125 MHz
	IF_FREQ_36166667HZ = 36166667,			///<   IF frequency = 36.167 MHz
	IF_FREQ_44000000HZ = 44000000,			///<   IF frequency = 44.000 MHz
};


/// Spectrum mode
enum SPECTRUM_MODE
{
	SPECTRUM_NORMAL,			///<   Normal spectrum
	SPECTRUM_INVERSE,			///<   Inverse spectrum
};
#define SPECTRUM_MODE_NUM		2





/**

@defgroup   BASE_INTERFACE   Base interface

All module functions access basic functions through base interface.
One should build base interface with proper basic functions and corresponding arguments before using module functions.

*/
/// @{





/// Base interface module alias
typedef struct BASE_INTERFACE_MODULE_TAG BASE_INTERFACE_MODULE;





/**

@brief   Basic I2C reading function pointer

Upper layer functions will use BASE_FP_I2C_READ() to read ByteNum bytes from I2C device to pReadingBytes buffer.


@param [in]    pBaseInterface   The base interface module pointer
@param [in]    DeviceAddr       I2C device address in 8-bit format
@param [out]   pReadingBytes    Buffer pointer to an allocated memory for storing reading bytes
@param [in]    ByteNum          Reading byte number


@retval   FUNCTION_SUCCESS   Read bytes from I2C device with reading byte number successfully.
@retval   FUNCTION_ERROR     Read bytes from I2C device unsuccessfully.


@note \n
	The requirements of BASE_FP_I2C_READ() function are described as follows:
	-# Follow the I2C format for BASE_FP_I2C_READ(). \n
	   start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit
	-# Don't allocate memory on pReadingBytes.
	-# Upper layer functions should allocate memory on pReadingBytes before using BASE_FP_I2C_READ().
	-# Need to assign I2C reading funtion to BASE_FP_I2C_READ() for upper layer functions.



@par Example:
@code


#include "foundation.h"


// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
	unsigned char ReadingBytes[100];


	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);

	...

	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
	
	...

	return 0;
}


@endcode

*/
typedef int
(*BASE_FP_I2C_READ)(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	);





/**

@brief   Basic I2C writing function pointer

Upper layer functions will use BASE_FP_I2C_WRITE() to write ByteNum bytes from pWritingBytes buffer to I2C device.


@param [in]   pBaseInterface   The base interface module pointer
@param [in]   DeviceAddr       I2C device address in 8-bit format
@param [in]   pWritingBytes    Buffer pointer to writing bytes
@param [in]   ByteNum          Writing byte number


@retval   FUNCTION_SUCCESS   Write bytes to I2C device with writing bytes successfully.
@retval   FUNCTION_ERROR     Write bytes to I2C device unsuccessfully.


@note \n
	The requirements of BASE_FP_I2C_WRITE() function are described as follows:
	-# Follow the I2C format for BASE_FP_I2C_WRITE(). \n
	   start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit
	-# Need to assign I2C writing funtion to BASE_FP_I2C_WRITE() for upper layer functions.



@par Example:
@code


#include "foundation.h"


// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer.
int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
	unsigned char WritingBytes[100];


	// Assign implemented I2C writing funciton to BASE_FP_I2C_WRITE in base interface module.
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., CustomI2cWrite, ...);

	...

	// Use I2cWrite() to write 33 bytes from WritingBytes to I2C device.
	pBaseInterface->I2cWrite(pBaseInterface, 0x20, WritingBytes, 33);
	
	...

	return 0;
}


@endcode

*/
typedef int
(*BASE_FP_I2C_WRITE)(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	);





/**

@brief   Basic waiting function pointer

Upper layer functions will use BASE_FP_WAIT_MS() to wait WaitTimeMs millisecond.


@param [in]   pBaseInterface   The base interface module pointer
@param [in]   WaitTimeMs       Waiting time in millisecond


@note \n
	The requirements of BASE_FP_WAIT_MS() function are described as follows:
	-# Need to assign a waiting function to BASE_FP_WAIT_MS() for upper layer functions.



@par Example:
@code


#include "foundation.h"


// Implement waiting funciton for BASE_FP_WAIT_MS function pointer.
void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...

	return;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Assign implemented waiting funciton to BASE_FP_WAIT_MS in base interface module.
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., ..., CustomWaitMs);

	...

	// Use WaitMs() to wait 30 millisecond.
	pBaseInterface->WaitMs(pBaseInterface, 30);
	
	...

	return 0;
}


@endcode

*/
typedef void
(*BASE_FP_WAIT_MS)(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	);





/**

@brief   User defined data pointer setting function pointer

One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for
custom basic function implementation.


@param [in]   pBaseInterface     The base interface module pointer
@param [in]   pUserDefinedData   Pointer to user defined data


@note \n
	One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for
	custom basic function implementation.



@par Example:
@code


#include "foundation.h"


// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	CUSTOM_USER_DEFINED_DATA *pUserDefinedData;


	// Get user defined data pointer of base interface structure for custom I2C reading function.
	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData);

	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
	unsigned char ReadingBytes[100];

	CUSTOM_USER_DEFINED_DATA UserDefinedData;


	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);

	...

	// Set user defined data pointer of base interface structure for custom basic functions.
	pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData);

	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
	
	...

	return 0;
}


@endcode

*/
typedef void
(*BASE_FP_SET_USER_DEFINED_DATA_POINTER)(
	BASE_INTERFACE_MODULE *pBaseInterface,
	void *pUserDefinedData
	);





/**

@brief   User defined data pointer getting function pointer

One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for
custom basic function implementation.


@param [in]   pBaseInterface      The base interface module pointer
@param [in]   ppUserDefinedData   Pointer to user defined data pointer


@note \n
	One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for
	custom basic function implementation.



@par Example:
@code


#include "foundation.h"


// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	CUSTOM_USER_DEFINED_DATA *pUserDefinedData;


	// Get user defined data pointer of base interface structure for custom I2C reading function.
	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData);

	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
	unsigned char ReadingBytes[100];

	CUSTOM_USER_DEFINED_DATA UserDefinedData;


	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);

	...

	// Set user defined data pointer of base interface structure for custom basic functions.
	pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData);

	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
	
	...

	return 0;
}


@endcode

*/
typedef void
(*BASE_FP_GET_USER_DEFINED_DATA_POINTER)(
	BASE_INTERFACE_MODULE *pBaseInterface,
	void **ppUserDefinedData
	);





/// Base interface module structure
struct BASE_INTERFACE_MODULE_TAG
{
	// Variables and function pointers
	unsigned char I2cReadingByteNumMax;
	unsigned char I2cWritingByteNumMax;

	BASE_FP_I2C_READ    I2cRead;
	BASE_FP_I2C_WRITE   I2cWrite;
	BASE_FP_WAIT_MS     WaitMs;

	BASE_FP_SET_USER_DEFINED_DATA_POINTER   SetUserDefinedDataPointer;
	BASE_FP_GET_USER_DEFINED_DATA_POINTER   GetUserDefinedDataPointer;


	// User defined data
	void *pUserDefinedData;
};





/**

@brief   Base interface builder

Use BuildBaseInterface() to build base interface for module functions to access basic functions.


@param [in]   ppBaseInterface              Pointer to base interface module pointer
@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
@param [in]   I2cReadingByteNumMax         Maximum I2C reading byte number for basic I2C reading function
@param [in]   I2cWritingByteNumMax         Maximum I2C writing byte number for basic I2C writing function
@param [in]   I2cRead                      Basic I2C reading function pointer
@param [in]   I2cWrite                     Basic I2C writing function pointer
@param [in]   WaitMs                       Basic waiting function pointer


@note \n
	-# One should build base interface before using module functions.
	-# The I2C reading format is described as follows:
	   start_bit + (device_addr | reading_bit) + reading_byte * byte_num + stop_bit
	-# The I2cReadingByteNumMax is the maximum byte_num of the I2C reading format.
	-# The I2C writing format is described as follows:
	   start_bit + (device_addr | writing_bit) + writing_byte * byte_num + stop_bit
	-# The I2cWritingByteNumMax is the maximum byte_num of the I2C writing format.



@par Example:
@code


#include "foundation.h"


// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer.
int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...

	return FUNCTION_SUCCESS;

error_status:

	return FUNCTION_ERROR;
}


// Implement waiting funciton for BASE_FP_WAIT_MS function pointer.
void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...

	return;
}


int main(void)
{
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Build base interface with the following settings.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);

	...

	return 0;
}


@endcode

*/
void
BuildBaseInterface(
	BASE_INTERFACE_MODULE **ppBaseInterface,
	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
	unsigned char I2cReadingByteNumMax,
	unsigned char I2cWritingByteNumMax,
	BASE_FP_I2C_READ I2cRead,
	BASE_FP_I2C_WRITE I2cWrite,
	BASE_FP_WAIT_MS WaitMs
	);





// User data pointer of base interface structure setting and getting functions
void
base_interface_SetUserDefinedDataPointer(
	BASE_INTERFACE_MODULE *pBaseInterface,
	void *pUserDefinedData
	);

void
base_interface_GetUserDefinedDataPointer(
	BASE_INTERFACE_MODULE *pBaseInterface,
	void **ppUserDefinedData
	);





/// @}





// Math functions

// Binary and signed integer converter
unsigned long
SignedIntToBin(
	long Value,
	unsigned char BitNum
	);

long
BinToSignedInt(
	unsigned long Binary,
	unsigned char BitNum
	);










/**

@mainpage Realtek demod Source Code Manual

@note
	-# The Realtek demod API source code is designed for demod IC driver porting.
	-# The API source code is written in C language without floating-point arithmetic.
	-# One can use the API to manipulate Realtek demod IC.
	-# The API will call custom underlayer functions through API base interface module.


@par Important:
	-# Please assign API base interface module with custom underlayer functions instead of modifying API source code.
	-# Please see the example code to understand the relation bewteen API and custom system.


@see
@subpage RTL2820_OOB_EXAMPLE_CODE              "RTL2820 OOB Example Code"
@subpage RTL2820_OC_EXAMPLE_CODE               "RTL2820 OpenCable Example Code"
@subpage RTL2840_EXAMPLE_CODE                  "RTL2840 Example Code"
@subpage RTL2840_TS_SERIAL_MODE_EXAMPLE_CODE   "RTL2840 TS serial mode Example Code"
@subpage RTL2840_DCT7045_EXAMPLE_CODE          "RTL2840 and DCT-7045 Example Code"
@subpage RTL2840_TDCHG001D_EXAMPLE_CODE        "RTL2840 and TDCH-G001D Example Code"

*/










/**

@page RTL2820_OOB_EXAMPLE_CODE   RTL2820 OOB Example Code


The following C code takes RTL2820 OOB driver porting as an example.


@code


#include "demod_rtl2820_oob.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int AagcLockStatus, EqLockStatus;

	long RfAgc, IfAgc;
	unsigned long DiAgc;

	unsigned long SnrDbNum, SnrDbDen;
	double SnrDb;

	unsigned long AdcClipCnt;
	long TrOffsetPpm;
	long CrOffsetHz;

	unsigned long SignalStrength, SignalQuality;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	OOB_DEMOD_MODULE  *pDemod;
	OOB_DEMOD_MODULE  OobDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2820OobI2cBridgeModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2820 OOB module with device address 0x24 in 8-bit format and crystal frequency 25 MHz.
	BuildRtl2820OobModule(&pDemod, &OobDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2820OobI2cBridgeModuleMemory,
		0x24, CRYSTAL_FREQ_25000000HZ);



	// Execute OpenCable demod initialization with OpenCable API here.


	// Initialize OOB demod.
	// Note: Need to initialize OpenCable demod with OpenCable API before OOB demod initialization.
	pDemod->Initialize(pDemod);


	// Set demod AAGC registers.
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_RF_AAGC_OOB_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_IF_AAGC_OOB_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_RF_AAGC_OOB_OE, 0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_IF_AAGC_OOB_OE, 1);
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_RF_AAGC_OOB_DRIVING, 0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_IF_AAGC_OOB_DRIVING, 0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_RF_AAGC_MAX, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, OOB_RF_AAGC_MIN, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, OOB_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, OOB_IF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, OOB_AAGC_MODE_SEL, 0);


	// Set demod symbol rate with 1.544 MHz.
	pDemod->SetSymbolRateHz(pDemod, 1544000);


	// Set demod alpha mode with alpha = 0.3.
	pDemod->SetAlphaMode(pDemod, OOB_ALPHA_0P3);


	// Set demod IF frequency with 44 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_44000000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);


	// Set demod LO with RF freuqnecy 100 MHz.
	pDemod->SetRfFreqHz(pDemod, 100000000);


	
	// Need to set tuner before demod software reset.
	// The order to set demod and tuner is not important.
	// Note: One can use "pDemod->SetRegBitsWithPage(pDemod, OOB_OPT_I2C_RELAY, 0x1);"
	//       for tuner I2C command forwarding.



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check EQ lock status through frame lock.
		pDemod->IsEqLocked(pDemod, &EqLockStatus);

		if(EqLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	// One can use the following functions to get demod information.


	// Get demod lock status.
	pDemod->IsAagcLocked(pDemod, &AagcLockStatus);
	pDemod->IsEqLocked(pDemod, &EqLockStatus);


	// Get demod AGC value.
	pDemod->GetRfAgc(pDemod, &RfAgc);
	pDemod->GetIfAgc(pDemod, &IfAgc);
	pDemod->GetDiAgc(pDemod, &DiAgc);


	// Get demod SNR in dB.
	pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen);
	SnrDb = (double)SnrDbNum / (double)SnrDbDen;


	// Get demod ADC clipping counter value., CR and TR offset
	pDemod->GetAdcClipCnt(pDemod, &AdcClipCnt);


	// Get demod TR offset in ppm.
	pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm);


	// Get demod CR offset in Hz
	pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz);


	// Get signal strength and quality.
	// Note: 1. The gotten signal strength is 0 ~ 100.
	//       2. The gotten signal qualtiy is 0 ~ 100.
	pDemod->GetSignalStrength(pDemod, &SignalStrength);
	pDemod->GetSignalQuality(pDemod, &SignalQuality);



	return 0;
}


@endcode

*/




















/**

@page RTL2820_OC_EXAMPLE_CODE   RTL2820 OpenCable Example Code


The following C code takes RTL2820 OpenCable driver porting as an example.


@code


#include "demod_rtl2820_oc.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int AagcLockStatus, EqLockStatus, FrameLockStatus;

	long RfAgc, IfAgc;
	unsigned long DiAgc;

	unsigned long SnrDbNum, SnrDbDen;
	double SnrDb;

	unsigned long BerNum, BerDen, PerNum, PerDen;
	double Ber, Per;

	unsigned long AdcClipCnt;
	long TrOffsetPpm;
	long CrOffsetHz;

	unsigned long SignalStrength, SignalQuality;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	QAM_DEMOD_MODULE  *pDemod;
	QAM_DEMOD_MODULE  QamDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2820OcI2cBridgeModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2820 OpenCable module with device address 0x24 in 8-bit format and crystal frequency 25 MHz.
	BuildRtl2820OcModule(&pDemod, &QamDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2820OcI2cBridgeModuleMemory,
		0x24, CRYSTAL_FREQ_25000000HZ);



	// Initialize demod.
	pDemod->Initialize(pDemod);


	// Set demod AAGC registers.
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_OE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_OE, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AGC_DRIVING, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AGC_DRIVING, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MAX, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MIN, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_AAGC_MODE_SEL, 1);


	// Set demod QAM mode with 64-QAM.
	pDemod->SetQamMode(pDemod, QAM_QAM_64);


	// Set demod symbol rate with 5.056941 MHz.
	pDemod->SetSymbolRateHz(pDemod, 5056941);


	// Set demod alpha mode with alpha = 0.18.
	pDemod->SetAlphaMode(pDemod, QAM_ALPHA_0P18);


	// Set demod IF frequency with 44 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_44000000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);


	
	// Need to set tuner before demod software reset.
	// The order to set demod and tuner is not important.
	// Note: One can use "pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1);"
	//       for tuner I2C command forwarding.



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check signal lock status through frame lock.
		pDemod->IsFrameLocked(pDemod, &FrameLockStatus);

		if(FrameLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	// One can use the following functions to get demod information.


	// Get demod lock status.
	pDemod->IsAagcLocked(pDemod, &AagcLockStatus);
	pDemod->IsEqLocked(pDemod, &EqLockStatus);
	pDemod->IsFrameLocked(pDemod, &FrameLockStatus);


	// Get demod AGC value.
	pDemod->GetRfAgc(pDemod, &RfAgc);
	pDemod->GetIfAgc(pDemod, &IfAgc);
	pDemod->GetDiAgc(pDemod, &DiAgc);


	// Get demod SNR in dB.
	pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen);
	SnrDb = (double)SnrDbNum / (double)SnrDbDen;


	// Get demod BER and PER.
	// Note: 1. Error test volume is 4 in the example.
	//          The error test packet number is pow(2, (2 * error_test_volume + 4)) = pow(2, 12) = 0x1000.
	//       2. Wait time is 1000 ms in the example.
	pDemod->GetErrorRate(pDemod, 4, 1000, &BerNum, &BerDen, &PerNum, &PerDen);

	// Get demod BER.
	Ber = (double)BerNum / (double)BerDen;

	// Get demod PER.
	Per = (double)PerNum / (double)PerDen;


	// Get demod ADC clipping counter value., CR and TR offset
	pDemod->GetAdcClipCnt(pDemod, &AdcClipCnt);


	// Get demod TR offset in ppm.
	pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm);


	// Get demod CR offset in Hz
	pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz);


	// Get signal strength and quality.
	// Note: 1. The gotten signal strength is 0 ~ 100.
	//       2. The gotten signal qualtiy is 0 ~ 100.
	pDemod->GetSignalStrength(pDemod, &SignalStrength);
	pDemod->GetSignalQuality(pDemod, &SignalQuality);



	return 0;
}


@endcode

*/




















/**

@page RTL2840_EXAMPLE_CODE   RTL2840 Example Code


The following C code takes RTL2840 driver porting as an example.


@code


#include "demod_rtl2840.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int AagcLockStatus, EqLockStatus, FrameLockStatus;

	long RfAgc, IfAgc;
	unsigned long DiAgc;

	unsigned long SnrDbNum, SnrDbDen;
	double SnrDb;

	unsigned long BerNum, BerDen, PerNum, PerDen;
	double Ber, Per;

	unsigned long AdcClipCnt;
	long TrOffsetPpm;
	long CrOffsetHz;

	unsigned long SignalStrength, SignalQuality;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	QAM_DEMOD_MODULE  *pDemod;
	QAM_DEMOD_MODULE  QamDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2840I2cBridgeModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2840 module with device address 0x44 in 8-bit format and crystal frequency 28.8 MHz.
	BuildRtl2840Module(&pDemod, &QamDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2840I2cBridgeModuleMemory,
		0x44, CRYSTAL_FREQ_28800000HZ, QAM_DEMOD_EN_AM_HUM);



	// Initialize demod.
	pDemod->Initialize(pDemod);


	// Set demod AAGC registers.
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_OEN, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_OEN, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MAX, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MIN, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_AAGC_MODE_SEL, 1);


	// Set demod QAM mode with 64-QAM.
	pDemod->SetQamMode(pDemod, QAM_QAM_64);


	// Set demod symbol rate with 6.952 MHz.
	pDemod->SetSymbolRateHz(pDemod, 6952000);


	// Set demod alpha mode with alpha = 0.15.
	pDemod->SetAlphaMode(pDemod, QAM_ALPHA_0P15);


	// Set demod IF frequency with 36 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_36000000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);



	// Need to set tuner before demod software reset.
	// The order to set demod and tuner is not important.
	// Note: One can use "pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1);"
	//       for tuner I2C command forwarding.



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check signal lock status through frame lock.
		pDemod->IsFrameLocked(pDemod, &FrameLockStatus);

		if(FrameLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	// One can use the following functions to get demod information.


	// Get demod lock status.
	pDemod->IsAagcLocked(pDemod, &AagcLockStatus);
	pDemod->IsEqLocked(pDemod, &EqLockStatus);
	pDemod->IsFrameLocked(pDemod, &FrameLockStatus);


	// Get demod AGC value.
	pDemod->GetRfAgc(pDemod, &RfAgc);
	pDemod->GetIfAgc(pDemod, &IfAgc);
	pDemod->GetDiAgc(pDemod, &DiAgc);


	// Get demod SNR in dB.
	pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen);
	SnrDb = (double)SnrDbNum / (double)SnrDbDen;


	// Get demod BER and PER.
	// Note: 1. Error test volume is 4 in the example.
	//          The error test packet number is pow(2, (2 * error_test_volume + 4)) = pow(2, 12) = 0x1000.
	//       2. Wait time is 1000 ms in the example.
	pDemod->GetErrorRate(pDemod, 4, 1000, &BerNum, &BerDen, &PerNum, &PerDen);

	// Get demod BER.
	Ber = (double)BerNum / (double)BerDen;

	// Get demod PER.
	Per = (double)PerNum / (double)PerDen;


	// Get demod ADC clipping counter value., CR and TR offset
	pDemod->GetAdcClipCnt(pDemod, &AdcClipCnt);


	// Get demod TR offset in ppm.
	pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm);


	// Get demod CR offset in Hz
	pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz);


	// Get signal strength and quality.
	// Note: 1. The gotten signal strength is 0 ~ 100.
	//       2. The gotten signal qualtiy is 0 ~ 100.
	pDemod->GetSignalStrength(pDemod, &SignalStrength);
	pDemod->GetSignalQuality(pDemod, &SignalQuality);



	return 0;
}


@endcode

*/




















/**

@page RTL2840_TS_SERIAL_MODE_EXAMPLE_CODE   RTL2840 TS Serial Mode Example Code


The following C code takes RTL2840 driver porting as an example.


@code


#include "demod_rtl2840.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr, 
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int FrameLockStatus;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	QAM_DEMOD_MODULE  *pDemod;
	QAM_DEMOD_MODULE  QamDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2840I2cBridgeModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2840 module with device address 0x44 in 8-bit format and crystal frequency 28.8 MHz.
	BuildRtl2840Module(&pDemod, &QamDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2840I2cBridgeModuleMemory,
		0x44, CRYSTAL_FREQ_28800000HZ, QAM_DEMOD_EN_AM_HUM);



	// Initialize demod.
	pDemod->Initialize(pDemod);


	// Set demod AAGC registers.
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_OEN, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_OEN, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MAX, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MIN, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_AAGC_MODE_SEL, 1);


	// Set demod TS interface with serial mode.
	pDemod->SetRegBitsWithPage(pDemod, QAM_SERIAL, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_CDIV_PH0, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_CDIV_PH1, 0);


	// Set demod QAM mode with 64-QAM.
	pDemod->SetQamMode(pDemod, QAM_QAM_64);


	// Set demod symbol rate with 6.952 MHz.
	pDemod->SetSymbolRateHz(pDemod, 6952000);


	// Set demod alpha mode with alpha = 0.15.
	pDemod->SetAlphaMode(pDemod, QAM_ALPHA_0P15);


	// Set demod IF frequency with 36 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_36000000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);



	// Need to set tuner before demod software reset.
	// The order to set demod and tuner is not important.
	// Note: One can use "pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1);"
	//       for tuner I2C command forwarding.



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check signal lock status through frame lock.
		pDemod->IsFrameLocked(pDemod, &FrameLockStatus);

		if(FrameLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	return 0;
}


@endcode

*/




















/**

@page RTL2840_TDCHG001D_EXAMPLE_CODE   RTL2840 TDCH-G001D Example Code


The following C code takes RTL2840 driver porting as an example.


@code


#include "demod_rtl2840.h"
#include "tuner_tdchg001d.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int FrameLockStatus;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	QAM_DEMOD_MODULE  *pDemod;
	QAM_DEMOD_MODULE  QamDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2840I2cBridgeModuleMemory;


	// TDCH-G001D tuner module
	TUNER_MODULE           *pTuner;
	TUNER_MODULE           TunerModuleMemory;
	TDCHG001D_EXTRA_MODULE Tdchg001dExtraModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2840 module with device address 0x44 in 8-bit format and crystal frequency 28.8 MHz.
	BuildRtl2840Module(&pDemod, &QamDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2840I2cBridgeModuleMemory,
		0x44, CRYSTAL_FREQ_28800000HZ, QAM_DEMOD_EN_AM_HUM);


	// Build TDCH-G001D tuner module with device address 0xc0 in 8-bit format.
	BuildTdchg001dModule(&pTuner, &TunerModuleMemory, &Tdchg001dExtraModuleMemory, &BaseInterfaceModuleMemory,
		&Rtl2840I2cBridgeModuleMemory, 0xc0);



	// Initialize demod.
	pDemod->Initialize(pDemod);


	// Set demod AAGC registers.
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_DRIVE, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_DRIVE, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_OEN, 0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_OEN, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MAX, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MIN, 0x80);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_AAGC_MODE_SEL, 1);


	// Set demod QAM mode with 64-QAM.
	pDemod->SetQamMode(pDemod, QAM_QAM_64);


	// Set demod symbol rate with 6.952 MHz.
	pDemod->SetSymbolRateHz(pDemod, 6952000);


	// Set demod alpha mode with alpha = 0.15.
	pDemod->SetAlphaMode(pDemod, QAM_ALPHA_0P15);


	// Set demod IF frequency with 36.125 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_36125000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);



	// Initialize tuner.
	pTuner->Initialize(pTuner);


	// Set tuner RF frequency with 858 MHz.
	pTuner->SetRfFreqHz(pTuner, 858000000);



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check signal lock status through frame lock.
		pDemod->IsFrameLocked(pDemod, &FrameLockStatus);

		if(FrameLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	return 0;
}


@endcode

*/




















/**

@page RTL2840_DCT7045_EXAMPLE_CODE   RTL2840 DCT-7045 Example Code


The following C code takes RTL2840 and DCT-7045 driver porting as an example.


@code


#include "demod_rtl2840.h"
#include "tuner_dct7045.h"



int
CustomI2cRead(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	unsigned char *pReadingBytes,
	unsigned char ByteNum
	)
{
	...
}


int
CustomI2cWrite(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char DeviceAddr,
	const unsigned char *pWritingBytes,
	unsigned char ByteNum
	)
{
	...
}


void
CustomWaitMs(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned long WaitTimeMs
	)
{
	...
}



int main(void)
{
	int i;

	int FrameLockStatus;





	// Base interface module
	BASE_INTERFACE_MODULE *pBaseInterface;
	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;


	// Demod module
	QAM_DEMOD_MODULE  *pDemod;
	QAM_DEMOD_MODULE  QamDemodModuleMemory;
	I2C_BRIDGE_MODULE Rtl2840I2cBridgeModuleMemory;


	// DCT-7045 tuner module
	TUNER_MODULE         *pTuner;
	TUNER_MODULE         TunerModuleMemory;
	DCT7045_EXTRA_MODULE Dct7045ExtraModuleMemory;



	// Set API base interface with custom underlayer functions and its arguments.
	//
	// 1. Assign 9 to maximum I2C reading byte number.
	// 2. Assign 8 to maximum I2C writing byte number.
	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
	// 5. Assign CustomWaitMs() to basic waiting function pointer.
	//
	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, 9, 8, CustomI2cRead, CustomI2cWrite, CustomWaitMs);



	// Build RTL2840 module with device address 0x44 in 8-bit format and crystal frequency 28.8 MHz.
	BuildRtl2840Module(&pDemod, &QamDemodModuleMemory, &BaseInterfaceModuleMemory, &Rtl2840I2cBridgeModuleMemory,
		0x44, CRYSTAL_FREQ_28800000HZ, QAM_DEMOD_EN_AM_HUM);


	// Build DCT-7045 tuner module with device address 0xc0 in 8-bit format.
	BuildDct7045Module(&pTuner, &TunerModuleMemory, &Dct7045ExtraModuleMemory, &Rtl2840I2cBridgeModuleMemory,
		0xc0, CRYSTAL_FREQ_4000000HZ);



	// Initialize demod.
	pDemod->Initialize(pDemod);


	// Set demod RTL2840 AAGC registers for tuner DCT-7045.
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_DRIVE, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_DRIVE, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_RF_AAGC_OEN, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_IF_AAGC_OEN, 1);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_RF_AAGC_MIN, 0x0);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MAX, 0xff);
	pDemod->SetRegBitsWithPage(pDemod, QAM_IF_AAGC_MIN, 0x38);
	pDemod->SetRegBitsWithPage(pDemod, QAM_AAGC_MODE_SEL, 1);


	// Set demod QAM mode with 64-QAM.
	pDemod->SetQamMode(pDemod, QAM_QAM_64);


	// Set demod symbol rate with 6.952 MHz.
	pDemod->SetSymbolRateHz(pDemod, 6952000);


	// Set demod alpha mode with alpha = 0.15.
	pDemod->SetAlphaMode(pDemod, QAM_ALPHA_0P15);


	// Set demod IF frequency with 36 MHz.
	pDemod->SetIfFreqHz(pDemod, IF_FREQ_36000000HZ);


	// Set demod spectrum mode wiht spectrum inverse.
	pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE);



	// Initialize tuner.
	pTuner->Initialize(pTuner);


	// Set tuner RF frequency with 858 MHz.
	pTuner->SetRfFreqHz(pTuner, 858000000);



	// Reset demod by software reset.
	pDemod->SoftwareReset(pDemod);


	// Wait maximum 1000 ms for demod converge.
	for(i = 0; i < 25; i++)
	{
		// Wait 40 ms.
		pBaseInterface->WaitMs(pBaseInterface, 40);

		// Check signal lock status through frame lock.
		pDemod->IsFrameLocked(pDemod, &FrameLockStatus);

		if(FrameLockStatus == YES)
		{
			// Signal is locked.
			break;
		}
	}



	return 0;
}


@endcode

*/

















#endif
