Files

4321 lines
167 KiB
C

/*
Copyright (C) 2010 NXP B.V., All Rights Reserved.
This source code and any compilation or derivative thereof is the proprietary
information of NXP B.V. and is confidential in nature. Under no circumstances
is this software to be exposed to or placed under an Open Source License of
any type without the expressed written permission of NXP B.V.
*
* \file tmbslTDA18273.c
*
* %version: CFR_FEAP#39 %
*
* \date %modify_time%
*
* \author David LEGENDRE
* Michael VANNIER
* Christophe CAZETTES
*
* \brief Describe briefly the purpose of this file.
*
* REFERENCE DOCUMENTS :
* TDA18273_Driver_User_Guide.pdf
*
* TVFE SW Arch V4 Template: Author Christophe CAZETTES
*
* \section info Change Information
*
*/
#include "../inc/config.h"
#include <stdio.h>
#if USE_TUNER
/*============================================================================*/
/* Standard include files: */
/*============================================================================*/
#include "tmNxTypes.h"
#include "tmNxCompId.h"
#include "tmFrontEnd.h"
#include "tmbslFrontEndTypes.h"
/*============================================================================*/
/* Project include files: */
/*============================================================================*/
#include "tmbslTDA18273.h"
#include "tmbslTDA18273_RegDef.h"
#include "tmbslTDA18273_Local.h"
#include "tmbslTDA18273_Instance.h"
#include "tmbslTDA18273_InstanceCustom.h"
/*============================================================================*/
/* Static internal functions: */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_SetLLPowerState(pTDA18273Object_t pObj, TDA18273PowerState_t F);
static tmErrorCode_t
iTDA18273_OverrideBandsplit(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_OverrideDigitalClock(pTDA18273Object_t pObj, UInt32 uRF);
static tmErrorCode_t
iTDA18273_OverrideICP(pTDA18273Object_t pObj, UInt32 freq);
static tmErrorCode_t
iTDA18273_OverrideWireless(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_FirstPassPLD_CC(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_LastPassPLD_CC(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_WaitXtalCal_End(pTDA18273Object_t pObj, UInt32 timeOut, UInt32 waitStep);
static tmErrorCode_t
iTDA18273_CalculatePostDivAndPrescaler(UInt32 LO, Bool growingOrder, UInt8* PostDiv, UInt8* Prescaler);
static tmErrorCode_t
iTDA18273_FindPostDivAndPrescalerWithBetterMargin(UInt32 LO, UInt8* PostDiv, UInt8* Prescaler);
static tmErrorCode_t
iTDA18273_CalculateNIntKInt(UInt32 LO, UInt8 PostDiv, UInt8 Prescaler, UInt32* NInt, UInt32* KInt);
static tmErrorCode_t
iTDA18273_SetPLL(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_FirstPassLNAPower(pTDA18273Object_t pObj);
static tmErrorCode_t
iTDA18273_LastPassLNAPower(pTDA18273Object_t pObj);
/*============================================================================*/
/* Static variables: */
/*============================================================================*/
typedef struct _TDA18273_PostDivPrescalerTableDef_
{
UInt32 LO_max;
UInt32 LO_min;
UInt8 Prescaler;
UInt8 PostDiv;
} TDA18273_PostDivPrescalerTableDef;
/* Table that maps LO vs Prescaler & PostDiv values */
static TDA18273_PostDivPrescalerTableDef PostDivPrescalerTable[35] =
{
/* PostDiv 1 */
{974000, 852250, 7, 1},
{852250, 745719, 8, 1},
{757556, 662861, 9, 1},
{681800, 596575, 10, 1},
{619818, 542341, 11, 1},
{568167, 497146, 12, 1},
{524462, 458904, 13, 1},
/* PostDiv 2 */
{487000, 426125, 7, 2},
{426125, 372859, 8, 2},
{378778, 331431, 9, 2},
{340900, 298288, 10, 2},
{309909, 271170, 11, 2},
{284083, 248573, 12, 2},
{262231, 229452, 13, 2},
/* PostDiv 4 */
{243500, 213063, 7, 4},
{213063, 186430, 8, 4},
{189389, 165715, 9, 4},
{170450, 149144, 10, 4},
{154955, 135585, 11, 4},
{142042, 124286, 12, 4},
{131115, 114726, 13, 4},
/* PostDiv 8 */
{121750, 106531, 7, 8},
{106531, 93215, 8, 8},
{94694, 82858, 9, 8},
{85225, 74572, 10, 8},
{77477, 67793, 11, 8},
{71021, 62143, 12, 8},
{65558, 57363, 13, 8},
/* PostDiv 16 */
{60875, 53266, 7, 16},
{53266, 46607, 8, 16},
{47347, 41429, 9, 16},
{42613, 37286, 10, 16},
{38739, 33896, 11, 16},
{35510, 31072, 12, 16},
{32779, 28681, 13, 16}
};
/* Middle of VCO frequency excursion : VCOmin + (VCOmax - VCOmin)/2 in KHz */
#define TDA18273_MIDDLE_FVCO_RANGE ((6818000 - 5965750) / 2 + 5965750)
/*============================================================================*/
/* Exported functions: */
/*============================================================================*/
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_Open: */
/* */
/* DESCRIPTION: Opens driver setup environment. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_Open(
tmUnitSelect_t tUnit, /* I: FrontEnd unit number */
tmbslFrontEndDependency_t* psSrvFunc /* I: setup parameters */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Test parameter(s) */
if(psSrvFunc == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
}
/* Check driver instance state */
if(err == TM_OK || err == TDA18273_ERR_ERR_NO_INSTANCES)
{
if(P_OBJ_VALID && pObj->init == True)
{
err = TDA18273_ERR_ALREADY_SETUP;
}
else
{
if(P_OBJ_VALID == False)
{
/* Try to allocate an instance of the driver */
err = iTDA18273_AllocInstance(tUnit, &pObj);
if(err != TM_OK || pObj == Null)
{
err = TDA18273_ERR_ERR_NO_INSTANCES;
}
}
if(err == TM_OK)
{
/* Initialize the Object by default values */
P_SIO = P_FUNC_SIO(psSrvFunc);
P_STIME = P_FUNC_STIME(psSrvFunc);
P_SDEBUG = P_FUNC_SDEBUG(psSrvFunc);
#ifdef _TVFE_IMPLEMENT_MUTEX
if( P_FUNC_SMUTEX_OPEN_VALID(psSrvFunc)
&& P_FUNC_SMUTEX_CLOSE_VALID(psSrvFunc)
&& P_FUNC_SMUTEX_ACQUIRE_VALID(psSrvFunc)
&& P_FUNC_SMUTEX_RELEASE_VALID(psSrvFunc) )
{
P_SMUTEX = psSrvFunc->sMutex;
err = P_SMUTEX_OPEN(&P_MUTEX);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "Mutex_Open(0x%08X) failed.", tUnit));
}
#endif
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_Open(0x%08X)", tUnit);
if(err == TM_OK)
{
pObj->init = True;
}
}
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_Close: */
/* */
/* DESCRIPTION: Closes driver setup environment. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_Close(
tmUnitSelect_t tUnit /* I: FrontEnd unit number */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
if(err == TM_OK)
{
#ifdef _TVFE_IMPLEMENT_MUTEX
/* Try to acquire driver mutex */
err = iTDA18273_MutexAcquire(pObj, TDA18273_MUTEX_TIMEOUT);
if(err == TM_OK)
{
#endif
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_Close(0x%08X)", tUnit);
#ifdef _TVFE_IMPLEMENT_MUTEX
P_SMUTEX_ACQUIRE = Null;
/* Release driver mutex */
(void)iTDA18273_MutexRelease(pObj);
if(P_SMUTEX_CLOSE_VALID && P_MUTEX_VALID)
{
err = P_SMUTEX_CLOSE(P_MUTEX);
}
P_SMUTEX_OPEN = Null;
P_SMUTEX_CLOSE = Null;
P_SMUTEX_RELEASE = Null;
P_MUTEX = Null;
}
#endif
err = iTDA18273_DeAllocInstance(pObj);
}
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetSWVersion: */
/* */
/* DESCRIPTION: Gets the versions of the driver. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetSWVersion(
ptmSWVersion_t pSWVersion /* I: Receives SW Version */
)
{
pSWVersion->compatibilityNr = TDA18273_COMP_NUM;
pSWVersion->majorVersionNr = TDA18273_MAJOR_VER;
pSWVersion->minorVersionNr = TDA18273_MINOR_VER;
return TM_OK;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetSWSettingsVersion: */
/* */
/* DESCRIPTION: Returns the version of the driver settings. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetSWSettingsVersion(
ptmSWSettingsVersion_t pSWSettingsVersion /* O: Receives SW Settings Version */
)
{
pSWSettingsVersion->customerNr = TDA18273_SETTINGS_CUSTOMER_NUM;
pSWSettingsVersion->projectNr = TDA18273_SETTINGS_PROJECT_NUM;
pSWSettingsVersion->majorVersionNr = TDA18273_SETTINGS_MAJOR_VER;
pSWSettingsVersion->minorVersionNr = TDA18273_SETTINGS_MINOR_VER;
return TM_OK;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_CheckHWVersion: */
/* */
/* DESCRIPTION: Checks TDA18273 HW Version. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_CheckHWVersion(
tmUnitSelect_t tUnit /* I: Unit number */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt16 uIdentity = 0;
UInt8 ID_byte_1 = 0;
UInt8 ID_byte_2 = 0;
UInt8 majorRevision = 0;
UInt8 minorRevision = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_CheckHWVersion(0x%08X)", tUnit);
err = iTDA18273_ReadRegMap(pObj, gTDA18273_Reg_ID_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_ID_byte_1__Ident_1, gTDA18273_Reg_ID_byte_3));
if(pObj->RegMap[0]==0x47 && pObj->RegMap[1]==0x61 && pObj->RegMap[2]==0x11){
printf("\n>> rd Match, d0=0x%x(need-0x47) d1=0x%x(need-0x61) d2=0x%x(need-0x11)\n\n", pObj->RegMap[0],pObj->RegMap[1],pObj->RegMap[2]);
}
else{
printf("\n>> rd Error, d0=0x%x(need-0x47) d1=0x%x(need-0x61) d2=0x%x(need-0x11)\n\n", pObj->RegMap[0],pObj->RegMap[1],pObj->RegMap[2]);
}
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_ReadRegMap(0x%08X) failed.", tUnit));
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_ID_byte_1__Ident_1, &ID_byte_1, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
}
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_ID_byte_2__Ident_2, &ID_byte_2, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
}
if(err == TM_OK)
{
/* Construct Identity */
uIdentity = (ID_byte_1 << 8) | ID_byte_2;
if(uIdentity == 18273)
{
/* TDA18273 found. Check Major & Minor Revision*/
err = iTDA18273_Read(pObj, &gTDA18273_Reg_ID_byte_3__Major_rev, &majorRevision, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
err = iTDA18273_Read(pObj, &gTDA18273_Reg_ID_byte_3__Minor_rev, &minorRevision, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
switch (majorRevision)
{
case 1:
{
switch (minorRevision)
{
case 1:
/* ES2 is supported */
err = TM_OK;
break;
default:
/* Only TDA18273 ES2 are supported */
err = TDA18273_ERR_BAD_VERSION;
break;
}
}
break;
default:
/* Only TDA18273 ES2 are supported */
err = TDA18273_ERR_BAD_VERSION;
break;
}
}
else
{
err = TDA18273_ERR_BAD_VERSION;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetPowerState */
/* */
/* DESCRIPTION: Sets the power state. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetPowerState(
tmUnitSelect_t tUnit, /* I: Unit number */
tmPowerState_t powerState /* I: Power state */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetPowerState(0x%08X)", tUnit);
if(powerState>=tmPowerMax)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
if(pObj->mapLLPowerState[powerState] != pObj->curLLPowerState)
{
err = iTDA18273_SetLLPowerState(pObj, pObj->mapLLPowerState[powerState]);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetLLPowerState(0x%08X, %d) failed.", tUnit, (int)pObj->mapLLPowerState[powerState]));
if(err == TM_OK)
{
/* Store power state in driver instance */
pObj->curPowerState = powerState;
}
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetPowerState: */
/* */
/* DESCRIPTION: Gets the power state. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetPowerState(
tmUnitSelect_t tUnit, /* I: Unit number */
tmPowerState_t* pPowerState /* O: Power state */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetPowerState(0x%08X)", tUnit);
/* Test parameter(s) */
if(pPowerState == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pPowerState = pObj->curPowerState;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetLLPowerState */
/* */
/* DESCRIPTION: Sets the power state. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetLLPowerState(
tmUnitSelect_t tUnit, /* I: Unit number */
TDA18273PowerState_t powerState /* I: Power state of TDA18273 */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetLLPowerState(0x%08X)", tUnit);
pObj->curPowerState = tmPowerMax;
err = iTDA18273_SetLLPowerState(pObj, powerState);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetLLPowerState(0x%08X, %d) failed.", tUnit, (int)powerState));
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetLLPowerState */
/* */
/* DESCRIPTION: Gets the power state. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetLLPowerState(
tmUnitSelect_t tUnit, /* I: Unit number */
TDA18273PowerState_t* pPowerState /* O: Power state of TDA18273 */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetLLPowerState(0x%08X)", tUnit);
/* Test parameter(s) */
if(pPowerState == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_state_byte_2, &uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
}
if(err == TM_OK)
{
if(!(uValue&(TDA18273_SM|TDA18273_SM_XT)))
{
*pPowerState = TDA18273_PowerNormalMode;
}
else if( (uValue&TDA18273_SM) && !(uValue&TDA18273_SM_XT) )
{
*pPowerState = TDA18273_PowerStandbyWithXtalOn;
}
else if( (uValue&TDA18273_SM) && (uValue&TDA18273_SM_XT) )
{
*pPowerState = TDA18273_PowerStandby;
}
else
{
err = TDA18273_ERR_NOT_SUPPORTED;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetStandardMode */
/* */
/* DESCRIPTION: Sets the standard mode. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetStandardMode(
tmUnitSelect_t tUnit, /* I: Unit number */
TDA18273StandardMode_t StandardMode /* I: Standard mode of this device */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
//pTDA18273StdCoefficients prevPStandard = Null;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetStandardMode(0x%08X)", tUnit);
/* Check if Hw is ready to operate */
err = iTDA18273_CheckHwState(pObj, TDA18273_HwStateCaller_SetStd);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckHwState(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Store standard mode */
pObj->StandardMode = StandardMode;
/* Reset standard map pointer */
// prevPStandard = pObj->pStandard;
pObj->pStandard = Null;
if(pObj->StandardMode>TDA18273_StandardMode_Unknown && pObj->StandardMode<TDA18273_StandardMode_Max)
{
/* Update standard map pointer */
pObj->pStandard = &pObj->Std_Array[pObj->StandardMode - 1];
/****************************************************************/
/* IF SELECTIVITY Settings */
/****************************************************************/
/* Set LPF */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Byte_1__LP_Fc, pObj->pStandard->LPF, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set LPF Offset */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Byte_1__LP_FC_Offset, pObj->pStandard->LPF_Offset, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set DC_Notch_IF_PPF */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IR_Mixer_byte_2__IF_Notch, pObj->pStandard->DC_Notch_IF_PPF, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Enable/disable HPF */
if(pObj->pStandard->IF_HPF == TDA18273_IF_HPF_Disabled )
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IR_Mixer_byte_2__Hi_Pass, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
else
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IR_Mixer_byte_2__Hi_Pass, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set IF HPF */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Byte_1__IF_HP_Fc, (UInt8)(pObj->pStandard->IF_HPF - 1), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
}
if(err == TM_OK)
{
/* Set IF Notch */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Byte_1__IF_ATSC_Notch, pObj->pStandard->IF_Notch, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set IF notch to RSSI */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_AGC_byte__IFnotchToRSSI, pObj->pStandard->IFnotchToRSSI, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/****************************************************************/
/* AGC TOP Settings */
/****************************************************************/
if(err == TM_OK)
{
/* Set AGC1 TOP I2C DN/UP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_1__AGC1_TOP, pObj->pStandard->AGC1_TOP_I2C_DN_UP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC1 Adapt TOP DN/UP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode_Val, pObj->pStandard->AGC1_Adapt_TOP_DN_UP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC1 mode */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode, pObj->pStandard->AGC1_Mode, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set Range_LNA_Adapt */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Adapt_Top_byte__Range_LNA_Adapt, pObj->pStandard->Range_LNA_Adapt, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set LNA_Adapt_RFAGC_Gv_Threshold */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Adapt_Top_byte__Index_K_LNA_Adapt, pObj->pStandard->LNA_Adapt_RFAGC_Gv_Threshold, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC1_Top_Adapt_RFAGC_Gv_Threshold */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Adapt_Top_byte__Index_K_Top_Adapt, pObj->pStandard->AGC1_Top_Adapt_RFAGC_Gv_Threshold, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC2 TOP DN/UP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC2_byte_1__AGC2_TOP, pObj->pStandard->AGC2_TOP_DN_UP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC3 RF AGC Top */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Top, pObj->pStandard->AGC3_TOP_I2C, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC3 Adapt TOP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Adapt_TOP, pObj->pStandard->AGC3_Adapt_TOP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC4 TOP DN/UP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IR_Mixer_byte_1__IR_Mixer_Top, pObj->pStandard->AGC4_TOP_DN_UP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC5 TOP DN/UP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC5_byte_1__AGC5_TOP, pObj->pStandard->AGC5_TOP_DN_UP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC3_Top_Adapt_Algorithm */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_AGC_byte__PD_AGC_Adapt3x, pObj->pStandard->AGC3_Top_Adapt_Algorithm, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC Overload TOP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Vsync_Mgt_byte__AGC_Ovld_TOP, pObj->pStandard->AGC_Overload_TOP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set Adapt TOP 34 Gain Threshold */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__TH_AGC_Adapt34, pObj->pStandard->TH_AGC_Adapt34, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set RF atten 3dB */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__RF_Atten_3dB, pObj->pStandard->RF_Atten_3dB, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set IF Output Level */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_AGC_byte__IF_level, pObj->pStandard->IF_Output_Level, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set S2D gain */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IR_Mixer_byte_1__S2D_Gain, pObj->pStandard->S2D_Gain, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set Negative modulation */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Vsync_byte__Neg_modulation, pObj->pStandard->Negative_Modulation, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/****************************************************************/
/* GSK Settings */
/****************************************************************/
if(err == TM_OK)
{
/* Set AGCK Step */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGCK_byte_1__AGCK_Step, pObj->pStandard->AGCK_Steps, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGCK Time Constant */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGCK_byte_1__AGCK_Mode, pObj->pStandard->AGCK_Time_Constant, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set AGC5 HPF */
UInt8 wantedValue = pObj->pStandard->AGC5_HPF;
if(pObj->pStandard->AGC5_HPF == TDA18273_AGC5_HPF_Enabled)
{
UInt8 checked = 0;
/* Check if Internal Vsync is selected */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Vsync_byte__Vsync_int, &checked, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK && checked == 0)
{
/* Internal Vsync is OFF, so override setting to OFF */
wantedValue = TDA18273_AGC5_HPF_Disabled;
}
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC5_byte_1__AGC5_Ana, wantedValue, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK)
{
/* Set Pulse Shaper Disable */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGCK_byte_1__Pulse_Shaper_Disable, pObj->pStandard->Pulse_Shaper_Disable, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/****************************************************************/
/* H3H5 Settings */
/****************************************************************/
if(err == TM_OK)
{
/* Set VHF_III_Mode */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__VHF_III_mode, pObj->pStandard->VHF_III_Mode, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/****************************************************************/
/* PLL Settings */
/****************************************************************/
if(err == TM_OK)
{
/* Set LO_CP_Current */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_CP_Current_byte__LO_CP_Current, pObj->pStandard->LO_CP_Current, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/****************************************************************/
/* IF Settings */
/****************************************************************/
if(err == TM_OK)
{
/* Set IF */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, (UInt8)((pObj->pStandard->IF - pObj->pStandard->CF_Offset)/50000), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
/* Update IF in pObj */
pObj->uIF = pObj->pStandard->IF;
}
if(err == TM_OK)
{
/* Write AGC1_byte_1 (0x0C) to IF_Byte_1 (0x15) Registers */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_AGC1_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_AGC1_byte_1, gTDA18273_Reg_IF_Byte_1));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write IF_Frequency_byte (0x17) Register */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_IF_Frequency_byte.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write Adapt_Top_byte (0x1F) Register */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_Adapt_Top_byte.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write Vsync_byte (0x20) to IR_Mixer_byte_2 (0x22) Registers */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_Vsync_byte.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_Vsync_byte, gTDA18273_Reg_IR_Mixer_byte_2));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write RFAGCs_Gain_byte_1 (0x24) Register */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_RFAGCs_Gain_byte_1.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write CP_Current_byte (0x2F) Register */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_CP_Current_byte.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
}
/* Update driver state machine */
pObj->eHwState = TDA18273_HwState_SetStdDone;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetStandardMode */
/* */
/* DESCRIPTION: Gets the standard mode. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetStandardMode(
tmUnitSelect_t tUnit, /* I: Unit number */
TDA18273StandardMode_t *pStandardMode /* O: Standard mode of this device */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetStandardMode(0x%08X)", tUnit);
if(pStandardMode == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Get standard mode */
*pStandardMode = pObj->StandardMode;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetRF: */
/* */
/* DESCRIPTION: Tunes to a RF. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetRF(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32 uRF /* I: RF frequency in hertz */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetRF(0x%08X)", tUnit);
/* Test parameter(s) */
if( pObj->StandardMode<=TDA18273_StandardMode_Unknown
|| pObj->StandardMode>=TDA18273_StandardMode_Max
|| pObj->pStandard == Null)
{
err = TDA18273_ERR_STD_NOT_SET;
}
if(err == TM_OK)
{
/* Check if Hw is ready to operate */
err = iTDA18273_CheckHwState(pObj, TDA18273_HwStateCaller_SetRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckHwState(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
pObj->uRF = uRF;
pObj->uProgRF = pObj->uRF + pObj->pStandard->CF_Offset;
err = iTDA18273_SetRF(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetRF(0x%08X) failed.", tUnit));
if(err == TM_OK)
{
/* Update driver state machine */
pObj->eHwState = TDA18273_HwState_SetRFDone;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetRF: */
/* */
/* DESCRIPTION: Gets tuned RF. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetRF(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32* puRF /* O: RF frequency in hertz */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetRF(0x%08X)", tUnit);
if(puRF == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Get RF */
*puRF = pObj->uRF;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_HwInit: */
/* */
/* DESCRIPTION: Initializes TDA18273 Hardware. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_HwInit(
tmUnitSelect_t tUnit /* I: Unit number */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValuePOR;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_HwInit(0x%08X)", tUnit);
/* Reset standard mode & Hw State */
pObj->StandardMode = TDA18273_StandardMode_Max;
pObj->eHwState = TDA18273_HwState_InitNotDone;
/* Read POR bit to see if it is the first init after POR */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_state_byte_1__POR, &uValuePOR, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
//printf("1 err.%s %d %d\n",__FUNCTION__,__LINE__,err);
/* Check for XtalCal End only when bufferMode is not used */
if (pObj->bBufferMode == False)
{
err = iTDA18273_WaitXtalCal_End(pObj, 100, 10);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitXtalCal_End(0x%08X) failed.", pObj->tUnitW));
}
//printf("2 err.%s %d %d\n",__FUNCTION__,__LINE__,err);
if(err == TM_OK)
{
/* Read all bytes */
err = iTDA18273_ReadRegMap(pObj, 0x00, TDA18273_REG_MAP_NB_BYTES);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_ReadRegMap(0x%08X) failed.", tUnit));
}
if(err == TM_OK)
{
/* Check if Calc_PLL algorithm is in automatic mode */
err = iTDA18273_CheckCalcPLL(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckCalcPLL(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/****************************************************/
/* Change POR values */
/****************************************************/
////weeee
/* Up_Step_Ovld: POR = 1 -> 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Vsync_Mgt_byte__Up_Step_Ovld, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* PLD_CC_Enable: POR = 1 -> 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset0 : 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog0, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* RFCAL_Offset1 : 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog1, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset2 : 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog2, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset3 : 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog3, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset4 : 3 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog4, 0x03, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset5 : 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog5, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset6 : 3 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog6, 0x03, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset7 : 3 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog7, 0x03, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* RFCAL_Offset8 : 1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog8, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write RF_Cal_byte_1 (0x27) to RF_Cal_byte_3 (0x29) Registers */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_RF_Cal_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_RF_Cal_byte_1, gTDA18273_Reg_RF_Cal_byte_3));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK)
{
/* PLD_Temp_Enable: POR = 1 -> 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_Temp_Enable, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Power Down Vsync Management: POR = 0 -> 1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Vsync_Mgt_byte__PD_Vsync_Mgt, 0x01, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK)
{
/* Set IRQ_clear */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set power state on */
err = iTDA18273_SetLLPowerState(pObj, TDA18273_PowerNormalMode);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetLLPowerState(0x%08X, PowerNormalMode) failed.", tUnit));
}
if(err == TM_OK)
{
pObj->curPowerState = tmPowerOn;
/* Launch tuner calibration */
/****************************************/
/* PLD spread fix */
/****************************************/
/* Perform this workaround only for the 2nd init and onwards */
if (uValuePOR == 0)
{
/* Set digital clock mode to 16 Mhz before resetting the IC to avoid unclocking the digital part*/
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x00, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if (pObj->bBufferMode == False)
{
/* Reset XTALCAL_End bit */
if(err == TM_OK)
{
/* Set IRQ_clear */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_XtalCal|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
/* Perform a SW reset to reset the digital calibrations */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_3, 0x03, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_3, 0x00, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if (pObj->bBufferMode == False)
{
/* Launch XTALCAL */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_MSM_byte_2__XtalCal_Launch, 0x01, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_MSM_byte_2__XtalCal_Launch, 0x00, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* Wait XTALCAL_End bit */
if(err == TM_OK)
{
err = iTDA18273_WaitXtalCal_End(pObj, 100, 10);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitXtalCal_End(0x%08X) failed.", pObj->tUnitW));
}
}
/* Set digital clock mode to sub-LO */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x03, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
/****************************************/
/* End of PLD spread fix */
/****************************************/
/* Set state machine (all CALs except IRCAL) and Launch it */
if(err == TM_OK)
{
err = iTDA18273_SetMSM(pObj, TDA18273_MSM_HwInit, True);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetMSM(0x%08X, TDA18273_MSM_HwInit) failed.", pObj->tUnitW));
}
/* Inform that init phase has started */
if(err == TM_OK)
{
pObj->eHwState = TDA18273_HwState_InitPending;
}
if(err == TM_OK && pObj->bIRQWaitHwInit)
{
/* State reached after 500 ms max */
err = iTDA18273_WaitIRQ(pObj, 500, 10, TDA18273_IRQ_HwInit);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitIRQ(0x%08X) failed.", tUnit));
}
/****************************************/
/* PLD spread fix */
/****************************************/
if(err == TM_OK)
{
/* Set IRQ_clear */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* Launch IRCALs after all other CALs are finished */
if(err == TM_OK)
{
err = iTDA18273_SetMSM(pObj, TDA18273_MSM_IrCal, True);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetMSM(0x%08X, TDA18273_MSM_IrCal) failed.", pObj->tUnitW));
}
if(err == TM_OK && pObj->bIRQWaitHwInit)
{
/* State reached after 500 ms max, 10 ms step due to CAL ~ 30ms */
err = iTDA18273_WaitIRQ(pObj, 500, 10, TDA18273_IRQ_IrCal);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitIRQ(0x%08X) failed.", tUnit));
}
/****************************************/
/* End of PLD spread fix */
/****************************************/
if(err == TM_OK && pObj->eHwState == TDA18273_HwState_InitPending)
{
pObj->eHwState = TDA18273_HwState_InitDone;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetIF: */
/* */
/* DESCRIPTION: Gets programmed IF. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetIF(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32* puIF /* O: IF Frequency in hertz */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetIF(0x%08X)", tUnit);
/* Test parameter(s) */
if( pObj->StandardMode<=TDA18273_StandardMode_Unknown
|| pObj->StandardMode>=TDA18273_StandardMode_Max
|| pObj->pStandard == Null
|| puIF == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*puIF = pObj->uIF - pObj->pStandard->CF_Offset;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetIF: */
/* */
/* DESCRIPTION: Sets programmed IF. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetIF(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32 uIF /* I: IF Frequency in hertz */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetIF(0x%08X)", tUnit);
/* Test parameter(s) */
if( pObj->StandardMode<=TDA18273_StandardMode_Unknown
|| pObj->StandardMode>=TDA18273_StandardMode_Max
|| pObj->pStandard == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Update IF in pObj structure */
pObj->uIF = uIF + pObj->pStandard->CF_Offset;
/* Update IF in TDA18273 registers */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, (UInt8)(uIF/50000), Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetCF_Offset: */
/* */
/* DESCRIPTION: Gets CF Offset. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetCF_Offset(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32* puOffset /* O: Center frequency offset in hertz */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetCF_Offset(0x%08X)", tUnit);
/* Test parameter(s) */
if( pObj->StandardMode<=TDA18273_StandardMode_Unknown
|| pObj->StandardMode>=TDA18273_StandardMode_Max
|| pObj->pStandard == Null
|| puOffset == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*puOffset = pObj->pStandard->CF_Offset;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetLockStatus: */
/* */
/* DESCRIPTION: Gets PLL Lock Status. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetLockStatus(
tmUnitSelect_t tUnit, /* I: Unit number */
tmbslFrontEndState_t* pLockStatus /* O: PLL Lock status */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0, uValueLO = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetLockStatus(0x%08X)", tUnit);
if( pLockStatus == Null )
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_state_byte_1__LO_Lock, &uValueLO, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status__IRQ_status, &uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
uValue = uValue & uValueLO;
*pLockStatus = (uValue)? tmbslFrontEndStateLocked : tmbslFrontEndStateNotLocked;
}
else
{
*pLockStatus = tmbslFrontEndStateUnknown;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetPowerLevel: */
/* */
/* DESCRIPTION: Gets HW Power Level. 1/2 steps dB */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t tmbslTDA18273_GetPowerLevel(tmUnitSelect_t tUnit,UInt8*pPowerLevel )
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetPowerLevel(0x%08X)", tUnit);
/* Test parameter(s) */
if( pPowerLevel == Null ||
pObj->StandardMode<=TDA18273_StandardMode_Unknown ||
pObj->StandardMode>=TDA18273_StandardMode_Max ||
pObj->pStandard == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pPowerLevel = 0;
/* Implement PLD CC algorithm to increase PLD read immunity to interferer */
/*
-PLD CC ON.
-Wait 40ms.
-PLD read standard.
-PLD CC OFF.
*/
/* Do the algorithm only if asked and not in analog mode */
if( (pObj->PLD_CC_algorithm == True) && isTDA18273_ANLG_STD(pObj->StandardMode) == False )
{
/* PLD_CC_Enable: 1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x01, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", tUnit));
if(err == TM_OK)
{
/* Wait 40 ms */
err = iTDA18273_Wait(pObj, 40);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", tUnit));
}
}
if(err == TM_OK)
{
/* Read Power Level */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Input_Power_Level_byte__Power_Level, pPowerLevel, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
}
if( (err == TM_OK) && (pObj->uProgRF <= 145408000))
{
/* RF <= 145.408 MHz, then apply minus 3 dB */
/* 1 step = 0.5 dB */
if (*pPowerLevel >= 6)
*pPowerLevel -= 6;
else
*pPowerLevel = 0;
}
/* Finish the algorithm only if asked and not in analog mode */
if( (pObj->PLD_CC_algorithm == True) && isTDA18273_ANLG_STD(pObj->StandardMode) == False )
{
/* PLD_CC_Enable: 0 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", tUnit));
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetInternalVsync: */
/* */
/* DESCRIPTION: Enables or disable the internal VSYNC */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetInternalVsync(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool bEnabled /* I: Enable of disable the internal VSYNC */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA182I4_SetInternalVsync(0x%08X)", tUnit);
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Vsync_byte__Vsync_int, ((bEnabled == True) ? 1 : 0), Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", tUnit));
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetInternalVsync: */
/* */
/* DESCRIPTION: Get the current status of the internal VSYNC */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetInternalVsync(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool* pbEnabled /* O: current status of the internal VSYNC */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValue;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA182I4_SetInternalVsync(0x%08X)", tUnit);
if(pbEnabled == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Vsync_byte__Vsync_int, &uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", tUnit));
}
if(err == TM_OK)
{
if (uValue == 1)
{
*pbEnabled = True;
}
else
{
*pbEnabled = False;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetPllManual: */
/* */
/* DESCRIPTION: Sets bOverridePLL flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetPllManual(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool bOverridePLL /* I: Determine if we need to put PLL in manual mode in SetRF */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetPllManual(0x%08X)", tUnit);
pObj->bOverridePLL = bOverridePLL;
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetIRQWait: */
/* */
/* DESCRIPTION: Sets IRQWait flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetIRQWait(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool bWait /* I: Determine if we need to wait IRQ in driver functions */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetIRQWait(0x%08X)", tUnit);
pObj->bIRQWait = bWait;
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetPllManual: */
/* */
/* DESCRIPTION: Gets bOverridePLL flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetPllManual(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool* pbOverridePLL /* O: Determine if we need to put PLL in manual mode in SetRF */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetPllManual(0x%08X)", tUnit);
if(pbOverridePLL == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pbOverridePLL = pObj->bOverridePLL;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetIRQWait: */
/* */
/* DESCRIPTION: Gets IRQWait flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetIRQWait(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetIRQWait(0x%08X)", tUnit);
if(pbWait == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pbWait = pObj->bIRQWait;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetIRQWaitHwInit: */
/* */
/* DESCRIPTION: Sets IRQWait flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetIRQWaitHwInit(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool bWait /* I: Determine if we need to wait IRQ in driver functions */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetIRQWaitHwInit(0x%08X)", tUnit);
pObj->bIRQWaitHwInit = bWait;
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetIRQWaitHwInit: */
/* */
/* DESCRIPTION: Gets IRQWait flag. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetIRQWaitHwInit(
tmUnitSelect_t tUnit, /* I: Unit number */
Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetIRQWaitHwInit(0x%08X)", tUnit);
if(pbWait == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pbWait = pObj->bIRQWaitHwInit;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetIRQ: */
/* */
/* DESCRIPTION: Gets IRQ status. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetIRQ(
tmUnitSelect_t tUnit /* I: Unit number */,
Bool* pbIRQ /* O: IRQ triggered */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetIRQ(0x%08X)", tUnit);
if(pbIRQ == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pbIRQ = 0;
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status__IRQ_status, &uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
*pbIRQ = uValue;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_WaitIRQ: */
/* */
/* DESCRIPTION: Waits for the IRQ to raise. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_WaitIRQ(
tmUnitSelect_t tUnit, /* I: Unit number */
UInt32 timeOut, /* I: timeOut for IRQ wait */
UInt32 waitStep, /* I: wait step */
UInt8 irqStatus /* I: IRQs to wait */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_WaitIRQ(0x%08X)", tUnit);
err = iTDA18273_WaitIRQ(pObj, timeOut, waitStep, irqStatus);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitIRQ(0x%08X) failed.", tUnit));
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_GetXtalCal_End: */
/* */
/* DESCRIPTION: Gets XtalCal_End status. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_GetXtalCal_End(
tmUnitSelect_t tUnit /* I: Unit number */,
Bool* pbXtalCal_End /* O: XtalCal_End triggered */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_GetXtalCal_End(0x%08X)", tUnit);
if(pbXtalCal_End == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
*pbXtalCal_End = 0;
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status__MSM_XtalCal_End, &uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
*pbXtalCal_End = uValue;
}
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_SetFineRF: */
/* */
/* DESCRIPTION: Fine tunes RF with given step. */
/* (tmbslTDA18273_SetRF must be called before calling this API) */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_SetFineRF(
tmUnitSelect_t tUnit, /* I: Unit number */
Int8 step /* I: step (-1, +1) */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* LO wanted = RF wanted + IF in KHz */
UInt32 LO = 0;
/* PostDiv */
UInt8 PostDiv = 0;
UInt8 LOPostDiv = 0;
/* Prescaler */
UInt8 Prescaler = 0;
/* Algorithm that calculates N, K */
UInt32 N_int = 0;
UInt32 K_int = 0;
UInt8 i = 0;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_SetFineRF(0x%08X)", tUnit);
/* Test parameter(s) */
if( pObj->StandardMode<=TDA18273_StandardMode_Unknown
|| pObj->StandardMode>=TDA18273_StandardMode_Max
|| pObj->pStandard == Null)
{
err = TDA18273_ERR_STD_NOT_SET;
}
if(err == TM_OK)
{
/* Check if Hw is ready to operate */
err = iTDA18273_CheckHwState(pObj, TDA18273_HwStateCaller_SetFineRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckHwState(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write the offset into 4 equal steps of 15.625 KHz = 62.5 KHz*/
for (i=0; i < 4; i++)
{
/* Calculate wanted LO = RF + IF */
pObj->uRF += step*15625;
pObj->uProgRF += step*15625;
LO = (pObj->uRF + pObj->uIF)/1000;
/* Don't touch on Prescaler and PostDiv programmed during setRF */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv, &LOPostDiv, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPresc, &Prescaler, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if (err == TM_OK)
{
/* Decode PostDiv */
switch(LOPostDiv)
{
case 1:
PostDiv = 1;
break;
case 2:
PostDiv = 2;
break;
case 3:
PostDiv = 4;
break;
case 4:
PostDiv = 8;
break;
case 5:
PostDiv = 16;
break;
default:
err = TDA18273_ERR_BAD_PARAMETER;
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmbslTDA18273_SetFineRF(0x%08X) LO_PostDiv value is wrong.", tUnit));
break;
}
/* Calculate N & K values of the PLL */
err = iTDA18273_CalculateNIntKInt(LO, PostDiv, Prescaler, &N_int, &K_int);
/* Affect registers */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_4__LO_Frac_0, (UInt8)(K_int & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_3__LO_Frac_1, (UInt8)((K_int >> 8) & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_2__LO_Frac_2, (UInt8)((K_int >> 16) & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_1__LO_Int, (UInt8)(N_int & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Force manual selection mode : 0x3 at @0x56 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Force manual selection mode : 0x3 at @0x56 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
/* Set the new PLL values */
if(err == TM_OK)
{
/* Write bytes Sigma_delta_byte_1 (0x52) to Sigma_delta_byte_5 (0x56) */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_Sigma_delta_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_Sigma_delta_byte_1, gTDA18273_Reg_Sigma_delta_byte_5));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
}
/* Update driver state machine */
pObj->eHwState = TDA18273_HwState_SetFineRFDone;
}
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_Write */
/* */
/* DESCRIPTION: Writes in TDA18273 hardware */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_Write(
tmUnitSelect_t tUnit, /* I: Unit number */
const TDA18273_BitField_t* pBitField, /* I: Bitfield structure */
UInt8 uData, /* I: Data to write */
eBusAccess_t eBusAccess /* I: Access to bus */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_Write(0x%08X)", tUnit);
err = iTDA18273_Write(pObj, pBitField, uData, eBusAccess);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* FUNCTION: tmbslTDA18273_Read */
/* */
/* DESCRIPTION: Reads in TDA18273 hardware */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
tmbslTDA18273_Read(
tmUnitSelect_t tUnit, /* I: Unit number */
const TDA18273_BitField_t* pBitField, /* I: Bitfield structure */
UInt8* puData, /* I: Data to read */
eBusAccess_t eBusAccess /* I: Access to bus */
)
{
pTDA18273Object_t pObj = Null;
tmErrorCode_t err = TM_OK;
/* Get a driver instance */
err = iTDA18273_GetInstance(tUnit, &pObj);
_MUTEX_ACQUIRE(TDA18273)
tmDBGPRINTEx(DEBUGLVL_INOUT, "tmbslTDA18273_Read(0x%08X)", tUnit);
err = iTDA18273_Read(pObj, pBitField, puData, eBusAccess);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
_MUTEX_RELEASE(TDA18273)
return err;
}
/*============================================================================*/
/* Internal functions: */
/*============================================================================*/
/*============================================================================*/
/* FUNCTION: iTDA18273_CheckHwState */
/* */
/* DESCRIPTION: Checks if Hw is ready to operate. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_CheckHwState(
pTDA18273Object_t pObj, /* I: Driver object */
TDA18273HwStateCaller_t caller /* I: Caller API */
)
{
tmErrorCode_t err = TM_OK;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_CheckHwState(0x%08X)", pObj->tUnitW);
switch(pObj->eHwState)
{
case TDA18273_HwState_InitNotDone:
switch(caller)
{
case TDA18273_HwStateCaller_SetPower:
break;
default:
err = TDA18273_ERR_NOT_INITIALIZED;
break;
}
break;
case TDA18273_HwState_InitDone:
switch(caller)
{
case TDA18273_HwStateCaller_SetRF:
case TDA18273_HwStateCaller_SetFineRF:
/* SetStandardMode API must be called before calling SetRF and SetFineRF */
err = TDA18273_ERR_STD_NOT_SET;
break;
default:
break;
}
break;
case TDA18273_HwState_SetStdDone:
switch(caller)
{
case TDA18273_HwStateCaller_SetFineRF:
/* SetRF API must be called before calling SetFineRF */
err = TDA18273_ERR_RF_NOT_SET;
break;
default:
break;
}
break;
case TDA18273_HwState_SetRFDone:
case TDA18273_HwState_SetFineRFDone:
break;
case TDA18273_HwState_InitPending:
/* Hw Init pending. Check if IRQ triggered. No wait. */
err = iTDA18273_WaitIRQ(pObj, 1, 1, TDA18273_IRQ_HwInit);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitIRQ(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Init Done. Call iTDA18273_CheckHwState to check after Hw Initialization. */
err = iTDA18273_CheckHwState(pObj, caller);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckHwState(0x%08X) failed.", pObj->tUnitW));
break;
}
default:
err = TDA18273_ERR_NOT_READY;
break;
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_CheckCalcPLL */
/* */
/* DESCRIPTION: Checks if CalcPLL Algo is enabled. Enable it if not. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_CheckCalcPLL(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_CheckCalcPLL(0x%08X)", pObj->tUnitW);
/* Check if Calc_PLL algorithm is in automatic mode */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, &uValue, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK && uValue != 0x00)
{
/* Enable Calc_PLL algorithm by putting PLL in automatic mode */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_SetLLPowerState */
/* */
/* DESCRIPTION: Sets the power state. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_SetLLPowerState(
pTDA18273Object_t pObj, /* I: Driver object */
TDA18273PowerState_t powerState /* I: Power state of TDA18273 */
)
{
tmErrorCode_t err = TM_OK;
UInt8 uValue = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_SetLLPowerState(0x%08X)", pObj->tUnitW);
if(err == TM_OK)
{
/* Check if Hw is ready to operate */
err = iTDA18273_CheckHwState(pObj, TDA18273_HwStateCaller_SetPower);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckHwState(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
switch(powerState)
{
case TDA18273_PowerNormalMode:
/* If we come from any standby mode, then power on the IC with LNA off */
/* Then powering on LNA with the minimal gain on AGC1 to avoid glitches at RF input will */
/* be done during SetRF */
if(pObj->curLLPowerState != TDA18273_PowerNormalMode)
{
/* Workaround to limit the spurs occurence on RF input, do it before entering normal mode */
/* PD LNA */
err = iTDA18273_FirstPassLNAPower(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_FirstPassLNAPower(0x%08X) failed.", pObj->tUnitW));
}
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_state_byte_2, TDA18273_SM_NONE, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set digital clock mode to sub-LO if normal mode is entered */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x03, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* Reset uValue to use it as a flag for below test */
uValue = 0;
break;
case TDA18273_PowerStandbyWithXtalOn:
uValue = TDA18273_SM;
break;
case TDA18273_PowerStandby:
default:
/* power state not supported */
uValue = TDA18273_SM|TDA18273_SM_XT;
break;
}
if(err == TM_OK && uValue!=0)
{
/* Set digital clock mode to 16 Mhz before entering standby */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x00, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_state_byte_2, uValue, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK)
{
/* Store low-level power state in driver instance */
pObj->curLLPowerState = powerState;
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_SetRF: */
/* */
/* DESCRIPTION: Tunes to a RF. */
/* */
/* RETURN: TM_OK */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_SetRF(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_SetRF(0x%08X)", pObj->tUnitW);
if(pObj->curPowerState != tmPowerOn)
{
/* Set power state ON */
err = iTDA18273_SetLLPowerState(pObj, TDA18273_PowerNormalMode);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetLLPowerState(0x%08X, PowerNormalMode) failed.", pObj->tUnitW));
}
/* Workaround to limit the spurs occurence on RF input */
/* Check if LNA is powered down, if yes, power it up */
if(err == TM_OK)
{
pObj->curPowerState = tmPowerOn;
err = iTDA18273_LastPassLNAPower(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_LastPassLNAPower(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Check if Calc_PLL algorithm is in automatic mode */
err = iTDA18273_CheckCalcPLL(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_CheckCalcPLL(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Setting Bandsplit parameters */
err = iTDA18273_OverrideBandsplit(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_OverrideBandsplit(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Implement PLD read immunity against interferers: first pass before channel change */
err = iTDA18273_FirstPassPLD_CC(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_FirstPassPLD_CC(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set RF frequency */
err = iTDA18273_SetRF_Freq(pObj, pObj->uProgRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetRF_Freq(0x%08X) failed.", pObj->tUnitW));
}
/* Implement PLD read immunity against interferers: last pass after channel change */
if(err == TM_OK)
{
err = iTDA18273_LastPassPLD_CC(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_LastPassPLD_CC(0x%08X) failed.", pObj->tUnitW));
}
/* Bypass ROM settings for wireless filters */
if(err == TM_OK)
{
err = iTDA18273_OverrideWireless(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_OverrideWireless(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_SetRF_Freq */
/* */
/* DESCRIPTION: Sets Tuner Frequency registers. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_SetRF_Freq(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 uRF /* I: Wanted frequency */
)
{
tmErrorCode_t err = TM_OK;
UInt32 uRFLocal = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_SetRF_Freq(0x%08X)", pObj->tUnitW);
/* Set IRQ_clear */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_SetRF, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
/* Set RF */
uRFLocal = (uRF + 500) / 1000;
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Frequency_byte_1__RF_Freq_1, (UInt8)((uRFLocal & 0x00FF0000) >> 16), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Frequency_byte_2__RF_Freq_2, (UInt8)((uRFLocal & 0x0000FF00) >> 8), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RF_Frequency_byte_3__RF_Freq_3, (UInt8)(uRFLocal & 0x000000FF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_RF_Frequency_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_RF_Frequency_byte_1, gTDA18273_Reg_RF_Frequency_byte_3));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set state machine and Launch it */
err = iTDA18273_SetMSM(pObj, TDA18273_MSM_SetRF, True);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetMSM(0x%08X, TDA18273_MSM_SetRF) failed.", pObj->tUnitW));
}
if(err == TM_OK && pObj->bIRQWait)
{
/* Wait for IRQ to trigger */
err = iTDA18273_WaitIRQ(pObj, 50, 5, TDA18273_IRQ_SetRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WaitIRQ(0x%08X, 50, 5, TDA18273_IRQ_SetRF) failed.", pObj->tUnitW));
}
if(err == TM_OK && pObj->bOverridePLL)
{
/* Override the calculated PLL to get the best margin in case fine tuning is used */
/* which means set the PLL in manual mode that provides the best occurence of LO tuning (+-2 MHz) */
/* without touching PostDiv and Prescaler */
err = iTDA18273_SetPLL(pObj);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetPLL failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Override ICP */
err = iTDA18273_OverrideICP(pObj, pObj->uProgRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_OverrideICP(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Override Digital Clock */
err = iTDA18273_OverrideDigitalClock(pObj, pObj->uProgRF);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_OverrideDigitalClock(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_OverrideDigitalClock */
/* */
/* DESCRIPTION: Overrides Digital clock. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_OverrideDigitalClock(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 uRF /* I: Wanted RF */
)
{
tmErrorCode_t err = TM_OK;
UInt8 uDigClock = 0;
UInt8 uPrevDigClock = 0;
UInt8 uProgIF = 0;
/* LO < 55 MHz then Digital Clock set to 16 MHz else subLO */
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_OverrideDigitalClock(0x%08X)", pObj->tUnitW);
/* Read Current IF */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, &uProgIF, Bus_NoWrite);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
/* Read Current Digital Clock */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, &uPrevDigClock, Bus_NoWrite);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
/* LO = RF + IF */
if ((uRF + (uProgIF*50000)) < 55000000)
{
uDigClock = 0; /* '00' = 16 MHz */
}
else
{
uDigClock = 3; /* '11' = subLO */
}
if(err == TM_OK && (uPrevDigClock != uDigClock) )
{
/* Set Digital Clock bits */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, uDigClock, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_OverrideICP */
/* */
/* DESCRIPTION: Overrides ICP. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_OverrideICP(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 uRF /* I: Wanted frequency */
)
{
tmErrorCode_t err = TM_OK;
UInt32 uIF = 0;
UInt8 ProgIF = 0;
UInt8 LOPostdiv = 0;
UInt8 LOPrescaler = 0;
UInt32 FVCO = 0;
UInt8 uICPBypass = 0;
UInt8 ICP = 0;
UInt8 uPrevICP = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_OverrideICP(0x%08X)", pObj->tUnitW);
/*
if fvco<6352 MHz ==> icp = 150 (register = 01b)
if fvco<6592 MHz ==> icp = 300 (register = 10b)
500 elsewhere (register 00b)
Reminder : fvco = postdiv*presc*(RFfreq+IFfreq)
*/
/* Read PostDiv et Prescaler */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Main_Post_Divider_byte, &LOPostdiv, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* PostDiv */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv, &LOPostdiv, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Prescaler */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPresc, &LOPrescaler, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* IF */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, &ProgIF, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Decode IF */
uIF = ProgIF*50000;
/* Decode PostDiv */
switch(LOPostdiv)
{
case 1:
LOPostdiv = 1;
break;
case 2:
LOPostdiv = 2;
break;
case 3:
LOPostdiv = 4;
break;
case 4:
LOPostdiv = 8;
break;
case 5:
LOPostdiv = 16;
break;
default:
err = TDA18273_ERR_BAD_PARAMETER;
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_OverrideICP(0x%08X) LOPostDiv value is wrong.", pObj->tUnitW));
break;
}
}
if(err == TM_OK)
{
/* Calculate FVCO in MHz*/
FVCO = LOPostdiv * LOPrescaler * ((uRF + uIF) / 1000000);
/* Set correct ICP */
if(FVCO < 6352)
{
/* Set ICP to 01 (= 150)*/
ICP = 0x01;
}
else if(FVCO < 6592)
{
/* Set ICP to 10 (= 300)*/
ICP = 0x02;
}
else
{
/* Set ICP to 00 (= 500)*/
ICP = 0x00;
}
/* Get ICP_bypass bit */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Charge_pump_byte__ICP_Bypass, &uICPBypass, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Get ICP */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Charge_pump_byte__ICP, &uPrevICP, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK && (uICPBypass == False || uPrevICP != ICP) )
{
/* Set ICP_bypass bit */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Charge_pump_byte__ICP_Bypass, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set ICP */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Charge_pump_byte__ICP, ICP, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Write Charge_pump_byte register */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_Charge_pump_byte.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
}
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_OverrideBandsplit */
/* */
/* DESCRIPTION: Overrides Bandsplit settings. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_OverrideBandsplit(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
UInt8 Bandsplit = 0;
UInt8 uPrevPSM_Bandsplit_Filter = 0;
UInt8 PSM_Bandsplit_Filter = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_OverrideBandsplit(0x%08X)", pObj->tUnitW);
/* Setting PSM bandsplit at -3.9 mA for some RF frequencies */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Bandsplit_Filter_byte__Bandsplit_Filter_SubBand, &Bandsplit, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_PowerSavingMode__PSM_Bandsplit_Filter, &uPrevPSM_Bandsplit_Filter, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
switch(Bandsplit)
{
default:
case 0:
/* LPF0 133MHz - LPF1 206MHz - HPF0 422MHz */
if(pObj->uProgRF < 133000000)
{
/* Set PSM bandsplit at -3.9 mA */
PSM_Bandsplit_Filter = 0x03;
}
else
{
/* Set PSM bandsplit at nominal */
PSM_Bandsplit_Filter = 0x02;
}
break;
case 1:
/* LPF0 139MHz - LPF1 218MHz - HPF0 446MHz */
if(pObj->uProgRF < 139000000)
{
/* Set PSM bandsplit at -3.9 mA */
PSM_Bandsplit_Filter = 0x03;
}
else
{
/* Set PSM bandsplit at nominal */
PSM_Bandsplit_Filter = 0x02;
}
break;
case 2:
/* LPF0 145MHz - LPF1 230MHz - HPF0 470MHz */
if(pObj->uProgRF < 145000000)
{
/* Set PSM bandsplit at -3.9 mA */
PSM_Bandsplit_Filter = 0x03;
}
else
{
/* Set PSM bandsplit at nominal */
PSM_Bandsplit_Filter = 0x02;
}
break;
case 3:
/* LPF0 151MHz - LPF1 242MHz - HPF0 494MHz */
if(pObj->uProgRF < 151000000)
{
/* Set PSM bandsplit at -3.9 mA */
PSM_Bandsplit_Filter = 0x03;
}
else
{
/* Set PSM bandsplit at nominal */
PSM_Bandsplit_Filter = 0x02;
}
break;
}
if(uPrevPSM_Bandsplit_Filter != PSM_Bandsplit_Filter)
{
/* Write PSM bandsplit */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_PowerSavingMode__PSM_Bandsplit_Filter, PSM_Bandsplit_Filter, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_OverrideWireless */
/* */
/* DESCRIPTION: Overrides Wireless settings. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_OverrideWireless(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
UInt8 uPrevW_Filter_byte = 0;
UInt8 uW_Filter_byte = 0;
UInt8 W_Filter = 0;
UInt8 W_Filter_Bypass = 0;
UInt8 W_Filter_Offset = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_OverrideWireless(0x%08X)", pObj->tUnitW);
/* Bypass ROM for wireless filters */
/* WF7 = 1.7GHz - 1.98GHz */
/* WF8 = 1.98GHz - 2.1GHz */
/* WF9 = 2.1GHz - 2.4GHz */
/* For all frequencies requiring WF7 and WF8, add -8% shift */
/* For all frequencies requiring WF9, change to WF8 and add +4% shift */
/* Check for filter WF9 */
if(
((pObj->uProgRF > 474000000) && (pObj->uProgRF < 536000000)) ||
((pObj->uProgRF > 794000000) && (pObj->uProgRF < 866000000))
)
{
/* ROM is selecting WF9 */
/* Bypass to WF8 */
W_Filter_Bypass = 0x01;
W_Filter = 0x01;
/* Apply +4% shift */
W_Filter_Offset = 0x00;
}
else
{
/* Let ROM do the job */
W_Filter_Bypass = 0x00;
W_Filter = 0x00;
/* Check for filter WF7 & WF8 */
if(
((pObj->uProgRF > 336000000) && (pObj->uProgRF < 431000000)) ||
((pObj->uProgRF > 563500000) && (pObj->uProgRF < 721000000))
)
{
/* ROM is selecting WF7 or WF8 */
/* Apply -8% shift */
W_Filter_Offset = 0x03;
}
else
{
/* Nominal */
W_Filter_Offset = 0x01;
}
}
/* Read current W_Filter_byte */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_W_Filter_byte, &uPrevW_Filter_byte, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set Wireless Filter Bypass */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__W_Filter_Bypass, W_Filter_Bypass, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Set Wireless Filter */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__W_Filter, W_Filter, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set Wireless Filter Offset */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__W_Filter_Offset, W_Filter_Offset, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Set Wireless filters ON */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_W_Filter_byte__W_Filter_Enable, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Read above-modified W_Filter_byte */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_W_Filter_byte, &uW_Filter_byte, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK && uPrevW_Filter_byte != uW_Filter_byte)
{
/* W_Filter_byte changed: Update it */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_W_Filter_byte.Address, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_FirstPassPLD_CC */
/* */
/* DESCRIPTION: Implements the first pass of the PLD_CC algorithm. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_FirstPassPLD_CC(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_FirstPassPLD_CC(0x%08X)", pObj->tUnitW);
/* Implement PLD CC algorithm to increase PLD read immunity to interferer */
/*
- set AGCK mode to 8ms.
- PLD CC ON.
- Set RF
- Loop of Read of AGC Lock:
- if((AGClock green) or TIMEOUT(200ms)) then next Step Else (Wait 1ms and next Read)
- Wait 20ms.
- PLD CC OFF.
- Wait 1ms.
- set AGCK mode back to initial mode
*/
/* Do the algorithm only if asked and not in analog mode */
if( (pObj->PLD_CC_algorithm == True) && isTDA18273_DGTL_STD(pObj->StandardMode) )
{
/* Set AGCK Time Constant */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGCK_byte_1__AGCK_Mode, TDA18273_AGCK_Time_Constant_8_192ms, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* PLD_CC_Enable: 1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x01, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_LastPassPLD_CC */
/* */
/* DESCRIPTION: Implements the last pass of the PLD_CC algorithm. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_LastPassPLD_CC(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
UInt8 counter = 200; /* maximum 200 loops so max wait time = 200ms */
UInt8 agcs_lock = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_LastPassPLD_CC(0x%08X)", pObj->tUnitW);
/* Finish the algorithm only if asked and not in analog mode */
if( (pObj->PLD_CC_algorithm == True) && isTDA18273_DGTL_STD(pObj->StandardMode) )
{
/* Get initial AGCs_Lock */
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_state_byte_1__AGCs_Lock, &agcs_lock, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
/* Perform the loop to detect AGCs_Lock = 1 or error or timeout */
while((err == TM_OK) && ((--counter)>0) && (agcs_lock == 0))
{
/* Wait 1 ms */
err = iTDA18273_Wait(pObj, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", pObj->tUnit));
if(err == TM_OK)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_state_byte_1__AGCs_Lock, &agcs_lock, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
}
}
/* Wait 20 ms */
if(err == TM_OK)
{
err = iTDA18273_Wait(pObj, 20);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", pObj->tUnit));
}
/* PLD_CC_Enable: 0 */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x00, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* Wait 1 ms */
if(err == TM_OK)
{
err = iTDA18273_Wait(pObj, 1);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", pObj->tUnit));
}
/* Set AGCK Time Constant */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGCK_byte_1__AGCK_Mode, pObj->pStandard->AGCK_Time_Constant, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_FirstPassLNAPower */
/* */
/* DESCRIPTION: Power down the LNA */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_FirstPassLNAPower(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
/* PD LNA */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, 0x1, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* PD Detector AGC1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_2__PD_Det1, 0x1, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* AGC1 Detector loop off */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off, 0x1, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_LastPassLNAPower */
/* */
/* DESCRIPTION: Power up the LNA */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_LastPassLNAPower(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
UInt8 uValue;
/* Check if LNA is PD */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, &uValue, Bus_NoWrite);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if ((uValue == 1) && (err == TM_OK))
{
/* LNA is Powered Down, so power it up */
/* Force gain to -10dB */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_3__AGC1_Gain, 0x0, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
/* Force LNA gain control */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_3__Force_AGC1_gain, 0x1, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* PD LNA */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, 0x0, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
/* Release LNA gain control */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_3__Force_AGC1_gain, 0x0, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* PD Detector AGC1 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Power_Down_byte_2__PD_Det1, 0x0, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* AGC1 Detector loop off */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off, 0x0, Bus_NoRead);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_SetPLL */
/* */
/* DESCRIPTION: Set the PLL in manual mode */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_SetPLL(
pTDA18273Object_t pObj /* I: Driver object */
)
{
tmErrorCode_t err = TM_OK;
/* LO wanted = RF wanted + IF in KHz */
UInt32 LO = 0;
/* Algorithm that calculates PostDiv */
UInt8 PostDiv = 0; /* absolute value */
UInt8 LOPostDiv = 0; /* register value */
/* Algorithm that calculates Prescaler */
UInt8 Prescaler = 0;
/* Algorithm that calculates N, K */
UInt32 N_int = 0;
UInt32 K_int = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_SetPLL(0x%08X)", pObj->tUnitW);
/* Calculate wanted LO = RF + IF in Hz */
LO = (pObj->uRF + pObj->uIF) / 1000;
/* Calculate the best PostDiv and Prescaler : the ones that provide the best margin */
/* in case of fine tuning +-2 MHz */
err = iTDA18273_FindPostDivAndPrescalerWithBetterMargin(LO, &PostDiv, &Prescaler);
if (err == TM_OK)
{
/* Program the PLL only if valid values are found, in that case err == TM_OK */
/* Decode PostDiv */
switch(PostDiv)
{
case 1:
LOPostDiv = 1;
break;
case 2:
LOPostDiv = 2;
break;
case 4:
LOPostDiv = 3;
break;
case 8:
LOPostDiv = 4;
break;
case 16:
LOPostDiv = 5;
break;
default:
err = TDA18273_ERR_BAD_PARAMETER;
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_SetPLL(0x%08X) *PostDiv value is wrong.", pObj->tUnitW));
break;
}
/* Affect register map without writing into IC */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv, LOPostDiv, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Main_Post_Divider_byte__LOPresc, Prescaler, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Calculate N & K values of the PLL */
err = iTDA18273_CalculateNIntKInt(LO, PostDiv, Prescaler, &N_int, &K_int);
/* Affect registers map without writing to IC */
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_4__LO_Frac_0, (UInt8)(K_int & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_3__LO_Frac_1, (UInt8)((K_int >> 8) & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_2__LO_Frac_2, (UInt8)((K_int >> 16) & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_1__LO_Int, (UInt8)(N_int & 0xFF), Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
/* Force manual selection mode : 0x3 at @0x56 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK)
{
/* Force manual selection mode : 0x3 at @0x56 */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK)
{
/* Write bytes Main_Post_Divider_byte (0x51) to Sigma_delta_byte_5 (0x56) */
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_Main_Post_Divider_byte.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_Main_Post_Divider_byte, gTDA18273_Reg_Sigma_delta_byte_5));
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_CalculatePostDivAndPrescaler */
/* */
/* DESCRIPTION: Calculate PostDiv and Prescaler by starting from lowest value */
/* of LO or not */
/* LO must be passed in Hz */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_FindPostDivAndPrescalerWithBetterMargin(
UInt32 LO, /* In Hz */
UInt8* PostDiv, /* Directly the value to set in the register */
UInt8* Prescaler /* Directly the value to set in the register */
)
{
/* Initialize to error in case no valuable values are found */
tmErrorCode_t err = TM_OK;
UInt8 PostDivGrowing;
UInt8 PrescalerGrowing;
UInt8 PostDivDecreasing;
UInt8 PrescalerDecreasing;
UInt32 FCVOGrowing = 0;
UInt32 DistanceFCVOGrowing = 0;
UInt32 FVCODecreasing = 0;
UInt32 DistanceFVCODecreasing = 0;
/* Get the 2 possible values for PostDiv & Prescaler to find the one
which provides the better margin on LO */
err = iTDA18273_CalculatePostDivAndPrescaler(LO, True, &PostDivGrowing, &PrescalerGrowing);
if (err == TM_OK)
{
/* Calculate corresponding FVCO value in kHz */
FCVOGrowing = LO * PrescalerGrowing * PostDivGrowing;
}
err = iTDA18273_CalculatePostDivAndPrescaler(LO, False, &PostDivDecreasing, &PrescalerDecreasing);
if (err == TM_OK)
{
/* Calculate corresponding FVCO value in kHz */
FVCODecreasing = LO * PrescalerDecreasing * PostDivDecreasing;
}
/* Now take the values that are providing the better margin, the goal is +-2 MHz on LO */
/* So take the point that is the nearest of (FVCOmax - FVCOmin)/2 = 6391,875 MHz */
if (FCVOGrowing != 0)
{
if (FCVOGrowing >= TDA18273_MIDDLE_FVCO_RANGE)
{
DistanceFCVOGrowing = FCVOGrowing - TDA18273_MIDDLE_FVCO_RANGE;
}
else
{
DistanceFCVOGrowing = TDA18273_MIDDLE_FVCO_RANGE - FCVOGrowing;
}
}
if (FVCODecreasing != 0)
{
if (FVCODecreasing >= TDA18273_MIDDLE_FVCO_RANGE)
{
DistanceFVCODecreasing = FVCODecreasing - TDA18273_MIDDLE_FVCO_RANGE;
}
else
{
DistanceFVCODecreasing = TDA18273_MIDDLE_FVCO_RANGE - FVCODecreasing;
}
}
if (FCVOGrowing == 0)
{
if (FVCODecreasing == 0)
{
/* No value at all are found */
err = TDA18273_ERR_BAD_PARAMETER;
}
else
{
/* No value in growing mode, so take the decreasing ones */
*PostDiv = PostDivDecreasing;
*Prescaler = PrescalerDecreasing;
}
}
else
{
if (FVCODecreasing == 0)
{
/* No value in decreasing mode, so take the growing ones */
*PostDiv = PostDivGrowing;
*Prescaler = PrescalerGrowing;
}
else
{
/* Find the value which are the nearest of the middle of VCO range */
if (DistanceFCVOGrowing <= DistanceFVCODecreasing)
{
*PostDiv = PostDivGrowing;
*Prescaler = PrescalerGrowing;
}
else
{
*PostDiv = PostDivDecreasing;
*Prescaler = PrescalerDecreasing;
}
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_CalculateNIntKInt */
/* */
/* DESCRIPTION: Calculate PLL N & K values */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_CalculateNIntKInt(
UInt32 LO,
UInt8 PostDiv,
UInt8 Prescaler,
UInt32* NInt,
UInt32* KInt
)
{
tmErrorCode_t err = TM_OK;
/* Algorithm that calculates N_K */
UInt32 FVCO = 0;
UInt32 N_K_prog = 0;
/* Algorithm that calculates N, K corrected */
UInt32 Nprime = 0;
UInt32 KforceK0_1 = 0;
UInt32 K2msb = 0;
UInt32 N0 = 0;
UInt32 Nm1 = 0;
/* Calculate N_K_Prog */
FVCO = LO * Prescaler * PostDiv;
N_K_prog = (FVCO * 128) / 125;
/* Calculate N & K corrected values */
Nprime = N_K_prog & 0xFF0000;
/* Force LSB to 1 */
KforceK0_1 = 2*(((N_K_prog - Nprime) << 7) / 2) + 1;
/* Check MSB bit around 2 */
K2msb = KforceK0_1 >> 21;
if (K2msb < 1)
{
N0 = 1;
}
else
{
if (K2msb >= 3)
{
N0 = 1;
}
else
{
N0 = 0;
}
}
if (K2msb < 1)
{
Nm1 = 1;
}
else
{
Nm1 = 0;
}
/* Calculate N */
*NInt = (2 * ((Nprime >> 16) - Nm1) + N0) - 128;
/* Calculate K */
if (K2msb < 1)
{
*KInt = KforceK0_1 + (2 << 21);
}
else
{
if (K2msb >= 3)
{
*KInt = KforceK0_1 - (2 << 21);
}
else
{
*KInt = KforceK0_1;
}
}
/* Force last 7 bits of K_int to 0x5D, as the IC is doing for spurs optimization */
*KInt &= 0xFFFFFF80;
*KInt |= 0x5D;
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_CalculatePostDivAndPrescaler */
/* */
/* DESCRIPTION: Calculate PostDiv and Prescaler by starting from lowest value */
/* of LO or not */
/* LO must be passed in Hz */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_CalculatePostDivAndPrescaler(
UInt32 LO, /* In Hz */
Bool growingOrder, /* Start from LO = 28.681 kHz or LO = 974 kHz */
UInt8* PostDiv, /* Absolute value */
UInt8* Prescaler /* Absolute value */
)
{
tmErrorCode_t err = TM_OK;
Int8 index;
Int8 sizeTable = sizeof(PostDivPrescalerTable) / sizeof(TDA18273_PostDivPrescalerTableDef);
if (growingOrder == True)
{
/* Start from LO = 28.681 kHz */
for (index = (sizeTable - 1); index >= 0; index--)
{
if (
(LO > PostDivPrescalerTable[index].LO_min) &&
(LO < PostDivPrescalerTable[index].LO_max)
)
{
/* We are at correct index in the table */
break;
}
}
}
else
{
/* Start from LO = 974000 kHz */
for (index = 0; index < sizeTable; index++)
{
if (
(LO > PostDivPrescalerTable[index].LO_min) &&
(LO < PostDivPrescalerTable[index].LO_max)
)
{
/* We are at correct index in the table */
break;
}
}
}
if ((index == -1) || (index == sizeTable))
{
err = TDA18273_ERR_BAD_PARAMETER;
}
else
{
/* Write Prescaler */
*Prescaler = PostDivPrescalerTable[index].Prescaler;
/* Decode PostDiv */
*PostDiv = PostDivPrescalerTable[index].PostDiv;
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_WaitXtalCal_End */
/* */
/* DESCRIPTION: Wait the XtalCal_End to trigger */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
static tmErrorCode_t
iTDA18273_WaitXtalCal_End(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 timeOut, /* I: timeout */
UInt32 waitStep /* I: wait step */
)
{
tmErrorCode_t err = TM_OK;
UInt32 counter = timeOut/waitStep; /* Wait max timeOut/waitStep ms */
UInt8 uMSM_XtalCal_End = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_WaitXtalCal_End(0x%08X)", pObj->tUnitW);
while(counter > 0)
{
/* Don't check for I2C error because it can occur, just after POR, that I2C is not yet available */
/* MSM_XtalCal_End must occur between POR and POR+70ms */
/* Check for XtalCal End */
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status__MSM_XtalCal_End, &uMSM_XtalCal_End, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(uMSM_XtalCal_End)
{
/* MSM_XtalCal_End is triggered => exit */
break;
}
if(counter)
{
/* Decrease the counter */
counter--;
/* Wait for a step */
err = iTDA18273_Wait(pObj, waitStep);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", pObj->tUnitW));
}
}
if(counter == 0)
{
err = TDA18273_ERR_NOT_READY;
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_SetMSM */
/* */
/* DESCRIPTION: Set the MSM bit(s). */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_SetMSM(
pTDA18273Object_t pObj, /* I: Driver object */
UInt8 uValue, /* I: Item value */
Bool bLaunch /* I: Launch MSM */
)
{
tmErrorCode_t err = TM_OK;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_SetMSM(0x%08X)", pObj->tUnitW);
/* Set state machine and Launch it */
err = iTDA18273_Write(pObj, &gTDA18273_Reg_MSM_byte_1, uValue, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK && bLaunch)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_MSM_byte_2__MSM_Launch, 0x01, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK)
{
err = iTDA18273_WriteRegMap(pObj, gTDA18273_Reg_MSM_byte_1.Address, bLaunch?0x02:0x01);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_WriteRegMap(0x%08X) failed.", pObj->tUnitW));
}
if(err == TM_OK && bLaunch)
{
err = iTDA18273_Write(pObj, &gTDA18273_Reg_MSM_byte_2__MSM_Launch, 0x00, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Write(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_WaitIRQ */
/* */
/* DESCRIPTION: Wait the IRQ to trigger */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_WaitIRQ(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 timeOut, /* I: timeout */
UInt32 waitStep, /* I: wait step */
UInt8 irqStatus /* I: IRQs to wait */
)
{
tmErrorCode_t err = TM_OK;
UInt32 counter = timeOut/waitStep; /* Wait max timeOut/waitStep ms */
UInt8 uIRQ = 0;
UInt8 uIRQStatus = 0;
Bool bIRQTriggered = False;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_WaitIRQ(0x%08X)", pObj->tUnitW);
while(err == TM_OK && (counter--)>0)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status__IRQ_status, &uIRQ, Bus_RW);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(err == TM_OK && uIRQ == 1)
{
bIRQTriggered = True;
}
if(bIRQTriggered)
{
/* IRQ triggered => Exit */
break;
}
if(err == TM_OK && irqStatus != 0x00)
{
err = iTDA18273_Read(pObj, &gTDA18273_Reg_IRQ_status, &uIRQStatus, Bus_None);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Read(0x%08X) failed.", pObj->tUnitW));
if(irqStatus == uIRQStatus)
{
bIRQTriggered = True;
}
}
if(counter)
{
err = iTDA18273_Wait(pObj, waitStep);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "iTDA18273_Wait(0x%08X) failed.", pObj->tUnitW));
}
}
if(err == TM_OK && bIRQTriggered == False)
{
err = TDA18273_ERR_NOT_READY;
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_Write */
/* */
/* DESCRIPTION: Writes in TDA18273 hardware */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_Write(
pTDA18273Object_t pObj, /* I: Driver object */
const TDA18273_BitField_t* pBitField, /* I: Bitfield structure */
UInt8 uData, /* I: Data to write */
eBusAccess_t eBusAccess /* I: Access to bus */
)
{
tmErrorCode_t err = TM_OK;
UInt8 RegAddr = 0;
UInt32 DataLen = 1;
UInt8 RegData = 0;
pUInt8 pRegData = Null;
UInt32 RegMask = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_Write(0x%08X)", pObj->tUnitW);
if(pBitField == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Set Register Address */
RegAddr = pBitField->Address;
if(RegAddr < TDA18273_REG_MAP_NB_BYTES)
{
pRegData = (UInt8 *)(&(pObj->RegMap)) + RegAddr;
}
else
{
pRegData = &RegData;
}
if( (eBusAccess&Bus_NoRead) == False && P_SIO_READ_VALID)
{
/* Read data from TDA18273 */
err = P_SIO_READ(pObj->tUnitW, TDA18273_REG_ADD_SZ, &RegAddr, DataLen, pRegData);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "IO_Read(0x%08X, 1, 0x%02X, %d) failed.", pObj->tUnitW, RegAddr, DataLen));
}
if(err == TM_OK)
{
RegMask = ( (1 << pBitField->WidthInBits) - 1);
/* Limit uData to WidthInBits */
uData &= RegMask;
/* Set Data */
RegMask = RegMask << pBitField->PositionInBits;
*pRegData &= (UInt8)(~RegMask);
*pRegData |= uData << pBitField->PositionInBits;
if( (eBusAccess&Bus_NoWrite) == False && P_SIO_WRITE_VALID)
{
/* Write data to TDA18273 */
//printf(" Write data to TDA18273 \n");
err = P_SIO_WRITE(pObj->tUnitW, TDA18273_REG_ADD_SZ, &RegAddr, DataLen, pRegData);
//printf(" Write data to TDA18273 end ret=%d\n",err);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "IO_Write(0x%08X, 1, 0x%02X, %d) failed.", pObj->tUnitW, RegAddr, DataLen));
}
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_Read */
/* */
/* DESCRIPTION: Reads in TDA18273 hardware */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_Read(
pTDA18273Object_t pObj, /* I: Driver object */
const TDA18273_BitField_t* pBitField, /* I: Bitfield structure */
UInt8* puData, /* I: Data to read */
eBusAccess_t eBusAccess /* I: Access to bus */
)
{
tmErrorCode_t err = TM_OK;
UInt8 RegAddr = 0;
UInt32 DataLen = 1;
UInt8 RegData = 0;
pUInt8 pRegData = Null;
UInt32 RegMask = 0;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_Read(0x%08X)", pObj->tUnitW);
if(pBitField == Null)
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK)
{
/* Set Register Address */
RegAddr = pBitField->Address;
if(RegAddr < TDA18273_REG_MAP_NB_BYTES)
{
pRegData = (UInt8 *)(&(pObj->RegMap)) + RegAddr;
}
else
{
pRegData = &RegData;
}
if( (eBusAccess&Bus_NoRead) == False && P_SIO_READ_VALID)
{
/* Read data from TDA18273 */
err = P_SIO_READ(pObj->tUnitW, TDA18273_REG_ADD_SZ, &RegAddr, DataLen, pRegData);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "IO_Read(0x%08X, 1, 0x%02X, %d) failed.", pObj->tUnitW, RegAddr, DataLen));
}
if(err == TM_OK && puData != Null)
{
/* Copy Raw Data */
*puData = *pRegData;
/* Get Data */
RegMask = ( (1 << pBitField->WidthInBits) - 1) << pBitField->PositionInBits;
*puData &= (UInt8)RegMask;
*puData = (*puData) >> pBitField->PositionInBits;
}
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_WriteRegMap */
/* */
/* DESCRIPTION: Writes driver RegMap cached data to TDA18273 hardware. */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_WriteRegMap(
pTDA18273Object_t pObj, /* I: Driver object */
UInt8 uAddress, /* I: Data to write */
UInt32 uWriteLen /* I: Number of data to write */
)
{
tmErrorCode_t err = TM_OK;
pUInt8 pRegData = Null;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_WriteRegMap(0x%08X)", pObj->tUnitW);
if( uAddress < TDA18273_REG_MAP_NB_BYTES &&
(uAddress + uWriteLen) <= TDA18273_REG_MAP_NB_BYTES )
{
pRegData = (UInt8 *)(&(pObj->RegMap)) + uAddress;
}
else
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK && P_SIO_WRITE_VALID)
{
/* Write data to TDA18273 */
err = P_SIO_WRITE(pObj->tUnitW, TDA18273_REG_ADD_SZ, &uAddress, uWriteLen, pRegData);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "IO_Write(0x%08X, 1, 0x%02X, %d) failed.", pObj->tUnitW, uAddress, uWriteLen));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_ReadRegMap */
/* */
/* DESCRIPTION: Reads driver RegMap cached data from TDA18273 hardware. */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_ReadRegMap(
pTDA18273Object_t pObj, /* I: Driver object */
UInt8 uAddress, /* I: Data to read */
UInt32 uReadLen /* I: Number of data to read */
)
{
tmErrorCode_t err = TM_OK;
pUInt8 pRegData = Null;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_ReadRegMap(0x%08X)", pObj->tUnitW);
if( uAddress < TDA18273_REG_MAP_NB_BYTES &&
(uAddress + uReadLen) <= TDA18273_REG_MAP_NB_BYTES )
{
pRegData = (UInt8 *)(&(pObj->RegMap)) + uAddress;
}
else
{
err = TDA18273_ERR_BAD_PARAMETER;
}
if(err == TM_OK && P_SIO_READ_VALID)
{
/* Read data from TDA18273 */
err = P_SIO_READ(pObj->tUnitW, TDA18273_REG_ADD_SZ, &uAddress, uReadLen, pRegData);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "IO_Read(0x%08X, 1, 0x%02X, %d) failed.", pObj->tUnitW, uAddress, uReadLen));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_Wait */
/* */
/* DESCRIPTION: Waits for requested time. */
/* */
/* RETURN: TM_OK if no error */
/* */
/*============================================================================*/
tmErrorCode_t
iTDA18273_Wait(
pTDA18273Object_t pObj, /* I: Driver object */
UInt32 Time /* I: time to wait for */
)
{
tmErrorCode_t err = TDA18273_ERR_NULL_CONTROLFUNC;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_Wait(0x%08X)", pObj->tUnitW);
if(P_STIME_WAIT_VALID)
{
/* Wait Time ms */
err = P_STIME_WAIT(pObj->tUnitW, Time);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TIME_Wait(0x%08X, %d) failed.", pObj->tUnitW, Time));
}
return err;
}
#ifdef _TVFE_IMPLEMENT_MUTEX
/*============================================================================*/
/* FUNCTION: iTDA18273_MutexAcquire: */
/* */
/* DESCRIPTION: Acquires driver mutex. */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/*============================================================================*/
tmErrorCode_t
iTDA18273_MutexAcquire(
pTDA18273Object_t pObj,
UInt32 timeOut
)
{
tmErrorCode_t err = TDA18273_ERR_NULL_CONTROLFUNC;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_MutexAcquire(0x%08X)", pObj->tUnitW);
if(P_SMUTEX_ACQUIRE_VALID && P_MUTEX_VALID)
{
err = P_SMUTEX_ACQUIRE(P_MUTEX, timeOut);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "Mutex_Acquire(0x%08X, %d) failed.", pObj->tUnitW, timeOut));
}
return err;
}
/*============================================================================*/
/* FUNCTION: iTDA18273_MutexRelease: */
/* */
/* DESCRIPTION: Releases driver mutex. */
/* */
/* RETURN: TM_OK if no error */
/* */
/* NOTES: */
/*============================================================================*/
tmErrorCode_t
iTDA18273_MutexRelease(
pTDA18273Object_t pObj
)
{
tmErrorCode_t err = TDA18273_ERR_NULL_CONTROLFUNC;
tmDBGPRINTEx(DEBUGLVL_INOUT, "iTDA18273_MutexRelease(0x%08X)", pObj->tUnitW);
if(P_SMUTEX_RELEASE_VALID && P_MUTEX_VALID)
{
err = P_SMUTEX_RELEASE(P_MUTEX);
tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "Mutex_Release(0x%08X) failed.", pObj->tUnitW));
}
return err;
}
#endif
#endif