cx24143_fun.c

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

C
1,929
字号
/* cobra_api.c test */
/****************************************************************************

* Conexant QPSK driver  (internal mode)                                                          			 *

* Copyright ? Shenzhen Coship Electronics Co.,LTD.            						 *

* All rights reserved.                                                  								 *

* Author: Sunfugong                                                   								 *

* Create Date:  2005/7/20                                                       						 *

* Update:   2005/8/01  Sunfugong												 *

*****************************************************************************/
//sfg #include "warnfix.h"
#include <time.h>                      /* ANSI Standard */
#include <stdlib.h>                    /* ANSI Standard */
#include <ctype.h>                     /* ANSI Standard */
#include <string.h>                    /* ANSI Standard */

#include "CSQpskCFG.h"
#include "cx24143_all.h"                     /* Cobra include files: ordered */
#include "cx24143_regs.h"                /* Cobra Internal */
#include "cx24143drv.h"
#include "cx24143_defs.h" //sfg
//sfg for debug
#include "cs_assert.h"


/*******************************************************************************************************/
/* static arrays visible to this file only */
/*******************************************************************************************************/
static  SAMPFRQ  sampfrq_list[] =   {SAMPLE_FREQ_NOM,SAMPLE_DCII_NOM,SAMPLE_FREQ_UNDEF};
static  ULONG    sampfrq_eqlist[] = {SAMPLE_FREQ_NOM_VAL,SAMPLE_DCII_NOM_VAL,SAMPLE_FREQ_ENDLIST};
//static CMPLXNO  gEsNo_last=0;
/*******************************************************************************************************/
/* API_InitEnvironment() */
/*******************************************************************************************************/
BOOL           API_InitEnvironment(                   /* function to initialize a NIM* passed by application */
NIM            *nim,                                  /* nim pointer used by all API functions */
ULONG  demodhandle,                           /* demod handle to be associated with this NIM (user-specific) */
WRITE_SB       SBwrite,                               /* pointer to user-supplied low-level read I/O function */
READ_SB        SBread,                                /* pointer to user-supplied low-level read I/O function */
TRANSPEC       transpec,                              /* transport spec: (DSS, DVB,...) */
BOOL           (*TUNER_install)(NIM *nim),            /* function that will install a specific tuner  */
ULONG  crystalfreq,                           /* crystal (,freq of) attached to NIM card */
VCOINIT        vcoinit,                               /* TRUE if VCO edges are to be detected for tuner attached to present NIM */
MPEG_OUT *mpeg, LNBMODE *lnbmode, BOOL (*waitfunct)(NIM *nim,int mscount))    /* pointer to user-defined wait function (if null, default function is used) */
{
  int            i;
  ULONG  ulRegVal;
  UCHAR  b;

  static int regmap_test = False;    /* allows test code to be run once at start-up */

  /* perform a couple of stupidity tests... */
  if (nim == (NIM*)NULL)
  {
    DRIVER_SetError(nim,API_INVALID_NIM);
    return(False);
  }
  
  if (DRIVER_ValidNim(nim) == True)
  {
    /* invalid nim or already allocated */
    DRIVER_SetError(nim,API_NIM_OPENED);
    return(False);
  }

  /* clear the entire nim struct */
  memset(nim,CNULL,sizeof(NIM));

  /* un-install any previously installed wait function (The correct calling pattern */
  /* --> for two-nim sys:  Init(1),API_SetWait(1); Init(2), API_SetWait(2) ) */
  if (API_SetDriverWait(nim,waitfunct) == False)  return(False);

  /* allow for easy use of existing tuner code */
  if (TUNER_install == NULL)  TUNER_install = &TUNER_install_CX24108;

  /* reset various nim fields */
  nim->berbusy = -1;
  nim->bytebusy = -1;
  nim->blockbusy = -1;
  nim->pnberbusy = -1;
  nim->pnberpolarity = 0x01L;
  nim->CLKSMDIV_flag = CLKSMOOTHDIV_UPDATE;
  nim->CLKSMDIV_CR = CODERATE_NONE;

  /* clear the esno fields */
  memset(nim->esno.esno_taps,CNULL,sizeof(nim->esno.esno_taps));
  nim->esno.esno = 0;
  nim->esno.last_esno = -1L;
  nim->esno.taps_idx = 0;
  nim->esno.table = NULL;

  /* indicate no present error */
  nim->__errno = API_NOERR;

  /* misc initializations */
  nim->TUNER_io_method = TUNER_BURST;                 /* default tuner i/o method */

  /* test for valid crystal */
  if (crystalfreq < (ULONG)(FREQ_XTAL_LOW*MM) || crystalfreq > (ULONG)(FREQ_XTAL_HIGH*MM))
  {
    /* xtal presented at init...() is out-of-bounds */
    DRIVER_SetError(nim,API_INIT_XTAL);
    return(False);
  }
  nim->crystal_freq = crystalfreq;
  nim->opt_fs_disable = False;
#ifdef CAMARIC_FEATURES
  if (DRIVER_Camaric(nim) == True)
  {
     /* for Camaric chip, disable fs optimization for Cobra by default */
     nim->opt_fs_disable = True;
  }
#endif /* #ifdef CAMARIC_FEATURES */

#ifdef OPTIMAL_FS_CODE                 /* Fs optimization */
  if (DRIVER_Opt_Fs_buildtable(nim) == False)  return(False);
#endif  /* #ifdef OPTIMAL_FS_CODE */

  nim->frequency = NIM_DEFAULT_FREQ;
//sfg   nim->lnboffset = NIM_DEFAULT_LNB;
//  nim->lnboffset = 2000000L;
  nim->lnboffset = CS_NIM_DEFAULT_LNB;
  nim->symbol_rate_ideal = NIM_DEFAULT_SYMB;
  nim->symbol_rate = NIM_DEFAULT_SYMB;
  nim->prevstate = ACQ_OFF;

  nim->tuner_offset = 0UL;             /* (CR 6243) */
  nim->actual_tuner_offset = 0L;       /* (CR 6243) */
  nim->swa_count = 0;                  /* (CR 6243) */

  /* place the new nim into the nim_list */
  for (i = 0 ; i < MAX_NIMS ; i++)
  {
    if (nim_list.nim[i] == NULL)
    {
      nim_list.nim[i] = nim;
      nim_list.nim_cnt += 1;
      break;
    }
  }

  /* verify register map once at start-up */
  if (regmap_test == False)
  {
    regmap_test = True;
    if (RegisterVerifyMap(nim) != True)
    {
      /* tell exactly where the error occurred! */
      nim->errfname = (CHAR*)Register[nim->errline].regname;
      return(False);
    }
  }

  /* save the demod handle, i/o function pointers */
  nim->demod_handle = demodhandle;
  nim->SBWrite = SBwrite;
  nim->SBRead = SBread;

  /* flag bad sbread/sbwrite functions as errors */
  if (nim->SBWrite == NULL || nim->SBRead == NULL)
  {
    DRIVER_SetError(nim,API_SBIO_NULL);
    return(False);
  }

  /* grab chip version */
  RegisterRead(nim,CX24130_SYSVERSION,&nim->version);
  
  /* (CR 8226) write DC2 default settings to the demod immediately after reset */
  if (transpec != SPEC_DCII)
  {
    b = 0xff;
    if (API_WriteReg(nim,0x66,&b) == False)  return(False);
  }
  else
  {
    ulRegVal = 0UL;
    if (RegisterWrite(nim,CX24130_DC2CLKDIS,ulRegVal) == False)  return(False);
    ulRegVal = 0UL;
    if (RegisterWrite(nim,CX24130_DC2CLKDIR,ulRegVal) == False)  return(False);
    ulRegVal = 10UL;
    if (RegisterWrite(nim,CX24130_DC2CLKFREQ,ulRegVal) == False)  return(False);
  }
  
  /* determine the type of demod */
  if (DRIVER_CxType(nim,&nim->demod_type,NULL) != True)  return(False);

  /* place the demod into a known state (if demod is unknon, record a warning) */
  if (DRIVER_Preset(nim) != True)  DRIVER_SetError(nim,API_CXTYPE);
  if (DRIVER_Reset(nim) != True)  return(False);

  /* initialize PLLMult shadow with default value */
  nim->ucPLLMult_shadow = (UCHAR)Register[CX24130_PLLMULT].default_value;

  /* Install the tuner specified by the user */
  if ((*TUNER_install)(nim) == False)
  {
    DRIVER_SetError(nim,API_INIT_TUNER);
    return(False);
  }

  /* test that a valid tuner (i.e. function pointer!=NULL) was installed */
  if (TUNER_Initialize == NULL)
  {
    DRIVER_SetError(nim,API_INIT_TUNER);
    return(False);
  }

  /* initialize the tuner specified by the caller in TUNER_install passed into this function */
  if ((*TUNER_Initialize)(nim) == False)
  {
    DRIVER_SetError(nim,API_INIT_TUNER);
    return(False);
  }

  /* compute tuner VCO ranges */
  if (vcoinit != True && vcoinit != False)
  {
    /* vcoinit presented at init...() is out-of-bounds */
    DRIVER_SetError(nim,API_INIT_VCO);
    return(False);
  }
  else  if (vcoinit == True)
  {
    /* find tuner VCO edges */
    if (API_FindVCOEdges(nim,DEFAULT_RDIVVAL) == False)  return(False);
  }

  /* initiate MPEG system */
  nim->temp_SyncPunctMode = -1;
  if (mpeg == NULL)
  {
    DRIVER_SetError(nim,API_INIT_MPEG);
    return(False);
  }

  /* set the transport spec */
  if (nim->tspec != transpec)
  {
    if (API_SetTransportSpec(nim,transpec) == False)  return(False);
  }

  if (API_SetOutputOptions(nim,mpeg) == False)  return(False);

  /* set the LNB mode parameters */
  if (API_SetLNBMode(nim,lnbmode) == False)  return(False);

  return(True);

}  /* API_InitEnvironment() */


/*******************************************************************************************************/
/* API_ChangeChannel() */
/*******************************************************************************************************/
BOOL     API_ChangeChannel(            /* High-level function to perform channel-change operation */
NIM      *nim,                         /* nim pointer */
CHANOBJ  *chanobj, CSHDITunerIndex bTunerIndex)                     /* channel struct containing pert. channel info */
{
  LONG      acqoffset;
  LONG      tuneroffset;
  LONG      freqoffset;

  DWORD  vrates;        /* temp viterbi search rates */

  ACQSTATE  acqstate;          /* current acq state (i.e. locked/not locked) */
  BYTE ucTunerType;

	ucTunerType = CX2414XGetTunerType(bTunerIndex);
  /* test for valid nim */
  if (DRIVER_ValidateNim(nim) == False)  return(False);

  /* if chanobj is bad, bail immediately */
  if (chanobj == NULL)
  {
    DRIVER_SetError(nim,API_BAD_PARM);
    return(False);
  }  

  /* read current acq state (looking for a locked and tracking) */
  if (API_AcqContinue(nim,&acqstate) == False)  return(False);

  /* (CR 7957) */
  nim->CLKSMDIV_flag = CLKSMOOTHDIV_UPDATE;
  nim->CLKSMDIV_CR = CODERATE_NONE;

  /* if locked to a signal, the acq-offset will be valid, otherwise use 0 */
  nim->actual_tuner_offset = 0L;  /* (CR 6243) */
  acqoffset = 0L;
  if (acqstate == ACQ_LOCKED_AND_TRACKING)
  {
    /* transfer LNB offset to nominal central frequency */
    /* (CR 8176) Removed per CR */
    /* if (API_GetAcquisitionOffset(nim,&acqoffset) == False)  return(False); */
  }

  /* (CR 7672) added line below */
  if (API_SetSymbolRate(nim,chanobj->symbrate) == False)  return(False);

  /* step-through each demod setting, as required, in seq. order required */
#ifdef OPTIMAL_FS_CODE                 /* Fs optimization */
  nim->samplerate = chanobj->samplerate;
#endif /* #ifdef OPTIMAL_FS_CODE */

	if ( ucTunerType == CX2414X_TUNER_SHARP0302)
	{
		CSTRACE(INFO_LEVEL, "[HDIQPSK]Shart0302aSetFrequency (freq, symbrate)=(%d, %d)\r\n", chanobj->frequency, chanobj->symbrate);
		//Shart0302aSetFrequency( bTunerIndex, chanobj->frequency/1000, chanobj->symbrate);
	}
	else
	{
  if (API_SetTunerFrequency(nim,chanobj->frequency) == False)  return(False);
	}
  /* restart demod's acq state machine early to improve acquisition performance */
  if (API_AcqBegin(nim) == False)  return(False);

  if (API_GetFrequencyOffset(nim,&tuneroffset) == False)  return(False);
  freqoffset = acqoffset + tuneroffset;

  /* call API_SetTunerFrequency before API_SetCentralFreq */
  /* (CR 7988) removed:  if (API_SetCentralFreq(nim,freqoffset) == False)  return(False); */

  if (API_SetSpectralInversion(nim,chanobj->specinv) == False)  return(False);
  
  /* set the Viterbi code rate settings  */
  vrates = (chanobj->viterbicoderates | chanobj->coderate);
  if (API_AcqSetViterbiCodeRates(nim,vrates) == False)  return(False);  /* new style */

  /* (CR7349) 4/23/02 cw */
  if (DRIVER_SWAssistAcq_CR1DIV2(nim,vrates) == False)  return(False);

  if (API_SetModulation(nim,chanobj->modtype) == False)  return(False);
  if (API_SetViterbiRate(nim,chanobj->coderate) == False)  return(False);


  /* if external sample freq is selected, do not touch the sample freq register */
  if (chanobj->samplerate != SAMPLE_FREQ_EXT)
  {
#ifdef OPTIMAL_FS_CODE                 /* Fs optimization */
    if (nim->opt_Fs_pllmult != 0 && nim->opt_fs_disable == False)
    {
      if (__API_SetSampleFrequency(nim,nim->opt_Fs_chosen) == False)  return(False);
    }
    else
#endif  /* #ifdef OPTIMAL_FS_CODE */
    if (API_SetSampleFrequency(nim,chanobj->samplerate) == False)  return(False);
#ifdef OPTIMAL_FS_CODE                 /* Fs optimization */
    /* set default Fs as one chosen */
    /* (CR 7672) line below commented */
    /* --> if (API_GetAssociatedSampleFrequency(nim,chanobj->samplerate,&nim->opt_Fs_chosen) == False)  return(False); */
  }
  else
  {
    /* Fs is externally set, so get current default Fs from by reading the demod */
    if (API_GetSampleFrequency(nim,&nim->opt_Fs_chosen) == False)  return(False);
#endif  /* #ifdef OPTIMAL_FS_CODE */
  }

  /* (CR 7672) removed line below */
  if (API_SetSymbolRate(nim,chanobj->symbrate) == False)  return(False);

  /* cause some serious channel-changing action */
  if (API_AcqTrackingSetup(nim) == False)  return(False);

  /* successful channel change operation, save copy in the nim */
  memcpy(&nim->chanobj,chanobj,sizeof(CHANOBJ));

  /* perform SW assist as required */
  if (DRIVER_SWAssistAcq(nim) == False)
  {
    DRIVER_SetError(nim,API_BAD_SWA);
    return(False);
  }

  /* (CR 6243) */
  if(DRIVER_SWAssistTuner(nim) == False)
  {
    DRIVER_SetError(nim,API_BAD_SWA);
    return(False);
  }

⌨️ 快捷键说明

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