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

📄 snimdriv.c

📁 ST5100 driver files for ST chipset
💻 C
📖 第 1 页 / 共 5 页
字号:
        else if (SNIM_MCLK_SYMB!=iClock)
        {/* Settings above do not need changing*/
            bOk = FALSE;
        }
       
    }
    
    if (bOk)
    { /* write the two registers */
        bOk = Snim_RegisterWrite(hSnim,SNIM_OP_CTRL,&OPcontrol,1)
            && Snim_RegisterWrite(hSnim,SNIM_FEC_SETUP,&FECsetup,1);
    }
    if (bOk && SNIM_ID_ZL10313==hSnim->ucChipID)
    { /*for ZL10313, write the extra 0 register as well*/
        bOk = Snim_WriteExtra(hSnim,ZL313_CTRL_SELEXTRA_MPEG ,ucXtra);
    }

    return bOk;

}






/************************Zarlink Semiconductor*********************************
*   Name: Snim_GetMpegClock()
*   Purpose:returns the current MPEG clock setting
*   Remarks:  valid possibilities:
*            hSnim->ucChipID    MAN_MOCLK       DIS_SR(MT312 only)
*               ZL10312             0               X       symbol rate
*               ZL10312             1               X       Pll derived
*               MT312/ZL10313       0               0       symbol rate
*               MT312/ZL10313       1               0       pll derived 
*               MT312/ZL10313       1               1       external

*   Inputs: 
*
*   Outputs:current setting
*
********************************************************************************/
Sint32T Snim_GetMpegClock(PSSNIMCTL hSnim)
{
	/* moclk ratio = (PLL frequency/moclckkHz  ) -6*/
	
	Uint8T OPcontrol=0,FECsetup=0,FECstaten=0,SysClock=0;
	Sint32T lTemp = SNIM_MCLK_ERROR;
	
    if (Snim_RegisterRead(hSnim,SNIM_SYS_CLK,&SysClock,1)
		&& Snim_RegisterRead(hSnim,SNIM_OP_CTRL,&OPcontrol,1)
		&& Snim_RegisterRead(hSnim,SNIM_FEC_SETUP,&FECsetup,1)
		&& Snim_RegisterRead(hSnim,SNIM_FEC_STAT_EN,&FECstaten,1))
	{
        if (!(OPcontrol & SNIM_OP_CTRL_MANMOCLK))
        {  /* symbol rate derived clock*/
            if ((hSnim->ucChipID==SNIM_ID_MT312||hSnim->ucChipID==SNIM_ID_ZL10313) && (FECsetup & SNIM_FEC_SETUP_DIS_SR))
            { /* except MT312/ZL10313 with DIS_SR set */
                lTemp = SNIM_MCLK_ERROR;
            }
            else
                lTemp = SNIM_MCLK_SYMB;
        }
        else
        {   /*pll derived clock */
            if ((hSnim->ucChipID==SNIM_ID_MT312||hSnim->ucChipID==SNIM_ID_ZL10313) && (FECsetup & SNIM_FEC_SETUP_DIS_SR))
            { /* except MT312/ZL10313 with DIS_SR set = external clock */ 
                lTemp = SNIM_MCLK_EXT;
            }
            else
            { /* calculate the clock frequency*/
                lTemp = SysClock;
                lTemp *= 5000;
                lTemp/= ((FECstaten >>4) +6);
                lTemp  +=5;
                lTemp /=10;
            }
        }
    }
        
  return lTemp;  

}


/************************Zarlink Semiconductor*********************************
*   Name:ReadQPSKBERSnim()
*   Purpose:Calculates the bit error rate out of the QPSK core 
*   Remarks: Pre Viterbi BER = VIT_ERCNT/(VIT_ERRPER*4)
*            BER*1000000 =  VIT_ERCNT*250000/VIT_ERRPER
*			  Now uses only VIT_ERRPER_H (M and L assumed to be 0xFFFF), and result
*             is same as with TNIM;
*   Inputs:
*
*   Outputs: BER * 1000000, or -1
*
********************************************************************************/
Sint32T Snim_CalcQPSKBER(PSSNIMCTL hSnim)
{
    Uint32T dwCount;
    Uint32T dwPeriod;

      
   if (!Snim_ReadRegisterValue(hSnim,SNIM_VIT_ERRCNT,&dwCount)
        || !Snim_ReadRegisterValue(hSnim,SNIM_VIT_ERRPER,1,&dwPeriod))
    {/* did not read both registers */
        return-1;
    }
    dwPeriod<<=16;
    dwPeriod +=65535;
   /* got the data do the arithmetic*/
        if (dwCount<=Uint32T_MAX/25000)
        {
            dwCount *=25000;
            dwPeriod +=5;
            dwPeriod /=10;
        }
        else if (dwCount<=Uint32T_MAX/2500)
        {
            dwCount *=2500;
            dwPeriod +=50;
            dwPeriod /=100;
        }
        else
        {
            dwCount *=250;
            dwPeriod +=500;
            dwPeriod /=1000;
        }

        if (dwPeriod>0)
            dwCount /= dwPeriod;
        
    return dwCount;
}


