|
|
//////////////////////////////////////////////////////////////////////////////
//
// (C) Philips Semiconductors-CSU and Microsoft 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.
//
// TUNER.CPP
//////////////////////////////////////////////////////////////////////////////
#include "philtune.h"
/*
* CTuner() * Input : * Output: TRUE - if initialization data can be written to I2C * FALSE - if there is an I2C error * Description: CTuner Constructor. */ CTuner::CTuner(CI2CScript *p_I2CScript, BoardInfoType *p_BoardInfo, NTSTATUS *pStatus) { m_pI2CScript = p_I2CScript; m_ucTunerAddress = TUNER_I2C_ADDRESS; m_ulInput = 0L; // unknown input or the only one
m_ulCurrentFrequency = 0L; // unknown tuning frequency
m_ulMode = 0; m_ulPrevMode = 0;
m_TunerID = TD1536;
m_ulPreviousFrequency = 0L; //m_FrequencyParam.ulCurrentCFrequency = 0L;
LONG lPLLOffset; BOOL bBusyStatus;
//GetPLLOffsetBusyStatus(&lPLLOffset, &bBusyStatus);
m_uiBoardID = 0;
if(p_BoardInfo != NULL) { NTSTATUS status; status = SetCapabilities(p_BoardInfo); if(pStatus != NULL) *pStatus = status; } }
/*
* ~CTuner() * Input : * Output: * Description: CTuner Destructor. */ CTuner::~CTuner() { }
/*
* SetCapabilities() * Purpose : Sets the capabilities based upon the Tuner Id * * Inputs : UINT tuner : Tuner Id * * Outputs : returns TRUE, if there is a supported Tuner Id specified; * * Author : MM */ NTSTATUS CTuner::SetCapabilities(BoardInfoType *p_BoardInfo) { NTSTATUS nStatus = STATUS_SUCCESS;
m_TunerID = (TunerTypes)(p_BoardInfo->uiTunerID); m_ucTunerAddress = p_BoardInfo->ucTunerAddress; m_uiBoardID = p_BoardInfo->uiBoardID;
// Note:
// If mode is KSPROPERTY_TUNER_MODE_ATSC, then the IF is
// 43.75MHz, else it is 44MHz. But as the frequency
// being passed (ulFrequency) is the Video Signal freq,
// the calculation should take into consideration that the video signal
// is 1.75 MHz from the centre of the band. This 1.75MHz should be
// added to the actual IF hence for ATSC IF = 43.75 + 1.75 = 45.5MHz
// and NTSC IF = 44 + 1.75 = 45.75MHz
// Currently , supporting only TD1536, other tune support can be added later
// as necessary
switch(m_TunerID) { case TD1536: // Digital Tuner
{ // Check to determine if it is a single input or a dual input
// tuner
ULONG inputs = 1; GetNumberOfInputs(&inputs); int i = 0; if(p_BoardInfo->ulSupportedModes & KSPROPERTY_TUNER_MODE_TV) { // Set mode capabilities for TV mode
m_ModeCaps[i].ModeCaps.ulMode = KSPROPERTY_TUNER_MODE_TV; m_ModeCaps[i].ModeCaps.ulNumberOfInputs = inputs; //2;
m_ModeCaps[i].ModeCaps.ulMinFrequency = 55250000L; m_ModeCaps[i].ModeCaps.ulMaxFrequency = 801250000L; m_ModeCaps[i].ModeCaps.ulStrategy = KS_TUNER_STRATEGY_PLL; m_ModeCaps[i].ulIntermediateFrequency = 45750000L; m_ModeCaps[i].ModeCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M; m_ModeCaps[i].ulNumberOfStandards = 1; m_ModeCaps[i].ModeCaps.ulTuningGranularity = 62500L; m_ModeCaps[i].ModeCaps.ulSettlingTime = 150; // 150 ms
i++; } if(p_BoardInfo->ulSupportedModes & KSPROPERTY_TUNER_MODE_ATSC) { // Set mode capabilities for ATSC mode
m_ModeCaps[i].ModeCaps.ulMode = KSPROPERTY_TUNER_MODE_ATSC; m_ModeCaps[i].ModeCaps.ulNumberOfInputs = inputs; //2;
m_ModeCaps[i].ModeCaps.ulMinFrequency = 55250000L; m_ModeCaps[i].ModeCaps.ulMaxFrequency = 801250000L; m_ModeCaps[i].ModeCaps.ulStrategy = KS_TUNER_STRATEGY_DRIVER_TUNES;
if((m_uiBoardID == BOARD_CATALINA) || (m_uiBoardID == BOARD_CORFU)) m_ModeCaps[i].ulIntermediateFrequency = 45750000L; else m_ModeCaps[i].ulIntermediateFrequency = 45500000L;
m_ModeCaps[i].ModeCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M; m_ModeCaps[i].ulNumberOfStandards = 0; m_ModeCaps[i].ModeCaps.ulTuningGranularity = 62500L; m_ModeCaps[i].ModeCaps.ulSettlingTime = 800; // 800ms
i++; }
m_ulSupportedModes = p_BoardInfo->ulSupportedModes; m_ulNumSupportedModes = p_BoardInfo->ulNumSupportedModes; m_ucTunerAddress = TUNER_I2C_ADDRESS; _DbgPrintF( DEBUGLVL_VERBOSE,("CDevice::Supported Modes = %x \n", m_ulSupportedModes)); } break;
default: return STATUS_INVALID_PARAMETER; }
SetMode(KSPROPERTY_TUNER_MODE_ATSC); m_ulVideoStandard = KS_AnalogVideo_NTSC_M;
return nStatus; }
/*
* GetModeCapabilities() * Inputs: TunerModeCapsType *p_TunerModeCaps : pointer to * mode capability structure of the tuner * Outputs: Filled TunerModeCapsType structure * Returns: BOOL: returns TRUE, if the operation succeeds else FALSE * Description: Returns the mode capabilities of tuner for a particluar mode. */ NTSTATUS CTuner::GetModeCapabilities(TunerModeCapsType *p_TunerModeCaps) {
ULONG ulOperationMode = p_TunerModeCaps->ulMode;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetTunerModeCapbilities Mode = %x Mode in obj %x\n", ulOperationMode, m_ulMode ));
// QF:This is a work-around, as the mode passed by the filter the 1st time
// is not correct. Will have to be removed later.
p_TunerModeCaps->ulMode = m_ulMode; ulOperationMode = m_ulMode;
if (!(ulOperationMode & m_ulSupportedModes)) { // TRAP;
return STATUS_INVALID_PARAMETER; }
// There is support for TVTuner at this time only.
// It will be enchanced later on to support FM Tuner as well.
for(ULONG i = 0; i < m_ulNumSupportedModes; i++) { if(ulOperationMode == m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMode) break; } MemoryCopy(&p_TunerModeCaps->ulMode, &m_ModeCaps[m_ulModeCapIndex].ModeCaps, sizeof(TunerModeCapsType));
return STATUS_SUCCESS; }
/*
* SetMode() * Inputs: ULONG ulMode : an operation mode required to be set * Outputs: * Returns: UINT: 0 - if mode is not supported * 1 - if mode is same as previous mode * 2 - if new mode has been set * Description: Set TV mode */ NTSTATUS CTuner::SetMode(ULONG ulMode) { ULONG i;
// Check if mod eis supported
if(ulMode & m_ulSupportedModes) { m_ulPrevMode = m_ulMode; // Change mode only if it is different from the previous mode
if(ulMode != m_ulMode) { // Check if the mode supported is part of the mode capability
// structure array for the tuner. If it is , get the index into the
// array for the given mode and change the mode.
for(i = 0; i < m_ulNumSupportedModes; i++) { if(m_ModeCaps[i].ModeCaps.ulMode == ulMode) { m_ulModeCapIndex = i; break; } } if(i == m_ulNumSupportedModes) { _DbgPrintF( DEBUGLVL_ERROR,("CTuner::SetMode: Couldn't find mode in capability array\n")); return STATUS_INVALID_PARAMETER; } else m_ulMode = ulMode; } return STATUS_SUCCESS; } else { _DbgPrintF( DEBUGLVL_ERROR,("CTuner: Mode not supported : %x %x \n", ulMode, m_ulSupportedModes)); return STATUS_INVALID_PARAMETER; } }
/*
* GetMode() * Inputs: ULONG *p_ulMode : pointer to operation mode that has to be read * Outputs: operation mode * Returns: * Description: Get Mode (TV/ATSC) */ void CTuner::GetMode(ULONG *p_ulMode) { *p_ulMode = m_ulMode ; }
/*
* SetVideoStandard() * Inputs: ULONG ulStandard : a standard required to be set * Outputs: * Returns: NTSTATUS: STATUS_INVALID_PARAMETER - if standard is not supported * STATUS_SUCCESS - if operation succeeded * Description: Set the TV video standard requested. */ NTSTATUS CTuner::SetVideoStandard(ULONG ulStandard) { if(ulStandard & m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulStandardsSupported) { if(ulStandard != m_ulVideoStandard) { m_ulVideoStandard = ulStandard; } return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; }
/*
* GetVideoStandard() * Inputs: ULONG *p_ulStandard : pointer to standard required to be filled * Outputs: standard * Returns: * Description: Get the TV video standard requested. */ void CTuner::GetVideoStandard(ULONG *p_ulStandard) { *p_ulStandard = m_ulVideoStandard; }
/*
* GetPLLOffsetBusyStatus() * Purpose: Returns tuner Busy status and PLLOffset, if the tuner is not busy * The function reads the hardware in order to accomplish the task * The operation might be carried on either synchronously or asynchronously * Inputs : PLONG plPLLOffset : a pointer to write a PLLOffset value * PBOOL pbBusyStatus : a pointer to write a Busy status * * Outputs: BOOL : returns TRUE, if the operation succeded * Author : MM */
NTSTATUS CTuner::GetPLLOffsetBusyStatus(PLONG plPLLOffset, PBOOL pbBusyStatus) { UCHAR ucI2CValue = 0; NTSTATUS nResult = STATUS_SUCCESS;
if( Read(&ucI2CValue, 1, 0) != WDMMINI_NOERROR) nResult = STATUS_ADAPTER_HARDWARE_ERROR; if (nResult == STATUS_SUCCESS) { // bit 6 - PLL locked indicator
*pbBusyStatus = !((BOOL)(ucI2CValue & 0x40)); if (!(* pbBusyStatus)) { ucI2CValue &= 0x07; // only 3 LSBits are PLLOffset
// let's map the result into MS defined values
// from -2 to 2
*plPLLOffset = ucI2CValue - 2; } }
// Read only busy bit for TD1536 as the tuner does not provide
// PLL offset information.
if (m_TunerID == TD1536) { *plPLLOffset = 0; // *pbBusyStatus = 0;
// return TRUE;
}
return nResult; }
/*
* SetFrequency() * Purpose: Sets a new Tuner frequency * Inputs : ULONG ulFrequency : a frequency required to be set * * Outputs: BOOL : returns TRUE, if the operation succeded * Author : MM */ BOOL CTuner::SetFrequency(ULONG ulFrequency) { ASSERT(m_ModeCaps[m_ulModeCapIndex].ulIntermediateFrequency != 0L);
// Change frequency
if (!ChangeFrequency(ulFrequency)) return FALSE;
m_ulCurrentFrequency = ulFrequency;
if (m_ulPreviousFrequency != ulFrequency) { // Mini: Delay for 400ms to let the tuner settle to a tuned state and to let
// the VSB acquire equalizer lock
if (m_ulMode == KSPROPERTY_TUNER_MODE_ATSC) Delay(400000); }
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::SetTunerFrequency(): PrevFreq = %d CurrentFreq = %d\n", m_ulPreviousFrequency,m_ulCurrentFrequency)); m_ulPreviousFrequency = ulFrequency; return TRUE; }
/*
* GetFrequency() * Purpose: Gets the Tuner frequency * Inputs : ULONG *p_ulFrequency : a frequency required * * Outputs: * Author : MM */ void CTuner::GetFrequency(ULONG *p_ulFrequency) { *p_ulFrequency = m_ulCurrentFrequency; }
/*
* ChangeFrequency() * Input : frequency * Output: TRUE if able to to tune to the frequency * FALSE if unable to tune to the frequency * Description: Change the frequency of tuner to that specified */
BOOL CTuner::ChangeFrequency(ULONG ulFrequency) { ULONG ulFrequenceDivider; USHORT usControlCode; UCHAR ucI2CBuffer[6]; I2CPacket i2cPacket; BOOL bResult; ULONG IF = m_ModeCaps[m_ulModeCapIndex].ulIntermediateFrequency; // Set the video carrier frequency by controlling the programmable divider
// N = (16 * (FreqRF + FreqIntermediate)) / 1000000
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner: ulFrequency = %x \n", ulFrequency)); ulFrequenceDivider = ulFrequency + IF; _DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::ChangeFrequency: IF = %d\n", IF));
ulFrequenceDivider /= (1000000 / 16); // divide by 62,500
usControlCode = GetControlCode(ulFrequenceDivider); if(!usControlCode) return(FALSE);
// _DbgPrintF( DEBUGLVL_VERBOSE,("PhilTune: ulFrequencyDivider before %x \n", ulFrequenceDivider));
// _DbgPrintF( DEBUGLVL_VERBOSE,("PhilTune: ulFrequencyDivider after %x \n", ulFrequenceDivider));
ucI2CBuffer[0] = 0xCE; ucI2CBuffer[1] = (UCHAR)usControlCode; ucI2CBuffer[2] = (UCHAR)(ulFrequenceDivider >> 8); ucI2CBuffer[3] = (UCHAR)ulFrequenceDivider; ucI2CBuffer[4] = (UCHAR)(usControlCode >> 8); ucI2CBuffer[5] = (UCHAR)usControlCode;
_DbgPrintF( DEBUGLVL_TERSE,("\n CPhilipsWDMTuner:Tuner Control Code = %x %x %x %x \n", ucI2CBuffer[0], ucI2CBuffer[1], ucI2CBuffer[2], ucI2CBuffer[3]));
/*i2cPacket.uchChipAddress = m_uchTunerI2CAddress;
i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 4; i2cPacket.puchReadBuffer = NULL; i2cPacket.puchWriteBuffer = auchI2CBuffer; i2cPacket.usFlags = 0;
bResult = m_pI2CScript->PerformI2CPacketOperation(&i2cPacket); return bResult; */ if(Write(ucI2CBuffer, sizeof(ucI2CBuffer), 0) == WDMMINI_NOERROR) return TRUE; else return FALSE; }
BOOL CTuner::TweakChannel(LONG lTweak, int iTweakReference) { // Should change the routine later to support tweak reference
// if tweak reference is TUNER_ABSOLUTE_TWEAK, then tweaking is about the centre
// frequency else if tweak reference is TUNER_RELATIVE_TWEAK, then tweaking is about
// the current frequency
LONG lTweakFrq = (lTweak * 62500) + m_ulCurrentFrequency; if (lTweakFrq > 0) if (!ChangeFrequency((ULONG)lTweakFrq)) return FALSE; else return FALSE; m_ulCurrentFrequency = (ULONG)lTweakFrq; return TRUE; }
/*
* GetNumberOfInputs() * Input : pointer to ULONG variable which will be filled with number of inputs * Output: TRUE - if the number of inputs can be determined * FALSE - if there is an I2C error & number of inputs can't be determined * Description: Determine the number of tuner inputs */ BOOL CTuner::GetNumberOfInputs(ULONG *p_ulInputs) { UCHAR ucMode = 0;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetNumberOfInputs: Inside\n")); if(m_uiBoardID == BOARD_CONEY) { if(!m_pI2CScript->ReadSeq(CONEY_I2C_PARALLEL_PORT, &ucMode, 1)) { _DbgPrintF( DEBUGLVL_ERROR,("CTuner::GetNumberOfInputs: Error\n")); return(FALSE); } // If the mode bit 0 = 1,then its a dual input tuner , else its a single input tuner
if ((ucMode & 0x1) == 0) *p_ulInputs = 1; else *p_ulInputs = 2; } else //if(m_uiBoardID == BOARD_CATALINA)
*p_ulInputs = 1; // else
// {
// *p_ulInputs = 1;
// _DbgPrintF( DEBUGLVL_ERROR,("CTuner::GetNumberOfInputs:Invalid Board ID\n"));
// }
m_uiNumInputs = *p_ulInputs; _DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetNumberOfInputs: Number of input pins = %d Mode = %x\n", *p_ulInputs, ucMode)); return(TRUE); }
/*
* GetInput() * Purpose: Gets the current tuner inputs as an active one * Inputs : ULONG nInput : input number required to be set as an active * (begins from 0) * * Outputs: BOOL : returns TRUE, if the operation succeded * Author : MM */ BOOL CTuner::GetInput(ULONG *p_ulInput) { *p_ulInput = m_ulInput; return(TRUE); }
/*
* SetInput() * Purpose: Sets one of the possible Tuner inputs as an active one * Inputs : ULONG nInput : input number required to be set as an active * (begins from 0) * * Returns: UINT: 0 - if tuner input is out of range * 1 - if tuner input is same as previous tuner input * 2 - if new tuner input has been set * Author : MM */ UINT CTuner::SetInput(ULONG ulInput) { if(ulInput < m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulNumberOfInputs) { if(ulInput != m_ulInput) m_ulInput = ulInput; else return 1; return 2; } else return 0; }
/*
* GetControlCode() * Purpose: Determines the Tuner control code to be send to tuner with a new frequency value * * Inputs : ULONG ulFrequencyDivider : new frequency divider * * Outputs: USHORT : value, the tuner should be programmed, when the new frequency is set * id the is no valid uiTunerId is passed as paramter, 0 is returned * Author : MM */ USHORT CTuner::GetControlCode(ULONG ulFrequencyDivider) { USHORT usLowBandFrequencyHigh, usMiddleBandFrequencyHigh; USHORT usLowBandControl, usMiddleBandControl, usHighBandControl; USHORT usControlCode = 0;
usLowBandFrequencyHigh = kUpperLowBand; usMiddleBandFrequencyHigh = kUpperMidBand; usLowBandControl = kLowBand; usMiddleBandControl = kMidBand; usHighBandControl = kHighBand;
switch(m_TunerID) { case TD1536: { if (m_ulMode != KSPROPERTY_TUNER_MODE_ATSC) { usLowBandControl = kLowBand_1536_NTSC_A; usMiddleBandControl = kMidBand_1536_NTSC_A; usHighBandControl = kHighBand_1536_NTSC_A;
if(m_uiBoardID == BOARD_CORONADO) { usLowBandControl &= 0xffbf; usMiddleBandControl &= 0xffbf; usHighBandControl &= 0xffbf; } } else { usLowBandControl = kLowBand_1536_NTSC_D; usMiddleBandControl = kMidBand_1536_NTSC_D; usHighBandControl = kHighBand_1536_NTSC_D;
if(m_uiBoardID == BOARD_CORONADO) { usLowBandControl |= 0x40; usMiddleBandControl |= 0x40; usHighBandControl |= 0x40; }
} // Based on the tuner input modify control word
// Test
ULONG ulInp = m_ulInput; //1
if (ulInp == 1) { usLowBandControl |= 0x1; usMiddleBandControl |= 0x1; usHighBandControl |= 0x1; } else { usLowBandControl &= 0xfffe; usMiddleBandControl &= 0xfffe; usHighBandControl &= 0xfffe; }
_DbgPrintF( DEBUGLVL_VERBOSE,("CPhilipsWDMTuner::GetControlCode(): LBand = %x, MBand = %x, HBand = %x\n", usLowBandControl, usMiddleBandControl, usHighBandControl)); } break;
default : return(usControlCode); }
if(ulFrequencyDivider <= (ULONG)usLowBandFrequencyHigh) usControlCode = usLowBandControl; else { if(ulFrequencyDivider <= (ULONG)usMiddleBandFrequencyHigh) usControlCode = usMiddleBandControl; else usControlCode = usHighBandControl; }
return(usControlCode); }
/*
* Write() * Input:UCHAR *p_ucBuffer - buffer to be written * int uiNumReg - Number of registers to be written * UINT uiStartAddr - start address * Output : UINT - Error code * Description: Write data to chip */
UINT CTuner::Write(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr) { UINT uiResult = WDMMINI_NOERROR;
// The present versions of the chip do not support sub-addressing, hence
// uiStartAddr is not used.
// write to chip
//$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
if(!m_pI2CScript->WriteSeq(m_ucTunerAddress, p_ucBuffer, (USHORT) uiNumReg)) uiResult = WDMMINI_HARDWAREFAILURE;
return uiResult; }
/*
* Read() * Input:UCHAR *p_ucBuffer - buffer to be filled * int uiNumReg - Number of registers to be read * UINT uiStartAddr - start address * Output : UINT - Error code * Description: Read data from chip */
UINT CTuner::Read(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr) { UINT uiResult = WDMMINI_NOERROR;
// The present versions of the chip do not support sub-addressing, hence
// uiStartAddr is not used.
// write to chip
//$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
if(!m_pI2CScript->ReadSeq(m_ucTunerAddress, p_ucBuffer, (USHORT) uiNumReg)) uiResult = WDMMINI_HARDWAREFAILURE;
return uiResult; }
#if 0
/*
* operator new * Purpose: CTuner class overrides operator new. * * Inputs : UINT uiSize : size of the object to be placed * * Outputs: PVOID : pointer of the CTuner class object * Author : MM */ PVOID CTuner::operator new(UINT uiSize) { if (uiSize != sizeof(CTuner)) { _DbgPrintF( DEBUGLVL_ERROR,("CTuner: operator new() fails\n")); return(NULL); }
return (AllocateFixedMemory(uiSize)); }
/*
* operator delete * Purpose: CTuner class overrides operator delete * * Inputs : PVOID p_Buffer : pointer to object being deleted * * Outputs: * Author : MM */ void CTuner::operator delete(PVOID p_Object) { if(p_Object != NULL) FreeFixedMemory(p_Object); _DbgPrintF( DEBUGLVL_VERBOSE,("CTuner: operator delete() succeeds\n"));
}
/*
* SetFrequencyParam() * Purpose: Sets the frequency parameters for the tuner * Inputs : TunerFrequencyType *p_Frequency : a frequency required to be set * * Returns: UINT: 0 - if frequency is out of range or frequency setting fails * 1 - if frequency is same as previous frequency * 2 - if new frequency has been set * Author : MM */ UINT CTuner::SetFrequencyParam(TunerFrequencyType *p_Frequency) { ULONG ulFrequency = p_Frequency->ulCurrentCFrequency; if((ulFrequency < m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMinFrequency) || (ulFrequency > m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMaxFrequency)) return 0;
// If the tuning frequency has changed or the tuner mode has changed ,
// then change the tuner frequency
if((ulFrequency != m_ulCurrentFrequency) || (m_ulPrevMode != m_ulMode)) { // Set the tuner frequency
if(!SetFrequency(ulFrequency)) return 0;
// Update the CTuner's frequency parameters
MemoryCopy(&m_FrequencyParam, p_Frequency, sizeof(TunerFrequencyType)); return 2; } return 1; }
/*
* GetFrequencyParam() * Purpose: Gets the frequency parameters for the tuner * Inputs : TunerFrequencyType *p_Frequency : a frequency required to be filled * Output: * Author : MM */ void CTuner::GetFrequencyParam(TunerFrequencyType *p_Frequency) { MemoryCopy(p_Frequency, &m_FrequencyParam, sizeof(TunerFrequencyType)); return; }
#endif
|