📄 stv199_i.c
字号:
{ 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 + -