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

📄 cx24108_tuner.c

📁 QPSK Tuner details, for conexant chipset.
💻 C
📖 第 1 页 / 共 5 页
字号:

  /* init the tuner vco_edge struct for div4 values: vc06/d4, vc07/d4, vc08/d4 */
  nim->tuner.cx24108.vco_edge[VCO6D4].lower = nim->tuner.cx24108.vco_edge[VCO6D2].lower/2UL;
  nim->tuner.cx24108.vco_edge[VCO6D4].upperthresh = nim->tuner.cx24108.vco_edge[VCO6D2].upperthresh/2UL;

  nim->tuner.cx24108.vco_edge[VCO7D4].lower = nim->tuner.cx24108.vco_edge[VCO7D2].lower/2UL;
  nim->tuner.cx24108.vco_edge[VCO7D4].upperthresh = nim->tuner.cx24108.vco_edge[VCO7D2].upperthresh/2UL;

  nim->tuner.cx24108.vco_edge[VCO8D4].lower = max((1019UL*M),(nim->tuner.cx24108.vco_edge[VCO8D2].lower/2UL));
  nim->tuner.cx24108.vco_edge[VCO8D4].upperthresh = max((1075UL*M),(nim->tuner.cx24108.vco_edge[VCO8D2].upperthresh/2UL));

  /* set all frequencies into Hz from khz */
  for (i = (int)VCO1D2 ; i < (int)VCO8D4+1 ; i++)
  {
    nim->tuner.cx24108.vco_edge[i].lower *= M;
    nim->tuner.cx24108.vco_edge[i].upperthresh *= M;

    /* determine the estimated vco lengths, used in vco high-edge calculations (these vco lengths should hold ~ True) */
    nim->tuner.cx24108.vco_len[i] = (nim->tuner.cx24108.vco_edge[i].upperthresh - nim->tuner.cx24108.vco_edge[i].lower);
  }

  /* adjust pre-set vco's if below 2150/2 */
  _TUNER_CX24108_adjust(nim);

  /* init the tuner breakpoint structure */
  for (i = 0 ; i < CX24108_BPCNT ; i++)  
    nim->tuner.cx24108.vco_bp[i].percentage = (int)nim->tuner.cx24108.BPPercentage;

  /* recalculate breakpoints */
  _TUNER_CX24108_calc_bp(nim);

  /* configure the tuner I/O interface with default settings */
  _TUNER_CX24108_defaultsettings(nim);

  return;

}  /* _TUNER_CX24108_initialize() */
#endif

/*******************************************************************************************************/
/* _TUNER_CX24108_setgainparms() */
/*******************************************************************************************************/
BOOL        _TUNER_CX24108_setgainparms(  /* copies caller's TUNERPARMS struct into nim */
NIM         *nim,                         /* nim pointer */
TUNERPARMS  *tunerparms)                  /* caller's TUNERPARMS struct that will overwrite nim's struct */
{
  /* copy caller's tunerparms settings into nim */  
  if (tunerparms != NULL)
  {
    memcpy(&nim->tuner.cx24108.tunerparms,tunerparms,sizeof(TUNERPARMS));
    return(True);
  }

  DRIVER_SetError(nim,API_BAD_PARM);
  return(False);

}  /* _Tuner_CX24108_setgainparms() */


/*******************************************************************************************************/
/* _TUNER_CX24108_band_info() */
/*******************************************************************************************************/
BOOL           _TUNER_CX24108_band_info(    /* function to calc and return band-select prog bits to caller */
NIM            *nim,                        /* pointer to nim */
ULONG  Fr,                          /* Fr (Freq. Receive) input */
DWORD   *bandbin,                    /* binary bits to program band-select for Fr */
DWORD   *vcodivbin,                  /* binary bit to program vco divider in band-select for Fr */
VCOSET         *vcoset,                     /* vco chosen for Fr */
VCODIV         *vcodiv,                     /* vco divider chosen for Fr */
VCONO          *vcono,                      /* vco number chosen (always 1..8) */
ULONG  *tunpll)                     /* calculated generic tuner pll programming setting */
{
  int  i;
  int  j;
  int  start_pt;

  ULONG  vco_len;
  ULONG  srm;

  static VCONO  _vcono[] =  {(UCHAR)VCO1D2,(UCHAR)VCO2D2,(UCHAR)VCO3D2,(UCHAR)VCO4D2,(UCHAR)VCO5D2,(UCHAR)VCO6D2,
                             (UCHAR)VCO7D2,(UCHAR)VCO8D2,(UCHAR)VCO6D2,(UCHAR)VCO7D2,(UCHAR)VCO8D2};

  static VCONO  _vcosearchorder[] =
                            {(UCHAR)VCO1D2,(UCHAR)VCO2D2,(UCHAR)VCO3D2,(UCHAR)VCO4D2,
                             (UCHAR)VCO5D2,(UCHAR)VCO6D2,(UCHAR)VCO7D2,(UCHAR)VCO8D2,
                             (UCHAR)VCO8D4,(UCHAR)VCO7D4,(UCHAR)VCO6D4};

  static VCOSET _vcoset[] = {VCO1D2,VCO2D2,VCO3D2,VCO4D2,VCO5D2,VCO6D2,VCO7D2,VCO8D2,VCO6D4,VCO7D4,VCO8D4};
  static VCODIV _vcodiv[] = {VCODIV2,VCODIV2,VCODIV2,VCODIV2,VCODIV2,VCODIV2,VCODIV2,VCODIV2,VCODIV4,VCODIV4,VCODIV4};

  static DWORD   _bandbin[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x20,0x40,0x80};
  static int    _vcodivbin[] = {-1,-1,1,-1,0};  /* 2=0x01, 4=0x00 */

  /* set the starting search pt.  If div/4, then start at the div/4 vcos */
  start_pt = CX24108_START_DIV2;
  if (nim->tuner.cx24108.vcodiv == VCODIV4)  start_pt = CX24108_START_DIV4;

  /* step through each VCO, examine for a valid VCO edge, if edge is not valid, generate a warning */
  for (j = 0 ; j < CX24108_VCOEDGES ; j++)
  {
    ULONG  Fl = nim->tuner.cx24108.vco_edge[j].lower;
    ULONG  Fh = nim->tuner.cx24108.vco_edge[j].upperthresh;

    if (Fl <= MAX_TUNER_VCOERROR || Fh <= MAX_TUNER_VCOERROR)
    {
      /* an invalid VCO edge was detected, flag as warning, then continue */
      DRIVER_SetError(nim,API_TUNERVCO);
    }
  }

  /* match Fr to vco edges, using high and low breakpoints, not actual edges */
  for (j = start_pt ; j < CX24108_VCOEDGES ; j++)
  {
    /* find a VCO by looking into 1/2 .. 8/2, then 8/4, 8/4, 6/4 vcos */
    i = _vcosearchorder[j];  /* remove this line if vco search s/b 1/2..8/2,6/4..8/4 */

    if (_TUNER_CX24108_vco_range(nim,Fr,i) == True)
    {
      int  idx;

      /* grab vcoset, vcodiv, return to caller */
      *vcono = (VCONO)(_vcono[i]+1);           /* returns VCO number before divider is set */
      *vcoset = _vcoset[i];                    /* returns actual VCOSET enum value */
      *vcodiv = _vcodiv[i];                    /* vco divider */
      *bandbin = _bandbin[i];                  /* band sel prog'd directly to cx24108 */
      *vcodivbin = (DWORD)_vcodivbin[*vcodiv];  /* vcodiv prog'd directly to cx24108 */
      *tunpll = 0UL;

      /* compute current vco length */
      vco_len = nim->tuner.cx24108.vco_edge[i].upperthresh - nim->tuner.cx24108.vco_edge[i].lower;
     
      /* set cpc default current to mid level */
      nim->tuner.cx24108.CPCCurrent = (int)nim->tuner.cx24108.tunerparms.CPC[_vcono[*vcoset]].mid;

      /* is fr in lower percentage area (defined by tunerparms.low percentage)? */
      if (Fr < (nim->tuner.cx24108.vco_edge[i].lower+
         ((vco_len/100UL)*nim->tuner.cx24108.tunerparms.CPC[_vcono[*vcoset]].LowPercentage)))
      {
        nim->tuner.cx24108.CPCCurrent = (int)nim->tuner.cx24108.tunerparms.CPC[_vcono[*vcoset]].low;
      }
      else
      {
        if (Fr >= (nim->tuner.cx24108.vco_edge[i].lower+
           ((vco_len/100UL)*nim->tuner.cx24108.tunerparms.CPC[_vcono[*vcoset]].HighPercentage)))
        {
          nim->tuner.cx24108.CPCCurrent = (int)nim->tuner.cx24108.tunerparms.CPC[_vcono[*vcoset]].high;
        }
      }

      /* save tuner slope data into rosie (current settings) */
      idx = 0;
      srm = MM;
      if (nim->symbol_rate < MM)  srm = M;  
      if (nim->symbol_rate >= (1UL*srm) && nim->symbol_rate <= (5UL*srm))  idx = CX24108_MSPS_1_TO_5;
      else  if (nim->symbol_rate >= (5UL*srm) && nim->symbol_rate <= (15UL*srm))  idx = CX24108_MSPS_5_TO_15;
      else  if (nim->symbol_rate >= (15UL*srm) && nim->symbol_rate <= (45UL*srm))  idx = CX24108_MSPS_15_TO_45;
      
      nim->tuner.cx24108.VCASlope = nim->tuner.cx24108.tunerparms.SLP[idx].VCASlope;
      nim->tuner.cx24108.VCAOffset = nim->tuner.cx24108.tunerparms.SLP[idx].VCAOffset;
      nim->tuner.cx24108.VGA1Offset = nim->tuner.cx24108.tunerparms.SLP[idx].VGA1Offset;
      nim->tuner.cx24108.VGA2Offset = nim->tuner.cx24108.tunerparms.SLP[idx].VGA2Offset;
      return(True);
    }
  }

  /* this error number is set if a valid freq can not be found within the present VCO edges. */
  /* (default VCO edges might have been used) */
  DRIVER_SetError(nim,API_TUNERVCO);
  return(False);

}  /* _TUNER_CX24108_band_info() */


