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

📄 stv199_i.c

📁 这是DVB tuner驱动部分和其它相关的源码和一些技术资料文档.
💻 C
📖 第 1 页 / 共 5 页
字号:
{    DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR;    U8 BetaTiming;    BOOL AGCLevelGood = FALSE;    Error = SetTunerFrequency(Demod_p,                              Frequency,                              NewFrequency_p);    if (Error == DEMOD_NO_ERROR)    {        /* In order to avoid the effects of erratic sampling time (due to the         * unstabilised timing loop), which can affect a lot the AGC1 value,         * the timing loop is opened.         */        BetaTiming = STV0199A_HANDLE(Demod_p)->BetaTiming;        /* Open the timing loop */        Error = STV0199A_SetBetaTiming(STV0199A_HANDLE(Demod_p),                                       0);        if (Error == DEMOD_NO_ERROR)        {            /* Timing loop in the middle */            Error = STV0199A_SetTimingLoopFrequency(STV0199A_HANDLE(Demod_p),                                                    0);            if (Error == DEMOD_NO_ERROR)            {                Error = IsAGC1Good(Demod_p, &AGCLevelGood);                if (Error == DEMOD_NO_ERROR)                {                    /* Close the timing loop */                    Error = STV0199A_SetBetaTiming(                        STV0199A_HANDLE(Demod_p),                        BetaTiming);                }            }        }    }    *AGCLevelGood_p = AGCLevelGood;    return Error;}/*****************************************************************************Name: SetTunerFrequency()Description:    This is a convenient wrapper routine for calling the TNR device to    set the current tuner frequency.Parameters:    Demod_p,            pointer the DEMOD device.    Frequency,          required frequency to set to (IF).    NewFrequency_p,     new frequency may not be the same as input.Return Value:    DEMOD_NO_ERROR,     the operation completed without error.    STI2C_xxx,          there was a problem accessing the device.See Also:    Nothing.*****************************************************************************/static DEMOD_ErrorCode_t SetTunerFrequency(DEMOD_ControlBlock_t *Demod_p,                                           U32 Frequency,                                           U32 *NewFrequency_p){    DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR;    U8 i;    Error = TNR_SetFrequency(TNR_HANDLE(Demod_p),                             Frequency,                             NewFrequency_p);    if (Error == DEMOD_NO_ERROR)    {        BOOL Locked;        for (i = 0; i < 50; i++)        {            TNR_IsTunerLocked(TNR_HANDLE(Demod_p),                              &Locked);            if (Locked)                break;            DEMOD_Delay(2);        }    }#ifdef STTUNER_DEBUG    if (i == 50)        printf("**** Tuner failure\n");#endif    return Error;}/*****************************************************************************Name: IsAGC1Good()Description:    This routine checks the AGC value, after a settling delay period,    against a threshold limit.Parameters:    Demod_p,            pointer to the DEMOD device.    AGC1GoodLevel_p,    pointer to area to store result (bool).Return Value:    DEMOD_NO_ERROR,     the operation completed without error.    STI2C_xxx,          there was a problem accessing the device.See Also:    Nothing.*****************************************************************************/static DEMOD_ErrorCode_t IsAGC1Good(DEMOD_ControlBlock_t *Demod_p,                                    BOOL *AGC1GoodLevel_p){    DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR;    U8 i;	/* The settling time is about 100 000 master clock periods.	 * master clock is given in Hz, then the result is multiplied by 1000     * in order to have milliseconds.  In order to give margin,     * 5 ms are added.     */    U16	SettlingTime = (U16)(100000000 /                             STV0199A_HANDLE(Demod_p)->MasterClock) + 5;    DEMOD_Delay(SettlingTime);    for (i = 0; i < 100; i++)    {      Error = STV0199A_GetAGC1(STV0199A_HANDLE(Demod_p));      if (Error == DEMOD_NO_ERROR)      {          if ((STV0199A_HANDLE(Demod_p)->AGC1 > -128) &&              (STV0199A_HANDLE(Demod_p)->AGC1 < 127))          {              *AGC1GoodLevel_p = TRUE;              break;          }          else          {              *AGC1GoodLevel_p = FALSE;          }      }    }#if 0    printf("**** AGC1 = %d\n", STV0199A_HANDLE(Demod_p)->AGC1);#endif    return Error;}/*****************************************************************************Name: IsAGC2Good()Description:    A number of samples are made of the of the AGC2 gain register.    The average sample is compared against a threshold value.Parameters:    Demod_p,            pointer to the DEMOD device.    NumberSamples,      number of samples to take.    AGC2Value_p,        pointer to location to store AGC2 value.    AGC2Good_p,         pointer to bool to store success/failure against                        AGC threshold.Return Value:    DEMOD_NO_ERROR,     the operation completed without error.    STI2C_xxx,          there was a problem accessing the device.See Also:    Nothing.*****************************************************************************/static DEMOD_ErrorCode_t IsAGC2Good(DEMOD_ControlBlock_t *Demod_p,                                    U16 NumberSamples,                                    S16 *AGC2Value_p,                                    BOOL *AGC2Good_p){    DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR;    /* The settling time of AGC2 is typically 3000 master clock periods	 * It is a short time, so that the delay is set to 1 ms -- more than     * enough time.     */    U16 i;    S16 AGC2Value = 0;    for (i = 0; i < NumberSamples; i++)    {        DEMOD_Delay(10);        Error = STV0199A_GetAGC2(STV0199A_HANDLE(Demod_p));        if (Error != DEMOD_NO_ERROR)            break;        AGC2Value += STV0199A_HANDLE(Demod_p)->AGC2;    }    if (Error == DEMOD_NO_ERROR &&        AGC2Value > 0 &&        AGC2Value < 128 * NumberSamples)    {        *AGC2Value_p = AGC2Value;        *AGC2Good_p = TRUE;    }    else        *AGC2Good_p = FALSE;    return Error;}/*****************************************************************************Name: SearchQPSK()Description:    Once a digital carrier has been found (i.e. timing look is good), the    complete frequency range identified by +/- LNB offsert is scanned until    a QPSK carrier is found.Parameters:    Demod_p,        pointer to the DEMOD device.    ScanParams_p,   pointer to a scan params block.    QPSKOk_p,       pointer to bool to store QPSK lock result.Return Value:    DEMOD_NO_ERROR,     the operation completed without error.    STI2C_xxx,          there was a problem accessing the device.See Also:    CheckQPSK()    NextQPSKLock()    SearchData()*****************************************************************************/static DEMOD_ErrorCode_t SearchQPSK(DEMOD_ControlBlock_t *Demod_p,                                    DEMOD_ScanParams_t *ScanParams_p,                                    BOOL *QPSKOk_p){    DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR;    S16 I;                              /* Temoporary vars */    S32 L;    DEMOD_SubRangeParams_t *SubRangeParams_p;    DEMOD_TimingLoopParams_t *TimingLoopParams_p;    DEMOD_DerotatorParams_t *DerotatorParams_p;    DEMOD_QPSKParams_t *QPSKParams_p;    BOOL DataSearchEnd;    BOOL DataFound;    BOOL QPSKSignalFound;    BOOL QPSKSearchEnd;    /* Initialize the SubRange values */    SubRangeSetting(Demod_p,                    ScanParams_p);    /* Convenient pointers for accessing various parameters */    SubRangeParams_p = &ScanParams_p->SubRangeParams;    TimingLoopParams_p = &ScanParams_p->TimingLoopParams;    DerotatorParams_p = &ScanParams_p->DerotatorParams;    QPSKParams_p = &ScanParams_p->QPSKParams;    /* Initialisation of the tuner */    if (ScanParams_p->ScannedFrequency != ScanParams_p->InitialFrequency)    {        U32 NewFrequency;        /* CurrentFrequency is the frequency computed by the scan routine and         * can be very different from the frequency entered by the user. The         * subrange settings are updated.         */        L = (ScanParams_p->ScannedFrequency - ScanParams_p->InitialFrequency) ; /* in KHz */        if (L < 0)            L -= SubRangeParams_p->SubRangeSize;        SubRangeParams_p->SubRangeInit =                   (S16)((2 * L + SubRangeParams_p->SubRangeSize) /                         (2 * SubRangeParams_p->SubRangeSize));        if (SubRangeParams_p->SubRangeInit > SubRangeParams_p->SubRangeLimit)            SubRangeParams_p->SubRangeInit = SubRangeParams_p->SubRangeLimit;        if (SubRangeParams_p->SubRangeInit < -SubRangeParams_p->SubRangeLimit)            SubRangeParams_p->SubRangeInit = -SubRangeParams_p->SubRangeLimit;        NewFrequency = ScanParams_p->InitialFrequency +                       SubRangeParams_p->SubRangeInit *                       SubRangeParams_p->SubRangeSize;        Error = SetTunerFrequency(Demod_p,                                  NewFrequency,                                  &ScanParams_p->ScannedFrequency);        if (Error != DEMOD_NO_ERROR)            goto qpsk_end;    }    ScanParams_p->CurrentFrequency = ScanParams_p->ScannedFrequency;    /* Timing loop computation & symbol rate optimization */    TimingLoopParams_p->NumberSamples = 3;    TimingLoopParams_p->TimingLimit = 120;    Error = CheckTimingLoop(Demod_p, TimingLoopParams_p);    if (Error != DEMOD_NO_ERROR)        goto qpsk_end;    Error = CentreTimingLoop(Demod_p,                             TimingLoopParams_p->TimingLoopFrequency);    if (Error != DEMOD_NO_ERROR)        goto qpsk_end;    /* Due to the fact that SymbolRate was corrected, a new derotator limit     * is computed (1016 = 8*127).     */    DerotatorParams_p->DerotatorLimit =                (U16)((1016 * SubRangeParams_p->SubRangeSize) /                      (STV0199A_HANDLE(Demod_p)->SymbolRate / 1000));    /* In order to insure that the limits are reached, the derotator limit     * must be a multiple of the derotator step.     */    DerotatorParams_p->DerotatorLimit =        ((DerotatorParams_p->DerotatorLimit /          DerotatorParams_p->DerotatorStep) + 1) *                                       DerotatorParams_p->DerotatorStep;    if (DerotatorParams_p->DerotatorLimit > 127 )        DerotatorParams_p->DerotatorLimit = 127;    /* Assuming that the LNB has been made with care , the small LNB frequency     * offsets have the highest probability. Then the scanning of the     * frequencies will start from the " zero" offset position, and in order     * to give the same priority to negative and positive offsets the scanning     * is done in a zig-zag mode. The first interval scanned is the zero offset     * centered interval (sub_range = 0), then the  sub_range_size offset     * centered interval (sub_range = 1), then the  -sub_range_size offset     * centered interval (sub_range = -1), then the  2*sub_range_size offset     * centered interval (sub_range = 2),...     * sub_range_size and sub_range_number are computed in such a manner     * that the upper limit of the interval (sub_range = sub_range_number) is     * +max_lnb_offset, and the lower limit	of the interval (sub_range =     * -sub_range_number) is -max_lnb_offset, the allowed zone for scanning     * data.     * All the sub-ranges have the same size, which is equal to     * 2*DerotatorLimit*derotator_step. This fact simplifies the code,     * discarding tests, and allows the use of "while" loops.     * 3 nested "while" loops are used (down-top description):     *	- the "QPSK_signal_found" while loop :     *	 The derotator frequency value (derotator_freq) is set with a     *	 zig-zag method (if F0 is the central frequency of the current     *	 sub-range, the derotator frequency value is set to F0,     *   F0 + 1 step, F0 - 1 step, F0 + 2 steps, F0 - 2 stepo,...).     *   For each value, a QPSK signal is searched.     *	 When this while loop is exited, the sub-range have been     *   scanned or a QPSK signal has been found.     *	- the "QPSK_search-end" while loop :     *	 The sub-ranges are scanned with a zig-zag method (sub-range     *	 suffixed by 0, then by 1, -1, 2, -2,...).     *	 When this while loop is exited,[-max_lnb_offset,+max_lnb_offset]     *   interval has been scanned or a False Lock position has been     *   found.     *	- the "data_search_end" while loop :     *	 The False Lock positions are scanned in a zig-zag mode, with a     *   step of Fs/4. Two sequences can be used (if FS0 is the first     *   found False lock position) :     * 	 * if FS0 is less than the starting frequency :     *	 (FS0, FS0 + Fs/4, FS0 - Fs/4, FS0 + 2*Fs/4, FS0 - 2*Fs/4,..)     *	 * if FS0 is greater than the starting frequency :     *	 (FS0, FS0 - Fs/4, FS0 + Fs/4, FS0 - 2*Fs/4, FS0 + 2*Fs/4,..)     * When this while loop is exited, all the False Lock positions

⌨️ 快捷键说明

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