📄 tua6034.c
字号:
#define TUA6034_C
/*
*******************************************************************************
**
** \file tua6034.cpp
** \version v1.0
** \date 02-12-2004
**
** (C) Copyright 2004 by Philips RF Solutions, Singapore
** All rights reserved.
**
**
** The code in this module may not be distributed or
** disclosed to third parties without written permission
** of the owner.
**
** ver date by Desc
** ==========================================================================
** 1 LD Created
*******************************************************************************
*/
#include <math.h>
#include "DataType.h"
#include "msAPI_Memory.h"
#include "nxtcommon.h"
//#include "systemfunc.h"
#include "tua6034.h"
/********************************************************************************/
/* Macro */
/********************************************************************************/
/////////////////////////////////////////////////////////////////////////////
// General values used for calculations
/////////////////////////////////////////////////////////////////////////////
// Reference divider ratios - see table 5-8 TUA6034 datasheet
//Laurent #define F_REF 7.8125e3
#define F_REF1 50e3 / 8.0
#define F_REF2 31.25e3 / 8.0
#define F_REF3 166.67e3 / 8.0
//#define F_REF4 7.8125e3 //
#define F_REF4 62.5e3 / 8.0 // default
#define F_REF5 125e3 / 8.0
#define F_REF6 142.86e3 / 8.0
// constants for single PLL, 44MHz for digital IF, 45.75 MHz for analogue IF
#define F_IF_DI 44.0e6
#define F_IF_AN 45.750e6
// I2C byte order for tuner data
enum { DIVIDER1, DIVIDER2, CONTROL1, CONTROL2 };
/////////////////////////////////////////////////////////////////////////////
// Masking values for write bytes CB, BB, AB and read byte SB
/////////////////////////////////////////////////////////////////////////////
/*
BYTE CB
*/
// OS bit
#define OS_BIT 0x01
// test bits' mask for determining CONTROL2
#define TEST_BITS 0x38 // bits 3, 4, 5 of byte CB
#define DEFAULT_TEST 1
#define AB_MODE 3 // value for committing AB_Byte
// charge pump setting
//#define LOW_PUMP 0x8E
#define HIGH_PUMP 0x40
/*
BYTE BB
*/
// frequency range
#define LOW_BAND 0x01
#define MID_BAND 0x02
#define HIGH_BAND 0x04
// Input selection
#define INPUT_SEL 0x08
#define FDC_INPUT_MASK 0x1C // for OOB tuner
#define FDC_INPUT_SEL 0x10 // for OOB tuner
/*
BYTE AB
*/
#define ATC_LOW 0x80
/*
BYTE SB
*/
// Status read back from Philips 1236
#define TUNER_POR_MASK 0x80
#define TUNER_LOCK_MASK 0x40
#define TUNER_AGC_MASK 0x08
#define TUNER_ADC_OP 0x07 // 5 level ADC
/********************************************************************************/
/* typedef */
/********************************************************************************/
/*Tuner Data Device Context*/
typedef struct
{
TUN_Standard_t standard;
double frequency; // current frequency
Data8 IIC_Addr; // IIC address of Tuner device
bool Digital_Mode;
double F_ref; // reference divider frequency
Data8 tunerConfig[4];
Data8 CB_Byte; // CB Byte, used as CONTROL1
Data8 BB_Byte; // BB Byte, used as CONTROL2
Data8 AB_Byte; // additional AB Byte that could be CONTROL2
Data8 Status_Byte;
bool DirectAccess; // TRUE==direct / FALSE==via channel decoder
void *pInstance; /* identifies the instance of this device */
void *pNext; /* link tonext instance */
}TUN_DC;
#define NULL_INSTANCE ((TUN_DC *)(-1))
/********************************************************************************/
/* Local */
/********************************************************************************/
/*Tuner Functions*/
// set data in tunerConfig table
static int SetOSBit(void* Instance, bool OSValue);
static int SetRSBits(void* Instance, Data8 RSValue);
static int SetChargePump(void* Instance, bool pumpSetting);
static int SetTestBits(void* Instance, Data8 TestValue);
static int SetATC(void* Instance, bool AtcBit);
static int SetAgcTakeOver(void* Instance, Data8 value);
static int SetInput(void* Instance, bool bInput);
// read tuner status functions
static int GetADCLevel(void* Instance);
static bool GetAgcBit(void* Instance);
static bool GetPorFlag(void* Instance);
// various tuner functions
static int SetFrequency(void* Instance, double dFMHz);
static int GetStandard(void* Instance, TUN_Standard_t *pStd);
static int MapChanToFreq(void* Instance, Data8 Channel, double *pdFMHz);
static int SetTunerBand(void* Instance, double dFMHz );
static int SetPLLDivider(void* Instance, int ratio);
static bool PrepareControlBytes(void* Instance);
static int GetAddr(void* Instance, Data8 *pAddr);
static int SetStandard(void* Instance, TUN_Standard_t* std );
static int MapFreqToChan(void* Instance, double* dFMHz, Data8 *pChannel );
static int GetFreq(void* Instance, double *pdFMHz );
static int SetMode(void* Instance, bool mode);
static TUN_DC *GetTunDC(void *pContext);
static TUN_DC *FindTunDC(void *pContext, TUN_DC **ppPrevious);
static void DeleteTunDC(void *pContext);
/* One Device Control instance is guaranteed --
* this is the root of a list if multiple are needed.
*/
static TUN_DC inst0 = {
OFF_AIR_STD,// standard;
70.0, // current frequency
0xC0, // IIC address of Tuner device
TRUE, // Digital_Mode;
F_REF4, // reference divider frequency
0,0,0,0, // tunerConfig[4];
0xCE, // CB Byte
0x00, // BB Byte
0x20, // AB Byte
0x00, // Status_Byte;
FALSE, // direct access
(void*)NULL_INSTANCE, /* *pInstance */
(void*)NULL_INSTANCE /* *pNext */
};
/**********************************************************************
*
* FatAgcData
*
* Pointer passed as a parameter to NxtSetFatAgcData.
*
* The data in the table below MUST be modified as necessary to
* work with the user's custom AGC circuit. NxtWave will provide
* tables for well-known AGC circuits. The table supplied with
* drv2user.c is an example only, the table used for the NxtWave
* evaluation tuner Philips r1.
*
* Format: Register, count, data, ..., data
*
* The table MAY include sections for NXT_AGC_SETUP_64QAM --
* modifications to the standard data for 64QAM reception
*
* The table MAY include sections for NXT_AGC_SETUP_256QAM --
* modifications to the standard data for 256QAM reception
*
* The table MAY include sections for NXT_FAT_AGC_SETUP_ADJ --
* modifications to the standard data for VSB reception with Adjacents
*
* The table MUST end with NXT_AGC_SETUP_DONE
*
**********************************************************************/
code Data16 TUV1216D_FatAgcData[] = {
AGC_ADC_TARGET_POWER_LEVEL, 1, 0x70, /* set ADC target level */
AGC_SDM_CONFIGURE, 1, 0x07, /* sdm1 non-inverted */
AGC_SDM1_INPUT_MSB, 2, 0x10, 0x00, /* SDM1 at mid range before update */
AGC_SDMX_INPUT_MSB, 2, 0x68, 0x00, /* SDMX */
AGC_ADC_POWER_LPF_FC, 1, 0x05, /* adc_power_lpf */
AGC_GAIN_LOOP_BANDWIDTH, 2, 0x00, 0x00, /* agc gain/distribution loop bw */
AGC_ACCUMULATOR2_MSB, 2, 0x80, 0x00,
AGC_KG1, 1, 0x00, /* k1 for gain loop */
AGC_SDM12_LPF_FC, 1, 0x44, /* sdm1 lpf */
AGC_CONTROL, 1, 0x04, /* START AGC */
NXT_FAT_AGC_SETUP_ADJ, /* optimized for VSB w/N-1 Adjacent */
AGC_SDMX_INPUT_MSB, 2, 0xF0, 0x00, /* SDMX */
NXT_AGC_SETUP_64QAM, /* optimized for 64QAM */
AGC_SDMX_INPUT_MSB, 2, 0x60, 0x00, /* SDMX */
NXT_AGC_SETUP_256QAM, /* optimized for 256QAM */
AGC_SDMX_INPUT_MSB, 2, 0x60, 0x00, /* SDMX */
NXT_AGC_IF_THRESHOLD, /* detect adjacent on/off */
0x87, 0xAD, 0x42, 0x8F, //53, 26
NXT_AGC_SETUP_DONE /* EOF */
};
/*****************************************************************************/
/////////////////////////////////////////////////////////////////////////////
// TUN_Init
//
// Inputs:
// void *Instance, points to device instance
// Data8 addrGuess, contains IIC address to use
// TUN_Standard_t std = OFF_AIR_STD or CABLE_STD
//
// Outputs:
// none
//
// Returns:
// 0 - no error
// TUN_NOT_FOUND -- could not locate the tuner
//
// Description:
// hunt for tuner's I2C address
// select the specified tuning standard
//
int TUN_Init(void* Instance, Data8 addrGuess, TUN_Standard_t std)
{
Data8 u8Data = 0xFF, k;
Data16 IiCError;
TUN_Error_t retValue=TUN_NOT_FOUND;
TUN_DC *pDC;
bool DirectAccess=FALSE;
// hunt performed at higher level
// start first with non-direct access
IiCError = NxtIicXfer( (void *)NULL,
NXT_IIC_READ,
NXT_IIC_SPEED_SLOWEST,
1,
addrGuess,
&u8Data);
if( NXT_NO_ERROR == IiCError)
{
// access through channel decoder
// read again to clear the power-up bit
IiCError |= NxtReadIicXferData((void *)NULL, 1, &u8Data);
if( NXT_NO_ERROR == IiCError)
{
// check for power-up bit gone
if(((~u8Data) & TUNER_POR_MASK))
{
/* create the referenced DCB */
pDC = GetTunDC((void*)(Instance));
if (pDC == NULL_INSTANCE) retValue= TUN_MEMORY_PB;
else
{
retValue= TUN_OK;
pDC->AB_Byte = 0x20;
}
}
}
}
if(retValue == TUN_OK)
{
/* instance created ok so need init */
pDC->standard = std;
pDC->frequency = 57.0;
pDC->IIC_Addr = addrGuess;
pDC->Digital_Mode = TRUE;
pDC->F_ref = F_REF4;
for(k=0; k<4; k++)
pDC->tunerConfig[k] = 0;
pDC->CB_Byte = 0xCE;
pDC->BB_Byte = 0x00;
pDC->Status_Byte = u8Data;
pDC->DirectAccess = DirectAccess;
}
return retValue;
} // TUN_Init
/////////////////////////////////////////////////////////////////////////////
// TUN_GetBytes
//
// Inputs:
// void *Instance, points to device instance
//
// Outputs:
// Data8* - values returned in buffer passed as pointer
//
// Returns:
// int - number of bytes returned
//
// Description:
// returns tunerConfig[dividerbytes] + CB_Byte + BB_Byte + AB_Byte
//
int TUN_GetBytes(void* Instance, Data8* pDataBytes)
{
TUN_DC *pDC, *pDummy;
pDC = FindTunDC(Instance, &pDummy);
if (pDC == NULL_INSTANCE) return TUN_MEMORY_PB;
pDataBytes[0]=pDC->tunerConfig[DIVIDER1];
pDataBytes[1]=pDC->tunerConfig[DIVIDER2];
pDataBytes[2]=pDC->CB_Byte;
pDataBytes[3]=pDC->BB_Byte;
pDataBytes[4]=pDC->AB_Byte;
return 5;
} //TUN_GetBytes
/////////////////////////////////////////////////////////////////////////////
// TUN_SetBytes
//
// Inputs:
// void *Instance, points to device instance
// Data8* - pointer to values stored in apps buffer
// int - number of bytes
//
// Outputs:
// none
//
// Returns:
// int - 0 if success or NXT error
//
// Description:
// reads tunerConfig[controlbytes] from control SW and reprograms tuner
// with new data, according to the following steps:
// 1) Need to check and save data. Divider bytes to be discarded, since added
// in SetFrequency.
// 2) Commit first CB_Byte and BB_Byte, by calling SetFrequency. Make sure
// T2T1T0 is != 3. If ==3, then use default.
// 3) Commit AB_Byte. If T2T1T0 does not reflect, save previous value of T2T1T0,
// replace by 011, SetFrequency, restore value back and SetFrequency again.
//
int TUN_SetBytes(void* Instance, Data8* pDataBytes, Data8 DataLength)
{
TUN_Error_t returnValue = TUN_OTHER_ERROR;
Data8 transfertunerConfig[3], tempTestVal, i;
TUN_DC *pDC, *pDummy;
pDC = FindTunDC(Instance, &pDummy);
if (pDC == NULL_INSTANCE) return TUN_MEMORY_PB;
// recover data
for(i=2; i< DataLength; i++)
{
transfertunerConfig[i-2]=pDataBytes[i];
}
// 1) check and save data
// CB_Byte
SetChargePump(Instance, (bool) ((transfertunerConfig[0]>>6) & 0x01));
tempTestVal=(transfertunerConfig[0]>>3) & 0x07;
SetTestBits(Instance, tempTestVal);
SetRSBits(Instance, (transfertunerConfig[0]>>1) & 0x03);
SetOSBit(Instance, (bool) (transfertunerConfig[0] & 0x01));
// BB_Byte
pDC->BB_Byte=transfertunerConfig[1];
// AB_Byte
SetAgcTakeOver(Instance, (transfertunerConfig[2]>>4) & 0x07);
if(pDC->AB_Byte != 0xFF)
{ // TUA6034 only
SetATC(Instance, (bool) ((transfertunerConfig[2]>>7) & 0x01));
// SetAgcTakeOver(Instance, (transfertunerConfig[2]>>4) & 0x07);
// 2) + 3)
// program CB_Byte and BB_Byte first
if (tempTestVal==AB_MODE) SetTestBits(Instance, DEFAULT_TEST);
SetFrequency(Instance, pDC->frequency);
// program AB_Byte
SetTestBits(Instance, AB_MODE);
SetFrequency(Instance, pDC->frequency);
}
// CB_Byte contains correct value
SetTestBits(Instance, tempTestVal);
returnValue = SetFrequency(Instance, pDC->frequency);
return returnValue;
} //TUN_SetBytes
/////////////////////////////////////////////////////////////////////////////
// TUN_ReadStatus
//
// Inputs:
// void *Instance, points to device instance
//
// Outputs:
// Data8* pstatus_byte: pointer to status data
//
// Returns:
// none
//
// Description:
// reads status byte of Tuner
//
int TUN_ReadStatus(void* Instance, Data8* pstatus_byte)
{
TUN_DC *pDC, *pDummy;
pDC = FindTunDC(Instance, &pDummy);
if (pDC == NULL_INSTANCE) return TUN_MEMORY_PB;
if(!pDC->DirectAccess)
{
// through channel decoder
NxtIicXfer((void *)NULL,
NXT_IIC_READ,
NXT_IIC_SPEED_SLOWEST,
1,
pDC->IIC_Addr,
pstatus_byte);
//now we can read the data
NxtReadIicXferData((void *)NULL, 1, &pDC->Status_Byte);
pstatus_byte=&pDC->Status_Byte;
}
return TUN_OK;
}//TUN_ReadStatus
/////////////////////////////////////////////////////////////////////////////
// TUN_IOCTL
//
// Inputs:
// void *Instance, points to device instance
// int function, selects which IO function is required
// void *pInputs
//
// Outputs:
// void *pOutputs
//
// Returns:
// int - 0 if success, else non-zero
//
// Description:
// performs special functionality
//
int TUN_IOCTL(void* Instance, int function, void *pInputs, void *pOutputs)
{
TUN_Error_t retVal = TUN_OK;
TUN_DC *pDC, *pDummy;
pDC = FindTunDC(Instance, &pDummy);
if (pDC == NULL_INSTANCE) return TUN_MEMORY_PB;
switch (function) {
case TUN_GET_TUV1236D_FAT_AGC_DATA:
*((Data16**)pOutputs) = TUV1216D_FatAgcData;
break;
case TUN_SET_CHARGE_PUMP:
SetChargePump(Instance, pInputs!=0);
break;
case TUN_SELECT_INPUT:
SetInput(Instance, pInputs!=0);
break;
case TUN_GET_IIC_AD:
GetAddr(Instance, (Data8*) pOutputs);
break;
case TUN_SET_STANDARD:
SetStandard(Instance, (TUN_Standard_t*)pInputs);
break;
case TUN_MAP_FREQ_TO_CHAN:
MapFreqToChan(Instance, (double*)pInputs, (Data8*) pOutputs);
break;
case TUN_GET_FREQ:
GetFreq(Instance, (double*) pOutputs);
break;
case TUN_SET_MODE:
SetMode(Instance, pInputs!=0);
break;
default:
retVal = TUN_OTHER_ERROR;//TUN_NOT_SUPPORTED;
break;
}
return retVal;
} // TUN_IOCTL
/////////////////////////////////////////////////////////////////////////////
// TUN_GetLocked
//
// Inputs:
// void *Instance, points to device instance
// Bool *Locked, points to lock bit
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -