📄 stv199_i.c
字号:
} /* DEMOD_GetAGC() *//*****************************************************************************Name: DEMOD_GetFECRate()Description: Checks the VEN rate register to deduce the forward error correction setting that is currently in use.Parameters: Demod_p, pointer to the DEMOD device. FECRate_p, pointer to area to store FEC rates in use.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 DEMOD_GetFECRate(DEMOD_Handle_t Handle, DEMOD_FECRate_t *FECRate_p){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; DEMOD_FECRate_t FecRate = 0; Error = STV0199A_GetVENRate(STV0199A_HANDLE(Handle)); if (Error == DEMOD_NO_ERROR) { U8 Data; Data = STV0199A_HANDLE(Handle)->VENRate; /* Convert venrate value to a DEMOD fecrate */ switch (Data) { case STV0199A_VSTATUS_PR_1_2: FecRate = DEMOD_FEC_1_2; break; case STV0199A_VSTATUS_PR_2_3: FecRate = DEMOD_FEC_2_3; break; case STV0199A_VSTATUS_PR_3_4: FecRate = DEMOD_FEC_3_4; break; case STV0199A_VSTATUS_PR_5_6: FecRate = DEMOD_FEC_5_6; break; case STV0199A_VSTATUS_PR_7_8: FecRate = DEMOD_FEC_7_8; break; } /* Copy back for caller */ *FECRate_p = FecRate; } return Error;} /* DEMOD_GetFECRates() *//*****************************************************************************Name: DEMOD_SetFECRates()Description: Sets the FEC rates to be used during demodulation.Parameters: Demod_p, pointer to DEMOD device. FECRates, bitmask of FEC rates to be applied.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 DEMOD_SetFECRates(DEMOD_Handle_t Handle, DEMOD_FECRate_t FECRates){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; U8 Data = 0; /* Convert DEMOD FEC rates to a VENRATE value to be applied to the * STV0199A. */ if (FECRates & DEMOD_FEC_1_2) Data |= STV0199A_VENRATE_E0_MSK; if (FECRates & DEMOD_FEC_2_3) Data |= STV0199A_VENRATE_E1_MSK; if (FECRates & DEMOD_FEC_3_4) Data |= STV0199A_VENRATE_E2_MSK; if (FECRates & DEMOD_FEC_5_6) Data |= STV0199A_VENRATE_E3_MSK; if (FECRates & DEMOD_FEC_7_8) Data |= STV0199A_VENRATE_E4_MSK; Error = STV0199A_SetVENRate(STV0199A_HANDLE(Handle), Data); return Error;} /* DEMOD_SetFECRates() *//* Private utility functions ---------------------------------------------- *//*****************************************************************************Name: InitializeSearchTimers()Description: Various delay times are calculated depending on the scan search criteria. e.g., - Timing lock time = depends on damping factor and natural frequency - QPSK capture time = carrier lock algorithm depends on df and nf. - Data wait time = uses the viterbi decoder and synchronization search. ** This must be called prior to SearchQPSK().Parameters: Demod_p, pointer to the DEMOD parameters. ScanParams_p, pointer to a scan params block.Return Value: DEMOD_NO_ERROR, the operation completed without error.See Also: Nothing.*****************************************************************************/static DEMOD_ErrorCode_t InitializeSearchTimers(DEMOD_ControlBlock_t *Demod_p, DEMOD_ScanParams_t *ScanParams_p){ DEMOD_ErrorCode_t Error = DEMOD_NO_ERROR; U16 ViterbiSearch, TimeOut, Hysteresis, HigherRate; U32 PhaseNumber[] = { 1, 3, 2, 6, 8 }; U32 Averaging[] = { 1024, 4096, 16384, 65536 }; U32 InnerCode; U32 L; /* Timing loop capture time (Ms) */ if (STV0199A_HANDLE(Demod_p)->DampingFactor2 >= 707) { /* Damping factor greater than the optimum value */ ScanParams_p->TimingLoopParams.TimingLoopWait = 1 + (U16)((2 * STV0199A_HANDLE(Demod_p)->DampingFactor2) / STV0199A_HANDLE(Demod_p)->NaturalFrequency2); } else { /* Damping factor lower than the optimum value */ ScanParams_p->TimingLoopParams.TimingLoopWait = 1 + (U16)((1000000 / STV0199A_HANDLE(Demod_p)->DampingFactor2) / STV0199A_HANDLE(Demod_p)->NaturalFrequency2); } /* QPSK capture time (ms) -- for the carrier damping factor, the true value * decrease strongly with the C/N ratio. With a C/N equal to 3 dB, the * damping factor is 2 or 3 times over the true equivalent damping factor. */ if (STV0199A_HANDLE(Demod_p)->DampingFactor1 >= 707) { /* damping factor greater than the optimum value */ ScanParams_p->QPSKParams.QPSKWaitValue = 1 + (U16)(2 * STV0199A_HANDLE(Demod_p)->DampingFactor1 / STV0199A_HANDLE(Demod_p)->NaturalFrequency1); } else { /* damping factor lower than the optimum value */ ScanParams_p->QPSKParams.QPSKWaitValue = 1 + (U16)((1000000 / STV0199A_HANDLE(Demod_p)->DampingFactor1) / STV0199A_HANDLE(Demod_p)->NaturalFrequency1); } /* Data capture time (ms) -- this time is due to the Viterbi * synchronisation. * For each authorized inner code, the Viterbi search time is calculated, * and the results are cumulated in Viterbi search. */ Error = STV0199A_GetE(STV0199A_HANDLE(Demod_p)); /* Rate indicator (VENRATE register) */ if (Error != DEMOD_NO_ERROR) goto timers_done; Error = STV0199A_GetSN(STV0199A_HANDLE(Demod_p)); /* Averaging period indicator (VSEARCH register) */ if (Error != DEMOD_NO_ERROR) goto timers_done; ViterbiSearch = 0 ; InnerCode = 1000; /* InnerCode = 1000* the inner code */ HigherRate = 1000; if ((STV0199A_HANDLE(Demod_p)->E & 0x01) == 0x01) { /* Inner code 1/2 */ InnerCode = 2000; /* 2.0 */ ViterbiSearch += (U16)((PhaseNumber[0] * Averaging[STV0199A_HANDLE(Demod_p)->SN] * InnerCode) / STV0199A_HANDLE(Demod_p)->SymbolRate); if (HigherRate < 2000) HigherRate = 2000; } if (((STV0199A_HANDLE(Demod_p)->E >> 1) & 0x01) == 0x01) { /* Inner code 2/3 */ InnerCode = 1500; /* 1.5 */ ViterbiSearch += (U16)((PhaseNumber[1] * Averaging[STV0199A_HANDLE(Demod_p)->SN] * InnerCode) / STV0199A_HANDLE(Demod_p)->SymbolRate); if (HigherRate < 1500 ) HigherRate = 1500; } if (((STV0199A_HANDLE(Demod_p)->E >> 2) & 0x01) == 0x01) { /* Inner code 3/4 */ InnerCode = 1333; /* 1.333 */ ViterbiSearch += (U16)((PhaseNumber[2] * Averaging[STV0199A_HANDLE(Demod_p)->SN] * InnerCode) / STV0199A_HANDLE(Demod_p)->SymbolRate); if (HigherRate < 1333) HigherRate = 1333; } if (((STV0199A_HANDLE(Demod_p)->E >> 3) & 0x01) == 0x01) { /* Inner code 5/6 */ InnerCode = 1200; /* 1.2 */ ViterbiSearch += (U16)((PhaseNumber[3] * Averaging[STV0199A_HANDLE(Demod_p)->SN] * InnerCode) / STV0199A_HANDLE(Demod_p)->SymbolRate); if (HigherRate < 1200) HigherRate = 1200; } if (((STV0199A_HANDLE(Demod_p)->E >> 4) & 0x01) == 0x01) { /* Inner code 7/8 */ InnerCode = 1143; /* 1.143 */ ViterbiSearch += (U16)((PhaseNumber[4] * Averaging[STV0199A_HANDLE(Demod_p)->SN] * InnerCode) / STV0199A_HANDLE(Demod_p)->SymbolRate); if (HigherRate < 1143) HigherRate = 1143; } /* Time out calculation -- this value indicates the maximum duration of * the synchro word research. */ STV0199A_GetTO(STV0199A_HANDLE(Demod_p)); /* time out value (VSearch register) */ L = (U32)(STV0199A_HANDLE(Demod_p)->TO + 1); TimeOut = (U16)((HigherRate * 16384 * L) / (2 * STV0199A_HANDLE(Demod_p)->SymbolRate)); /* Calculate hysteresis duration */ STV0199A_GetH(STV0199A_HANDLE(Demod_p)); /* hysteresis value (VSearch register) */ L = (U32)(STV0199A_HANDLE(Demod_p)->H + 1); Hysteresis = (U16)((HigherRate * 26112 * L) / (2 * STV0199A_HANDLE(Demod_p)->SymbolRate)); /* 26112 = 16*204*8 bits -- a guard time of 1 mS is added */ ScanParams_p->QPSKParams.DataWaitValue = 1 + ViterbiSearch + TimeOut + Hysteresis;timers_done: return Error;}/*****************************************************************************Name: SubRangeSetting()Description: The derotator control bandwidth is [-Fs/16,+Fs/16]. This routine is responsible for computing how many frequency intervals of width less than Fs/8 can be spanned over the range [-MaxLNBOffset,MaxLNBOffset]. To ensure there is an overlap between the intervals the computation is made with Fs/8 minus one derotator step (usually 6). The range used will be [-127,+127] -- derotator settings. -lnb_max lnb_max ||-srl | ... | -1 | 0 | 1 | ... | srl || || | | | | | | | | | | | | | || ||_____|_____|_____|_____|_____|_____|_____|| <---> (srl = sub range limit) sub range size (<= Fs/8)Parameters: Demod_p, pointer to the DEMOD device. ScanParams_p, pointer to scan parameters in use.Return Value: None.See Also: Nothing.*****************************************************************************/static void SubRangeSetting(DEMOD_ControlBlock_t *Demod_p, DEMOD_ScanParams_t *ScanParams_p){ U16 I; U32 L; /* In order to avoid frontier effects ("twilight zones"), an overlap of * at least 'DerotatorStep' derotator steps is garantized. */ L = STV0199A_HANDLE(Demod_p)->SymbolRate / 8 - (STV0199A_HANDLE(Demod_p)->SymbolRate * ScanParams_p->DerotatorParams.DerotatorStep) / 2048; /* 2048=8*256 */ I = (U16)((2 * ScanParams_p->MaxLNBOffset)/L) + 1; /* range = [-sub_range_limit,+sub_range_limit] */ ScanParams_p->SubRangeParams.SubRangeLimit = I/2; /* Once the number of subranges computed, the subrange size is increased * with derotator_step*Fs/8, in order to guarantee the overlap * The interval size must be a multiple of TunerStep, which is the * resolution of the tuner. */ L = (2 * ScanParams_p->MaxLNBOffset) / (2 * ScanParams_p->SubRangeParams.SubRangeLimit + 1); L += (ScanParams_p->DerotatorParams.DerotatorStep * STV0199A_HANDLE(Demod_p)->SymbolRate) / 2048; /* Overlap guarantee */ ScanParams_p->SubRangeParams.SubRangeSize = (U16)((L / ScanParams_p->TunerStep) + 1) * (ScanParams_p->TunerStep / 1000); /* in KHz */ if (ScanParams_p->SubRangeParams.SubRangeSize > (STV0199A_HANDLE(Demod_p)->SymbolRate / 8000)) { ScanParams_p->SubRangeParams.SubRangeSize = STV0199A_HANDLE(Demod_p)->SymbolRate / 8000; } /* Will be initialised by Scan(), in case of SCPC */ ScanParams_p->SubRangeParams.SubRangeInit = 0;}/*****************************************************************************Name: FastSearch()Description: This routine sets the tuner frequency and checks the AGC integrator in order to detect whether or not there is a signal.Parameters: Demod_p, pointer to demod device. Frequency, tuner IF. NewFrequency_p, the new frequency value to store -- may be different to required setting. AGCLevelGood_p, boolean to set to indicate whether or not there is a signal.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 FastSearch(DEMOD_ControlBlock_t *Demod_p, U32 Frequency, U32 *NewFrequency_p, BOOL *AGCLevelGood_p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -