windows-nt/Source/XPSP1/NT/drivers/wdm/bda/samples/mauitune/vsb1.cpp
2020-09-26 16:20:57 +08:00

449 lines
11 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// (C) Philips Semiconductors-CSU 1999
// All rights are reserved. Reproduction in whole or in part is prohibited
// without the written consent of the copyright owner.
//
// Philips reserves the right to make changes without notice at any time.
// Philips makes no warranty, expressed, implied or statutory, including but
// not limited to any implied warranty of merchantibility or fitness for any
// particular purpose, or that the use will not infringe any third party
// patent, copyright or trademark. Philips must not be liable for any loss
// or damage arising from its use.
//
// VSB1.CPP
// Class CVSB1Demod Implementation
//////////////////////////////////////////////////////////////////////////////
#include "philtune.h"
#include "vsb1.h"
//VSB Initialization sequence
UCHAR VsbInitArray[17]=
{
0x00, //0
0x00, //1
0x04, //2
0x00, //3
0x02, //4
0x80, //5
0x00, //6
0xca, //7
0x74, //8
0x00, //9
0x00, //a
0x00, //b
0xfc, //c
0x96, //d
0x66, //e
0x55, //f
0x5f //10
};
/*
* CVSB1Demod()
* Input :
* Output: TRUE - if initialization data can be written to I2C
* FALSE - if there is an I2C error
* Description: CVSB2Demod Constructor.
*/
CVSB1Demod::CVSB1Demod(CI2CScript *p_I2CScript, BoardInfoType *p_BoardInfo, NTSTATUS *p_Status)
:CVSBDemod(p_I2CScript, p_BoardInfo, p_Status)
{
Initialize();
}
/*
* ~CVSB1Demod()
* Input :
* Output:
* Description: CVSB1Demod Destructor.
*/
CVSB1Demod::~CVSB1Demod()
{
}
#if 0
/*
* operator new
* Purpose: CVSB1Demod class overrides operator new.
*
* Inputs : UINT uiSize : size of the object to be placed
*
* Outputs: PVOID : pointer of the CVSB1Demod class object
* Author : MM
*/
PVOID CVSB1Demod::operator new(UINT uiSize)
{
if (uiSize != sizeof(CVSB1Demod))
{
_DbgPrintF( DEBUGLVL_ERROR,("CVSB1Demod: operator new() fails\n"));
return(NULL);
}
return (AllocateFixedMemory(uiSize));
}
/*
* operator delete
* Purpose: CVSB1Demod class overrides operator delete
*
* Inputs : PVOID p_Buffer : pointer to object being deleted
*
* Outputs:
* Author : MM
*/
void CVSB1Demod::operator delete(PVOID p_Object)
{
if(p_Object != NULL)
FreeFixedMemory(p_Object);
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod: operator delete() succeeds\n"));
}
#endif
/*
* Initialize()
* Input :
* Output: TRUE - if initialization data can be written to I2C
* FALSE - if there is an I2C error
* Description: Initialize.
*/
BOOL CVSB1Demod::Initialize()
{
m_uiMaxControlRegisterAddress = VSB1_CONTROL_SIZE - 1;
m_uiMaxStatusRegisterAddress = VSB1_STATUS_SIZE - 1;
return (InitVSB());
}
/*
* InitVSB()
* Input :
* Output: TRUE - if initialization data can be written to I2C
* FALSE - if there is an I2C error
* Description: Initialize the VSB chip with default values.
*/
BOOL CVSB1Demod::InitVSB()
{
MemoryCopy(m_ucControlReg, VsbInitArray, sizeof(VsbInitArray));
// Write I2C sequence to chip
if(Write(VsbInitArray, sizeof VsbInitArray, 0) == WDMMINI_NOERROR)
{
_DbgPrintF( DEBUGLVL_TERSE,("CVSB1Demod: Demodulator Init PASSED !!! ------------ \n"));
return TRUE;
}
else
{
_DbgPrintF( DEBUGLVL_TERSE,("CVSB1Demod: Demodulator Init FAILED !!! ------------ \n"));
return FALSE;
}
}
/*
* GetStatus()
* Input : PVsbStatusType p_Status : pointer to Status structure
* Output: TRUE - if status can be read from I2C
* FALSE - if there is an I2C error
* Description: Get chip status. The status is stored in m_8VSBStatus
*/
BOOL CVSB1Demod::GetStatus(PVsbStatusType p_Status)
{
UCHAR ucStatus[VSB1_STATUS_SIZE];
if(Read(ucStatus, sizeof(ucStatus), 0) != WDMMINI_NOERROR)
return FALSE;
p_Status->bFrontEndLock = (ucStatus[0] & 0x4) >> 2;
p_Status->ucState = ucStatus[0] & 0x3;
p_Status->bEqualizerLock = ((ucStatus[0] & 0x7) == 0x7) ? 1 : 0;
p_Status->uiMse = ((UINT(ucStatus[1]) << 8) & 0xff00) |
(UINT(ucStatus[2]) & 0xff);
p_Status->ucCarrierOffset = UCHAR(ucStatus[3]) & 0xff;
// Not implemented in VSB1
p_Status->uiSegmentErrorRate = 0;
// _DbgPrintF( DEBUGLVL_TERSE,("CVSB1Demod::GetStatus: %x %x %x %x\n", ucStatus[0], ucStatus[1], ucStatus[2], ucStatus[3]));
return TRUE;
}
/*
* EnableCoefficients()
* Input: UCHAR ucEnable
* Output :
* Description: Set the enable coefficients register
*/
BOOL CVSB1Demod::EnableCoefficients(UCHAR ucEnable)
{
// Nothing is done in VSB1 as no register has to be set for reading
// coefficients
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod::EnableCoefficients()\n"));
return TRUE;
}
/*
* DisableCoefficients()
* Input:
* Output :
* Description: Disable coefficient Read/Write
*/
BOOL CVSB1Demod::DisableCoefficients()
{
// Nothing is done in VSB1 as no register has to be set for reading
// coefficients
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod::DisableCoefficients()\n"));
return TRUE;
}
/*
* ResetHangCounter()
* Input:
* Output :
* Description: Reset Hang Counters
*/
void CVSB1Demod::ResetHangCounter()
{
// Initialize parameters
m_uiHangCounter = 0;
m_uiPrevMseValue = 0xffff;
}
/*
* CheckHang()
* Input:
* Output :
* Description: Check VSB chip Hang
*/
BOOL CVSB1Demod::CheckHang()
{
VsbStatusType VSBStatus;
BOOL bReset;
// Read status register and MSE
if(!GetStatus(&VSBStatus))
return TRUE; // Chip is not in HANG, hence returning TRUE
// _DbgPrintF( DEBUGLVL_VERBOSE,("CPhilipsWDMTuner::TimerRoutine(): Prev MSE = %x Curent MSE = %x\n",
// *p_uiMseValue, VSBStatusItem.Mse));
bReset = TRUE;
if (VSBStatus.ucState == 0x1)
{
// Check Hang
if(m_uiPrevMseValue == VSBStatus.uiMse)// Is VSB State = 1 and mse = previous mse
{
bReset = FALSE;
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod::TimerRoutine(): Increment HC \n"));
// Is the hang counter count > 800ms ( hang counter
// = 8 as interrupt occurs every 100 ms)
if(++(m_uiHangCounter) > 8)
{
m_uiHangCounter = 0; // Reset Hang Counter
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod::TimerRoutine(): Chip Hang. Resetting\n"));
SoftwareReset(VSB_GENERAL_RESET);
return TRUE ;
}
}
}
if (bReset == TRUE)
{
// Reset the Hang counter if the the chip is not in
// State 1 as the chip hangs only in State 1
m_uiHangCounter = 0;
// Save current MSE
m_uiPrevMseValue = VSBStatus.uiMse;
// _DbgPrintF( DEBUGLVL_VERBOSE,("CPhilipsWDMTuner::TimerRoutine(): Prev MSE = %x \n",
// m_PrevMseValue));
}
return FALSE;
}
/*
* CoeffIDToAddress()
* Input: UINT uiID - ID
* UINT *p_uiAddress - The address pointer
* Output : TRUE: If ID can be translated
* FALSE: IF ID does not exist
* Description: Translate coefficient ID to address
*/
BOOL CVSB1Demod::CoeffIDToAddress(UINT uiID, UINT *p_uiAddress,
UINT uiRegisterType)
{
_DbgPrintF( DEBUGLVL_VERBOSE,("CVSB1Demod::CoeffIDToAddress()\n"));
switch(uiID)
{
case EQUALIZER_ID:
if(uiRegisterType == WRITE_REGISTERS)
*p_uiAddress = VSB1_CTRL_REG_EQUALIZER_COEFF;
else
*p_uiAddress = VSB1_STATUS_REG_EQUALIZER_COEFF;
break;
default:
*p_uiAddress = 0;
return FALSE;
}
return TRUE;
}
/*
* SetOutputMode()
* Input:
* Output :
* Description: Set The output mode (Normal/Diagnostic/Bypass)
*/
BOOL CVSB1Demod::SetOutputMode(UINT uiOutputMode)
{
RegisterType Control;
UCHAR ucOutput;
UCHAR ucMask;
ucOutput = m_ucControlReg[VSB1_REG_OUTPUT] & VSB1_TS_OUT_MODE_MASK;
if(uiOutputMode == VSB_OUTPUT_MODE_NORMAL)
{}
else if(uiOutputMode == VSB_OUTPUT_MODE_DIAGNOSTIC)
ucOutput |= 0x80;
else if(uiOutputMode == VSB_OUTPUT_MODE_BYPASS)
ucOutput |= 0x40;
else
return FALSE;
Control.uiAddress = VSB1_REG_OUTPUT;
Control.uiLength = 1;
Control.p_ucBuffer = &ucOutput;
// Reset chip
if(SetControlRegister(&Control, 1) != WDMMINI_NOERROR)
return FALSE;
return TRUE;
}
/*
* GetOutputMode()
* Input:
* Output :
* Description: Get The output mode (Normal/Diagnostic/Bypass)
*/
BOOL CVSB1Demod::GetOutputMode(UINT *p_uiOutputMode)
{
RegisterType Control;
UCHAR ucOutput;
UCHAR ucMask;
ucOutput = m_ucControlReg[VSB1_REG_OUTPUT] & (~VSB1_TS_OUT_MODE_MASK);
if(ucOutput == 0)
*p_uiOutputMode = VSB_OUTPUT_MODE_NORMAL;
else if(ucOutput == 0x40)
*p_uiOutputMode = VSB_OUTPUT_MODE_BYPASS;
else
*p_uiOutputMode = VSB_OUTPUT_MODE_DIAGNOSTIC;
return TRUE;
}
/*
* SetDiagMode()
* Input: ULONG ulMode - Diagnostic mode(enumeration VSBDIAGTYPE)
* Output :
* Description: Set The diag mode
*/
BOOL CVSB1Demod::SetDiagMode(VSBDIAGTYPE ulMode)
{
RegisterType Control;
UCHAR ucOutput;
UCHAR ucMask;
ucOutput = m_ucControlReg[VSB1_REG_OUTPUT] & VSB1_DIAG_MODE_MASK;
if((((LONG)ulMode >= EQUALIZER_OUT) && (ulMode <= TRELLIS_DEC_DIAG_OUT)) ||
((ulMode >= TRELLIS_DEC_OUT) && (ulMode <= REED_SOLOMON_DIAG_OUT)))
{
Control.uiAddress = VSB1_REG_OUTPUT;
Control.uiLength = 1;
Control.p_ucBuffer = &ucOutput;
// Send Diag type to chip
if(SetControlRegister(&Control, 1) != WDMMINI_NOERROR)
return FALSE;
return TRUE;
}
else
return FALSE;
}
/*
* GetDiagMode()
* Input: ULONG *p_ulMode - pointer to diagnostic mode
* Output : Diagnostic mode (enumeration VSBDIAGTYPE)
* Description: Get The Diag mode
*/
BOOL CVSB1Demod::GetDiagMode(ULONG *p_ulMode)
{
RegisterType Control;
UCHAR ucOutput;
UCHAR ucMask;
*p_ulMode = (UINT)(m_ucControlReg[VSB1_REG_OUTPUT]) & (~VSB1_DIAG_MODE_MASK);
return TRUE;
}
/*
* GetDiagSpeed()
* Input: ULONG ulType - Diagnostic type
* Output : Diagnostic speed
* Description: Get The Diagnostic data speed
*/
ULONG CVSB1Demod::GetDiagSpeed(ULONG ulType)
{
RegisterType Control;
UCHAR ucOutput;
UCHAR ucMask;
ULONG ulSpeed;
ucOutput = m_ucControlReg[VSB1_REG_OUTPUT] & (~VSB1_TS_OUT_MODE_MASK);
switch(ulType)
{
case EQUALIZER_OUT:
case CR_ERROR:
case TR_ERROR:
case EQUALIZER_IN:
case TRELLIS_DEC_DIAG_OUT:
ulSpeed = TENPOINT76MHZ;
break;
case TRELLIS_DEC_OUT:
case REED_SOLOMON_DIAG_OUT:
ulSpeed = TWOPOINT69MHZ;
break;
default:
ulSpeed = 0;
break;
}
return ulSpeed;
}