/************************Zarlink Semiconductor*********************************
*   Name:Snim_CalcViterbiBER()
*   Purpose:Calculates the Post Viterbi bit error rate
*   Remarks:    Vitberi BER = RS_BERCNT/(dt *Rs * CR * Q), where
*               dt is the time in seconds
*               Rs is the symbol rate in Baud
*               CR is the code rate (expressed as a fraction 3/4 for example)
*               Q is 1 (BPSK) or 2 (QPSK)
*   
*   Inputs:time and error counts cached by demodmain
*
*   Outputs:PostViterbi BER (x 1E9)
*
*Calculation becomes:
*   Viber BER (x10^9) = (RS_BERCNT x 1E9)/(dt Rs_x128 x10^6/128 xCR xQ)
*                 = (RS_BERCNT x 128000 x(c+1)) / (dt Rs_x128 x c xQ),  where
*               Rs_x128 is Rs in MBd x128
*               c is the numerator and (c+1) the denominator (e.g. 3 and 4)
********************************************************************************/
Sint32T Snim_CalcViterbiBER(PSSNIMCTL hSnim)
{
	Uint32T numerator; 
	Uint8T coderate;  
    Uint8T config;
	Uint16T symbolratex128;
	Uint32T denominator;

    coderate=Snim_GetCodeRate(hSnim);
    symbolratex128=Snim_GetSymbolRate(hSnim)/8;/* symbol rate in MS x128*/

    if (!Snim_RegisterRead(hSnim,SNIM_CONFIG,&config,1)	|| (0==coderate)  || (0==symbolratex128) )
	               return -1;
	numerator = hSnim->dwErrorCount;
    denominator = (hSnim->dwErrPer +500)/1000;/* time in seconds*/
	if (denominator >74000) return -1;     /* too long, arithmetic overflow will occur */
	
	/* calculate  the denominator */
	denominator *= symbolratex128; /* 65535 x (64MBd max)x128  */
	denominator *= coderate;             /* x 7 => 3,758,039,040 max*/
	denominator /= (coderate+1);
	if (config & SNIM_CONFIG_BPSK)
		denominator /=2; /* BPSK*/
	else
		denominator *=4; /*QPSK*/
	

	/*spread the *256000 around the numerator and denominator to best effect
	bearing in mind minimum value of denominator*/

	if (numerator <=Uint32T_MAX/256000)
	{
		numerator *=256000;
	}
	else if (numerator <=Uint32T_MAX/25600)
	{
		numerator *=25600;
		denominator +=5;
		denominator /=10;
	}
	else if (numerator <=Uint32T_MAX/2560)
	{
		numerator *=2560;
		denominator +=50;
		denominator /=100;
	}
	else if (denominator < 5000)
	{
		/* error count is greater than Uint32T_MAX/2560 clip it*/
		numerator = Uint32T_MAX/2560;
		denominator +=50;
		denominator /=100;
	}
	else
	{
		numerator *=256;
		denominator +=500;
		denominator /=1000;
	}
		

	/* post the answer and return*/
	if (0== denominator) return -1;
	
    numerator/=denominator;
    if (numerator>Sint32T_MAX) numerator=Sint32T_MAX;
    return numerator;
   
}





/************************Zarlink Semiconductor*********************************
*   Name:SnimSetLnb()
*   Purpose:Set the required LNB parameters 
*   Remarks:Takes effect next time a channel or scan is initialised
*   Inputs:psLnb pointer to an Lnb specifier
*
*   Outputs:
*
********************************************************************************/
void SnimSetLnb(HANDLE hSnim, SSnimLnb *psLnb)
{

	ENTER_SNIM_CONTENTION_LOCK;
    if (Snim_CheckPointers(PSSNIM) && psLnb!=NULL) PSSNIM->Lnb = *psLnb;
	EXIT_SNIM_CONTENTION_LOCK;
   
}





/************************Zarlink Semiconductor*********************************
*   Name:   SnimReadChannel()
*   Purpose:Reads current channel info
*   Remarks:if psChannel returns tuning info in pchannel structure
*
*   Inputs:none
*
*   Outputs:FLASE if device read error
*
********************************************************************************/


BOOL SnimReadChannel(HANDLE hSnim, SSnimChannel *psChannel)
{
	Sint32T temp;
	BOOL ret;

	ENTER_SNIM_CONTENTION_LOCK;
	ret=TRUE;
	if (!Snim_CheckPointers(PSSNIM)) 
	{
		ret = FALSE;
	}
	else
	{

		if (psChannel!=NULL)
		{
			*psChannel = PSSNIM->Channel;
			if ((PSSNIM->DemodFsmState==SNIM_DEMODFSM_SCANSTOP) || (PSSNIM->DemodFsmState==SNIM_DEMODFSM_LOCK))
			{/* locked, get the real values*/
				psChannel->ucExt&= SCHANNELEXT_HORIZONTAL;
				temp = Snim_GetLNBFreq(PSSNIM,_LNBFREQ_MODE_ACTUAL);
				psChannel->MHz = Uint16T(((Uint32T)temp +500)/1000); /*rounded to MHz;*/
				temp -= psChannel->MHz*1000;  /* remaining kHz */
				if (temp>=0) temp += 50; else temp -=50;
				temp/=100;   /* tenths */
				psChannel->ucExt |= Uint8T((temp <<4) & 0xF0);

				if (PSSNIM->DSSmode)
					psChannel->kRs= SNIM_DSS_SYMBOLRATE;
				else
					psChannel->kRs = Snim_GetSymbolRate(PSSNIM);

				psChannel->ucExt &= ~SCHANNELEXT_CODERATE;
				psChannel->ucExt |= Snim_GetCodeRate(PSSNIM);
				if (0==psChannel->kRs || 0 == (psChannel->ucExt &SCHANNELEXT_CODERATE)) ret = FALSE;
			}
			else if (PSSNIM->DemodFsmState>=SNIM_DEMODFSM_SCANINIT)
			{/* scanning, set element to zero */
				psChannel->kRs =0;
			}
		}

	}
	EXIT_SNIM_CONTENTION_LOCK;
	return ret;
}



/************************Zarlink Semiconductor*********************************
*   Name: SnimAcquire()
*   Purpose: To start acquisition of a new known channel
*   Remarks:Copies passed channel data into PSSNIM structure and forces state to PROGRAM_TUNER
*   Inputs: Pointer to channel data, psChannel. If psChannel = NULL, Aquisition is restarted with current setting.
*
*   Outputs:TRUE indicates no errors occured, and does not indicate lock occured
*
********************************************************************************/

BOOL SnimAcquire(HANDLE hSnim,PSSNIMCHANNEL psChannel)
{
	BOOL ret;
	ENTER_SNIM_CONTENTION_LOCK;
	if (!Snim_CheckPointers(PSSNIM))
	{/* error in pointers*/
		printSnimDrvError(("[SnimAcquire] >> error in pointers\n"));
		ret= FALSE;
	}
	else if (PSSNIM->DemodFsmState>=SNIM_DEMODFSM_SCANINIT ||PSSNIM->DemodFsmState<SNIM_DEMODFSM_IDLE) 
	{ /* off, standby or scanning */
		printSnimDrvError(("[SnimAcquire] >> off, standby or scanning DemodFsmState : %x \n",PSSNIM->DemodFsmState));
		ret = FALSE;
	}
	else
	{ /* start acqusition (with new channel if required)*/
		printSnimDrv(("[SnimAcquire] >> start acqusition (with new channel if required)\n"));
		if (psChannel != NULL)   PSSNIM->Channel = *psChannel;
		PSSNIM->DemodFsmCommand=SNIM_FSMCOMMAND_NEWCHAN;
		ret = TRUE;
	}

	EXIT_SNIM_CONTENTION_LOCK;
	return ret;
	}

/***********************Zarlink Semiconductor*********************************
*   Name: Snim_DemodMain()
*   Purpose: Finite state machine to run Snim power control, acquisition and scanning
*   Remarks: Intended to be in host programs main loop, called regularly say every 10 msec.
*            Actual performance depends on calling rate, faster the better
*           PSSNIM->pMilliSeconds (32 bit millisecond counter) controls timeouts. The state machine will timeout of 
*           various activities based on this time value. This routine should be called frequently (say every 10 msec) with a 
*           new value of PSSNIM->pMilliSeconds for best performance. However the time may be updated less frequently (say every 50 msec)
*           which will result in slower scanning performance due to longer timouts for example. 
*           Processing occurs in two stages: 1) any pending command in PSSNIM->ACQcoomand is processed
*           2) the state machine is run. 
*    Inputs: PSSNIM structure
*
*   Outputs: return value descriptive of activity (e.g. IDLE, BUSY, LOCKED etc)
*

⌨️ 快捷键说明

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