hamaro_cx24128.c

来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 1,877 行 · 第 1/5 页

C
1,877
字号


/*******************************************************************************************************
 * HAMARO_TUNER_CX24128_GetVcoStatus() 
 * reads tuner register to get the Vco edge detection status
 *******************************************************************************************************/
BOOL     
HAMARO_TUNER_CX24128_GetVcoStatus(HAMARO_NIM     *p_nim,         /* pointer to nim */
                           HAMARO_VCOSTATUS *p_vcostatus) /* pointer to the returned vco status. */
{
   unsigned char reg_value;
   HAMARO_VCOMODE       VcoMode;
   
   HAMARO_TUNER_CX24128_VALIDATE(p_nim);
   
   VcoMode = p_nim->tuner.cx24128.viperparms.VcoMode;
   
   switch(VcoMode)
   {
      case HAMARO_VCOMODE_AUTO:
      case HAMARO_VCOMODE_TEST:
      {
         /* read 0x17[0] */
         if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x17), (unsigned long*)&reg_value, HAMARO_IO_UNKNOWN) != True)  
            return(False);
         reg_value &= 0x01;
		 
         if (reg_value == 0x01UL)
         {
            *p_vcostatus = HAMARO_VCO_AUTO_FAIL;
         }
         else
         {
            *p_vcostatus = HAMARO_VCO_AUTO_DONE;
         }
         break;
      }
      default:
      {
         return(False);
         break;
      }
   }
   
   p_nim->tuner.cx24128.viperparms.VCOstatus = *p_vcostatus;
   
   return(True);
}/* HAMARO_TUNER_CX24128_GetVcoStatus() */

/*******************************************************************************************************
 * HAMARO_TUNER_CX24128_GetVcoStatus() 
 * reads tuner register to get the selected ICP level
 *******************************************************************************************************/
BOOL  
HAMARO_TUNER_CX24128_GetAnalogICPLevel(HAMARO_NIM *p_nim, HAMARO_ICPSELECT *p_icplevel)
{
   unsigned char reg_value;
   
   HAMARO_TUNER_CX24128_VALIDATE(p_nim);
   /* get the selected level from the tuner */
   /* read 0x12[1:0] */
   if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x12), (unsigned long*)&reg_value, HAMARO_IO_UNKNOWN) != True)  
      return(False);
   reg_value &= 0x03;
   
   if (reg_value == 0)
   {
      *p_icplevel = HAMARO_ICPSELECT_LEVEL1;
   }
   else
   {
      *p_icplevel = (HAMARO_ICPSELECT)reg_value;
   }
   
   p_nim->tuner.cx24128.viperparms.ICPselect = *p_icplevel;
   
   return(True);
}

/*******************************************************************************************************
 * HAMARO_TUNER_CX24128_GetPLLFrequency() 
 * returns current frequency. programmed into the tuner pll register 
 *******************************************************************************************************/
#if 0

BOOL HAMARO_TUNER_CX24128_GetPLLFrequency(HAMARO_NIM            *p_nim,     /* pointer to nim */
                              unsigned long  *p_pllfreq) /* pointer to unsigned long where pll frequency.*/ 
                                                         /* in Hz. will be returned */
{
   unsigned short nvalue; /* Returned N value */
   /*unsigned long*/int  fvalue; 
   signed long    fvalue_signed;
   unsigned long  Nfrac;
   HAMARO_RDIVVAL        R;
   HAMARO_VCODIV         vcodiv;
   
   HAMARO_BCDNO bcd;
   static sem_id_t semid= NULL;
   BOOL retValue = False;
   
   if   (semid == NULL)
   {
		semid = sem_create(1, "GetPLLFreSem");
		USPPrint(3, "GetPLLFreSem");
   }
   if (semid != NULL)
   {
 		sem_get(semid, KAL_WAIT_FOREVER);
   }

   /* test for valid nim */
   HAMARO_TUNER_CX24128_VALIDATE(p_nim);
   
   if (p_pllfreq == 0)
   {
      HAMARO_DRIVER_SET_ERROR(p_nim, HAMARO_BAD_PARM);
      goto extilabel;//return(False);
   }
   
   if (HAMARO_TUNER_CX24128_calc_pllNF(p_nim, &nvalue, &fvalue) == False )
   {
      goto extilabel;//return (False);
   }
   
   fvalue_signed = (signed long)(fvalue);
   
   R = p_nim->tuner.cx24128.R;
   vcodiv = p_nim->tuner.cx24128.vcodiv;
   
   /* catch any div by zero errors */
   if ((R != 0UL) && (vcodiv != 0UL))
   {
      /*
      The frequency can be calculated from the crystal frequency and divider settings as follows:
      
      FLO = [2 * Nfrac * (Fxtal/R)]/D
      
      ,where R = reference divider setting (either 1 or 2)
      D = LO divider setting (either 2 or 4)
      Fxtal = actual crystal frequency
      Nfrac = total fractional divide ratio and can be calculated from
      Nfrac = (Dividend/262144) + Nreg + 32
      
      where, Dividend = DSM setting 18-bit signed value (between +/-131072)
      Nreg = 9-bit divider setting
      */
      /* multiplication factor of 10000 is used to improve precision */
      Nfrac = ( (fvalue_signed * 10000L) / HAMARO_CX24128_DIVIDER) + (nvalue * 10000UL) + (32UL * 10000UL);
      HAMARO_BCD_set (&bcd, (p_nim->tuner_crystal_freq / R));
      HAMARO_BCD_mult(&bcd, Nfrac);
      HAMARO_BCD_mult(&bcd, 2);
      HAMARO_BCD_div (&bcd, 10000);
      HAMARO_BCD_div (&bcd, vcodiv);
      
      if ((p_nim->tuner_crystal_freq) / HAMARO_MM >= 20)
      {
         HAMARO_BCD_mult(&bcd, 2);
      }
      *p_pllfreq = HAMARO_BCD_out(&bcd); 
      retValue = True;
   }
   else
   {
      HAMARO_DRIVER_SET_ERROR(p_nim,HAMARO_BAD_DIV);
      retValue = False;
   }
extilabel:
   if (semid != NULL)
   {
 	sem_put(semid);
   }
   return (retValue);
}/* HAMARO_TUNER_CX24128_GetPLLFrequency() */

#else
BOOL           
HAMARO_TUNER_CX24128_GetPLLFrequency(HAMARO_NIM            *p_nim,     /* pointer to nim */
                              unsigned long  *p_pllfreq) /* pointer to unsigned long where pll frequency.*/ 
                                                         /* in Hz. will be returned */
{
   unsigned short nvalue; /* Returned N value */
   /*unsigned long*/int  fvalue; 
   signed long    fvalue_signed;
   unsigned long  Nfrac;
   HAMARO_RDIVVAL        R;
   HAMARO_VCODIV         vcodiv;
   
   HAMARO_BCDNO bcd;
   
   /* test for valid nim */
   HAMARO_TUNER_CX24128_VALIDATE(p_nim);
   
   if (p_pllfreq == 0)
   {
      HAMARO_DRIVER_SET_ERROR(p_nim, HAMARO_BAD_PARM);
      return(False);
   }
   
   if (HAMARO_TUNER_CX24128_calc_pllNF(p_nim, &nvalue, &fvalue) == False )
   {
      return (False);
   }
   
   fvalue_signed = (signed long)(fvalue);
   
   R = p_nim->tuner.cx24128.R;
   vcodiv = p_nim->tuner.cx24128.vcodiv;
   
   /* catch any div by zero errors */
   if ((R != 0UL) && (vcodiv != 0UL))
   {
      /*
      The frequency can be calculated from the crystal frequency and divider settings as follows:
      
      FLO = [2 * Nfrac * (Fxtal/R)]/D
      
      ,where R = reference divider setting (either 1 or 2)
      D = LO divider setting (either 2 or 4)
      Fxtal = actual crystal frequency
      Nfrac = total fractional divide ratio and can be calculated from
      Nfrac = (Dividend/262144) + Nreg + 32
      
      where, Dividend = DSM setting 18-bit signed value (between +/-131072)
      Nreg = 9-bit divider setting
      */
      /* multiplication factor of 10000 is used to improve precision */
      Nfrac = ( (fvalue_signed * 10000L) / HAMARO_CX24128_DIVIDER) + (nvalue * 10000UL) + (32UL * 10000UL);
      HAMARO_BCD_set (&bcd, (p_nim->tuner_crystal_freq / R));
      HAMARO_BCD_mult(&bcd, Nfrac);
      HAMARO_BCD_mult(&bcd, 2);
      HAMARO_BCD_div (&bcd, 10000);
      HAMARO_BCD_div (&bcd, vcodiv);
      
      if ((p_nim->tuner_crystal_freq) / HAMARO_MM >= 20)
      {
         HAMARO_BCD_mult(&bcd, 2);
      }
      *p_pllfreq = HAMARO_BCD_out(&bcd); 
   }
   else
   {
      HAMARO_DRIVER_SET_ERROR(p_nim,HAMARO_BAD_DIV);
      return(False);
   }
   return(True);
}/* HAMARO_TUNER_CX24128_GetPLLFrequency() */
#endif
/*******************************************************************************************************
 * HAMARO_TUNER_CX24128_pll_status
 * reads current tuner pll lock status 
 *******************************************************************************************************/