/*******************************************************************************************************/
/* _TUNER_CX24108_vco_range() */
/*******************************************************************************************************/
BOOL           _TUNER_CX24108_vco_range(       /* function to test if Freq. requested is within vcoidx bounds */
NIM            *nim,                           /* pointer to nim */
ULONG  Fr,                             /* frequency requested */
int            vcoidx)                         /* vco index */
{
  ULONG  Ft;           /* Freq-test */
  ULONG  Fl = nim->tuner.cx24108.vco_edge[vcoidx].lower;
  ULONG  Fh = nim->tuner.cx24108.vco_edge[vcoidx].upperthresh;

  if (Fr >= Fl && Fr <= Fh)
  {
    /* test Fr against valid low range */
    Ft = _TUNER_CX24108_vco_low(nim,vcoidx);
    if (Fr < Ft)  return(False);
    
    Ft = _TUNER_CX24108_vco_high(nim,vcoidx);
    if (Fr > Ft)  return(False);
    return(True);
  }

  return(False);

}  /* _TUNER_CX24108_vco_range() */


/*******************************************************************************************************/
/* _TUNER_CX24108_vco_low() */
/*******************************************************************************************************/
ULONG  _TUNER_CX24108_vco_low( /* function to return Fr low range based on vcoidx */
NIM            *nim,                   /* pointer to nim */
int            vcoidx)                 /* vco index */
{
  if (vcoidx >= 0)
  {
    switch(vcoidx)
    {
      case  0:
      {
        return(nim->tuner.cx24108.vco_bp[CX24108_BPCNT-1].breakpt);
        break;
      }
      case  1:
      case  2:
      case  3:
      case  4:
      case  5:
      case  6:
      case  7:
      {
        return(nim->tuner.cx24108.vco_bp[vcoidx-1].breakpt);
        break;
      }
      case  8:
      {
        return(nim->tuner.cx24108.vco_edge[vcoidx].lower);
        break;
      }
      case  9:
      {
        /* no other BP's to test, so return lowest freq tested */
        return(nim->tuner.cx24108.vco_bp[7].breakpt);
        break;
      }
      case  10:
      {
        return(nim->tuner.cx24108.vco_bp[8].breakpt);
        break;
      }
      default:
      {
        break;
      }
    }  /* switch(... */
  }

  return(0UL);

}  /* _TUNER_vco_low() */


/*******************************************************************************************************/
/* _TUNER_CX24108_vco_high() */
/*******************************************************************************************************/
ULONG  _TUNER_CX24108_vco_high(/* function to return Fr high range based on vcoidx */
NIM            *nim,                   /* pointer to nim */
int            vcoidx)                 /* vco index */
{
  if (vcoidx >= 0)
  {
    switch(vcoidx)
    {
      case  0:
      case  1:
      case  2:
      case  3:
      case  4:
      case  5:
      case  6:
      {
        return(nim->tuner.cx24108.vco_bp[vcoidx].breakpt);
        break;
      }
      case  7:
      {
        return(nim->tuner.cx24108.vco_edge[vcoidx].upperthresh);
        break;
      }
      case  8:
      {
        /* (CR 7452) should return the current break pt. */
        return(nim->tuner.cx24108.vco_bp[7].breakpt);
        break;
      }
      case  9:
      {
        /* no other BP's to test, so return lowest freq tested */
        return(nim->tuner.cx24108.vco_bp[8].breakpt);
        break;
      }
      case  10:
      {
        return(nim->tuner.cx24108.vco_edge[vcoidx].upperthresh);
        break;
      }
      default:
      {
        break;
      }
    }  /* switch(... */
  }

  return(0UL);

}  /* _TUNER_vco_high() */


/*******************************************************************************************************/
/* _TUNER_CX24108_calc_bp() */
/*******************************************************************************************************/

⌨️ 快捷键说明

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