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

📄 drv_8722.c

📁 机顶盒解调芯片DCF8722驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
         break;
      
      case DCF872x_STEP_50000:
         /* TunerB[3] - xxxx xx0x b */
         pCFG->TunerB[3] = pCFG->TunerB[3] & 0xFD;
         pCFG->TunerREF = 50000;
         pCFG->TunerIFN = 720;   /* TunerIFN = TunerIF / TunerREF */
         break;
      
      case DCF872x_STEP_62500:
         /* TunerB[3] - xxxx x11x b */
         pCFG->TunerB[3] = pCFG->TunerB[3] | 0x06;
         pCFG->TunerREF = 62500;
         pCFG->TunerIFN = 576;   /* TunerIFN = TunerIF / TunerREF */
         break;
      
      default:
         /* TunerB[3] - xxxx x11x b */
         pCFG->TunerB[3] = pCFG->TunerB[3] | 0x06;
         pCFG->TunerREF = 62500;
         pCFG->TunerIFN = 576;   /* TunerIFN = TunerIF / TunerREF */
         break;
   }
   return (DRV_OK);
}

/*****************************************************************************/
/*  FUNCTION:    dcf872x_tuner_init                                          */
/*                                                                           */
/*  PARAMETERS:  pCFG - pointer to the CNIM_CFG structure                    */
/*                                                                           */
/*  DESCRIPTION: The function initialize the tuner part in THOMSON DCF872x.  */
/*                                                                           */
/*  RETURNS:     DRV_OK if successful, DRV_ERROR if unsuccessful.            */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
static DRV_RETURN dcf872x_tuner_init (CNIM_CFG *pCFG)
{
   /* set the tuner output IF in KHz - always 36 MHz */
   pCFG->TunerIF  = 36000;
   /* set the tuner bandwidth in Hz - always 8 MHz */
   pCFG->TunerBW  = 8000000;
   /* the tuner module is controlled by STV0297 i2c repeater */
   pCFG->TunerI2cRepeater = 1;
   /* set the tuner i2c address to 0xC0 */
   pCFG->TunerAddr = 0xC0;
   /* initialize the i2c control bytes for tuner */
   pCFG->TunerB[0] = pCFG->TunerAddr;  /* address byte, always */
   pCFG->TunerB[1] = 0x00;             /* prog. divider byte 1 */
   pCFG->TunerB[2] = 0x00;             /* prog. divider byte 2 */
   pCFG->TunerB[3] = 0x86;             /* control byte 1 */
   pCFG->TunerB[4] = 0x00;             /* control byte 2 */
   pCFG->TunerB[5] = 0x00;             /* readback byte  */
   /* set the tuner reference frequency (step) - 62500 Hz */
   dcf872x_tuner_set_step (pCFG, DCF872x_STEP_62500);
   /* set the tuner charge pump current - 50 uA */
   dcf872x_tuner_set_cp (pCFG, DCF872x_CP_50);
   return (DRV_OK);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*****************************************************************************/
/*  FUNCTION:    dcf872x_get_CNE                                             */
/*                                                                           */
/*  PARAMETERS:  uUnit  - the unit id of the unit to access.                 */
/*                                                                           */
/*  DESCRIPTION: The function gets the current C/N estimator.                */
/*                                                                           */
/*  RETURNS:     DRV_OK if successful, DRV_ERROR if unsuccessful.            */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
DRV_RETURN dcf872x_get_CNE (u_int32 uUnit)
{
   CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   u_int8      ui8Addr = pCNimCfg->DemodAddr;
   u_int16     ui16Temp;
   int32       i, iQ, iD;
   int32       iCurrentMean, iComputedMean, iOldMean;
   
   st0_get_qam_size (ui8Addr, (&pCNimCfg->DemodQAM));
   iQ = pCNimCfg->DemodQAM;
   
   /* Removed by steven shen. May 19th, 2004 */
   #if (0)
   /* if in MOD_QAMAUTO mode, update the current QAM mode of the tuning SPEC. */
   if (pCNimCfg->SignalQAM == MOD_QAMAUTO)
   {
      switch (iQ)
      {
         case ST0_QAM16:
            pCNimCfg->SignalQAM = MOD_QAM16;
            break;
         case ST0_QAM32:
            pCNimCfg->SignalQAM = MOD_QAM32;
            break;
         case ST0_QAM64:
            pCNimCfg->SignalQAM = MOD_QAM64;
            break;
         case ST0_QAM128:
            pCNimCfg->SignalQAM = MOD_QAM128;
            break;
         case ST0_QAM256:
            pCNimCfg->SignalQAM = MOD_QAM256;
            break;
         default:
            break;
      } /* endswitch (iQ) */
   } /* endif (pCNimCfg->SignalQAM == MOD_QAMAUTO) */
   #endif
   
   /*
    * the STV0297 noise estimation must be filtered. The used filter is:
    * Estimation(n) = 63/64*Estimation(n-1) + 1/64*NoiseEstimation
    */
   for (i=0; i<100; i++)
   {
      st0_get_noise_accumulator (ui8Addr, (&ui16Temp));
      pCNimCfg->DemodCNEmean = (pCNimCfg->DemodCNEmean * 63 + (int32)(ui16Temp)) >> 6;
   }
   
   iComputedMean = pCNimCfg->DemodCNEmean - pCNimCfg->DemodCNEoffset;
   iCurrentMean = gST0CN[iQ][0];
   iD = 1;
   while ( iD < 40 )
   {
      iOldMean = iCurrentMean;
      iCurrentMean = gST0CN[iQ][iD];
      if ( iCurrentMean <= iComputedMean )
      {
         break;
      }
      else
      {
         iD ++;
      }
   }
   pCNimCfg->DemodCNE = iD;
   return (DRV_OK);
}

/*****************************************************************************/
/*  FUNCTION:    dcf872x_set_bert                                            */
/*                                                                           */
/*  PARAMETERS:  uUnit  - the unit id of the unit to access.                 */
/*                                                                           */
/*  DESCRIPTION: The function sets the working mode of the integrated BERT.  */
/*                                                                           */
/*  RETURNS:     DRV_OK if successful, DRV_ERROR if unsuccessful.            */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
DRV_RETURN dcf872x_set_bert (u_int32 uUnit)
{
   CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   u_int8      ui8BERTmode = 0x00;
   u_int8      ui8Count;
   
   /* set the BERT source */
   pCNimCfg->DemodBERTsrc = (u_int8)ST0_BERT_BIT_SRC;
   if ( pCNimCfg->DemodBERTsrc == ST0_BERT_BYTE_SRC )
   {
      ui8BERTmode |= 0x10;
   }
   
   /* set the BERT stop mode */
   pCNimCfg->DemodBERTsp = (u_int8)ST0_BERT_AUTO_STOP;
   if ( pCNimCfg->DemodBERTsp == ST0_BERT_MANUAL_STOP )
   {
      ui8BERTmode |= 0x08;
   }
   
   /* set the final BERT working mode */
   pCNimCfg->DemodBERTmode = ui8BERTmode | (u_int8)ST0_BERT_NBYTE;
   
   /* calculate the number of bytes during which errors are to be detected. */
   ui8Count = ((u_int8)(ST0_BERT_NBYTE) << 1) + 12;
   pCNimCfg->DemodBERTnb = ((u_int32)(0x00000001) << ui8Count);
   
   /* clear the waiting flag */
   pCNimCfg->DemodBERTwait = 0;
   
   return (DRV_OK);
}

/*****************************************************************************/
/*  FUNCTION:    dcf872x_get_bert                                            */
/*                                                                           */
/*  PARAMETERS:  uUnit  - the unit id of the unit to access.                 */
/*                                                                           */
/*  DESCRIPTION: The function calculates the current BER.                    */
/*                                                                           */
/*  RETURNS:     DRV_OK if successful, DRV_ERROR if unsuccessful.            */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
DRV_RETURN dcf872x_get_bert (u_int32 uUnit)
{
   CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   u_int8      ui8Addr = pCNimCfg->DemodAddr;
   float       fError, fCount;
   
   if (pCNimCfg->DemodBERTwait == 0)
   {
      /* start the BERT */
      st0_start_bert (ui8Addr, pCNimCfg->DemodBERTmode);
      pCNimCfg->DemodBERTwait = 1;
   }
   else
   {
      /* check whether the BERT is stoped. */
      st0_get_bert_status (ui8Addr, &(pCNimCfg->DemodBERTst));
      if ( (pCNimCfg->DemodBERTst & 0x80) == 0x00 )
      {
         /* get the BER error counter */
         st0_get_bert_error (ui8Addr, &(pCNimCfg->DemodBERTerr));
         /* calculate the Bit Error Rate */
         fError = (float)(pCNimCfg->DemodBERTerr);
         fCount = (float)(pCNimCfg->DemodBERTnb);
         pCNimCfg->DemodBER = fError / fCount;
         pCNimCfg->DemodBERTwait = 0;
      }
   }
   return (DRV_OK);
}

DRV_RETURN dcf872x_get_strength (u_int32 uUnit)
{
   CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   u_int8      ui8Addr = pCNimCfg->DemodAddr;
   
   /* get the current WBAGC agc2sd value. */
   st0_wbagc_get_agc2sd (ui8Addr, &(pCNimCfg->Demodagc2sd));
   // debug_out (TL_INFO, "agc2sd = %d\n", pCNimCfg->Demodagc2sd);
   /* according to the WBAGC agc2sd value, to estimate the signal strength. */
   if (pCNimCfg->Demodagc2sd <= 460)         /* > 75 dBuV --- strong signal */
   {
      pCNimCfg->SignalStrength = 255;
   }
   else if (pCNimCfg->Demodagc2sd <= 520)    /* > 35 dBuV --- 255 to 75 */
   {
      pCNimCfg->SignalStrength = 255 - (pCNimCfg->Demodagc2sd - 460) * 3;
   }
   else if (pCNimCfg->Demodagc2sd < 670)     /* < 35 dBuV --- weak signal */
   {
      pCNimCfg->SignalStrength = 75 - (pCNimCfg->Demodagc2sd - 520) / 2;
   }
   else if (pCNimCfg->Demodagc2sd >= 670)    /* no signal or very weak signal */
   {
      pCNimCfg->SignalStrength = 0;
   }
   return (DRV_OK);
}

DRV_RETURN dcf872x_init_statics (u_int32 uUnit)
{
   CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   u_int8      ui8Addr = pCNimCfg->DemodAddr;
   
   /* initialize the block counts */
   pCNimCfg->DemodBlkCnt = 0;
   pCNimCfg->DemodCorrCnt = 0;
   pCNimCfg->DemodUncorrCnt = 0;
   /* start the block counts */
   st0_start_ct (ui8Addr);
   pCNimCfg->DemodCNE = 0;
   pCNimCfg->DemodBERTwait = 0;
   return (DRV_OK);
}


DRV_RETURN dcf872x_get_statics (u_int32 uUnit)
{
   //CNIM_CFG    *pCNimCfg = (CNIM_CFG *)(&gCNimCfg);
   //u_int8      ui8Addr = pCNimCfg->DemodAddr;
   
   //st0_get_blk_ct (ui8Addr, (&pCNimCfg->DemodBlkCnt));
   //st0_get_corr_ct (ui8Addr, (&pCNimCfg->DemodCorrCnt));
   //st0_get_uncorr_ct (ui8Addr, (&pCNimCfg->DemodUncorrCnt));
   //debug_out (TL_INFO, "   Received Block = %d\n", pCNimCfg->DemodBlkCnt);
   //debug_out (TL_INFO, "  Corrected Block = %d\n", pCNimCfg->DemodCorrCnt);
   //debug_out (TL_INFO, "Uncorrected Block = %d\n", pCNimCfg->DemodUncorrCnt);
   dcf872x_get_CNE (uUnit);
   dcf872x_get_bert (uUnit);
   //dcf872x_get_strength (uUnit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -