⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drx3973d.c

📁 用于DRX3973或DRX39系列的芯片的控制
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -