source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/thd/7552/bthd_acq.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 151.0 KB
Line 
1/******************************************************************************
2*     (c)2010-2012 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-2012 Broadcom Corporation
41
42*
43* $brcm_Workfile: bthd_acq.c $
44* $brcm_Revision: 71 $
45* $brcm_Date: 3/29/12 7:57p $
46*
47* [File Description:]
48*
49* Revision History:
50*
51 * $brcm_Log: /AP/ctfe/core/thd/bthd_acq.c $
52 *
53 * 71   3/29/12 7:57p farshidf
54 * SW7552-239: remove warning
55 *
56 * Fw_Integration_Devel/23   3/29/12 7:56p farshidf
57 * Sw7552-239: remove warning
58 *
59 * Fw_Integration_Devel/AP_V4_0_THD_DEV/6   3/29/12 7:55p farshidf
60 * SW7552-239: remove warning
61 *
62 * 70   3/27/12 11:53a farshidf
63 * SW7552-207: ISDBT fix
64 *
65 * Fw_Integration_Devel/22   3/27/12 11:52a farshidf
66 * SW7552-207: ISDBT fix
67 *
68 * Fw_Integration_Devel/AP_V4_0_THD_DEV/5   3/26/12 5:50p farshidf
69 * SW3461-1: fix ISDB-T by Jack
70 *
71 * Fw_Integration_Devel/AP_V4_0_THD_DEV/4   3/23/12 12:38p farshidf
72 * SW3128-125: FW version 4.6
73 *
74 * SW3461-173/4   3/21/12 8:52p hfu
75 * SW3461-179: Previous version does not solve the issue.  Added back the
76 *  bad pilot estimation which was removed in previous check-in.
77 *
78 * SW3461-173/3   3/16/12 4:46p hfu
79 * SW3461-179: For Huawei immediate FW release, removed bad pilot
80 *  estimation.
81 *
82 * SW3461-173/2   3/15/12 7:37p hfu
83 * SW3461-179: Removed check RS lock from Acquiring FEC state.
84 *
85 * SW3461-173/1   3/15/12 2:05p farshidf
86 * SW3461-173: add Jeff's changes
87 *
88 * Fw_Integration_Devel/AP_V4_0_THD_DEV/3   3/9/12 11:26a jputnam
89 * SW3461-175: Implement SmartNotch to notch known tuner spurs for
90 *  improved acquisition probability
91 *
92 * Fw_Integration_Devel/AP_V4_0_THD_DEV/2   3/8/12 4:44p farshidf
93 * SW3461-1: merge to main
94 *
95 * 67   3/8/12 4:37p farshidf
96 * SW3461-1: add tuner status on timer base
97 *
98 * 66   3/8/12 12:01a farshidf
99 * SW3461-171: merge to main
100 *
101 * Fw_Integration_Devel/19   3/7/12 10:52p farshidf
102 * SW3461-171: merge to integ
103 *
104 * Fw_Integration_Devel/AP_V4_0_THD_DEV/1   3/7/12 10:43p mpovich
105 * SW3461-159: Merge to Dev. branch.
106 *
107 * Fw_Integration_Devel/AP_V4_0_THD_DEV/SW3461-159/1   3/7/12 9:55p mpovich
108 * SW3461-159: Add debug printf for "Early Exit".
109 *
110 * Fw_Integration_Devel/18   2/8/12 2:49p farshidf
111 * SW3461-1: remove warning
112 *
113 * 64   1/25/12 4:08p farshidf
114 * SW3461-110: merge to integ/main
115 *
116 * Fw_Integration_Devel/17   1/25/12 4:06p farshidf
117 * SW3461-110: merge to integ/main
118 *
119 * Fw_Integration_Devel/AP_V3_0_THD_DEV/25   1/24/12 3:25p mpovich
120 * SW3461-110:  Modify THD acquisition logic to abort during various
121 *  stages if expected events (flagged by register reads) do not occur
122 *  within expected timeframe.
123 *
124 * Fw_Integration_Devel/AP_V3_0_THD_DEV/24   1/24/12 11:20a mpovich
125 * SW3461-110: Fix comment(s).
126 *
127 * Fw_Integration_Devel/AP_V3_0_THD_DEV/23   1/24/12 10:47a mpovich
128 * SW3461-110:  Modify THD acquisition logic to abort during various
129 *  stages if expected events (flagged by register reads) do not occur
130 *  within expected timeframe.
131 *
132 * Fw_Integration_Devel/AP_V3_0_THD_DEV/22   1/24/12 8:44a mpovich
133 * SW3461-110:  Modify THD acquisition logic to abort during various
134 *  stages if expected events (flagged by register reads) do not occur
135 *  within expected timeframe.
136 *
137 * Fw_Integration_Devel/AP_V3_0_THD_DEV/21   1/12/12 7:35p jputnam
138 * SW3461-133: Added Ssi and Sqi computation code
139 *
140 * Fw_Integration_Devel/AP_V3_0_THD_DEV/20   1/6/12 1:54p farshidf
141 * SW3461-40: merge to Dev branch
142 *
143 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/7   12/29/11 2:53p mpovich
144 * SW3461-40: Rebase with DEV branch.
145 *
146 * Fw_Integration_Devel/AP_V3_0_THD_DEV/18   12/14/11 2:51p mbsingh
147 * SW3461-1: Remove statics from THD code. Now ready for 7552 merge !
148 *
149 * Fw_Integration_Devel/AP_V3_0_THD_DEV/17   12/12/11 6:30p hfu
150 * SW3461-108: Changed BTHD_P_Status() function's SNR calculation.
151 *
152 * Fw_Integration_Devel/AP_V3_0_THD_DEV/16   12/9/11 4:13p mbsingh
153 * SW3461-1: Add back static to fix crash
154 *
155 * Fw_Integration_Devel/AP_V3_0_THD_DEV/15   11/22/11 2:46p mbsingh
156 * SW3461-1: Fix more of different type variables assigned to each other
157 *  and other cleanup
158 *
159 * Fw_Integration_Devel/AP_V3_0_THD_DEV/14   11/22/11 1:11p mbsingh
160 * SW3461-1: Remove some of the static's and a variable assignment
161 *  mismatch
162 *
163 * Fw_Integration_Devel/AP_V3_0_THD_DEV/13   11/14/11 10:19a mpovich
164 * SW3461-39: Leave "No Signal" status flag in its prior state when
165 *  starting an acquire (flag is updated at the end of the acquire
166 *  function).  Ensure that "No Signal" IRQ only generated once after a
167 *  commanded acquire.
168 *
169 * Fw_Integration_Devel/AP_V2_0_THD_DEV/SW3461-39/2   11/11/11 3:11p mpovich
170 * SW3461-39: Leave "No Signal" status flag in its prior state when
171 *  starting an acquire (flag is updated at the end of the acquire
172 *  function).
173 *
174 * Fw_Integration_Devel/AP_V3_0_THD_DEV/12   11/3/11 3:47p hfu
175 * SW3461-1,  Changed check in description for
176 *  Fw_Integration_Devel/AP_V3_0_THD_DEV/11  to fix a compile error.
177 *
178 * Fw_Integration_Devel/AP_V3_0_THD_DEV/11   11/3/11 3:05p hfu
179 *  SW3461-73: (1) Added conditions for FW_REF_RST in P_AcquireTrack().
180 *  (2) Change FW min_scale from 1.5 to 1.125 in P_DvbtSetFwFtt().  Also
181 *  changed one commented out line
182 *
183 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/6   11/2/11 4:12p mpovich
184 * SW3461-40: Abort-Early for THD acquire (Check for, and return "Abort-
185 *  Early" before returning "No Signal").
186 *
187 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/5   11/1/11 3:46p mpovich
188 * SW3461-40: Abort-Early for THD acquire (Initial
189 *  concept/implementation).
190 *
191 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/4   11/1/11 2:45p mpovich
192 * SW3461-40: Rebase with devel. branch.
193 *
194 * Fw_Integration_Devel/AP_V3_0_THD_DEV/10   10/28/11 12:12p farshidf
195 * SW3461-75: Move to new IRQ handling
196 *
197 * Fw_Integration_Devel/AP_V3_0_THD_DEV/9   10/27/11 5:32p jputnam
198 * SW3461-73: Improve acquisition probability by: (1) Add FW_REF_RST in
199 *  P_AcquireTrack() to match deployed 7550 firmware, (2) Change FW
200 *  min_scale from 1.125 to 1.5 in P_DvbtSetFwFtt(), and (3) Enable FW
201 *  slip during acquisition in  P_DvbtSetFwFtt() (disabled later in
202 *  tracking)
203 *
204 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/3   10/27/11 2:33p mpovich
205 * SW3461-40: Abort-Early for THD acquire (Initial
206 *  concept/implementation).
207 *
208 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/2   10/27/11 11:32a mpovich
209 * SW3461-40: Abort-Early for THD acquire (Initial
210 *  concept/implementation).
211 *
212 * Fw_Integration_Devel/AP_V3_0_THD_DEV/SW3461-40/1   10/24/11 10:02p mpovich
213 * SW3461-40: Abort-Early for THD acquire (Initial
214 *  concept/implementation).
215 *
216 * Fw_Integration_Devel/AP_V3_0_THD_DEV/8   10/19/11 6:18p hfu
217 * SW3461-1, Fixed a compile error when BDBG_MSG is on during make
218 *  process.
219 *
220 * Fw_Integration_Devel/AP_V3_0_THD_DEV/7   10/14/11 12:31a farshidf
221 * SW3461-64: merge warning fix
222 *
223 * 57   10/14/11 12:27a farshidf
224 * SW3461-64: fix warning
225 *
226 * 56   10/13/11 11:50p farshidf
227 * SW3461-64: merge to main
228 *
229 * Fw_Integration_Devel/11   10/13/11 6:57p farshidf
230 * SW3461-64: merge to integ
231 *
232 * Fw_Integration_Devel/AP_V3_0_THD_DEV/6   10/12/11 5:36p hfu
233 * SW3461-61. BER changes in DVBT QAM64, 2/3, 2k mode after retune is
234 *  performed.   FW fix: Changed the delay time before DvbtGetNotch() from
235 *  32 to 64 for 2K mode.  In addition to 2K mode cci_threshold change
236 *  from 0xC to 0xF which is made in bthd_acq_dvbt.c
237 *
238 * Fw_Integration_Devel/AP_V3_0_THD_DEV/5   10/7/11 5:12p hfu
239 *  SW3461-62: 3461B0 FW3.0 DVB-T Nordig Tests failed at multiecho and
240 *  outsideguard tests.  Fixed the bug in setting
241 *  BCHP_THD_CORE_CE_RECORD_CFG.
242 *
243 * Fw_Integration_Devel/AP_V3_0_THD_DEV/4   10/7/11 4:41p hfu
244 * SW3461-61: BER changes in DVBT QAM64, 2/3, 2k mode after retune is
245 *  performed.   Changed EQ Pilots Noise Averager Forgetting Factor during
246 *  acquire process to prevent Notch filter to be turned on for AWGN
247 *  channel .
248 *
249 * Fw_Integration_Devel/AP_V3_0_THD_DEV/3   9/30/11 4:00p mbsingh
250 * - Fixing a bug from the previous checkin
251 *
252 * Fw_Integration_Devel/AP_V3_0_THD_DEV/2   9/27/11 12:25p mbsingh
253 * SW3461-1: Due to THD core v5.1, TPS values can be read directly from
254 *  snooper. Using this enhancement to optimize FTT algo.
255 *
256 * Fw_Integration_Devel/AP_V3_0_THD_DEV/1   9/26/11 2:55p mbsingh
257 * SW3461-1: Merge from 2.0 dev branch (This is mainly a shift to WPO
258 *  algorithm)
259 *
260 * Fw_Integration_Devel/AP_V2_0_THD_DEV/9   9/21/11 5:37p jputnam
261 * SW3461-1: Fix tuner callback so that it works with SmartTune defined or
262 *  not defined
263 *
264 * Fw_Integration_Devel/AP_V2_0_THD_DEV/8   9/20/11 9:48a mpovich
265 * SW3461-39: Add "No Signal" to T2 Status and THD Status HAB commands.
266 *  Add "FEC Lock" to THD Status HAB command.
267 *
268 * Fw_Integration_Devel/AP_V2_0_THD_DEV/SW3461-39/1   9/20/11 9:04a mpovich
269 * SW3461-39: Support for FEC lock and No Signal in status.
270 *
271 * Fw_Integration_Devel/AP_V2_0_THD_DEV/7   9/15/11 2:18p mbsingh
272 * - Fix function naming
273 *
274 * Fw_Integration_Devel/AP_V2_0_THD_DEV/6   9/9/11 6:07p mbsingh
275 * SW3461-1:  - Change // comments to fix compile on non-leap chips -
276 *  Remove MAXPEAX stuff - Ifdef GetChannelSpan function for ISDBT
277 *  containing chips only - Added back AcquirechangeFFTwindow function
278 *  (needed by ISDB-T)   - Added back FW_WIN enable for ISDBT
279 *
280 * Fw_Integration_Devel/AP_V2_0_THD_DEV/5   9/8/11 10:47p mbsingh
281 * SW3461-1:  Separated SetFW function cleanly now to make DVBT work for
282 *  ISDBT containing chips also.  In initial merged code from THD_FTT_WPO
283 *  branch DVBT would work only in non ISDBT chips due to wrong SetFW
284 *  function
285 *
286 * Fw_Integration_Devel/AP_V2_0_THD_DEV/4   9/8/11 10:05p mbsingh
287 * SW3461-1: Merging from THD_FTT_WPO branch                   -
288 *  Architectural change to new FTT algo for acquisition
289 *
290 * Fw_Integration_Devel/AP_V0_6_THD_DEV/Thd_ftt_wpo/3   8/24/11 10:56a hzou
291 * Update state machine to do FFTTrigger after TPS synch, and only redo
292 *  TPS synch is missing first peak or having on-the-gurad echos. Also
293 *  reduced wait time in FFTTtrigger
294 *
295 * Fw_Integration_Devel/AP_V0_6_THD_DEV/Thd_ftt_wpo/2   8/18/11 3:58p hzou
296 * Improved on-the-guard pre-echo in FTT
297 *
298 * Fw_Integration_Devel/AP_V0_6_THD_DEV/Thd_ftt_wpo/1   8/18/11 10:49a hzou
299 * Ported in chnages for FTT and WPO
300 *
301 * Fw_Integration_Devel/10   9/22/11 4:57p farshidf
302 * SW3461-1: disable smarttune
303 *
304 * Fw_Integration_Devel/9   8/26/11 5:25p farshidf
305 * SW3461-1: merge to integ
306 *
307 * Fw_Integration_Devel/AP_V2_0_THD_DEV/3   8/26/11 5:22p farshidf
308 * SW3461-1: make it magnum compatible
309 *
310 * 48   8/24/11 5:54p farshidf
311 * SW7552-60: merge to main
312 *
313 * Fw_Integration_Devel/8   8/24/11 5:47p farshidf
314 * SW7552-60: add the isdb-t constellation
315 *
316 * Fw_Integration_Devel/AP_V2_0_THD_DEV/2   8/24/11 5:40p farshidf
317 * SW7552-60: add the softdecision for isdbt
318 *
319 * 47   8/24/11 12:32p farshidf
320 * SW3461-38: merge to main
321 *
322 * Fw_Integration_Devel/7   8/24/11 12:07p farshidf
323 * SW3461-38: merge to integ
324 *
325 * Fw_Integration_Devel/AP_V2_0_THD_DEV/1   8/22/11 12:45p jputnam
326 * SW3461-1: Added SmartTune
327 *
328 * Fw_Integration_Devel/5   8/12/11 2:11p farshidf
329 * SW3461-1: merge to integ
330 *
331 * Fw_Integration_Devel/AP_V0_6_THD_DEV/6   8/10/11 3:45p farshidf
332 * SW3461-1: update status printf
333 *
334 * Fw_Integration_Devel/AP_V0_6_THD_DEV/5   7/22/11 12:30p jputnam
335 * Added SignalStrength
336 *
337 * Fw_Integration_Devel/AP_V0_6_THD_DEV/4   7/12/11 4:13p farshidf
338 * SW3461-17: compile fix
339 *
340 * Fw_Integration_Devel/AP_V0_6_THD_DEV/3   7/12/11 3:28p jchien
341 * AP_V0_6_THD_DEV:  checkLock state: add three layer check for isdbt.
342 *
343 * Fw_Integration_Devel/AP_V0_6_THD_DEV/2   7/12/11 12:17p farshidf
344 * SW3461-17: fix compilation issue
345 *
346 * Fw_Integration_Devel/AP_V0_6_THD_DEV/1   7/7/11 5:10p farshidf
347 * SW3461-17: add the T2 and Thd callback to tuner
348 *
349 * Fw_Integration_Devel/2   6/29/11 12:38p farshidf
350 * SW3461-13: merge to integration branch
351 *
352 * Fw_Integration_Devel/Dvbt_Fw_Devel_Rc05/1   6/20/11 1:55p mpovich
353 * SW3461-1: Merge post 0.4 release made to Dvb_Fw_Devel_4 and
354 *  SW_System_4_Integ branches.
355 *
356 * Fw_Integration_Devel/1   6/20/11 1:53p mpovich
357 * SW3461-1: Merge post 0.4 release made to Dvb_Fw_Devel_4 and
358 *  SW_System_4_Integ branches.
359 *
360 * SW_System_4_Integ_Test/5   6/20/11 1:52p mpovich
361 * SW3461-1: Rebase System_4 integ Test branch with main / 0.4 release.
362 *
363 * SW_System_4_Integ_Test/4   6/17/11 6:51p mpovich
364 * SW3461-1: Pick up post 3461 version 0.4 release change.
365 *
366 * Dvb_Fw_Devel_4/6   6/17/11 5:40p jputnam
367 * SW3461-1: Resurrect proper return value logic inside P_GetChannelSpan()
368 *  which was lost in some previous merge
369 *
370 * 44   6/10/11 2:48p farshidf
371 * SW3461-1: minor compile fix
372 *
373 * 43   6/9/11 6:36p mpovich
374 * SW3461-1: merge main
375 *
376 * SW_System_4_Integ_Test/3   6/9/11 5:58p farshidf
377 * SW3461-1: fix the auto acquire for 3461
378 *
379 * SW_System_4_Integ_Test/2   6/9/11 12:21p mpovich
380 * SW3461-1: Integrate latest from all devel. branches.  Remove end of
381 *  line comments per coding standards.
382 *
383 * 42   6/8/11 6:18p farshidf
384 * SW3461-1: merge main
385 *
386 * Dvb_Fw_Devel_4/5   6/8/11 6:16p farshidf
387 * SW3461-1: sync up with magnum
388*
389* SW_System_4_Integ_Test/1   6/6/11 1:53p mpovich
390* SW3461-1: Integ. test all development branches together.
391*
392* Hydra_Software_Devel/17   6/3/11 5:15p farshidf
393* SW7552-36: compile fix
394*
395* Hydra_Software_Devel/16   6/3/11 4:43p farshidf
396* SW7552-36: merge to main
397*
398* Hydra_Software_Devel/SWDTV-7361/2   6/2/11 2:15p mbsingh
399* SWDTV-7361: DVB-T Channel Scan Improvements
400*
401* Hydra_Software_Devel/SWDTV-7361/1   6/2/11 2:08p mbsingh
402* SWDTV-7361: Initialize status spares, Hold retcode in spare1
403*
404* Hydra_Software_Devel/15   6/3/11 4:41p farshidf
405* SW7552-36: merge to main
406*
407* Hydra_Software_Devel/14   6/1/11 11:44a farshidf
408* SW7552-36: clean up the code
409*
410* Hydra_Software_Devel/13   5/31/11 7:37p farshidf
411* SW7552-36: remove ISDB-T warning
412*
413* Hydra_Software_Devel/12   5/27/11 10:53a farshidf
414* SW7552-36: compile fix
415*
416* Hydra_Software_Devel/17   6/3/11 5:15p farshidf
417* SW7552-36: compile fix
418*
419* Hydra_Software_Devel/16   6/3/11 4:43p farshidf
420* SW7552-36: merge to main
421*
422* Hydra_Software_Devel/15   6/3/11 4:41p farshidf
423* SW7552-36: merge to main
424*
425* Hydra_Software_Devel/SWDTV-7146/2   5/25/11 3:31p jchien
426* SWDTV-7146: add isdbt HW status reset
427*
428* Hydra_Software_Devel/SWDTV-7146/1   5/24/11 12:20p jchien
429* SWDTV-7146: add RS_SYNC FEC block monitor. Add fast_acq.
430*
431* Hydra_Software_Devel/11   5/18/11 12:11p farshidf
432* SWDTV-7035: fix the memory allocation for ISDB-T
433*
434* Hydra_Software_Devel/10   5/6/11 6:43p farshidf
435* SWDTV-6857: fix teh scan mode
436*
437* Hydra_Software_Devel/9   5/6/11 6:22p farshidf
438* SWDTV-6857: add scan
439*
440* Hydra_Software_Devel/8   5/6/11 2:21p farshidf
441* SWDTV-6857: update the auto acquire mode
442*
443* Hydra_Software_Devel/7   5/5/11 8:34p farshidf
444* SWDTV-6857: merge main
445*
446* Hydra_Software_Devel/SWDTV-6857/4   5/5/11 7:04p farshidf
447* SWDTV-6857: add flag around ISDB-T variable
448*
449* Hydra_Software_Devel/SWDTV-6857/3   5/5/11 6:47p farshidf
450* SWDTV-6857: merge main
451*
452* Hydra_Software_Devel/SWDTV-6857/1   5/3/11 4:23p jchien
453* SWDTV-6857: add ISDBT changes
454*
455* 40   5/3/11 1:33p mpovich
456* SW3461-1: Merge to main of intermediate label, FW_3461_A0_05022011_1100
457*  (05/02/2011 Pace build).
458*
459* DVB_3461_1/27   4/28/11 10:05a jputnam
460* SW3461-1: Reverted FW min_scale to 1.5 for InSpan mode. Added
461*  GetChannelSpan() and associated parameter in status structure.
462*
463* DVB_3461_1/26   4/27/11 8:30a jputnam
464* SW3461-1:  Added #define ChangeFFTWindowSeamless for experimentation
465*  with seamless FW switching to improve acquisition time
466*
467* DVB_3461_1/25   4/27/11 7:56a jputnam
468* SW3461-1: Changed FW min_scale from 1.5 to 1.0625 to allow better
469*  detection of weak pre-echoes for InSpan mode
470*
471* DVB_3461_1/24   4/26/11 9:21p jputnam
472* SW3461-1: Removed code associated with frequency-domain FFT trigger
473*  algorithm.  Development moved to another branch. Removed unconditional
474*  return value of THD_AcquireResult_Lock in AcquireCheckLock() function
475*
476* DVB_3461_1/23   4/25/11 11:43a jputnam
477* SW3461-1: Move additional statement inside #ifndef FFTTriggerPosition
478*  statement
479*
480* 39   4/21/11 6:22p farshidf
481* SW3461-1: merge main
482*
483* DVB_3461_1/22   4/21/11 6:21p farshidf
484* SW3461-1: merge main
485*
486* DVB_3461_1/21   4/21/11 6:03p farshidf
487* SW3461-1: merge main
488*
489* 38   4/21/11 6:01p farshidf
490* SW3461-1: make the files host compatible
491*
492* 37   4/21/11 5:45p farshidf
493* SW3461-1: merge main
494*
495* DVB_3461_1/20   4/21/11 5:45p farshidf
496* SW3461-1: merge main
497*
498* DVB_3461_1/19   4/15/11 9:37p jputnam
499* SW3461-1: Firmware FFT trigger positioning functional. Feature can be
500*  disabled by removing #define FFTTriggerPosition in bthd_acq.h
501*
502* DVB_3461_1/18   4/13/11 4:21p jchien
503* SW3461-1: fix isdbt related bugs
504*
505* DVB_3461_1/17   4/13/11 10:33a jputnam
506* SW3461-1: Hooked-up GetChannelEstimateBuf() and
507*  GetInterpolatorCoefficientsBuf() in API. Added code supporting Time
508*  Response and Frequency Interpolator Response displays
509*
510* DVB_3461_1/16   4/12/11 10:25a jputnam
511* SW3461-1: Added P_GetChannelEstimateBuf() and
512*  P_GetInterpolatorCoefficientsBuf() functions. Reduced FI leakage to
513*  2^(-20)
514*
515* DVB_3461_1/15   4/11/11 6:50p jputnam
516* SW3461-1: Cosmetic cleanup of GetFFTTirggerPosition() function
517*
518* DVB_3461_1/14   4/11/11 4:16p mbsingh
519* SW3461-1: Adding FFT Trigger position determination Function
520*
521* 36   4/21/11 5:29p farshidf
522* SW3461-1: make it host compatible
523*
524* 35   4/20/11 4:55p farshidf
525* SW3461-1: make it host compatible
526*
527* 34   4/19/11 12:03p farshidf
528* SW3461-1: make host compatible
529*
530* 33   4/11/11 3:49p farshidf
531* SW3461-1: merge main
532*
533* DVB_3461_1/13   4/11/11 9:16a jputnam
534* SW3461-1: Functional CoChannel mode
535*
536* DVB_3461_1/12   4/8/11 11:56a jputnam
537* SW3461-1: Automatic ChannelEstimatorMode now functional
538*
539* DVB_3461_1/11   4/7/11 10:58p jputnam
540* SW3461-1: Removed obsolete lock functions. Reverted state machine so
541*  that SP, TPS, and FEC states are revisited upon FFTWindowMode change.
542*  Force RS_SYNC_LOSS interrupt if P_Acquire returns without locking to
543*  force proper update of lock state.
544*
545* DVB_3461_1/10   4/7/11 9:28p jputnam
546* SW3461-1: Initial version of interrupt-based lock detection
547*
548* DVB_3461_1/9   4/6/11 5:27p farshidf
549* SW3461-1: compile fix
550*
551* DVB_3461_1/8   4/6/11 5:22p farshidf
552* SW3461-1: remove not used code
553*
554* DVB_3461_1/7   4/6/11 2:12p jputnam
555* SW3461-1: Removed obsolete AcqRequest field from Common Acquire Params
556*
557* DVB_3461_1/6   4/5/11 10:01p jputnam
558* SW3461-1: Corrected RS retention threshold
559*
560* DVB_3461_1/5   4/5/11 9:14p jputnam
561* SW3461-1: Revamped P_Lock and P_DvbtLock functions. Added proper Acq
562*  and Ret thresholds for RS lock detectors. Cosmetic clean-up of code
563*  and printfs.
564*
565* DVB_3461_1/4   4/5/11 8:00p mpovich
566* SW3461-1: Update THD Status HAB command to include missing parameters:
567*  Acquire Mode, and block counters.
568*
569* DVB_3461_1/3   4/4/11 5:12p jputnam
570* SW3461-1: Fixed P_GetSoftDecisionBuf()
571*
572* 28   4/4/11 4:33p mpovich
573* SW3461-1: Update THD Status HAB command to include missing parameters:
574*  Acquire Mode, and block counters.
575*
576* 27   3/25/11 6:29p mpovich
577* SW3461-1: Merge latest from T2 and THD to the main branch.
578*
579* DVB_3461_1/2   3/18/11 4:13p farshidf
580* SW3461-1: merge  main
581*
582* 26   3/14/11 10:19a farshidf
583* SW3461-1: merge to main branch
584*
585* DVB_3461_1/1   3/13/11 11:45a jputnam
586* SW3461-1: Suppress TS clock in serial mode for compatibility with 7231
587*  reference design
588*
589* 25   3/9/11 3:44p jputnam
590* SW3461-1: Moved status copy from BTHD_P_Status() up to BTHD_Status()
591*
592* 24   3/8/11 12:39p farshidf
593* SW3461-1: fix teh THD API
594*
595* 23   3/4/11 4:52p farshidf
596* SW3461-1: add the power seq
597*
598* 22   2/25/11 5:45p jputnam
599* SW3461-1: Added hook for emulation with and without UFE
600*
601* 21   2/8/11 11:57a jputnam
602* SW3461-1: Added spectral inversion field to status
603*
604* 20   1/21/11 5:57p farshidf
605* SW3461-1: update names
606*
607* 19   1/20/11 4:22p farshidf
608* SW3461-1: update the thd/isdbt
609*
610* 18   1/6/11 10:08a jputnam
611* SW3461-1: Major cosmetic overhaul - Conform to new API conventions
612*  common to all demods - Conform to naming conventions for private
613*  functions and typedefs - Separate DVB-T and ISDB-T params, status,
614*  functions
615*
616* 17   1/3/11 5:35p jputnam
617* SW3461-1: changed enumerated type and #define names from THD_ to BTHD_
618*
619* 16   12/16/10 6:48p farshidf
620* SW3461-1: clean up
621*
622* 15   12/13/10 5:07p farshidf
623* SW3461-1: add the sync and out of sync irq
624*
625* 14   12/3/10 4:37p farshidf
626* SW3461-1: printf update
627*
628* 13   12/2/10 8:59a jputnam
629* SW3461-1: ifdef out redundant BMTH_2560log10() and
630*  BTHD_SetDefaultSettings() as these functions have already been moved
631*  to bmth.c and bthd_api.c respectively
632*
633* 12   11/30/10 11:19a farshidf
634* SW3461-1: add BMTH_2560log10 to math lib
635*
636* 11   11/30/10 10:44a farshidf
637* SW3461-1: update the thd files
638*
639* 10   11/23/10 5:43p farshidf
640* SW3461-1: update the timer and printf
641*
642* 9   11/15/10 12:40p farshidf
643* SW3461-1: compile fix
644*
645* 8   11/11/10 9:43a jputnam
646* SW3461-1: Acquisition successful in EMULATION_ENABLED.  TL_FCW is temporarily
647*  hard-coded in SetFrequency() due to error in 64-bit computation.
648*
649* 7   11/4/10 2:36p farshidf
650* SW3461-1: clean up the irq
651*
652* 6   11/4/10 10:06a jputnam
653* SW3461-1: Separated Acquire() function into multiple functions called
654*  by a new top-level acquisition state machine
655*
656* 1   8/17/10 5:12p farshidf
657* SW3461-1: initial THD code
658*
659*
660***************************************************************************/
661/* #define FASTACQ */
662
663#include "bstd.h"
664#include "bmth.h"
665#include "bkni.h"
666#include "btmr.h"
667
668
669#ifndef LEAP_BASED_CODE
670#include "bthd_3x7x.h"
671#endif
672#include "bthd_api.h"
673#include "bthd_acq.h"
674#include "bchp_thd_core.h"
675
676#include "bthd_acq_dvbt.h"
677#ifdef BTHD_ISDBT_SUPPORT
678#include "bthd_acq_isdbt.h"
679#endif
680#include "bthd_coef.h"
681
682#include "bchp_thd_intr2.h"
683#include "bchp_thd_intr2b.h"
684#ifdef LEAP_BASED_CODE
685#include "bchp_leap_ctrl.h"
686#include "bthd_irq.h"
687#endif
688#ifdef EMULATION_ENABLED
689#include "bchp_thd_intr.h"
690#endif
691
692#ifndef LEAP_BASED_CODE
693BDBG_MODULE(bthd_acq);
694#endif
695
696/* Convert milliseconds to Sample-rate counts  */
697#define BTHD_P_MSEC_TO_FSCNT(TIME_MSEC) ((uint32_t)((TIME_MSEC)*54000U))
698
699/***************************************************************************
700 * BTHD_P_OSleep()
701 ***************************************************************************/
702BERR_Code BTHD_P_OSleep(BTHD_3x7x_Handle h, 
703                        uint32_t symbols, 
704                        uint32_t N, 
705                        uint32_t D)
706{
707  uint32_t samples = symbols*(N + (N >> (5-D))); 
708  BERR_Code eEventWaitResult;
709 
710  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FBCNT,samples);
711  BINT_EnableCallback(h->hFbcCntCallback);
712  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hFbcntZeroEvent, 400); 
713  if ( eEventWaitResult != BERR_SUCCESS && eEventWaitResult != BTHD_ERR_ACQUIRE_ABORTED ) {
714    BDBG_MSG(("BTHD_P_OSleep:No FBCNT zero"));
715  }
716  BINT_DisableCallback(h->hFbcCntCallback);
717  return ( eEventWaitResult );
718}
719
720/***************************************************************************
721* BTHD_P_Read_FSCnt_Time()
722***************************************************************************/
723static uint32_t BTHD_P_Read_FSCnt_Time ( BTHD_3x7x_Handle h )
724{
725  return ( BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT) ); 
726}
727
728/***************************************************************************
729* BTHD_P_Check_FSCnt_TimeExceeded()
730***************************************************************************/
731static bool BTHD_P_Check_FSCnt_TimeExceeded ( BTHD_3x7x_Handle h, uint32_t uStartFsCount, uint32_t uTimeoutInFsCounts )
732{
733  bool bTimeout = false;
734  uint32_t uCurrFsCount, w_time = 0; 
735
736  uCurrFsCount = BTHD_P_Read_FSCnt_Time(h);
737
738  if ( uStartFsCount < uCurrFsCount) {
739      /* The counter is wrapped */
740      w_time = (0xffffffffU - uCurrFsCount) + uStartFsCount; 
741  }
742  else {
743      w_time = uStartFsCount - uCurrFsCount; 
744  }
745
746  if ( w_time > uTimeoutInFsCounts ) {
747      bTimeout = true;
748  }
749 
750  /* Timeout period was exceeded */
751  return ( bTimeout );
752}
753
754/***************************************************************************
755* BTHD_P_Wait_CE_Recording_Status_Done()
756***************************************************************************/
757bool BTHD_P_Wait_CE_Recording_Status_Done ( BTHD_3x7x_Handle h, uint32_t uTimeOutMsec )
758{
759  bool bTimedOutWaiting = false;
760  uint32_t start_stamp; 
761  uint32_t uTimeOutFScounts = BTHD_P_MSEC_TO_FSCNT(uTimeOutMsec);
762
763  start_stamp = BTHD_P_Read_FSCnt_Time(h);
764  while ( (0 == BREG_ReadField(h->hRegister, THD_CORE_CE_RECORD_CFG, DONE)) && (! bTimedOutWaiting) ){
765    bTimedOutWaiting = BTHD_P_Check_FSCnt_TimeExceeded(h, start_stamp, uTimeOutFScounts);
766  }
767  if ( bTimedOutWaiting ) {
768      BDBG_MSG(("\t\tWait THD_CORE_CE_RECORD_CFG DONE timeout at 0x%08X", BTHD_P_Read_FSCnt_Time(h)));
769  }
770  return ( ! bTimedOutWaiting );
771}
772
773/******************************************************************************
774 * BTHD_P_GetChannelEstimateBuf()
775 ******************************************************************************/
776BERR_Code BTHD_P_GetChannelEstimateBuf(BTHD_3x7x_Handle h,uint32_t *pData, THD_SnooperMode_t mode)
777{
778  BERR_Code eResult = BERR_SUCCESS;
779
780  uint32_t val,idx,start=0,step=3,size=285;
781  uint32_t N=bthd_transmission_mode[BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE)];
782 
783  if (mode == THD_SnooperMode_Ce) {
784    /* Use this selection, to get center 256 pilots for time response display */
785    start = 852*(N >> 11) - 3*127;
786    step = 3;
787    size = 256;
788   
789    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_RECORD_CFG,0x01000000 + (mode << 25) + (step << 16) + start ); /* Snooper snapshot mode */
790    /* while (!BREG_ReadField(h->hRegister, THD_CORE_CE_RECORD_CFG, DONE)); */
791    /* Wait 1 second for internal buffer to fill */
792    if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 1000) ) {
793      eResult = BERR_TIMEOUT;
794      goto BTHD_P_GetChannelEstimateBuf_Exit;
795    }
796
797    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_READ_INDEX,0x00000000);
798    for (idx=0; idx<size; idx++) {
799      val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_READ_DATA);
800      pData[idx] = val;
801    } 
802  } else {
803    start = 0;
804    step = 6*(N >> 11);
805    size = 285; 
806   
807    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_RECORD_CFG,0x01000000 + (mode << 25) + (step << 16) + start ); /* Snooper snapshot mode */
808
809    /* while (!BREG_ReadField(h->hRegister, THD_CORE_CE_RECORD_CFG, DONE)); */
810    /* Wait 1 second for internal buffer to fill */
811    if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 1000) ) {
812      eResult = BERR_TIMEOUT;
813      goto BTHD_P_GetChannelEstimateBuf_Exit;
814    }
815
816    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_READ_INDEX,0x00000000);
817    for (idx=0; idx<256; idx++) {
818      val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_READ_DATA);
819      pData[idx] = val;
820    }
821   
822    start = 1704*(N >> 11) - step*255;   
823    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_RECORD_CFG,0x01000000 + (mode << 25) + (step << 16) + start ); /* Snooper snapshot mode */
824    /* while (!BREG_ReadField(h->hRegister, THD_CORE_CE_RECORD_CFG, DONE)); */
825    /* Wait 1 second for internal buffer to fill */
826    if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 1000) ) {
827      eResult = BERR_TIMEOUT;
828      goto BTHD_P_GetChannelEstimateBuf_Exit;
829    }
830
831    /*BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_READ_INDEX,256-start/step); */
832    BREG_Write32(h->hRegister,BCHP_THD_CORE_CE_READ_INDEX,0x00000000);
833    for (idx=0; idx<256; idx++) {
834      val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_READ_DATA);
835      if (idx > (255 - start/step))
836        pData[255 + idx - (255 - start/step)] = val; 
837    }           
838  }
839 
840BTHD_P_GetChannelEstimateBuf_Exit:
841  return ( eResult );
842}
843
844/******************************************************************************
845 * BTHD_P_GetInterpolatorCoefficientsBuf()
846 ******************************************************************************/
847BERR_Code BTHD_P_GetInterpolatorCoefficientsBuf(BTHD_3x7x_Handle h,uint32_t *pData, THD_InterpolatorMode_t mode)
848{
849  uint32_t val=0,idx,phase;
850 
851  if (mode == THD_InterpolatorMode_Ti) {
852    for (idx=0; idx<16; idx+=2) {
853      switch(idx) {
854        case 0:  val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF01); break;
855        case 2:  val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF23); break;
856        case 4:  val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF45); break;
857        case 6:  val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF67); break;
858        case 8:  val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF89); break;
859        case 10: val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF1011); break;
860        case 12: val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF1213); break;                               
861        case 14: val = BREG_Read32(h->hRegister,BCHP_THD_CORE_CE_TCOEF14); break;       
862      }
863      pData[idx]   = (val & 0xffff0000);
864      pData[idx+1] = (val & 0x0000ffff) << 16;
865    }
866  } else {
867    /* Total coefficients = (11 sets) x (36 coeff/set) = 396.  Read only the 36 coefficients for the center set for display
868       which correspond to indices 180-191, 192-203, 204-215 for the three polyphase subfilters */
869    BREG_Write32(h->hRegister,BCHP_THD_CORE_FI_ADDR,36*5);     
870    for (phase=0; phase<3; phase++) {   
871      for (idx=0; idx<12; idx++) {
872        val = BREG_Read32(h->hRegister,BCHP_THD_CORE_FI_COEF);
873        pData[3*idx+phase] = ((val & 0x3fff0000) << 2) | ((val & 0x00003fff) << 2);
874      } 
875    } 
876  }
877  return BERR_SUCCESS;
878}
879
880/***************************************************************************
881 * BTHD_P_Init() 
882 ***************************************************************************/
883BERR_Code BTHD_P_Init(BTHD_3x7x_Handle h)
884{
885  /* Reset FEC error counters */
886  BREG_WriteField(h->hRegister,  THD_CORE_RST, RS_ERC_RST, 1 );           
887  BREG_WriteField(h->hRegister,  THD_CORE_RST, RS_ERC_RST, 0 ); 
888  return BERR_SUCCESS;
889}
890
891/***************************************************************************
892 * BTHD_P_EnableLockInterrupts()
893 ***************************************************************************/
894void BTHD_P_EnableLockInterrupts(BTHD_3x7x_Handle h)
895{
896#ifdef BTHD_ISDBT_SUPPORT
897  uint32_t segs_b, segs_c;
898  /* Reset lock detector, clear interrupt status, and enable lock interrupts */ 
899
900  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
901    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );
902    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
903    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 1 );
904    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 0 );
905    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 1 );
906    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 0 );
907    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );
908    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 1 );
909    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 1 );
910    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 );
911    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 0 );
912    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 0 );
913
914    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_INTR, 1 );
915    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_INTR, 1 );
916    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_B_INTR, 1 );
917    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_B_INTR, 1 );
918    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_C_INTR, 1 );
919    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_C_INTR, 1 );
920    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_INTR, 0 );
921    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_INTR, 0 );   
922    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_B_INTR, 0 );
923    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_B_INTR, 0 );   
924    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_C_INTR, 0 );
925    BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_C_INTR, 0 );   
926        BTHD_P_IsdbtResetLockSetClrFlag(h);  /* clear previous interrupt flags */
927  } else {
928#endif
929  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );
930  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 );
931  BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_INTR, 1 );
932  BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_INTR, 1 );
933  BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_INTR, 0 );
934  BREG_WriteField(h->hRegister, THD_INTR2B_CPU_CLEAR, RS_SYNC_LOSS_INTR, 0 );   
935#ifdef BTHD_ISDBT_SUPPORT
936  }
937#endif
938
939#ifdef BTHD_ISDBT_SUPPORT
940  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
941        segs_b = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG);
942        segs_c = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG);
943    BINT_EnableCallback(h->hRsSyncCallback);
944    BINT_EnableCallback(h->hRsSyncLossCallback);
945        if (segs_b) {
946          BINT_EnableCallback(h->hRsSyncBCallback);
947      BINT_EnableCallback(h->hRsSyncLossBCallback);
948        }
949        if (segs_c) {
950      BINT_EnableCallback(h->hRsSyncCCallback);
951      BINT_EnableCallback(h->hRsSyncLossCCallback);
952        }
953  } else {
954#endif
955
956  BINT_EnableCallback(h->hRsSyncCallback);
957  BINT_EnableCallback(h->hRsSyncLossCallback);
958
959#ifdef BTHD_ISDBT_SUPPORT
960  }
961#endif
962}
963 
964/***************************************************************************
965 * BTHD_P_AbortAcquire()
966 ***************************************************************************/
967void BTHD_P_AbortAcquire ( BTHD_3x7x_Handle h )
968{
969  volatile bool prevAbortFlagValue = h->pInternalAcquireParam->AbortAcquireRequested;
970
971  /* Set flag to abort an acquire already in-progress */
972  h->pInternalAcquireParam->AbortAcquireRequested = true;
973
974  /* On a new Abort, signal the event being waited on just once. (Do not trigger the event once Abort flag is set) */ 
975  if ( (! prevAbortFlagValue) && (h->pInternalAcquireParam->hCurrAbortableEventHandle != NULL) ) 
976  {
977    /* After setting the abort flag, signal the "abortable" event being waited on */
978    BKNI_SetEvent(h->pInternalAcquireParam->hCurrAbortableEventHandle);
979  }
980}
981
982/***************************************************************************
983 * BTHD_P_AbortAcquireReset()
984 ***************************************************************************/
985void BTHD_P_AbortAcquireReset ( BTHD_3x7x_Handle h )
986{
987  /* Nullify the (now stale) "abortable" event handle */
988  h->pInternalAcquireParam->hCurrAbortableEventHandle = NULL;
989  /* Reset the "abort acquire" flag */
990  h->pInternalAcquireParam->AbortAcquireRequested = false;
991}
992
993/***************************************************************************
994 * BTHD_P_IsAbortAcquireRequested()
995 ***************************************************************************/
996bool BTHD_P_IsAbortAcquireRequested ( BTHD_3x7x_Handle h )
997{
998  /* Get the "abort acquire" flag */
999  return ( h->pInternalAcquireParam->AbortAcquireRequested );
1000}
1001
1002/***************************************************************************
1003 * BTHD_P_WaitForEventOrAbort()
1004 * Assumption: Multiple threads do not concurrently run a receiver's acquisition.
1005 *             If so, Abort-Early is merely prolonged by the longest timeout
1006 *             among all events' concurrently pended during the acquire.
1007 ***************************************************************************/
1008BERR_Code BTHD_P_WaitForEventOrAbort ( BTHD_3x7x_Handle h, BKNI_EventHandle event, int timeoutMsec )
1009{
1010  BERR_Code eResult = BERR_SUCCESS;
1011
1012  /* BDBG_MSG(("BTHD_P_WaitForEventOrAbort")); */
1013
1014  /* Always check for Abort-Early condition first.  Exit without waiting once the Abort condition has set. */
1015  if ( BTHD_P_IsAbortAcquireRequested(h) )
1016  {
1017    eResult = BTHD_ERR_ACQUIRE_ABORTED;
1018  }
1019  else
1020  {
1021    /* Copy event handle to be waited on. */
1022    /* This copy is signaled by the abort function on an Abort condition. */
1023    h->pInternalAcquireParam->hCurrAbortableEventHandle = event;
1024
1025    /* First wait for the desired event */
1026    eResult = BKNI_WaitForEvent(event, timeoutMsec);
1027
1028    /* Immediately nullify the event-handle copy so that the "Abort Acquire" function will no longer signal this event */
1029    h->pInternalAcquireParam->hCurrAbortableEventHandle = NULL;
1030
1031    /* Check to see if the event was triggered for, or during, an Abort-Early condition */
1032    if ( BTHD_P_IsAbortAcquireRequested(h) )
1033    {
1034      /* On an Abort condition only: reset the event in case it subsequently set a second time for either an Abort or for the actual event itself. */
1035      BKNI_ResetEvent(event);
1036      eResult = BTHD_ERR_ACQUIRE_ABORTED;
1037    }
1038  }
1039  if ( eResult == BTHD_ERR_ACQUIRE_ABORTED )
1040  {
1041    BDBG_MSG(("BTHD_P_WaitForEventOrAbort: Early Exit"));
1042  }
1043
1044  return ( eResult );
1045}
1046
1047/***************************************************************************
1048 * BTHD_P_MapWaitForEventResult_To_THD_AcqResult() 
1049 ***************************************************************************/
1050BTHD_RESULT BTHD_P_MapWaitForEventResult_To_THD_AcqResult ( BERR_Code eEventWaitResult, BTHD_RESULT successCode, BTHD_RESULT failureCode )
1051{
1052  /* eEventWaitResult success: successCode, Failure: failureCode, or,
1053  * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
1054
1055  /* Map BERR_Code from WaitForEvent() into THD result (depending on having successfully signaled the event, or not) */
1056  if ( eEventWaitResult == BERR_SUCCESS ) {
1057    return(successCode);
1058  }
1059  else
1060  {
1061    /* The event-wait returned "Acquire Aborted Early" failure code */
1062    if ( eEventWaitResult == BTHD_ERR_ACQUIRE_ABORTED ) {
1063      return(THD_AcquireResult_AbortedEarly);
1064    }
1065    return(failureCode);
1066  }
1067}
1068
1069/***************************************************************************
1070 * BTHD_P_Acquire() 
1071 ***************************************************************************/
1072BERR_Code BTHD_P_Acquire(BTHD_3x7x_Handle h)
1073{
1074  uint32_t  ReacquireCount;
1075  BERR_Code retCode;
1076#ifdef SmartTuneEnabled 
1077  int16_t TunerGain;
1078  uint16_t SmartTune;
1079  uint32_t RfFreq;
1080#endif
1081 
1082#ifdef LEAP_BASED_CODE  /* sample code of how to call the tuner to turn on/off the AGC */
1083  BTHD_P_ThdCallbackData_t TunerCallback;
1084 
1085  TunerCallback.hTunerChn = (h->pCallbackParam[BTHD_Callback_eTuner]);
1086  TunerCallback.Mode = BTHD_CallbackMode_eDisablePower;
1087  BKNI_EnterCriticalSection();
1088  (h->pCallback[BTHD_Callback_eTuner])(&TunerCallback); 
1089  BKNI_LeaveCriticalSection();
1090
1091
1092  TunerCallback.Mode = BTHD_CallbackMode_eEnablePower;
1093  BKNI_EnterCriticalSection();
1094  (h->pCallback[BTHD_Callback_eTuner])(&TunerCallback); 
1095  BKNI_LeaveCriticalSection();
1096#endif
1097
1098  BINT_DisableCallback(h->hRsSyncCallback);
1099  BINT_DisableCallback(h->hRsSyncLossCallback);
1100
1101#ifdef BTHD_ISDBT_SUPPORT 
1102  BINT_DisableCallback(h->hRsSyncBCallback);
1103  BINT_DisableCallback(h->hRsSyncLossBCallback);
1104  BINT_DisableCallback(h->hRsSyncCCallback);
1105  BINT_DisableCallback(h->hRsSyncLossCCallback);
1106#endif
1107
1108#ifdef SmartTuneEnabled 
1109  BTHD_3x7x_P_TNR_callback(h,BTHD_CallbackMode_eSmartTune,&TunerGain,&SmartTune,&RfFreq);
1110  if (SmartTune)
1111    h->pInternalAcquireParam->SampleFreq = 51300000; 
1112  else
1113    h->pInternalAcquireParam->SampleFreq = 54000000; 
1114  BDBG_MSG(("BTHD_P_Acquire: SmartTune = %d, Fs = %d MHz",SmartTune,h->pInternalAcquireParam->SampleFreq));
1115#endif   
1116
1117  BTHD_P_ResetStatus(h);
1118  BTHD_P_ResetAll(h);
1119  BTHD_P_Config(h);
1120  BTHD_P_ResetAcquire(h);
1121
1122  /* Reset lock flag(s), keeping the existing "No Signal" condition */
1123  h->ThdLockStatus &= (1U << THD_LockStatusBit_NoDVBTSignal);   
1124
1125
1126  /* Reset "Abort-Early" signal/flag when starting an acquire */
1127  BTHD_P_AbortAcquireReset(h);
1128
1129#ifdef BTHD_ISDBT_SUPPORT 
1130  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)
1131    retCode = BTHD_P_IsdbtAcquire(h);
1132  else
1133#endif
1134  retCode = BTHD_P_DvbtAcquire(h);
1135  h->pStatus->spare[0] = retCode;
1136
1137  h->pStatus->ReacquireCount++;
1138
1139  switch (retCode) {
1140  case THD_AcquireResult_Lock:          BDBG_MSG(("\tTHD Lock\n"));            break;
1141  case THD_AcquireResult_NoFFTLock:     BDBG_MSG(("\tTHD No FFT Lock\n"));     break;
1142  case THD_AcquireResult_NoCarrierLock: BDBG_MSG(("\tTHD No Carrier Lock\n")); break;
1143  case THD_AcquireResult_NoSPLock:      BDBG_MSG(("\tTHD No SP Lock\n"));      break;
1144  case THD_AcquireResult_NoTPSLock:     BDBG_MSG(("\tTHD No TPS Lock\n"));     break;
1145  case THD_AcquireResult_NoFECLock:     BDBG_MSG(("\tTHD No FEC Lock\n"));     break;
1146  case THD_AcquireResult_NoSignal:      BDBG_MSG(("\tTHD No Signal\n"));       break;
1147  case THD_AcquireResult_NoDVBTSignal:  BDBG_MSG(("\tTHD No DVBT Signal\n"));  break;
1148  case THD_AcquireResult_AbortedEarly:  BDBG_MSG(("\tTHD Acq Aborted Early\n"));  break;
1149  default: BDBG_MSG(("BTHD_ThdTop:retCode = %d", retCode));
1150  }
1151
1152  if ((retCode == THD_AcquireResult_NoSignal) || 
1153      (retCode == THD_AcquireResult_NoDVBTSignal) || 
1154      (retCode == THD_AcquireResult_NoSPLock))
1155  {
1156    h->ThdLockStatus |= (1U << THD_LockStatusBit_NoDVBTSignal);
1157    if (h->pAcquireParam->CommonAcquireParam.AcquireMode & THD_AcquireMode_Scan) {
1158      h->pAcquireParam->CommonAcquireParam.AcquireMode &= ~THD_AcquireMode_Scan;
1159      BKNI_SetEvent(h->hLockEvent);
1160      return retCode;
1161   }
1162
1163   if (h->pAcquireParam->CommonAcquireParam.AcquireMode & THD_AcquireMode_Auto) 
1164   {
1165#ifndef LEAP_BASED_CODE
1166           BKNI_SetEvent(h->hInterruptEvent);
1167#else
1168           BKNI_SetAnyEvent(h->hInterruptEvent, BKNI_TIMER_THD_FLAG);
1169#endif
1170                return retCode;
1171   }
1172  }
1173  else
1174  {
1175    h->ThdLockStatus &= (~(1U << THD_LockStatusBit_NoDVBTSignal));
1176  }
1177
1178/*
1179  if ((retCode == BTHD_AcquireResult_NoSignal) ||
1180      (retCode == BTHD_AcquireResult_NoDVBTSignal) ||
1181      (retCode == BTHD_AcquireResult_NoTPSLock)  ||
1182      (retCode == BTHD_AcquireResult_NoFECLock))
1183  {
1184    if (h->pAcquireParam->CommonAcquireParam.AcquireMode & THD_AcquireMode_Scan) {
1185      h->pAcquireParam->CommonAcquireParam.AcquireMode &= ~THD_AcquireMode_Scan;
1186      BTHD_P_UpdateStatusChange(h, BCHP_LEAP_CTRL_HOST_IRQ_GOT_LOCK_MASK);
1187      return retCode;
1188    }
1189  }
1190*/
1191  /* If lock was achieved, then clear the status but preserve the reacquire count. */
1192  if ((retCode == THD_AcquireResult_Lock) && (retCode != THD_AcquireResult_InitLockState)) {   
1193    ReacquireCount = h->pStatus->ReacquireCount;
1194    BTHD_P_ResetStatusHW(h);
1195    BTHD_P_ResetStatus(h);
1196        h->pStatus->spare[0] = retCode;
1197    h->pStatus->ReacquireCount = ReacquireCount;
1198    BTHD_P_SetTs(h);
1199  }
1200#if 0
1201  /* Check for loss-of-lock in ce_mode=Fixed with timing FD enabled.  If lock is lost, try timing PD */
1202  if (!(h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)) {
1203    /* Check for FEC lock */
1204    if (!((h->ThdLockStatus>> THD_LockStatusBit_SystemLock) & 1) &&
1205                (h->pStatus->ChannelEstimatorMode == THD_ChannelEstimatorMode_Fixed) &&
1206                !BREG_ReadField(h->hRegister,  THD_CORE_CP, PHASE_FREQ_SELECT )) {
1207      BDBG_MSG(("BTHD_ThdTop:\tLock fallback from timing FD to PD"));
1208      BREG_WriteField(h->hRegister, THD_CORE_CP, F_SPACE, 2 );                              /* 12-bin timing pd pilot spacing (mandatory for long-echo channels)*/
1209      BREG_WriteField(h->hRegister, THD_CORE_CP, PHASE_FREQ_SELECT, 1 );                    /* Timing pd enable*/
1210      BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_TPHASE_FRZ, 0 );                       /* Unfreeze timing pd*/ 
1211      BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_COEF,0x00010200 * (2048/2048) );         /* Ki=2^(-13),Kl=2^(-4) (for CCI)*/
1212      BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_MISC,0x00000200 );                       /* FFT window leak to timing loop disabled (prevents "wandering" at low SNR)*/
1213    }
1214  }
1215
1216  /* Check for lock */
1217  /*if((h->ThdLockStatus>> BTHD_LockStatusBit_SystemLock) & 1) {
1218    BTHD_P_UpdateStatusChange(h, BCHP_LEAP_CTRL_HOST_IRQ_GOT_LOCK_MASK);
1219  }*/
1220#endif
1221  BTHD_P_EnableLockInterrupts(h); 
1222  return retCode;
1223}
1224
1225/***************************************************************************
1226 * BTHD_P_SetTs()
1227 ***************************************************************************/
1228void BTHD_P_SetTs(BTHD_3x7x_Handle h)
1229{
1230  uint32_t oi=0;
1231
1232  switch (h->pInternalAcquireParam->TSMode){
1233  /*case BTHD_TSMode_Serial:   oi = 0x00000003; break;*/ /* OI serial mode  */
1234  case THD_TSMode_Serial:   oi = 0x00000103; break; /* OI suppress clock when not valid, serial mode (for external daughter cars in STB ref design)  */
1235  case THD_TSMode_Parallel: oi = 0x00000101; break; /* OI suppress clock when not valid, parallel smooth mode */
1236  default:  BDBG_WRN(("BTHD_SetTs: THD_TSMode_None not supported")); break;
1237  } 
1238  BREG_Write32(h->hRegister, BCHP_THD_CORE_OI, oi);
1239}
1240
1241/***************************************************************************
1242* BTHD_P_SetFrequency()
1243***************************************************************************/
1244void BTHD_P_SetFrequency(BTHD_3x7x_Handle h)
1245{
1246  uint32_t bw, tl_fcw, tl_n, tl_d, cl_n;
1247  uint32_t cl_fcw=0,CenterFreq;
1248  uint32_t pouthi, poutlo, pouthi2;
1249
1250  /* Set the baseband rate */
1251  bw = bthd_bandwidth[h->pAcquireParam->CommonAcquireParam.Bandwidth];
1252  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
1253    tl_n = 512000000 * bw / 3;      /* at bw = 6MHz, fcw = 2 * (512/63) MHz */
1254    tl_d = h->pInternalAcquireParam->SampleFreq * 63;
1255  }
1256  else {
1257    tl_n = (2 * 8000000) * bw;
1258    tl_d = h->pInternalAcquireParam->SampleFreq * 7;
1259  }
1260  /* tl_fcw = (tl_n * (1ULL << 32)) / tl_d; */
1261  BMTH_HILO_32TO64_Mul((tl_n * 2), 0x80000000, &pouthi, &poutlo);
1262  BMTH_HILO_64TO64_Div32(pouthi, poutlo, tl_d, &pouthi2, &tl_fcw);
1263  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_FCW, tl_fcw );
1264
1265  /* Set the carrier frequency */
1266  if ((h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) && 
1267      (h->pAcquireParam->CommonAcquireParam.CenterFreq > h->pInternalAcquireParam->SampleFreq)) {               
1268    CenterFreq = h->pAcquireParam->CommonAcquireParam.CenterFreq - 45000000 - 11250000 + 13500000;
1269  } else
1270    CenterFreq = h->pAcquireParam->CommonAcquireParam.CenterFreq;
1271
1272  cl_n   = CenterFreq ? (long)(h->pInternalAcquireParam->SampleFreq - CenterFreq) : 0L;
1273  /* cl_fcw = (cl_n * (1LL << 32)) / (long)h->pAcquireParam->CommonAcquireParam.SampleFreq; */
1274  BMTH_HILO_32TO64_Mul((cl_n * 2), 0x80000000, &pouthi, &poutlo);
1275  BMTH_HILO_64TO64_Div32(pouthi, poutlo, h->pInternalAcquireParam->SampleFreq, &pouthi2, &cl_fcw);
1276  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_FCW, cl_fcw );
1277
1278  /* BDBG_MSG(("BTHD_P_SetFrequency:\tTL_FCW = 0x%08x\n", tl_fcw)); */
1279  /* BDBG_MSG(("BTHD_P_SetFrequency:\tCL_FCW = 0x%08x\n", cl_fcw)); */
1280}
1281
1282/***************************************************************************
1283 * BTHD_P_SetFrontEnd()
1284 ***************************************************************************/
1285void BTHD_P_SetFrontEnd(BTHD_3x7x_Handle h)
1286{
1287  if (h->pInternalAcquireParam->FrontEndMode == THD_FrontEndMode_Baseband) {
1288    BREG_Write32(h->hRegister,  BCHP_THD_CORE_GLB,0x00000028 );  /* Fs=54,Baseband input,BE=disabled,ICE=acquisition */
1289    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FE,0x00000008 );   /* I/Q aligned, posedge, spinv=0, 2's complement */
1290  } else {
1291    BDBG_MSG(("BTHD_SetFrontEnd:IF input mode"));
1292    BREG_Write32(h->hRegister,  BCHP_THD_CORE_GLB,0x00000020 );  /* Fs=54,IF input,BE=disabled,ICE=acquisition */
1293    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FE,0x00000008 );   /* I/Q aligned, posedge, spinv=0, 2's complement */
1294  }
1295  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)                     
1296    BREG_WriteField(h->hRegister, THD_CORE_GLB, STD, 2);         /* ISDBT Mode */
1297}
1298
1299/***************************************************************************
1300 * BTHD_P_SetNotch()
1301 ***************************************************************************/
1302void BTHD_P_SetNotch(BTHD_3x7x_Handle h)
1303{
1304  uint32_t bw,fcw;
1305  int32_t x[4],y,n,num_notches;
1306  uint32_t pouthi, poutlo, poutlo2, utmp, tmp;
1307
1308#ifdef SmartNotchEnabled 
1309  int16_t TunerGain;
1310  uint16_t SmartTune;
1311  uint32_t RfFreq;
1312  int32_t SmartNotchFreq;
1313  int32_t SmartNotchNum = 6;
1314  int32_t SmartNotchFreqList[6] = {198000000,216000000,506000000,540000000,675000000,844000000};
1315#endif
1316
1317  /* Set the baseband rate */
1318  bw = bthd_bandwidth[h->pAcquireParam->CommonAcquireParam.Bandwidth];
1319  switch(h->pAcquireParam->CommonAcquireParam.CoChannelMode) {
1320  case THD_CoChannelMode_None:  break;
1321  case THD_CoChannelMode_Auto:
1322    if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
1323      /* NTSC Co-channel */
1324      x[0] = -1893000; /* NTSC picture carrier */             
1325      x[1] =  1687000; /* NTSC color carrier */
1326      x[2] =  2607000; /* NTSC FM audio carrier */
1327      num_notches = 3;
1328    }
1329    else {
1330      /* PAL Co-channel */
1331      x[0] = -2750000 + (long)(500000*(8-bw)); /* PALB/G picture  carrier {-2.75,-2.25,-1.75} MHz for BW={8,7,6} MHz */
1332      x[1] =  1550000 + (long)(500000*(8-bw)); /* PALB/G color    carrier { 1.55, 2.05, 2.55} MHz for BW={8,7,6} MHz */
1333      x[2] =  2750000 + (long)(500000*(8-bw)); /* PALB/G FM audio carrier { 2.75, 3.25, 3.75} MHz for BW={8,7,6} MHz */
1334      num_notches = 3;
1335    }
1336#ifdef SmartNotchEnabled 
1337        BTHD_3x7x_P_TNR_callback(h,BTHD_CallbackMode_eRequestMode,&TunerGain,&SmartTune,&RfFreq);
1338                for (n=0; n<SmartNotchNum; n++) {
1339                        SmartNotchFreq = SmartNotchFreqList[n] - RfFreq;       
1340                        /* BDBG_MSG(("{%d,%d,%d,%d}",n,RfFreq,SmartNotchFreqList[n],SmartNotchFreq)); */
1341                        if ((SmartNotchFreq >= -(int32_t)((bw*1000000)>>1)) && (SmartNotchFreq <= ((int32_t)(bw*1000000)>>1)) && (num_notches < 4)) {
1342                                x[num_notches] = SmartNotchFreq;
1343                        num_notches++; 
1344                        h->pInternalAcquireParam->SmartNotchPresent = true;
1345                        break; 
1346        }
1347                }
1348#endif   
1349
1350    /* Compute FCWs */
1351    for (n=0; n<num_notches; n++) {
1352      if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {     
1353        /* Hard-coded for 6MHz channels */
1354        if (n) {
1355          if ((x[n]-x[n-1]) < 0) {
1356            tmp = ~(x[n]-x[n-1]);               
1357            tmp = tmp + 1;             
1358          } else
1359            tmp = (x[n]-x[n-1]);
1360
1361          BMTH_HILO_32TO64_Mul(tmp, (0x1000000 * 63), &pouthi, &poutlo);
1362          BMTH_HILO_64TO64_Div32(pouthi, poutlo, 512000000, &utmp, &poutlo2);
1363          if ((x[n]-x[n-1]) < 0) {
1364            y = ~poutlo2;
1365            y = y + 1; 
1366          }
1367          else
1368            y = poutlo2;
1369          /*y = ((x[n]-x[n-1]) * (1LL<<24) * 63)/(512000000);*/
1370        } else {
1371          if ((x[n]-0     ) < 0) {
1372            tmp = ~(x[n]-0);           
1373            tmp = tmp + 1;             
1374          } else
1375            tmp = (x[n]-0     );
1376
1377          BMTH_HILO_32TO64_Mul(tmp, (0x1000000 * 63), &pouthi, &poutlo);
1378          BMTH_HILO_64TO64_Div32(pouthi, poutlo, 512000000, &utmp, &poutlo2);
1379          if ((x[n]-0) < 0) {
1380            y = ~poutlo2;
1381            y = y + 1; 
1382          } else
1383            y = poutlo2;
1384          /*y = ((x[n]-0     ) * (1LL<<24) * 63)/(512000000);   */
1385        }
1386      } else {
1387        if (n) {
1388          if ((x[n]-x[n-1]) < 0) {
1389            tmp = ~(x[n]-x[n-1]);               
1390            tmp = tmp + 1;             
1391          } else
1392            tmp = (x[n]-x[n-1]);
1393
1394          BMTH_HILO_32TO64_Mul(tmp, (0x1000000 * 7), &pouthi, &poutlo);
1395          BMTH_HILO_64TO64_Div32(pouthi, poutlo, (bw*8000000), &utmp, &poutlo2);
1396          if ((x[n]-x[n-1]) < 0) {
1397            y = ~poutlo2;
1398            y = y + 1; 
1399          } else
1400            y = poutlo2;
1401          /*y = ((x[n]-x[n-1]) * (1LL<<24) * 7)/(bw*8000000);*/
1402        } else {
1403          if ((x[n]-0) < 0) {
1404            tmp = ~(x[n]-0);           
1405            tmp = tmp + 1;             
1406          } else
1407            tmp = (x[n]-0);
1408          BMTH_HILO_32TO64_Mul(tmp, (0x1000000 * 7), &pouthi, &poutlo);
1409          BMTH_HILO_64TO64_Div32(pouthi, poutlo, (bw*8000000), &utmp, &poutlo2);
1410          if ((x[n]-0) < 0) {
1411            y = ~poutlo2;
1412            y = y + 1; 
1413          } else
1414            y = poutlo2;
1415          /*y = ((x[n]-0     ) * (1LL<<24) * 7)/(bw*8000000);   */
1416        }
1417      }
1418      if (y < 0)
1419        fcw = ((uint32_t)((1U << 24) + y)) << 8;
1420      else
1421        fcw = ((uint32_t)y) << 8; 
1422      switch(n) {
1423      case 0: BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH0_FCW, fcw ); break;
1424      case 1: BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH1_FCW, fcw ); break;
1425      case 2: BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH2_FCW, fcw ); break;
1426      case 3: BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH3_FCW, fcw ); break;
1427      default: break;
1428      }
1429    }
1430
1431    /* Enable notch filter */
1432    BREG_WriteField(h->hRegister, THD_CORE_BYP, NOTCH_BYP, 0); 
1433    BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH_DEPTH,0x00000aaa );        /* Acquisition notch depth and width */
1434    BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH_WIDTH,0x00000ddd );                       
1435#ifdef SmartNotchEnabled
1436    BREG_WriteField(h->hRegister,  THD_CORE_NOTCH_DEPTH, DEPTH3, 0xa );
1437    BREG_WriteField(h->hRegister,  THD_CORE_NOTCH_WIDTH, WIDTH3, 0xd );                       
1438#endif
1439    /* BDBG_MSG(("BTHD_P_SetNotch:\tTHD_CORE_NOTCH0_FCW = 0x%08x", BREG_Read32(h->hRegister,  BCHP_THD_CORE_NOTCH0_FCW)); */
1440    /* BDBG_MSG(("BTHD_P_SetNotch:\tTHD_CORE_NOTCH1_FCW = 0x%08x", BREG_Read32(h->hRegister,  BCHP_THD_CORE_NOTCH1_FCW)); */
1441    /* BDBG_MSG(("BTHD_P_SetNotch:\tTHD_CORE_NOTCH2_FCW = 0x%08x", BREG_Read32(h->hRegister,  BCHP_THD_CORE_NOTCH2_FCW)); */
1442
1443    break;       
1444  case THD_CoChannelMode_Other: break;
1445  default: break;
1446  }
1447  return;
1448}
1449
1450/***************************************************************************
1451 * BTHD_P_SetTransGuard()
1452 *** ************************************************************************/
1453THD_TransGuardResult_t BTHD_P_SetTransGuard(BTHD_3x7x_Handle h)
1454{
1455  uint32_t n,d,maxN=0,maxD=0,N;
1456  uint32_t curCorr, maxMinRatio, maxThreshold;
1457  uint32_t maxCorr = 0; /* maxCorr initialization */
1458  uint32_t minCorr[3];
1459  THD_TransGuardResult_t mode_guard_result = THD_TransGuardResult_None;
1460  BERR_Code retCode = BERR_SUCCESS;
1461  uint32_t nMin = 0, nMax = 0, nInc = 1;
1462  uint32_t dMin = 0, dMax = 3;
1463  uint32_t length;
1464
1465  switch (h->pAcquireParam->CommonAcquireParam.TransGuardMode) {
1466    case THD_TransGuardMode_Auto_DVBT:  nMin = 0; nMax = 1; nInc = 1; break;
1467    case THD_TransGuardMode_Auto_ISDBT: nMin = 1; nMax = 2; nInc = 1; break;
1468    case THD_TransGuardMode_Auto:       nMin = 0; nMax = 2; nInc = 1; break;
1469    default: break;
1470  }
1471
1472  if (h->pAcquireParam->CommonAcquireParam.TransGuardMode != THD_TransGuardMode_Manual) {
1473    /* FFT window max correlation,postcursor bias,disable fft,sync_symbols=32,beta=2^(-3),slip_limit=0 */
1474    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW,0x00a01020 );                               
1475    for (n=nMin; n<=nMax; n+=nInc) {
1476      minCorr[n] = 0x7fffffff; /* minCorr initialization */
1477      BREG_WriteField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE, n);
1478
1479      /* Define Guard Interval search range */
1480      if (h->pAcquireParam->CommonAcquireParam.TransGuardMode == THD_TransGuardMode_Auto_ISDBT)
1481        switch (n) {
1482                case 1:   dMin = 1; dMax = 3; break; /* 8K: {1/4, 1/8, 1/16} */
1483                case 2:   dMin = 2; dMax = 3; break; /* 4K: {1/4, 1/8} */
1484                default:  dMin = 0; dMax = 3; break;
1485              }
1486      else {                                 /* Default: {1/4, 1/8, 1/16, 1/32} */
1487        dMin = 0;
1488        dMax = 3;
1489      }
1490
1491      for (d=dMin; d<=dMax; d++) {
1492        BREG_WriteField(h->hRegister, THD_CORE_TPS_OV, GUARD, d);
1493        switch (n) {
1494                case 0:  length = 2048 >> (5-d); break;
1495                case 1:  length = 8192 >> (5-d); break;
1496                case 2:  length = 4096 >> (5-d); break;
1497                default: length = 2048 >> (5-d); break;
1498        }
1499        BREG_WriteField(h->hRegister, THD_CORE_FW_SEARCH, MVG_SUM_LENGTH, length); /* L=D */ 
1500        BREG_WriteField(h->hRegister, THD_CORE_RST, FW_RST, 0);
1501                BINT_EnableCallback( h->hFwCorrMaxCallback);
1502        retCode = BTHD_P_WaitForEventOrAbort(h, h->hFwCorrMaxEvent, 500);
1503        if (retCode != BERR_SUCCESS) {
1504          /*BDBG_MSG(("BTHD_SetTransGuard:\tNo hFwCorrMaxEvent")); */
1505        }
1506
1507                BINT_DisableCallback( h->hFwCorrMaxCallback);
1508        curCorr = BREG_Read32(h->hRegister,  BCHP_THD_CORE_FW_CORR_MAX ) >> d;
1509
1510        if (curCorr > maxCorr) {
1511                /* Update maxCorr, maxN, maxD */
1512          maxCorr = curCorr;
1513          maxN = n;
1514          maxD = d;
1515        }
1516        if (curCorr < minCorr[n])
1517          minCorr[n] = curCorr; /* Update minCorr */
1518
1519        BREG_WriteField(h->hRegister, THD_CORE_RST, FW_RST, 1);
1520        /*BDBG_MSG(("N=%d,D=%d,Cur=%08x,Max=%08x,Min=%08x,maxN=%d,maxD=%d",n,d,curCorr,maxCorr,minCorr[n],maxN,maxD); */
1521      }
1522    }
1523   
1524    maxMinRatio = minCorr[maxN] * h->pInternalAcquireParam->TransGuardMaxMinRatioThreshold[maxD];
1525
1526    /* Normalize max correlation threshold relative to current DAGC threshold.
1527       For consistency with previous chips (2930,3556), h->pAcquireParam->CommonAcquireParam.TransGuardMaxThreshold
1528       is defined assuming a DAGC threshold=14dB=0x028c4 ((uint32_t)(pow(10.0,-14/10)* 262144)). */
1529    maxThreshold = (h->pInternalAcquireParam->TransGuardMaxThreshold / 0x028c4) * BREG_ReadField(h->hRegister, THD_CORE_DAGC, THRESH);
1530
1531    /* Threshold scaling based on mode (2k,4k,8k) */
1532    switch (maxN) {
1533      case 1: maxThreshold = 3* maxThreshold ; break;       /* 8K (multiply by 3) */
1534      case 2:   maxThreshold = (maxThreshold >> 1) ; break; /* 4K (multiply by 2) */
1535      default:  break;
1536    }
1537
1538    if ((maxCorr < maxThreshold) && ((maxCorr << 4) < maxMinRatio))
1539      mode_guard_result = THD_TransGuardResult_NoSignal;
1540    else
1541      if ((maxCorr << 4) < maxMinRatio)
1542        mode_guard_result = THD_TransGuardResult_CoChannelPresent;
1543   
1544    BREG_WriteField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE, maxN);
1545    BREG_WriteField(h->hRegister, THD_CORE_TPS_OV, GUARD, maxD);
1546    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW, 0x00202050 );
1547    BREG_WriteField(h->hRegister, THD_CORE_FW_SEARCH, MVG_SUM_LENGTH, 8); /* L=8*/
1548
1549    N = bthd_transmission_mode[maxN];
1550    BTHD_P_OSleep(h,2,N,maxD);
1551    /* Reset BE and FFT (Necessary to improve acquisition probability) */
1552    BREG_WriteField(h->hRegister, THD_CORE_RST, BE_RST, 1 ); 
1553    BREG_WriteField(h->hRegister, THD_CORE_RST, BE_RST, 0 );     
1554    BREG_WriteField(h->hRegister, THD_CORE_RST, FFT_RST, 1 );
1555    BREG_WriteField(h->hRegister, THD_CORE_RST, FFT_RST, 0 );
1556    BREG_WriteField(h->hRegister, THD_CORE_FW, OUT_ENABLE, 1);
1557
1558    /*BDBG_MSG(("BTHD_SetTransGuard:\tN=%d, D=%d", maxN, maxD); */
1559  }
1560  return mode_guard_result;
1561}
1562
1563/***************************************************************************
1564 * BTHD_P_SetCE()
1565 ***************************************************************************/
1566void BTHD_P_SetCE( BTHD_3x7x_Handle h, 
1567                   THD_ChannelEstimatorMode_t ChannelEstimatorMode)
1568{
1569
1570  switch (ChannelEstimatorMode) {
1571  case THD_ChannelEstimatorMode_Fixed:     
1572    BREG_WriteField(h->hRegister, THD_CORE_CE, AVG_FF, 0x3);        /* CE averager beta = 2^(-4) */
1573    BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 0);     /* CE averager unbypassed */
1574    BREG_WriteField(h->hRegister, THD_CORE_EQ, NSE_AVG_FF, 0x5 );   /* EQ noise averager beta=2^(-8) */
1575    BREG_WriteField(h->hRegister, THD_CORE_BYP, EXP_AVG_NSE, 0x0 ); /* EQ nse + avg nse exponents unbypassed */
1576    break;
1577  case THD_ChannelEstimatorMode_Pedestrian:
1578    BREG_WriteField(h->hRegister, THD_CORE_CE, AVG_FF, 0x0);        /* CE averager beta = 2^(-1) */
1579    BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 0);     /* CE averager bypassed */
1580    BREG_WriteField(h->hRegister, THD_CORE_EQ, NSE_AVG_FF, 0x5 );   /* EQ noise averager beta=2^(-8) */
1581    BREG_WriteField(h->hRegister, THD_CORE_BYP, EXP_AVG_NSE, 0x0 ); /* EQ nse + avg nse exponents unbypassed */
1582    break;
1583  case THD_ChannelEstimatorMode_Mobile:   
1584    BREG_WriteField(h->hRegister, THD_CORE_CE, AVG_FF, 0x0);        /* CE averager beta = 2^(-1) */
1585    BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 1);     /* CE averager bypassed */
1586    BREG_WriteField(h->hRegister, THD_CORE_EQ, NSE_AVG_FF, 0x5 );   /* EQ noise averager beta=2^(-8) */
1587    BREG_WriteField(h->hRegister, THD_CORE_BYP, EXP_AVG_NSE, 0x3 ); /* EQ nse + avg nse exponents unbypassed */
1588    break;
1589  default:
1590    BDBG_WRN(("BTHD_SetCE: BTHD_ChannelEstimatorMode_Auto not supported")); 
1591    break;
1592  }   
1593
1594  /*
1595  switch (ChannelEstimatorMode) {
1596  case BTHD_ChannelEstimatorMode_Fixed:      BDBG_MSG(("BTHD_P_SetCE:\t\tFixed")); break;
1597  case BTHD_ChannelEstimatorMode_Pedestrian: BDBG_MSG(("BTHD_P_SetCE:\t\tPedestrian")); break;
1598  case BTHD_ChannelEstimatorMode_Mobile:     BDBG_MSG(("BTHD_P_SetCE:\t\tMobile")); break;
1599  default:                                   BDBG_WRN(("BTHD_P_SetCE: BTHD_ChannelEstimatorMode_Auto not supported")); break;
1600  }
1601  */
1602}
1603
1604/***************************************************************************
1605 * BTHD_P_WriteTICoef()
1606 ***************************************************************************/
1607void BTHD_P_WriteTICoef( BTHD_3x7x_Handle h)
1608{
1609  /* time_interp_polyphase_1pre_3post_1_16_15dB (1/16) */
1610  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF01,  0x0f8922af);
1611  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF23,  0x3cf55eb4);
1612  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF45,  0x5a9a4ede);
1613  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF67,  0x324b02d5);
1614  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF89,  0xf51beb17);
1615  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF1011,0xecdafd40);
1616  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF1213,0x00a6034b);
1617  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF14,  0x03d00000);
1618
1619  /* 2-tap time interpolator coefficients */
1620  /*
1621  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF01,  0x18003000);
1622  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF23,  0x48006000);
1623  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF45,  0x48003000);
1624  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF67,  0x18000000);
1625  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF89,  0x00000000);
1626  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF1011,0x00000000);
1627  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF1213,0x00000000);
1628  BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_TCOEF14,  0x00000000);
1629  */
1630}   
1631
1632/***************************************************************************
1633 * BTHD_P_WriteFICoef()
1634 ***************************************************************************/
1635void BTHD_P_WriteFICoef( BTHD_3x7x_Handle h, 
1636                         THD_FrequencyInterpolatorMode_t FrequencyInterpolatorMode)
1637{
1638  int ndx;
1639  uint32_t coef;
1640
1641  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FI_ADDR, 0 );
1642  for (ndx = 0; ndx < THD_FrequencyInterpolatorCoefLength; ++ndx) {
1643    coef = bthd_freq_coef_table[ FrequencyInterpolatorMode*THD_FrequencyInterpolatorCoefLength + ndx ];
1644    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FI_COEF, coef );
1645  }
1646  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FI, 0x00000000);
1647}
1648
1649#ifdef BTHD_ISDBT_SUPPORT
1650/***************************************************************************
1651* BTHD_P_GetChannelSpan()
1652***************************************************************************/
1653BTHD_RESULT BTHD_P_GetChannelSpan(BTHD_3x7x_Handle h, THD_FFTWindowMode_t FFTWindowMode, THD_TransmissionMode_t TransmissionMode,THD_GuardInterval_t GuardInterval)
1654{ 
1655  bool bInSpan = false;
1656
1657  /*------- Variables -------*/
1658  /* General */
1659  uint32_t n,k,idx,value,start=0;
1660  uint16_t K,N,D,guard;
1661  uint32_t fscntInit = BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT);
1662 
1663  /* Channel Estimate */
1664   int16_t ceI[256],ceQ[256],ce_num_avg=4, z;
1665 
1666  /* Channel Impulse Response */
1667  int32_t  cirI,cirQ;
1668   uint32_t cir[256];
1669
1670  /* Peak Detection */
1671  uint32_t paths=0;
1672  uint32_t cir_max_val=0,cir_max_idx=0,cir_thresh,thresh=8; /* thresh_dB = thresh*3dB = 24dB */
1673  uint32_t start_idx, cur_max, idx_max;
1674  uint32_t peak_val[128];
1675  int16_t peak_location[128], peak_width[128]; 
1676
1677  /* Span */
1678  int16_t span=0;
1679  uint32_t right_edge_idx=0;
1680 
1681  /*---------- Algorithm --------*/     
1682  /* Get channel estimates for center 256 pilots using snooper */
1683  if (TransmissionMode == THD_TransmissionMode_2k) 
1684    {start = 468; K = 1705; N = 2048;} 
1685  else 
1686    {start = 3024; K = 6817;N = 8192;} 
1687  for (z=0; z<ce_num_avg; z++) {   /* Average CE over multiple captures to improve SNR */
1688    BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_RECORD_CFG,0x01030000 + start );  /* Capture CE, snapshot mode, step=3 */
1689    /* while (!BREG_ReadField(h->hRegister, THD_CORE_CE_RECORD_CFG, DONE)); */
1690    /* Wait 1 second for internal buffer to fill */
1691    if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 1000) ) {
1692      goto BTHD_P_GetChannelSpan_Abort;
1693    }
1694    BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_READ_INDEX,0x00000000 );
1695    for (n=0; n<256; n++) {
1696      value = BREG_Read32(h->hRegister, BCHP_THD_CORE_CE_READ_DATA );
1697      if (z == 0) {
1698        ceI[n] = (int16_t)(((value >> 16) & 0xfff) << 4)/ce_num_avg;
1699        ceQ[n] = (int16_t)(((value >>  4) & 0xfff) << 4)/ce_num_avg;       
1700      } else {
1701        ceI[n] += (int16_t)(((value >> 16) & 0xfff) << 4)/ce_num_avg;
1702        ceQ[n] += (int16_t)(((value >>  4) & 0xfff) << 4)/ce_num_avg;         
1703      }
1704    }   
1705  }
1706
1707  /* Compute CIR using IDFT (should be changed to IFFT for better efficiency) */
1708  for (k=0; k<256; k++) {
1709    /* Compute DFT */
1710    cirI = 0;
1711    cirQ = 0;
1712    for (n=0; n<256; n++) {
1713      idx = (k*n) % 256;
1714      cirI += ((int32_t)( ceI[n]*dft_table[idx][0]) + (int32_t)(ceQ[n]*dft_table[idx][1])) >> 8;
1715      cirQ += ((int32_t)(-ceI[n]*dft_table[idx][1]) + (int32_t)(ceQ[n]*dft_table[idx][0])) >> 8;
1716    }
1717    cirI = cirI >> 16;
1718    cirQ = cirQ >> 16;
1719
1720    /* Compute Power */
1721    cir[k] = (uint32_t)(cirI*cirI + cirQ*cirQ);
1722
1723    /* Compute Max */
1724    if (cir[k] > cir_max_val) {
1725      cir_max_val = cir[k];
1726      cir_max_idx = k;
1727    }
1728  }
1729        /* BDBG_MSG(("\t\tMax of CIR at index:%d , height: %d",cir_max_idx,cir_max_val)); */
1730
1731  /* Determine number of paths in CIR */
1732  cir_thresh = cir_max_val >> thresh;
1733  start_idx = 0; cur_max = cir[0]; idx_max =0;
1734  for (k=1; k<256; k++) {
1735          if (cir[k] > cir_thresh && cir[k-1] <= cir_thresh) {
1736                  start_idx=k;
1737                  cur_max = cir[k];
1738                  idx_max = k;
1739          } else if (cir[k] > cir_thresh && cir[k-1] >= cir_thresh) {
1740                  if (cir[k] > cur_max) {
1741                          cur_max = cir[k];
1742                          idx_max = k;
1743                  }
1744          } else if (cir[k] < cir_thresh && cir[k-1] >= cir_thresh){
1745                peak_val[paths] = cur_max;
1746                peak_width[paths] = k-1-start_idx;
1747                peak_location[paths] = idx_max;
1748                /* BDBG_MSG(("\t\tPath at Index:%d, height: %d, width: %d",peak_location[paths],peak_val[paths], peak_width[paths])); */
1749                paths++;
1750          } else {
1751                  /* Do Nothing */
1752          }             
1753  }
1754
1755  /* Determine guard interval */
1756  switch (GuardInterval) {
1757    case THD_GuardInterval_1_32: D = N/32; break;
1758    case THD_GuardInterval_1_16: D = N/16; break;
1759    default: BDBG_MSG(("Unrecognized GuardInterval - defaulting to BTHD_GuardInterval_e1_8"));
1760    /* fall through */
1761    case THD_GuardInterval_1_8: D = N/8; break;
1762    case THD_GuardInterval_1_4: D = N/4; break;
1763  }
1764  guard = (uint16_t)((256*D*3)/N);
1765   
1766  /* Determine span */
1767  if (paths > 1) {
1768    if (FFTWindowMode == THD_FFTWindowMode_OutOfSpanPre) {
1769      for (k=0; k<paths-1; k++)
1770        if ((peak_location[k] <= guard) && (peak_location[k+1] > guard))   
1771          right_edge_idx = k;
1772      span = peak_location[right_edge_idx] + (256 - peak_location[right_edge_idx+1]);
1773    } else
1774          span = peak_location[paths-1] - peak_location[0];   
1775  }
1776 
1777  /* Convert span to microseconds and save to status structure */
1778  switch (h->pAcquireParam->CommonAcquireParam.Bandwidth) {
1779    case THD_Bandwidth_8MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*8); break;
1780    case THD_Bandwidth_7MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*7); break;
1781    case THD_Bandwidth_6MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*6); break;
1782    case THD_Bandwidth_5MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*5); break;
1783    default: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*8); break;       
1784  }
1785
1786  if (span <= (15*guard/16))
1787    bInSpan = true; 
1788  else
1789    bInSpan = false; 
1790
1791  goto BTHD_P_GetChannelSpan_Exit;
1792
1793
1794BTHD_P_GetChannelSpan_Abort:
1795  bInSpan = false;
1796  BDBG_MSG(("\t\tBTHD_P_GetChannelSpan_Abort (timeout)"));
1797  goto BTHD_P_GetChannelSpan_Exit;
1798
1799BTHD_P_GetChannelSpan_Exit:
1800  BDBG_MSG(("\t\tPaths     : %d",paths));
1801  BDBG_MSG(("\t\tSpan      : %dus (%d)",h->pStatus->ChannelSpan,span));
1802  BDBG_MSG(("\t\tTime      : %dms",(fscntInit - BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT))/(h->pInternalAcquireParam->SampleFreq/1000)));
1803
1804  return (bInSpan);
1805}
1806#endif
1807
1808/***************************************************************************
1809* BTHD_P_GetFFTTriggerPosition()
1810***************************************************************************/
1811bool BTHD_P_GetFFTTriggerPosition(BTHD_3x7x_Handle h, THD_TransmissionMode_t TransmissionMode,THD_GuardInterval_t GuardInterval)
1812{ 
1813  /* completed GetFFTTriggerPosition successfully */
1814  bool bCompletedSuccess = false;
1815
1816  /*------- Variables -------*/
1817  /* General */
1818  uint32_t i,j;
1819  uint32_t n,k,idx,value,start=0;
1820  uint16_t K,N,D,m;
1821 /* uint32_t fscntInit = BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT);*/
1822
1823  /* Channel Estimate */
1824  int16_t z, ceI[256], ceQ[256],ce_num_avg=4;
1825 
1826  /*FFT Output*/
1827  int16_t fftI,fftQ;
1828  #ifdef BCHP_THD_CORE_V_4_0   
1829        int32_t fftpwr[768];
1830  #else
1831        int32_t fftpwr[68];
1832  #endif
1833
1834  /* Channel Impulse Response */
1835  int32_t  cirI,cirQ;
1836  uint32_t cir[256];
1837
1838  /* Peak Detection */
1839  bool     peak_det = false; 
1840  uint32_t paths=0;
1841  uint32_t cir_max_val=0,cir_max_idx=0,cir_thresh,thresh=7; /* thresh_dB = thresh*3dB = 24dB */
1842  uint32_t start_idx, cur_max, idx_max;
1843  uint32_t peak_val[64];
1844  uint16_t peak_location[64], peak_width[64];   
1845
1846  /* First Peak Detection */
1847  int32_t left_edge=8; 
1848  uint16_t tps_num = 6,tps_loc, tps_index, tps_num_avg=4, ce_one_k;
1849  uint16_t tps_loc_2k[7] = {569, 595, 688, 790, 901,1073,1219};
1850  uint16_t tps_loc_8k[7] = {3173,3298,3391,3442,3458,3617,3754};
1851  #ifndef BCHP_THD_CORE_V_4_0
1852  uint16_t tps_start_2k = 5 ;
1853  uint16_t tps_start_8k = 31;
1854  uint16_t num_tps_read;
1855  #endif
1856  int32_t slope=0, slope_scaled=0, tps_rotI[7], tps_rotQ[7];
1857  int32_t aI, aQ, bI, bQ, cI, cQ, dI, dQ;
1858  int32_t error[64], error_min, error_tmp;
1859  uint16_t error_min_idx;
1860  int16_t phase_idx,exp_idx,flt_idx;
1861 
1862  /* Span */
1863  int16_t span=0;
1864  bool missed_first_peak = false;
1865  bool out_of_span = false;
1866  bool in_span = false; 
1867  bool on_guard = false; 
1868 
1869  /* Minimum ISI */
1870  /*uint32_t circirc[256];*/
1871  int32_t guard, x, y;
1872  uint32_t isi_pre, isi_post, isi_y, isi_min;
1873  uint32_t isi_min_offset=0;   
1874
1875  /* Offset and Slope Calculation */
1876  int32_t offset_no_modulo=0, offset=0, offset_scaled=0;
1877
1878  /*---------- Algorithm --------*/     
1879  BDBG_MSG(("\t\t{%d,%d,%d}",BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_OFFSET),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_CORR_INDEX),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_ABS_MIN_INDEX)));
1880
1881  /* Get channel estimates for center 256 pilots using snooper */
1882  if (TransmissionMode == THD_TransmissionMode_2k) 
1883    {start = 468; K = 1705; N = 2048;} 
1884  else 
1885    {start = 3024; K = 6817;N = 8192;} 
1886
1887  /* calculate guard interval length */
1888  switch (GuardInterval) {
1889    case THD_GuardInterval_1_32: D = N/32; break;
1890    case THD_GuardInterval_1_16: D = N/16; break;
1891    default: BDBG_MSG(("Unrecognized GuardInterval - defaulting to BTHD_GuardInterval_e1_8"));
1892    /* fall through */
1893    case THD_GuardInterval_1_8: D = N/8; break;
1894    case THD_GuardInterval_1_4: D = N/4; break;
1895  }
1896  guard = (uint16_t)((256*D*3)/N);
1897
1898  for (z=0; z<ce_num_avg; z++) {   /* Average CE over multiple captures to improve SNR */
1899    BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_RECORD_CFG,0x01030000 + start );  /* Capture CE, snapshot mode, step=3 */
1900    /* Wait 10 msec for internal buffer to fill */
1901    if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 10) ) {
1902        goto BTHD_P_GetFFTTriggerPosition_Abort;
1903    }
1904    BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_READ_INDEX,0x00000000 );
1905    for (n=0; n<256; n++) {
1906      value = BREG_Read32(h->hRegister, BCHP_THD_CORE_CE_READ_DATA );
1907      if (z == 0) {
1908        ceI[n] = (int16_t)(((value >> 16) & 0xfff) << 4)/ce_num_avg;
1909        ceQ[n] = (int16_t)(((value >>  4) & 0xfff) << 4)/ce_num_avg;       
1910      } else {
1911        ceI[n] += (int16_t)(((value >> 16) & 0xfff) << 4)/ce_num_avg;
1912        ceQ[n] += (int16_t)(((value >>  4) & 0xfff) << 4)/ce_num_avg;         
1913      }
1914    }   
1915  }
1916
1917  /* Early-exit abort triggered ? */
1918  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
1919    goto BTHD_P_GetFFTTriggerPosition_Abort;
1920  }
1921
1922  /* Average TPS error for each path over multiple captures to improve SNR */
1923  for (k=0; k<tps_num_avg; k++) { 
1924        #ifdef BCHP_THD_CORE_V_4_0
1925    /* Get fft data for center 256*3 carriers using snooper */
1926    for (m=0; m<3; m++ ) {
1927                BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_RECORD_CFG,0x09010000 + start + m*256 );  /* Capture CE, snapshot mode, step=1 */
1928        /* Wait 10 msec for internal buffer to fill */
1929            if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 10) )  {
1930          goto BTHD_P_GetFFTTriggerPosition_Abort;
1931        }
1932                BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_READ_INDEX,0x00000000 );
1933                for (n=0; n<256; n++) {
1934                        value = BREG_Read32(h->hRegister, BCHP_THD_CORE_CE_READ_DATA );
1935                        fftI = (int16_t)(((value >> 16) & 0xfff) << 4);
1936                        fftQ = (int16_t)(((value >>  4) & 0xfff) << 4);
1937                        if (k)
1938                          fftpwr[m*256 + n] += (fftI*fftI + fftQ*fftQ);
1939                        else
1940                          fftpwr[m*256 + n] = (fftI*fftI + fftQ*fftQ);                 
1941                }
1942    }
1943        #else
1944         /* Get all tps carriers using snooper */
1945                BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_RECORD_CFG,0x09410000 );  /* Capture CE, snapshot mode, TPS Only, step=1 */
1946        /* Wait 10 msec for internal buffer to fill */
1947        if ( ! BTHD_P_Wait_CE_Recording_Status_Done(h, 10) ) {
1948          goto BTHD_P_GetFFTTriggerPosition_Abort;
1949        }
1950                BREG_Write32(h->hRegister, BCHP_THD_CORE_CE_READ_INDEX,0x00000000 );
1951       
1952        if (TransmissionMode == THD_TransmissionMode_2k)
1953            num_tps_read = 17;
1954        else
1955            num_tps_read = 68; 
1956                for (n=0; n<num_tps_read; n++) {
1957                        value = BREG_Read32(h->hRegister, BCHP_THD_CORE_CE_READ_DATA );
1958                        fftI = (int16_t)(((value >> 16) & 0xfff) << 4);
1959                        fftQ = (int16_t)(((value >>  4) & 0xfff) << 4);
1960                        if (k)
1961                          fftpwr[n] += (fftI*fftI + fftQ*fftQ);
1962                        else
1963                          fftpwr[n] = (fftI*fftI + fftQ*fftQ);                 
1964                }
1965   
1966        #endif
1967  }
1968
1969  /* Early-exit abort triggered ? */
1970  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
1971    goto BTHD_P_GetFFTTriggerPosition_Abort;
1972  }
1973
1974  /* Compute CIR using IDFT (should be changed to IFFT for better efficiency) */
1975  for (k=0; k<256; k++) {
1976    /* Compute DFT */
1977    cirI = 0;
1978    cirQ = 0;
1979    for (n=0; n<256; n++) {
1980      idx = (k*n) % 256;
1981      cirI += ((int32_t)( ceI[n]*dft_table[idx][0]) + (int32_t)(ceQ[n]*dft_table[idx][1])) >> 8;
1982      cirQ += ((int32_t)(-ceI[n]*dft_table[idx][1]) + (int32_t)(ceQ[n]*dft_table[idx][0])) >> 8;
1983    }
1984    cirI = cirI >> 16;
1985    cirQ = cirQ >> 16;
1986
1987    /* Compute Power */
1988    cir[k] = (uint32_t)(cirI*cirI + cirQ*cirQ);
1989
1990    /* Compute Max */
1991    if (cir[k] > cir_max_val) {
1992      cir_max_val = cir[k];
1993      cir_max_idx = k;
1994    }
1995          /* BDBG_MSG(("\t\tCIR at index:%d , height: %d",k,cir[k])); */
1996  }
1997        /* BDBG_MSG(("\t\tMax of CIR at index:%d , height: %d",cir_max_idx,cir_max_val)); */
1998
1999  /* Determine number of paths in CIR */
2000  cir_thresh = cir_max_val >> thresh;
2001  start_idx = 0; cur_max = cir[0]; idx_max =0;
2002  for (k=1; k<256; k++) {
2003          if (cir[k] > cir_thresh && cir[k-1] <= cir_thresh) {
2004                  start_idx=k;
2005                  cur_max = cir[k];
2006                  idx_max = k;
2007      peak_det = true;
2008          } else if (cir[k] > cir_thresh && cir[k-1] >= cir_thresh) {
2009                  if (cir[k] > cur_max) {
2010                          cur_max = cir[k];
2011                          idx_max = k;
2012                  }
2013          } else if (cir[k] < cir_thresh && cir[k-1] >= cir_thresh){
2014                peak_val[paths] = cur_max;
2015                peak_width[paths] = k-1-start_idx;
2016                peak_location[paths] = idx_max;
2017                BDBG_MSG(("\t\tPath at Index:%d, height: %d, width: %d, at 0x%x",peak_location[paths],peak_val[paths], peak_width[paths], BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT)));
2018                if (paths < 63)
2019                {
2020                        paths++;
2021                }
2022      peak_det = false;
2023          } else {
2024                  /* Do Nothing */
2025      peak_det = false;
2026          }             
2027  }
2028  /* Peak at the end */
2029  if (peak_det) {
2030                peak_val[paths] = cur_max;
2031                peak_width[paths] = k-1-start_idx;
2032                peak_location[paths] = idx_max;
2033                BDBG_MSG(("\t\tLast Path at Index:%d, height: %d, width: %d",peak_location[paths],peak_val[paths], peak_width[paths])); 
2034                paths++;
2035  }
2036
2037  /* Find first Peak */
2038  /* 2K: 256 Scattered pilots- {468:3:1233} ; TPS pilots- {569, 595, 688, 790, 901,1073,1219} */
2039  /* 8K: 256 Scattered pilots- {3024:3:3789}; TPS pilots- {3173,3298,3391,3442,3458,3617,3754} */
2040  for (error_min = 1<<30, error_min_idx=0, i=0; i<paths ; i++) { /* For all paths in CIR */ 
2041    error[i] = 0; 
2042        slope = peak_location[i] - 1 + left_edge; /* Find IFFT domain shift required */
2043       
2044        for (j=0;j<tps_num ;j++ ) { /* For all TPS carriers - calculate error */
2045                if (TransmissionMode == THD_TransmissionMode_2k) 
2046                        tps_loc = tps_loc_2k[j]; 
2047                else 
2048                        tps_loc = tps_loc_8k[j];
2049                #ifndef BCHP_THD_CORE_V_4_0
2050                if (TransmissionMode == THD_TransmissionMode_2k) 
2051                        tps_index = tps_start_2k + j; 
2052                else 
2053                        tps_index = tps_start_8k + j;
2054                #endif
2055               
2056                /* for ( tps_rotI[j] = 0, tps_rotQ[j] = 0, m=0 ;m<12 ;m++) { */ /* 12 interpolation points */
2057                for ( tps_rotI[j] = 0, tps_rotQ[j] = 0, m=0 ;m<24 ;m++) { /* 24 interpolation points */
2058                  /* Find Filter Coeffs */
2059                        flt_idx = m*3 + 2 - (int16_t)(tps_loc%3);
2060                        aI= interpI[flt_idx];
2061                        aQ= interpQ[flt_idx];
2062                       
2063                        /* Find Unrotated Channel Estimate */
2064                        /* ce_one_k = (uint16_t)3*(((tps_loc/3)) - 5); */ /* 12 interpolation points */
2065                        ce_one_k = (uint16_t)3*(((tps_loc/3)) - 11); /* 24 interpolation points */
2066                        bI= ceI[(ce_one_k - start)/3 + m];
2067                        bQ= ceQ[(ce_one_k - start)/3 + m];
2068
2069                        /* Find Weighting Complex Exponential */
2070                        phase_idx = ((ce_one_k +3*(m) - (K-1)/2)*slope/3)%256;
2071                        exp_idx = (uint16_t) (255-((phase_idx +3*256/2)%256));
2072                        cI = dft_table[ exp_idx ][0];
2073                        cQ = dft_table[ exp_idx ][1];
2074                        /* BDBG_WRN(("BTHD_P_GetChannelImpulseResponse: ce_one_k=%d, phase_idx=%d, exp_idx=%d, flt_idx=%d, cI=%d, cQ=%d, aI=%d, aQ=%d",ce_one_k, phase_idx, exp_idx, flt_idx, cI, cQ, aI, aQ)); */
2075                       
2076                        /* Calculate Resultant TPS Estimate */
2077                        dI = (int32_t)(aI*bI - aQ*bQ) >> 15;
2078                        dQ = (int32_t)(aQ*bI + bQ*aI) >> 15;
2079                        tps_rotI[j] = tps_rotI[j] + ( ((int32_t)cI*dI - (int32_t)cQ*dQ) >> 15 );
2080                        tps_rotQ[j] = tps_rotQ[j] + ( ((int32_t)cQ*dI + (int32_t)cI*dQ) >> 15 );
2081                }
2082
2083                /* Detector Based on rotated TPS values */     
2084                #ifdef BCHP_THD_CORE_V_4_0     
2085                error_tmp = ( (fftpwr[tps_loc - start]/tps_num_avg) - (tps_rotI[j]*tps_rotI[j]) - (tps_rotQ[j]*tps_rotQ[j]) );
2086                #else
2087                error_tmp = ( (fftpwr[tps_index]/tps_num_avg) - (tps_rotI[j]*tps_rotI[j]) - (tps_rotQ[j]*tps_rotQ[j]) );
2088                #endif
2089                if (error_tmp >=0) {
2090                        error[i] += error_tmp;
2091                }       else {
2092                  error[i] += -1*error_tmp;
2093                }
2094    }
2095    error[i] /= tps_num_avg;
2096    BDBG_MSG(("\t\tPath = %d, idx = %d, Err = %d, at 0x%x",i,peak_location[i],error[i], BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT)));
2097  }
2098
2099        /* Find min Error */
2100        for (i=0; i<paths; i++) {
2101        if (error_min > error[i]) {
2102                error_min = error[i];
2103                  error_min_idx = i;
2104                  /* BDBG_MSG(("\t\tMin Path = %d, Min Err = %d",error_min_idx,error_min)); */
2105          }
2106        }
2107  BDBG_MSG(("\t\tMin Path = %d, Min Err = %d",error_min_idx,error_min)); 
2108
2109  /* Determine Span */
2110  if (error_min_idx>0) {
2111    if (peak_location[error_min_idx] == 255) /* Special case of echo wrap around at end */
2112            span = peak_location[paths-2] - peak_location[0];
2113    else {
2114      k = error_min_idx-1;
2115      while (k && ((peak_location[error_min_idx]-peak_location[k]) < left_edge)) k--; /* Do not consider peaks within left_edge of peak w/minimum error in span calculation */
2116            span = 256 + peak_location[k] - peak_location[error_min_idx];
2117            missed_first_peak = true;     
2118    }
2119  } else if (peak_location[paths-1] == 255) /* Special case of echo wrap around at end */
2120          span = peak_location[paths-2] - peak_location[error_min_idx];
2121  else
2122          span = peak_location[paths-1] - peak_location[error_min_idx];
2123  if (span > 220)
2124    out_of_span = true;   
2125
2126  if (span <= (15*guard/16))
2127    in_span = true;
2128
2129  if ( (span <= guard+2) & (span >= guard-3) )  /* For the special case of on-the-GI echos, force FFTT adjustment */
2130          on_guard = true;           
2131 
2132  /* BDBG_MSG(("\t\tSpan=%d ", span)); */
2133
2134  /* Continue with ISI, offset, slope calculations only if the time-domain processing missed the first peak */
2135  if (missed_first_peak | on_guard) {
2136    /* Determine FW Offset for minimum ISI */
2137        #if 0
2138    for (i=0;i<256;i++ ) /* Circular Shift */
2139          circirc[i] = cir[ (i+peak_location[error_min_idx])%256 ];
2140        #endif
2141
2142    for (isi_min = 1<<30,y=0; y<(256-guard); y++) {
2143          for ( isi_pre=0,x=0; x<=y; x++) /* ISI_Pre */
2144                  isi_pre += (y-x)*(cir[(x+peak_location[error_min_idx])%256]/256);
2145          for (isi_post=0, x=y+guard; x<256; x++) /* ISI_Post */
2146                  isi_post += (x-y-guard+1)*(cir[(x+peak_location[error_min_idx])%256]/256);
2147          isi_y = isi_pre + isi_post;
2148
2149          if (isi_y < isi_min) {
2150                  isi_min = isi_y;
2151                  isi_min_offset = y;
2152          }
2153    }
2154    BDBG_MSG(("\t\tISI_Min=%d, ISI_min_offset=%d ",isi_min,isi_min_offset)); 
2155
2156    /* Determine Offset and Slope */
2157    offset_no_modulo = isi_min_offset + peak_location[error_min_idx] - peak_width[error_min_idx];
2158    /* Special case for on-the-guard echo */
2159    if (on_guard & ~missed_first_peak) { /* special case of on-guard post echo */
2160      if (peak_location[error_min_idx] == 255) /* Special case of wrap around echo */
2161        offset_no_modulo = offset_no_modulo - 2 + peak_width[error_min_idx];
2162      else
2163        offset_no_modulo = - peak_location[error_min_idx] + 2 ;
2164    }
2165    else if (on_guard & missed_first_peak) /* special case of on-guard pre echo */
2166      offset_no_modulo = offset_no_modulo - 2 + peak_width[error_min_idx];
2167
2168    if (peak_location[error_min_idx] > cir_max_idx) { /* Determine offset */
2169          BDBG_MSG(("\t\tModulo offset"));
2170          offset = 256 - offset_no_modulo;
2171    } else {
2172          offset = offset_no_modulo;
2173    }
2174
2175
2176    if (span <= guard) { /*Determine slope*/
2177            slope = 0;
2178    } else {
2179      slope = peak_location[error_min_idx] + offset;
2180          BDBG_MSG(("\t\tSlope before Modulo = %d", slope));
2181      if (peak_location[error_min_idx] == 255) { /* special case for on-the-GI peak*/ 
2182        slope = offset - 1;
2183      }
2184      else if ((peak_location[error_min_idx] > cir_max_idx) && (slope > guard)) {
2185            BDBG_MSG(("\t\tModulo slope"));
2186            slope = slope - 256 - cir_max_idx + left_edge; 
2187          }     
2188    }
2189
2190    /* Scale from IFFT-point time-domain to N-point freq-domain */
2191    offset_scaled = (int16_t)((offset*N)/(3*256));
2192    slope_scaled  = (slope*N)/(3*256);
2193  }
2194
2195  h->pStatus->FFTTriggerOffset = offset_scaled;
2196  h->pStatus->FFTTriggerSlope = slope_scaled;
2197  h->pStatus->FFTTriggerMissed = missed_first_peak;
2198  h->pStatus->FFTTriggerOutOfSpan = out_of_span;
2199  h->pStatus->FFTTriggerInSpan = in_span;
2200  h->pStatus->FFTTriggerOnGuard = on_guard;
2201     
2202  /* Convert span to microseconds and save to status structure */
2203  switch (h->pAcquireParam->CommonAcquireParam.Bandwidth) {
2204    case THD_Bandwidth_8MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*8); break;
2205    case THD_Bandwidth_7MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*7); break;
2206    case THD_Bandwidth_6MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*6); break;
2207    case THD_Bandwidth_5MHz: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*5); break;
2208    default: h->pStatus->ChannelSpan = (span*(N >> 11)*7)/(3*8); break;       
2209  }
2210
2211  BDBG_MSG(("\t\tPaths     : %d",paths));
2212  BDBG_MSG(("\t\tMissed    : %d",missed_first_peak));
2213  BDBG_MSG(("\t\tOutOfSpan : %d",out_of_span));   
2214  BDBG_MSG(("\t\tOnGuard   : %d",on_guard));   
2215  BDBG_MSG(("\t\tOffset    : %d (%d)",offset_scaled,offset));
2216  BDBG_MSG(("\t\tSlope     : %d (%d)",slope_scaled,slope));   
2217  BDBG_MSG(("\t\tSpan      : %dus (%d)",h->pStatus->ChannelSpan,span));
2218  /*BDBG_MSG(("\t\tTime      : %dms",(fscntInit - BREG_Read32(h->hRegister, BCHP_THD_CORE_FSCNT))/54000));*/
2219
2220  bCompletedSuccess = true;
2221  goto BTHD_P_GetFFTTriggerPosition_Exit;
2222
2223BTHD_P_GetFFTTriggerPosition_Abort:
2224  BDBG_MSG(("\t\tBTHD_P_GetFFTTriggerPosition Abort (timeout or early-exit)"));
2225  bCompletedSuccess = false; 
2226  h->pStatus->FFTTriggerMissed = true;
2227  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
2228      BDBG_MSG(("\t\tBTHD_P_GetFFTTriggerPosition: Early-Exit abort request is active."));
2229  }
2230
2231BTHD_P_GetFFTTriggerPosition_Exit:
2232  return ( bCompletedSuccess );
2233}
2234
2235/***************************************************************************
2236* BTHD_P_SetFFTTriggerPosition()
2237***************************************************************************/
2238void BTHD_P_SetFFTTriggerPosition(BTHD_3x7x_Handle h, THD_TransmissionMode_t TransmissionMode,THD_GuardInterval_t GuardInterval)
2239{ 
2240  BSTD_UNUSED(TransmissionMode);
2241  BSTD_UNUSED(GuardInterval);
2242  /*uint32_t N = bthd_transmission_mode[TransmissionMode];*/
2243 
2244  BDBG_MSG(("\t\t{%d,%d,%d,%d}",BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_OFFSET),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_CORR_INDEX),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_ABS_MIN_INDEX),h->pStatus->FFTTriggerOffset));
2245
2246  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );                    /* Deassert FFT window reference index reset (active-low) */
2247  BINT_EnableCallback( h->hFwSyncCallback);
2248
2249  BKNI_WaitForEvent(h->hFwSyncEvent, 10);
2250  /* BREG_WriteField(h->hRegister,THD_CORE_FW_MISC, TL_SHIFT, 0); */
2251  /* BREG_WriteField(h->hRegister, THD_CORE_FW, LIMIT, 0); */                   /* FW slip_limit=0 */
2252  BREG_WriteField(h->hRegister, THD_CORE_FW_OFFSET, OFFSET, h->pStatus->FFTTriggerOffset );        /* Apply pre-FFT trigger offset */
2253  BREG_WriteField(h->hRegister, THD_CORE_FW_SLIP, SLIP_OFFSET, h->pStatus->FFTTriggerSlope );      /* Apply post-FFT slope */
2254  BKNI_WaitForEvent(h->hFwSyncEvent, 10);
2255  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 0 );                 /* Reset FFT window reference index (active low) for new fw_offset to take effect*/
2256  BKNI_WaitForEvent(h->hFwSyncEvent, 10); 
2257  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );                 /* Deassert FFT window reference index reset (active-low) */
2258
2259  BINT_DisableCallback( h->hFwSyncCallback);
2260
2261  BDBG_MSG(("\t\t{%d,%d,%d}",BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_OFFSET),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_CORR_INDEX),BREG_Read32(h->hRegister, BCHP_THD_CORE_FW_ABS_MIN_INDEX)));
2262
2263
2264}
2265
2266/***************************************************************************
2267* BTHD_P_StatusSsi()
2268***************************************************************************/
2269uint32_t BTHD_P_StatusSsi( int32_t SignalStrength, THD_Qam_t mod, THD_CodeRate_t cod)
2270{
2271  int16_t prel, return_val=0;
2272  int16_t refSignalLevel[3][5] = /* mod,cod */
2273        {
2274        { -93, -91, -90, -89, -88 }, /* QPSK            */
2275        { -87, -85, -84, -83, -82 }, /* 16-QAM  */
2276        { -82, -80, -78, -77, -76 }  /* 64-QAM  */
2277        };
2278
2279  /* SSI Calculation */
2280  prel = SignalStrength - refSignalLevel[mod][cod];
2281  if ( prel >= 35 )
2282  {     return_val = 100;       }
2283  else if ( prel >= 20 && prel < 35 )
2284  {     return_val = (prel-20)*2/3 + 90;        }
2285  else if ( prel >= 0 && prel < 20 )
2286  {     return_val = 4*prel + 10;       }
2287  else if ( prel >= -15 && prel < 0 )
2288  {     return_val = (prel + 15)*2/3;   }
2289  else if ( prel < -15 )
2290  {     return_val = 0; }
2291
2292  return((uint32_t)return_val);
2293}
2294
2295/***************************************************************************
2296* BTHD_P_StatusSqi()
2297***************************************************************************/
2298uint32_t BTHD_P_StatusSqi(int32_t SNRx256, uint32_t BER, uint32_t TotFrm, THD_Qam_t mod, THD_CodeRate_t cod)
2299{
2300  int16_t ber_sqi=0, cnrel, return_val=0;
2301  int16_t CNNordigP1x256[3][5] =  /* mod,cod */
2302        {
2303  {1305, 1766, 2022, 2278, 2483}, /* QPSK:   256*{  5.1,  6.9,  7.9,  8.9,  9.7 } */
2304  {2764, 3353, 3737, 3993, 4096}, /* 16-QAM: 256*{ 10.8, 13.1, 14.6, 15.6, 16.0 } */
2305  {4224, 4787, 5171, 5529, 5760}  /* 64-QAM: 256*{ 16.5, 18.7, 20.2, 21.6, 22.5 } */   
2306        };
2307   
2308  /* BER SQI Calculation */ 
2309  /* 2^31 = 0x80000000, 1e-3*(2^31) = 2147484, 1e-7*(2^31)=215  */
2310  if (TotFrm) {
2311          if ( BER <= 215 )
2312          {     ber_sqi = 100;  }
2313          else if ( (BER <= 2147484) && (BER > 215) )
2314          {     ber_sqi = (BMTH_2560log10((0x80000000)/BER)/128) - 40; }
2315          else if ( BER > 2147484 )
2316          {     ber_sqi = 0;    }
2317  }
2318
2319  /* SQI Calculation */
2320  cnrel = (SNRx256 - CNNordigP1x256[mod][cod]) >> 8;
2321  if ( cnrel >= 3 )
2322  {     return_val = ber_sqi;   }
2323  else if ( cnrel >= -7 && cnrel < 3 )
2324  {     return_val = (((cnrel-3)/10)+1)*ber_sqi;        }
2325  else if ( cnrel < -7 )
2326  {     return_val = 0; }
2327
2328  return((uint32_t)return_val);
2329}
2330
2331/***************************************************************************
2332 * BTHD_P_Status()
2333 ***************************************************************************/
2334void BTHD_P_Status(BTHD_3x7x_Handle h)
2335{
2336  uint32_t value,bw,N,eq_snrp,ce_beta,ce_byp;
2337  long int cl_int,tl_int;
2338  int16_t TunerGain;
2339  uint16_t SmartTune; 
2340  int32_t  snr_factor, tmp;
2341  uint32_t pouthi,poutlo,poutlo2,utmp,RfFreq;
2342 
2343#ifdef EMULATION_ENABLED
2344  h->pStatus->Lock = 6;
2345  return;
2346#endif
2347
2348  /* Determine transmission parameters */
2349  value = BREG_Read32(h->hRegister,  BCHP_THD_CORE_TPS_OV);
2350  h->pStatus->TransmissionMode = ((value >> 24) & 0x3);
2351  h->pStatus->GuardInterval = ((value >> 20) & 0x3);
2352  h->pStatus->Bandwidth = h->pAcquireParam->CommonAcquireParam.Bandwidth;
2353
2354  /* Determine spctral inversion (only works for baseband input mode) */
2355  if (BREG_ReadField(h->hRegister, THD_CORE_FE, NEGATE_Q))
2356    h->pStatus->Spectrum = THD_Spectrum_Inverted;
2357  else
2358    h->pStatus->Spectrum = THD_Spectrum_Normal;
2359   
2360  /* Compute DAGC gain */
2361  value  = BREG_ReadField(h->hRegister,  THD_CORE_DAGC_FILT,  LFO  ) ;
2362  h->pStatus->DagcGain = (short)((long int)(BMTH_2560log10(value) << 1) - 38632);  /* When the gain = -1.0, 0dB =  floor(2*2560*log10(hex2dec('2000000'))) = 38632 = adjust factor, Application takes 20*log10(x/256.0) to obtain value in dB */
2363
2364  /* Compute signal strength */
2365  BTHD_3x7x_P_TNR_callback(h,BTHD_CallbackMode_eRequestMode,&TunerGain,&SmartTune,&RfFreq);
2366
2367  h->pStatus->SignalStrength = 256*THD_SignalStrengthCalibrationFactor - ((int32_t)TunerGain + h->pStatus->DagcGain);
2368  /* BDBG_MSG(("\tSignalStrength: %d dBm",h->pStatus->SignalStrength/256)); */
2369
2370  /* Compute carrier offset */
2371  bw = bthd_bandwidth[h->pAcquireParam->CommonAcquireParam.Bandwidth];
2372  cl_int = (long int)BREG_Read32(h->hRegister,  BCHP_THD_CORE_CL_INT );
2373  if (cl_int < 0)
2374    cl_int = -cl_int;
2375
2376  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2377    /* freq = (cl_int / N / 2^32) * (2 * 512 / 63) * (bw / 6) * 1000000  */
2378    utmp = (1000000*bw);
2379    BMTH_HILO_32TO64_Mul(utmp, cl_int, &pouthi, &poutlo);
2380    BMTH_HILO_64TO64_Div32(pouthi, poutlo, 378, &utmp, &poutlo2);
2381    BMTH_HILO_64TO64_Div32(utmp, poutlo2, 0x400000, &pouthi, &poutlo);  /* this is the same as >> 22 */
2382  } else {
2383    /* freq = (cl_int / N / 2^32) * (2 * 64 / 7) * (bw / 8) * 1000000 */
2384    utmp = (15625*bw);
2385    BMTH_HILO_32TO64_Mul(utmp, cl_int, &pouthi, &poutlo);
2386    BMTH_HILO_64TO64_Div32(pouthi, poutlo, 7, &utmp, &poutlo2);
2387    BMTH_HILO_64TO64_Div32(utmp, poutlo2, 0x400000, &pouthi, &poutlo);  /* this is the same as >> 22 */
2388  }
2389  N = bthd_transmission_mode[h->pStatus->TransmissionMode]/1024;
2390  h->pStatus->CarrierOffset = (poutlo / N);
2391
2392  cl_int = BREG_Read32(h->hRegister,  BCHP_THD_CORE_CL_INT );
2393  if (cl_int < 0)
2394    h->pStatus->CarrierOffset = -h->pStatus->CarrierOffset;
2395
2396  /* Compute timing offset */
2397  tl_int  = (long int)BREG_Read32(h->hRegister,  BCHP_THD_CORE_TL_INT ); 
2398  if (tl_int < 0)
2399    tl_int = -tl_int;
2400
2401  /* tmp = (((((long long int)h->pAcquireParam->CommonAcquireParam.SampleFreq)*tl_int)/1000000)*15625) >> (16 + 6 + 10);
2402     h->pStatus->TimingOffset = (long int)(tmp / N);
2403  */
2404  BMTH_HILO_32TO64_Mul(h->pInternalAcquireParam->SampleFreq, tl_int, &pouthi, &poutlo);
2405  BMTH_HILO_64TO64_Div32(pouthi, poutlo, 1000000, &utmp, &poutlo2);
2406  BMTH_HILO_64TO64_Mul(utmp, poutlo2, 0, 15625, &utmp, &poutlo);
2407  h->pStatus->TimingOffset = (long int)(utmp / N);
2408
2409  tl_int  = (long int)BREG_Read32(h->hRegister,  BCHP_THD_CORE_TL_INT ); 
2410  if (tl_int < 0)
2411    h->pStatus->TimingOffset = -h->pStatus->TimingOffset;
2412
2413/* Compute pilot SNR, pilotSNR = 256 * BBS_SNR
2414     pilotSNR   = 256 * (b-m*10*log10(EQ_SNRP)) ,   
2415                = 256*b - m*256*10*log10(EQ_SNRP)
2416               
2417    m = 1.03, b (ce_beta = snr_factor_table[][])is depended on GI and CE_AVG_FF. 
2418  */
2419  h->pStatus->SNRPilot = 0;
2420  eq_snrp = BREG_Read32(h->hRegister,  BCHP_THD_CORE_EQ_SNRP);
2421  if (eq_snrp) {
2422   /* ce_beta has 4 possible values.*/
2423    const uint16_t snr_factor_8K_table[][5] = {
2424      { /* Guard interval: 1/32 */
2425        19706, 
2426        20702,
2427        21104,
2428        21270,
2429        21344
2430      },
2431      { /* Guard interval: 1/16 */
2432        19699,
2433        20680,
2434        21083,
2435        21249,
2436        21357
2437      },
2438      { /* Guard interval: 1/8 */
2439        19658,
2440        20626,
2441        21032,
2442        21221,
2443        21343
2444      },
2445      { /* Guard interval: 1/4 */
2446        19478,
2447        20558,
2448        20936,
2449        21139,
2450        21220
2451      }
2452    };
2453   
2454    const uint16_t snr_factor_2K_table[][5] = {
2455      { /* Guard interval: 1/32 */
2456        19786,
2457        20781,
2458        21144,
2459        21326,
2460        21400       
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477      },
2478      { /* Guard interval: 1/16 */
2479        19804,
2480        20785,
2481        21163,
2482        21330,
2483        21374
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500      },
2501      { /* Guard interval: 1/8 */
2502        19796,
2503        20781,
2504        21164,
2505        21324,
2506        21413
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523      },
2524      { /* Guard interval: 1/4 */
2525        19794,
2526        20770,
2527        21162,
2528        21332,
2529        21408
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546      }
2547    };
2548
2549    ce_byp = BREG_ReadField(h->hRegister,  THD_CORE_BYP, CE_AVG_BYP); 
2550       
2551    if (ce_byp == 0)
2552    {
2553        ce_beta = BREG_ReadField(h->hRegister,  THD_CORE_CE, AVG_FF);
2554        if (ce_beta > 4)  /* limited ce_beta < 5 */
2555            ce_beta = 4;
2556       
2557        if (h->pStatus->TransmissionMode == THD_TransmissionMode_2k)
2558            snr_factor = snr_factor_2K_table[h->pStatus->GuardInterval][ce_beta];
2559        else
2560            snr_factor = snr_factor_8K_table[h->pStatus->GuardInterval][ce_beta];
2561                       
2562        tmp = ((103*BMTH_2560log10(eq_snrp))/100); 
2563               
2564        if (snr_factor > (tmp))
2565
2566
2567
2568
2569            h->pStatus->SNRPilot = snr_factor - tmp;
2570        else
2571            h->pStatus->SNRPilot = 0;   /* Should never happen, prevent SNRPilot becoming random number. */           
2572       
2573
2574
2575    }
2576    else
2577    {}        /*Place holder for ce_byp = 1, */       
2578  }
2579#ifdef BTHD_ISDBT_SUPPORT
2580  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2581    BTHD_P_IsdbtStatus(h);
2582 } else {
2583#endif
2584    BTHD_P_DvbtStatus(h); 
2585    h->pStatus->SNR = h->pStatus->SNRPilot;
2586          h->pStatus->Ssi = BTHD_P_StatusSsi(h->pStatus->SignalStrength/256, 
2587                                             h->pStatus->DvbtStatus.Qam, 
2588                                             h->pStatus->DvbtStatus.CodeRateHP);
2589        h->pStatus->Sqi = BTHD_P_StatusSqi(h->pStatus->SNRPilot, 
2590                                           h->pStatus->DvbtStatus.VitBER, 
2591                                           h->pStatus->DvbtStatus.TS_TBERC,
2592                                           h->pStatus->DvbtStatus.Qam, 
2593                                           h->pStatus->DvbtStatus.CodeRateHP);   
2594#ifdef BTHD_ISDBT_SUPPORT
2595  }
2596#endif
2597
2598  /* Update Lock Status */
2599  h->pStatus->Lock = ((h->ThdLockStatus >> THD_LockStatusBit_SystemLock) & 1);
2600  h->pStatus->NoSignal = ((h->ThdLockStatus >> THD_LockStatusBit_NoDVBTSignal) & 1);
2601  h->pStatus->FECLock = ((h->ThdLockStatus >> THD_LockStatusBit_FECLock) & 1);
2602
2603  /* Update Auto Acquire Mode Status */
2604  h->pStatus->AcquireMode = h->pAcquireParam->CommonAcquireParam.AcquireMode;
2605}
2606
2607/***************************************************************************
2608 * BTHD_P_ResetAll()
2609 ***************************************************************************/
2610void BTHD_P_ResetAll(BTHD_3x7x_Handle h)
2611{
2612  uint32_t reg1, reg4, reg5, regmem;
2613
2614  reg1 = BREG_Read32(h->hRegister,  BCHP_THD_CORE_SWSPARE1);   
2615  reg4 = BREG_Read32(h->hRegister, BCHP_THD_CORE_SWSPARE4 );
2616  reg5 = BREG_Read32(h->hRegister, BCHP_THD_CORE_SWSPARE5 ); 
2617  regmem = BREG_Read32(h->hRegister, BCHP_THD_CORE_SCB_ADDR_OFFSET ); 
2618
2619  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST ,0xffffffff );       /* Reset datapath and register interface */
2620  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST2,0x000001ff );
2621  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST ,0x007a1008 );       /* Hold RS_ERC,RS,FEC,BCH_ERC,TPS,FW,FE FIFO in reset */
2622  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST2,0x00000061 );       /* Hold TMCC_ERC,TMCC,NSE_AVG in reset */
2623  BREG_Write32(h->hRegister,  BCHP_THD_INTR2_CPU_CLEAR,0x001fffff);  /* Clear all MIPS interrupt status */
2624  BREG_Write32(h->hRegister,  BCHP_THD_INTR2_PCI_CLEAR,0x001fffff);  /* Clear all PCI interrupt status */
2625
2626  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE1, reg1);
2627  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE4, reg4);
2628  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE5, reg5);
2629  BREG_Write32(h->hRegister, BCHP_THD_CORE_SCB_ADDR_OFFSET, regmem);
2630}
2631
2632/***************************************************************************
2633 * BTHD_P_ResetAcquire()
2634 ***************************************************************************/
2635void BTHD_P_ResetAcquire(BTHD_3x7x_Handle h)
2636{
2637  uint32_t reg1, reg4, reg5, regmem;
2638
2639  reg1 = BREG_Read32(h->hRegister,  BCHP_THD_CORE_SWSPARE1);   
2640  reg4 = BREG_Read32(h->hRegister, BCHP_THD_CORE_SWSPARE4 );
2641  reg5 = BREG_Read32(h->hRegister, BCHP_THD_CORE_SWSPARE5 ); 
2642  regmem = BREG_Read32(h->hRegister, BCHP_THD_CORE_SCB_ADDR_OFFSET ); 
2643
2644  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST ,0xfffffffe );       /* Reset datapath */
2645  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST2,0x000000ff );
2646  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FRZ,0xffffffff );        /* Freeze all */
2647  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST ,0x007a1008 );       /* Hold RS_ERC,RS,FEC,BCH_ERC,TPS,FW,FE FIFO in reset */
2648  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RST2,0x00000161 );       /* Release active-low FW_REF reset, hold TMCC_ERC,TMCC,NSE_AVG in reset */
2649  BREG_Write32(h->hRegister,  BCHP_THD_INTR2_CPU_CLEAR,0x001fffff);  /* Clear all MIPS interrupt status */
2650  BREG_Write32(h->hRegister,  BCHP_THD_INTR2_PCI_CLEAR,0x001fffff);  /* Clear all PCI interrupt status */
2651
2652  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE1, reg1);
2653  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE4, reg4);
2654  BREG_Write32(h->hRegister, BCHP_THD_CORE_SWSPARE5, reg5);
2655  BREG_Write32(h->hRegister, BCHP_THD_CORE_SCB_ADDR_OFFSET, regmem);
2656#ifdef SmartNotchEnabled 
2657  h->pInternalAcquireParam->SmartNotchPresent = false;
2658#endif 
2659}
2660
2661/***************************************************************************
2662 * BTHD_P_ResetStatus()
2663 ***************************************************************************/
2664void BTHD_P_ResetStatus(BTHD_3x7x_Handle h)
2665{
2666#ifdef BTHD_ISDBT_SUPPORT
2667  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2668    BTHD_P_IsdbtResetStatus(h);
2669    h->pStatus->Lock = false; 
2670  } else
2671#endif
2672    BTHD_P_DvbtResetStatus(h);
2673    h->pStatus->Lock = 0;
2674}
2675
2676/***************************************************************************
2677 * BTHD_P_ResetStatusHW()
2678 ***************************************************************************/
2679void BTHD_P_ResetStatusHW(BTHD_3x7x_Handle h)
2680{
2681  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );       /* Reset FEC error counters */
2682  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
2683#ifdef BTHD_ISDBT_SUPPORT
2684  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2685    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 1 );
2686    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 0 );
2687    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 1 );
2688    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 0 );
2689  }
2690#endif
2691}
2692
2693/***************************************************************************
2694 * BTHD_P_Config()
2695 ***************************************************************************/
2696void BTHD_P_Config(BTHD_3x7x_Handle h)
2697{
2698        uint32_t k;
2699
2700  /*************************************************************************
2701   * Configuration
2702   *************************************************************************/
2703  BTHD_P_SetFrontEnd(h);                                             /* Setup frontend */
2704  BTHD_P_SetFrequency(h);                                            /* Setup frequencies (channel bandwidth,carrier frequency) */
2705  BTHD_P_WriteTICoef(h);                                             /* Setup time interpolator coefficients */
2706  BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_InSpan);       /* Setup frequency interpolator coefficients */
2707
2708  BREG_WriteField(h->hRegister, THD_CORE_DAGC, THRESH, 0x00a3d );    /* DAGC threshold=20dB (uint32_t)(pow(10.0,-20/10)* 262144) */
2709  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL,0x00000600 );         /* Carrier loop int_wait=6 */
2710  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW,0x00212050 );         /* FFT window postcursor bias,enable fft,sync_symbols=32,beta=2^(-5),slip_limit=0 */
2711  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SEARCH,0x01802008 );  /* FFT window min_scale=1.5,out-of-span pre or in-span echoes,1st peak mode,L=8 */
2712  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_OFFSET,0x00000010 );  /* FFT window offset=16 */
2713  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_MISC,0x00000200 );    /* FFT window leak to timing loop disabled, disallow zeros */
2714  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SPAN,0x00000200 );    /* FFT window span scale = 0.25 */
2715  /*BREG_Write32(h->hRegister,  BCHP_THD_CORE_CE_LMS,0x66030210 );  */   /* CE lms FI center leakage=2^-12,FI edge leakage=2^-12,TI mu=2^-8, FI center mu=2^-4, FI edge mu=2^-6 */ 
2716  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CE_LMS,0x55830212 );     /* CE lms FI center leakage=2^-14,FI edge leakage=2^-14,FI leak center only,TI mu=2^-8, FI center mu=2^-4, FI edge mu=2^-6, FI adapt center only */ 
2717  BREG_Write32(h->hRegister,  BCHP_THD_CORE_EQ_SNR_CTL,0x00000003 ); /* EQ SNR estimator beta=2^(-12) */
2718  BREG_Write32(h->hRegister,  BCHP_THD_CORE_BER_SYNC,0x004001ff );   /* BERT sync thresholds */
2719  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TPS_SYNC,0x00000076 );   /* TPS sync thresholds */
2720  BREG_Write32(h->hRegister,  BCHP_THD_CORE_OI,0x00000003);          /* OI burst mode */
2721#ifdef BTHD_ISDBT_SUPPORT
2722  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2723    BREG_WriteField(h->hRegister, THD_CORE_TMCC_FAST, TDI_ACCL, 0x1 );    /* enable TMCC fast acquisition */
2724    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_SYNC_CTRL,0x00005656);   
2725    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_AC_CTRL,0x00000001);     
2726    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_SYNC_CTRL_B,0x00005656); /* AC and RT (uncr+corr)/(uncr+corr+clean) */
2727    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_AC_CTRL_B,0x00000001);   
2728    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_SYNC_CTRL_C,0x00005656);
2729    BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_AC_CTRL_C,0x00000001);   /* lock if ( ZERO (uncr+corr) per ONE (uncr_corr+clean) = one clean block */ 
2730  } else {
2731#endif
2732  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_SYNC_CTRL,0x00002656); /* RS lock detector acq_numer=Uncorrected, acq_denom=Total, trk_numer=Corrected+Uncorrected,trk_denom=Total */ 
2733  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_AC_CTRL,0x00000001);  /* RS lock achieved if 0 uncorrected out of 1 total */ 
2734  /*BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_RT_CTRL,0x01ff0200); */ /* RS lock lost if >511 (uncorrected+corrected) out of 512 total (i.e. no clean blocks out of 512) */ 
2735  BREG_Write32(h->hRegister,  BCHP_THD_CORE_RS_RT_CTRL,0x07ff0800);  /* RS lock lost if >2047 (uncorrected+corrected) out of 2048 total (i.e. no clean blocks out of 2048) */ 
2736#ifdef BTHD_ISDBT_SUPPORT   
2737  }
2738#endif
2739
2740 /*Initialize Status Spares*/
2741 /*Note: On using a spare, remove its initilization here, as init would overwrite the spare value in case of unlocked and reacquire*/
2742  for (k=1; k<8; k++)
2743    h->pStatus->spare[k] = (k+1)*0x1111;
2744}
2745
2746/***************************************************************************
2747* BTHD_P_AcquireInit()
2748***************************************************************************/
2749BTHD_RESULT BTHD_P_AcquireInit( BTHD_3x7x_Handle h, THD_FFTWindowMode_t FFTWindowMode )
2750{
2751  uint32_t value;
2752  uint32_t N=2048;
2753  uint32_t ice,cl_int,cl_int_ice;
2754
2755  THD_TransGuardResult_t TransGuardResult;
2756  THD_TransmissionMode_t TransmissionMode = h->pAcquireParam->CommonAcquireParam.TransmissionMode;
2757  THD_GuardInterval_t GuardInterval;
2758  BERR_Code eEventWaitResult;
2759   
2760#ifdef EMULATION_ENABLED
2761#ifndef UFE_ENABLED
2762  /* For THD-only emulation: apply input data to THD testport*/
2763  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TP,    0x00000021);      /* TPOUT_SEL=BE,TPOUT_EN=1 */
2764  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TP_FE, 0x00001000);      /* TPIN_EN=1 */
2765  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TP_FW, 0x00ff2110);      /* CRC_EN,TPOUT_SEL=1,TPOUT_EN */
2766  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TP_BE, 0x00000710);      /* TPOUT_SEL=bsft,TPOUT_EN=1 */
2767#endif
2768  /* Signal testbench to start input data */
2769  BREG_Write32(h->hRegister,  BCHP_THD_INTR_AP_SET, 0x00000040 );
2770#endif
2771
2772  /*************************************************************************
2773   * Configuration
2774   *************************************************************************/
2775  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)
2776    BREG_WriteField(h->hRegister, THD_CORE_GLB, STD, 2);             /* ISDBT mode */
2777  BREG_WriteField(h->hRegister, THD_CORE_GLB, BE_MODE, 0 );          /* BE=disabled */
2778  BREG_WriteField(h->hRegister, THD_CORE_GLB, ICE_MODE, 1 );         /* ICE=acquisition */
2779  BREG_WriteField(h->hRegister, THD_CORE_RST, FE_FIFO_RST, 0 );      /* Relese FE FIFO reset */
2780
2781  value = ((uint32_t)h->pAcquireParam->CommonAcquireParam.GuardInterval << 20) | 
2782          ((uint32_t)h->pAcquireParam->CommonAcquireParam.TransmissionMode << 24) | (1U << 31);
2783  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TPS_OV, value );
2784  BTHD_P_SetNotch(h);                                                /* Setup notch filter */
2785
2786  BREG_WriteField(h->hRegister, THD_CORE_DAGC, KL, 0x6 );            /* DAGC K=2(-12) */
2787
2788  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW,0x00212051 );         /* FFT window postcursor bias,enable fft,sync_symbols=32,beta=2^(-5),slip_limit=1 */
2789  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CE,0x02020008 );         /* CE use CPs, ACT=2, ACB=0, auto-reacq SP phase,beta=2^(-1) */
2790  BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 1 );
2791  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CP,0xc2029080 );         /* CP t/c_modulo_add=1,timing PD average 32 symbols,timing PD beta=2^(-2),use freq detector,enable phase ramp comp,trk_range=4,acq_range=128 */
2792  BREG_Write32(h->hRegister,  BCHP_THD_CORE_EQ,0x00003100 );         /* EQ nse avg all beta=2^(-9),nse avg beta=2^(-4),linear nse interpolation */
2793  BREG_WriteField(h->hRegister, THD_CORE_BYP, EQ_BYP, 0x19);         /* EQ bypass nse + avg nse exp, unbypass chan exp, unbypass nse averager, bypass bit scaling */
2794  BREG_WriteField(h->hRegister, THD_CORE_RST2,CP_BAD_RST, 1 );
2795  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CP_BAD,0x00000c40 );     /* CP bad thresh=9dB, window=+/-4 pilots, auto, disabled for CPP */
2796#if 0
2797  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CP_BAD,0x00000c41 );     /* CP bad thresh=9dB, window=+/-4 pilots, auto, enabled for CPP */
2798  BREG_WriteField(h->hRegister, THD_CORE_CP_CPE, USE_CP_BAD, 1 );
2799  BREG_WriteField(h->hRegister, THD_CORE_CP_CGE, USE_CP_BAD, 1 );
2800  BREG_WriteField(h->hRegister, THD_CORE_CE_LMS, TIME_USE_CP_BAD, 1);
2801#endif
2802  /*************************************************************************
2803   * Acquisition
2804   *************************************************************************/
2805  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FRZ,0x07f0f1e0 );        /* Unfreeze NOTCH,CE AVG,FFT Win,DAGC */
2806#ifndef FASTACQ
2807  BKNI_Sleep(10);
2808#endif
2809
2810  /*  Co-Channel (Always enable video carrier notch before SetTransGuard() - improves 2K mode/guard detection with analog TV CCI) */
2811  if (h->pAcquireParam->CommonAcquireParam.CoChannelMode == THD_CoChannelMode_Auto) {
2812#ifdef SmartNotchEnabled
2813                if (h->pInternalAcquireParam->SmartNotchPresent) 
2814        BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ ,0x20 ); /* Unfreeze Notch DDFS 0,1,2,3,0M */ 
2815    else             
2816#endif 
2817    BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ ,0x3c );   /* Unfreeze Notch DDFS 0,0M */                 
2818    BREG_Write32(h->hRegister, BCHP_THD_CORE_NOTCH_SWP2,0x04001001 );/* Dwell=0x40,Step_Size=0x4,Num_Steps=0x1 */
2819    BREG_Write32(h->hRegister, BCHP_THD_CORE_NOTCH_SWP3,0x00000000 );/* Threshold = 0 */
2820    BREG_Write32(h->hRegister, BCHP_THD_CORE_NOTCH_SWP1,0x801b2200 );/* Start sweep,enable carrier adjust,enable notch0 pwr,sweep  notch width = 0xb,enable thresh,auto enable */
2821    while (  BREG_ReadField(h->hRegister,  THD_CORE_NOTCH_STATUS1, DONE ) != 1 );
2822  }
2823
2824  TransGuardResult = BTHD_P_SetTransGuard(h);
2825  BREG_Write32(h->hRegister, BCHP_THD_CORE_INTR_STATUS2_CLR,0xffffffff);
2826
2827  /* Early-Abort occurred (during BTHD_P_SetTransGuard())? */
2828  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
2829    /* Acquire aborted early waiting for fwSyncEvent */
2830    return (THD_AcquireResult_AbortedEarly);
2831  }
2832
2833  if (TransGuardResult == THD_TransGuardResult_NoSignal)
2834    return (THD_AcquireResult_NoSignal);
2835
2836  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
2837  N = bthd_transmission_mode[TransmissionMode];
2838  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
2839
2840  /* Co-Channel */
2841  if (h->pAcquireParam->CommonAcquireParam.CoChannelMode == THD_CoChannelMode_Auto)
2842        {
2843#ifdef SmartNotchEnabled 
2844                if (h->pInternalAcquireParam->SmartNotchPresent) 
2845        BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ ,0x20 );     
2846
2847    else
2848#endif   
2849    BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ, 0x30 );     
2850        }
2851
2852  /* Impulse Noise */
2853  if (h->pInternalAcquireParam->ImpulseMode == THD_ImpulseMode_Auto) {                       
2854    BREG_Write32(h->hRegister,  BCHP_THD_CORE_IMPE_MA_THR,0x00118eed);             /* Set impulse eraser moving averager threshold to -7dB */
2855    BREG_Write32(h->hRegister,  BCHP_THD_CORE_IMPE_INST_THR,0x000a24b0);           /* Set impulse eraser instantaneous threshold to -9dB */
2856    BREG_Write32(h->hRegister,  BCHP_THD_CORE_IMPE,0x00000040);                    /* Enable impulse eraser,11-tap moving average */
2857    value = BREG_Read32(h->hRegister,  BCHP_THD_CORE_IMPE_ERASE_CNT);
2858    if (value < 50)
2859      BREG_Write32(h->hRegister,  BCHP_THD_CORE_IMPE,0x00000041);                  /* Disable impulse eraser,11-tap moving average */
2860  }
2861
2862  /* FFT Window and Loops */
2863#ifndef FASTACQ
2864  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_COEF,0x02000000);                   /* Carrier loop Ki=2^(-6),Kl=0 */
2865#else
2866  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_COEF,0x08000000);                   /* Carrier loop Ki=2^(-4),Kl=0 */
2867#endif
2868  BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_COEF,0x02000000 * (N/2048));        /* Timing loop  Ki=2^(-6)*N/2048,Kl=0 (freq detector acquisition BW) */
2869
2870#ifdef BTHD_ISDBT_SUPPORT
2871  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2872  BTHD_P_SetFW(h,FFTWindowMode,TransmissionMode,GuardInterval);
2873  }
2874  else
2875#endif
2876  {
2877  BTHD_P_DvbtSetFWFtt(h,FFTWindowMode,TransmissionMode,GuardInterval); 
2878  }
2879  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CL_FRZ, 0 );                         /* Unfreeze carrier loop */ 
2880
2881
2882  if (BREG_ReadField(h->hRegister,  THD_CORE_INTR_STATUS, FW_SYNC))
2883    BDBG_WRN(("BTHD_P_AcquireInit:\tFW_SYNC Interrupt Status is set before FW Search!\n"));
2884  BREG_WriteField(h->hRegister, THD_CORE_INTR_STATUS_CLR, FW_SYNC, 1);             /* Clear interrupt */
2885  BKNI_ResetEvent(h->hFwSyncEvent);
2886  BINT_EnableCallback( h->hFwSyncCallback);
2887  BREG_WriteField(h->hRegister, THD_CORE_RST, FW_RST, 0);                          /* Release FFT window reset */ 
2888  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hFwSyncEvent, 200);
2889  BINT_DisableCallback(h->hFwSyncCallback);
2890  BKNI_ResetEvent(h->hFwSyncEvent);
2891
2892  if ( eEventWaitResult == BTHD_ERR_ACQUIRE_ABORTED ) {
2893    /* Acquire aborted early waiting for fwSyncEvent */
2894    return (THD_AcquireResult_AbortedEarly);
2895  }
2896  if ( eEventWaitResult != BERR_SUCCESS && eEventWaitResult != BTHD_ERR_ACQUIRE_ABORTED ) {
2897    BDBG_MSG(("\nBTHD_P_AcquireInit:\t failed THD_CORE_INTR_STATUS = %80x\n", BREG_Read32(h->hRegister,  BCHP_THD_CORE_INTR_STATUS)));
2898  }
2899  /* Integer Carrier Acquisition */
2900  if (h->pAcquireParam->CommonAcquireParam.CarrierRange == THD_CarrierRange_Narrow)
2901    value =  48 * (N/2048);                                                        /* CP acq_range={ 48, 96,192} for {2K,4K,8K} (works for +/-210kHz offset in 8MHz channels)*/
2902  else
2903    value = 144 * (N/2048);
2904  BREG_WriteField(h->hRegister, THD_CORE_CP, ACQ_RANGE, value);                    /* CP acq_range=192 for {4K,8K} (temporary fix for ICE acquisition failure in Portable channel at low SNR) */
2905  BREG_WriteField(h->hRegister, THD_CORE_DAGC, THRESH, 0x028c4 );                  /* DAGC threshold=14dB (uint32_t)(pow(10.0,-14/10)* 262144) */
2906  eEventWaitResult = BTHD_P_OSleep(h,2,N,GuardInterval);
2907  if ( eEventWaitResult == BTHD_ERR_ACQUIRE_ABORTED ) {
2908    /* Acquire aborted early waiting for fwSyncEvent */
2909    return (THD_AcquireResult_AbortedEarly);
2910  }
2911  /* Determine ICE value which occurs most often */
2912#ifdef BTHD_ISDBT_SUPPORT
2913  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) 
2914    ice = BTHD_P_IsdbtSetICE(h,TransmissionMode,GuardInterval);
2915    else
2916#endif
2917    ice = BTHD_P_DvbtSetICE(h,TransmissionMode,GuardInterval);
2918#ifdef SmartNotchEnabled 
2919                if (h->pInternalAcquireParam->SmartNotchPresent)                     
2920                        BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH3, 0);
2921#endif
2922  /* Early-Abort occurred (during BTHD_P_IsdbtSetICE() / BTHD_P_DvbtSetICE())? */
2923  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
2924    /* Acquire aborted early waiting for fwSyncEvent */
2925    return (THD_AcquireResult_AbortedEarly);
2926  }
2927
2928#ifdef BTHD_ISDBT_SUPPORT
2929  if (h->pStatus->LowICECount)                                                     /* Exit on ICE lock failure */
2930    return (THD_AcquireResult_NoSignal);
2931#endif
2932  cl_int = BREG_Read32(h->hRegister,  BCHP_THD_CORE_CL_INT);
2933  if (ice >> 10)
2934    cl_int_ice = cl_int + ((0xfffff800 | ice) << 21);                              /* Sign extend for negative ICE value */
2935  else
2936    cl_int_ice = cl_int + (ice << 21); 
2937  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_INT,cl_int_ice); 
2938  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CL_FRZ, 0 );                         /* Unfreeze carrier loop */
2939
2940  /* Reduce input level to BE and DAGC bandwidths */
2941  BREG_WriteField(h->hRegister, THD_CORE_DAGC, THRESH, 0x00a3d );                  /* DAGC threshold=20dB (uint32_t)(pow(10.0,-20/10)* 262144) */
2942  BREG_WriteField(h->hRegister, THD_CORE_DAGC, KL,0x8 );                           /* DAGC K=2(-14) */
2943#ifndef FASTACQ
2944  eEventWaitResult = BTHD_P_OSleep(h,10,N,GuardInterval);
2945#endif
2946  /* BREG_Write32(h->hRegister,  BCHP_THD_CORE_CP2,0x10000007 ); */                      /* CP pilot thresh=1.0, use thresh */
2947
2948  BREG_WriteField(h->hRegister, THD_CORE_GLB, BE_MODE, 0 );                        /* BE=disabled */
2949  BREG_WriteField(h->hRegister, THD_CORE_GLB, ICE_MODE, 0 );                       /* ICE=tracking */
2950  BREG_WriteField(h->hRegister, THD_CORE_FRZ, TL_FRZ, 1 );                         /* Freeze timing loop */
2951  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CFINE_FRZ,1 );                    /* Freeze fine carrier estimator */
2952  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_TFINE_FRZ,1 );                    /* Freeze fine timing estimator */
2953  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CE_AVG_FRZ, 1 );                     /* Freeze CE averager */
2954  BREG_WriteField(h->hRegister, THD_CORE_BYP, CPE_BYP, 1 );                        /* Bypass CPE */
2955  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 1 );             /* Enable auto-reacq SP phase */
2956  BREG_WriteField(h->hRegister, THD_CORE_RST, TL_RST,1 );                          /* Reset timing loop */
2957  BREG_WriteField(h->hRegister, THD_CORE_RST, TL_RST,0 );
2958  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_FEC_BCH_TPS_SNR_RST ,0x3b );      /* Assert RS, FEC, BCH, TPS, and SNR resets */
2959  BREG_WriteField(h->hRegister, THD_CORE_RST2, NSE_AVG_RST, 1 );                   /* Assert noise averager reset*/
2960
2961  if ( eEventWaitResult == BTHD_ERR_ACQUIRE_ABORTED ) {
2962    /* Acquire aborted early during previous delay(s) */
2963    return (THD_AcquireResult_AbortedEarly);
2964  }
2965  return(THD_AcquireResult_InitLockState);
2966}
2967
2968/***************************************************************************
2969 * BTHD_P_AcquireSP()
2970 ***************************************************************************/
2971BTHD_RESULT BTHD_P_AcquireSP( BTHD_3x7x_Handle h )
2972{
2973  BERR_Code eEventWaitResult;
2974  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
2975
2976  /* Enable continuous pilot processing and the BE */
2977  BREG_WriteField(h->hRegister, THD_CORE_FRZ, TL_FRZ, 0 );
2978  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_TFINE_FRZ, 0 );
2979  BREG_WriteField(h->hRegister, THD_CORE_GLB, BE_MODE, 1 );  /* BE=enabled */
2980  BREG_WriteField(h->hRegister, THD_CORE_GLB, ICE_MODE, 0 ); /* ICE=tracking */
2981
2982  /* Scattered Pilot Synchronization */ 
2983  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
2984    /* Do not wait for SP Lock... unreliable at this point because TMCC has not yet identified
2985       which segments contain scattered pilots */ 
2986    BREG_WriteField(h->hRegister, THD_CORE_CE, ACE_ACT ,0x00);                   
2987  }
2988  else {
2989    BREG_WriteField(h->hRegister, THD_CORE_CE, ACE_ACT ,0x82);
2990        BINT_EnableCallback( h->hSpSyncCallback);
2991
2992    eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hSpSyncEvent, 100);
2993    /* eEventWaitResult success: return_val, Failure: THD_AcquireResult_NoSPLock, or,
2994     * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
2995    return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, return_val, THD_AcquireResult_NoSPLock);
2996
2997        BINT_DisableCallback( h->hSpSyncCallback);
2998  }
2999
3000  return(return_val);
3001}
3002
3003/***************************************************************************
3004 * BTHD_P_AcquireFFTTrigger()
3005 ***************************************************************************/
3006BTHD_RESULT BTHD_P_AcquireFFTTrigger (BTHD_3x7x_Handle h)
3007{
3008  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3009  uint32_t N;
3010  THD_TransmissionMode_t TransmissionMode;
3011  THD_GuardInterval_t GuardInterval;
3012  BERR_Code eEventWaitResult;
3013
3014  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3015  N = bthd_transmission_mode[TransmissionMode];
3016  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3017
3018#ifndef FASTACQ
3019  eEventWaitResult = BTHD_P_OSleep(h,1,N,GuardInterval);              /* Wait 64 OFDM symbols for span calculation to settle */     
3020#else
3021  eEventWaitResult = BTHD_P_OSleep(h,1,N,GuardInterval);
3022#endif
3023  if ( eEventWaitResult == BTHD_ERR_ACQUIRE_ABORTED ) {
3024    /* Acquire aborted early waiting for fwSyncEvent */
3025    return_val = THD_AcquireResult_AbortedEarly;
3026    goto BTHD_P_AcquireFFTTrigger_Exit;
3027  }
3028
3029  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SPAN,0x00000140 );      /* FFT window span scale = 0.1875 (better for detecting long weak echoes) */
3030  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CFINE_FRZ, 0 );
3031
3032  /* Begin Channel Estimation and Common Phase Estimation */
3033  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CE_AVG_FRZ, 0 );
3034  BREG_WriteField(h->hRegister, THD_CORE_BYP, CPE_BYP, 0 );
3035  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 0 ); /* Disable auto-reacq SP phase */
3036 
3037  /* FFT Trigger Position */
3038  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 0 );        /* Assert FFT window reference index reset (active-low) */
3039  BTHD_P_OSleep(h,1,N,GuardInterval);
3040  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );        /* De-assert FFT window reference index reset (active low) */
3041  BTHD_P_OSleep(h,8,N,GuardInterval);       
3042
3043  if ( ! BTHD_P_GetFFTTriggerPosition( h, TransmissionMode, GuardInterval) )
3044  {
3045    if ( BTHD_P_IsAbortAcquireRequested(h) )
3046      return_val = THD_AcquireResult_AbortedEarly;
3047    else
3048      return_val = THD_AcquireResult_NoSPLock;
3049
3050    goto BTHD_P_AcquireFFTTrigger_Exit;
3051  }
3052
3053  if (h->pStatus->FFTTriggerOutOfSpan) {
3054    BTHD_P_WriteFICoef(h,THD_FrequencyInterpolatorMode_OutOfSpanPost); /* Setup frequency interpolator coefficients for out-of-span channels */
3055  }
3056       
3057  if (h->pStatus->FFTTriggerMissed || h->pStatus->FFTTriggerOnGuard) {
3058        BTHD_P_SetFFTTriggerPosition( h, TransmissionMode, GuardInterval);   
3059  }
3060
3061  /* Early-exit abort triggered (during BTHD_P_GetFFTTriggerPosition()) ? */
3062  if ( BTHD_P_IsAbortAcquireRequested(h) ) {
3063    return_val = THD_AcquireResult_AbortedEarly;
3064    goto BTHD_P_AcquireFFTTrigger_Exit;
3065  }
3066
3067  /* Re-acquire SP phase */ 
3068  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 1 );             /* Enable auto-reacq SP phase */
3069  BINT_EnableCallback( h->hSpSyncCallback);
3070
3071  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hSpSyncEvent, 10);
3072  /* eEventWaitResult success: return_val, Failure: THD_AcquireResult_NoSPLock, or,
3073   * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3074  return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, return_val, THD_AcquireResult_NoSPLock);
3075
3076  BINT_DisableCallback( h->hSpSyncCallback);
3077
3078BTHD_P_AcquireFFTTrigger_Exit:
3079  return(return_val);
3080}
3081
3082/***************************************************************************
3083 * BTHD_P_AcquireTPS()
3084 ***************************************************************************/
3085BTHD_RESULT BTHD_P_AcquireTPS( BTHD_3x7x_Handle h)
3086{
3087  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3088  uint32_t N;
3089  THD_TransmissionMode_t TransmissionMode;
3090  THD_GuardInterval_t GuardInterval;
3091  BERR_Code eSleepResult;
3092
3093  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3094  N = bthd_transmission_mode[TransmissionMode];
3095  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3096
3097#ifndef FASTACQ
3098  eSleepResult = BTHD_P_OSleep(h,16,N,GuardInterval);                                 /* Wait 64 OFDM symbols for span calculation to settle */     
3099#else
3100  eSleepResult = BTHD_P_OSleep(h,10,N,GuardInterval);
3101#endif
3102  if ( eSleepResult == BTHD_ERR_ACQUIRE_ABORTED ) {
3103    return(THD_AcquireResult_AbortedEarly);
3104  }
3105
3106  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_SPAN,0x00000140 );      /* FFT window span scale = 0.1875 (better for detecting long weak echoes) */
3107  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CFINE_FRZ, 0 );
3108
3109  /* Begin Channel Estimation and Common Phase Estimation */
3110  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CE_AVG_FRZ, 0 );
3111  BREG_WriteField(h->hRegister, THD_CORE_BYP, CPE_BYP, 0 );
3112  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 0 ); /* Disable auto-reacq SP phase */
3113 
3114  BREG_WriteField(h->hRegister, THD_CORE_RST, SNR_RST, 0 );
3115  BREG_WriteField(h->hRegister, THD_CORE_RST2,NSE_AVG_RST, 1 );        /* Reset noise averager (necessary for proper co-channel filter detection when CP bad is used) */
3116  BREG_WriteField(h->hRegister, THD_CORE_RST2,NSE_AVG_RST, 0 );
3117  BREG_WriteField(h->hRegister, THD_CORE_RST2,CP_BAD_RST, 0 );
3118
3119  /* Search for TPS (DVB-T) or TMCC (ISDB-T) */
3120#ifdef BTHD_ISDBT_SUPPORT
3121  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3122    BTHD_P_IsdbtSetFEC(h);
3123    BTHD_P_IsdbtSetOI(h);
3124    return_val = BTHD_P_IsdbtSetTMCC(h, TransmissionMode, GuardInterval);  /* Setup TMCC and wait for lock or timeout */
3125  } 
3126  else
3127#endif
3128    return_val = BTHD_P_DvbtSetTPS(h, TransmissionMode, GuardInterval);    /* Setup TPS and wait for lock or timeout */
3129
3130  return(return_val);
3131}
3132
3133/***************************************************************************
3134 * BTHD_P_AcquireFEC()
3135 ***************************************************************************/
3136BTHD_RESULT BTHD_P_AcquireFEC( BTHD_3x7x_Handle h, bool FirstTime )
3137{
3138  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3139  uint32_t N,notchwidth;
3140  bool CoChannelPresent = false;
3141  THD_TransmissionMode_t TransmissionMode;
3142  THD_GuardInterval_t GuardInterval;
3143  BERR_Code eEventWaitResult;
3144 #ifdef BTHD_ISDBT_SUPPORT 
3145  uint32_t segs_b=0, segs_c=0;
3146#endif
3147  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3148  N = bthd_transmission_mode[TransmissionMode];
3149  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3150
3151  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 0 ); /* Disable auto-reacq SP phase */
3152
3153  /* Configure OI and wait for FEC sync (DVB-T only) */
3154  if (h->pAcquireParam->CommonAcquireParam.Standard != THD_Standard_ISDBT) {
3155    BTHD_P_DvbtSetOI(h);                                               /* Setup output interface */
3156    return_val = BTHD_P_DvbtSetFEC(h);                                 /* Setup FEC and wait for lock or timeout */
3157  }
3158 
3159  if (FirstTime) {
3160    /* Check for Cochannel Interference and remove notch filter if not needed */
3161    if (h->pAcquireParam->CommonAcquireParam.CoChannelMode != THD_CoChannelMode_None) {
3162      /* Need to enable the CE averager in order to estimate the noise */
3163      BREG_WriteField(h->hRegister, THD_CORE_CE, AVG_FF, 0x0);                       /* CE averager beta = 2^(-4) */
3164      BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 0);                    /* CE averager unbypassed */
3165      if (TransmissionMode == THD_TransmissionMode_2k)
3166        BTHD_P_OSleep(h,64,N,GuardInterval);
3167      else
3168        BTHD_P_OSleep(h,32,N,GuardInterval);
3169     
3170      /* Determine CCI presence using snooper (Look for video, color, or audio to guarantee robust CCI detection) */
3171  #ifdef BTHD_ISDBT_SUPPORT   
3172      if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)
3173        CoChannelPresent = BTHD_P_IsdbtGetNotch(h, TransmissionMode);
3174      else {
3175  #endif   
3176                        BREG_WriteField(h->hRegister, THD_CORE_BYP, EXP_AVG_NSE, 0x0 );              /* EQ nse + avg nse exponents unbypassed */
3177                        CoChannelPresent = BTHD_P_DvbtGetNotch(h, TransmissionMode);
3178  #ifdef BTHD_ISDBT_SUPPORT   
3179                }       
3180  #endif               
3181                BREG_WriteField(h->hRegister, THD_CORE_BYP, CE_AVG_BYP, 1);                    /* CE averager bypassed */
3182                if (!CoChannelPresent) {
3183          uint32_t uNotchWidthStartTimeCnt = BTHD_P_Read_FSCnt_Time(h);
3184          do {                                                                         /*  Gradually reduce notch to avoid burst error */
3185            notchwidth = BREG_ReadField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH4);
3186            if (notchwidth)
3187              BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH4, notchwidth - 1);
3188            notchwidth = BREG_ReadField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH3);
3189            if (notchwidth)
3190              BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH3, notchwidth - 1);
3191            notchwidth = BREG_ReadField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH2);
3192            if (notchwidth)
3193              BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH2, notchwidth - 1);
3194            notchwidth = BREG_ReadField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH1);
3195            if (notchwidth)
3196              BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH1, notchwidth - 1);
3197            notchwidth = BREG_ReadField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH0);
3198            if (notchwidth)
3199              BREG_WriteField(h->hRegister, THD_CORE_NOTCH_WIDTH, WIDTH0, notchwidth - 1);
3200            notchwidth = BREG_Read32(h->hRegister, BCHP_THD_CORE_NOTCH_WIDTH);
3201
3202            /* Delay, and check if Early-Exit was requested while delaying */
3203            if ( BTHD_ERR_ACQUIRE_ABORTED == BTHD_P_OSleep(h,3,N,GuardInterval) ) {
3204                return_val = THD_AcquireResult_AbortedEarly;
3205                goto BTHD_P_AcquireFEC_Exit;
3206            }
3207            /* Check 1 second exceeded adjusting notch */
3208            if ( BTHD_P_Check_FSCnt_TimeExceeded(h, uNotchWidthStartTimeCnt, BTHD_P_MSEC_TO_FSCNT(1000)) ) {
3209              BDBG_MSG(("\t\tNotchwidth whileLoop time out at 0x%08X", BTHD_P_Read_FSCnt_Time(h)));
3210              return_val = THD_AcquireResult_NoFECLock;
3211              goto BTHD_P_AcquireFEC_Exit;
3212            }
3213          } while (notchwidth);
3214                }
3215    }
3216
3217    /* Check if Early-Exit occurred */
3218    if ( BTHD_P_IsAbortAcquireRequested(h) ) {
3219      /* Acquire aborted early waiting for fwSyncEvent */
3220      return_val = THD_AcquireResult_AbortedEarly;
3221      goto BTHD_P_AcquireFEC_Exit;
3222    }
3223
3224    /* Update status structure with auto-detected modes */ 
3225    h->pStatus->CoChannelPresent = CoChannelPresent;
3226    if (h->pStatus->CoChannelPresent)
3227      h->pStatus->CoChannelMode = THD_CoChannelMode_Auto;
3228    else
3229      h->pStatus->CoChannelMode = THD_CoChannelMode_None;
3230  }
3231  BREG_WriteField(h->hRegister,  THD_CORE_EQ, NSE_AVG_ALL_FF, 3 );         /* EQ nse avg all beta=2^(-12) */
3232 
3233  /* Wait for data at FEC output */
3234#ifdef BTHD_ISDBT_SUPPORT
3235  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3236    segs_b = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG);
3237    segs_c = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG);
3238    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );
3239    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
3240    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );
3241    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 ); 
3242        BINT_EnableCallback( h->hRsSyncCallback);
3243        if (segs_b) {
3244      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 1 );
3245      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 0 );
3246      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 1 );
3247      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 0 ); 
3248          BINT_EnableCallback( h->hRsSyncBCallback);
3249        }
3250        if (segs_c) {
3251      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 1 );
3252      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 0 );
3253      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 1 );
3254      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 0 ); 
3255          BINT_EnableCallback( h->hRsSyncCCallback);
3256        }
3257    eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hRsSyncEvent, 540);
3258    /* eEventWaitResult success: THD_AcquireResult_Lock, Failure: THD_AcquireResult_NoFECLock, or,
3259     * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3260    return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, THD_AcquireResult_Lock, THD_AcquireResult_NoFECLock);
3261
3262    BINT_DisableCallback( h->hRsSyncCallback);
3263        if (segs_b)
3264      BINT_DisableCallback( h->hRsSyncBCallback);               
3265        if (segs_c)
3266      BINT_DisableCallback( h->hRsSyncCCallback);               
3267  } else {
3268#endif
3269#if 0
3270  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );
3271  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
3272  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );
3273  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 );
3274
3275  BINT_EnableCallback( h->hRsSyncCallback);
3276
3277  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hRsSyncEvent, 100);
3278  /* eEventWaitResult success: THD_AcquireResult_Lock, Failure: THD_AcquireResult_NoFECLock, or,
3279   * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3280  return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, THD_AcquireResult_Lock, THD_AcquireResult_NoFECLock);
3281
3282
3283  BINT_DisableCallback( h->hRsSyncCallback);
3284#endif
3285#ifdef BTHD_ISDBT_SUPPORT   
3286  }
3287#endif
3288
3289BTHD_P_AcquireFEC_Exit:
3290  return(return_val);
3291}
3292
3293#ifdef BTHD_ISDBT_SUPPORT
3294/***************************************************************************
3295 * BTHD_P_AcquireChangeFFTWindow()
3296 ***************************************************************************/
3297BTHD_RESULT BTHD_P_AcquireChangeFFTWindow( BTHD_3x7x_Handle h, THD_FFTWindowMode_t FFTWindowMode)
3298{
3299  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3300  uint32_t N;
3301  THD_TransmissionMode_t TransmissionMode;
3302  THD_GuardInterval_t GuardInterval;
3303  BERR_Code eEventWaitResult;
3304
3305  /* Determine N */
3306  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3307  N = bthd_transmission_mode[TransmissionMode];
3308  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3309
3310#ifndef ChangeFFTWindowSeamless     
3311  BREG_WriteField(h->hRegister, THD_CORE_GLB, BE_MODE, 0 );                        /* BE=disabled */
3312  BREG_WriteField(h->hRegister, THD_CORE_GLB, ICE_MODE, 0 );                       /* ICE=tracking */
3313  BREG_WriteField(h->hRegister, THD_CORE_FRZ, TL_FRZ, 1 );                         /* Freeze timing loop */
3314  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_CFINE_FRZ,1 );                    /* Freeze fine carrier estimator */
3315  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_TFINE_FRZ,1 );                    /* Freeze fine timing estimator */
3316  BREG_WriteField(h->hRegister, THD_CORE_FRZ, CE_AVG_FRZ, 1 );                     /* Freeze CE averager */
3317  BREG_WriteField(h->hRegister, THD_CORE_BYP, CPE_BYP, 1 );                        /* Bypass CPE */
3318  BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 1 );             /* Enable auto-reacq SP phase */
3319  BREG_WriteField(h->hRegister, THD_CORE_RST, TL_RST,1 );                          /* Reset timing loop */
3320  BREG_WriteField(h->hRegister, THD_CORE_RST, TL_RST,0 );
3321  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_FEC_BCH_TPS_SNR_RST ,0x3b );      /* Assert RS, FEC, BCH, TPS, and SNR resets */
3322  BREG_WriteField(h->hRegister, THD_CORE_RST2, NSE_AVG_RST, 1 );                   /* Assert noise averager reset*/
3323#endif
3324
3325  /* Reset/freeze various modules */
3326  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_FEC_BCH_TPS_SNR_RST ,0x38 );      /* Assert RS, FEC, BCH */
3327  /* BREG_WriteField(h->hRegister, THD_CORE_CE, SP_PHASE_REACQ_MODE, 1 ); */       /* Enable auto-reacq SP phase */
3328  BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_WIN,0x00000000);                     /* Disable time-domain windowing */
3329
3330#ifndef ChangeFFTWindowSeamless
3331  /* Non-seamless switch of FFT window mode (requires SP, TPS re-acquire) */
3332  BTHD_P_SetFW(h, FFTWindowMode, TransmissionMode, GuardInterval);
3333
3334  BINT_EnableCallback( h->hFwSyncCallback);
3335
3336  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hFwSyncEvent, 200);
3337  /* eEventWaitResult success: return_val, Failure: THD_AcquireResult_NoFFTLock, or,
3338   * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3339  return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, return_val, THD_AcquireResult_NoFFTLock);
3340
3341
3342  BINT_DisableCallback( h->hFwSyncCallback);
3343
3344  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 0 );                    /* Reset FFT window reference index */
3345  BTHD_P_OSleep(h,1,N,GuardInterval); 
3346  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );
3347#else
3348  /* Seamless switch of FFT window mode (hopefully eliminates SP, TPS re-acquire) */
3349  BINT_EnableCallback( h->hFwSyncCallback);
3350  BKNI_WaitForEvent(h->hFwSyncEvent, 10);
3351  BTHD_P_SetFW(h, FFTWindowMode, TransmissionMode, GuardInterval);
3352  BKNI_WaitForEvent(h->hFwSyncEvent, 10);
3353  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 0 );                    /* Assert FFT window reference index reset (active-low) */
3354  /* BREG_Write32(h->hRegister, h->hRegister, BCHP_THD_CORE_FBCNT, N>>1  ); */
3355  BKNI_WaitForEvent(h->hFwSyncEvent, 10);
3356  BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );                    /* Deassert FFT window reference index reset (active-low) */
3357  BINT_DisableCallback( h->hFwSyncCallback);
3358 
3359#endif
3360
3361  return(return_val);
3362}
3363#endif
3364
3365/***************************************************************************
3366 * BTHD_P_AcquireTrack()
3367 ***************************************************************************/
3368BTHD_RESULT BTHD_P_AcquireTrack( BTHD_3x7x_Handle h, THD_FFTWindowMode_t FFTWindowMode, THD_ChannelEstimatorMode_t ChannelEstimatorMode)
3369{
3370  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3371  uint32_t N;
3372  THD_TransmissionMode_t TransmissionMode;
3373  THD_GuardInterval_t GuardInterval;
3374  BERR_Code eEventWaitResult;
3375#ifdef BTHD_ISDBT_SUPPORT
3376  bool InSpan=false;
3377  uint32_t segs_b, segs_c;
3378#endif
3379  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3380  N = bthd_transmission_mode[TransmissionMode];
3381  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3382
3383  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FEC_SYNC,0x07001f1f );                 /* Force FEC sync retention */
3384  BREG_Write32(h->hRegister,  BCHP_THD_CORE_VIT,0x00000687 );                      /* Force Viterbi sync retention */   
3385  BTHD_P_DvbtSetFrame(h);
3386  BREG_Write32(h->hRegister,  BCHP_THD_CORE_DAGC,0x04000A3D );                     /* DAGC threshold=20dB, thresh = (thd_u32)(pow(10.0,-17/10)* 262144), K=2^(-8) */
3387
3388  /* Channel Estimator */
3389  if (h->pInternalAcquireParam->ChannelEstimatorMode == THD_ChannelEstimatorMode_Auto)
3390    ChannelEstimatorMode = THD_ChannelEstimatorMode_Fixed;
3391  else
3392    ChannelEstimatorMode = h->pInternalAcquireParam->ChannelEstimatorMode;
3393  BTHD_P_SetCE(h, ChannelEstimatorMode);
3394  BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_MISC,0x00000208 );                  /* FFT window leak to timing loop enabled w/limiting (prevents "V" noise response) */
3395
3396  /* Common Gain Estimator */
3397  BREG_WriteField(h->hRegister, THD_CORE_CP_CGE, THRESH, 0x16b );                  /* CGE target back-off = 9dB (floor(10^(-9/20)*2^10)) */
3398  if (h->pAcquireParam->CommonAcquireParam.Standard != THD_Standard_ISDBT)
3399    BREG_WriteField(h->hRegister, THD_CORE_CP_CGE, ENABLE, 1 );                    /* CGE enable */
3400
3401  /* Reduce Timing and Carrier Bandwidths */
3402  if (!BREG_ReadField(h->hRegister, THD_CORE_NOTCH_STATUS1,BYP_DP))
3403    BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_COEF,0x00100000 * (N/2048) );     /* Ki=2^(-11)*N/2048,Kl=2^0 (better for CCI) */ 
3404  else
3405    BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_COEF,0x00020000 * (N/2048) );     /* Ki=2^(-14)*N/2048,Kl=2^0 (better for echo tests inside/outside guard interval) */
3406 
3407  /*BREG_Write32(h->hRegister,  BCHP_THD_CORE_CL_COEF,0x08000000);*/                   /* Carrier loop Ki=2^(-4),Kl=0 for improved phase noise tracking */
3408
3409  /* FW Tracking Parameters */
3410  BREG_WriteField(h->hRegister, THD_CORE_FW, LIMIT, 0);                            /* FW slip_limit=0 (fixes "breathing noise response") */
3411  BREG_WriteField(h->hRegister, THD_CORE_FW, AVG_FF, 7);                           /* Reduce FW avg. FF  */
3412  if ((N > 2048) && (ChannelEstimatorMode != THD_ChannelEstimatorMode_Fixed)) /* (FFTWindowMode == BTHD_FFTWindowMode_InSpan))*/
3413    BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_WIN,0x00000001);                  /* Enable time-domain windowing in auto mode */
3414
3415  if (!(h->pStatus->FFTTriggerMissed || h->pStatus->FFTTriggerOnGuard)) {
3416    BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 1 );                    /* Reset FFT window reference index */
3417    BTHD_P_OSleep(h,1,N,GuardInterval); 
3418    BREG_WriteField(h->hRegister, THD_CORE_RST2, FW_REF_RST, 0 );
3419    }
3420
3421
3422  /* Cochannel Interference Tracking Parameters */
3423  if ((h->pAcquireParam->CommonAcquireParam.CoChannelMode != THD_CoChannelMode_None) && h->pStatus->CoChannelPresent) {
3424    if (ChannelEstimatorMode == THD_ChannelEstimatorMode_Fixed) {                 /* Enable timing PD for fixed mode */
3425      BREG_WriteField(h->hRegister, THD_CORE_CP, F_SPACE, 2 );                     /* 12-bin timing pd pilot spacing (mandatory for long-echo channels)*/
3426      BREG_WriteField(h->hRegister, THD_CORE_CP, PHASE_FREQ_SELECT, 1 );           /* Timing pd enable*/
3427      BREG_WriteField(h->hRegister, THD_CORE_FRZ, CP_TPHASE_FRZ, 0 );              /* Unfreeze timing pd  */
3428      BREG_Write32(h->hRegister,  BCHP_THD_CORE_TL_COEF,0x00010200 * (N/2048) );   /* Ki=2^(-13),Kl=2^(-4) (for CCI)*/
3429      BREG_Write32(h->hRegister,  BCHP_THD_CORE_FW_MISC,0x00000200 );              /* FFT window leak to timing loop disabled (prevents "wandering" at low SNR) */
3430    } 
3431
3432    BTHD_P_DvbtSetEq(h, THD_CoChannelMode_Auto); 
3433
3434    if (TransmissionMode == THD_TransmissionMode_2k)
3435      BREG_WriteField(h->hRegister, THD_CORE_EQ, EXP_OFFSET, 0x3f8);               /* EQ exponent offset = -8 for 2K (helps with color pattern (not color bars))*/
3436    if (TransmissionMode == THD_TransmissionMode_8k)
3437      BREG_WriteField(h->hRegister, THD_CORE_CE, AVG_FF, 0x1);                     /* CE set beta=2^-2 for 8K w/CCI*/
3438
3439    BREG_WriteField(h->hRegister, THD_CORE_BYP, NOTCH_BYP, 0);                     /* Unbypass notch filter*/
3440    BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH_DEPTH,0x0000081a );
3441    BREG_Write32(h->hRegister,  BCHP_THD_CORE_NOTCH_WIDTH,0x00000bcb );
3442#ifdef SmartNotchEnabled
3443                if (h->pInternalAcquireParam->SmartNotchPresent) 
3444        BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ ,0x20 );                                                   /* Unfreeze Notch DDFS 0,1,2,3,0M */               
3445    else
3446#endif   
3447    BREG_WriteField(h->hRegister, THD_CORE_FRZ, NOTCH_FRZ ,0x30 );                 /* Unfreeze Notch DDFS,2,1,0,0M*/
3448  }
3449#if 1
3450  /* Bad Pilot Estimation */
3451  BREG_Write32(h->hRegister,  BCHP_THD_CORE_CP_BAD,0x00000c41 );     /* CP bad thresh=9dB, window=+/-4 pilots, auto, enabled for CPP */
3452  BREG_WriteField(h->hRegister, THD_CORE_CP_CPE, USE_CP_BAD, 1 );
3453  BREG_WriteField(h->hRegister, THD_CORE_CP_CGE, USE_CP_BAD, 1 );
3454  BREG_WriteField(h->hRegister, THD_CORE_CE_LMS, TIME_USE_CP_BAD, 1);
3455#endif
3456  /* Adaptive Time/Frequency Interpolators */
3457  if (h->pAcquireParam->CommonAcquireParam.Standard != THD_Standard_ISDBT) {
3458      BREG_WriteField(h->hRegister, THD_CORE_CE_LMS, TIME_MU, 0 );                   /* Adaptive time interpolator mu=2^(-2) */   
3459          BREG_WriteField(h->hRegister, THD_CORE_CE_LMS, TIME_ENABLE, 1 );               /* Adaptive time interpolator enable */
3460    /*BREG_WriteField(h->hRegister, THD_CORE_CE_LMS, FREQ_ENABLE, 1 );  */             /* Adaptive frequency interpolator enable */
3461  }
3462
3463  /* Wait for data at FEC output */
3464#ifdef BTHD_ISDBT_SUPPORT
3465  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3466    segs_b = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG);
3467    segs_c = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG);
3468
3469    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );
3470    BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
3471    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );
3472    BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 ); 
3473        BINT_EnableCallback( h->hRsSyncCallback);
3474        if (segs_b) {
3475      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 1 );
3476      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_B, 0 );
3477      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 1 );
3478      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_B, 0 ); 
3479          BINT_EnableCallback( h->hRsSyncBCallback);
3480        }
3481        if (segs_c) {
3482      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 1 );
3483      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_ERC_RST_C, 0 );
3484      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 1 );
3485      BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST_C, 0 ); 
3486          BINT_EnableCallback( h->hRsSyncCCallback);
3487        }
3488    eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hRsSyncEvent, 514);
3489    /* eEventWaitResult success: THD_AcquireResult_Lock, Failure: THD_AcquireResult_NoFECLock, or,
3490     * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3491    return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, THD_AcquireResult_Lock, THD_AcquireResult_NoFECLock);
3492
3493    BINT_DisableCallback( h->hRsSyncCallback);
3494        if (segs_b)
3495      BINT_DisableCallback( h->hRsSyncBCallback);               
3496        if (segs_c)
3497      BINT_DisableCallback( h->hRsSyncCCallback);       
3498
3499        InSpan = BTHD_P_GetChannelSpan(h,FFTWindowMode,TransmissionMode,GuardInterval);
3500        if (InSpan && (TransmissionMode != THD_TransmissionMode_2k))
3501                BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_WIN,0x00000001);                   /* Time-domain windowing enable */ 
3502
3503  } else {
3504#endif
3505  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 1 );                     /* Reset FEC error counters */
3506  BREG_WriteField(h->hRegister, THD_CORE_RST, RS_ERC_RST, 0 );
3507  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 1 );                   /* Reset lock detector */
3508  BREG_WriteField(h->hRegister, THD_CORE_RST2, RS_SYNC_RST, 0 );   
3509
3510  if (h->pStatus->FFTTriggerInSpan && (TransmissionMode != THD_TransmissionMode_2k))
3511    BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_WIN,0x00000001);                   /* Time-domain windowing enable */ 
3512
3513  BINT_EnableCallback( h->hRsSyncCallback);
3514
3515  eEventWaitResult = BTHD_P_WaitForEventOrAbort(h, h->hRsSyncEvent, 200);
3516  /* eEventWaitResult success: THD_AcquireResult_Lock, Failure: THD_AcquireResult_NoFECLock, or,
3517   * THD_AcquireResult_AbortedEarly if "Acquire Aborted Early" Event took place */
3518  return_val = BTHD_P_MapWaitForEventResult_To_THD_AcqResult(eEventWaitResult, THD_AcquireResult_Lock, THD_AcquireResult_NoFECLock);
3519
3520
3521  BINT_DisableCallback( h->hRsSyncCallback);
3522
3523#ifdef BTHD_ISDBT_SUPPORT
3524  }
3525#endif
3526  /* Update status structure with auto-detected modes */
3527  h->pStatus->ChannelEstimatorMode = ChannelEstimatorMode;
3528  h->pStatus->FFTWindowMode = FFTWindowMode;
3529
3530  return(return_val);
3531}
3532
3533/***************************************************************************
3534 * BTHD_P_AcquireCheckLock()
3535 ***************************************************************************/
3536BTHD_RESULT BTHD_P_AcquireCheckLock( BTHD_3x7x_Handle h )
3537{
3538  BTHD_RESULT return_val = THD_AcquireResult_InitLockState;
3539  uint32_t N, rs_rt_ctrl, rs_rt_ctrl_b, rs_rt_ctrl_c;
3540  THD_TransmissionMode_t TransmissionMode;
3541  THD_GuardInterval_t GuardInterval;
3542  BERR_Code eSleepResult;
3543
3544  h->pInternalAcquireParam->AllowRsSyncEvent = false; /* Must disable this, otherwise lock ISR will not set the lock status */
3545
3546  rs_rt_ctrl = BREG_Read32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL);
3547  rs_rt_ctrl_b = BREG_Read32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_B);
3548  rs_rt_ctrl_c = BREG_Read32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_C);
3549
3550#ifdef BTHD_ISDBT_SUPPORT
3551  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3552/*    BTHD_P_IsdbtSetRsAc(h, 3, 2);   */
3553        BTHD_P_IsdbtSetRsRt(h, 1, 2);             /* evaluate 3000/2^3=  800 packets for three layers */
3554  } else 
3555#endif
3556    BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL, 0x00ff0100);  /* RS lock lost if >255 (uncorrected+corrected) out of 256 total (i.e. no clean blocks out of 256) */   
3557  BTHD_P_EnableLockInterrupts(h); 
3558
3559  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3560  N = bthd_transmission_mode[TransmissionMode];
3561  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3562 
3563#ifdef BTHD_ISDBT_SUPPORT
3564  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT)
3565    eSleepResult = BTHD_P_OSleep(h,300,N,GuardInterval);
3566  else 
3567#endif
3568    eSleepResult = BTHD_P_OSleep(h,75,N,GuardInterval);
3569
3570  if ( eSleepResult == BTHD_ERR_ACQUIRE_ABORTED ) {
3571    return_val = THD_AcquireResult_AbortedEarly;
3572  }
3573  else if (!((h->ThdLockStatus >> THD_LockStatusBit_SystemLock) & 1)) {
3574    return_val = THD_AcquireResult_NoFECLock;
3575  } 
3576  else {
3577    return_val = THD_AcquireResult_Lock;
3578#ifdef BTHD_ISDBT_SUPPORT
3579    if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3580      BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL,   rs_rt_ctrl);   
3581      BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_B, rs_rt_ctrl_b);   
3582      BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL_C, rs_rt_ctrl_c);   
3583    } else
3584#endif
3585    BREG_Write32(h->hRegister, BCHP_THD_CORE_RS_RT_CTRL, rs_rt_ctrl);   
3586  }
3587  return(return_val);
3588}
3589
3590/***************************************************************************
3591 * BTHD_P_AcquireChangeChannelEstimator()
3592 ***************************************************************************/
3593BTHD_RESULT BTHD_P_AcquireChangeChannelEstimator(BTHD_3x7x_Handle h, THD_ChannelEstimatorMode_t ChannelEstimatorMode)
3594{
3595  uint32_t N;
3596  uint32_t segs_b, segs_c, isdbt_ti=0, isdbt_ti_b=0, isdbt_ti_c=0;
3597  THD_TransmissionMode_t TransmissionMode;
3598  THD_GuardInterval_t GuardInterval;
3599
3600  TransmissionMode = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, TRANS_MODE );
3601  N = bthd_transmission_mode[TransmissionMode];
3602  GuardInterval = BREG_ReadField(h->hRegister, THD_CORE_TPS_OV, GUARD);
3603
3604  BTHD_P_SetCE(h, ChannelEstimatorMode);
3605  if (ChannelEstimatorMode == THD_ChannelEstimatorMode_Fixed) {
3606    BDBG_MSG(("\tFixed"));
3607    if (TransmissionMode != THD_TransmissionMode_2k)
3608      BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_WIN,0x00000000);         /* Disable time-domain windowing */
3609  } else {
3610    BDBG_MSG(("\tPedestrian"));
3611    if (TransmissionMode != THD_TransmissionMode_2k)
3612      BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_WIN,0x00000001);         /* Enable time-domain windowing */
3613  }
3614  BREG_Write32(h->hRegister, BCHP_THD_CORE_FW_MISC,0x00000208 );           /* FFT window leak to timing loop enabled w/limiting*/
3615  BREG_Write32(h->hRegister, BCHP_THD_CORE_TL_COEF,0x00020000 * (N/2048)); /* Ki=2^(-14)*N/2048,Kl=2^0 (better for echo tests inside/outside guard interval)*/
3616  BREG_WriteField(h->hRegister, THD_CORE_CP, PHASE_FREQ_SELECT, 0 );       /* Timing FD enable */
3617   
3618  if (h->pAcquireParam->CommonAcquireParam.Standard == THD_Standard_ISDBT) {
3619    /*  Add delay for data to flush through time interleaver based on max time interleaver depth */
3620    segs_b = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_SEG);
3621    segs_c = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_SEG);   
3622    isdbt_ti   = BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_0, LAYERA_TI);
3623    isdbt_ti_b = segs_b ? BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERB_TI) : 0;
3624    isdbt_ti_c = segs_c ? BREG_ReadField(h->hRegister, THD_CORE_TMCC_OV_1, LAYERC_TI) : 0;
3625    isdbt_ti   = (isdbt_ti > isdbt_ti_b) ? isdbt_ti : isdbt_ti_b;
3626    isdbt_ti   = (isdbt_ti > isdbt_ti_c) ? isdbt_ti : isdbt_ti_c;
3627    BTHD_P_OSleep(h,(96*isdbt_ti),N,GuardInterval);                        /*  Time for TI to flush */       
3628    BDBG_MSG(("BTHD_P_AcquireChangeChannelEstimator:\tWaiting %d symbols for TI to flush\n",96*isdbt_ti));
3629  } else
3630    BTHD_P_OSleep(h,30,N,GuardInterval);
3631
3632  return(THD_AcquireResult_InitLockState);
3633}
3634
3635
Note: See TracBrowser for help on using the repository browser.