summaryrefslogtreecommitdiffstats
path: root/api/TDA18291.c
diff options
context:
space:
mode:
Diffstat (limited to 'api/TDA18291.c')
-rw-r--r--api/TDA18291.c1315
1 files changed, 1315 insertions, 0 deletions
diff --git a/api/TDA18291.c b/api/TDA18291.c
new file mode 100644
index 0000000..4736b49
--- /dev/null
+++ b/api/TDA18291.c
@@ -0,0 +1,1315 @@
+/**
+ * $Header:
+ * (C) Copyright 2001 Philips Semiconductors, All rights reserved
+ *
+ * This source code and any compilation or derivative thereof is the sole
+ * property of Philips Corporation and is provided pursuant to a Software
+ * License Agreement. This code is the proprietary information of Philips
+ * Corporation and is confidential in nature. Its use and dissemination by
+ * any party other than Philips Corporation is strictly limited by the
+ * confidential information provisions of the Agreement referenced above.
+ *-----------------------------------------------------------------------------
+ * FILE NAME: tmbslTDA18291.c
+ *
+ * DESCRIPTION: Function for the digimob tuner TDATDA18291
+ *
+ * DOCUMENT REF: DigiMob - ObjectiveSpecification_V4.2.doc - 21 April 2005
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * Standard include files:
+ *-----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * Project include files:
+ *-----------------------------------------------------------------------------
+ */
+#include "TDA18291local.h"
+#include "standard.h"
+
+/*-----------------------------------------------------------------------------
+ * Types and defines:
+ *-----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * Global data:
+ *-----------------------------------------------------------------------------
+ */
+
+
+/* default instance */
+tm18291object_t g18291Instance[] =
+{
+ {
+ {
+ Null, /* Demodulator */
+ 0x01 /* chip */
+ },
+
+ False, /* init [False : instance is not initialized] */
+ 0, /* uHwAddress [HwId not set] */
+ { Null, Null/*, Null,*/ /* systemFunc [system function not initialized] */
+ /*Null, Null, Null*/
+ },
+ tmPowerOff, /* default power state */
+ {
+ CUSTOM_BOARD_DEF, /* uBoard [default configuration structure] */
+ TDA18291_NB_AGC_RANGES, /* Nb [number of lines] */
+ 0, /* Index [start index] */
+ {
+ {0,0},
+ {5,1},
+ {10,2},
+ {15,3},
+ {20,4},
+ {25,5},
+ {30,6},
+ {35,7},
+ {40,8},
+ {45,9},
+ {50,10},
+ {55,11},
+ {60,12},
+ {65,13},
+ {70,14},
+ {75,15},
+ {80,64},
+ {85,65},
+ {90,66},
+ {95,67},
+ {100,68},
+ {105,69},
+ {110,70},
+ {115,71},
+ {120,72},
+ {125,73},
+ {130,74},
+ {135,75},
+ {140,76},
+ {145,77},
+ {150,78},
+ {155,79},
+ {160,192},
+ {165,193},
+ {170,194},
+ {175,195},
+ {180,196},
+ {185,197},
+ {190,198},
+ {195,199},
+ {200,200},
+ {205,201},
+ {210,202},
+ {215,203},
+ {220,204},
+ {225,205},
+ {230,206},
+ {235,207},
+ {240,320},
+ {245,321},
+ {250,322},
+ {255,323},
+ {260,324},
+ {265,325},
+ {270,326},
+ {275,327},
+ {280,328},
+ {285,329},
+ {290,330},
+ {295,331},
+ {300,332},
+ {305,333},
+ {310,334},
+ {315,335},
+ {320,448},
+ {325,449},
+ {330,450},
+ {335,451},
+ {340,452},
+ {345,453},
+ {350,454},
+ {355,455},
+ {360,456},
+ {365,457},
+ {370,458},
+ {375,459},
+ {380,460},
+ {385,461},
+ {390,462},
+ {395,463},
+ {400,464},
+ {405,465},
+ {410,466},
+ {415,467},
+ {420,468},
+ {425,469},
+ {430,470},
+ {435,471},
+ {440,472},
+ {445,473},
+ {450,474},
+ {455,475},
+ {460,476},
+ {465,477},
+ {470,478},
+ {475,479},
+ {480,480},
+ {485,481},
+ {490,482},
+ {495,483},
+ {500,484},
+ {505,485},
+ {510,486},
+ {515,487},
+ {520,488},
+ {525,489},
+ {530,490},
+ {535,491},
+ {540,492},
+ {545,493},
+ {550,494},
+ {555,495},
+ {560,496},
+ {565,497},
+ {570,498},
+ {575,499},
+ {580,500},
+ {585,501},
+ {590,502},
+ {595,503},
+ {600,504},
+ {605,505},
+ {610,506},
+ {615,507},
+ {620,508},
+ {625,509},
+ {630,510},
+ {635,511},
+ },
+ },
+ {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* pTunerReg[register default values]; */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },
+ 0, /* LO_FreqProg [RF programmed] */
+ 0, /* uTickEnd [end tick value] */
+ {
+ 1,1,0,0,1,365,3, /* UserData [tm18291UserData_t] */
+ 0,0,0,0,0,0,0,0,
+ 0x01,0x0C,0x00,0x02,0x01,0x00,0x80,0x00,0x90,0x86,
+ 0,0,0,0,0,26000,
+ 0,0,0,0,0,0,0,
+ 2,1,0
+ }
+ }
+};
+
+/*-----------------------------------------------------------------------------
+ * Internal Prototypes:
+ *-----------------------------------------------------------------------------
+ */
+Bool_
+TDA18291Init (
+ tmUnitSelect_t TunerUnit /* I: Tuner unit number */
+ );
+
+Bool_
+TDA18291CalcPLL (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 LO_Freq /* I: Frequency in hertz */
+ );
+
+Bool_
+TDA18291GetGainIndex(
+ ptm18291object_t pObject, /* I: Tuner object */
+ UInt32 *uIndex /* O: Gain */
+ );
+
+Bool_
+TDA18291WaitTick(
+ ptm18291object_t pObj /* I: Tuner unit number */
+ );
+
+Bool_
+TDA18291InitTick(
+ ptm18291object_t pObj, /* I: Tuner unit number */
+ UInt16 wTime /* I: time to wait for */
+ );
+
+/*-----------------------------------------------------------------------------
+ * Exported functions:
+ *-----------------------------------------------------------------------------
+ */
+Bool_ SY_Write2(UInt32 uAddress,
+ UInt32 uSubAddress,
+ UInt32 uNbData,
+ UInt32* pDataBuff)
+{
+ Bool_ RetStatus = False;
+ ptm18291object_t pObj;
+ UInt32 dwError = 0;
+ UInt8 uBuffer[39];
+ UInt32 i;
+
+ for (i = 0; i < uNbData; i++)
+ {
+ uBuffer[i] = (UInt8)pDataBuff[i];
+ }
+
+ pObj = &g18291Instance[0];
+ dwError = Standard_writeTunerRegisters (pObj->AFAInfo.demodulator, pObj->AFAInfo.chip,
+ (unsigned short)uSubAddress, (UInt8)uNbData, uBuffer);
+ if (dwError == 0) RetStatus = True;
+
+ return (RetStatus);
+};
+
+Bool_ SY_Read2(UInt32 uAddress,
+ UInt32 uSubAddress,
+ UInt32 uNbData,
+ UInt32* pDataBuff)
+{
+ Bool_ RetStatus = False;
+ ptm18291object_t pObj;
+ UInt32 dwError = 0;
+ UInt8 uBuffer[39];
+ UInt32 i;
+
+ pObj = &g18291Instance[0];
+ dwError = Standard_readTunerRegisters (pObj->AFAInfo.demodulator, pObj->AFAInfo.chip, (UInt16)uSubAddress, (UInt8)uNbData, uBuffer);
+ if (dwError == 0)
+ {
+ RetStatus = True;
+
+ for (i = 0; i < uNbData; i++)
+ {
+ pDataBuff[i] = (UInt32)uBuffer[i];
+ }
+ }
+
+ return (RetStatus);
+};
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291Init:
+ *
+ * DESCRIPTION: create an instance of a TDA18291 tuner
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291Init(
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ tmbslTuParam_t Param /* I: setup parameters */
+ )
+{
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the max number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /*----------------------
+ * initialize the object
+ *----------------------
+ * return if already initialized
+ */
+ if(g18291Instance[TunerUnit].init == True)
+ return TM_OK;
+
+ /*----------------
+ * init the object
+ *----------------
+ * initialize the object by default values
+ */
+ g18291Instance[TunerUnit].uHwAddress = Param.uHwAddress;
+ g18291Instance[TunerUnit].systemFunc = Param.systemFunc;
+ g18291Instance[TunerUnit].init = True;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291DeInit:
+ *
+ * DESCRIPTION: destroy an instance of a TDA18291 tuner
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291DeInit (
+ tmUnitSelect_t TunerUnit /* I: Tuner unit number */
+ )
+{
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*-------------------------
+ * De-initialize the object
+ *-------------------------
+ */
+ g18291Instance[TunerUnit].init = False;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291GetSWVersion:
+ *
+ * DESCRIPTION: Return the version of this device
+ *
+ * RETURN: TM_OK
+ *
+ * NOTES: Values defined in the tmTDA18291local.h file
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291GetSWVersion (
+ ptmSWVersion_t pSWVersion /* I: Receives SW Version */
+ )
+{
+ pSWVersion->compatibilityNr = TDA18291_BSL_COMP_NUM;
+ pSWVersion->majorVersionNr = TDA18291_BSL_MAJOR_VER;
+ pSWVersion->minorVersionNr = TDA18291_BSL_MINOR_VER;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291SetPowerState:
+ *
+ * DESCRIPTION: Set the power state of this device.
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_OK
+ *
+ * NOTES: NOT implemented - inputs from stephane needed
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291SetPowerState (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ tmPowerState_t powerState /* I: Power state of this device */
+)
+{
+ ptm18291UserData_t pUserData;
+ ptm18291object_t pObj;
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+
+ /* pObj & pUserData initialisation */
+ pObj = &g18291Instance[TunerUnit];
+ pUserData = &(pObj->UserData);
+
+ /*--------------------------------------------------------------------------
+ * set the value
+ * 4 possble values: tmPowerOn tmPowerOff tmPowerStandy tmPowerSuspend
+ *--------------------------------------------------------------------------
+ */
+
+ switch (powerState)
+ {
+ case tmPowerOn:
+ pUserData->PDIC = 0; /* IC is active */
+ pUserData->PDIF = 0; /* IF output is active */
+ pUserData->h03b5 = 1; /* default value */
+ pUserData->PDRF = 0; /* RF is active */
+ pUserData->PDRefBuff = 0; /* REFBUFF is active */
+ pUserData->PDSYNTH = 0; /* SYNTH is active */
+ pUserData->PDVCO = 0; /* VCO is active */
+ pUserData->PD_Xtout = 0; /* default value */
+ break;
+
+ case tmPowerOff:
+ pUserData->PDIC = 1; /* IC is off */
+ pUserData->PDIF = 1; /* IF output is off */
+ pUserData->h03b5 = 1; /* default value */
+ pUserData->PDRF = 1; /* RF is off */
+ pUserData->PDRefBuff = 1; /* REFBUFF is off */
+ pUserData->PDSYNTH = 1; /* SYNTH is off */
+ pUserData->PDVCO = 1; /* VCO is off */
+ pUserData->PD_Xtout = 0; /* default value */
+ break;
+ case tmPowerStandby:
+ case tmPowerSuspend:
+ break;
+ }
+ pObj->curPowerState = powerState;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291GetPowerState:
+ *
+ * DESCRIPTION: Get the power state of this device.
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291GetPowerState (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ tmPowerState_t *pPowerState /* O: Power state of this device */
+)
+{
+ /*----------------------
+ * test input parameters
+ *----/------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*--------------
+ * get the value
+ *--------------
+ */
+ *pPowerState = g18291Instance[TunerUnit].curPowerState;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291Write:
+ *
+ * DESCRIPTION: Write in the tuner.
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TMBSL_ERR_IIC_ERR
+ * TM_OK
+ *
+ * NOTES: uIndex: IN parameter containing the HW Sub Address as specified in
+ * the datasheet (i.e. looks like 0xX0)
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291Write (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 uIndex, /* I: Start index to write */
+ UInt32 uNbBytes, /* I: Number of bytes to write */
+ UInt32* puBytes /* I: Pointer on an array of bytes */
+)
+{
+
+ UInt32 uCounter;
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /* test the parameters. uIndex is: 0x0X */
+ if ((uIndex + uNbBytes) > TDA18291_NB_REGISTERS)
+ return TMBSL_ERR_TUNER_BAD_PARAMETER;
+
+ /*--------------
+ * set the value
+ *--------------
+ * save the values written in the tuner
+ */
+ for (uCounter = 0; uCounter < uNbBytes; uCounter++)
+ g18291Instance[TunerUnit].pTunerReg[uCounter+uIndex] = puBytes[uCounter];
+
+ /* write in the tuner */
+ if (g18291Instance[TunerUnit].systemFunc.SY_Write(
+ g18291Instance[TunerUnit].uHwAddress,
+ uIndex, uNbBytes, &(g18291Instance[TunerUnit].pTunerReg[uIndex])) != 1)
+ return TMBSL_ERR_IIC_ERR;
+
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291WriteBit:
+ *
+ * DESCRIPTION: Write in the tuner.
+ *
+ * RETURN: TM_ERR_NOT_SUPPORTED
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291WriteBit (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 uIndex, /* I: Start index to write */
+ UInt32 uBitMask, /* I: bit mask */
+ UInt32 uBitValue /* I: bit value */
+)
+{
+ return TM_ERR_NOT_SUPPORTED;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291Read:
+ *
+ * DESCRIPTION: Read in the tuner.
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TMBSL_ERR_TUNER_BAD_PARAMETER
+ * TMBSL_ERR_IIC_ERR
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291Read (
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 uIndex, /* I: Start index to read */
+ UInt32 uNbBytes, /* I: Number of bytes to read */
+ UInt32* puBytes /* I: Pointer on an array of bytes */
+)
+{
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /* test the object */
+ if (uNbBytes > TDA18291_NB_REGISTERS)
+ return TMBSL_ERR_TUNER_BAD_PARAMETER;
+
+ /*--------------
+ * get the value
+ *--------------
+ */
+ if (uIndex == -1)
+ {
+
+ /* read the status byte if index is -1 */
+ /* Return the complete register. Mask is applied in higher layer */
+ if (g18291Instance[TunerUnit].systemFunc.SY_Read(
+ g18291Instance[TunerUnit].uHwAddress,
+ 0, uNbBytes, puBytes) != 1) return TMBSL_ERR_IIC_ERR;
+ }
+ else
+ {
+ UInt32 uCounter;
+
+ /* return value previously written */
+ for (uCounter = uIndex; (uCounter < uIndex + uNbBytes) && (uCounter < TDA18291_NB_REGISTERS); uCounter++)
+ puBytes[uCounter-uIndex] = g18291Instance[TunerUnit].pTunerReg[uCounter];
+
+ }
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291SetRf:
+ *
+ * DESCRIPTION: Calculate i2c register & write in TDA18291
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TMBSL_ERR_TUNER_BAD_PARAMETER
+ * TMBSL_ERR_IIC_ERR
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291SetRf(
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 LO_Freq /* I: Frequency in hertz */
+)
+{
+ UInt8 uCounter = 0;
+
+ ptm18291object_t pObj;
+ ptm18291UserData_t pUserData;
+
+ /* pObj & pUserData initialisation */
+ pObj = &g18291Instance[TunerUnit];
+ pUserData = &(pObj->UserData);
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*--------------
+ * set the value
+ *--------------
+ * Bytes h05 h06 h07 h08 h09
+ * initialised in TDA18291CalcPLL
+ * calculate the tuner reg h5X h6X h7X h8X h9X
+ */
+ pUserData->Flo_max08 = 987000;
+ pUserData->Flo_max09 = 877000;
+ pUserData->Flo_max10 = 790000;
+ pUserData->Flo_max11 = 718000;
+ pUserData->Flo_max12 = 658000;
+ pUserData->Flo_max13 = 607000;
+ pUserData->Flo_max14 = 564000;
+ pUserData->Flo_max15 = 526000;
+ TDA18291CalcPLL(TunerUnit, LO_Freq);
+
+ /* Byte h03 */
+ pUserData->PDIC = 0; /* IC is active */
+ pUserData->PDIF = 0; /* IF output is active */
+ pUserData->h03b5 = 1; /* default value */
+ pUserData->PDRF = 0; /* RF is active */
+ pUserData->PDRefBuff = 0; /* REFBUFF is active */
+ pUserData->PDSYNTH = 0; /* SYNTH is active */
+ pUserData->PDVCO = 0; /* VCO is active */
+ pUserData->PD_Xtout = 0; /* Xtout is active */
+ pObj->pTunerReg[TDA18291_REG_H03] = pUserData->PDIC << 7 | pUserData->PDIF << 6 | pUserData->h03b5 << 5 | pUserData->PDRF << 4 | pUserData->PDRefBuff << 3 | pUserData->PDSYNTH << 2 | pUserData->PDVCO << 1 | pUserData->PD_Xtout << 0;
+
+ /* Byte h04 */
+ pUserData->h04b3tob0 = 0x0C; /* enable xtal out (bit3)*/
+ pObj->pTunerReg[TDA18291_REG_H04] = pUserData->Ref_Freq << 6 | pUserData->AGCBusEn << 5 | pUserData->AGCext << 4 | pUserData->h04b3tob0 << 0;
+
+ /* Bytes h05 h06 h07 h08 h09 */
+ /* calculated in TDA18291CalcPLL function */
+ pUserData->h09b7tob6 = 0; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H09] = pUserData->h09b7tob6 << 6 | pObj->pTunerReg[TDA18291_REG_H09] << 0;
+
+ /* Bytes h0A h0B */
+ /* Search for the agc range corresponding to wanted gain */
+ while (pUserData->AGCGain > pObj->config.Map[uCounter].uGain)
+ uCounter++;
+ pUserData->AGCBB = pObj->config.Map[uCounter].uAGC_BB;
+ pUserData->h0Ab7 = pUserData->Enable_LNA; /* enable or disable the LNA */
+ pUserData->h0Ab1tob0 = 0x02; /* default value */
+ pUserData->h0Bb7tob6 = 0; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H0A] = pUserData->h0Ab7 << 7 | (UInt8)(pUserData->AGCBB >> 6) << 4 | pUserData->FC << 2 | pUserData->h0Ab1tob0 << 0 ;
+ pObj->pTunerReg[TDA18291_REG_H0B] = pUserData->h0Bb7tob6 << 6 | (UInt8)(pUserData->AGCBB << 2) >> 2;
+
+ /* Byte h0C */
+ pUserData->h0C = 0x80; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H0C] = pUserData->h0C << 0;
+
+ /* Byte h0D */
+ pUserData->h0D = 0x00; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H0D] = pUserData->h0D << 0;
+
+ /* Byte h0E */
+ pUserData->h0E = 0x90; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H0E] = pUserData->h0E << 0;
+
+ /* Byte h0F */
+ pUserData->h0F = 0x86; /* default value */
+ pObj->pTunerReg[TDA18291_REG_H0F] = pUserData->h0F << 0;
+
+
+ if (pUserData->FlagI2CWrite){
+ /* Write h03 to h0F */
+ if (pObj->systemFunc.SY_Write(
+ pObj->uHwAddress,
+ 3, 0x0d, &(pObj->pTunerReg[TDA18291_REG_H03])) != 1)
+
+ return TMBSL_ERR_IIC_ERR;
+ }
+
+
+ /* return value */
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291GetRf:
+ *
+ * DESCRIPTION: Get the frequency programmed in the tuner
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_OK
+ *
+ * NOTES: The value returned is the one stored in the object
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291GetRf(
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32* pLO_Freq /* O: Frequency in hertz */
+ )
+{
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*--------------
+ * get the value
+ *--------------
+ * the read function can't be used
+ */
+ *pLO_Freq = g18291Instance[TunerUnit].LO_FreqProg*1000;
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291SetConfig:
+ *
+ * DESCRIPTION: Set the config of the TDA18291
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_ERR_NOT_SUPPORTED
+ * TMBSL_ERR_TUNER_BAD_PARAMETER
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291SetConfig(
+ tmUnitSelect_t TunerUnit, /* I: TunerUnit number */
+ UInt32 uItemId, /* I: Identifier of the item to modify */
+ UInt32 uValue /* I: Value to set for the config item */
+ )
+{
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object*/
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*--------------
+ * set the value
+ *--------------
+ */
+ switch((tm18291cfgIndex_t)uItemId)
+ {
+ case BOARD:
+ switch (uValue & 0xffff0000)
+ {
+ case OM5768_BOARD_DEF:
+ /* Default Xtal Freq is 26 MHz */
+ g18291Instance[TunerUnit].UserData.Ref_Freq = 2;
+ g18291Instance[TunerUnit].UserData.LO_XTALFreq = gTableXtalFreq[2];
+ /* Default Xtal Out Mode is OFF */
+ /*g18291Instance[TunerUnit].UserData.h04b3tob0 = 4; */
+ g18291Instance[TunerUnit].UserData.PDRefBuff = 0;
+ g18291Instance[TunerUnit].UserData.PD_Xtout = 0;
+ /* Default AGC control is from external pin */
+ g18291Instance[TunerUnit].UserData.AGCBusEn = 0;
+ g18291Instance[TunerUnit].UserData.AGCext = 1;
+
+ break;
+ case CUSTOM_BOARD_DEF:
+ /* do nothing more than setting the default values */
+ break;
+ default:
+ /* board not supported */
+ return TM_ERR_NOT_SUPPORTED;
+ }
+ /* store board */
+ g18291Instance[TunerUnit].config.uBoard = uValue;
+ break;
+
+ case SET_CUTOFF_FREQ:
+ /* Cut-off Frequency, added by max */
+ g18291Instance[TunerUnit].UserData.FC = (UInt8)uValue;
+ break;
+
+ /* backdoor functions */
+ case FEINIT:
+ TDA18291Init( TunerUnit );
+ break;
+
+ case AGC_BUS_ENABLE:
+ g18291Instance[TunerUnit].UserData.AGCBusEn = (UInt8)uValue;
+ break;
+
+ case AGC_EXT:
+ g18291Instance[TunerUnit].UserData.AGCext = (UInt8)uValue;
+ break;
+
+ case AGC_GAIN_VALUE:
+ g18291Instance[TunerUnit].UserData.AGCGain = (UInt32)uValue;
+ break;
+
+ case LO_XTAL_FREQ_INDEX:
+ if ((UInt8)uValue==3)
+ {
+ uValue=1;
+ }
+ g18291Instance[TunerUnit].UserData.Ref_Freq = (UInt8)uValue;
+ g18291Instance[TunerUnit].UserData.LO_XTALFreq = gTableXtalFreq[uValue];
+ break;
+
+ case XTAL_MODE:
+ if (uValue)
+ {
+ /* Activate XTout */
+ g18291Instance[TunerUnit].UserData.PDRefBuff = 0;
+ g18291Instance[TunerUnit].UserData.PD_Xtout = 0;
+ }
+ else
+ {
+ /* Disable XTout */
+ g18291Instance[TunerUnit].UserData.PDRefBuff = 1;
+ g18291Instance[TunerUnit].UserData.PD_Xtout = 1;
+ }
+ break;
+ case CUT_OFF_IND:
+ g18291Instance[TunerUnit].UserData.CutOffIndex = (UInt8)uValue;
+ g18291Instance[TunerUnit].UserData.FC = gTableCutOffVal[uValue];
+ break;
+
+ case ENABLE_LNA:
+ g18291Instance[TunerUnit].UserData.Enable_LNA = (UInt8)uValue;
+ break;
+ }
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: tmbslTDA18291GetConfig:
+ *
+ * DESCRIPTION: Get the config of the TDA18291
+ *
+ * RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER
+ * TMBSL_ERR_TUNER_NOT_INITIALIZED
+ * TM_OK
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+tmErrorCode_t
+tmbslTDA18291GetConfig(
+ tmUnitSelect_t TunerUnit, /* I: Tuner unit number */
+ UInt32 uItemId, /* I: Identifier of the item to modify */
+ UInt32* puValue /* I: Value to set for the config item */
+ )
+{
+ UInt32 uCounter = 0;
+
+ /*----------------------
+ * test input parameters
+ *----------------------
+ * test the instance number
+ */
+ if (TunerUnit > TDA18291_MAX_UNITS)
+ return TMBSL_ERR_TUNER_BAD_UNIT_NUMBER;
+
+ /* test the object */
+ if (g18291Instance[TunerUnit].init == False)
+ return TMBSL_ERR_TUNER_NOT_INITIALIZED;
+
+ /*--------------
+ * set the value
+ *--------------
+ */
+ switch((tm18291cfgIndex_t)uItemId)
+ {
+ case BOARD:
+ *puValue = g18291Instance[TunerUnit].config.uBoard;
+ break;
+
+ case AGC_BUS_ENABLE:
+ *puValue = g18291Instance[TunerUnit].UserData.AGCBusEn;
+ break;
+
+ case AGC_EXT:
+ *puValue = g18291Instance[TunerUnit].UserData.AGCext;
+ break;
+
+ case AGC_GAIN_INDEX:
+ if ( g18291Instance[TunerUnit].UserData.AGCBusEn )
+ {
+ /* Return the index of the field of type tm18291agcMap_t */
+ /* that corresponds to the current setting of gain */
+ uCounter = 0;
+ while ( g18291Instance[TunerUnit].config.Map[uCounter].uGain < g18291Instance[TunerUnit].UserData.AGCGain)
+ uCounter ++;
+
+ *puValue = uCounter;
+ }
+ else
+ /* Return the index of the field of type tm18291agcMap_t */
+ /* that corresponds to the gain read in the tuner */
+ TDA18291GetGainIndex(&g18291Instance[TunerUnit], puValue);
+ break;
+
+ case AGC_GAIN_VALUE:
+ if ( g18291Instance[TunerUnit].UserData.AGCBusEn )
+ *puValue = g18291Instance[TunerUnit].UserData.AGCGain;
+ else
+ {
+
+ TDA18291GetGainIndex(&g18291Instance[TunerUnit], &uCounter);
+ *puValue = g18291Instance[TunerUnit].config.Map[uCounter].uGain;/*g18291Instance[TunerUnit].config.Map[uCounter].uGain; */
+
+ }
+ break;
+
+ case LO_XTAL_FREQ_INDEX:
+
+ *puValue = g18291Instance[TunerUnit].UserData.Ref_Freq;
+ break;
+
+ case LO_XTAL_FREQ_VALUE:
+ *puValue = g18291Instance[TunerUnit].UserData.LO_XTALFreq;
+ break;
+
+ case XTAL_MODE:
+ *puValue = g18291Instance[TunerUnit].UserData.PD_Xtout;
+ break;
+
+ case ENABLE_LNA:
+ *puValue = g18291Instance[TunerUnit].UserData.Enable_LNA;
+ break;
+ }
+
+ return TM_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Internal functions:
+ *-----------------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: TDA18291Init:
+ *
+ * DESCRIPTION: Initialisation of the tuner
+ * The protocol used to initialise the tuner is the same as for the
+ * programming of the tuner to a new RF
+ *
+ * RETURN: always True
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+Bool_
+TDA18291Init (
+ tmUnitSelect_t TunerUnit /* I: tuner object */
+ )
+{
+ UInt32 uDefaultFreq = 600000000; /* Default LO frequency; */
+
+ tmbslTDA18291SetRf( TunerUnit ,uDefaultFreq);
+
+ return TM_TRUE;
+}
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: TDA18291CalcPLL:
+ *
+ * DESCRIPTION: Calculate the LO fractionnal PLL settings
+ *
+ * RETURN: Always True
+ *
+ * NOTES: This function doesn't write in the tuner
+ *-----------------------------------------------------------------------------
+ */
+Bool_
+TDA18291CalcPLL (
+ tmUnitSelect_t TunerUnit, /* Tuner unit number */
+ UInt32 LO_Freq /* Local oscillator frequency in hertz */
+ )
+{
+ UInt8 LO_PostdivTmp;
+ UInt32 LO_IntTmp;
+ UInt32 LO_FracTmp;
+ UInt32 LO_FreqTmp;
+
+ ptm18291object_t pObj;
+ ptm18291UserData_t pUserData;
+
+ /* pObj & pUserData initialisation */
+ pObj = &g18291Instance[TunerUnit];
+ pUserData = &(pObj->UserData);
+
+ /* LO Postdiv calculation */
+ if (LO_Freq > 493500000)
+ pUserData->LO_Postdiv = 1;
+ else if (LO_Freq > 246750000)
+ pUserData->LO_Postdiv = 2;
+ else if (LO_Freq > 123374000)
+ pUserData->LO_Postdiv = 4;
+ else if (LO_Freq > 61687000)
+ pUserData->LO_Postdiv = 8;
+ else
+ pUserData->LO_Postdiv = 16;
+
+ /* LO Prescaler calculation */
+ LO_FreqTmp = (LO_Freq / 1000) * pUserData->LO_Postdiv;
+ if (pUserData->LO_Postdiv >= 1)
+ {
+ if (LO_FreqTmp > pUserData->Flo_max09)
+ pUserData->LO_Presc = 8;
+ else if (LO_FreqTmp > pUserData->Flo_max10)
+ pUserData->LO_Presc = 9;
+ else if (LO_FreqTmp > pUserData->Flo_max11)
+ pUserData->LO_Presc = 10;
+ else if (LO_FreqTmp > pUserData->Flo_max12)
+ pUserData->LO_Presc = 11;
+ else if (LO_FreqTmp > pUserData->Flo_max13)
+ pUserData->LO_Presc = 12;
+ else if (LO_FreqTmp > pUserData->Flo_max14)
+ pUserData->LO_Presc = 13;
+ else if (LO_FreqTmp >= pUserData->Flo_max15)
+ pUserData->LO_Presc = 14;
+ else if (LO_FreqTmp < pUserData->Flo_max15)
+ pUserData->LO_Presc = 15;
+ }
+ else
+ {
+ pUserData->LO_Postdiv = 1;
+ pUserData->LO_Presc = 8;
+ }
+
+ /* VCO Frequency calculation */
+ pUserData->LO_VCOFreq = (LO_FreqTmp * pUserData->LO_Presc);
+
+ /* LO_IntTmp calculation */
+ LO_IntTmp = pUserData->LO_VCOFreq / (4 * pUserData->LO_XTALFreq);
+
+ /* LO_FracTmp calculation */
+ LO_FracTmp = (pUserData->LO_VCOFreq * 100) / 4;
+ LO_FracTmp -= (LO_IntTmp * pUserData->LO_XTALFreq * 100);
+ LO_FracTmp /= (pUserData->LO_XTALFreq / 100);
+
+ /* LO_Int & LO_Frac correction */
+ if (LO_FracTmp > 7500) {
+ pUserData->LO_Int = 2 * (LO_IntTmp) + 1 - 128;
+ pUserData->LO_Frac = ((LO_FracTmp - 5000) * 83886) / 100;
+ }
+ else if (LO_FracTmp >= 2500){
+ pUserData->LO_Int = 2 * (LO_IntTmp) - 128;
+ pUserData->LO_Frac = (LO_FracTmp * 83886) / 100;
+ }
+ else if (LO_FracTmp < 2500){
+ pUserData->LO_Int = 2 * (LO_IntTmp - 1 ) + 1 - 128;
+ pUserData->LO_Frac = ((LO_FracTmp + 5000) * 83886) / 100;
+ }
+
+ /* LO_Postdiv bits inversion correction */
+ switch (pUserData->LO_Postdiv){
+ case 1:
+ LO_PostdivTmp = 1;
+ break;
+ case 2: LO_PostdivTmp = 2;
+ break;
+ case 4: LO_PostdivTmp = 3;
+ break;
+ case 8: LO_PostdivTmp = 4;
+ break;
+ case 16:LO_PostdivTmp = 5;
+ break;
+ default:LO_PostdivTmp = 0;
+ break;
+ }
+
+ /* Bytes h5X h6X h7X h8X h9X */
+ pObj->pTunerReg[TDA18291_REG_H05] = (UInt8)(pUserData->LO_Int >> 1);
+ pObj->pTunerReg[TDA18291_REG_H06] = (UInt8)(pUserData->LO_Int << 7) | (UInt8)(pUserData->LO_Frac >> 16);
+ pObj->pTunerReg[TDA18291_REG_H07] = (UInt8)(pUserData->LO_Frac >> 8);
+ pObj->pTunerReg[TDA18291_REG_H08] = (UInt8)(pUserData->LO_Frac);
+ pObj->pTunerReg[TDA18291_REG_H09] = (UInt8)(pUserData->LO_Presc << 5) >> 2 | LO_PostdivTmp;
+
+ /* return value */
+ return True;
+}
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: TDA18291GetGainIndex
+ *
+ * DESCRIPTION: this function will read the gain AGCBB of the TDA18291
+ * ( i.e. combination of AGC1 and AGC2)
+ * and will determine the associated element of the Map table
+ * of the object config and return its index
+ *
+ * RETURN: nothing
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+Bool_
+TDA18291GetGainIndex(
+ ptm18291object_t pObject, /* I: Tuner object */
+ UInt32 *uIndex /* O: Gain */
+ )
+{
+ UInt32 puBytes[16];
+ UInt8 uGainReg[2];
+ UInt8 uGainMsb;
+ UInt32 uCounter, uGainTemp;
+
+ if (pObject->systemFunc.SY_Read(
+ pObject->uHwAddress,
+ 0, 16, puBytes) != 1) return False;
+
+ uGainReg[0] = (UInt8) (puBytes[1] & 0x1F);
+ uGainReg[1] = (UInt8) (puBytes[2] >> 4);
+
+ /* Get bit AGC1[2] */
+ uGainMsb = (uGainReg[0] & 0x10) >> 4;
+ /* keep bits AGC1[1], AGC1[0] and AGC2[5] AGC1[4] */
+ uGainReg[0] = (uGainReg[0] & 0x0F);
+
+ uGainTemp = (uGainMsb << 8) | (uGainReg[0] << 4) | uGainReg[1];
+
+ uCounter = 0;
+ while ( pObject->config.Map[uCounter].uAGC_BB < uGainTemp)
+ uCounter ++;
+
+ *uIndex = uCounter;
+
+ return True;
+}
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: TDA18291InitTick
+ *
+ * DESCRIPTION: this function will delay for the number of millisecond
+ *
+ * RETURN: nothing
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+#if 0
+Bool_
+TDA18291InitTick(
+ ptm18291object_t pObj, /* I: Tuner unit number */
+ UInt16 wTime /* I: time to wait for */
+)
+{
+ /* get current tick */
+ UInt32 uCurrentTick = pObj->systemFunc.SY_GetTickTime();
+
+ /* calculate end tick */
+ pObj->uTickEnd = (UInt32)wTime;
+ pObj->uTickEnd += pObj->systemFunc.SY_GetTickPeriod()/2;
+ pObj->uTickEnd /= pObj->systemFunc.SY_GetTickPeriod();
+ pObj->uTickEnd += uCurrentTick;
+
+ /* always add 1 because of rounding issue */
+ if (wTime)
+ pObj->uTickEnd++;
+
+ /* test overflow */
+ if (pObj->uTickEnd < uCurrentTick)
+ return False;
+ else
+ return True;
+}
+
+/*-----------------------------------------------------------------------------
+ * FUNCTION: TDA18291WaitTick
+ *
+ * DESCRIPTION: this function will block for the number of millisecond
+ *
+ * RETURN: True if time has elapsed else False
+ *
+ * NOTES:
+ *-----------------------------------------------------------------------------
+ */
+
+Bool_
+TDA18291WaitTick(
+ ptm18291object_t pObj /* I: Tuner unit number */
+)
+{
+ /* test if time has elapsed */
+ if (pObj->systemFunc.SY_GetTickTime() >= pObj->uTickEnd)
+ return True;
+ else
+ return False;
+}
+#endif