BOOL  
HAMARO_TUNER_CX24128_pll_status(HAMARO_NIM  *p_nim,    /* nim pointer */
                               BOOL       *p_locked) /* BOOL pointer, where tuner pll lock status is returned */
{
   unsigned char  reg_value = 0;
   
   if(HAMARO_CX24128_refresh_tuner_pll_lock == True)
   {
      /* read the tuner register to get tuner pll lock status */
      /* read 0x10[1] */
      if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x10), (unsigned long*)&reg_value, HAMARO_IO_UNKNOWN) != True)  
      {
         return(False);
      }
      reg_value &= 0x02;
      if (reg_value == 0x00)  
      {
         *p_locked = False;
         HAMARO_CX24128_tuner_pll_lock = False;
      }
      else  
      {
         *p_locked = True;
         HAMARO_CX24128_tuner_pll_lock = True;
      }
      HAMARO_CX24128_refresh_tuner_pll_lock = False;
   
   }
   else
   {		
      *p_locked = HAMARO_CX24128_tuner_pll_lock;
   }
   
   return(True);
}  /* HAMARO_TUNER_CX24128_pll_status() */

/*******************************************************************************************************
 * HAMARO_TUNER_CX24128_calc_pllNF()  
 * function to calc pll settings (n,f) using bcd functions.
 * input is the specified pll frequency, output is N, F values to be set
 * to tuner and nim.
 *******************************************************************************************************/
BOOL 
HAMARO_TUNER_CX24128_calc_pllNF(HAMARO_NIM *p_nim,        /* nim pointer */
                         unsigned short *nvalue, /* Returned N value. */
                         int  *fvalue) /* Returned F value. */
{
   long           N;
   long           F;
   HAMARO_RDIVVAL        R;
   HAMARO_VCODIV         vcodiv;
   HAMARO_BCDNO          bcd;
   unsigned char  factor;
   unsigned char reg_value;
   
   /* set frequency to a default setting, if not presently set, test xtal for zero before divide. */
   if (p_nim->pll_frequency == 0UL)  p_nim->pll_frequency = HAMARO_NIM_DEFAULT_FREQ;
   if (p_nim->tuner_crystal_freq == 0UL)  p_nim->tuner_crystal_freq = HAMARO_NIM_DEFAULT_XTAL;
   
   if ((p_nim->tuner_crystal_freq) /HAMARO_MM < 20)
   {
      factor = 1;
   }
   else
   {
      factor = 2;
   }
   
   /* Set lo divider to tuner and nim. */
   if (((p_nim->pll_frequency) / HAMARO_MM) >= HAMARO_CX24128_LO_DIV_BREAKPOINT)
   {
      vcodiv = HAMARO_VCODIV2;
      if (HAMARO_TUNER_CX24128_SetVcoDivider(p_nim,vcodiv) != True) return(False);
   }
   else
   {
      vcodiv = HAMARO_VCODIV4;
      if (HAMARO_TUNER_CX24128_SetVcoDivider(p_nim,vcodiv) != True) 
         return(False);
   }
   
   /* Set reference divider to nim. */
   HAMARO_TUNER_CX24128_SetReferenceDivider(p_nim,HAMARO_RDIV_1);
   
   R = p_nim->tuner.cx24128.R;
   
   /* calculate tuner PLL settings: */
   /* Calculate N first. No need to use BCD functions. */  
   N = (p_nim->pll_frequency / 100UL * vcodiv) * R;
   N /= ((p_nim->tuner_crystal_freq /HAMARO_M * factor) * 2UL);
   N += 5UL;     /* For round up. */
   N /= 10UL;
   N -= 32UL;
   
   /* N has to be >= than 8. */
   if (N < 8)
   {
      /* Set reference divider to nim. */
      HAMARO_TUNER_CX24128_SetReferenceDivider(p_nim,HAMARO_RDIV_2);
      
      R = p_nim->tuner.cx24128.R;
      
      /* Calculate N again. No need to use BCD functions. */  
      N = (p_nim->pll_frequency * vcodiv / 100UL) * R;
      N /= ((p_nim->tuner_crystal_freq * factor / HAMARO_M) * 2UL);
      N += 5UL;     /* For round up. */
      N /= 10UL;
      N -= 32UL;
      
      if (N < 8)
      {
         return(False);
      }
   }
   
   /* Now calculate F. */
   HAMARO_BCD_set(&bcd,p_nim->pll_frequency);
   HAMARO_BCD_mult(&bcd,((unsigned long)R * (unsigned long)vcodiv * HAMARO_CX24128_DIVIDER));
   HAMARO_BCD_div(&bcd,(p_nim->tuner_crystal_freq * factor * 2UL));
   F = HAMARO_BCD_out(&bcd);
   F -= (N + 32) * HAMARO_CX24128_DIVIDER;
   

⌨️ 快捷键说明

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