📄 stv199_i.c
字号:
* inside the [-max_lnb_offset,+max_lnb_offset] interval have * been scanned or data have been found. */ /* If 'GoodSignal' is still equal to "NO" at the end of the search, * the signal is wrong. */ DataSearchEnd = FALSE; DataFound = FALSE; QPSKParams_p->FLIndex = 0; DerotatorParams_p->DerotatorStart = 0; while (!DataSearchEnd) { SubRangeParams_p->SubRangeIndex = 0; QPSKSearchEnd = FALSE; while (!QPSKSearchEnd) { DerotatorParams_p->DerotatorFrequency = 0; QPSKSignalFound = FALSE; while ((DerotatorParams_p->DerotatorFrequency <= DerotatorParams_p->DerotatorLimit) && (DerotatorParams_p->DerotatorFrequency >= -DerotatorParams_p->DerotatorLimit) && !QPSKSignalFound) { /* DerotatorFreq range is [-DerotatorLimit, +DerotatorLimit]. * In order to avoid useless computations, the starting point is * not zero but DerotatorStart, which is believed near of the * good value. * * In order to stay in the good range, on overflow test is added. * The computation is done in a way that the range is fully * covered. */ I = DerotatorParams_p->DerotatorFrequency + DerotatorParams_p->DerotatorStart; if ((I > DerotatorParams_p->DerotatorLimit) || (I < -DerotatorParams_p->DerotatorLimit)) I = DerotatorParams_p->DerotatorStart - I ; /* In case of overflow */#if 0 printf("**** Trying CarrierLoop = %d\n", I);#endif Error = STV0199A_SetCarrierLoopFrequency(STV0199A_HANDLE(Demod_p), I); if (Error != DEMOD_NO_ERROR) goto qpsk_end; Error = CheckQPSK(Demod_p, QPSKParams_p->QPSKWaitValue, &QPSKSignalFound); if (Error != DEMOD_NO_ERROR) goto qpsk_end; if (!QPSKSignalFound) { DerotatorParams_p->DerotatorFrequency = ( DerotatorParams_p->DerotatorFrequency > 0 ) ? ( -DerotatorParams_p->DerotatorFrequency ) : ( DerotatorParams_p->DerotatorStep - DerotatorParams_p->DerotatorFrequency ); } } /* !QPSKSignalFound */ if (QPSKSignalFound) { QPSKSearchEnd = TRUE; } else { BOOL RangeOk; /* Interval change : the tuner is updated */ Error = NewRange(Demod_p, ScanParams_p, &RangeOk); if (!RangeOk) QPSKSearchEnd = TRUE; DerotatorParams_p->DerotatorStart = 0; } } /* !QPSKSearchEnd */ if (QPSKSignalFound) { /* QPSK signal was found : * - it is a true signal, and then Search_data will find it * and the search will be finished * or * - it is a false lock signal and the other false lock positions * will be explored */ SubRangeParams_p->SubRangeLimit = -1; #if 0 printf("**** Carrier found\n");#endif /* QPSK frequency must be corrected by the derotator value * (seen as a frequency offset) */ Error = STV0199A_GetCarrierLoopFrequency(STV0199A_HANDLE(Demod_p)); if (Error != DEMOD_NO_ERROR) goto qpsk_end; L = ScanParams_p->IQSense * STV0199A_HANDLE(Demod_p)->CarrierLoopFrequency; L *= STV0199A_HANDLE(Demod_p)->SymbolRate / (16*128); /* Fs/8*(nb derot steps/128) */ L /= 1000; /* QPSK frequency is in KHz */ QPSKParams_p->QPSKFrequency = ScanParams_p->CurrentFrequency + L;#if 0 printf("**** QPSK offset = %d\n", L);#endif /* QPSK signal has been found: * - if data are found, it is ok, the job is finished ! * - if data are not found, it is a false lock : * the alias (+/- Fs/4,...) are scanned */ Error = SearchData(Demod_p, ScanParams_p->CurrentFrequency, QPSKParams_p->DataWaitValue, &DataFound); if (Error != DEMOD_NO_ERROR) goto qpsk_end; if (DataFound) {#ifdef STTUNER_DEBUG printf("**** Data found\n");#endif /* The tuner is updated in such a way => the derotator value is * as close as possible to zero. */ Error = Optimization(Demod_p, ScanParams_p->CurrentFrequency, QPSKParams_p->DataWaitValue, ScanParams_p->IQSense, ScanParams_p->TunerStep, &DataSearchEnd, &ScanParams_p->CurrentFrequency);#ifdef STTUNER_DEBUG if (DataSearchEnd) printf("**** Optimization ok\n"); else printf("**** Optimization failed\n");#endif } } else { if (QPSKParams_p->FLIndex != 0) DerotatorParams_p->DerotatorFrequency = 0; } if ((!DataFound) && ((QPSKSignalFound) || (QPSKParams_p->FLIndex != 0))) { BOOL LockFound; /* There is not a true data signal: * it is a false lock position or there was a false lock position */ Error = NextQPSKLock(Demod_p, ScanParams_p, &LockFound ); if (!LockFound || !TimingLoopParams_p->TimingLoopOk) break; } else { break; } } /* DataSearchEnd */qpsk_end: *QPSKOk_p = DataFound; return Error;}/*****************************************************************************Name: CheckTimingLoop()Description: This routine verifies that the we are locked on a true digital carrier. When the timing offset register is successively sampled with a small delta from the initial sample, we are safe to assume we are locked on a digital carrier. This routine checks for this condition. A settling time is allowed, in case of a low symbol rate. NOTE: The result is placed in the 'timing loop ok' member of the timing loop parameter block.Parameters: Demod_p, pointer to the DEMOD device. Params_p, pointer to the timing loop params block.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 CheckTimingLoop(DEMOD_ControlBlock_t *Demod_p, DEMOD_TimingLoopParams_t *Params_p){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; S16 TimingValue[20]; S16 DeltaTiming = 0; U16 DeltaLimit; S16 TimingLoopSave; U16 i; Params_p->TimingLoopOk = TRUE; TimingLoopSave = 0; DeltaLimit = Params_p->NumberSamples * 36; /* An average delta of 6 is accepted */ /* STV0199 timing loop value is checked several times (=timing_sampling) * and the timing_loop is said "OK" if each value is valid (in the range * ]-limit..limit[) and if the variation between the value (=delta_timing) * is enough small (less than delta_limit) */ /* Timing value mean value computation */ for (i = 0; i < Params_p->NumberSamples; i++) { DEMOD_Delay(Params_p->TimingLoopWait) ; Error = STV0199A_GetTimingLoopFrequency(STV0199A_HANDLE(Demod_p)); if (Error != DEMOD_NO_ERROR) goto tloop_end; TimingValue[i] = STV0199A_HANDLE(Demod_p)->TimingLoopFrequency; if((TimingValue[i] > Params_p->TimingLimit) || (TimingValue[i] < -Params_p->TimingLimit)) Params_p->TimingLoopOk = FALSE; TimingLoopSave += TimingValue[i]; } TimingLoopSave /= Params_p->NumberSamples; /* Timing value variation computation */ for (i = 0; i < Params_p->NumberSamples; i++) { DeltaTiming += (TimingLoopSave-TimingValue[i]) * (TimingLoopSave-TimingValue[i]); }tloop_end: if (DeltaTiming >= DeltaLimit) Params_p->TimingLoopOk = FALSE; Params_p->TimingLoopFrequency = TimingLoopSave; return Error;}/*****************************************************************************Name: CentreTimingLoop()Description: This routine aims to correct the symbol rate in order to obtain a timing loop as close to the centre as possible -- best results are obtained by doing so.Parameters: Demod_p, pointer to the DEMOD device. TimingLoopFrequency, the current timing loop frequency.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 CentreTimingLoop(DEMOD_ControlBlock_t *Demod_p, S16 TimingLoopFrequency){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; S32 Correction; S32 Tloop = TimingLoopFrequency; /* Centring the timing loop */ Correction = (S32)((Tloop * (S32)(STV0199A_HANDLE(Demod_p)->SymbolRate / 8)) / (S32)(STV0199A_HANDLE(Demod_p)->MasterClock / 2)); /* Rounding */ Correction = (Correction >= 0) ? (Correction + 1) / 2 : (Correction - 1) / 2; Error = STV0199A_DeltaSymbolRate(STV0199A_HANDLE(Demod_p), Correction); return Error;}/*****************************************************************************Name: CheckQPSK()Description: The routine identifies whether or not a QPSK signal has been found i.e, does the carrier contain QPSK data. In most cases it is sufficient to check the "carrier found" flag. SearchData() performs a further check for QPSK data.Parameters: Demod_p, pointer to the DEMOD device. QPSKWaitValue, settling delay time. SignalFound, pointer to bool for storing QPSK check result.Return Value: DEMOD_NO_ERROR, the operation completed without error. STI2C_xxx, there was a problem accessing the device.See Also: SearchData()*****************************************************************************/static DEMOD_ErrorCode_t CheckQPSK(DEMOD_ControlBlock_t *Demod_p, U16 QPSKWaitValue, BOOL *SignalFound){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; DEMOD_Delay(QPSKWaitValue); Error = STV0199A_GetCF(STV0199A_HANDLE(Demod_p)); if (Error == DEMOD_NO_ERROR) { if (STV0199A_HANDLE(Demod_p)->CF == 1) *SignalFound = TRUE; else *SignalFound = FALSE; } return Error;}/*****************************************************************************Name: SearchData()Description: Once a QPSK signal is detected, the inner code recognition and packet synchronization is automatically performed by the STV0119A. We must check the status register (LK) to ensure this is occuring successfully. A settling period is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -