📄 drx3973d.c
字号:
static
DRXStatus_t AtomicReadBlock (
pI2CDeviceAddr_t devAddr,
DRXaddr_t addr,
u16_t datasize,
pu8_t data,
DRXflags_t flags)
{
DRX3973DHiCmd_t hiCmd;
u16_t dummy=0;
u16_t i=0;
/* Parameter check */
if ( ( data == NULL ) ||
( devAddr == NULL ) ||
( (datasize%2)!=0 )
)
{
return (DRX_STS_INVALID_ARG);
}
/* Instruct HI to read n bytes */
hiCmd.cmd = HI_RA_RAM_SRV_CMD_EXECUTE;
hiCmd.param1 = (u16_t) (HI_TR_FUNC_ADDR & 0xFFFF);
hiCmd.param2 = (u16_t)(addr >> 16);
hiCmd.param3 = (u16_t)(addr & 0xFFFF);
hiCmd.param4 = (u16_t)((datasize/2) - 1);
hiCmd.param5 = HI_TR_READ;
CHK_ERROR( HI_Command( devAddr, &hiCmd, &dummy) );
for (i = 0; i < (datasize/2); i++)
{
u16_t word;
RR16 (devAddr, (HI_RA_RAM_USR_BEGIN__A + i), &word, 0);
data[2*i] = (u8_t) (word & 0xFF);
data[(2*i) + 1] = (u8_t) (word >> 8 );
}
return DRX_STS_OK;
rw_error:
return (DRX_STS_ERROR);
}
/*============================================================================*/
/**
* \fn DRXStatus_t AtomicReadReg32()
* \brief Atomic read of 32 bits words
*/
static
DRXStatus_t AtomicReadReg32 (
pI2CDeviceAddr_t devAddr,
DRXaddr_t addr,
pu32_t data,
DRXflags_t flags)
{
u8_t buf[sizeof (*data)];
DRXStatus_t rc = DRX_STS_ERROR;
u32_t word = 0;
if (!data)
{
return DRX_STS_INVALID_ARG;
}
rc = AtomicReadBlock (devAddr, addr, sizeof (*data), buf, flags);
word = (u32_t)buf[3];
word <<= 8;
word |= (u32_t)buf[2];
word <<= 8;
word |= (u32_t)buf[1];
word <<= 8;
word |= (u32_t)buf[0];
*data = word;
return rc;
}
/*============================================================================*/
#if 0
/**
* \fn DRXStatus_t TunetI2CWriteRead()
* \brief I2C communication for tuner via micro
*/
DRXStatus_t TunerI2CWriteRead( pTUNERInstance_t tuner,
pI2CDeviceAddr_t wDevAddr,
u16_t wCount,
pu8_t wData,
pI2CDeviceAddr_t rDevAddr,
u16_t rCount,
pu8_t rData)
{
pDRXDemodInstance_t demod;
DRXI2CData_t i2cData = { 1, wDevAddr, wCount, wData, rDevAddr, rCount, rData };
demod = (pDRXDemodInstance_t) (tuner->myCommonAttr->myUserData);
return ( DRX_Ctrl( demod, DRX_CTRL_I2C_READWRITE, &i2cData ) );
}
#endif
/*=============================================================================
===== Reset related funtions ================================================
===========================================================================*/
/**
* \fn DRXStatus_t StopAllProcessors( const pI2CDeviceAddr_t devAddr )
* \brief Stop all processors except the HI.
* \param devAddr pointer to device address.
* \return DRXStatus_t Return status.
*/
static DRXStatus_t
StopAllProcessors( const pI2CDeviceAddr_t devAddr )
{
/* Do not stop HI controller!
Otherwise there will be no communication with the device */
/* Do inverse broadcast, write to all blocks except the HI block
and CC block */
BCWR16( devAddr, HI_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP );
return (DRX_STS_OK);
rw_error:
return (DRX_STS_ERROR);
}
/*============================================================================*/
/**
* \fn DRXStatus_t EnableAndResetMB( const pI2CDeviceAddr_t devAddr )
* \brief Enable and reset monitor bus.
* \param devAddr pointer to device address.
* \return DRXStatus_t Return status.
*/
static DRXStatus_t
EnableAndResetMB( const pI2CDeviceAddr_t devAddr )
{
#if (DRXD_TYPE_A)
/* disable? monitor bus observe @ EC_OC */
WR16( devAddr, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
#endif
/* Do inverse broadcast, followed by explicit write to HI */
BCWR16( devAddr, HI_COMM_MB__A, 0x0000 );
WR16( devAddr, HI_COMM_MB__A, 0x0000, 0x0000);
return (DRX_STS_OK);
rw_error:
return (DRX_STS_ERROR);
}
/*============================================================================*/
/**
* \fn DRXStatus_t ResetCE_FR( const pI2CDeviceAddr_t devAddr )
* \brief Reset CE FR.
* \param devAddr pointer to device address.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Success.
* \retval DRX_STS_ERROR Failure.
*
* Due to bug in HW the default values of these registers have
* to be programmed by the host.
*
*/
#if (DRXD_TYPE_A)
static DRXStatus_t
ResetCEFR( const pI2CDeviceAddr_t devAddr )
{
static u8_t resetData[] =
{ 0x52,0x00, /* CE_REG_FR_TREAL00__A */
0x00,0x00, /* CE_REG_FR_TIMAG00__A */
0x52,0x00, /* CE_REG_FR_TREAL01__A */
0x00,0x00, /* CE_REG_FR_TIMAG01__A */
0x52,0x00, /* CE_REG_FR_TREAL02__A */
0x00,0x00, /* CE_REG_FR_TIMAG02__A */
0x52,0x00, /* CE_REG_FR_TREAL03__A */
0x00,0x00, /* CE_REG_FR_TIMAG03__A */
0x52,0x00, /* CE_REG_FR_TREAL04__A */
0x00,0x00, /* CE_REG_FR_TIMAG04__A */
0x52,0x00, /* CE_REG_FR_TREAL05__A */
0x00,0x00, /* CE_REG_FR_TIMAG05__A */
0x52,0x00, /* CE_REG_FR_TREAL06__A */
0x00,0x00, /* CE_REG_FR_TIMAG06__A */
0x52,0x00, /* CE_REG_FR_TREAL07__A */
0x00,0x00, /* CE_REG_FR_TIMAG07__A */
0x52,0x00, /* CE_REG_FR_TREAL08__A */
0x00,0x00, /* CE_REG_FR_TIMAG08__A */
0x52,0x00, /* CE_REG_FR_TREAL09__A */
0x00,0x00, /* CE_REG_FR_TIMAG09__A */
0x52,0x00, /* CE_REG_FR_TREAL10__A */
0x00,0x00, /* CE_REG_FR_TIMAG10__A */
0x52,0x00, /* CE_REG_FR_TREAL11__A */
0x00,0x00, /* CE_REG_FR_TIMAG11__A */
0x52,0x00, /* CE_REG_FR_MID_TAP__A */
0x0B,0x00, /* CE_REG_FR_SQS_G00__A */
0x0B,0x00, /* CE_REG_FR_SQS_G01__A */
0x0B,0x00, /* CE_REG_FR_SQS_G02__A */
0x0B,0x00, /* CE_REG_FR_SQS_G03__A */
0x0B,0x00, /* CE_REG_FR_SQS_G04__A */
0x0B,0x00, /* CE_REG_FR_SQS_G05__A */
0x0B,0x00, /* CE_REG_FR_SQS_G06__A */
0x0B,0x00, /* CE_REG_FR_SQS_G07__A */
0x0B,0x00, /* CE_REG_FR_SQS_G08__A */
0x0B,0x00, /* CE_REG_FR_SQS_G09__A */
0x0B,0x00, /* CE_REG_FR_SQS_G10__A */
0x0B,0x00, /* CE_REG_FR_SQS_G11__A */
0x0B,0x00, /* CE_REG_FR_SQS_G12__A */
0xFF,0x01, /* CE_REG_FR_RIO_G00__A */
0x90,0x01, /* CE_REG_FR_RIO_G01__A */
0x0B,0x01, /* CE_REG_FR_RIO_G02__A */
0xC8,0x00, /* CE_REG_FR_RIO_G03__A */
0xA0,0x00, /* CE_REG_FR_RIO_G04__A */
0x85,0x00, /* CE_REG_FR_RIO_G05__A */
0x72,0x00, /* CE_REG_FR_RIO_G06__A */
0x64,0x00, /* CE_REG_FR_RIO_G07__A */
0x59,0x00, /* CE_REG_FR_RIO_G08__A */
0x50,0x00, /* CE_REG_FR_RIO_G09__A */
0x49,0x00, /* CE_REG_FR_RIO_G10__A */
0x10,0x00, /* CE_REG_FR_MODE__A */
0x78,0x00, /* CE_REG_FR_SQS_TRH__A */
0x00,0x00, /* CE_REG_FR_RIO_GAIN__A */
0x00,0x02, /* CE_REG_FR_BYPASS__A */
0x0D,0x00, /* CE_REG_FR_PM_SET__A */
0x07,0x00, /* CE_REG_FR_ERR_SH__A */
0x04,0x00, /* CE_REG_FR_MAN_SH__A */
0x06,0x00 /* CE_REG_FR_TAP_SH__A */
};
WRBLOCK( devAddr, CE_REG_FR_TREAL00__A, sizeof(resetData), resetData );
return (DRX_STS_OK);
rw_error:
return (DRX_STS_ERROR);
}
#endif /* DRXD_TYPE_A */
/*============================================================================*/
/**
* \fn DRXStatus_t SetDeviceTypeId( const pDRXDemodInstance_t demod )
* \brief Determine and set typeId of device.
* \param demod pointer to demod instance.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Success.
* \retval DRX_STS_ERROR Failure.
*
*/
static DRXStatus_t
SetDeviceTypeId( const pDRXDemodInstance_t demod )
{
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
u16_t deviceId = 0 ;
DRXStatus_t status = DRX_STS_OK;
RR16( devAddr, CC_REG_JTAGID_L__A , &deviceId, 0x0000);
if ( deviceId == 0 )
{
/* DRXD_TYPE_A , DRX3975D only type available */
demod->myDemodFunct->typeId = DRX3975D_TYPE_ID;
} else {
/* DRXD_TYPE_B */
deviceId = deviceId >> 12;
switch ( deviceId )
{
case 3 :
demod->myDemodFunct->typeId = DRX3973D_TYPE_ID;
break;
case 4 :
demod->myDemodFunct->typeId = DRX3974D_TYPE_ID;
break;
case 5 :
demod->myDemodFunct->typeId = DRX3975D_TYPE_ID;
break;
case 6 :
demod->myDemodFunct->typeId = DRX3976D_TYPE_ID;
break;
case 7 :
demod->myDemodFunct->typeId = DRX3977D_TYPE_ID;
break;
case 8 :
demod->myDemodFunct->typeId = DRX3978D_TYPE_ID;
break;
default:
demod->myDemodFunct->typeId = 0;
status = DRX_STS_ERROR;
break;
} /* switch */
} /* if */
return (status);
rw_error:
return (DRX_STS_ERROR);
}
/*============================================================================*/
/**
* \fn DRXStatus_t InitCC( const pDRXDemodInstance_t demod )
* \brief Initialize clock controler
* \param demod pointer to demod data.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Success.
* \retval DRX_STS_ERROR Failure.
*
* Two pads are available for clock input.
* Only one pad is bounded to XI and XO pins.
* Both pads can form, together with an external Xtal, an Xtal oscillator.
* One pad can do this with an Xtal from 4 upto 20 MHz. This is prefered.
* Another pad can do this with an Xtal of 48 Mhz. This needs different bounding
* and a metal change. Only needed if to other solution fails.
* Both pads can accept a signal from an external oscillator from at least 4 MHz
* upto 48 MHz.
*/
static DRXStatus_t
InitCC( const pDRXDemodInstance_t demod )
{
const DRXFrequency_t divider_base = 4000;
u16_t divider = 0;
#ifndef COMPILE_FOR_QT
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
#endif
DRXFrequency_t oscFreq = demod->myCommonAttr->oscClockFreq;
pDRX3973DData_t extAttr= (pDRX3973DData_t) demod -> myExtAttr;
/* compute clock divider */
divider = (u16_t) (oscFreq/divider_base);
/* handle non 4-fold clocks, asymetric tolerance range:
approx. -1.4 Mhz ... +3.2Mhz */
if ( oscFreq%divider_base > 2600 )
{
divider++;
}
if ( divider > CC_REG_REF_DIVIDE_D10 )
{
if ( oscFreq%divider_base > 3200 )
{
/* out of range */
return (DRX_STS_ERROR);
} else {
/* still within upper tolerance range */
divider--;
}
}
(extAttr->expectedSysClockFreq) = oscFreq*12/divider;
/* rounding */
if ( (2*((oscFreq*12)%divider)) > divider )
{
(extAttr->expectedSysClockFreq)++;
}
if(oscFreq == 48000)
{
(extAttr->expectedSysClockFreq) = oscFreq;
}
#ifndef COMPILE_FOR_QT
/* 4-20 MHz pad */
WR16( devAddr, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0x0000);
if ( oscFreq != 48000 )
{
/* active PLL, pump=1.2, outen = 0 */
WR16( devAddr, CC_REG_PLL_MODE__A, ( CC_REG_PLL_MODE_BYPASS_PLL |
CC_REG_PLL_MODE_PUMP_CUR_12 ) , 0);
/* clock divider */
WR16( devAddr, CC_REG_REF_DIVIDE__A, divider, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -