source: svn/newcon3bcm2_21bu/magnum/portinginterface/thd/7552/bthd_acq_isdbt.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 45.5 KB
Line 
1/******************************************************************************
2*     (c)2010-2011 Broadcom Corporation
3
4*  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5*  and may only be used, duplicated, modified or distributed pursuant to the terms and
6*  conditions of a separate, written license agreement executed between you and Broadcom
7*  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8*  no license (express or implied), right to use, or waiver of any kind with respect to the
9*  Software, and Broadcom expressly reserves all rights in and to the Software and all
10*  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11*  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12*  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. 
13*   
14*  Except as expressly set forth in the Authorized License,
15*   
16*  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17*  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18*  and to use this information only in connection with your use of Broadcom integrated circuit products.
19*   
20*  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21*  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22*  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23*  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24*  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25*  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26*  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27*  USE OR PERFORMANCE OF THE SOFTWARE.
28
29*  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30*  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31*  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32*  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33*  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34*  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35*  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36*  ANY LIMITED REMEDY.
37*
38 *****************************************************************************/
39/***************************************************************************
40*     (c)2005-2011 Broadcom Corporation
41
42*
43* $brcm_Workfile: bthd_acq_isdbt.c $
44* $brcm_Revision: 8 $
45* $brcm_Date: 12/21/11 2:25p $
46*
47* [File Description:]
48*
49* Revision History:
50*
51* $brcm_Log: /AP/ctfe/core/thd/bthd_acq_isdbt.c $
52*
53* 8   12/21/11 2:25p farshidf
54* SW3128-1: remove warning
55*
56* 7   10/13/11 7:32p farshidf
57* SW3461-64: merge to main
58*
59* Fw_Integration_Devel/6   10/13/11 6:58p farshidf
60* SW3461-64: merge to integ
61*
62* Fw_Integration_Devel/AP_V3_0_THD_DEV/1   9/26/11 2:40p mbsingh
63* SW3461-1: Merge from 2.0 dev branch (This is mainly a shift to WPO
64*  algorithm)
65*
66* Fw_Integration_Devel/AP_V2_0_THD_DEV/2   9/8/11 10:49p mbsingh
67* SW3461-1:  Separated SetFW function cleanly now to make DVBT work for
68*  ISDBT containing chips also.  In initial merged code from THD_FTT_WPO
69*  branch DVBT would work only in non ISDBT chips due to wrong SetFW
70*  function selection
71*
72* 6   8/24/11 5:55p farshidf
73* SW7552-60: merge to main
74*
75* Fw_Integration_Devel/5   8/24/11 5:48p farshidf
76* SW7552-60: add the isdb-t constellation
77*
78* Fw_Integration_Devel/AP_V2_0_THD_DEV/1   8/24/11 5:41p farshidf
79* SW7552-60: add the softdecision for isdbt
80*
81* 5   8/24/11 12:33p farshidf
82* SW3461-38: merge to main
83*
84* Fw_Integration_Devel/4   8/17/11 4:06p farshidf
85* SW3461-1: update the printf
86*
87* 4   8/17/11 4:04p farshidf
88* SW3461-1: update the printf
89*
90* 3   7/20/11 12:38p farshidf
91* SW7552-60: warning fix
92*
93* 2   7/20/11 12:11p farshidf
94* SW7552-60: merge to main
95*
96* Fw_Integration_Devel/2   7/20/11 12:07p farshidf
97* SW7552-60: latest ISDB-T
98*
99* Fw_Integration_Devel/AP_V0_6_THD_DEV/1   7/12/11 3:39p jchien
100* AP_V0_6_THD_DEV: add ResetLockSetClrFlag and SetRsRt
101*
102* Fw_Integration_Devel/1   6/29/11 12:39p farshidf
103* SW3461-13: merge to integration branch
104*
105* Fw_Integration_Devel/Dvbt_Fw_Devel_Rc05/1   6/14/11 6:44p jchien
106* DVBT_FW_Devel_Rc05: fix a bug introduced during code port in
107*  state_track.  add seamless to speed up acquisition
108*
109* 1   6/8/11 5:41p farshidf
110* SW3461-1: merge main
111*
112* Hydra_Software_Devel/4   6/1/11 11:49a farshidf
113* SW7552-36: clean up
114*
115* Hydra_Software_Devel/3   5/31/11 7:37p farshidf
116* SW7552-36: remove ISDB-T warning
117*
118* Hydra_Software_Devel/2   5/24/11 1:56p farshidf
119* SWDTV-7146: merge to main
120*
121* Hydra_Software_Devel/SWDTV-7146/2   5/24/11 12:22p jchien
122* SWDTV-7146: add ISDBT RS_SYNC monitor for three layers
123*
124* Hydra_Software_Devel/SWDTV-7146/1   5/17/11 4:41p jchien
125* SWDTV-7146: fix isdbt status
126*
127* Hydra_Software_Devel/1   5/16/11 5:18p farshidf
128* SWDTV-7035: merge to main
129*
130* Hydra_Software_Devel/SWDTV-6857/1   5/3/11 4:20p jchien
131* SWDTV-6857: initial check-in
132*
133* 1   3/4/11 5:30p jchien
134* SW3461-1: Initial check-in
135*
136*
137***************************************************************************/
138#include "bstd.h"
139#include "bmth.h"
140#include "bkni.h"
141#include "btmr.h"
142
143#ifndef LEAP_BASED_CODE
144#include "bthd_3x7x.h"
145#endif
146
147#include "bchp_thd_core.h"
148#include "bthd_api.h"
149#include "bthd_acq.h"
150#include "bthd_acq_isdbt.h"
151#include "bthd_coef.h"
152
153#include "bchp_thd_intr2.h"
154#include "bchp_thd_intr2b.h"
155
156#ifdef LEAP_BASED_CODE
157#include "bchp_leap_ctrl.h"
158#include "bthd_irq.h"
159#endif
160
161#ifndef LEAP_BASED_CODE
162BDBG_MODULE(bthd_acq_isdbt);
163#endif
164
165
166/***************************************************************************
167 * BTHD_P_SetFW()
168 ***************************************************************************/
169void BTHD_P_SetFW( BTHD_3x7x_Handle h, 
170                   THD_FFTWindowMode_t FFTWindowMode, 
171                   THD_TransmissionMode_t TransmissionMode, 
172                   THD_GuardInterval_t GuardInterval)
173{
174  uint32_t fw= 0,fw_search=0,N=bthd_transmission_mode[TransmissionMode];
175
176  switch (FFTWindowMode) {
177  case THD_FFTWindowMode_InSpan:
178    /*fw_search = 0x11102000 | (8 * (N/2048)); */ /* FFT window min_scale=1.0625,start_index_mode=1,1st peak mode,L=8*N/2048 */
179    fw_search = 0x11802000 | (8 * (N/2048));  /* FFT window min_scale=1.5,start_index_mode=1,1st peak mode,L=8*N/2048 */
180    fw = 0x03214071;
181    break;
182  case THD_FFTWindowMode_OutOfSpanPost: 
183    fw_search = 0x11400000 | (8 * (N/2048));  /* FFT window min_scale=1.25,start_index_mode=0,1st peak mode,L=8*N/2048 */
184    fw = 0x03014071;     
185    break;
186  case THD_FFTWindowMode_OutOfSpanPre: 
187    fw_search = 0x11402000 | (8 * (N/2048));  /* FFT window min_scale=1.5,start_index_mode=1,1st peak mode,L=8*N/2048 */   
188    fw = 0x03014071;
189    break;
190  default:
191    BDBG_WRN(("BTHD_SetFW: THD_FFTWindowMode_Auto not supported")); 
192    break;
193  } 
194
195  /* Disable expanded search mode for GI=1/4 due to acquisition instability */
196  /* if (GuardInterval == 3) */
197  fw = fw & 0xfcffffff;
198
199#ifdef FASTACQ
200  fw = (fw & 0xffff00ff) | 0x00002000;
201#endif
202  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW,fw );
203  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SEARCH,fw_search);
204  if (FFTWindowMode == THD_FFTWindowMode_OutOfSpanPre) {
205    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_OFFSET,0x00000000 );  /* FFT window offset=0 */
206  } else {
207    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_OFFSET,0x00000010 );  /* FFT window offset=16 */
208  }
209  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_MISC,0x0000020a );      /* FFT window leak to timing loop disabled, disallow zeros */
210  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SPAN,0x00000200 );      /* FFT window span scale = 0.25 */
211
212  /* Setup frequency interpolator coefficients for out-of-span conditions */
213  if (FFTWindowMode != THD_FFTWindowMode_InSpan) {
214    if (FFTWindowMode == THD_FFTWindowMode_OutOfSpanPre) {
215      if (GuardInterval == THD_GuardInterval_1_4)
216        BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_OutOfSpanPre_1_4);
217      else if (GuardInterval == THD_GuardInterval_1_8)
218        BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_OutOfSpanPre_1_8);
219      else
220        BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_OutOfSpanPre_1_16);
221    }
222    else
223      BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_OutOfSpanPost);
224  }
225 
226  /*
227  switch (FFTWindowMode) {
228  case BTHD_FFTWindowMode_InSpan:        BDBG_MSG(("BTHD_P_SetFW:\t\tIn-Span")); break;
229  case BTHD_FFTWindowMode_OutOfSpanPost: BDBG_MSG(("BTHD_P_SetFW:\t\tOut-of-Span Postcursor")); break;
230  case BTHD_FFTWindowMode_OutOfSpanPre:  BDBG_MSG(("BTHD_P_SetFW:\t\tOut-of-Span Precursor")); break;
231  default:                              BDBG_WRN(("BTHD_P_SetFW: THD_FFTWindowMode_Auto not supported")); break;
232  }
233  */
234}
235
236/******************************************************************************
237 * BTHD_P_GetIsdbtSoftDecisionBuf()
238 ******************************************************************************/
239BERR_Code BTHD_P_GetIsdbtSoftDecisionBuf(BTHD_3x7x_Handle h,  /* [in] BTHD handle */
240    int16_t nbrToGet,                 /* [in] Number values to get */
241    int16_t *pI,                      /* [out] Ptr to array to store output I soft decision */
242    int16_t *pQ,                      /* [out] Ptr to array to store output Q soft decision */
243    int16_t *nbrGotten                /* [out] Number of values gotten/read */
244    )
245{
246
247  uint32_t softValue, layerType;
248  uint8_t idx=0;
249  uint32_t layerAQam = bthd_transmission_mode_isdbt[BREG_ReadField(h->hRegister, THD_CORE_TMCC_LAYER_0, LAYERA_QAM )];
250  uint32_t layerBQam = bthd_transmission_mode_isdbt[BREG_ReadField(h->hRegister, THD_CORE_TMCC_LAYER_1, LAYERB_QAM )];
251  uint32_t layerCQam = bthd_transmission_mode_isdbt[BREG_ReadField(h->hRegister, THD_CORE_TMCC_LAYER_1, LAYERC_QAM )];
252  uint32_t N = bthd_transmission_mode[BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE )];
253  uint32_t GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
254
255  BSTD_UNUSED(nbrGotten);
256  BSTD_UNUSED(nbrToGet);
257 
258
259  while (idx < 30) {
260    softValue = BREG_Read32(h->hRegister, BCHP_THD_CORE_SOFT_READ_DATA);
261        layerType  = ((softValue >> 2) & 0x3);
262    pI[idx] = (int)((softValue >> 18) & 0x3FFF);
263    pQ[idx] = (int)((softValue >> 4) & 0x3FFF);
264
265    if ((pI[idx] & 0x2000) == 0x2000)
266        pI[idx] -= 0x4000;
267    if ((pQ[idx] & 0x2000) == 0x2000)
268         pQ[idx] -= 0x4000;
269     switch (layerType)
270     {
271        case 0:
272             pI[idx] = pI[idx] * layerAQam;
273             pQ[idx] = pQ[idx] * layerAQam;
274             break;
275         case 1:
276              pI[idx] =  pI[idx] * layerBQam;
277              pQ[idx] =  pQ[idx] * layerBQam;
278              break;
279          case 2:
280               pI[idx] =  pI[idx] * layerCQam;
281               pQ[idx] =  pQ[idx] * layerCQam;
282               break;
283            default:
284                                break;
285       }
286    idx++;
287    BTHD_P_OSleep(h,1,N,GuardInterval);
288  }
289
290  return BERR_SUCCESS;
291}
292
293/***************************************************************************
294 * BTHD_P_IsdbtSetTMCC()
295 ***************************************************************************/
296BTHD_RESULT BTHD_P_IsdbtSetTMCC( BTHD_3x7x_Handle h, 
297                               THD_TransmissionMode_t TransmissionMode, 
298                               THD_GuardInterval_t GuardInterval)
299{
300  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
301  uint32_t temp_0, temp_1, N=bthd_transmission_mode[TransmissionMode];
302  BREG_WriteField(h->hRegister, THD_CORE_RST2, TMCC_RST, 1);     
303  BREG_WriteField(h->hRegister, THD_CORE_RST2, TMCC_ERC_RST, 1); 
304  BREG_WriteField(h->hRegister, THD_CORE_RST2, TMCC_ERC_RST, 0); 
305  BREG_WriteField(h->hRegister, THD_CORE_RST2, ISDBT_TDI_RST, 1);
306  BREG_WriteField(h->hRegister, THD_CORE_RST2, ISDBT_TDI_RST, 0);
307
308  if (h->pAcquireParam->IsdbtAcquireParam.TMCCMode == THD_IsdbtTMCCMode_Manual) {
309    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, PRFLAG,     h->pAcquireParam->IsdbtAcquireParam.Pr);
310    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_QAM, h->pAcquireParam->IsdbtAcquireParam.Qam[0]);
311    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_CR,  h->pAcquireParam->IsdbtAcquireParam.CodeRate[0]);
312    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_TI,  h->pAcquireParam->IsdbtAcquireParam.TimeInt[0]);
313    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_SEG, h->pAcquireParam->IsdbtAcquireParam.Segments[0]);
314
315    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_QAM, h->pAcquireParam->IsdbtAcquireParam.Qam[1]);
316    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_CR,  h->pAcquireParam->IsdbtAcquireParam.CodeRate[1]);
317    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_TI,  h->pAcquireParam->IsdbtAcquireParam.TimeInt[1]);
318    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG, h->pAcquireParam->IsdbtAcquireParam.Segments[1]);
319
320    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_QAM, h->pAcquireParam->IsdbtAcquireParam.Qam[2]);
321    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_CR,  h->pAcquireParam->IsdbtAcquireParam.CodeRate[2]);
322    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_TI,  h->pAcquireParam->IsdbtAcquireParam.TimeInt[2]);
323    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG, h->pAcquireParam->IsdbtAcquireParam.Segments[2]);
324
325    BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, USE_OV, 1);
326    BREG_WriteField(h->hRegister, THD_CORE_RST2, TMCC_RST, 0);     
327  } else {
328    BREG_WriteField(h->hRegister, THD_CORE_RST2, TMCC_RST, 0);     
329#if LEAP_BASED_CODE
330    ThdL2_EnableIsr(BCHP_INT_ID_TMCC_SYNC_INTR);
331#else
332        BINT_EnableCallback( h->hTmccSyncCallback);
333#endif
334    if (BKNI_WaitForEvent(h->hTmccSyncEvent, 540) != BERR_SUCCESS) {
335      return_val = THD_AcquireResult_NoTPSLock;
336    }
337#if LEAP_BASED_CODE
338    ThdL2_DisableIsr(BCHP_INT_ID_TMCC_SYNC_INTR); 
339#else
340        BINT_DisableCallback( h->hTmccSyncCallback);
341#endif
342    if (return_val != THD_AcquireResult_NoTPSLock) {
343      BTHD_P_OSleep(h,1,N,GuardInterval);
344      temp_0 =  BREG_Read32(h->hRegister, BCHP_THD_CORE_TMCC_OV_0) & 0xfffe0000;
345      temp_0 |= BREG_ReadField(h->hRegister, THD_CORE_TMCC_MISC, PRFLAG) << 16;
346      temp_0 |= BREG_Read32(h->hRegister, BCHP_THD_CORE_TMCC_LAYER_0) & 0x0000ffff;
347      temp_1 = BREG_Read32(h->hRegister, BCHP_THD_CORE_TMCC_LAYER_1);
348      BREG_Write32(h->hRegister, BCHP_THD_CORE_TMCC_OV_0, temp_0);
349      BREG_Write32(h->hRegister, BCHP_THD_CORE_TMCC_OV_1, temp_1);
350          BREG_WriteField(h->hRegister, THD_CORE_TMCC_OV_0, USE_OV, 1);
351/*
352          temp_0 = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_SEG) * 230;
353          temp_0 |= (temp_0 -1) << 16;
354          BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_RT_CTRL,temp_0);
355          temp_0 = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG) * 230;
356          if (temp_0 > 0) {
357                temp_0 |= (temp_0 -1) << 16;
358                BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_RT_CTRL_B,temp_0);
359          }
360          temp_0 = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG) * 230;
361          if (temp_0 > 0) {
362                temp_0 |= (temp_0 -1) << 16;
363                BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_RT_CTRL_C,temp_0);
364          }
365*/
366    }
367  }
368  return return_val;
369}       
370
371/***************************************************************************
372 * BTHD_P_IsdbtSetOI()
373 ***************************************************************************/
374void BTHD_P_IsdbtSetOI( BTHD_3x7x_Handle h )
375{
376  BREG_Write32(h->hRegister,  BCHP_THD_CORE_OI_N, 0x00000001 );
377  BREG_Write32(h->hRegister,  BCHP_THD_CORE_OI_D, 0x00000002 );
378  /*
379  BDBG_MSG(("BTHD_P_ISDBTSetOI:\tOIN = 0x%08x", 0x00000001));
380  BDBG_MSG(("                  \tOID = 0x%08x", 0x00000002));
381  */
382}
383
384/***************************************************************************
385 * BTHD_P_IsdbtSetFEC()
386 ***************************************************************************/
387BTHD_RESULT BTHD_P_IsdbtSetFEC( BTHD_3x7x_Handle h )
388{
389
390  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
391
392  /* Set soft decision exponent parameters */
393  BREG_WriteField(h->hRegister, THD_CORE_EQ, FORMAT_OV, 0);
394  BREG_WriteField(h->hRegister, THD_CORE_EQ, EXP_OFFSET, 0);
395
396  /* Configure Viterbi and release resets */
397  BREG_Write32(h->hRegister, BCHP_THD_CORE_VIT, 0x00000100);           /* VIT reacq, no cycle slip, no spectrum inversion */
398  BREG_WriteField(h->hRegister, THD_CORE_RST, FEC_RST, 1 ); 
399  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_RST, 1 );
400  BREG_WriteField(h->hRegister, THD_CORE_RST, FEC_RST, 0 ); 
401  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_RST, 0 );
402  return return_val;
403}
404
405/***************************************************************************
406 * BTHD_P_IsdbtGetNotch()
407 ***************************************************************************/
408BTHD_RESULT BTHD_P_IsdbtGetNotch( BTHD_3x7x_Handle h, 
409                                 THD_TransmissionMode_t TransmissionMode)
410{ 
411  uint32_t iteration=0, start=0,idx,value,max_idx=0, max=0, NumCoChannelFound = 0;
412  uint32_t errpwr;
413  bool CoChannelPresent = false;
414
415  /* Get average pilot noise level.  Scale factor of 45 gives good match to mean snooper level for white noise */
416  errpwr = BREG_Read32(h->hRegister, BCHP_THD_CORE_EQ_SNRP)/45;
417
418  /* Determine whether analog TV CCI is present using snooper.
419     Look for the presence of any 2 of the video, color, or audio carriers. 
420     This 2-out-of-3 criterion allows differentiation between true analog TV CCI
421     and spurs which often occur around sensitivity. If this criterion is too
422     strict, consider using a 1-out-of-3 criterion for input power levels above
423     sensitivity and this 2-out-of-3 criterion for input power levels near sensitivity */
424  iteration = 0;
425  while ((iteration < 3) && !CoChannelPresent) {
426    switch (iteration) {
427      /* Snooper captures only active carriers.  For ISDBT, there are 4617 active carriers. */
428      /* start = 2808 - 128*3 - f*8192*(63/512) */
429      case 0: if (TransmissionMode == THD_TransmissionMode_2k) start=000; else start = 0516; break;  /* Video carrier (f = -1.893) */
430      case 1: if (TransmissionMode == THD_TransmissionMode_2k) start=936; else start = 4124; break;  /* Color carrier (f =  1.687) */
431      case 2: if (TransmissionMode == THD_TransmissionMode_2k) start=936; else start = 4848; break;  /* Audio carrier (f =  2.607) */
432    }
433    BREG_Write32(h->hRegister,  BCHP_THD_CORE_CE_RECORD_CFG,0x05030000 + start );  /* CE snooper capture exponents, snapshot mode, step=3 */
434
435    while (!BREG_ReadField(h->hRegister,  THD_CORE_CE_RECORD_CFG, DONE));
436    BREG_Write32(h->hRegister,  BCHP_THD_CORE_CE_READ_INDEX,0x00000000 );
437    for (idx=0; idx<256; idx++) {
438      value = BREG_Read32(h->hRegister,  BCHP_THD_CORE_CE_READ_DATA );
439          if ((idx == 0) || (value > max)) {
440            max = value;
441                max_idx = idx;
442          }
443    }
444    if (max >= 16*errpwr)                                                                     /* CCI present if min_exp-mean_exp > 3 */
445      NumCoChannelFound++;
446    if (NumCoChannelFound > 1)
447      CoChannelPresent = true;
448    iteration++;
449  }
450  return CoChannelPresent;
451}
452
453/***************************************************************************
454 * BTHD_P_IsdbtSetICE ()
455 ***************************************************************************/
456BTHD_RESULT BTHD_P_IsdbtSetICE( BTHD_3x7x_Handle h, 
457                               THD_TransmissionMode_t TransmissionMode,
458                               THD_GuardInterval_t GuardInterval)
459{
460  int n,k;
461  uint32_t ice[16],ice_val[16],ice_cnt[16],ice_found,ice_val_max,ice_cnt_max,ice_index_max;
462  uint32_t ice_cnt_best=0,ice_val_best=0,ice_index_best=0,spinv_best=0;
463  uint32_t N=bthd_transmission_mode[TransmissionMode];
464  uint32_t iteration = 0;
465  uint32_t carrier_off   = 0;
466  uint32_t carrier_step  = 1;
467  uint32_t carrier_limit = 1;
468  int32_t  cl_int, cl_fcw;
469  bool     ice_done=0;
470
471/*  if ( !(BREG_Read32(h->hRegister, BCHP_THD_CORE_RESERVED2) & 0x80000000) )  */               /* no more reserved2 */
472  switch (GuardInterval) {
473      case THD_GuardInterval_1_4:  carrier_limit = 2;  carrier_step = 1; break;
474      case THD_GuardInterval_1_8:  carrier_limit = 4;  carrier_step = 2; break;
475      case THD_GuardInterval_1_16: carrier_limit = 8;  carrier_step = 4; break;
476      case THD_GuardInterval_1_32: carrier_limit = 16; carrier_step = 8; break;
477  }
478
479  /* Collect ICE values with carrier loop frozen */
480  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CL_FRZ, 1);
481  cl_int = BREG_Read32(h->hRegister,  BCHP_THD_CORE_CL_INT); 
482  cl_fcw = BREG_Read32(h->hRegister,  BCHP_THD_CORE_CL_FCW);
483         
484  for (iteration=0; iteration<2; iteration++) {
485    for (carrier_off=0; carrier_off < carrier_limit; carrier_off += carrier_step) {
486      /* To aid AC1 demodulation, offset initial carrier frequency */
487      if (iteration == 0)
488        BREG_Write32(h->hRegister, BCHP_THD_CORE_CL_INT, cl_int + (carrier_off << 21));
489          else  /* bug fix for spectral inversion.  need to keep the integrator programmed to the inverted value */
490                BREG_Write32(h->hRegister, BCHP_THD_CORE_CL_INT, ((cl_int ^ 0xffffffff) + 1U) + (carrier_off << 21));
491
492      BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CINT_FRZ, 0 );
493      BTHD_P_OSleep(h,3,N,GuardInterval);
494      for (n=0; n<16; n++) {
495        ice[n] = BREG_ReadField(h->hRegister,  THD_CORE_CL_IEST, INT) + carrier_off;
496        ice_val[n] = 0;
497        ice_cnt[n] = 0;
498        BTHD_P_OSleep(h,1,N,GuardInterval);
499        /* BDBG_MSG(("BTHD_P_DvbtSetICE:\tICE = 0x%08x\n",ice[n]); */
500          }
501
502    /* Identify unique ICE values and count number-of-occurrences of each */
503      ice_val[0] = ice[0];
504      ice_cnt[0] = 1;
505      for (n=1; n<16; n++) {
506        ice_found = 0;
507        for (k=0; k<n; k++) {
508              if (ice[n] == ice_val[k]) {  /* found, increment the count */
509                    ice_cnt[k] = ice_cnt[k]+1;
510                ice_found = 1;       
511                  }
512        }
513        if (!ice_found) {              /* not found, add it to the table */
514              ice_val[k] = ice[n];
515              ice_cnt[k] = 1;
516        }
517      }
518      /* Determine value which occurs most often */ 
519      ice_val_max = ice_val[0];
520      ice_cnt_max = ice_cnt[0];
521      ice_index_max = 0;
522      for (n=1; n<16; n++) {
523        if (ice_cnt[n] > ice_cnt_max) {
524              ice_val_max = ice_val[n];
525                  ice_cnt_max = ice_cnt[n];
526                  ice_index_max = n;
527        }
528      }
529      /* BDBG_MSG(("BTHD_P_DvbtSetICE:\tIC Offset = %d, ICE Max = 0x%08x (%d occurences)\n", carrier_off, ice_val[ice_index_max],ice_cnt_max); */
530      /* Keep track of the best result for comparison */
531      if (ice_cnt_max > ice_cnt_best) {
532        ice_cnt_best   =  ice_cnt_max;
533        ice_val_best   =  ice_val_max;
534        ice_index_best =  ice_index_max;
535        spinv_best     =  iteration;
536      }
537
538    /* Check for valid ICE and exit */
539      if ( ice_cnt_best >= 12 ) {
540                ice_done = 1;
541        break;
542          }
543        }
544
545        if (ice_done)
546          break;
547
548    /* Try spectral inversion on second iteration */
549    BDBG_MSG(("BTHD_P_IsdbtSetICE:\tTrying spectral inversion\n"));
550    if (h->pInternalAcquireParam->FrontEndMode == THD_FrontEndMode_Baseband) {
551      BREG_WriteField(h->hRegister, THD_CORE_FE, NEGATE_Q, 1);
552    } else {
553      /*  Negate carrier fcw and integrator */ 
554      BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_FCW, (cl_fcw ^ 0xffffffff) + 1U);
555      BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_INT, (cl_int ^ 0xffffffff) + 1U);   
556    }
557
558    /* Freeze and wait 10 symbols */
559    BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CINT_FRZ, 1 );             /*  Freeze integer carrier estimator*/
560    BTHD_P_OSleep(h,10,N,GuardInterval);
561  }
562
563  /* Reset CL_INT back to initial value (allowing for spectral inversion) */
564  if (iteration)
565    BREG_Write32(h->hRegister, BCHP_THD_CORE_CL_INT, (cl_int ^ 0xffffffff) + 1U);
566  else
567    BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_INT, cl_int);
568
569  /* Uninvert signal if needed. 
570     This can happen if spectral inversion was tested but noninverted spectrum yielded a better ICE */
571  if (iteration && !spinv_best) {
572    if (h->pInternalAcquireParam->FrontEndMode == THD_FrontEndMode_Baseband) {
573      BREG_WriteField(h->hRegister, THD_CORE_FE, NEGATE_Q, 0);
574    } else {
575      BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_FCW, cl_fcw);
576      BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_INT, cl_int);
577    }
578  }
579  if (spinv_best)
580    BDBG_MSG(("BTHD_P_IsdbtSetICE:\tSpectral Inversion Detected\n"));
581 
582  /* Detection flag for suspect ICE result */
583  if (ice_cnt_best < 6) {
584    BDBG_WRN(("BTHD_P_IsdbtSetICE:\tLow ICE Count Detected\n"));
585    h->pStatus->LowICECount = 1;
586  }
587  else {
588    h->pStatus->LowICECount = 0;
589  }
590
591  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CINT_FRZ, 1 );
592  BTHD_P_OSleep(h,1,N,GuardInterval);
593
594  /* BDBG_MSG(("BTHD_P_DvbtSetICE:\tICE Max = 0x%08x (%d occurences)",ice_val_best,ice_cnt_best)); */
595  return(ice_val_best);
596}
597
598/***************************************************************************
599 * BTHD_P_IsdbtStatus()
600 ***************************************************************************/
601void BTHD_P_IsdbtStatus( BTHD_3x7x_Handle h ) 
602{
603  uint32_t  CERC,CBERC,NBERC,UBERC,TBERC,NFERC,UFERC,TFERC,eq_snr;
604  uint32_t  CERC_B,CBERC_B,NBERC_B,UBERC_B,TBERC_B;
605  uint32_t  CERC_C,CBERC_C,NBERC_C,UBERC_C,TBERC_C;
606  uint32_t  sft_scale;
607  uint32_t  tmp_a=0, tmp_b=0, tmp_c=0, scale;
608  uint32_t  pouthi, poutlo, pouthi2, poutlo2, pouthi3, poutlo3;
609
610  const uint8_t scale_table[] = { 29, 27, 25, 29 }; /* Support invalid QAM.*/
611  const uint8_t sft_scale_table[][4] = \
612  {
613    {  2,  2,  2,  2 },
614    { 10, 10, 20, 52 },
615    { 42, 42, 60, 108},
616    {  2,  2,  2,  2 } 
617  };
618  /* Determine transmission parameters */
619  h->pStatus->IsdbtStatus.Ews                   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_MISC, ALERT);
620  h->pStatus->IsdbtStatus.Pr                    =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, PRFLAG); 
621  h->pStatus->IsdbtStatus.Qam[0]                =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_QAM);
622  h->pStatus->IsdbtStatus.Qam[1]                =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_QAM);
623  h->pStatus->IsdbtStatus.Qam[2]                =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_QAM); 
624  h->pStatus->IsdbtStatus.CodeRate[0]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_CR);
625  h->pStatus->IsdbtStatus.CodeRate[1]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_CR); 
626  h->pStatus->IsdbtStatus.CodeRate[2]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_CR); 
627  h->pStatus->IsdbtStatus.TimeInt[0]    =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_TI); 
628  h->pStatus->IsdbtStatus.TimeInt[1]    =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_TI); 
629  h->pStatus->IsdbtStatus.TimeInt[2]    =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_TI); 
630  h->pStatus->IsdbtStatus.Segments[0]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_SEG); 
631  h->pStatus->IsdbtStatus.Segments[1]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG); 
632  h->pStatus->IsdbtStatus.Segments[2]   =               BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG); 
633
634  /* Compute data SNR */
635  /* Layer A SNR */
636  eq_snr = BREG_Read32(h->hRegister, BCHP_THD_CORE_EQ_SNR);
637  if (eq_snr >> (8+2)) {
638        scale           =       scale_table[h->pStatus->IsdbtStatus.Qam[0]];
639        sft_scale       =       sft_scale_table[h->pStatus->IsdbtStatus.Qam[0]][0];
640        tmp_a           =       (sft_scale << (scale-2))/(eq_snr >> (8+2));
641    h->pStatus->IsdbtStatus.SNRData[0] = BMTH_2560log10(tmp_a) - 6165;
642  }
643  /* Layer B SNR */
644  eq_snr = BREG_Read32(h->hRegister, BCHP_THD_CORE_EQ_SNR_B);
645  if (eq_snr >> (8+2)) {
646        scale           =       scale_table[h->pStatus->IsdbtStatus.Qam[1]];
647        sft_scale       =       sft_scale_table[h->pStatus->IsdbtStatus.Qam[1]][0];
648        tmp_b           =       (sft_scale << (scale-2))/(eq_snr >> (8+2));
649        h->pStatus->IsdbtStatus.SNRData[1] = BMTH_2560log10(tmp_b) - 6165;
650  }
651  /* Layer C SNR */
652  eq_snr = BREG_Read32(h->hRegister, BCHP_THD_CORE_EQ_SNR_C);
653  if (eq_snr >> (8+2)) {
654        scale           =       scale_table[h->pStatus->IsdbtStatus.Qam[2]];
655        sft_scale       =       sft_scale_table[h->pStatus->IsdbtStatus.Qam[2]][0];
656        tmp_c           =       (sft_scale << (scale-2))/(eq_snr >> (8+2));
657    h->pStatus->IsdbtStatus.SNRData[2] = BMTH_2560log10(tmp_c) - 6165;
658  }
659  /* Layer Weighted SNR */
660  BMTH_HILO_32TO64_Mul(tmp_a, h->pStatus->IsdbtStatus.Segments[0], &pouthi, &poutlo);
661  BMTH_HILO_32TO64_Mul(tmp_b, h->pStatus->IsdbtStatus.Segments[1], &pouthi2, &poutlo2);
662  BMTH_HILO_64TO64_Add(pouthi, poutlo, pouthi2, poutlo2, &pouthi3, &poutlo3);
663  BMTH_HILO_32TO64_Mul(tmp_c, h->pStatus->IsdbtStatus.Segments[2], &pouthi, &poutlo);
664  BMTH_HILO_64TO64_Add(pouthi, poutlo, pouthi3, poutlo3, &pouthi2, &poutlo2);
665  BMTH_HILO_64TO64_Div32(pouthi2, poutlo2,  13, &pouthi, &poutlo);
666  h->pStatus->SNR                                = BMTH_2560log10(poutlo) - 6165;
667
668  /* Read hardware error counters */
669  BREG_WriteField(h->hRegister, THD_CORE_FEC, CAPERC, 1 ); 
670
671  NFERC = BREG_Read32(h->hRegister,  BCHP_THD_CORE_NFERC );
672  UFERC = BREG_Read32(h->hRegister,  BCHP_THD_CORE_UFERC );
673  TFERC = NFERC + UFERC; 
674
675  CERC  = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CERC );
676  NBERC = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_NBERC );
677  CBERC = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CBERC );
678  UBERC = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_UBERC );
679  TBERC = NBERC + CBERC + UBERC;
680
681  CERC_B  = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CERC_B );
682  NBERC_B = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_NBERC_B );
683  CBERC_B = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CBERC_B );
684  UBERC_B = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_UBERC_B );
685  TBERC_B = NBERC_B + CBERC_B + UBERC_B;
686
687  CERC_C  = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CERC_C );
688  NBERC_C = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_NBERC_C );
689  CBERC_C = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_CBERC_C );
690  UBERC_C = BREG_Read32(h->hRegister,  BCHP_THD_CORE_RS_UBERC_C );
691  TBERC_C = NBERC_C + CBERC_C + UBERC_C;
692
693  BREG_WriteField(h->hRegister, THD_CORE_FEC, CAPERC, 0 ); 
694
695  /* Update software error counters */
696  h->pStatus->IsdbtStatus.TS_NFERC = h->pStatus->IsdbtStatus.TS_NFERC_ref + NFERC;
697  h->pStatus->IsdbtStatus.TS_UFERC = h->pStatus->IsdbtStatus.TS_UFERC_ref + UFERC;
698  h->pStatus->IsdbtStatus.TS_TFERC = h->pStatus->IsdbtStatus.TS_TFERC_ref + TFERC;
699
700  h->pStatus->IsdbtStatus.TS_CERC[0]  = h->pStatus->IsdbtStatus.TS_CERC_ref[0]  + CERC;
701  h->pStatus->IsdbtStatus.TS_NBERC[0] = h->pStatus->IsdbtStatus.TS_NBERC_ref[0] + NBERC;
702  h->pStatus->IsdbtStatus.TS_CBERC[0] = h->pStatus->IsdbtStatus.TS_CBERC_ref[0] + CBERC;
703  h->pStatus->IsdbtStatus.TS_UBERC[0] = h->pStatus->IsdbtStatus.TS_UBERC_ref[0] + UBERC;
704  h->pStatus->IsdbtStatus.TS_TBERC[0] = h->pStatus->IsdbtStatus.TS_TBERC_ref[0] + TBERC;
705
706  h->pStatus->IsdbtStatus.TS_CERC[1]  = h->pStatus->IsdbtStatus.TS_CERC_ref[1]  + CERC_B;
707  h->pStatus->IsdbtStatus.TS_NBERC[1] = h->pStatus->IsdbtStatus.TS_NBERC_ref[1] + NBERC_B;
708  h->pStatus->IsdbtStatus.TS_CBERC[1] = h->pStatus->IsdbtStatus.TS_CBERC_ref[1] + CBERC_B;
709  h->pStatus->IsdbtStatus.TS_UBERC[1] = h->pStatus->IsdbtStatus.TS_UBERC_ref[1] + UBERC_B;
710  h->pStatus->IsdbtStatus.TS_TBERC[1] = h->pStatus->IsdbtStatus.TS_TBERC_ref[1] + TBERC_B;
711
712  h->pStatus->IsdbtStatus.TS_CERC[2]  = h->pStatus->IsdbtStatus.TS_CERC_ref[2]  + CERC_C;
713  h->pStatus->IsdbtStatus.TS_NBERC[2] = h->pStatus->IsdbtStatus.TS_NBERC_ref[2] + NBERC_C;
714  h->pStatus->IsdbtStatus.TS_CBERC[2] = h->pStatus->IsdbtStatus.TS_CBERC_ref[2] + CBERC_C;
715  h->pStatus->IsdbtStatus.TS_UBERC[2] = h->pStatus->IsdbtStatus.TS_UBERC_ref[2] + UBERC_C;
716  h->pStatus->IsdbtStatus.TS_TBERC[2] = h->pStatus->IsdbtStatus.TS_TBERC_ref[2] + TBERC_C;
717
718  /* Reset hardware error counters every 10 one-second frames */
719  if (TFERC >= THD_StatusFramesForReset) {
720    BTHD_P_ResetStatusHW(h);
721    h->pStatus->IsdbtStatus.TS_CERC_ref[0]  = h->pStatus->IsdbtStatus.TS_CERC[0];
722    h->pStatus->IsdbtStatus.TS_NBERC_ref[0] = h->pStatus->IsdbtStatus.TS_NBERC[0];
723    h->pStatus->IsdbtStatus.TS_CBERC_ref[0] = h->pStatus->IsdbtStatus.TS_CBERC[0];
724    h->pStatus->IsdbtStatus.TS_UBERC_ref[0] = h->pStatus->IsdbtStatus.TS_UBERC[0];
725    h->pStatus->IsdbtStatus.TS_TBERC_ref[0] = h->pStatus->IsdbtStatus.TS_TBERC[0];
726
727    h->pStatus->IsdbtStatus.TS_CERC_ref[1]  = h->pStatus->IsdbtStatus.TS_CERC[1];
728    h->pStatus->IsdbtStatus.TS_NBERC_ref[1] = h->pStatus->IsdbtStatus.TS_NBERC[1];
729    h->pStatus->IsdbtStatus.TS_CBERC_ref[1] = h->pStatus->IsdbtStatus.TS_CBERC[1];
730    h->pStatus->IsdbtStatus.TS_UBERC_ref[1] = h->pStatus->IsdbtStatus.TS_UBERC[1];
731    h->pStatus->IsdbtStatus.TS_TBERC_ref[1] = h->pStatus->IsdbtStatus.TS_TBERC[1];
732
733    h->pStatus->IsdbtStatus.TS_CERC_ref[2]  = h->pStatus->IsdbtStatus.TS_CERC[2];
734    h->pStatus->IsdbtStatus.TS_NBERC_ref[2] = h->pStatus->IsdbtStatus.TS_NBERC[2];
735    h->pStatus->IsdbtStatus.TS_CBERC_ref[2] = h->pStatus->IsdbtStatus.TS_CBERC[2];
736    h->pStatus->IsdbtStatus.TS_UBERC_ref[2] = h->pStatus->IsdbtStatus.TS_UBERC[2];
737    h->pStatus->IsdbtStatus.TS_TBERC_ref[2] = h->pStatus->IsdbtStatus.TS_TBERC[2];
738
739    h->pStatus->IsdbtStatus.TS_NFERC_ref = h->pStatus->IsdbtStatus.TS_NFERC;
740    h->pStatus->IsdbtStatus.TS_UFERC_ref = h->pStatus->IsdbtStatus.TS_UFERC;
741    h->pStatus->IsdbtStatus.TS_TFERC_ref = h->pStatus->IsdbtStatus.TS_TFERC;
742  } 
743
744  /* Compute Viterbi BER and TS PER */
745  if (h->pStatus->IsdbtStatus.TS_TBERC[0]) {
746    /* h->pStatus->IsdbtStatus.TS_PER[0] = (h->pStatus->IsdbtStatus.TS_UBERC[0] * (1ULL<<31)) / h->pStatus->IsdbtStatus.TS_TBERC[0]; */
747    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_UBERC[0]), &pouthi, &poutlo);
748    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[0]), &pouthi, &h->pStatus->IsdbtStatus.TS_PER[0] );
749    /* h->pStatus->IsdbtStatus.VitBER[0] = (h->pStatus->IsdbtStatus.TS_CERC[0] * (1ULL<<31)) / (h->pStatus->IsdbtStatus.TS_TBERC[0] * 8 * 188ULL); */
750    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_CERC[0]), &pouthi, &poutlo);
751    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[0] * 8 * 188), &pouthi, &h->pStatus->IsdbtStatus.VitBER[0] );
752  }
753  if (h->pStatus->IsdbtStatus.TS_TBERC[1]) {
754    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_UBERC[1]), &pouthi, &poutlo);
755    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[1]), &pouthi, &h->pStatus->IsdbtStatus.TS_PER[1] );
756    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_CERC[1]), &pouthi, &poutlo);
757    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[1] * 8 * 188), &pouthi, &h->pStatus->IsdbtStatus.VitBER[1] );
758  }
759  if (h->pStatus->IsdbtStatus.TS_TBERC[2]) {
760    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_UBERC[2]), &pouthi, &poutlo);
761    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[2]), &pouthi, &h->pStatus->IsdbtStatus.TS_PER[2] );
762    BMTH_HILO_32TO64_Mul(0x80000000, (h->pStatus->IsdbtStatus.TS_CERC[2]), &pouthi, &poutlo);
763    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TBERC[2] * 8 * 188), &pouthi, &h->pStatus->IsdbtStatus.VitBER[2] );
764  }
765  if (h->pStatus->IsdbtStatus.TS_TFERC){
766    /* h->pStatus->IsdbtStatus.TS_ESR = ((100ULL * h->pStatus->IsdbtStatus.TS_UFERC) / h->pStatus->IsdbtStatus.TS_TFERC); */
767    BMTH_HILO_32TO64_Mul(100, (h->pStatus->IsdbtStatus.TS_UFERC), &pouthi, &poutlo);
768    BMTH_HILO_64TO64_Div32(pouthi, poutlo, (h->pStatus->IsdbtStatus.TS_TFERC), &pouthi, &h->pStatus->IsdbtStatus.TS_ESR );
769  }
770}
771
772
773/***************************************************************************
774 * BTHD_P_IsdbtResetStatus()
775 ***************************************************************************/
776void BTHD_P_IsdbtResetStatus( BTHD_3x7x_Handle h )
777{
778  h->pStatus->IsdbtStatus.TS_UFERC     = 0; 
779  h->pStatus->IsdbtStatus.TS_NFERC     = 0;
780  h->pStatus->IsdbtStatus.TS_TFERC     = 0;
781
782  h->pStatus->IsdbtStatus.TS_UFERC_ref = 0; 
783  h->pStatus->IsdbtStatus.TS_NFERC_ref = 0;
784  h->pStatus->IsdbtStatus.TS_TFERC_ref = 0;
785
786  h->pStatus->IsdbtStatus.TS_ESR       = 0;
787
788  h->pStatus->IsdbtStatus.TS_CERC[0]      = 0;
789  h->pStatus->IsdbtStatus.TS_CBERC[0]     = 0;
790  h->pStatus->IsdbtStatus.TS_UBERC[0]     = 0; 
791  h->pStatus->IsdbtStatus.TS_NBERC[0]     = 0;
792  h->pStatus->IsdbtStatus.TS_TBERC[0]     = 0;
793  h->pStatus->IsdbtStatus.VitBER[0]       = 0;
794  h->pStatus->IsdbtStatus.TS_PER[0]       = 0;
795
796  h->pStatus->IsdbtStatus.TS_CERC[1]      = 0;
797  h->pStatus->IsdbtStatus.TS_CBERC[1]     = 0;
798  h->pStatus->IsdbtStatus.TS_UBERC[1]     = 0; 
799  h->pStatus->IsdbtStatus.TS_NBERC[1]     = 0;
800  h->pStatus->IsdbtStatus.TS_TBERC[1]     = 0;
801  h->pStatus->IsdbtStatus.VitBER[1]       = 0;
802  h->pStatus->IsdbtStatus.TS_PER[1]       = 0;
803
804  h->pStatus->IsdbtStatus.TS_CERC[2]      = 0;
805  h->pStatus->IsdbtStatus.TS_CBERC[2]     = 0;
806  h->pStatus->IsdbtStatus.TS_UBERC[2]     = 0; 
807  h->pStatus->IsdbtStatus.TS_NBERC[2]     = 0;
808  h->pStatus->IsdbtStatus.TS_TBERC[2]     = 0;
809  h->pStatus->IsdbtStatus.VitBER[2]       = 0;
810  h->pStatus->IsdbtStatus.TS_PER[2]       = 0;
811
812  h->pStatus->IsdbtStatus.TS_CERC_ref[0]      = 0;
813  h->pStatus->IsdbtStatus.TS_CBERC_ref[0]     = 0;
814  h->pStatus->IsdbtStatus.TS_UBERC_ref[0]     = 0; 
815  h->pStatus->IsdbtStatus.TS_NBERC_ref[0]     = 0;
816  h->pStatus->IsdbtStatus.TS_TBERC_ref[0]     = 0;
817
818  h->pStatus->IsdbtStatus.TS_CERC_ref[1]      = 0;
819  h->pStatus->IsdbtStatus.TS_CBERC_ref[1]     = 0;
820  h->pStatus->IsdbtStatus.TS_UBERC_ref[1]     = 0; 
821  h->pStatus->IsdbtStatus.TS_NBERC_ref[1]     = 0;
822  h->pStatus->IsdbtStatus.TS_TBERC_ref[1]     = 0;
823
824  h->pStatus->IsdbtStatus.TS_CERC_ref[2]      = 0;
825  h->pStatus->IsdbtStatus.TS_CBERC_ref[2]     = 0;
826  h->pStatus->IsdbtStatus.TS_UBERC_ref[2]     = 0; 
827  h->pStatus->IsdbtStatus.TS_NBERC_ref[2]     = 0;
828  h->pStatus->IsdbtStatus.TS_TBERC_ref[2]     = 0;
829}
830
831/***************************************************************************
832 * BTHD_P_IsdbtResetLockSetClrFlag()
833 ***************************************************************************/
834void BTHD_P_IsdbtResetLockSetClrFlag( BTHD_3x7x_Handle h )
835{
836  h->pAcquireParam->IsdbtLocaleParam.set_a = 0;
837  h->pAcquireParam->IsdbtLocaleParam.set_b = 0;
838  h->pAcquireParam->IsdbtLocaleParam.set_c = 0;
839  h->pAcquireParam->IsdbtLocaleParam.clr_a = 0;
840  h->pAcquireParam->IsdbtLocaleParam.clr_b = 0;
841  h->pAcquireParam->IsdbtLocaleParam.clr_c = 0;
842}
843
844/***************************************************************************
845 * BTHD_P_IsdbtSetRSRT()
846 ***************************************************************************/
847void BTHD_P_IsdbtSetRsRt( BTHD_3x7x_Handle h, uint32_t nom_scale, uint32_t t_div)
848{
849
850  uint32_t count_a, count_b, count_c;
851        BSTD_UNUSED(nom_scale);
852  /* 3000 /13 ~ 230 per segment.  set to 256 to approximate*/
853  count_a = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_SEG) * (256 >> t_div);
854/*  count_a |= (count_a>>nom_scale) << 16; */
855  count_a |= (count_a-1) << 16; 
856  BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL, count_a);                           
857  count_b = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG) * (256 >> t_div);
858/*  count_b |= (count_b>>nom_scale) << 16; */
859  count_b |= (count_b-1) << 16; 
860  BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_B, count_b); 
861  count_c = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG) * (256 >> t_div);
862/*  count_c |= (count_c>>nom_scale) << 16; */
863  count_c |= (count_c-1) << 16; 
864  BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_C, count_c); 
865/*  BDBG_MSG(("RsRt count_a: %0x, count_b: %0x, count_c: %0x, t_div: t_div: %0x", count_a, count_b, count_c, t_div)); */
866}
867
868/***************************************************************************
869 * BTHD_P_IsdbtAcquire()
870 ***************************************************************************/
871BTHD_RESULT BTHD_P_IsdbtAcquire( BTHD_3x7x_Handle h )
872{
873  BTHD_RESULT return_val=THD_AcquireResult_InitLockState;
874
875  THD_FFTWindowMode_t FFTWindowMode=THD_FFTWindowMode_InSpan, FFTWindowModeList[3];
876  THD_ChannelEstimatorMode_t ChannelEstimatorMode=THD_ChannelEstimatorMode_Fixed, ChannelEstimatorModeList[2];
877  THD_State_t NextState=THD_State_Init, LastState=THD_State_Init, State=THD_State_Init;
878  bool Done=false, acqProfileValid[16];
879  uint32_t retries=0, FFTWindowRetries, ChannelEstimatorRetries, fscntInit=0xffffffff, acqProfile[16], k;
880  char     *acqProfileString[16];
881
882  /* Initialize Candidate FFT Window Modes */
883  FFTWindowModeList[0] = THD_FFTWindowMode_InSpan;
884  FFTWindowModeList[1] = THD_FFTWindowMode_OutOfSpanPre;
885  FFTWindowModeList[2] = THD_FFTWindowMode_OutOfSpanPost;
886  if (h->pInternalAcquireParam->FFTWindowMode == THD_FFTWindowMode_Auto) {
887    FFTWindowMode = FFTWindowModeList[0];
888#ifdef FFTTriggerPosition
889    FFTWindowRetries = 2;
890#else
891        FFTWindowRetries = 1;
892#endif
893  } else {
894    FFTWindowMode = h->pInternalAcquireParam->FFTWindowMode;
895    FFTWindowRetries = 0;
896  }
897
898  /* Initialize Candidate Channel Estimator Modes */
899  ChannelEstimatorModeList[0] = THD_ChannelEstimatorMode_Fixed;
900  ChannelEstimatorModeList[1] = THD_ChannelEstimatorMode_Pedestrian;
901  if (h->pInternalAcquireParam->ChannelEstimatorMode == THD_ChannelEstimatorMode_Auto) {
902    ChannelEstimatorMode = ChannelEstimatorModeList[0];
903    ChannelEstimatorRetries = 1;
904  } else {
905    ChannelEstimatorModeList[0] = h->pInternalAcquireParam->ChannelEstimatorMode;
906    ChannelEstimatorRetries = 0;
907  }
908
909  /* Use Fscnt for acquisition time profiling */
910  BREG_Write32(h->hRegister, BCHP_THD_CORE_FSCNT,fscntInit);
911
912  acqProfileString[THD_State_Init] = "Init";
913  acqProfileString[THD_State_SP] = "SP";
914  acqProfileString[THD_State_TPS] = "TPS";
915  acqProfileString[THD_State_FEC] = "FEC";
916  acqProfileString[THD_State_Track] = "Track";
917  acqProfileString[THD_State_ChangeFFTWindow] = "ChangeFFTWindow";
918  acqProfileString[THD_State_CheckLock] = "CheckLock";
919  acqProfileString[THD_State_ChangeChannelEstimator] = "ChangeChannelEstimator";
920  acqProfileString[THD_State_Done] = "Done";
921  for (k=0; k<16; k++)
922    acqProfileValid[k] = false;
923
924  /* State Machine */
925  while (!Done) {
926    switch(State) {
927
928    case THD_State_Init:
929      BDBG_MSG(("\tInit"));
930      h->pInternalAcquireParam->AllowRsSyncEvent = true;
931      return_val = BTHD_P_AcquireInit(h,FFTWindowMode);
932      if ((return_val == THD_AcquireResult_NoSignal) || (return_val == THD_AcquireResult_NoFFTLock))
933                NextState = THD_State_Done;
934      else
935                NextState = THD_State_SP;
936      break;
937
938    case THD_State_SP:
939      BDBG_MSG(("\tSP"));
940      return_val = BTHD_P_AcquireSP(h);
941      if (return_val == THD_AcquireResult_NoSPLock)
942        NextState = THD_State_Done;
943      else
944        NextState = THD_State_TPS;
945      break;
946
947        case THD_State_FFTTrigger:
948      BDBG_MSG(("\tTHD_State_FFTTrigger"));
949      break;
950
951    case THD_State_TPS:
952      BDBG_MSG(("\tTPS"));
953      return_val = BTHD_P_AcquireTPS(h);
954      if (return_val == THD_AcquireResult_NoTPSLock)
955#ifndef ChangeFFTWindowSeamless     
956              if (retries < FFTWindowRetries) {
957                retries++;
958                NextState = THD_State_ChangeFFTWindow;
959              } else
960#endif
961                NextState = THD_State_Done;
962      else
963              NextState = THD_State_FEC;
964      break;
965
966    case THD_State_FEC:
967      BDBG_MSG(("\tFEC"));
968          BTHD_P_IsdbtSetRsRt(h,3,0);                   /* 0: based on approximately 3000 packets */
969          BTHD_P_IsdbtResetLockSetClrFlag(h);   /* clear previous interrupt flags */
970      return_val = BTHD_P_AcquireFEC(h,(retries==0));
971      if (return_val == THD_AcquireResult_NoFECLock) {
972              if (retries < FFTWindowRetries) {
973                retries++;
974                NextState = THD_State_ChangeFFTWindow;
975              } else
976                NextState = THD_State_Done;
977      } else {
978              NextState = THD_State_Track;
979              retries = 0;
980      }
981      break;
982
983    case THD_State_ChangeFFTWindow:
984      BDBG_MSG(("\tChangeFFTWindow"));
985      FFTWindowMode = FFTWindowModeList[retries];
986      return_val = BTHD_P_AcquireChangeFFTWindow(h,FFTWindowMode);
987      if (return_val == THD_AcquireResult_NoFFTLock)
988        NextState = THD_State_Done;
989      else
990#ifndef ChangeFFTWindowSeamless
991              NextState = THD_State_SP;
992#else
993              NextState = THD_State_FEC;
994#endif     
995      break;
996
997    case THD_State_Track:
998      BDBG_MSG(("\tTrack"));
999          BTHD_P_IsdbtResetLockSetClrFlag(h);   /* clear previous interrupt flags */
1000      ChannelEstimatorMode = ChannelEstimatorModeList[retries];
1001      return_val = BTHD_P_AcquireTrack(h,FFTWindowMode,ChannelEstimatorMode);
1002      if ((retries < ChannelEstimatorRetries) && (h->pStatus->CoChannelMode == THD_CoChannelMode_None) && (FFTWindowMode == THD_FFTWindowMode_InSpan))
1003              NextState = THD_State_CheckLock;
1004      else {
1005/*        if ((return_val != THD_AcquireResult_NoFECLock) && (ChannelEstimatorMode == THD_ChannelEstimatorMode_Fixed)) */
1006        NextState = THD_State_Done;
1007      }
1008
1009      break;
1010
1011    case THD_State_CheckLock:
1012      BDBG_MSG(("\tCheckLock"));
1013      return_val = BTHD_P_AcquireCheckLock(h);
1014      if (return_val == THD_AcquireResult_NoFECLock) {
1015              if (retries < ChannelEstimatorRetries) {
1016                retries++;
1017                NextState = THD_State_ChangeChannelEstimator;
1018              } else
1019                NextState = THD_State_Done;
1020      } else
1021              NextState = THD_State_Done;
1022      break;
1023
1024    case THD_State_ChangeChannelEstimator:
1025      BDBG_MSG(("\tChangeChannelestimator"));
1026      ChannelEstimatorMode = ChannelEstimatorModeList[retries];
1027      return_val = BTHD_P_AcquireChangeChannelEstimator(h,ChannelEstimatorMode);
1028      NextState = THD_State_CheckLock;
1029      break;
1030
1031    case THD_State_Done:
1032      BDBG_MSG(("\tDone"));
1033      h->pInternalAcquireParam->AllowRsSyncEvent = false;
1034      BKNI_ResetEvent(h->hRsSyncEvent);     
1035      Done = true;
1036#ifdef EMULATION_ENABLE
1037          BREG_Write32(h->hRegister,  BCHP_THD_INTR_AP_SET, 0x00000080 );
1038#endif
1039      break;
1040    }
1041
1042    acqProfile[State] = BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT);
1043    acqProfileValid[State] = true;
1044    if (!Done)
1045      LastState=State;
1046    State=NextState;
1047  }
1048
1049  /* Update status structure with auto-detected modes */
1050  h->pStatus->ChannelEstimatorMode = ChannelEstimatorMode;
1051  h->pStatus->FFTWindowMode = FFTWindowMode;
1052
1053  /* Report acquisition time */
1054  h->pStatus->AcquisitionTime = (fscntInit - acqProfile[LastState])/54000;
1055  BDBG_MSG(("BTHD_P_Acquire:\tAcquisition Time = %d msec",h->pStatus->AcquisitionTime)); 
1056  /*
1057  for (k=0; k<16; k++)
1058    if (acqProfileValid[k])
1059      BDBG_MSG(("\t\t%d msec: %s", (fscntInit - acqProfile[k])/54000, acqProfileString[k]));
1060  */
1061  return(return_val);
1062}
1063
Note: See TracBrowser for help on using the repository browser.